fontdue-js 3.7.0 → 3.9.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/CHANGELOG.md +11 -0
- package/README.md +8 -5
- package/dist/__generated__/AddToCartBannerQuery.graphql.d.ts +1 -1
- package/dist/__generated__/AddToCartBannerQuery.graphql.js +16 -10
- package/dist/__generated__/AddToCartBanner_item.graphql.d.ts +4 -1
- package/dist/__generated__/AddToCartBanner_item.graphql.js +7 -2
- package/dist/__generated__/AddToCartBanner_order.graphql.d.ts +4 -1
- package/dist/__generated__/AddToCartBanner_order.graphql.js +6 -1
- package/dist/__generated__/BuyButtonIDQuery.graphql.d.ts +3 -3
- package/dist/__generated__/BuyButtonIDQuery.graphql.js +31 -16
- package/dist/__generated__/BuyButtonPackIDQuery.graphql.d.ts +21 -0
- package/dist/__generated__/BuyButtonPackIDQuery.graphql.js +129 -0
- package/dist/__generated__/BuyButtonPackSlugQuery.graphql.d.ts +25 -0
- package/dist/__generated__/BuyButtonPackSlugQuery.graphql.js +167 -0
- package/dist/__generated__/BuyButtonSlugQuery.graphql.d.ts +3 -3
- package/dist/__generated__/BuyButtonSlugQuery.graphql.js +45 -17
- package/dist/__generated__/BuyButton_product.graphql.d.ts +27 -0
- package/dist/__generated__/BuyButton_product.graphql.js +72 -0
- package/dist/__generated__/CartItemProduct_product.graphql.d.ts +1 -1
- package/dist/__generated__/CartItemProduct_product.graphql.js +7 -2
- package/dist/__generated__/CartOrderCompleteOrderMutation.graphql.d.ts +1 -1
- package/dist/__generated__/CartOrderCompleteOrderMutation.graphql.js +26 -20
- package/dist/__generated__/CartOrderRemoveDiscountMutation.graphql.d.ts +1 -1
- package/dist/__generated__/CartOrderRemoveDiscountMutation.graphql.js +26 -20
- package/dist/__generated__/CartOrderUpdateMutation.graphql.d.ts +1 -1
- package/dist/__generated__/CartOrderUpdateMutation.graphql.js +26 -20
- package/dist/__generated__/CartQuery.graphql.d.ts +1 -1
- package/dist/__generated__/CartQuery.graphql.js +26 -20
- package/dist/__generated__/CartStateUpdateMutation.graphql.d.ts +1 -1
- package/dist/__generated__/CartStateUpdateMutation.graphql.js +26 -20
- package/dist/__generated__/CheckoutUpdateCustomerMutation.graphql.d.ts +1 -1
- package/dist/__generated__/CheckoutUpdateCustomerMutation.graphql.js +26 -20
- package/dist/__generated__/CheckoutUpdateOrderMutation.graphql.d.ts +1 -1
- package/dist/__generated__/CheckoutUpdateOrderMutation.graphql.js +26 -20
- package/dist/__generated__/CollectionAa_Query.graphql.d.ts +1 -1
- package/dist/__generated__/CollectionAa_Query.graphql.js +20 -14
- package/dist/__generated__/CollectionAa_product.graphql.d.ts +7 -1
- package/dist/__generated__/CollectionAa_product.graphql.js +22 -16
- package/dist/__generated__/NodePasswordFormElementIDQuery.graphql.d.ts +3 -3
- package/dist/__generated__/NodePasswordFormElementIDQuery.graphql.js +9 -9
- package/dist/__generated__/NodePasswordFormElementPackSlugQuery.graphql.d.ts +25 -0
- package/dist/__generated__/NodePasswordFormElementPackSlugQuery.graphql.js +108 -0
- package/dist/__generated__/PrecartAddToCartMutation.graphql.d.ts +1 -1
- package/dist/__generated__/PrecartAddToCartMutation.graphql.js +32 -26
- package/dist/__generated__/StoreModalCartQuery.graphql.d.ts +1 -1
- package/dist/__generated__/StoreModalCartQuery.graphql.js +37 -31
- package/dist/__generated__/StoreModalIndexPackItem_fontPack.graphql.d.ts +23 -0
- package/dist/__generated__/StoreModalIndexPackItem_fontPack.graphql.js +58 -0
- package/dist/__generated__/StoreModalIndexQuery.graphql.d.ts +9 -1
- package/dist/__generated__/StoreModalIndexQuery.graphql.js +174 -110
- package/dist/__generated__/StoreModalPackButton_fontPack.graphql.d.ts +33 -0
- package/dist/__generated__/StoreModalPackButton_fontPack.graphql.js +119 -0
- package/dist/__generated__/StoreModalPack_fontPack.graphql.d.ts +45 -0
- package/dist/__generated__/StoreModalPack_fontPack.graphql.js +150 -0
- package/dist/__generated__/StoreModalProductContent_collection.graphql.d.ts +3 -2
- package/dist/__generated__/StoreModalProductContent_collection.graphql.js +36 -19
- package/dist/__generated__/{StoreModalProductLicenseSelection_collection.graphql.d.ts → StoreModalProductLicenseSelection_licenseable.graphql.d.ts} +6 -6
- package/dist/__generated__/{StoreModalProductLicenseSelection_collection.graphql.js → StoreModalProductLicenseSelection_licenseable.graphql.js} +5 -5
- package/dist/__generated__/StoreModalProductQuery.graphql.d.ts +1 -1
- package/dist/__generated__/StoreModalProductQuery.graphql.js +159 -103
- package/dist/__generated__/StoreModalProductRefetchQuery.graphql.d.ts +1 -1
- package/dist/__generated__/StoreModalProductRefetchQuery.graphql.js +184 -128
- package/dist/__generated__/StoreModalProductSlugQuery.graphql.d.ts +5 -1
- package/dist/__generated__/StoreModalProductSlugQuery.graphql.js +248 -171
- package/dist/__generated__/StoreModalProductSummaryRefetchQuery.graphql.d.ts +1 -1
- package/dist/__generated__/StoreModalProductSummaryRefetchQuery.graphql.js +9 -4
- package/dist/__generated__/StoreModalProductSummary_viewer.graphql.d.ts +7 -1
- package/dist/__generated__/StoreModalProductSummary_viewer.graphql.js +7 -2
- package/dist/__generated__/TestFontsFormUpdateCustomerMutation.graphql.d.ts +1 -1
- package/dist/__generated__/TestFontsFormUpdateCustomerMutation.graphql.js +26 -20
- package/dist/__generated__/TestFontsForm_Query.graphql.d.ts +14 -2
- package/dist/__generated__/TestFontsForm_Query.graphql.js +76 -18
- package/dist/__generated__/productState_Query.graphql.d.ts +99 -1
- package/dist/__generated__/productState_Query.graphql.js +43 -4
- package/dist/__generated__/productState_fontPack.graphql.d.ts +111 -0
- package/dist/__generated__/productState_fontPack.graphql.js +117 -0
- package/dist/__tests__/bundleSelectionOrder.test.js +2 -0
- package/dist/__tests__/collectionBundleSelection.test.js +2 -0
- package/dist/__tests__/fontPackSelection.test.js +435 -0
- package/dist/__tests__/licenseExclusions.test.js +2 -0
- package/dist/__tests__/storeModalPackButton.test.js +102 -0
- package/dist/__tests__/storeModalPackUnlisted.test.js +112 -0
- package/dist/__tests__/storeModalRoutes.test.js +9 -0
- package/dist/__tests__/testFontsFamilyChoice.test.js +150 -0
- package/dist/components/AddToCartBanner/index.js +1 -1
- package/dist/components/BuyButton/index.d.ts +29 -9
- package/dist/components/BuyButton/index.js +123 -26
- package/dist/components/BuyButton/index.server.d.ts +4 -2
- package/dist/components/BuyButton/index.server.js +24 -3
- package/dist/components/Cart/CartItem/CartItemProduct.js +3 -3
- package/dist/components/CollectionAa/index.js +2 -2
- package/dist/components/ConfigContext.d.ts +11 -0
- package/dist/components/ConfigContext.js +7 -1
- package/dist/components/NodePasswordForm/NodePasswordFormElement.d.ts +1 -1
- package/dist/components/NodePasswordForm/NodePasswordFormElement.js +45 -21
- package/dist/components/NodePasswordForm/index.d.ts +7 -4
- package/dist/components/NodePasswordForm/index.js +6 -6
- package/dist/components/Root/productState.js +57 -7
- package/dist/components/StoreModal/StoreModalFamily.d.ts +7 -0
- package/dist/components/StoreModal/StoreModalFamily.js +7 -5
- package/dist/components/StoreModal/StoreModalIndex.js +13 -3
- package/dist/components/StoreModal/StoreModalIndexEntry.d.ts +13 -0
- package/dist/components/StoreModal/StoreModalIndexEntry.js +43 -0
- package/dist/components/StoreModal/StoreModalIndexItem.js +7 -30
- package/dist/components/StoreModal/StoreModalIndexPackItem.d.ts +7 -0
- package/dist/components/StoreModal/StoreModalIndexPackItem.js +21 -0
- package/dist/components/StoreModal/StoreModalPack.d.ts +9 -0
- package/dist/components/StoreModal/StoreModalPack.js +79 -0
- package/dist/components/StoreModal/StoreModalPackButton.d.ts +8 -0
- package/dist/components/StoreModal/StoreModalPackButton.js +53 -0
- package/dist/components/StoreModal/StoreModalProduct.js +38 -15
- package/dist/components/StoreModalProductLicenseSelection/index.d.ts +3 -3
- package/dist/components/StoreModalProductLicenseSelection/index.js +6 -6
- package/dist/components/StoreModalProductSummary/index.js +1 -1
- package/dist/components/TestFontsForm/TestFontsFormElement.d.ts +4 -1
- package/dist/components/TestFontsForm/TestFontsFormElement.js +11 -3
- package/dist/components/TestFontsForm/index.d.ts +6 -3
- package/dist/components/TestFontsForm/index.js +82 -13
- package/dist/components/TestFontsForm/index.server.js +2 -1
- package/dist/components/TestFontsForm/variables.d.ts +8 -0
- package/dist/components/TestFontsForm/variables.js +22 -0
- package/dist/components/elements/StoreModalFamily/index.d.ts +1 -1
- package/dist/components/elements/StoreModalFamily/index.js +1 -1
- package/dist/fontdue.css +13 -0
- package/dist/reducer.d.ts +7 -0
- package/dist/reducer.js +9 -0
- package/dist/selection.d.ts +5 -1
- package/dist/selection.js +61 -16
- package/dist/storeModalRoutes.js +5 -4
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/dist/__generated__/BuyButton_collection.graphql.d.ts +0 -25
- package/dist/__generated__/BuyButton_collection.graphql.js +0 -49
- package/fontdue.css +0 -2733
- package/fontdue.css.map +0 -1
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
|
|
3
|
+
// The pack's row at the top of its product page: the name is shown exactly as
|
|
4
|
+
// the admin entered it, the à-la-carte total is struck through with an <s>,
|
|
5
|
+
// and a pack without a SKU is not clickable.
|
|
6
|
+
|
|
7
|
+
import React, { act } from 'react';
|
|
8
|
+
import { createRoot } from 'react-dom/client';
|
|
9
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
10
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
11
|
+
const {
|
|
12
|
+
stateRef
|
|
13
|
+
} = vi.hoisted(() => ({
|
|
14
|
+
stateRef: {
|
|
15
|
+
current: null
|
|
16
|
+
}
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
// The fragment reader hands back the data it was given; the redux selector
|
|
20
|
+
// runs against a default store's state.
|
|
21
|
+
vi.mock('react-relay', () => ({
|
|
22
|
+
graphql: () => null,
|
|
23
|
+
fetchQuery: vi.fn(),
|
|
24
|
+
useFragment: (_fragment, key) => key
|
|
25
|
+
}));
|
|
26
|
+
vi.mock('react-redux', async importOriginal => ({
|
|
27
|
+
...(await importOriginal()),
|
|
28
|
+
useSelector: selector => selector(stateRef.current)
|
|
29
|
+
}));
|
|
30
|
+
import StoreModalPackButton from '../components/StoreModal/StoreModalPackButton.js';
|
|
31
|
+
import { createDefaultStore } from '../reducer.js';
|
|
32
|
+
const money = amount => ({
|
|
33
|
+
amount,
|
|
34
|
+
currency: 'USD'
|
|
35
|
+
});
|
|
36
|
+
const pack = function () {
|
|
37
|
+
let overrides = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
38
|
+
return {
|
|
39
|
+
name: 'Pack of Basics',
|
|
40
|
+
sku: {
|
|
41
|
+
id: 'pack-sku',
|
|
42
|
+
price: money(15000)
|
|
43
|
+
},
|
|
44
|
+
featureStyle: null,
|
|
45
|
+
totalStyles: 3,
|
|
46
|
+
totalStylesPrice: money(30000),
|
|
47
|
+
...overrides
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
const markup = packData => renderToStaticMarkup( /*#__PURE__*/React.createElement(StoreModalPackButton, {
|
|
51
|
+
pack: packData,
|
|
52
|
+
onSelectSku: () => {}
|
|
53
|
+
}));
|
|
54
|
+
const mount = async (packData, onSelectSku) => {
|
|
55
|
+
const container = document.createElement('div');
|
|
56
|
+
document.body.appendChild(container);
|
|
57
|
+
const root = createRoot(container);
|
|
58
|
+
await act(async () => {
|
|
59
|
+
root.render( /*#__PURE__*/React.createElement(StoreModalPackButton, {
|
|
60
|
+
pack: packData,
|
|
61
|
+
onSelectSku: onSelectSku
|
|
62
|
+
}));
|
|
63
|
+
});
|
|
64
|
+
return container.querySelector('button');
|
|
65
|
+
};
|
|
66
|
+
describe('StoreModalPackButton', () => {
|
|
67
|
+
beforeEach(() => {
|
|
68
|
+
globalThis.IS_REACT_ACT_ENVIRONMENT = true;
|
|
69
|
+
stateRef.current = createDefaultStore(undefined).getState();
|
|
70
|
+
document.body.innerHTML = '';
|
|
71
|
+
});
|
|
72
|
+
it("shows the pack's name as entered, without adding a suffix", () => {
|
|
73
|
+
expect(markup(pack())).toContain('>Pack of Basics<');
|
|
74
|
+
expect(markup(pack())).not.toContain('Pack of Basics Pack');
|
|
75
|
+
expect(markup(pack({
|
|
76
|
+
name: 'Essentials'
|
|
77
|
+
}))).toContain('>Essentials<');
|
|
78
|
+
});
|
|
79
|
+
it('strikes through the à-la-carte total with an <s> when the pack is cheaper', () => {
|
|
80
|
+
expect(markup(pack())).toMatch(/<s class="store-modal__family-button__styles-price">/);
|
|
81
|
+
expect(markup(pack({
|
|
82
|
+
totalStylesPrice: money(15000)
|
|
83
|
+
}))).not.toContain('store-modal__family-button__styles-price');
|
|
84
|
+
});
|
|
85
|
+
it('selects the pack SKU on click', async () => {
|
|
86
|
+
const onSelectSku = vi.fn();
|
|
87
|
+
const button = await mount(pack(), onSelectSku);
|
|
88
|
+
expect(button.dataset.clickable).toBe('true');
|
|
89
|
+
await act(async () => button.click());
|
|
90
|
+
expect(onSelectSku).toHaveBeenCalledWith('pack-sku', true);
|
|
91
|
+
});
|
|
92
|
+
it('is not clickable without a SKU', async () => {
|
|
93
|
+
const onSelectSku = vi.fn();
|
|
94
|
+
const button = await mount(pack({
|
|
95
|
+
sku: null,
|
|
96
|
+
totalStylesPrice: null
|
|
97
|
+
}), onSelectSku);
|
|
98
|
+
expect(button.dataset.clickable).toBe('false');
|
|
99
|
+
await act(async () => button.click());
|
|
100
|
+
expect(onSelectSku).not.toHaveBeenCalled();
|
|
101
|
+
});
|
|
102
|
+
});
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
|
|
3
|
+
// A pack page renders a block per member. An unlisted collection has no block
|
|
4
|
+
// anywhere in the Store Modal (FD-1239), so the pack page leaves it out too –
|
|
5
|
+
// the pack still grants it, and the pack button still sells it.
|
|
6
|
+
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
9
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
10
|
+
const {
|
|
11
|
+
stateRef
|
|
12
|
+
} = vi.hoisted(() => ({
|
|
13
|
+
stateRef: {
|
|
14
|
+
current: null
|
|
15
|
+
}
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
// The fragment reader hands back the data it was given; the redux selector
|
|
19
|
+
// runs against a default store's state.
|
|
20
|
+
vi.mock('react-relay', () => ({
|
|
21
|
+
graphql: () => null,
|
|
22
|
+
fetchQuery: vi.fn(),
|
|
23
|
+
useFragment: (_fragment, key) => key
|
|
24
|
+
}));
|
|
25
|
+
vi.mock('react-redux', async importOriginal => ({
|
|
26
|
+
...(await importOriginal()),
|
|
27
|
+
useSelector: selector => selector(stateRef.current)
|
|
28
|
+
}));
|
|
29
|
+
import StoreModalPack from '../components/StoreModal/StoreModalPack.js';
|
|
30
|
+
import { createDefaultStore } from '../reducer.js';
|
|
31
|
+
const money = amount => ({
|
|
32
|
+
amount,
|
|
33
|
+
currency: 'USD'
|
|
34
|
+
});
|
|
35
|
+
const style = name => ({
|
|
36
|
+
id: `style:${name}`,
|
|
37
|
+
name: 'Regular',
|
|
38
|
+
supportedLanguages: ['en'],
|
|
39
|
+
variableInstances: [],
|
|
40
|
+
sku: {
|
|
41
|
+
id: `sku:style:${name}`,
|
|
42
|
+
price: money(4000)
|
|
43
|
+
},
|
|
44
|
+
cssFamily: name,
|
|
45
|
+
cssWeight: '400',
|
|
46
|
+
cssStretch: 'normal',
|
|
47
|
+
cssStyle: 'normal'
|
|
48
|
+
});
|
|
49
|
+
const family = function (name, visibility) {
|
|
50
|
+
let children = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
51
|
+
return {
|
|
52
|
+
__typename: 'FontCollection',
|
|
53
|
+
id: `collection:${name}`,
|
|
54
|
+
name,
|
|
55
|
+
visibility,
|
|
56
|
+
collectionType: 'family',
|
|
57
|
+
isVariableFont: false,
|
|
58
|
+
sku: {
|
|
59
|
+
id: `sku:${name}`,
|
|
60
|
+
price: money(20000)
|
|
61
|
+
},
|
|
62
|
+
totalStyles: 1,
|
|
63
|
+
totalStylesPrice: money(4000),
|
|
64
|
+
featureStyle: null,
|
|
65
|
+
bundles: [],
|
|
66
|
+
fontStyles: [style(name)],
|
|
67
|
+
children
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
const styleMember = (familyName, visibility) => ({
|
|
71
|
+
__typename: 'FontStyle',
|
|
72
|
+
...style(familyName),
|
|
73
|
+
family: {
|
|
74
|
+
id: `collection:${familyName}`,
|
|
75
|
+
name: familyName,
|
|
76
|
+
isVariableFont: false,
|
|
77
|
+
visibility
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
const pack = {
|
|
81
|
+
name: 'Anniversary pack',
|
|
82
|
+
sku: {
|
|
83
|
+
id: 'sku:pack',
|
|
84
|
+
price: money(30000)
|
|
85
|
+
},
|
|
86
|
+
featureStyle: null,
|
|
87
|
+
totalStyles: 6,
|
|
88
|
+
totalStylesPrice: money(60000),
|
|
89
|
+
members: [family('Alpha', 'VISIBLE', [family('Bravo', 'VISIBLE'), family('Charlie', 'UNLISTED')]), family('Delta', 'UNLISTED'), styleMember('Echo', 'VISIBLE'), styleMember('Foxtrot', 'UNLISTED')]
|
|
90
|
+
};
|
|
91
|
+
describe('StoreModalPack member blocks', () => {
|
|
92
|
+
beforeEach(() => {
|
|
93
|
+
stateRef.current = createDefaultStore(undefined).getState();
|
|
94
|
+
});
|
|
95
|
+
const markup = () => renderToStaticMarkup( /*#__PURE__*/React.createElement(StoreModalPack, {
|
|
96
|
+
pack: pack,
|
|
97
|
+
onSelect: () => {}
|
|
98
|
+
}));
|
|
99
|
+
it('renders a block for each visible member and child family', () => {
|
|
100
|
+
expect(markup()).toContain('Alpha');
|
|
101
|
+
expect(markup()).toContain('Bravo');
|
|
102
|
+
expect(markup()).toContain('Echo');
|
|
103
|
+
});
|
|
104
|
+
it('leaves out an unlisted member, an unlisted child and an unlisted style member', () => {
|
|
105
|
+
expect(markup()).not.toContain('Charlie');
|
|
106
|
+
expect(markup()).not.toContain('Delta');
|
|
107
|
+
expect(markup()).not.toContain('Foxtrot');
|
|
108
|
+
});
|
|
109
|
+
it('still sells the pack as a whole', () => {
|
|
110
|
+
expect(markup()).toContain('Anniversary pack');
|
|
111
|
+
});
|
|
112
|
+
});
|
|
@@ -69,6 +69,15 @@ describe('storeModalUrlActions', () => {
|
|
|
69
69
|
it('opens the modal on its default route for ?store=open', () => {
|
|
70
70
|
expect(storeModalUrlActions('?store=open', config(['unlisted']))).toEqual([OPEN]);
|
|
71
71
|
});
|
|
72
|
+
it('opens the modal on the browse page for ?store=index', () => {
|
|
73
|
+
expect(storeModalUrlActions('?store=index', config(['unlisted']))).toEqual([{
|
|
74
|
+
type: 'STORE_MODAL_REPLACE',
|
|
75
|
+
route: 'index',
|
|
76
|
+
variables: {
|
|
77
|
+
excludeTags: ['unlisted']
|
|
78
|
+
}
|
|
79
|
+
}, OPEN]);
|
|
80
|
+
});
|
|
72
81
|
it('opens the modal on a product for ?store=product/<id>', () => {
|
|
73
82
|
expect(storeModalUrlActions(`?store=product/${PRODUCT_ID}`, config())).toEqual([{
|
|
74
83
|
type: 'STORE_MODAL_REPLACE',
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
|
|
3
|
+
// The test fonts form's family choice (FD-28): the archive endpoint takes
|
|
4
|
+
// `collection_ids[]` to narrow the ZIP, and the form fills it from checkboxes
|
|
5
|
+
// (`familySelection: 'choice'`) or from its own `collectionId`/`collectionSlug`.
|
|
6
|
+
|
|
7
|
+
import React, { act } from 'react';
|
|
8
|
+
import { createRoot } from 'react-dom/client';
|
|
9
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
10
|
+
const {
|
|
11
|
+
queryRef
|
|
12
|
+
} = vi.hoisted(() => ({
|
|
13
|
+
queryRef: {
|
|
14
|
+
data: null,
|
|
15
|
+
variables: null
|
|
16
|
+
}
|
|
17
|
+
}));
|
|
18
|
+
vi.mock('react-relay', () => ({
|
|
19
|
+
graphql: () => null,
|
|
20
|
+
commitMutation: vi.fn(),
|
|
21
|
+
useRelayEnvironment: () => ({}),
|
|
22
|
+
usePreloadedQuery: () => queryRef.data,
|
|
23
|
+
useLazyLoadQuery: (_query, variables) => {
|
|
24
|
+
queryRef.variables = variables;
|
|
25
|
+
return queryRef.data;
|
|
26
|
+
}
|
|
27
|
+
}));
|
|
28
|
+
vi.mock('../components/FontdueContextProvider/index.js', () => ({
|
|
29
|
+
EnsureFontdueContext: _ref => {
|
|
30
|
+
let {
|
|
31
|
+
children
|
|
32
|
+
} = _ref;
|
|
33
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, children);
|
|
34
|
+
},
|
|
35
|
+
LazyQueryBoundary: _ref2 => {
|
|
36
|
+
let {
|
|
37
|
+
children
|
|
38
|
+
} = _ref2;
|
|
39
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, children);
|
|
40
|
+
}
|
|
41
|
+
}));
|
|
42
|
+
import TestFontsForm from '../components/TestFontsForm/index.js';
|
|
43
|
+
import ConfigContext, { makeConfig } from '../components/ConfigContext.js';
|
|
44
|
+
globalThis.IS_REACT_ACT_ENVIRONMENT = true;
|
|
45
|
+
const families = [{
|
|
46
|
+
id: 'RmFtaWx5OjE=',
|
|
47
|
+
name: 'Alpha'
|
|
48
|
+
}, {
|
|
49
|
+
id: 'RmFtaWx5OjI=',
|
|
50
|
+
name: 'Beta'
|
|
51
|
+
}];
|
|
52
|
+
const viewer = function (familySelection) {
|
|
53
|
+
let list = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : families;
|
|
54
|
+
return {
|
|
55
|
+
viewer: {
|
|
56
|
+
settings: {
|
|
57
|
+
eulaAgreementLabel: 'I agree',
|
|
58
|
+
newsletterOptInLabel: null,
|
|
59
|
+
recaptchaEnabled: false,
|
|
60
|
+
recaptchaSiteKey: null
|
|
61
|
+
},
|
|
62
|
+
fontdueConfig: {
|
|
63
|
+
testFonts: {
|
|
64
|
+
familySelection
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
testFonts: {
|
|
68
|
+
archiveUrl: 'https://example.test/test-fonts/archive',
|
|
69
|
+
families: list
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
let container;
|
|
75
|
+
let root;
|
|
76
|
+
beforeEach(() => {
|
|
77
|
+
container = document.createElement('div');
|
|
78
|
+
document.body.append(container);
|
|
79
|
+
root = createRoot(container);
|
|
80
|
+
});
|
|
81
|
+
afterEach(() => {
|
|
82
|
+
act(() => root.unmount());
|
|
83
|
+
container.remove();
|
|
84
|
+
});
|
|
85
|
+
const render = function () {
|
|
86
|
+
let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
87
|
+
let config = arguments.length > 1 ? arguments[1] : undefined;
|
|
88
|
+
return act(() => root.render( /*#__PURE__*/React.createElement(ConfigContext.Provider, {
|
|
89
|
+
value: makeConfig(config)
|
|
90
|
+
}, /*#__PURE__*/React.createElement(TestFontsForm, props))));
|
|
91
|
+
};
|
|
92
|
+
const familyCheckboxes = () => [...container.querySelectorAll('.test-fonts__family input')];
|
|
93
|
+
const hiddenIds = () => [...container.querySelectorAll('input[type="hidden"]')].filter(input => input.name === 'collection_ids[]').map(input => input.value);
|
|
94
|
+
describe('TestFontsForm family choice', () => {
|
|
95
|
+
it('downloads everything without checkboxes by default', () => {
|
|
96
|
+
queryRef.data = viewer('all');
|
|
97
|
+
render();
|
|
98
|
+
expect(familyCheckboxes()).toHaveLength(0);
|
|
99
|
+
expect(hiddenIds()).toEqual([]);
|
|
100
|
+
expect(queryRef.variables).toEqual({
|
|
101
|
+
collectionIds: null,
|
|
102
|
+
collectionSlugs: null
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
it('lists the families when the dashboard says choice, and sends the ticked ones', () => {
|
|
106
|
+
queryRef.data = viewer('choice');
|
|
107
|
+
render();
|
|
108
|
+
expect(familyCheckboxes().map(box => box.value)).toEqual(families.map(f => f.id));
|
|
109
|
+
expect(container.textContent).toContain('Beta');
|
|
110
|
+
expect(hiddenIds()).toEqual([]);
|
|
111
|
+
act(() => familyCheckboxes()[1].click());
|
|
112
|
+
expect(hiddenIds()).toEqual(['RmFtaWx5OjI=']);
|
|
113
|
+
act(() => container.querySelector('.test-fonts__families__all input').click());
|
|
114
|
+
expect(hiddenIds()).toEqual(families.map(f => f.id));
|
|
115
|
+
});
|
|
116
|
+
it('lets code config and the prop override the dashboard setting', () => {
|
|
117
|
+
queryRef.data = viewer('choice');
|
|
118
|
+
render({}, {
|
|
119
|
+
testFonts: {
|
|
120
|
+
familySelection: 'all'
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
expect(familyCheckboxes()).toHaveLength(0);
|
|
124
|
+
queryRef.data = viewer('all');
|
|
125
|
+
render({
|
|
126
|
+
familySelection: 'choice'
|
|
127
|
+
});
|
|
128
|
+
expect(familyCheckboxes()).toHaveLength(2);
|
|
129
|
+
});
|
|
130
|
+
it('downloads exactly the named collections without checkboxes', () => {
|
|
131
|
+
queryRef.data = viewer('choice', [families[0]]);
|
|
132
|
+
render({
|
|
133
|
+
collectionSlug: 'alpha, gamma'
|
|
134
|
+
});
|
|
135
|
+
expect(queryRef.variables).toEqual({
|
|
136
|
+
collectionIds: null,
|
|
137
|
+
collectionSlugs: ['alpha', 'gamma']
|
|
138
|
+
});
|
|
139
|
+
expect(familyCheckboxes()).toHaveLength(0);
|
|
140
|
+
expect(hiddenIds()).toEqual(['RmFtaWx5OjE=']);
|
|
141
|
+
});
|
|
142
|
+
it('says so when the named collections have no test fonts', () => {
|
|
143
|
+
queryRef.data = viewer('all', []);
|
|
144
|
+
render({
|
|
145
|
+
collectionId: 'RmFtaWx5Ojk='
|
|
146
|
+
});
|
|
147
|
+
expect(container.querySelector('form')).toBeNull();
|
|
148
|
+
expect(container.textContent).toContain('Test fonts aren’t available for this family.');
|
|
149
|
+
});
|
|
150
|
+
});
|
|
@@ -21,7 +21,7 @@ const getOrderItemName = item => {
|
|
|
21
21
|
if ('name' in product) return product.name;
|
|
22
22
|
return null;
|
|
23
23
|
};
|
|
24
|
-
_AddToCartBanner_item.hash && _AddToCartBanner_item.hash !== "
|
|
24
|
+
_AddToCartBanner_item.hash && _AddToCartBanner_item.hash !== "5b6c677fd518073e74b1651f3b872e8a" && console.error("The definition of 'AddToCartBanner_item' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _AddToCartBanner_item;
|
|
25
25
|
function AddToCartBanner(_ref) {
|
|
26
26
|
var _order$orderItems, _order$orderItems2;
|
|
27
27
|
let {
|
|
@@ -1,19 +1,35 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { BuyButtonIDQuery } from '../../__generated__/BuyButtonIDQuery.graphql.js';
|
|
3
3
|
import { BuyButtonSlugQuery } from '../../__generated__/BuyButtonSlugQuery.graphql.js';
|
|
4
|
+
import { BuyButtonPackIDQuery } from '../../__generated__/BuyButtonPackIDQuery.graphql.js';
|
|
5
|
+
import { BuyButtonPackSlugQuery } from '../../__generated__/BuyButtonPackSlugQuery.graphql.js';
|
|
4
6
|
import { SerializablePreloadedQuery, type LoadQueryOptions } from '../../relay/loadSerializableQuery.js';
|
|
5
7
|
import { Config } from '../ConfigContext.js';
|
|
6
8
|
export interface BuyButton_props {
|
|
7
9
|
collectionName?: string;
|
|
8
10
|
label?: string;
|
|
9
11
|
}
|
|
10
|
-
export type BuyButtonPreloadedQuery = SerializablePreloadedQuery<BuyButtonIDQuery> | SerializablePreloadedQuery<BuyButtonSlugQuery>;
|
|
12
|
+
export type BuyButtonPreloadedQuery = SerializablePreloadedQuery<BuyButtonIDQuery> | SerializablePreloadedQuery<BuyButtonSlugQuery> | SerializablePreloadedQuery<BuyButtonPackIDQuery> | SerializablePreloadedQuery<BuyButtonPackSlugQuery>;
|
|
11
13
|
export type LoadBuyButtonQueryVariables = {
|
|
12
14
|
collectionId: string;
|
|
13
15
|
collectionSlug?: never;
|
|
16
|
+
fontPackId?: never;
|
|
17
|
+
fontPackSlug?: never;
|
|
14
18
|
} | {
|
|
15
19
|
collectionId?: never;
|
|
16
20
|
collectionSlug: string;
|
|
21
|
+
fontPackId?: never;
|
|
22
|
+
fontPackSlug?: never;
|
|
23
|
+
} | {
|
|
24
|
+
collectionId?: never;
|
|
25
|
+
collectionSlug?: never;
|
|
26
|
+
fontPackId: string;
|
|
27
|
+
fontPackSlug?: never;
|
|
28
|
+
} | {
|
|
29
|
+
collectionId?: never;
|
|
30
|
+
collectionSlug?: never;
|
|
31
|
+
fontPackId?: never;
|
|
32
|
+
fontPackSlug: string;
|
|
17
33
|
};
|
|
18
34
|
export declare function loadBuyButtonQuery(variables: LoadBuyButtonQueryVariables, options?: LoadQueryOptions): Promise<BuyButtonPreloadedQuery>;
|
|
19
35
|
export declare function BuyButtonPreloadedIDQueryRenderer({ preloadedQuery, ...rest }: BuyButton_props & {
|
|
@@ -22,19 +38,23 @@ export declare function BuyButtonPreloadedIDQueryRenderer({ preloadedQuery, ...r
|
|
|
22
38
|
export declare function BuyButtonPreloadedSlugQueryRenderer({ preloadedQuery, ...rest }: BuyButton_props & {
|
|
23
39
|
preloadedQuery: SerializablePreloadedQuery<BuyButtonSlugQuery>;
|
|
24
40
|
}): React.JSX.Element;
|
|
41
|
+
export declare function BuyButtonPreloadedPackIDQueryRenderer({ preloadedQuery, ...rest }: BuyButton_props & {
|
|
42
|
+
preloadedQuery: SerializablePreloadedQuery<BuyButtonPackIDQuery>;
|
|
43
|
+
}): React.JSX.Element;
|
|
44
|
+
export declare function BuyButtonPreloadedPackSlugQueryRenderer({ preloadedQuery, ...rest }: BuyButton_props & {
|
|
45
|
+
preloadedQuery: SerializablePreloadedQuery<BuyButtonPackSlugQuery>;
|
|
46
|
+
}): React.JSX.Element;
|
|
47
|
+
type BuyButton_lazyProps = LoadBuyButtonQueryVariables;
|
|
25
48
|
export type BuyButton_unifiedProps = BuyButton_props & {
|
|
26
49
|
config?: Config;
|
|
27
50
|
} & ({
|
|
28
51
|
preloadedQuery: BuyButtonPreloadedQuery;
|
|
29
52
|
collectionId?: never;
|
|
30
53
|
collectionSlug?: never;
|
|
31
|
-
|
|
54
|
+
fontPackId?: never;
|
|
55
|
+
fontPackSlug?: never;
|
|
56
|
+
} | ({
|
|
32
57
|
preloadedQuery?: never;
|
|
33
|
-
|
|
34
|
-
collectionSlug?: never;
|
|
35
|
-
} | {
|
|
36
|
-
preloadedQuery?: never;
|
|
37
|
-
collectionId?: never;
|
|
38
|
-
collectionSlug: string;
|
|
39
|
-
});
|
|
58
|
+
} & BuyButton_lazyProps));
|
|
40
59
|
export default function BuyButton(props: BuyButton_unifiedProps): React.JSX.Element;
|
|
60
|
+
export {};
|