Skip to content

Commit 525403d

Browse files
committed
Create mocks for the entire Customer Account extension API
1 parent d0b57dc commit 525403d

20 files changed

Lines changed: 2434 additions & 0 deletions

File tree

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Environment Configuration
2+
.env
3+
.env.*
4+
5+
# Dependency directory
6+
node_modules
7+
8+
# Test coverage directory
9+
coverage
10+
11+
# Ignore Apple macOS Desktop Services Store
12+
.DS_Store
13+
14+
# Logs
15+
logs
16+
*.log
17+
18+
# extensions build output
19+
extensions/*/build
20+
extensions/*/dist
21+
22+
# lock files
23+
24+
25+
26+
27+
# Ignore shopify files created during app dev
28+
.shopify/*
29+
.shopify.lock
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const fs = require("node:fs");
2+
3+
function getConfig() {
4+
const config = {
5+
projects: {},
6+
};
7+
8+
let extensions = [];
9+
try {
10+
extensions = fs.readdirSync("./extensions");
11+
} catch {
12+
// ignore if no extensions
13+
}
14+
15+
for (const entry of extensions) {
16+
const extensionPath = `./extensions/${entry}`;
17+
const schema = `${extensionPath}/schema.graphql`;
18+
if (!fs.existsSync(schema)) {
19+
continue;
20+
}
21+
config.projects[entry] = {
22+
schema,
23+
documents: [`${extensionPath}/**/*.graphql`],
24+
};
25+
}
26+
27+
return config;
28+
}
29+
30+
module.exports = getConfig();
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
This extension was created with:
2+
3+
```
4+
shopify app init --name customer-account-testing-example
5+
cd customer-account-testing-example
6+
shopify app generate extension
7+
# I chose 'Customer account UI'
8+
```
9+
10+
See it in action:
11+
12+
```
13+
npm install
14+
npm run typecheck
15+
npm test
16+
```

examples/testing/customer-account-testing-example/extensions/.gitkeep

Whitespace-only changes.

examples/testing/customer-account-testing-example/extensions/customer-account-testing-example/package-lock.json

Lines changed: 55 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "customer-account-testing-example-ext",
3+
"private": true,
4+
"version": "1.0.0",
5+
"license": "UNLICENSED",
6+
"dependencies": {
7+
"preact": "^10.10.x",
8+
"@preact/signals": "^2.3.x",
9+
"@shopify/ui-extensions": "file:../../../../packages/ui-extensions"
10+
}
11+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import '@shopify/ui-extensions';
2+
3+
//@ts-ignore
4+
declare module './src/OrderStatusBlock.jsx' {
5+
const shopify: import('@shopify/ui-extensions/customer-account.order-status.block.render').Api;
6+
const globalThis: { shopify: typeof shopify };
7+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Learn more about configuring your Customer account UI extension:
2+
# https://shopify.dev/api/customer-account-ui-extensions/unstable/configuration
3+
4+
# The version of APIs your extension will receive. Learn more:
5+
# https://shopify.dev/docs/api/usage/versioning
6+
api_version = "2026-01"
7+
8+
[[extensions]]
9+
name = "customer-account-testing-example"
10+
handle = "customer-account-testing-example"
11+
type = "ui_extension"
12+
uid = "9ebaa5f0-a0d8-25bf-6290-c55f579e4dfac7c7fcd2"
13+
14+
[[extensions.targeting]]
15+
module = "./src/OrderStatusBlock.jsx"
16+
target = "customer-account.order-status.block.render"
17+
18+
[extensions.capabilities]
19+
api_access = true
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import '@shopify/ui-extensions/preact';
2+
import {render} from 'preact';
3+
4+
export default async () => {
5+
render(<Extension />, document.body);
6+
};
7+
8+
function Extension() {
9+
const order = shopify.order.value;
10+
const totalAmount = shopify.cost.totalAmount.value;
11+
12+
return (
13+
<s-banner>
14+
<s-heading>{order ? `Order ${order.name}` : 'Order Summary'}</s-heading>
15+
<s-text>
16+
Total: {totalAmount.amount} {totalAmount.currencyCode}
17+
</s-text>
18+
</s-banner>
19+
);
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/// <reference types="@shopify/ui-extensions/customer-account.order-status.block.render" />
2+
// ^ This defines types for custom Shopify elements supported by the target.
3+
4+
import {expect, test, beforeEach, afterEach} from 'vitest';
5+
import {getExtension} from '@shopify/ui-extensions-tester';
6+
7+
const extension = getExtension(
8+
'customer-account.order-status.block.render',
9+
);
10+
11+
beforeEach(() => {
12+
extension.setUp();
13+
});
14+
15+
afterEach(() => {
16+
extension.tearDown();
17+
});
18+
19+
test('shows a generic heading when there is no order', async () => {
20+
extension.shopify.order.value = undefined;
21+
22+
await extension.render();
23+
const heading = extension.querySelector('s-heading')!;
24+
expect(heading.textContent).toEqual('Order Summary');
25+
});
26+
27+
test('shows the order name in the heading', async () => {
28+
extension.shopify.order.value.name = '#1042';
29+
30+
await extension.render();
31+
const heading = extension.querySelector('s-heading')!;
32+
expect(heading.textContent).toEqual('Order #1042');
33+
});
34+
35+
test('shows the total amount with currency', async () => {
36+
await extension.render();
37+
const texts = extension.querySelectorAll('s-text');
38+
const content = texts.map((el) => el.textContent).join('');
39+
expect(content).toContain('0');
40+
expect(content).toContain('USD');
41+
});

0 commit comments

Comments
 (0)