@rebilly/instruments 1.0.2-beta.8 → 2.1.1-beta.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 (211) hide show
  1. package/.babelrc +13 -4
  2. package/.eslintrc.js +3 -0
  3. package/.prettierrc.js +11 -0
  4. package/README.md +15 -314
  5. package/dist/events/base-event.js +6 -9
  6. package/dist/events/events.spec.js +4 -4
  7. package/dist/events/index.js +2 -1
  8. package/dist/functions/destroy.js +12 -14
  9. package/dist/functions/destroy.spec.js +3 -3
  10. package/dist/functions/mount/fetch-data.js +183 -0
  11. package/dist/functions/mount/fetch-data.spec.js +189 -0
  12. package/dist/functions/mount/index.js +158 -251
  13. package/dist/functions/mount/mount.spec.js +24 -121
  14. package/dist/functions/mount/setup-element.js +40 -0
  15. package/dist/functions/mount/setup-framepay.js +46 -0
  16. package/dist/functions/mount/setup-i18n.js +33 -0
  17. package/dist/functions/mount/setup-options.js +96 -0
  18. package/dist/functions/mount/setup-options.spec.js +66 -0
  19. package/dist/functions/mount/setup-storefront.js +34 -0
  20. package/dist/functions/mount/setup-styles.js +43 -0
  21. package/dist/functions/on.js +13 -4
  22. package/dist/functions/on.spec.js +19 -5
  23. package/dist/functions/purchase.js +139 -22
  24. package/dist/functions/purchase.spec.js +23 -19
  25. package/dist/functions/setup.js +85 -0
  26. package/dist/functions/setup.spec.js +87 -0
  27. package/dist/functions/show.js +31 -14
  28. package/dist/functions/show.spec.js +47 -18
  29. package/dist/functions/update.js +53 -27
  30. package/dist/functions/update.spec.js +40 -21
  31. package/dist/i18n/en.json +4 -1
  32. package/dist/i18n/es.json +4 -1
  33. package/dist/index.js +67 -56
  34. package/dist/index.spec.js +7 -27
  35. package/dist/loader/index.js +4 -3
  36. package/dist/storefront/index.js +33 -0
  37. package/dist/storefront/invoices.js +27 -0
  38. package/dist/storefront/models/base-model.js +18 -0
  39. package/dist/storefront/models/invoice-model.js +14 -0
  40. package/dist/storefront/models/plan-model.js +4 -35
  41. package/dist/storefront/models/product-model.js +4 -23
  42. package/dist/storefront/models/summary-model.js +12 -25
  43. package/dist/storefront/models/transaction-model.js +31 -0
  44. package/dist/storefront/payment-instruments.js +47 -0
  45. package/dist/storefront/payment-instruments.spec.js +55 -0
  46. package/dist/storefront/plans.js +15 -24
  47. package/dist/storefront/plans.spec.js +17 -44
  48. package/dist/storefront/products.js +16 -20
  49. package/dist/storefront/products.spec.js +25 -49
  50. package/dist/storefront/purchase.js +28 -16
  51. package/dist/storefront/purchase.spec.js +4 -22
  52. package/dist/storefront/ready-to-pay.js +26 -22
  53. package/dist/storefront/ready-to-pay.spec.js +25 -54
  54. package/dist/storefront/storefront.spec.js +1 -1
  55. package/dist/storefront/summary.js +27 -24
  56. package/dist/storefront/summary.spec.js +44 -86
  57. package/dist/storefront/transactions.js +27 -0
  58. package/dist/style/base/theme.js +3 -3
  59. package/dist/style/components/methods.js +43 -42
  60. package/dist/style/utils/color-values.js +1 -3
  61. package/dist/style/views/confirmation.js +0 -4
  62. package/dist/style/views/method-selector.js +1 -1
  63. package/dist/style/views/modal.js +3 -1
  64. package/dist/style/views/summary.js +5 -1
  65. package/dist/utils/format-currency.js +4 -2
  66. package/dist/utils/has-valid-css-selector.js +1 -1
  67. package/dist/utils/process-property-as-dom-element.js +0 -2
  68. package/dist/views/__snapshots__/summary.spec.js.snap +103 -113
  69. package/dist/views/common/iframe/base-iframe.js +10 -2
  70. package/dist/views/common/iframe/modal-iframe.js +44 -3
  71. package/dist/views/confirmation.js +44 -20
  72. package/dist/views/method-selector/express-methods/apple-pay.js +92 -0
  73. package/dist/views/method-selector/express-methods/google-pay.js +31 -0
  74. package/dist/views/method-selector/express-methods/paypal.js +19 -0
  75. package/dist/views/method-selector/generate-digital-wallet.js +68 -0
  76. package/dist/views/method-selector/generate-digital-wallet.spec.js +135 -0
  77. package/dist/views/method-selector/get-payment-methods.js +28 -8
  78. package/dist/views/method-selector/get-payment-methods.spec.js +25 -26
  79. package/dist/views/method-selector/index.js +55 -86
  80. package/dist/views/method-selector/method-selector.spec.js +80 -69
  81. package/dist/views/method-selector/mount-express-methods.js +38 -62
  82. package/dist/views/method-selector/mount-methods.js +18 -18
  83. package/dist/views/modal.js +21 -15
  84. package/dist/views/result.js +13 -16
  85. package/dist/views/summary.js +170 -114
  86. package/dist/views/summary.spec.js +72 -76
  87. package/package.json +5 -4
  88. package/src/events/base-event.js +15 -17
  89. package/src/events/events.spec.js +6 -4
  90. package/src/events/index.js +6 -3
  91. package/src/functions/destroy.js +12 -13
  92. package/src/functions/destroy.spec.js +30 -31
  93. package/src/functions/mount/fetch-data.js +148 -0
  94. package/src/functions/mount/fetch-data.spec.js +238 -0
  95. package/src/functions/mount/index.js +129 -244
  96. package/src/functions/mount/mount.spec.js +35 -139
  97. package/src/functions/mount/setup-element.js +26 -0
  98. package/src/functions/mount/setup-framepay.js +41 -0
  99. package/src/functions/mount/setup-i18n.js +19 -0
  100. package/src/functions/mount/setup-options.js +100 -0
  101. package/src/functions/mount/setup-options.spec.js +60 -0
  102. package/src/functions/mount/setup-storefront.js +24 -0
  103. package/src/functions/mount/setup-styles.js +30 -0
  104. package/src/functions/on.js +13 -8
  105. package/src/functions/on.spec.js +30 -17
  106. package/src/functions/purchase.js +101 -19
  107. package/src/functions/purchase.spec.js +18 -18
  108. package/src/functions/setup.js +48 -0
  109. package/src/functions/setup.spec.js +98 -0
  110. package/src/functions/show.js +20 -10
  111. package/src/functions/show.spec.js +43 -22
  112. package/src/functions/update.js +50 -27
  113. package/src/functions/update.spec.js +57 -22
  114. package/src/i18n/en.json +4 -1
  115. package/src/i18n/es.json +4 -1
  116. package/src/i18n/i18n.spec.js +6 -4
  117. package/src/i18n/index.js +14 -11
  118. package/src/index.js +41 -52
  119. package/src/index.spec.js +8 -37
  120. package/src/loader/index.js +51 -47
  121. package/src/loader/loader.spec.js +26 -19
  122. package/src/storefront/index.js +37 -7
  123. package/src/storefront/invoices.js +11 -0
  124. package/src/storefront/models/base-model.js +10 -0
  125. package/src/storefront/models/invoice-model.js +3 -0
  126. package/src/storefront/models/plan-model.js +3 -35
  127. package/src/storefront/models/product-model.js +3 -23
  128. package/src/storefront/models/ready-to-pay-model.js +3 -3
  129. package/src/storefront/models/summary-model.js +15 -29
  130. package/src/storefront/models/transaction-model.js +19 -0
  131. package/src/storefront/payment-instruments.js +30 -0
  132. package/src/storefront/payment-instruments.spec.js +69 -0
  133. package/src/storefront/plans.js +16 -23
  134. package/src/storefront/plans.spec.js +25 -54
  135. package/src/storefront/products.js +18 -22
  136. package/src/storefront/products.spec.js +23 -54
  137. package/src/storefront/purchase.js +14 -14
  138. package/src/storefront/purchase.spec.js +17 -29
  139. package/src/storefront/ready-to-pay.js +26 -23
  140. package/src/storefront/ready-to-pay.spec.js +41 -71
  141. package/src/storefront/storefront.spec.js +1 -1
  142. package/src/storefront/summary.js +26 -22
  143. package/src/storefront/summary.spec.js +60 -109
  144. package/src/storefront/transactions.js +11 -0
  145. package/src/style/base/theme.js +10 -8
  146. package/src/style/base/theme.spec.js +4 -2
  147. package/src/style/browserslist.js +1 -3
  148. package/src/style/components/button.js +3 -1
  149. package/src/style/components/forms/checkbox.js +3 -1
  150. package/src/style/components/index.js +1 -1
  151. package/src/style/components/loader.js +3 -1
  152. package/src/style/components/methods.js +43 -42
  153. package/src/style/helpers/index.js +1 -1
  154. package/src/style/index.js +2 -1
  155. package/src/style/utils/color-values.js +4 -4
  156. package/src/style/vendor/framepay.js +1 -1
  157. package/src/style/vendor/postmate.js +1 -1
  158. package/src/style/views/confirmation.js +0 -4
  159. package/src/style/views/index.js +1 -1
  160. package/src/style/views/method-selector.js +1 -1
  161. package/src/style/views/modal.js +4 -2
  162. package/src/style/views/summary.js +5 -1
  163. package/src/utils/add-dom-element.js +12 -13
  164. package/src/utils/format-currency.js +6 -2
  165. package/src/utils/has-valid-css-selector.js +2 -2
  166. package/src/utils/is-dom-element.js +1 -1
  167. package/src/utils/process-property-as-dom-element.js +27 -24
  168. package/src/utils/sleep.js +1 -1
  169. package/src/views/__snapshots__/summary.spec.js.snap +103 -113
  170. package/src/views/common/iframe/base-iframe.js +12 -4
  171. package/src/views/common/iframe/event-listeners.js +6 -6
  172. package/src/views/common/iframe/index.js +1 -1
  173. package/src/views/common/iframe/method-iframe.js +3 -6
  174. package/src/views/common/iframe/modal-iframe.js +42 -6
  175. package/src/views/common/iframe/view-iframe.js +3 -5
  176. package/src/views/common/render-utilities.js +3 -3
  177. package/src/views/confirmation.js +34 -25
  178. package/src/views/method-selector/express-methods/apple-pay.js +78 -0
  179. package/src/views/method-selector/express-methods/google-pay.js +24 -0
  180. package/src/views/method-selector/express-methods/paypal.js +7 -0
  181. package/src/views/method-selector/generate-digital-wallet.js +51 -0
  182. package/src/views/method-selector/generate-digital-wallet.spec.js +135 -0
  183. package/src/views/method-selector/get-method-data.js +7 -4
  184. package/src/views/method-selector/get-payment-methods.js +38 -29
  185. package/src/views/method-selector/get-payment-methods.spec.js +26 -33
  186. package/src/views/method-selector/index.js +70 -99
  187. package/src/views/method-selector/method-selector.spec.js +88 -78
  188. package/src/views/method-selector/mount-express-methods.js +36 -60
  189. package/src/views/method-selector/mount-methods.js +32 -21
  190. package/src/views/modal.js +37 -23
  191. package/src/views/result.js +12 -15
  192. package/src/views/summary.js +169 -101
  193. package/src/views/summary.spec.js +99 -74
  194. package/tests/async-utilities.js +22 -0
  195. package/tests/mocks/rebilly-instruments-mock.js +89 -77
  196. package/tests/mocks/storefront-api-mock.js +8 -0
  197. package/tests/mocks/storefront-mock.js +17 -0
  198. package/dist/events/purchase-completed.js +0 -24
  199. package/dist/functions/initialize.js +0 -82
  200. package/dist/functions/initialize.spec.js +0 -34
  201. package/dist/functions/mount/fetch-summary-data.js +0 -31
  202. package/dist/functions/mount/fetch-summary-data.spec.js +0 -45
  203. package/dist/views/method-selector/process-digital-wallet-options.js +0 -35
  204. package/dist/views/method-selector/process-digital-wallet-options.spec.js +0 -80
  205. package/src/events/purchase-completed.js +0 -11
  206. package/src/functions/initialize.js +0 -74
  207. package/src/functions/initialize.spec.js +0 -38
  208. package/src/functions/mount/fetch-summary-data.js +0 -26
  209. package/src/functions/mount/fetch-summary-data.spec.js +0 -46
  210. package/src/views/method-selector/process-digital-wallet-options.js +0 -16
  211. package/src/views/method-selector/process-digital-wallet-options.spec.js +0 -94
