@curless/shopify-storefront 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/card-contract.test.d.ts +2 -0
- package/dist/__tests__/card-contract.test.d.ts.map +1 -0
- package/dist/__tests__/card-contract.test.js +22 -0
- package/dist/__tests__/card-contract.test.js.map +1 -0
- package/dist/__tests__/catalog-registry.test.d.ts +2 -0
- package/dist/__tests__/catalog-registry.test.d.ts.map +1 -0
- package/dist/__tests__/catalog-registry.test.js +109 -0
- package/dist/__tests__/catalog-registry.test.js.map +1 -0
- package/dist/__tests__/challenge.test.d.ts +2 -0
- package/dist/__tests__/challenge.test.d.ts.map +1 -0
- package/dist/__tests__/challenge.test.js +46 -0
- package/dist/__tests__/challenge.test.js.map +1 -0
- package/dist/__tests__/config.test.d.ts +2 -0
- package/dist/__tests__/config.test.d.ts.map +1 -0
- package/dist/__tests__/config.test.js +123 -0
- package/dist/__tests__/config.test.js.map +1 -0
- package/dist/__tests__/connection-state.test.d.ts +2 -0
- package/dist/__tests__/connection-state.test.d.ts.map +1 -0
- package/dist/__tests__/connection-state.test.js +40 -0
- package/dist/__tests__/connection-state.test.js.map +1 -0
- package/dist/__tests__/multi-token-store.test.d.ts +2 -0
- package/dist/__tests__/multi-token-store.test.d.ts.map +1 -0
- package/dist/__tests__/multi-token-store.test.js +89 -0
- package/dist/__tests__/multi-token-store.test.js.map +1 -0
- package/dist/__tests__/oauth.test.d.ts +2 -0
- package/dist/__tests__/oauth.test.d.ts.map +1 -0
- package/dist/__tests__/oauth.test.js +112 -0
- package/dist/__tests__/oauth.test.js.map +1 -0
- package/dist/__tests__/output-schema.test.d.ts +2 -0
- package/dist/__tests__/output-schema.test.d.ts.map +1 -0
- package/dist/__tests__/output-schema.test.js +112 -0
- package/dist/__tests__/output-schema.test.js.map +1 -0
- package/dist/__tests__/ping.test.d.ts +2 -0
- package/dist/__tests__/ping.test.d.ts.map +1 -0
- package/dist/__tests__/ping.test.js +22 -0
- package/dist/__tests__/ping.test.js.map +1 -0
- package/dist/__tests__/rate-limit.test.d.ts +2 -0
- package/dist/__tests__/rate-limit.test.d.ts.map +1 -0
- package/dist/__tests__/rate-limit.test.js +46 -0
- package/dist/__tests__/rate-limit.test.js.map +1 -0
- package/dist/__tests__/stock.test.d.ts +2 -0
- package/dist/__tests__/stock.test.d.ts.map +1 -0
- package/dist/__tests__/stock.test.js +109 -0
- package/dist/__tests__/stock.test.js.map +1 -0
- package/dist/__tests__/tenant.test.d.ts +2 -0
- package/dist/__tests__/tenant.test.d.ts.map +1 -0
- package/dist/__tests__/tenant.test.js +105 -0
- package/dist/__tests__/tenant.test.js.map +1 -0
- package/dist/__tests__/tools.test.d.ts +2 -0
- package/dist/__tests__/tools.test.d.ts.map +1 -0
- package/dist/__tests__/tools.test.js +543 -0
- package/dist/__tests__/tools.test.js.map +1 -0
- package/dist/__tests__/upstream-cap.test.d.ts +2 -0
- package/dist/__tests__/upstream-cap.test.d.ts.map +1 -0
- package/dist/__tests__/upstream-cap.test.js +78 -0
- package/dist/__tests__/upstream-cap.test.js.map +1 -0
- package/dist/__tests__/webhooks.test.d.ts +2 -0
- package/dist/__tests__/webhooks.test.d.ts.map +1 -0
- package/dist/__tests__/webhooks.test.js +88 -0
- package/dist/__tests__/webhooks.test.js.map +1 -0
- package/dist/card.generated.d.ts +2 -0
- package/dist/card.generated.d.ts.map +1 -0
- package/dist/card.generated.js +6 -0
- package/dist/card.generated.js.map +1 -0
- package/dist/catalog-registry.d.ts +44 -0
- package/dist/catalog-registry.d.ts.map +1 -0
- package/dist/catalog-registry.js +105 -0
- package/dist/catalog-registry.js.map +1 -0
- package/dist/catalog.d.ts +51 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +189 -0
- package/dist/catalog.js.map +1 -0
- package/dist/challenge.d.ts +11 -0
- package/dist/challenge.d.ts.map +1 -0
- package/dist/challenge.js +36 -0
- package/dist/challenge.js.map +1 -0
- package/dist/config.d.ts +141 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +65 -0
- package/dist/config.js.map +1 -0
- package/dist/connection.d.ts +10 -0
- package/dist/connection.d.ts.map +1 -0
- package/dist/connection.js +21 -0
- package/dist/connection.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +974 -0
- package/dist/index.js.map +1 -0
- package/dist/legal.d.ts +52 -0
- package/dist/legal.d.ts.map +1 -0
- package/dist/legal.js +139 -0
- package/dist/legal.js.map +1 -0
- package/dist/load-config.d.ts +11 -0
- package/dist/load-config.d.ts.map +1 -0
- package/dist/load-config.js +23 -0
- package/dist/load-config.js.map +1 -0
- package/dist/multi-token-store.d.ts +18 -0
- package/dist/multi-token-store.d.ts.map +1 -0
- package/dist/multi-token-store.js +95 -0
- package/dist/multi-token-store.js.map +1 -0
- package/dist/oauth.d.ts +20 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +123 -0
- package/dist/oauth.js.map +1 -0
- package/dist/rate-limit.d.ts +15 -0
- package/dist/rate-limit.d.ts.map +1 -0
- package/dist/rate-limit.js +56 -0
- package/dist/rate-limit.js.map +1 -0
- package/dist/stock.d.ts +39 -0
- package/dist/stock.d.ts.map +1 -0
- package/dist/stock.js +77 -0
- package/dist/stock.js.map +1 -0
- package/dist/tenant.d.ts +69 -0
- package/dist/tenant.d.ts.map +1 -0
- package/dist/tenant.js +68 -0
- package/dist/tenant.js.map +1 -0
- package/dist/token-store.d.ts +16 -0
- package/dist/token-store.d.ts.map +1 -0
- package/dist/token-store.js +47 -0
- package/dist/token-store.js.map +1 -0
- package/dist/tools.d.ts +201 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +779 -0
- package/dist/tools.js.map +1 -0
- package/dist/webhooks.d.ts +30 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +69 -0
- package/dist/webhooks.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,543 @@
|
|
|
1
|
+
// The four tools, against a stub shaped like the REAL Moody store — which is
|
|
2
|
+
// not what I assumed before seeing it:
|
|
3
|
+
//
|
|
4
|
+
// • The colour is part of the product NAME ("Matcha Green"), not an option.
|
|
5
|
+
// • A pair has TWO prescription options, Left and Right, because a buyer's
|
|
6
|
+
// eyes are usually different. 26 values each, 100+ variants.
|
|
7
|
+
// • The same lens also ships as -L and -R singles, one option each.
|
|
8
|
+
//
|
|
9
|
+
// So "how many answers do I need from the buyer" is a property of the product,
|
|
10
|
+
// and getting it wrong means either an unanswerable question or a lens someone
|
|
11
|
+
// cannot wear.
|
|
12
|
+
import { toolNames } from '../config.js';
|
|
13
|
+
// Same names the live connector uses, so these exercises stay a check on it.
|
|
14
|
+
const NAMES = toolNames({
|
|
15
|
+
id: 'moody',
|
|
16
|
+
server: { name: 'moody-lenses', title: 'Moody Lenses' },
|
|
17
|
+
naming: { prefix: 'moody', noun: 'lens', nounPlural: 'lenses' },
|
|
18
|
+
shopify: { mode: 'env' },
|
|
19
|
+
urls: { appUrl: 'https://shopify.curless.ai/moody' },
|
|
20
|
+
legal: {},
|
|
21
|
+
});
|
|
22
|
+
import { describe, expect, test, vi } from 'vitest';
|
|
23
|
+
import { Catalog } from '../catalog.js';
|
|
24
|
+
import { callTool } from '../tools.js';
|
|
25
|
+
const SHOPIFY = { shopDomain: 'rqxbft-fw.myshopify.com', adminToken: 'shpat_test' };
|
|
26
|
+
const POWERS = ['0.00', '-1.00', '-2.00'];
|
|
27
|
+
const variant = (id, opts, price = '27.99', available = true) => ({
|
|
28
|
+
id: `gid://shopify/ProductVariant/${id}`,
|
|
29
|
+
sku: `SKU-${id}`,
|
|
30
|
+
title: Object.values(opts).join(' / '),
|
|
31
|
+
price,
|
|
32
|
+
compareAtPrice: null,
|
|
33
|
+
availableForSale: available,
|
|
34
|
+
selectedOptions: Object.entries(opts).map(([name, value]) => ({ name, value })),
|
|
35
|
+
image: null,
|
|
36
|
+
});
|
|
37
|
+
const product = (id, handle, title, options, variants, tags = []) => ({
|
|
38
|
+
id: `gid://shopify/Product/${id}`,
|
|
39
|
+
handle,
|
|
40
|
+
title,
|
|
41
|
+
description: '',
|
|
42
|
+
productType: '',
|
|
43
|
+
tags,
|
|
44
|
+
status: 'ACTIVE',
|
|
45
|
+
featuredImage: null,
|
|
46
|
+
media: { nodes: [] },
|
|
47
|
+
options: options.map((o) => ({ name: o.name, optionValues: o.values.map((v) => ({ name: v })) })),
|
|
48
|
+
variants: { pageInfo: { hasNextPage: false }, nodes: variants },
|
|
49
|
+
});
|
|
50
|
+
// A pair: Left × Right. Every combination is its own variant, as at Moody.
|
|
51
|
+
const pairVariants = POWERS.flatMap((l, i) => POWERS.map((r, j) => variant(`${100 + i * 10 + j}`, { Left: l, Right: r })));
|
|
52
|
+
const SHOP = { currencyCode: 'USD', primaryDomain: { url: 'https://moodycosmetics.com' } };
|
|
53
|
+
const PRODUCTS = {
|
|
54
|
+
data: {
|
|
55
|
+
shop: SHOP,
|
|
56
|
+
products: {
|
|
57
|
+
pageInfo: { hasNextPage: false, endCursor: null },
|
|
58
|
+
nodes: [
|
|
59
|
+
product('900', 'matcha-green', 'Matcha Green', [
|
|
60
|
+
{ name: 'Left', values: POWERS },
|
|
61
|
+
{ name: 'Right', values: POWERS },
|
|
62
|
+
], pairVariants, ['6 Months', '14.2', '38%']),
|
|
63
|
+
product('901', 'matcha-green-l', 'Matcha Green-L', [{ name: 'Left', values: POWERS }], POWERS.map((l, i) => variant(`${200 + i}`, { Left: l })), ['6 Months']),
|
|
64
|
+
product('902', 'oud-wood', 'Breathe+ Oud Wood', [{ name: 'Diopter', values: POWERS }], POWERS.map((d, i) => variant(`${300 + i}`, { Diopter: d }, '29.99')), ['1 Day']),
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
// One stub for the whole store: it answers the products query, the per-product
|
|
70
|
+
// variants query, and the order lookup, choosing by what the query asks for.
|
|
71
|
+
// Variants are fetched lazily now, so a stub that only covered the catalogue
|
|
72
|
+
// would let a checkout reach the real network.
|
|
73
|
+
const shopStub = (payload, orders) => vi.fn(async (_url, init) => {
|
|
74
|
+
const body = JSON.parse(String(init?.body ?? '{}'));
|
|
75
|
+
const q = body.query ?? '';
|
|
76
|
+
let data;
|
|
77
|
+
if (q.includes('productByHandle')) {
|
|
78
|
+
const node = payload.data.products.nodes.find((n) => n.handle === body.variables?.handle);
|
|
79
|
+
data = {
|
|
80
|
+
shop: SHOP,
|
|
81
|
+
productByHandle: node
|
|
82
|
+
? {
|
|
83
|
+
variants: {
|
|
84
|
+
pageInfo: { hasNextPage: false, endCursor: null },
|
|
85
|
+
nodes: node.variants.nodes,
|
|
86
|
+
},
|
|
87
|
+
}
|
|
88
|
+
: null,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
else if (q.includes('automaticDiscountNodes')) {
|
|
92
|
+
data = { shop: SHOP, automaticDiscountNodes: { nodes: [] } };
|
|
93
|
+
}
|
|
94
|
+
else if (q.includes('orders(')) {
|
|
95
|
+
data = orders?.data ?? { orders: { nodes: [] } };
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
data = {
|
|
99
|
+
shop: payload.data.shop,
|
|
100
|
+
products: {
|
|
101
|
+
pageInfo: payload.data.products.pageInfo,
|
|
102
|
+
// The real bulk read asks for no variants; strip them so the test
|
|
103
|
+
// cannot accidentally depend on data production does not have.
|
|
104
|
+
nodes: payload.data.products.nodes.map(({ variants, ...rest }) => ({
|
|
105
|
+
...rest,
|
|
106
|
+
priceRangeV2: {
|
|
107
|
+
minVariantPrice: { amount: variants.nodes[0]?.price ?? '0.00', currencyCode: 'USD' },
|
|
108
|
+
},
|
|
109
|
+
})),
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return new Response(JSON.stringify({ data }), {
|
|
114
|
+
status: 200,
|
|
115
|
+
headers: { 'content-type': 'application/json' },
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
// Runs `fn` with the store stubbed in — including the lazy variant fetches a
|
|
119
|
+
// checkout makes.
|
|
120
|
+
const withStore = async (fn, payload = PRODUCTS, orders) => {
|
|
121
|
+
const real = globalThis.fetch;
|
|
122
|
+
globalThis.fetch = shopStub(payload, orders);
|
|
123
|
+
try {
|
|
124
|
+
const catalog = new Catalog(async () => SHOPIFY, () => { });
|
|
125
|
+
await catalog.refresh();
|
|
126
|
+
return await fn({
|
|
127
|
+
catalog,
|
|
128
|
+
shopify: SHOPIFY,
|
|
129
|
+
merchantName: 'Moody Lenses',
|
|
130
|
+
tools: NAMES,
|
|
131
|
+
vocab: { noun: 'lens', nounPlural: 'lenses' },
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
finally {
|
|
135
|
+
globalThis.fetch = real;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
describe('browsing', () => {
|
|
139
|
+
test('says whether a lens is a pair or a single, which decides what to ask', () => withStore(async (deps) => {
|
|
140
|
+
const sc = (await callTool(deps, 'list_moody_lenses', {})).structured;
|
|
141
|
+
expect(sc.products.map((p) => [p.name, p.eyes])).toEqual([
|
|
142
|
+
['Matcha Green', 'pair'],
|
|
143
|
+
['Matcha Green-L', 'single'],
|
|
144
|
+
['Breathe+ Oud Wood', 'single'],
|
|
145
|
+
]);
|
|
146
|
+
expect(sc.products[0]?.choices.map((c) => c.name)).toEqual(['Left', 'Right']);
|
|
147
|
+
}));
|
|
148
|
+
// A buyer who wants reviews or a size guide should land on Moody's own page,
|
|
149
|
+
// not on a *.myshopify.com address they have never heard of.
|
|
150
|
+
test('every lens carries a link to the merchant’s own product page', () => withStore(async (deps) => {
|
|
151
|
+
const sc = (await callTool(deps, 'list_moody_lenses', {})).structured;
|
|
152
|
+
const p = sc.products[0];
|
|
153
|
+
expect(p?.url).toBe(`https://moodycosmetics.com/products/${p?.handle}`);
|
|
154
|
+
}));
|
|
155
|
+
test('colour is searched through the NAME, because that is where it lives', () => withStore(async (deps) => {
|
|
156
|
+
// There is no colour option at this store; "green" only matches text.
|
|
157
|
+
const green = (await callTool(deps, 'list_moody_lenses', { query: 'green' })).structured;
|
|
158
|
+
expect(green.products).toHaveLength(2);
|
|
159
|
+
const byTag = (await callTool(deps, 'list_moody_lenses', { query: '1 Day' })).structured;
|
|
160
|
+
expect(byTag.products[0]?.name).toBe('Breathe+ Oud Wood');
|
|
161
|
+
}));
|
|
162
|
+
// A naive substring match answered "brown lenses" and "棕色系" with nothing, so
|
|
163
|
+
// the assistant searched again, and again — and every retry drew ANOTHER
|
|
164
|
+
// storefront card in front of the buyer. Three cards stacked up for one
|
|
165
|
+
// question. The search has to answer the first time.
|
|
166
|
+
test('a colour family finds lenses whose NAME carries the colour', () => withStore(async (deps) => {
|
|
167
|
+
const zh = (await callTool(deps, 'list_moody_lenses', { query: '绿色系' })).structured;
|
|
168
|
+
expect(zh.products.map((p) => p.name)).toContain('Matcha Green');
|
|
169
|
+
expect(zh.relaxedFrom, 'labelled as broader than asked').toBe('绿色系');
|
|
170
|
+
}));
|
|
171
|
+
// At the real store "Matcha Green" describes itself as having "hojicha-brown
|
|
172
|
+
// iris details", so a search for brown matches its DESCRIPTION — and unranked,
|
|
173
|
+
// a green lens led the first row for a buyer who asked for brown. Mirrored
|
|
174
|
+
// here the other way round, which the fixture can express: a lens that only
|
|
175
|
+
// MENTIONS green must not outrank the ones named for it.
|
|
176
|
+
test('a name match outranks a description that merely mentions the colour', () => {
|
|
177
|
+
const payload = structuredClone(PRODUCTS);
|
|
178
|
+
const oud = payload.data.products.nodes[2];
|
|
179
|
+
if (!oud)
|
|
180
|
+
throw new Error('fixture changed');
|
|
181
|
+
oud.description = 'warm wood tones over a deep green limbal ring';
|
|
182
|
+
return withStore(async (deps) => {
|
|
183
|
+
const sc = (await callTool(deps, 'list_moody_lenses', { query: '绿色系' })).structured;
|
|
184
|
+
const names = sc.products.map((p) => p.name);
|
|
185
|
+
expect(names[0]).toBe('Matcha Green');
|
|
186
|
+
expect(names.indexOf('Breathe+ Oud Wood')).toBeGreaterThan(names.indexOf('Matcha Green-L'));
|
|
187
|
+
}, payload);
|
|
188
|
+
});
|
|
189
|
+
// The SAME ranking, on the exact-match path — which is the one the test above
|
|
190
|
+
// never touches, because a CJK colour family always falls through to the
|
|
191
|
+
// relaxed branch. An English colour word does not: at the real store "grey"
|
|
192
|
+
// appears in the descriptions of several brown lenses, so it matched exactly,
|
|
193
|
+
// skipped the ranking entirely, and led a search for grey with Oolong Brown
|
|
194
|
+
// and Barley Tea. One word is the common case, not the corner — the fix had
|
|
195
|
+
// been applied to the branch a buyer rarely reaches.
|
|
196
|
+
//
|
|
197
|
+
// `relaxedFrom` is asserted undefined to pin WHICH branch this covers. Without
|
|
198
|
+
// it the test would quietly start passing through the relaxed path the day the
|
|
199
|
+
// matching changes, and stop testing the thing it was written for.
|
|
200
|
+
test('a name match outranks a description on the exact-match path too', () => {
|
|
201
|
+
const payload = structuredClone(PRODUCTS);
|
|
202
|
+
const matcha = payload.data.products.nodes[0];
|
|
203
|
+
if (!matcha)
|
|
204
|
+
throw new Error('fixture changed');
|
|
205
|
+
matcha.description = 'soft wood-toned edges over a green iris';
|
|
206
|
+
return withStore(async (deps) => {
|
|
207
|
+
const sc = (await callTool(deps, 'list_moody_lenses', { query: 'wood' })).structured;
|
|
208
|
+
expect(sc.relaxedFrom, 'exact path, not the relaxed one').toBeUndefined();
|
|
209
|
+
expect(sc.products.map((p) => p.name)[0]).toBe('Breathe+ Oud Wood');
|
|
210
|
+
}, payload);
|
|
211
|
+
});
|
|
212
|
+
// The picker offers families as "灰/蓝色系", so the query arrives split by a
|
|
213
|
+
// slash and suffixed. Enumerating every suffix by hand is how 绿色系 and 棕色系
|
|
214
|
+
// got mapped while 蓝色系 quietly fell through to all 382 products.
|
|
215
|
+
test('a colour survives the picker’s own phrasing — slashes and 色系 suffixes', () => withStore(async (deps) => {
|
|
216
|
+
const bare = (await callTool(deps, 'list_moody_lenses', { query: '绿' })).structured;
|
|
217
|
+
for (const q of ['绿色', '绿色系', '黄/绿色系', '绿色系(自然)', '绿色系 (natural)']) {
|
|
218
|
+
const sc = (await callTool(deps, 'list_moody_lenses', { query: q })).structured;
|
|
219
|
+
expect(sc.total, `${q} narrowed the shelf`).toBe(bare.total);
|
|
220
|
+
expect(sc.products[0]?.name, q).toBe('Matcha Green');
|
|
221
|
+
}
|
|
222
|
+
}));
|
|
223
|
+
test('a phrase falls back to its words rather than to nothing', () => withStore(async (deps) => {
|
|
224
|
+
const sc = (await callTool(deps, 'list_moody_lenses', { query: 'oud wood lenses' }))
|
|
225
|
+
.structured;
|
|
226
|
+
expect(sc.products.map((p) => p.name)).toContain('Breathe+ Oud Wood');
|
|
227
|
+
}));
|
|
228
|
+
// An empty card is a dead end — the buyer's next move is to narrow the list,
|
|
229
|
+
// and they cannot narrow nothing. It is also what made the assistant retry.
|
|
230
|
+
test('an unmatchable query shows the shelf and tells the assistant not to retry', () => withStore(async (deps) => {
|
|
231
|
+
const res = await callTool(deps, 'list_moody_lenses', { query: 'zzzz' });
|
|
232
|
+
const sc = res.structured;
|
|
233
|
+
expect(sc.products.length).toBeGreaterThan(0);
|
|
234
|
+
expect(sc.relaxedFrom).toBe('zzzz');
|
|
235
|
+
expect(res.text).toMatch(/Do NOT search again/);
|
|
236
|
+
}));
|
|
237
|
+
// Real store, 2026-08-04: all 676 Matcha Green combinations report out of
|
|
238
|
+
// stock through the first 250, and the stocked ones sit deep in the tail. A
|
|
239
|
+
// payload capped at the FIRST 30 is thirty things nobody can buy — and an
|
|
240
|
+
// assistant reading it concludes the store is empty, or worse, reads the
|
|
241
|
+
// option lists instead and names a prescription confidently.
|
|
242
|
+
test('the stocked variants come first, and the prose says how few there are', () => {
|
|
243
|
+
const payload = structuredClone(PRODUCTS);
|
|
244
|
+
const pair = payload.data.products.nodes[0];
|
|
245
|
+
if (!pair)
|
|
246
|
+
throw new Error('fixture changed');
|
|
247
|
+
for (const v of pair.variants.nodes)
|
|
248
|
+
v.availableForSale = false;
|
|
249
|
+
const last = pair.variants.nodes.at(-1);
|
|
250
|
+
if (!last)
|
|
251
|
+
throw new Error('fixture changed');
|
|
252
|
+
last.availableForSale = true;
|
|
253
|
+
return withStore(async (deps) => {
|
|
254
|
+
const res = await callTool(deps, 'get_moody_lens', { product: 'Matcha Green' });
|
|
255
|
+
const p = res.structured.product;
|
|
256
|
+
expect(p.inStockCount).toBe(1);
|
|
257
|
+
expect(p.variantCount).toBe(9);
|
|
258
|
+
expect(p.variants[0]?.available, 'the one buyable variant leads').toBe(true);
|
|
259
|
+
expect(res.text).toContain('In stock: 1 of 9');
|
|
260
|
+
}, payload);
|
|
261
|
+
});
|
|
262
|
+
// The picker filters its chips on this. If it does not arrive, the buyer is
|
|
263
|
+
// back to choosing from 26x26 and being told "sold out" almost every time.
|
|
264
|
+
test('the buyable combinations ship as option maps the picker can filter on', () => {
|
|
265
|
+
const payload = structuredClone(PRODUCTS);
|
|
266
|
+
const pair = payload.data.products.nodes[0];
|
|
267
|
+
if (!pair)
|
|
268
|
+
throw new Error('fixture changed');
|
|
269
|
+
for (const v of pair.variants.nodes)
|
|
270
|
+
v.availableForSale = false;
|
|
271
|
+
// 0.00/-2.00 and -2.00/0.00 — deliberately NOT the same left eye, so a test
|
|
272
|
+
// that ignored the pairing would still look right.
|
|
273
|
+
const [a, b] = [pair.variants.nodes[2], pair.variants.nodes[6]];
|
|
274
|
+
if (!a || !b)
|
|
275
|
+
throw new Error('fixture changed');
|
|
276
|
+
a.availableForSale = true;
|
|
277
|
+
b.availableForSale = true;
|
|
278
|
+
return withStore(async (deps) => {
|
|
279
|
+
const res = await callTool(deps, 'get_moody_lens', { product: 'Matcha Green' });
|
|
280
|
+
const p = res.structured.product;
|
|
281
|
+
expect(p.inStock).toEqual([
|
|
282
|
+
{ Left: '0.00', Right: '-2.00' },
|
|
283
|
+
{ Left: '-2.00', Right: '0.00' },
|
|
284
|
+
]);
|
|
285
|
+
expect(p.inStockTruncated).toBe(false);
|
|
286
|
+
}, payload);
|
|
287
|
+
});
|
|
288
|
+
// Reached when an assistant calls checkout straight from the conversation. The
|
|
289
|
+
// picker opens on THIS payload, so it needs the same list.
|
|
290
|
+
test('needs-options carries the buyable combinations too', () => withStore(async (deps) => {
|
|
291
|
+
const res = await callTool(deps, 'create_moody_checkout', {
|
|
292
|
+
product: 'Matcha Green',
|
|
293
|
+
options: { Left: '-2.00' },
|
|
294
|
+
});
|
|
295
|
+
const sc = res.structured;
|
|
296
|
+
expect(sc.view).toBe('needs-options');
|
|
297
|
+
expect(sc.inStock.length).toBe(9);
|
|
298
|
+
}));
|
|
299
|
+
test('a product with nothing in stock says so outright', () => {
|
|
300
|
+
const payload = structuredClone(PRODUCTS);
|
|
301
|
+
const pair = payload.data.products.nodes[0];
|
|
302
|
+
if (!pair)
|
|
303
|
+
throw new Error('fixture changed');
|
|
304
|
+
for (const v of pair.variants.nodes)
|
|
305
|
+
v.availableForSale = false;
|
|
306
|
+
return withStore(async (deps) => {
|
|
307
|
+
const res = await callTool(deps, 'get_moody_lens', { product: 'Matcha Green' });
|
|
308
|
+
expect(res.structured.product.inStockCount).toBe(0);
|
|
309
|
+
expect(res.text).toContain('OUT OF STOCK');
|
|
310
|
+
}, payload);
|
|
311
|
+
});
|
|
312
|
+
test('an unloaded catalog says so instead of reporting an empty store', async () => {
|
|
313
|
+
const catalog = new Catalog(async () => SHOPIFY, () => { });
|
|
314
|
+
const res = await callTool({
|
|
315
|
+
catalog,
|
|
316
|
+
shopify: SHOPIFY,
|
|
317
|
+
merchantName: 'Moody Lenses',
|
|
318
|
+
tools: NAMES,
|
|
319
|
+
vocab: { noun: 'lens', nounPlural: 'lenses' },
|
|
320
|
+
}, 'list_moody_lenses', {});
|
|
321
|
+
expect(res.structured.error).toBe('catalog-unavailable');
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
describe('checkout', () => {
|
|
325
|
+
test('both eyes given → the link to Moody’s own checkout', () => withStore(async (deps) => {
|
|
326
|
+
const sc = (await callTool(deps, 'create_moody_checkout', {
|
|
327
|
+
product: 'Matcha Green',
|
|
328
|
+
options: { Left: '-2.00', Right: '0.00' },
|
|
329
|
+
})).structured;
|
|
330
|
+
expect(sc.view).toBe('checkout');
|
|
331
|
+
const url = new URL(sc.checkoutUrl);
|
|
332
|
+
// The SAME host as the product page above, and for the same reason. This
|
|
333
|
+
// assertion used to read rqxbft-fw.myshopify.com while the test forty
|
|
334
|
+
// lines up already said a buyer should not be sent there — the link that
|
|
335
|
+
// mattered most was the one still pointing at the handle.
|
|
336
|
+
expect(url.host + url.pathname).toBe('moodycosmetics.com/cart/120:1');
|
|
337
|
+
// Where the order came from. The order's Channel will say Online Store
|
|
338
|
+
// whatever we do, so this attribute is the only trace it carries.
|
|
339
|
+
expect(url.searchParams.get('attributes[Source]')).toBe('Curless');
|
|
340
|
+
}));
|
|
341
|
+
// A shop that has never set a primary domain still has to be able to sell.
|
|
342
|
+
// The myshopify host is the fallback, not an error — preferring the nicer
|
|
343
|
+
// link must not be able to produce https:///cart/ on the one path that takes
|
|
344
|
+
// money.
|
|
345
|
+
test('no primary domain → still a working link, on the myshopify host', () => {
|
|
346
|
+
const payload = structuredClone(PRODUCTS);
|
|
347
|
+
payload.data.shop = { currencyCode: 'USD' };
|
|
348
|
+
return withStore(async (deps) => {
|
|
349
|
+
const sc = (await callTool(deps, 'create_moody_checkout', {
|
|
350
|
+
product: 'Matcha Green',
|
|
351
|
+
options: { Left: '-2.00', Right: '0.00' },
|
|
352
|
+
})).structured;
|
|
353
|
+
expect(sc.view).toBe('checkout');
|
|
354
|
+
expect(new URL(sc.checkoutUrl).host).toBe('rqxbft-fw.myshopify.com');
|
|
355
|
+
}, payload);
|
|
356
|
+
});
|
|
357
|
+
// THE one that matters. Two eyes, usually different prescriptions. Filling
|
|
358
|
+
// the second in from the first is how someone ends up with a lens they
|
|
359
|
+
// cannot wear — and it looks like a helpful assistant right up until it ships.
|
|
360
|
+
test('one eye given → asks for the other, and names which', () => withStore(async (deps) => {
|
|
361
|
+
const res = await callTool(deps, 'create_moody_checkout', {
|
|
362
|
+
product: 'Matcha Green',
|
|
363
|
+
options: { Left: '-2.00' },
|
|
364
|
+
});
|
|
365
|
+
const sc = res.structured;
|
|
366
|
+
expect(sc.view).toBe('needs-options');
|
|
367
|
+
expect(sc.eyes).toBe('pair');
|
|
368
|
+
expect(res.text).toContain('PAIR');
|
|
369
|
+
expect(res.text, 'says which one is still missing').toMatch(/Right.*still needed/);
|
|
370
|
+
expect(res.text).toMatch(/Never assume one answer carries to another option/i);
|
|
371
|
+
}));
|
|
372
|
+
// The card pre-selects from `given` and the assistant reads the prose. Both
|
|
373
|
+
// have to agree that "-2.0" against a "-2.00" option is ANSWERED: if they do
|
|
374
|
+
// not, the buyer is asked for a prescription they already gave, or sees a live
|
|
375
|
+
// Buy button over a question with nothing selected.
|
|
376
|
+
test('a paraphrased eye comes back answered, in the store’s own words', () => withStore(async (deps) => {
|
|
377
|
+
const res = await callTool(deps, 'create_moody_checkout', {
|
|
378
|
+
product: 'Matcha Green',
|
|
379
|
+
options: { left: '−2.0' }, // lowercase name, unicode minus, one decimal
|
|
380
|
+
});
|
|
381
|
+
const sc = res.structured;
|
|
382
|
+
expect(sc.given).toEqual({ Left: '-2.00' });
|
|
383
|
+
expect(POWERS, 'a value the picker can find among the chips it draws').toContain(sc.given.Left);
|
|
384
|
+
expect(res.text).toContain('Left (given: -2.00)');
|
|
385
|
+
expect(res.text).toMatch(/Right.*still needed/);
|
|
386
|
+
}));
|
|
387
|
+
test('a single-eye product needs exactly one, and gets a link', () => withStore(async (deps) => {
|
|
388
|
+
const sc = (await callTool(deps, 'create_moody_checkout', {
|
|
389
|
+
product: 'Matcha Green-L',
|
|
390
|
+
options: { Left: '-1.00' },
|
|
391
|
+
})).structured;
|
|
392
|
+
expect(sc.view).toBe('checkout');
|
|
393
|
+
expect(sc.checkoutUrl).toContain('/cart/201:1');
|
|
394
|
+
}));
|
|
395
|
+
test('a prescription the store does not carry is not rounded to a near one', () => withStore(async (deps) => {
|
|
396
|
+
const res = await callTool(deps, 'create_moody_checkout', {
|
|
397
|
+
product: 'Breathe+ Oud Wood',
|
|
398
|
+
options: { Diopter: '-1.75' },
|
|
399
|
+
});
|
|
400
|
+
expect(res.structured.view).toBe('needs-options');
|
|
401
|
+
}));
|
|
402
|
+
test('an out-of-stock variant is refused, not linked', () => {
|
|
403
|
+
const payload = structuredClone(PRODUCTS);
|
|
404
|
+
const node = payload.data.products.nodes[2]?.variants.nodes[0];
|
|
405
|
+
if (!node)
|
|
406
|
+
throw new Error('fixture changed');
|
|
407
|
+
node.availableForSale = false;
|
|
408
|
+
return withStore(async (deps) => {
|
|
409
|
+
const res = await callTool(deps, 'create_moody_checkout', {
|
|
410
|
+
product: 'Breathe+ Oud Wood',
|
|
411
|
+
options: { Diopter: '0.00' },
|
|
412
|
+
});
|
|
413
|
+
expect(res.structured.view).toBe('out-of-stock');
|
|
414
|
+
}, payload);
|
|
415
|
+
});
|
|
416
|
+
});
|
|
417
|
+
describe('order lookup', () => {
|
|
418
|
+
const ORDER = {
|
|
419
|
+
data: {
|
|
420
|
+
orders: {
|
|
421
|
+
nodes: [
|
|
422
|
+
{
|
|
423
|
+
name: '#1052',
|
|
424
|
+
createdAt: '2026-08-04T02:00:00Z',
|
|
425
|
+
email: 'robin@example.com',
|
|
426
|
+
displayFinancialStatus: 'PAID',
|
|
427
|
+
displayFulfillmentStatus: 'UNFULFILLED',
|
|
428
|
+
statusPageUrl: 'https://rqxbft-fw.myshopify.com/orders/abc',
|
|
429
|
+
currentTotalPriceSet: { shopMoney: { amount: '27.99', currencyCode: 'USD' } },
|
|
430
|
+
lineItems: {
|
|
431
|
+
nodes: [
|
|
432
|
+
{
|
|
433
|
+
title: 'Matcha Green',
|
|
434
|
+
variantTitle: '-2.00 / 0.00',
|
|
435
|
+
quantity: 1,
|
|
436
|
+
originalUnitPriceSet: { shopMoney: { amount: '27.99' } },
|
|
437
|
+
image: null,
|
|
438
|
+
},
|
|
439
|
+
],
|
|
440
|
+
},
|
|
441
|
+
fulfillments: [],
|
|
442
|
+
},
|
|
443
|
+
],
|
|
444
|
+
},
|
|
445
|
+
},
|
|
446
|
+
};
|
|
447
|
+
test('the matching pair returns the order', () => withStore(async (deps) => {
|
|
448
|
+
const res = await callTool(deps, 'lookup_moody_order', {
|
|
449
|
+
orderNumber: '1052',
|
|
450
|
+
email: 'robin@example.com',
|
|
451
|
+
});
|
|
452
|
+
expect(res.structured.view).toBe('order');
|
|
453
|
+
}, PRODUCTS, ORDER));
|
|
454
|
+
// Order numbers are sequential, so the number alone is guessable. An answer
|
|
455
|
+
// that distinguished "wrong email" from "no such order" would confirm the
|
|
456
|
+
// order exists — which is half of what the asker wanted.
|
|
457
|
+
test('a stranger with the order number gets nothing, and no hint', () => withStore(async (deps) => {
|
|
458
|
+
const res = await callTool(deps, 'lookup_moody_order', {
|
|
459
|
+
orderNumber: '1052',
|
|
460
|
+
email: 'stranger@elsewhere.com',
|
|
461
|
+
});
|
|
462
|
+
expect(res.structured.view).toBe('order-not-found');
|
|
463
|
+
expect(res.text).not.toMatch(/exists|wrong email|belongs/i);
|
|
464
|
+
}, PRODUCTS, ORDER));
|
|
465
|
+
});
|
|
466
|
+
// Moody files a lens under By Style / By Color / By G.Diameter / Replacement
|
|
467
|
+
// cycle, and their tags land on exactly those axes. A flat row of the commonest
|
|
468
|
+
// tags — which is what this was — mixes a colour with a product line and a lens
|
|
469
|
+
// finish, and asks the buyer to tell them apart by eye.
|
|
470
|
+
describe('filter axes', () => {
|
|
471
|
+
const tagged = (handle, title, tags) => product(handle, handle, title, [{ name: 'Diopter', values: POWERS }], POWERS.map((d, i) => variant(`${900 + i}${handle.length}`, { Diopter: d })), tags);
|
|
472
|
+
const SHELF = {
|
|
473
|
+
data: {
|
|
474
|
+
shop: SHOP,
|
|
475
|
+
products: {
|
|
476
|
+
pageInfo: { hasNextPage: false, endCursor: null },
|
|
477
|
+
nodes: [
|
|
478
|
+
tagged('a', 'A', ['Brown', 'With Limbal ring', '1 Day', '14.2', '8.6', '55%']),
|
|
479
|
+
tagged('b', 'B', ['Brown', 'Glowy Highlight', '6 Months', '13.5', '8.7', '38%']),
|
|
480
|
+
tagged('c', 'C', ['Grey', 'With Limbal ring', '1 Day', '13.2', '8.6', '47%']),
|
|
481
|
+
tagged('d', 'D', ['Blue', 'Bold', '1 Month', '14.5', '8.6', '20%']),
|
|
482
|
+
],
|
|
483
|
+
},
|
|
484
|
+
},
|
|
485
|
+
};
|
|
486
|
+
const facetsOfShelf = async (deps) => (await callTool(deps, 'list_moody_lenses', {})).structured;
|
|
487
|
+
test('groups by the merchant’s own axes instead of one flat row', () => withStore(async (deps) => {
|
|
488
|
+
const axes = (await facetsOfShelf(deps)).facets.map((f) => f.axis);
|
|
489
|
+
expect(axes).toContain('Colour');
|
|
490
|
+
expect(axes).toContain('Style');
|
|
491
|
+
expect(axes).toContain('Cycle');
|
|
492
|
+
}, SHELF));
|
|
493
|
+
// I had been dropping these as noise along with base curve and water content.
|
|
494
|
+
// Moody offers G.Diameter as a top-level choice, bucketed — twelve bare
|
|
495
|
+
// numbers is not a filter, three buckets is.
|
|
496
|
+
test('diameter is a filter, bucketed at their own thresholds', () => withStore(async (deps) => {
|
|
497
|
+
const d = (await facetsOfShelf(deps)).facets.find((f) => f.axis === 'Diameter');
|
|
498
|
+
expect(d, 'diameter axis exists').toBeTruthy();
|
|
499
|
+
const large = d?.values.find((v) => v.label.startsWith('Large'));
|
|
500
|
+
expect(large?.tags.sort()).toEqual(['14.2', '14.5']);
|
|
501
|
+
expect(d?.values.find((v) => v.label.startsWith('Small'))?.tags).toEqual(['13.2']);
|
|
502
|
+
}, SHELF));
|
|
503
|
+
// 8.6 is a base curve and 55% is water content. They are on Moody's spec
|
|
504
|
+
// sheets and in none of their filter menus, and a buyer choosing a lens by
|
|
505
|
+
// base curve is a buyer we have confused.
|
|
506
|
+
test('base curve and water content are specs, not filters', () => withStore(async (deps) => {
|
|
507
|
+
const all = (await facetsOfShelf(deps)).facets.flatMap((f) => f.values.flatMap((v) => v.tags));
|
|
508
|
+
expect(all).not.toContain('8.6');
|
|
509
|
+
expect(all).not.toContain('55%');
|
|
510
|
+
}, SHELF));
|
|
511
|
+
// A lens is tagged with every diameter it comes in, so at the real store all
|
|
512
|
+
// 40 results offered a large size — and the old value-level rule silently
|
|
513
|
+
// dropped "Large" while keeping Medium and Small. The row then told a buyer
|
|
514
|
+
// this store has no large lenses, about the diameters it stocks most.
|
|
515
|
+
test('a value everything shares is still offered, if the axis has others', () => {
|
|
516
|
+
const all_large = structuredClone(SHELF);
|
|
517
|
+
for (const n of all_large.data.products.nodes) {
|
|
518
|
+
n.tags = [...n.tags, '14.5'];
|
|
519
|
+
}
|
|
520
|
+
return withStore(async (deps) => {
|
|
521
|
+
const d = (await facetsOfShelf(deps)).facets.find((f) => f.axis === 'Diameter');
|
|
522
|
+
const labels = d?.values.map((v) => v.label) ?? [];
|
|
523
|
+
expect(labels.some((l) => l.startsWith('Large'))).toBe(true);
|
|
524
|
+
expect(d?.values.find((v) => v.label.startsWith('Large'))?.count).toBe(4);
|
|
525
|
+
// Still worth showing, because Small tells some of them apart.
|
|
526
|
+
expect(labels.some((l) => l.startsWith('Small'))).toBe(true);
|
|
527
|
+
}, all_large);
|
|
528
|
+
});
|
|
529
|
+
// The other half of the same rule: when NOTHING distinguishes the results, the
|
|
530
|
+
// whole row goes rather than offering chips that all return everything.
|
|
531
|
+
test('an axis whose every value matches everything is dropped whole', () => {
|
|
532
|
+
const uniform = structuredClone(SHELF);
|
|
533
|
+
for (const n of uniform.data.products.nodes) {
|
|
534
|
+
n.tags = ['Brown', 'Bold', '1 Day'];
|
|
535
|
+
}
|
|
536
|
+
return withStore(async (deps) => {
|
|
537
|
+
const axes = (await facetsOfShelf(deps)).facets.map((f) => f.axis);
|
|
538
|
+
expect(axes).not.toContain('Colour');
|
|
539
|
+
expect(axes).not.toContain('Cycle');
|
|
540
|
+
}, uniform);
|
|
541
|
+
});
|
|
542
|
+
});
|
|
543
|
+
//# sourceMappingURL=tools.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.test.js","sourceRoot":"","sources":["../../src/__tests__/tools.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upstream-cap.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/upstream-cap.test.ts"],"names":[],"mappings":""}
|