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.
Files changed (135) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +8 -5
  3. package/dist/__generated__/AddToCartBannerQuery.graphql.d.ts +1 -1
  4. package/dist/__generated__/AddToCartBannerQuery.graphql.js +16 -10
  5. package/dist/__generated__/AddToCartBanner_item.graphql.d.ts +4 -1
  6. package/dist/__generated__/AddToCartBanner_item.graphql.js +7 -2
  7. package/dist/__generated__/AddToCartBanner_order.graphql.d.ts +4 -1
  8. package/dist/__generated__/AddToCartBanner_order.graphql.js +6 -1
  9. package/dist/__generated__/BuyButtonIDQuery.graphql.d.ts +3 -3
  10. package/dist/__generated__/BuyButtonIDQuery.graphql.js +31 -16
  11. package/dist/__generated__/BuyButtonPackIDQuery.graphql.d.ts +21 -0
  12. package/dist/__generated__/BuyButtonPackIDQuery.graphql.js +129 -0
  13. package/dist/__generated__/BuyButtonPackSlugQuery.graphql.d.ts +25 -0
  14. package/dist/__generated__/BuyButtonPackSlugQuery.graphql.js +167 -0
  15. package/dist/__generated__/BuyButtonSlugQuery.graphql.d.ts +3 -3
  16. package/dist/__generated__/BuyButtonSlugQuery.graphql.js +45 -17
  17. package/dist/__generated__/BuyButton_product.graphql.d.ts +27 -0
  18. package/dist/__generated__/BuyButton_product.graphql.js +72 -0
  19. package/dist/__generated__/CartItemProduct_product.graphql.d.ts +1 -1
  20. package/dist/__generated__/CartItemProduct_product.graphql.js +7 -2
  21. package/dist/__generated__/CartOrderCompleteOrderMutation.graphql.d.ts +1 -1
  22. package/dist/__generated__/CartOrderCompleteOrderMutation.graphql.js +26 -20
  23. package/dist/__generated__/CartOrderRemoveDiscountMutation.graphql.d.ts +1 -1
  24. package/dist/__generated__/CartOrderRemoveDiscountMutation.graphql.js +26 -20
  25. package/dist/__generated__/CartOrderUpdateMutation.graphql.d.ts +1 -1
  26. package/dist/__generated__/CartOrderUpdateMutation.graphql.js +26 -20
  27. package/dist/__generated__/CartQuery.graphql.d.ts +1 -1
  28. package/dist/__generated__/CartQuery.graphql.js +26 -20
  29. package/dist/__generated__/CartStateUpdateMutation.graphql.d.ts +1 -1
  30. package/dist/__generated__/CartStateUpdateMutation.graphql.js +26 -20
  31. package/dist/__generated__/CheckoutUpdateCustomerMutation.graphql.d.ts +1 -1
  32. package/dist/__generated__/CheckoutUpdateCustomerMutation.graphql.js +26 -20
  33. package/dist/__generated__/CheckoutUpdateOrderMutation.graphql.d.ts +1 -1
  34. package/dist/__generated__/CheckoutUpdateOrderMutation.graphql.js +26 -20
  35. package/dist/__generated__/CollectionAa_Query.graphql.d.ts +1 -1
  36. package/dist/__generated__/CollectionAa_Query.graphql.js +20 -14
  37. package/dist/__generated__/CollectionAa_product.graphql.d.ts +7 -1
  38. package/dist/__generated__/CollectionAa_product.graphql.js +22 -16
  39. package/dist/__generated__/NodePasswordFormElementIDQuery.graphql.d.ts +3 -3
  40. package/dist/__generated__/NodePasswordFormElementIDQuery.graphql.js +9 -9
  41. package/dist/__generated__/NodePasswordFormElementPackSlugQuery.graphql.d.ts +25 -0
  42. package/dist/__generated__/NodePasswordFormElementPackSlugQuery.graphql.js +108 -0
  43. package/dist/__generated__/PrecartAddToCartMutation.graphql.d.ts +1 -1
  44. package/dist/__generated__/PrecartAddToCartMutation.graphql.js +32 -26
  45. package/dist/__generated__/StoreModalCartQuery.graphql.d.ts +1 -1
  46. package/dist/__generated__/StoreModalCartQuery.graphql.js +37 -31
  47. package/dist/__generated__/StoreModalIndexPackItem_fontPack.graphql.d.ts +23 -0
  48. package/dist/__generated__/StoreModalIndexPackItem_fontPack.graphql.js +58 -0
  49. package/dist/__generated__/StoreModalIndexQuery.graphql.d.ts +9 -1
  50. package/dist/__generated__/StoreModalIndexQuery.graphql.js +174 -110
  51. package/dist/__generated__/StoreModalPackButton_fontPack.graphql.d.ts +33 -0
  52. package/dist/__generated__/StoreModalPackButton_fontPack.graphql.js +119 -0
  53. package/dist/__generated__/StoreModalPack_fontPack.graphql.d.ts +45 -0
  54. package/dist/__generated__/StoreModalPack_fontPack.graphql.js +150 -0
  55. package/dist/__generated__/StoreModalProductContent_collection.graphql.d.ts +3 -2
  56. package/dist/__generated__/StoreModalProductContent_collection.graphql.js +36 -19
  57. package/dist/__generated__/{StoreModalProductLicenseSelection_collection.graphql.d.ts → StoreModalProductLicenseSelection_licenseable.graphql.d.ts} +6 -6
  58. package/dist/__generated__/{StoreModalProductLicenseSelection_collection.graphql.js → StoreModalProductLicenseSelection_licenseable.graphql.js} +5 -5
  59. package/dist/__generated__/StoreModalProductQuery.graphql.d.ts +1 -1
  60. package/dist/__generated__/StoreModalProductQuery.graphql.js +159 -103
  61. package/dist/__generated__/StoreModalProductRefetchQuery.graphql.d.ts +1 -1
  62. package/dist/__generated__/StoreModalProductRefetchQuery.graphql.js +184 -128
  63. package/dist/__generated__/StoreModalProductSlugQuery.graphql.d.ts +5 -1
  64. package/dist/__generated__/StoreModalProductSlugQuery.graphql.js +248 -171
  65. package/dist/__generated__/StoreModalProductSummaryRefetchQuery.graphql.d.ts +1 -1
  66. package/dist/__generated__/StoreModalProductSummaryRefetchQuery.graphql.js +9 -4
  67. package/dist/__generated__/StoreModalProductSummary_viewer.graphql.d.ts +7 -1
  68. package/dist/__generated__/StoreModalProductSummary_viewer.graphql.js +7 -2
  69. package/dist/__generated__/TestFontsFormUpdateCustomerMutation.graphql.d.ts +1 -1
  70. package/dist/__generated__/TestFontsFormUpdateCustomerMutation.graphql.js +26 -20
  71. package/dist/__generated__/TestFontsForm_Query.graphql.d.ts +14 -2
  72. package/dist/__generated__/TestFontsForm_Query.graphql.js +76 -18
  73. package/dist/__generated__/productState_Query.graphql.d.ts +99 -1
  74. package/dist/__generated__/productState_Query.graphql.js +43 -4
  75. package/dist/__generated__/productState_fontPack.graphql.d.ts +111 -0
  76. package/dist/__generated__/productState_fontPack.graphql.js +117 -0
  77. package/dist/__tests__/bundleSelectionOrder.test.js +2 -0
  78. package/dist/__tests__/collectionBundleSelection.test.js +2 -0
  79. package/dist/__tests__/fontPackSelection.test.js +435 -0
  80. package/dist/__tests__/licenseExclusions.test.js +2 -0
  81. package/dist/__tests__/storeModalPackButton.test.js +102 -0
  82. package/dist/__tests__/storeModalPackUnlisted.test.js +112 -0
  83. package/dist/__tests__/storeModalRoutes.test.js +9 -0
  84. package/dist/__tests__/testFontsFamilyChoice.test.js +150 -0
  85. package/dist/components/AddToCartBanner/index.js +1 -1
  86. package/dist/components/BuyButton/index.d.ts +29 -9
  87. package/dist/components/BuyButton/index.js +123 -26
  88. package/dist/components/BuyButton/index.server.d.ts +4 -2
  89. package/dist/components/BuyButton/index.server.js +24 -3
  90. package/dist/components/Cart/CartItem/CartItemProduct.js +3 -3
  91. package/dist/components/CollectionAa/index.js +2 -2
  92. package/dist/components/ConfigContext.d.ts +11 -0
  93. package/dist/components/ConfigContext.js +7 -1
  94. package/dist/components/NodePasswordForm/NodePasswordFormElement.d.ts +1 -1
  95. package/dist/components/NodePasswordForm/NodePasswordFormElement.js +45 -21
  96. package/dist/components/NodePasswordForm/index.d.ts +7 -4
  97. package/dist/components/NodePasswordForm/index.js +6 -6
  98. package/dist/components/Root/productState.js +57 -7
  99. package/dist/components/StoreModal/StoreModalFamily.d.ts +7 -0
  100. package/dist/components/StoreModal/StoreModalFamily.js +7 -5
  101. package/dist/components/StoreModal/StoreModalIndex.js +13 -3
  102. package/dist/components/StoreModal/StoreModalIndexEntry.d.ts +13 -0
  103. package/dist/components/StoreModal/StoreModalIndexEntry.js +43 -0
  104. package/dist/components/StoreModal/StoreModalIndexItem.js +7 -30
  105. package/dist/components/StoreModal/StoreModalIndexPackItem.d.ts +7 -0
  106. package/dist/components/StoreModal/StoreModalIndexPackItem.js +21 -0
  107. package/dist/components/StoreModal/StoreModalPack.d.ts +9 -0
  108. package/dist/components/StoreModal/StoreModalPack.js +79 -0
  109. package/dist/components/StoreModal/StoreModalPackButton.d.ts +8 -0
  110. package/dist/components/StoreModal/StoreModalPackButton.js +53 -0
  111. package/dist/components/StoreModal/StoreModalProduct.js +38 -15
  112. package/dist/components/StoreModalProductLicenseSelection/index.d.ts +3 -3
  113. package/dist/components/StoreModalProductLicenseSelection/index.js +6 -6
  114. package/dist/components/StoreModalProductSummary/index.js +1 -1
  115. package/dist/components/TestFontsForm/TestFontsFormElement.d.ts +4 -1
  116. package/dist/components/TestFontsForm/TestFontsFormElement.js +11 -3
  117. package/dist/components/TestFontsForm/index.d.ts +6 -3
  118. package/dist/components/TestFontsForm/index.js +82 -13
  119. package/dist/components/TestFontsForm/index.server.js +2 -1
  120. package/dist/components/TestFontsForm/variables.d.ts +8 -0
  121. package/dist/components/TestFontsForm/variables.js +22 -0
  122. package/dist/components/elements/StoreModalFamily/index.d.ts +1 -1
  123. package/dist/components/elements/StoreModalFamily/index.js +1 -1
  124. package/dist/fontdue.css +13 -0
  125. package/dist/reducer.d.ts +7 -0
  126. package/dist/reducer.js +9 -0
  127. package/dist/selection.d.ts +5 -1
  128. package/dist/selection.js +61 -16
  129. package/dist/storeModalRoutes.js +5 -4
  130. package/dist/version.js +1 -1
  131. package/package.json +1 -1
  132. package/dist/__generated__/BuyButton_collection.graphql.d.ts +0 -25
  133. package/dist/__generated__/BuyButton_collection.graphql.js +0 -49
  134. package/fontdue.css +0 -2733
  135. 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 !== "93905c08206c30255368dbb06f59ccec" && 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;
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
- collectionId: string;
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 {};