@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
@@ -3,39 +3,156 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.Purchase = Purchase;
6
+ exports.makePayment = makePayment;
7
+ exports.makePurchase = makePurchase;
8
+ exports.handleApprovalUrl = handleApprovalUrl;
9
+ exports.purchase = purchase;
10
+
11
+ var _purchase = require("../storefront/purchase");
7
12
 
8
13
  var _events = _interopRequireDefault(require("../events"));
9
14
 
15
+ var _modal = require("../views/modal");
16
+
17
+ var _fetchData = require("./mount/fetch-data");
18
+
10
19
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
20
 
12
- async function Purchase(purchasePayload) {
21
+ async function makePayment({
22
+ state,
23
+ payload
24
+ }) {
25
+ const {
26
+ _raw: {
27
+ id: token
28
+ }
29
+ } = payload;
30
+ const data = {
31
+ token,
32
+ ...payload
33
+ };
34
+
35
+ if (state.options.invoiceId) {
36
+ data.invoiceId = state.options.invoiceId;
37
+ }
38
+
39
+ if (state.options.transactionId) {
40
+ data.transactionId = state.options.transactionId;
41
+ }
42
+
43
+ if (state.options.money) {
44
+ data.websiteId = state.options.websiteId;
45
+ data.amount = state.options.money.amount;
46
+ data.currency = state.options.money.currency;
47
+ }
48
+
49
+ let {
50
+ fields
51
+ } = await (0, _purchase.postPayment)({
52
+ state,
53
+ data
54
+ });
55
+ fields = {
56
+ transaction: fields,
57
+ token: fields.token || state.options.customerJwt
58
+ };
59
+
60
+ if (state.data.invoice) {
61
+ fields.invoice = state.data.invoice;
62
+ }
63
+
64
+ return fields;
65
+ }
66
+
67
+ async function makePurchase({
68
+ state,
69
+ payload
70
+ }) {
71
+ const {
72
+ fields
73
+ } = await (0, _purchase.postPurchase)({
74
+ state,
75
+ data: {
76
+ websiteId: state.options.websiteId,
77
+ items: state.options.items,
78
+ paymentInstruction: {
79
+ token: payload._raw.id
80
+ },
81
+ ...payload
82
+ }
83
+ });
84
+ return fields;
85
+ }
86
+
87
+ function handleApprovalUrl({
88
+ state,
89
+ fields
90
+ }) {
91
+ const {
92
+ paymentMethodsUrl
93
+ } = state.options._computed;
94
+ const model = {};
95
+
96
+ if (state.data.isPayment) {
97
+ model.payment = fields;
98
+ } else {
99
+ model.purchase = fields;
100
+ }
101
+
102
+ state.data = new _fetchData.DataInstance({
103
+ state,
104
+ ...fields
105
+ });
106
+ (0, _modal.mountModal)({
107
+ state,
108
+ name: 'rebilly-instruments-approval-url',
109
+ url: `${paymentMethodsUrl}/approval-url`,
110
+ model,
111
+ close: updatedPurchase => {
112
+ _events.default.purchaseCompleted.dispatch(updatedPurchase);
113
+ }
114
+ });
115
+ }
116
+
117
+ async function purchase({
118
+ state,
119
+ payload
120
+ }) {
13
121
  try {
14
- const {
15
- fields: purchase
16
- } = await this._postPurchase(purchasePayload);
17
-
18
- if (purchase.transaction.approvalUrl) {
19
- const {
20
- paymentMethodsUrl
21
- } = this.options._computed;
22
-
23
- this._mountModal({
24
- name: 'rebilly-instruments-approval-url',
25
- url: `${paymentMethodsUrl}/approval-url`,
26
- model: {
27
- purchase
28
- },
29
- close: updatedPurchase => {
30
- // TODO: Check if this is purchase...
31
- _events.default.purchaseCompleted.dispatch(updatedPurchase);
32
- }
122
+ var _fields$transaction;
123
+
124
+ let fields;
125
+
126
+ if (state.data.isPayment) {
127
+ fields = await makePayment({
128
+ state,
129
+ payload
130
+ });
131
+ } else {
132
+ fields = await makePurchase({
133
+ state,
134
+ payload
135
+ });
136
+ }
137
+
138
+ if ((_fields$transaction = fields.transaction) !== null && _fields$transaction !== void 0 && _fields$transaction.approvalUrl) {
139
+ handleApprovalUrl({
140
+ state,
141
+ fields
33
142
  });
34
143
  } else {
35
- _events.default.purchaseCompleted.dispatch(purchase);
144
+ _events.default.purchaseCompleted.dispatch(fields);
36
145
  }
146
+
147
+ return fields;
37
148
  } catch (error) {
38
149
  // TODO: Display error to customer
150
+ console.error(error);
151
+
152
+ if (error.status === 422) {
153
+ error.details.forEach(e => console.error(e));
154
+ }
155
+
39
156
  return error;
40
157
  }
41
158
  }
@@ -1,29 +1,27 @@
1
1
  "use strict";
2
2
 
3
- var _rebillyInstrumentsMock = require("tests/mocks/rebilly-instruments-mock");
3
+ var _rebillyInstrumentsMock = require("../../tests/mocks/rebilly-instruments-mock");
4
4
 
5
5
  var _mswWhenThen = require("msw-when-then");
6
6
 
7
- var _server = require("tests/msw/server");
7
+ var _server = require("../../tests/msw/server");
8
8
 
9
- var _storefrontApiMock = require("tests/mocks/storefront-api-mock");
9
+ var _storefrontApiMock = require("../../tests/mocks/storefront-api-mock");
10
10
 
11
11
  var _events = _interopRequireDefault(require("../events"));
12
12
 
13
+ var _asyncUtilities = require("../../tests/async-utilities");
14
+
13
15
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
16
 
15
17
  describe('RebillyInstruments purchase', () => {
16
18
  it('should be able to make a purchase', async () => {
17
- const configs = {
18
- websiteId: 'test-website-id'
19
- };
20
19
  const options = {
21
- intent: {
22
- items: [{
23
- planId: 'test-plan-id',
24
- quantity: 1
25
- }]
26
- }
20
+ websiteId: 'test-website-id',
21
+ items: [{
22
+ planId: 'test-plan-id',
23
+ quantity: 1
24
+ }]
27
25
  };
28
26
  const token = {
29
27
  id: 'test-token-id'
@@ -44,14 +42,19 @@ describe('RebillyInstruments purchase', () => {
44
42
  }
45
43
  };
46
44
  (0, _server.when)((0, _mswWhenThen.post)(`${_storefrontApiMock.storefrontURL}/purchase`)).thenReturn((0, _mswWhenThen.ok)(fields));
47
- const rebillyInstruments = (0, _rebillyInstrumentsMock.MockRebillyInstruments)(configs, options);
48
- jest.spyOn(rebillyInstruments.storefront.purchase, 'purchase');
45
+ const rebillyInstruments = await (0, _rebillyInstrumentsMock.RenderMockRebillyInstruments)(options);
46
+ const spyStorefrontPurchase = jest.spyOn(rebillyInstruments.state.storefront.purchase, 'purchase');
49
47
  jest.spyOn(_events.default.purchaseCompleted, 'dispatch');
50
48
  const purchaseCompletedListener = jest.fn();
51
49
  rebillyInstruments.on('purchase-completed', purchaseCompletedListener);
52
50
  const purchasePayload = {
53
- websiteId: rebillyInstruments.configs.websiteId,
54
- items: rebillyInstruments.options.intent.items,
51
+ billingAddress,
52
+ deliveryAddress,
53
+ _raw: token
54
+ };
55
+ const purchasePayloadParsed = {
56
+ websiteId: rebillyInstruments.state.options.websiteId,
57
+ items: rebillyInstruments.state.options.items,
55
58
  billingAddress,
56
59
  deliveryAddress,
57
60
  paymentInstruction: {
@@ -59,12 +62,13 @@ describe('RebillyInstruments purchase', () => {
59
62
  }
60
63
  };
61
64
  await rebillyInstruments.purchase(purchasePayload);
62
- expect(rebillyInstruments.storefront.purchase.purchase).toBeCalledTimes(1);
63
- expect(rebillyInstruments.storefront.purchase.purchase).toBeCalledWith(expect.objectContaining({
64
- data: purchasePayload
65
+ expect(spyStorefrontPurchase).toBeCalledTimes(1);
66
+ expect(spyStorefrontPurchase).toBeCalledWith(expect.objectContaining({
67
+ data: purchasePayloadParsed
65
68
  }));
66
69
  expect(_events.default.purchaseCompleted.dispatch).toBeCalledTimes(1);
67
70
  expect(purchaseCompletedListener).toBeCalledTimes(1);
68
71
  expect(purchaseCompletedListener).toBeCalledWith(expect.objectContaining(fields));
72
+ await (0, _asyncUtilities.avoidUnhandledPromises)();
69
73
  });
70
74
  });
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.setup = setup;
7
+
8
+ var _paymentInstruments = require("../storefront/payment-instruments");
9
+
10
+ var _events = _interopRequireDefault(require("../events"));
11
+
12
+ var _modal = require("../views/modal");
13
+
14
+ var _fetchData = require("./mount/fetch-data");
15
+
16
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
+
18
+ async function setup({
19
+ state,
20
+ payload
21
+ }) {
22
+ try {
23
+ var _state$options;
24
+
25
+ const {
26
+ instrument,
27
+ transaction
28
+ } = await (0, _paymentInstruments.setupPaymentInstrument)({
29
+ state,
30
+ data: {
31
+ token: payload._raw.id,
32
+ websiteId: (_state$options = state.options) === null || _state$options === void 0 ? void 0 : _state$options.websiteId,
33
+ ...payload
34
+ }
35
+ });
36
+ state.data = new _fetchData.DataInstance({
37
+ state,
38
+ instrument,
39
+ transaction
40
+ });
41
+
42
+ if (transaction.approvalUrl) {
43
+ const {
44
+ paymentMethodsUrl
45
+ } = state.options._computed;
46
+ (0, _modal.mountModal)({
47
+ state,
48
+ name: 'rebilly-instruments-approval-url',
49
+ url: `${paymentMethodsUrl}/approval-url`,
50
+ model: {
51
+ setup: {
52
+ transaction
53
+ }
54
+ },
55
+ close: ({
56
+ transaction: updatedTransaction = transaction
57
+ }) => {
58
+ _events.default.setupCompleted.dispatch({
59
+ instrument,
60
+ transaction: updatedTransaction
61
+ });
62
+ }
63
+ });
64
+ } else {
65
+ _events.default.setupCompleted.dispatch({
66
+ instrument,
67
+ transaction
68
+ });
69
+ }
70
+
71
+ return {
72
+ instrument,
73
+ transaction
74
+ };
75
+ } catch (error) {
76
+ // TODO: Display error to customer
77
+ console.error(error);
78
+
79
+ if (error.status === 422) {
80
+ error.details.forEach(e => console.error(e));
81
+ }
82
+
83
+ return error;
84
+ }
85
+ }
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+
3
+ var _rebillyInstrumentsMock = require("../../tests/mocks/rebilly-instruments-mock");
4
+
5
+ var _mswWhenThen = require("msw-when-then");
6
+
7
+ var _server = require("../../tests/msw/server");
8
+
9
+ var _storefrontApiMock = require("../../tests/mocks/storefront-api-mock");
10
+
11
+ var _events = _interopRequireDefault(require("../events"));
12
+
13
+ var _asyncUtilities = require("../../tests/async-utilities");
14
+
15
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
+
17
+ describe('RebillyInstruments setup', () => {
18
+ it('should be able to setup a payment instrument', async () => {
19
+ const options = {
20
+ websiteId: 'test-website-id',
21
+ money: {
22
+ amount: 30,
23
+ currency: 'USD'
24
+ },
25
+ transactionType: 'setup'
26
+ };
27
+ const token = {
28
+ id: 'test-token-id'
29
+ };
30
+ const billingAddress = {
31
+ billing: 'address'
32
+ };
33
+ const deliveryAddress = {
34
+ delivery: 'address'
35
+ };
36
+ const paymentInstrumentFields = {
37
+ id: 'payment-instrument-id'
38
+ };
39
+ const paymentInstrumentSetupFields = {
40
+ id: 'payment-instrument-id',
41
+ approvalUrl: null
42
+ };
43
+ (0, _server.when)((0, _mswWhenThen.post)(`${_storefrontApiMock.storefrontURL}/payment-instruments`)).thenReturn((0, _mswWhenThen.ok)(paymentInstrumentFields));
44
+ (0, _server.when)((0, _mswWhenThen.post)(`${_storefrontApiMock.storefrontURL}/payment-instruments/*/setup`)).thenReturn((0, _mswWhenThen.ok)(paymentInstrumentSetupFields));
45
+ const rebillyInstruments = await (0, _rebillyInstrumentsMock.RenderMockRebillyInstruments)(options);
46
+ const spyCreatePaymentInstrument = jest.spyOn(rebillyInstruments.state.storefront.paymentInstruments, 'create');
47
+ const spySetupPaymentInstrument = jest.spyOn(rebillyInstruments.state.storefront.paymentInstruments, 'setup');
48
+ const spyDispatchSetupCompleted = jest.spyOn(_events.default.setupCompleted, 'dispatch');
49
+ const setupCompletedListener = jest.fn();
50
+ rebillyInstruments.on('setup-completed', setupCompletedListener);
51
+ const setupPayload = {
52
+ billingAddress,
53
+ deliveryAddress,
54
+ ...options.money,
55
+ _raw: token
56
+ };
57
+ rebillyInstruments.mock.data({
58
+ previewPurchase: {
59
+ currency: 'USD',
60
+ total: 30
61
+ }
62
+ });
63
+ await rebillyInstruments.setup(setupPayload);
64
+ expect(spyCreatePaymentInstrument).toBeCalledTimes(1);
65
+ expect(spyCreatePaymentInstrument).toBeCalledWith(expect.objectContaining({
66
+ data: expect.objectContaining({
67
+ token: token.id
68
+ })
69
+ }));
70
+ expect(spySetupPaymentInstrument).toBeCalledTimes(1);
71
+ expect(spySetupPaymentInstrument).toBeCalledWith(expect.objectContaining({
72
+ id: expect.stringContaining(paymentInstrumentFields.id),
73
+ data: expect.objectContaining({
74
+ websiteId: rebillyInstruments.state.options.websiteId,
75
+ currency: 'USD',
76
+ amount: 30
77
+ })
78
+ }));
79
+ expect(spyDispatchSetupCompleted).toBeCalledTimes(1);
80
+ expect(setupCompletedListener).toBeCalledTimes(1);
81
+ expect(setupCompletedListener).toBeCalledWith(expect.objectContaining({
82
+ instrument: paymentInstrumentFields,
83
+ transaction: paymentInstrumentSetupFields
84
+ }));
85
+ await (0, _asyncUtilities.avoidUnhandledPromises)();
86
+ });
87
+ });
@@ -3,33 +3,50 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.Show = Show;
6
+ exports.show = show;
7
+
8
+ var _confirmation = require("../views/confirmation");
9
+
10
+ var _result = require("../views/result");
11
+
12
+ /**
13
+ @typedef ShowParams
14
+ @type {Object}
15
+ @property {string} componentName - The name of the component to render to the form.
16
+ @property {object} payload - The extra data to provide the component.
17
+ @property {object} state - The global state.
18
+ */
7
19
 
8
20
  /**
9
21
  * Register events that will be triggered
10
- * @param {string} componentName - The name of the component to render to the form
11
- * @param {function} payload - The extra data to provide the component
22
+ * @param {ShowParams} params
12
23
  */
13
- async function Show(componentName, payload = {}) {
24
+ async function show({
25
+ componentName,
26
+ payload,
27
+ state
28
+ }) {
14
29
  switch (componentName) {
15
30
  case 'result':
16
- this.iframeComponents = this.iframeComponents.filter(iframe => {
17
- iframe.component.destroy();
31
+ state.iframeComponents = state.iframeComponents.filter(iframe => {
32
+ iframe.destroy();
18
33
  return false;
19
34
  });
20
-
21
- this._mountResult.call(this, payload);
22
-
35
+ (0, _result.mountResult)({
36
+ payload,
37
+ state
38
+ });
23
39
  break;
24
40
 
25
41
  case 'confirmation':
26
- this.iframeComponents = this.iframeComponents.filter(iframe => {
27
- iframe.component.destroy();
42
+ state.iframeComponents = state.iframeComponents.filter(iframe => {
43
+ iframe.destroy();
28
44
  return false;
29
45
  });
30
-
31
- this._mountConfirmation.call(this, payload);
32
-
46
+ (0, _confirmation.mountConfirmation)({
47
+ payload,
48
+ state
49
+ });
33
50
  break;
34
51
 
35
52
  default:
@@ -1,32 +1,61 @@
1
1
  "use strict";
2
2
 
3
- var _rebillyInstrumentsMock = require("tests/mocks/rebilly-instruments-mock");
3
+ var result = _interopRequireWildcard(require("../views/result"));
4
4
 
5
+ var confirmation = _interopRequireWildcard(require("../views/confirmation"));
6
+
7
+ var _rebillyInstrumentsMock = require("../../tests/mocks/rebilly-instruments-mock");
8
+
9
+ var _index = require("../index");
10
+
11
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
12
+
13
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
14
+
15
+ const iframeMock = {
16
+ destroy: jest.fn()
17
+ };
5
18
  describe('RebillyInstruments show', () => {
6
- it('should show result component', () => {
19
+ it('should show result component', async () => {
20
+ const mountResult = jest.spyOn(result, 'mountResult').mockReturnValue(Promise.resolve());
21
+ const instance = new _index.RebillyInstrumentsInstance();
22
+ instance.state.iframeComponents.push(iframeMock);
7
23
  const payload = {
8
24
  test: 'value'
9
25
  };
10
- const rebillyInstruments = (0, _rebillyInstrumentsMock.MockRebillyInstruments)();
11
- rebillyInstruments._mountResult = jest.fn();
12
- rebillyInstruments.show('result', payload);
13
- expect(rebillyInstruments._mountResult).toBeCalledTimes(1);
14
- expect(rebillyInstruments._mountResult).toBeCalledWith(payload);
26
+ await instance.show('result', payload);
27
+ expect(mountResult).toBeCalledTimes(1);
28
+ expect(mountResult).toBeCalledWith({
29
+ payload,
30
+ state: instance.state
31
+ });
32
+ expect(instance.state.iframeComponents).toEqual([]);
15
33
  });
16
- it('should show confirmation component', () => {
34
+ it('should show confirmation component', async () => {
35
+ const mountConfirmation = jest.spyOn(confirmation, 'mountConfirmation').mockReturnValue(Promise.resolve());
36
+ const instance = new _index.RebillyInstrumentsInstance();
37
+ instance.state.iframeComponents.push(iframeMock);
17
38
  const payload = {
18
39
  test: 'value'
19
40
  };
20
- const rebillyInstruments = (0, _rebillyInstrumentsMock.MockRebillyInstruments)();
21
- rebillyInstruments._mountConfirmation = jest.fn();
22
- rebillyInstruments.show('confirmation', payload);
23
- expect(rebillyInstruments._mountConfirmation).toBeCalledTimes(1);
24
- expect(rebillyInstruments._mountConfirmation).toBeCalledWith(payload);
41
+ await instance.show('confirmation', payload);
42
+ expect(mountConfirmation).toBeCalledTimes(1);
43
+ expect(mountConfirmation).toBeCalledWith({
44
+ payload,
45
+ state: instance.state
46
+ });
47
+ expect(instance.state.iframeComponents).toEqual([]);
25
48
  });
26
- it('should fail for non supported component', () => {
27
- const rebillyInstruments = (0, _rebillyInstrumentsMock.MockRebillyInstruments)();
28
- expect(async () => {
29
- rebillyInstruments.show('not-a-component');
30
- }).rejects.toEqual(new Error(`'not-a-component' not a supported component`));
49
+ it('should fail for non supported component', async () => {
50
+ const rebillyInstruments = new _index.RebillyInstrumentsInstance();
51
+ let error;
52
+
53
+ try {
54
+ await rebillyInstruments.show('not-a-component', 'any payload');
55
+ } catch (e) {
56
+ error = e;
57
+ }
58
+
59
+ expect(error.toString()).toBe(`Error: 'not-a-component' not a supported component`);
31
60
  });
32
61
  });
@@ -3,16 +3,37 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.Update = Update;
6
+ exports.update = update;
7
7
 
8
8
  var _lodash = _interopRequireDefault(require("lodash.merge"));
9
9
 
10
- var _lodash2 = _interopRequireDefault(require("lodash.isequal"));
10
+ var _destroy = require("./destroy");
11
+
12
+ var _mount = require("./mount");
11
13
 
12
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
15
 
14
- async function Update(newConfig) {
15
- if (!this.hasMounted) {
16
+ function sanitizeOldPurchaseData({
17
+ newOptions
18
+ }) {
19
+ let purchaseData = {};
20
+ const hasPurchaseDataKeys = Object.keys(newOptions).some(key => ['items', 'money', 'invoiceId', 'transactionId'].includes(key));
21
+ purchaseData = hasPurchaseDataKeys ? {
22
+ items: null,
23
+ money: null,
24
+ invoiceId: null,
25
+ transactionId: null
26
+ } : purchaseData;
27
+ return purchaseData;
28
+ }
29
+
30
+ ;
31
+
32
+ async function update({
33
+ state,
34
+ newOptions = {}
35
+ }) {
36
+ if (!state.hasMounted) {
16
37
  throw Error('Update method cannot be called before mounting instruments');
17
38
  }
18
39
  /**
@@ -20,29 +41,34 @@ async function Update(newConfig) {
20
41
  * https://github.com/Rebilly/framepay/issues/450
21
42
  * That's why this toggle disables real time locale update until that issue is fixed.
22
43
  */
44
+ // const updatingJustLocale =
45
+ // newOptions?.options && isEqual(Object.keys(newOptions), ['locale']);
46
+ // if (updatingJustLocale) {
47
+ // const updatedOptions = merge(state.options, newOptions);
48
+ // const newLocale = newOptions?.locale;
49
+ // state.options = updatedOptions;
50
+ // state.translate.updateTranslationsToNewLocale(newLocale);
51
+ // state.iframeComponents.forEach((iframe) =>
52
+ // iframe.component.call('changeLocale', newLocale)
53
+ // );
54
+ // return;
55
+ // }
23
56
 
24
57
 
25
- const temporaryDisableRealTimeLocaleUpdate = true;
26
- const updatingJustLocale = (newConfig === null || newConfig === void 0 ? void 0 : newConfig.options) && (0, _lodash2.default)(Object.keys(newConfig === null || newConfig === void 0 ? void 0 : newConfig.options), ['locale']);
27
-
28
- if (updatingJustLocale && !temporaryDisableRealTimeLocaleUpdate) {
29
- const updatedOptions = (0, _lodash.default)(this.options, newConfig.options);
30
- const newLocale = newConfig === null || newConfig === void 0 ? void 0 : newConfig.options.locale;
31
- this.options = updatedOptions;
32
- this.translate.updateTranslationsToNewLocale(newLocale);
33
- this.iframeComponents.forEach(iframe => iframe.component.call('changeLocale', newLocale));
34
- return;
35
- }
36
-
37
- const updatedOptions = (0, _lodash.default)(this.options, newConfig.options);
38
- await this.destroy();
39
- this.initialize(this.configs);
40
- this.mount({
41
- form: this.form,
42
- summary: this.summary,
43
- options: updatedOptions,
44
- _dev: this._dev
58
+ const oldOptions = { ...state.options,
59
+ ...sanitizeOldPurchaseData({
60
+ newOptions
61
+ })
62
+ };
63
+ const updatedOptions = (0, _lodash.default)({ ...oldOptions
64
+ }, newOptions);
65
+ await (0, _destroy.destroy)({
66
+ state
45
67
  });
46
- }
47
-
48
- ;
68
+ (0, _mount.mount)({
69
+ state,
70
+ form: state.form,
71
+ summary: state.summary,
72
+ ...updatedOptions
73
+ });
74
+ }