@@ -1,30 +1,23 @@
1
1
  import PlanModel from './models/plan-model';
2
+ import { Endpoint } from './index';
2
3
 
3
- export async function FetchPlans ({
4
- data = null
5
- } = {}) {
6
- if (!this.storefront) {
7
- throw new Error('Could not access rebilly-js-sdk instance');
8
- }
9
-
10
- if (!this.configs || !this.options) {
11
- throw new Error('Could not use Rebilly Instruments configurations or mount options to fetch Rebilly data');
12
- }
13
-
14
- try {
15
- const { lineItems } = data || {};
4
+ export async function fetchPlans({ state = {}, data = {} }) {
5
+ return Endpoint({state}, async () => {
6
+ const lineItems = data.lineItems || state.data.summaryLineItems;
16
7
 
17
8
  const filterByPlanId = {
18
- filter: '',
19
- }
9
+ filter: ''
10
+ };
20
11
 
21
- if (lineItems) {
22
- filterByPlanId.filter = `id:${lineItems.map(item => item.planId).join(',')}`;
12
+ if (lineItems.length) {
13
+ filterByPlanId.filter = `id:${lineItems
14
+ .map((item) => item.planId)
15
+ .join(',')}`;
23
16
  }
24
17
 
25
- const {items: planItems} = await this.storefront.plans.getAll(filterByPlanId);
26
- return planItems.map(({fields}) => new PlanModel(fields));
27
- } catch (error) {
28
- throw error;
29
- }
30
- };
18
+ const { items: planItems } = await state.storefront.plans.getAll(
19
+ filterByPlanId
20
+ );
21
+ return planItems.map(({ fields }) => new PlanModel(fields));
22
+ });
23
+ }
@@ -1,36 +1,22 @@
1
- import { MockStorefront } from 'tests/mocks/storefront-mock';
1
+ import { StorefontTestingInstance } from 'tests/mocks/storefront-mock';
2
2
  import { ok, get } from 'msw-when-then';
