@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.
- package/.babelrc +13 -4
- package/.eslintrc.js +3 -0
- package/.prettierrc.js +11 -0
- package/README.md +15 -314
- package/dist/events/base-event.js +6 -9
- package/dist/events/events.spec.js +4 -4
- package/dist/events/index.js +2 -1
- package/dist/functions/destroy.js +12 -14
- package/dist/functions/destroy.spec.js +3 -3
- package/dist/functions/mount/fetch-data.js +183 -0
- package/dist/functions/mount/fetch-data.spec.js +189 -0
- package/dist/functions/mount/index.js +158 -251
- package/dist/functions/mount/mount.spec.js +24 -121
- package/dist/functions/mount/setup-element.js +40 -0
- package/dist/functions/mount/setup-framepay.js +46 -0
- package/dist/functions/mount/setup-i18n.js +33 -0
- package/dist/functions/mount/setup-options.js +96 -0
- package/dist/functions/mount/setup-options.spec.js +66 -0
- package/dist/functions/mount/setup-storefront.js +34 -0
- package/dist/functions/mount/setup-styles.js +43 -0
- package/dist/functions/on.js +13 -4
- package/dist/functions/on.spec.js +19 -5
- package/dist/functions/purchase.js +139 -22
- package/dist/functions/purchase.spec.js +23 -19
- package/dist/functions/setup.js +85 -0
- package/dist/functions/setup.spec.js +87 -0
- package/dist/functions/show.js +31 -14
- package/dist/functions/show.spec.js +47 -18
- package/dist/functions/update.js +53 -27
- package/dist/functions/update.spec.js +40 -21
- package/dist/i18n/en.json +4 -1
- package/dist/i18n/es.json +4 -1
- package/dist/index.js +67 -56
- package/dist/index.spec.js +7 -27
- package/dist/loader/index.js +4 -3
- package/dist/storefront/index.js +33 -0
- package/dist/storefront/invoices.js +27 -0
- package/dist/storefront/models/base-model.js +18 -0
- package/dist/storefront/models/invoice-model.js +14 -0
- package/dist/storefront/models/plan-model.js +4 -35
- package/dist/storefront/models/product-model.js +4 -23
- package/dist/storefront/models/summary-model.js +12 -25
- package/dist/storefront/models/transaction-model.js +31 -0
- package/dist/storefront/payment-instruments.js +47 -0
- package/dist/storefront/payment-instruments.spec.js +55 -0
- package/dist/storefront/plans.js +15 -24
- package/dist/storefront/plans.spec.js +17 -44
- package/dist/storefront/products.js +16 -20
- package/dist/storefront/products.spec.js +25 -49
- package/dist/storefront/purchase.js +28 -16
- package/dist/storefront/purchase.spec.js +4 -22
- package/dist/storefront/ready-to-pay.js +26 -22
- package/dist/storefront/ready-to-pay.spec.js +25 -54
- package/dist/storefront/storefront.spec.js +1 -1
- package/dist/storefront/summary.js +27 -24
- package/dist/storefront/summary.spec.js +44 -86
- package/dist/storefront/transactions.js +27 -0
- package/dist/style/base/theme.js +3 -3
- package/dist/style/components/methods.js +43 -42
- package/dist/style/utils/color-values.js +1 -3
- package/dist/style/views/confirmation.js +0 -4
- package/dist/style/views/method-selector.js +1 -1
- package/dist/style/views/modal.js +3 -1
- package/dist/style/views/summary.js +5 -1
- package/dist/utils/format-currency.js +4 -2
- package/dist/utils/has-valid-css-selector.js +1 -1
- package/dist/utils/process-property-as-dom-element.js +0 -2
- package/dist/views/__snapshots__/summary.spec.js.snap +103 -113
- package/dist/views/common/iframe/base-iframe.js +10 -2
- package/dist/views/common/iframe/modal-iframe.js +44 -3
- package/dist/views/confirmation.js +44 -20
- package/dist/views/method-selector/express-methods/apple-pay.js +92 -0
- package/dist/views/method-selector/express-methods/google-pay.js +31 -0
- package/dist/views/method-selector/express-methods/paypal.js +19 -0
- package/dist/views/method-selector/generate-digital-wallet.js +68 -0
- package/dist/views/method-selector/generate-digital-wallet.spec.js +135 -0
- package/dist/views/method-selector/get-payment-methods.js +28 -8
- package/dist/views/method-selector/get-payment-methods.spec.js +25 -26
- package/dist/views/method-selector/index.js +55 -86
- package/dist/views/method-selector/method-selector.spec.js +80 -69
- package/dist/views/method-selector/mount-express-methods.js +38 -62
- package/dist/views/method-selector/mount-methods.js +18 -18
- package/dist/views/modal.js +21 -15
- package/dist/views/result.js +13 -16
- package/dist/views/summary.js +170 -114
- package/dist/views/summary.spec.js +72 -76
- package/package.json +5 -4
- package/src/events/base-event.js +15 -17
- package/src/events/events.spec.js +6 -4
- package/src/events/index.js +6 -3
- package/src/functions/destroy.js +12 -13
- package/src/functions/destroy.spec.js +30 -31
- package/src/functions/mount/fetch-data.js +148 -0
- package/src/functions/mount/fetch-data.spec.js +238 -0
- package/src/functions/mount/index.js +129 -244
- package/src/functions/mount/mount.spec.js +35 -139
- package/src/functions/mount/setup-element.js +26 -0
- package/src/functions/mount/setup-framepay.js +41 -0
- package/src/functions/mount/setup-i18n.js +19 -0
- package/src/functions/mount/setup-options.js +100 -0
- package/src/functions/mount/setup-options.spec.js +60 -0
- package/src/functions/mount/setup-storefront.js +24 -0
- package/src/functions/mount/setup-styles.js +30 -0
- package/src/functions/on.js +13 -8
- package/src/functions/on.spec.js +30 -17
- package/src/functions/purchase.js +101 -19
- package/src/functions/purchase.spec.js +18 -18
- package/src/functions/setup.js +48 -0
- package/src/functions/setup.spec.js +98 -0
- package/src/functions/show.js +20 -10
- package/src/functions/show.spec.js +43 -22
- package/src/functions/update.js +50 -27
- package/src/functions/update.spec.js +57 -22
- package/src/i18n/en.json +4 -1
- package/src/i18n/es.json +4 -1
- package/src/i18n/i18n.spec.js +6 -4
- package/src/i18n/index.js +14 -11
- package/src/index.js +41 -52
- package/src/index.spec.js +8 -37
- package/src/loader/index.js +51 -47
- package/src/loader/loader.spec.js +26 -19
- package/src/storefront/index.js +37 -7
- package/src/storefront/invoices.js +11 -0
- package/src/storefront/models/base-model.js +10 -0
- package/src/storefront/models/invoice-model.js +3 -0
- package/src/storefront/models/plan-model.js +3 -35
- package/src/storefront/models/product-model.js +3 -23
- package/src/storefront/models/ready-to-pay-model.js +3 -3
- package/src/storefront/models/summary-model.js +15 -29
- package/src/storefront/models/transaction-model.js +19 -0
- package/src/storefront/payment-instruments.js +30 -0
- package/src/storefront/payment-instruments.spec.js +69 -0
- package/src/storefront/plans.js +16 -23
- package/src/storefront/plans.spec.js +25 -54
- package/src/storefront/products.js +18 -22
- package/src/storefront/products.spec.js +23 -54
- package/src/storefront/purchase.js +14 -14
- package/src/storefront/purchase.spec.js +17 -29
- package/src/storefront/ready-to-pay.js +26 -23
- package/src/storefront/ready-to-pay.spec.js +41 -71
- package/src/storefront/storefront.spec.js +1 -1
- package/src/storefront/summary.js +26 -22
- package/src/storefront/summary.spec.js +60 -109
- package/src/storefront/transactions.js +11 -0
- package/src/style/base/theme.js +10 -8
- package/src/style/base/theme.spec.js +4 -2
- package/src/style/browserslist.js +1 -3
- package/src/style/components/button.js +3 -1
- package/src/style/components/forms/checkbox.js +3 -1
- package/src/style/components/index.js +1 -1
- package/src/style/components/loader.js +3 -1
- package/src/style/components/methods.js +43 -42
- package/src/style/helpers/index.js +1 -1
- package/src/style/index.js +2 -1
- package/src/style/utils/color-values.js +4 -4
- package/src/style/vendor/framepay.js +1 -1
- package/src/style/vendor/postmate.js +1 -1
- package/src/style/views/confirmation.js +0 -4
- package/src/style/views/index.js +1 -1
- package/src/style/views/method-selector.js +1 -1
- package/src/style/views/modal.js +4 -2
- package/src/style/views/summary.js +5 -1
- package/src/utils/add-dom-element.js +12 -13
- package/src/utils/format-currency.js +6 -2
- package/src/utils/has-valid-css-selector.js +2 -2
- package/src/utils/is-dom-element.js +1 -1
- package/src/utils/process-property-as-dom-element.js +27 -24
- package/src/utils/sleep.js +1 -1
- package/src/views/__snapshots__/summary.spec.js.snap +103 -113
- package/src/views/common/iframe/base-iframe.js +12 -4
- package/src/views/common/iframe/event-listeners.js +6 -6
- package/src/views/common/iframe/index.js +1 -1
- package/src/views/common/iframe/method-iframe.js +3 -6
- package/src/views/common/iframe/modal-iframe.js +42 -6
- package/src/views/common/iframe/view-iframe.js +3 -5
- package/src/views/common/render-utilities.js +3 -3
- package/src/views/confirmation.js +34 -25
- package/src/views/method-selector/express-methods/apple-pay.js +78 -0
- package/src/views/method-selector/express-methods/google-pay.js +24 -0
- package/src/views/method-selector/express-methods/paypal.js +7 -0
- package/src/views/method-selector/generate-digital-wallet.js +51 -0
- package/src/views/method-selector/generate-digital-wallet.spec.js +135 -0
- package/src/views/method-selector/get-method-data.js +7 -4
- package/src/views/method-selector/get-payment-methods.js +38 -29
- package/src/views/method-selector/get-payment-methods.spec.js +26 -33
- package/src/views/method-selector/index.js +70 -99
- package/src/views/method-selector/method-selector.spec.js +88 -78
- package/src/views/method-selector/mount-express-methods.js +36 -60
- package/src/views/method-selector/mount-methods.js +32 -21
- package/src/views/modal.js +37 -23
- package/src/views/result.js +12 -15
- package/src/views/summary.js +169 -101
- package/src/views/summary.spec.js +99 -74
- package/tests/async-utilities.js +22 -0
- package/tests/mocks/rebilly-instruments-mock.js +89 -77
- package/tests/mocks/storefront-api-mock.js +8 -0
- package/tests/mocks/storefront-mock.js +17 -0
- package/dist/events/purchase-completed.js +0 -24
- package/dist/functions/initialize.js +0 -82
- package/dist/functions/initialize.spec.js +0 -34
- package/dist/functions/mount/fetch-summary-data.js +0 -31
- package/dist/functions/mount/fetch-summary-data.spec.js +0 -45
- package/dist/views/method-selector/process-digital-wallet-options.js +0 -35
- package/dist/views/method-selector/process-digital-wallet-options.spec.js +0 -80
- package/src/events/purchase-completed.js +0 -11
- package/src/functions/initialize.js +0 -74
- package/src/functions/initialize.spec.js +0 -38
- package/src/functions/mount/fetch-summary-data.js +0 -26
- package/src/functions/mount/fetch-summary-data.spec.js +0 -46
- package/src/views/method-selector/process-digital-wallet-options.js +0 -16
- package/src/views/method-selector/process-digital-wallet-options.spec.js +0 -94
package/src/storefront/plans.js
CHANGED
|
@@ -1,30 +1,23 @@
|
|
|
1
1
|
import PlanModel from './models/plan-model';
|
|
2
|
+
import { Endpoint } from './index';
|
|
2
3
|
|
|
3
|
-
export async function
|
|
4
|
-
|
|
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
|
|
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
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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 {
|
|
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 {
|
|
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
|
-
|
|
10
|
-
|
|
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
|
|
15
|
+
const instance = new StorefontTestingInstance();
|
|
30
16
|
|
|
31
17
|
jest.spyOn(instance.storefront.plans, 'getAll');
|
|
32
18
|
|
|
33
|
-
const response = await
|
|
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
|
|
45
|
-
const instance = new
|
|
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
|
|
35
|
+
await fetchPlans({
|
|
36
|
+
state: instance,
|
|
50
37
|
data: {
|
|
51
|
-
lineItems: [
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
|
65
|
-
const
|
|
66
|
-
|
|
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
|
-
|
|
80
|
-
|
|
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
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
|
16
|
+
filterByProductId.filter = `id:${plansData
|
|
17
|
+
.map((item) => item.productId)
|
|
18
|
+
.join(',')}`;
|
|
23
19
|
}
|
|
24
20
|
|
|
25
|
-
const {items: productItems} = await
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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 {
|
|
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 {
|
|
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
|
-
|
|
10
|
-
|
|
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
|
|
15
|
+
const instance = new StorefontTestingInstance();
|
|
30
16
|
|
|
31
17
|
jest.spyOn(instance.storefront.products, 'getAll');
|
|
32
18
|
|
|
33
|
-
const response = await
|
|
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
|
|
45
|
-
const instance = new
|
|
46
|
-
|
|
47
|
-
|
|
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
|
|
66
|
-
const
|
|
67
|
-
|
|
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
|
-
|
|
81
|
-
|
|
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
|
-
|
|
2
|
-
if (!this.storefront) {
|
|
3
|
-
throw new Error('Could not access rebilly-js-sdk instance');
|
|
4
|
-
}
|
|
1
|
+
import { Endpoint } from './index';
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
throw error;
|
|
18
|
-
}
|
|
19
|
-
};
|
|
17
|
+
return state.storefront.purchase.payment({ data });
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -1,40 +1,26 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
9
|
-
|
|
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
|
-
|
|
29
|
-
|
|
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(
|
|
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
|
|
5
|
-
|
|
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 =
|
|
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
|
-
|
|
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(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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 {
|
|
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 {
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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(
|
|
29
|
+
when(post(`${storefrontURL}/ready-to-pay`)).thenReturn(
|
|
30
|
+
ok(readyToPayPayload)
|
|
31
|
+
);
|
|
46
32
|
|
|
47
|
-
const instance =
|
|
48
|
-
|
|
49
|
-
options,
|
|
33
|
+
const instance = StorefontTestingInstance({
|
|
34
|
+
options
|
|
50
35
|
});
|
|
51
36
|
|
|
52
37
|
jest.spyOn(instance.storefront.purchase, 'readyToPay');
|
|
53
38
|
|
|
54
|
-
const
|
|
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.
|
|
60
|
-
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
|
-
|
|
52
|
+
expect(response).toEqual([
|
|
53
|
+
new ReadyToPayModel({
|
|
68
54
|
index: 0,
|
|
69
55
|
...readyToPayPayload[0]
|
|
70
|
-
})
|
|
56
|
+
})
|
|
57
|
+
]);
|
|
71
58
|
});
|
|
72
59
|
|
|
73
|
-
it
|
|
74
|
-
const
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
});
|