3
3
  import { when } from 'tests/msw/server';
4
4
  import { storefrontURL } from 'tests/mocks/storefront-api-mock';
5
- import { FetchPlans } from './plans';
5
+ import { fetchPlans } from './plans';
6
6
  import PlanModel from './models/plan-model';
7
+ import { expectConfigurationError } from 'tests/async-utilities';
7
8
 
8
9
  describe('Storefront API Plan', () => {
9
- class TestPlansInstance {
10
- constructor({
11
- configs = {},
12
- options = {}
13
- } = {}) {
14
- this.configs = configs;
15
- this.options = options;
16
- this.storefront = MockStorefront();
17
- }
18
-
19
- fetchPlans(...args) {
20
- return FetchPlans.apply(this, args);
21
- }
22
- }
23
-
24
- it ('can fetch plans', async () => {
25
- const testPlan = {name: 'Test Plan', id: 'test-plan-id-1'};
10
+ it('can fetch plans', async () => {
11
+ const testPlan = { name: 'Test Plan', id: 'test-plan-id-1' };
26
12
 
27
13
  when(get(`${storefrontURL}/plans`)).thenReturn(ok([testPlan]));
28
14
 
29
- const instance = new TestPlansInstance();
15
+ const instance = new StorefontTestingInstance();
30
16
 
31
17
  jest.spyOn(instance.storefront.plans, 'getAll');
32
18
 
33
- const response = await instance.fetchPlans({});
19
+ const response = await fetchPlans({ state: instance });
34
20
 
35
21
  expect(instance.storefront.plans.getAll).toBeCalledTimes(1);
36
22
  expect(instance.storefront.plans.getAll).toBeCalledWith({
@@ -41,18 +27,22 @@ describe('Storefront API Plan', () => {
41
27
  expect(response).toEqual([new PlanModel(testPlan)]);
42
28
  });
43
29
 
44
- it ('can fetch plans with filter', async () => {
45
- const instance = new TestPlansInstance();
30
+ it('can fetch plans with filter', async () => {
31
+ const instance = new StorefontTestingInstance();
46
32
 
47
33
  jest.spyOn(instance.storefront.plans, 'getAll');
48
34
 
49
- await instance.fetchPlans({
35
+ await fetchPlans({
36
+ state: instance,
50
37
  data: {
51
- lineItems: [{
52
- planId: 'test-plan-id-1'
53
- }, {
54
- planId: 'test-plan-id-2'
55
- }]
38
+ lineItems: [
39
+ {
40
+ planId: 'test-plan-id-1'
41
+ },
42
+ {
43
+ planId: 'test-plan-id-2'
44
+ }
45
+ ]
56
46
  }
57
47
  });
58
48
 
@@ -61,31 +51,12 @@ describe('Storefront API Plan', () => {
61
51
  });
62
52
  });
63
53
 
64
- it ('should throw errors with no configs or options', () => {
65
- const NoConfigOrOptionsError = new Error('Could not use Rebilly Instruments configurations or mount options to fetch Rebilly data');
66
- const noConfigOrOptionsInstance = new TestPlansInstance({
67
- configs: null,
68
- options: null,
69
- });
70
- const noConfigInstance = new TestPlansInstance({
71
- configs: null,
72
- options: {},
73
- });
74
- const noOptionsInstance = new TestPlansInstance({
75
- configs: {},
76
- options: null,
54
+ it('should throw errors with no options', async () => {
55
+ const noConfigOrOptionsInstance = new StorefontTestingInstance({
56
+ options: null
77
57
  });
78
-
79
- expect(async () => {
80
- await noConfigOrOptionsInstance.fetchPlans();
81
- }).rejects.toEqual(NoConfigOrOptionsError);
82
-
83
- expect(async () => {
84
- await noConfigInstance.fetchPlans();
85
- }).rejects.toEqual(NoConfigOrOptionsError);
86
-
87
- expect(async () => {
88
- await noOptionsInstance.fetchPlans();
89
- }).rejects.toEqual(NoConfigOrOptionsError);
58
+ await expectConfigurationError(
59
+ fetchPlans({ state: noConfigOrOptionsInstance })
60
+ );
90
61
  });
91
62
  });
@@ -1,30 +1,26 @@
1
1
  import ProductModel from './models/product-model';
2
+ import { Endpoint } from './index';
2
3
 
3
- export async function FetchProducts ({
4
- data = null
5
- } = {}) {
6
- if (!this.storefront) {
7
- throw new Error('Could not access rebilly-js-sdk instance');
8
- }
9
-
10
- if (!this.configs || !this.options) {
11
- throw new Error('Could not use Rebilly Instruments configurations or mount options to fetch Rebilly data');
12
- }
13
-
14
- try {
15
- const plansData = data || [];
4
+ export async function fetchProducts({ state }) {
5
+ return Endpoint({state}, async () => {
6
+ if (state.data.plans === null) {
7
+ return null;
8
+ }
16
9
 
10
+ const plansData = state.data.plans || [];
17
11
  const filterByProductId = {
18
- filter: '',
19
- }
12
+ filter: ''
13
+ };
20
14
 
21
15
  if (plansData.length) {
22
- filterByProductId.filter = `id:${plansData.map(item => item.productId).join(',')}`;
16
+ filterByProductId.filter = `id:${plansData
17
+ .map((item) => item.productId)
18
+ .join(',')}`;
23
19
  }
24
20
 
25
- const {items: productItems} = await this.storefront.products.getAll(filterByProductId);
26
- return productItems.map(({fields}) => new ProductModel(fields));
27
- } catch (error) {
28
- throw error;
29
- }
30
- };
21
+ const { items: productItems } = await state.storefront.products.getAll(
22
+ filterByProductId
23
+ );
24
+ return productItems.map(({ fields }) => new ProductModel(fields));
25
+ });
26
+ }
@@ -1,36 +1,22 @@
1
- import { MockStorefront } from 'tests/mocks/storefront-mock';
1
+ import { StorefontTestingInstance } from 'tests/mocks/storefront-mock';
2
2
  import { ok, get } from 'msw-when-then';
3
3
  import { when } from 'tests/msw/server';
4
4
  import { storefrontURL } from 'tests/mocks/storefront-api-mock';
5
- import { FetchProducts } from './products';
5
+ import { fetchProducts } from './products';
6
6
  import ProductModel from './models/product-model';
7
+ import { expectConfigurationError } from 'tests/async-utilities';
7
8
 
8
9
  describe('Storefront API Plan', () => {
9
- class TestProductsInstance {
10
- constructor({
11
- configs = {},
12
- options = {}
13
- } = {}) {
14
- this.configs = configs;
15
- this.options = options;
16
- this.storefront = MockStorefront();
17
- }
18
-
19
- FetchProducts(...args) {
20
- return FetchProducts.apply(this, args);
21
- }
22
- }
23
-
24
- it ('can fetch products', async () => {
25
- const testProduct = {name: 'Test Product', id: 'test-product-id-1'};
10
+ it('can fetch products', async () => {
11
+ const testProduct = { name: 'Test Product', id: 'test-product-id-1' };
26
12
 
27
13
  when(get(`${storefrontURL}/products`)).thenReturn(ok([testProduct]));
28
14
 
29
- const instance = new TestProductsInstance();
15
+ const instance = new StorefontTestingInstance();
30
16
 
31
17
  jest.spyOn(instance.storefront.products, 'getAll');
32
18
 
33
- const response = await instance.FetchProducts({});
19
+ const response = await fetchProducts({ state: instance });
34
20
 
35
21
  expect(instance.storefront.products.getAll).toBeCalledTimes(1);
36
22
  expect(instance.storefront.products.getAll).toBeCalledWith({
@@ -41,52 +27,35 @@ describe('Storefront API Plan', () => {
41
27
  expect(response).toEqual([new ProductModel(testProduct)]);
42
28
  });
43
29
 
44
- it ('can fetch products with filter', async () => {
45
- const instance = new TestProductsInstance();
46
-
47
- jest.spyOn(instance.storefront.products, 'getAll');
48
-
49
- await instance.FetchProducts({
50
- data: [
30
+ it('can fetch products with filter', async () => {
31
+ const instance = new StorefontTestingInstance({
32
+ data: {
33
+ plans: [
51
34
  {
52
35
  productId: 'test-product-1'
53
36
  },
54
37
  {
55
38
  productId: 'test-product-2'
56
39
  }
57
- ],
40
+ ]
41
+ }
58
42
  });
59
43
 
44
+ jest.spyOn(instance.storefront.products, 'getAll');
45
+
46
+ await fetchProducts({ state: instance });
47
+
60
48
  expect(instance.storefront.products.getAll).toBeCalledWith({
61
49
  filter: 'id:test-product-1,test-product-2'
62
50
  });
63
51
  });
64
52
 
65
- it ('should throw errors with no configs or options', () => {
66
- const NoConfigOrOptionsError = new Error('Could not use Rebilly Instruments configurations or mount options to fetch Rebilly data');
67
- const noConfigOrOptionsInstance = new TestProductsInstance({
68
- configs: null,
69
- options: null,
70
- });
71
- const noConfigInstance = new TestProductsInstance({
72
- configs: null,
73
- options: {},
74
- });
75
- const noOptionsInstance = new TestProductsInstance({
76
- configs: {},
77
- options: null,
53
+ it('should throw errors with no options', async () => {
54
+ const noConfigOrOptionsInstance = new StorefontTestingInstance({
55
+ options: null
78
56
  });
79
-
80
- expect(async () => {
81
- await noConfigOrOptionsInstance.FetchProducts();
82
- }).rejects.toEqual(NoConfigOrOptionsError);
83
-
84
- expect(async () => {
85
- await noConfigInstance.FetchProducts();
86
- }).rejects.toEqual(NoConfigOrOptionsError);
87
-
88
- expect(async () => {
89
- await noOptionsInstance.FetchProducts();
90
- }).rejects.toEqual(NoConfigOrOptionsError);
57
+ await expectConfigurationError(
58
+ fetchProducts({ state: noConfigOrOptionsInstance })
59
+ );
91
60
  });
92
61
  });
@@ -1,19 +1,19 @@
1
- export async function PostPurchase (data) {
2
- if (!this.storefront) {
3
- throw new Error('Could not access rebilly-js-sdk instance');
4
- }
1
+ import { Endpoint } from './index';
5
2
 
6
- if (!this.configs || !this.options) {
7
- throw new Error('Could not use Rebilly Instruments configurations or mount options to fetch Rebilly data');
8
- }
3
+ export async function postPurchase({ data, state }) {
4
+ return Endpoint({state}, async () => {
5
+ if (data._raw) {
6
+ delete data._raw;
7
+ }
8
+ return state.storefront.purchase.purchase({ data });
9
+ });
10
+ }
9
11
 
10
- try {
12
+ export async function postPayment({ data, state }) {
13
+ return Endpoint({state}, async () => {
11
14
  if (data._raw) {
12
15
  delete data._raw;
13
16
  }
14
- const resp = await this.storefront.purchase.purchase({data});
15
- return resp;
16
- } catch (error) {
17
- throw error;
18
- }
19
- };
17
+ return state.storefront.purchase.payment({ data });
18
+ });
19
+ }
@@ -1,40 +1,26 @@
1
- import { MockStorefront } from 'tests/mocks/storefront-mock';
1
+ import { StorefontTestingInstance } from 'tests/mocks/storefront-mock';
2
2
  import { ok, post } from 'msw-when-then';
3
3
  import { when } from 'tests/msw/server';
4
4
  import { storefrontURL } from 'tests/mocks/storefront-api-mock';
5
- import { PostPurchase } from './purchase';
6
5
 
7
6
  describe('Storefront API Purchase', () => {
8
- class TestPurchaseInstance {
9
- constructor({
10
- configs = {},
11
- options = {}
12
- } = {}) {
13
- this.configs = configs;
14
- this.options = options;
15
- this.storefront = MockStorefront();
16
- }
17
-
18
- postPurchase(...args) {
19
- return PostPurchase.apply(this, args);
20
- }
21
- }
22
-
23
- it ('can make purchase', async () => {
24
- const instance = new TestPurchaseInstance();
7
+ it('can make purchase', async () => {
8
+ const instance = StorefontTestingInstance();
25
9
  const payload = {
26
10
  websiteId: 'test-website-id',
27
- items: [{
28
- planId: 'test-plan-id-1',
29
- quantity: 1
30
- }],
11
+ items: [
12
+ {
13
+ planId: 'test-plan-id-1',
14
+ quantity: 1
15
+ }
16
+ ],
31
17
  billingAddress: {
32
18
  firstName: 'Test',
33
19
  lastName: 'Customer'
34
20
  },
35
21
  paymentInstruction: {
36
- token: 'test-token',
37
- },
22
+ token: 'test-token'
23
+ }
38
24
  };
39
25
  const fields = {
40
26
  orderId: 'test-order-id',
@@ -44,17 +30,19 @@ describe('Storefront API Purchase', () => {
44
30
  transaction: {
45
31
  id: 'test-transaction-id'
46
32
  }
47
- }
33
+ };
48
34
 
49
35
  when(post(`${storefrontURL}/purchase`)).thenReturn(ok(fields));
50
36
 
51
37
  jest.spyOn(instance.storefront.purchase, 'purchase');
52
38
 
53
- const requestResponse = await instance.storefront.purchase.purchase(payload);
39
+ const requestResponse = await instance.storefront.purchase.purchase(
40
+ payload
41
+ );
54
42
 
55
43
  expect(instance.storefront.purchase.purchase).toBeCalledTimes(1);
56
44
  expect(instance.storefront.purchase.purchase).toBeCalledWith(payload);
57
-
45
+
58
46
  expect(requestResponse.config).toBeInstanceOf(Object);
59
47
  expect(requestResponse.fields).toBeInstanceOf(Object);
60
48
  expect(requestResponse.response).toBeInstanceOf(Object);
@@ -62,4 +50,4 @@ describe('Storefront API Purchase', () => {
62
50
  expect(requestResponse.fields).toEqual(fields);
63
51
  expect(requestResponse.fields).toMatchObject(fields);
64
52
  });
65
- });
53
+ });
@@ -1,36 +1,39 @@
1
1
  import { collectData } from '@rebilly/risk-data-collector';
2
2
  import ReadyToPayModel from './models/ready-to-pay-model';
3
+ import { Endpoint } from './index';
3
4
 
4
- export async function FetchReadyToPay (riskMetadata = null) {
5
- if (!this.storefront) {
6
- throw new Error('Could not access rebilly-js-sdk instance');
7
- }
8
-
9
- if (!this.configs || !this.options) {
10
- throw new Error('Could not use Rebilly Instruments configurations or mount options to fetch Rebilly data');
11
- }
12
-
13
- try {
5
+ export async function fetchReadyToPay({ state, riskMetadata = null }) {
6
+ return Endpoint({state}, async () => {
14
7
  if (!riskMetadata) {
15
- const {riskMetadata: data} = await collectData();
8
+ const { riskMetadata: data } = await collectData();
16
9
  riskMetadata = data;
17
10
  }
18
- const websiteId = this.configs?.websiteId || null;
19
- const items = this.options?.intent?.items || [];
11
+ const websiteId = state.options?.websiteId || null;
20
12
 
21
13
  const data = {
22
- items,
23
14
  websiteId,
24
15
  riskMetadata
25
16
  };
26
17
 
27
- const {fields: readyToPayFields} = await this.storefront.purchase.readyToPay({data});
18
+ if (state.options?.items) {
19
+ data.items = state.options.items;
20
+ }
21
+
22
+ if (state.data?.amountAndCurrency) {
23
+ const money = state.data.amountAndCurrency;
24
+ data.amount = money.amount;
25
+ data.currency = money.currency;
26
+ }
27
+
28
+ const { fields: readyToPayFields } =
29
+ await state.storefront.purchase.readyToPay({ data });
28
30
 
29
- return Object.values(readyToPayFields).map((fields, index) => new ReadyToPayModel({
30
- index,
31
- ...fields,
32
- }));
33
- } catch (error) {
34
- throw error;
35
- }
36
- };
31
+ return Object.values(readyToPayFields).map(
32
+ (fields, index) =>
33
+ new ReadyToPayModel({
34
+ index,
35
+ ...fields
36
+ })
37
+ );
38
+ });
39
+ }
@@ -1,100 +1,70 @@
1
- import { MockStorefront } from 'tests/mocks/storefront-mock';
1
+ import { StorefontTestingInstance } from 'tests/mocks/storefront-mock';
2
2
  import { ok, post } from 'msw-when-then';
3
3
  import { when } from 'tests/msw/server';
4
4
  import { storefrontURL } from 'tests/mocks/storefront-api-mock';
5
- import { FetchReadyToPay } from './ready-to-pay';
5
+ import { fetchReadyToPay } from './ready-to-pay';
6
6
  import ReadyToPayModel from './models/ready-to-pay-model';
7
+ import { expectConfigurationError } from 'tests/async-utilities';
7
8
 
8
9
  describe('Storefront API Ready to Pay', () => {
9
- class TestReadyToPayInstance {
10
- constructor({
11
- configs = {},
12
- options = {}
13
- } = {}) {
14
- this.configs = configs;
15
- this.options = options;
16
- this.storefront = MockStorefront();
17
- }
18
-
19
- fetchReadyToPay(...args) {
20
- return FetchReadyToPay.apply(this, args);
21
- }
22
- }
23
-
24
- it ('can fetch ready to pay', async () => {
25
- const readyToPayPayload = [{
26
- method: 'payment-card',
27
- feature:null,
28
- brands: ['Visa'],
29
- filters:[]
30
- }];
31
- const configs = {
32
- websiteId: 'test-website-id'
33
- };
34
- const options = {
35
- intent: {
36
- items: [
37
- {
38
- planId: 'test-plan-id',
39
- quantity: 1
40
- }
41
- ]
10
+ it('can fetch ready to pay', async () => {
11
+ const readyToPayPayload = [
12
+ {
13
+ method: 'payment-card',
14
+ feature: null,
15
+ brands: ['Visa'],
16
+ filters: []
42
17
  }
18
+ ];
19
+ const options = {
20
+ websiteId: 'test-website-id',
21
+ items: [
22
+ {
23
+ planId: 'test-plan-id',
24
+ quantity: 1
25
+ }
26
+ ]
43
27
  };
44
28
 
45
- when(post(`${storefrontURL}/ready-to-pay`)).thenReturn(ok(readyToPayPayload));
29
+ when(post(`${storefrontURL}/ready-to-pay`)).thenReturn(
30
+ ok(readyToPayPayload)
31
+ );
46
32
 
47
- const instance = new TestReadyToPayInstance({
48
- configs,
49
- options,
33
+ const instance = StorefontTestingInstance({
34
+ options
50
35
  });
51
36
 
52
37
  jest.spyOn(instance.storefront.purchase, 'readyToPay');
53
38
 
54
- const response = await instance.fetchReadyToPay();
55
-
39
+ const riskMetadata = null;
40
+ const response = await fetchReadyToPay({ state: instance, riskMetadata });
41
+
56
42
  expect(instance.storefront.purchase.readyToPay).toBeCalledTimes(1);
57
43
  expect(instance.storefront.purchase.readyToPay).toBeCalledWith({
58
44
  data: {
59
- items: options.intent.items,
60
- websiteId: configs.websiteId,
45
+ items: options.items,
46
+ websiteId: options.websiteId,
61
47
  riskMetadata: {}
62
48
  }
63
49
  });
64
50
  expect(response).toBeInstanceOf(Array);
65
51
  expect(response[0]).toBeInstanceOf(ReadyToPayModel);
66
- expect(response)
67
- .toEqual([new ReadyToPayModel({
52
+ expect(response).toEqual([
53
+ new ReadyToPayModel({
68
54
  index: 0,
69
55
  ...readyToPayPayload[0]
70
- })]);
56
+ })
57
+ ]);
71
58
  });
72
59
 
73
- it ('should throw errors with no configs or options', () => {
74
- const NoConfigOrOptionsError = new Error('Could not use Rebilly Instruments configurations or mount options to fetch Rebilly data');
75
- const noConfigOrOptionsInstance = new TestReadyToPayInstance({
76
- configs: null,
77
- options: null,
78
- });
79
- const noConfigInstance = new TestReadyToPayInstance({
80
- configs: null,
81
- options: {},
82
- });
83
- const noOptionsInstance = new TestReadyToPayInstance({
84
- configs: {},
85
- options: null,
86
- });
87
-
88
- expect(async () => {
89
- await noConfigOrOptionsInstance.fetchReadyToPay();
90
- }).rejects.toEqual(NoConfigOrOptionsError);
60
+ it('should throw errors with no options', async () => {
61
+ const riskMetadata = null;
91
62
 
92
- expect(async () => {
93
- await noConfigInstance.fetchReadyToPay();
94
- }).rejects.toEqual(NoConfigOrOptionsError);
95
-
96
- expect(async () => {
97
- await noOptionsInstance.fetchReadyToPay();
98
- }).rejects.toEqual(NoConfigOrOptionsError);
63
+ const noConfigOrOptionsInstance = new StorefontTestingInstance({
64
+ options: null
65
+ });
66
+ await expectConfigurationError(
67
+ fetchReadyToPay({ riskMetadata, state: noConfigOrOptionsInstance })
68
+ );
99
69
  });
100
70
  });
@@ -11,4 +11,4 @@ describe('Storefront application programming interface', () => {
11
11
  expect(storefront).toHaveProperty('purchase');
12
12
  expect(storefront.purchase).toHaveProperty('readyToPay');
13
13
  });
14
- });
14
+ });