@rebilly/instruments 1.0.1-beta → 1.0.2-beta.10

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 (277) hide show
  1. package/.babelrc +23 -5
  2. package/.eslintrc.js +27 -0
  3. package/.prettierrc.js +11 -0
  4. package/CONTRIBUTING.md +4 -0
  5. package/README.md +361 -2
  6. package/dist/events/base-event.js +51 -37
  7. package/dist/events/events.spec.js +18 -0
  8. package/dist/events/index.js +11 -8
  9. package/dist/functions/destroy.js +27 -5
  10. package/dist/functions/destroy.spec.js +69 -0
  11. package/dist/functions/initialize.js +60 -41
  12. package/dist/functions/initialize.spec.js +13 -13
  13. package/dist/functions/mount/fetch-summary-data.js +46 -0
  14. package/dist/functions/mount/fetch-summary-data.spec.js +44 -0
  15. package/dist/functions/mount/index.js +346 -0
  16. package/dist/functions/mount/mount.spec.js +135 -0
  17. package/dist/functions/on.js +26 -18
  18. package/dist/functions/on.spec.js +45 -63
  19. package/dist/functions/purchase.js +41 -154
  20. package/dist/functions/purchase.spec.js +60 -76
  21. package/dist/functions/show.js +39 -43
  22. package/dist/functions/show.spec.js +57 -0
  23. package/dist/functions/update.js +60 -5
  24. package/dist/functions/update.spec.js +100 -0
  25. package/dist/i18n/en.json +19 -0
  26. package/dist/i18n/es.json +19 -0
  27. package/dist/i18n/i18n.spec.js +6 -23
  28. package/dist/i18n/index.js +44 -67
  29. package/dist/index.js +70 -71
  30. package/dist/index.spec.js +24 -44
  31. package/dist/loader/index.js +63 -62
  32. package/dist/loader/loader.spec.js +14 -11
  33. package/dist/storefront/index.js +28 -39
  34. package/dist/storefront/models/plan-model.js +37 -54
  35. package/dist/storefront/models/product-model.js +25 -36
  36. package/dist/storefront/models/ready-to-pay-model.js +38 -42
  37. package/dist/storefront/models/summary-model.js +72 -99
  38. package/dist/storefront/plans.js +37 -84
  39. package/dist/storefront/plans.spec.js +61 -151
  40. package/dist/storefront/products.js +35 -83
  41. package/dist/storefront/products.spec.js +60 -150
  42. package/dist/storefront/purchase.js +27 -64
  43. package/dist/storefront/purchase.spec.js +51 -87
  44. package/dist/storefront/ready-to-pay.js +45 -107
  45. package/dist/storefront/ready-to-pay.spec.js +72 -147
  46. package/dist/storefront/storefront.spec.js +6 -6
  47. package/dist/storefront/summary.js +37 -84
  48. package/dist/storefront/summary.spec.js +135 -240
  49. package/dist/style/base/__snapshots__/theme.spec.js.snap +52 -0
  50. package/dist/style/base/index.js +72 -0
  51. package/dist/style/base/theme.js +73 -0
  52. package/dist/style/base/theme.spec.js +30 -0
  53. package/dist/style/browserslist.js +8 -0
  54. package/dist/style/components/address.js +64 -0
  55. package/dist/style/components/button.js +61 -0
  56. package/dist/style/components/divider.js +48 -0
  57. package/dist/style/components/forms/checkbox.js +83 -0
  58. package/dist/style/components/forms/field.js +53 -0
  59. package/dist/style/components/forms/form.js +28 -0
  60. package/dist/style/components/forms/input.js +45 -0
  61. package/dist/style/components/forms/label.js +43 -0
  62. package/dist/style/components/forms/select.js +63 -0
  63. package/dist/style/components/forms/validation.js +34 -0
  64. package/dist/style/components/icons.js +22 -0
  65. package/dist/style/components/index.js +57 -0
  66. package/dist/style/components/loader.js +48 -0
  67. package/dist/style/components/methods.js +104 -0
  68. package/dist/style/components/overlay.js +33 -0
  69. package/dist/style/helpers/index.js +59 -0
  70. package/dist/style/index.js +48 -0
  71. package/dist/style/payment-instruments/content.js +17 -0
  72. package/dist/style/payment-instruments/index.js +20 -0
  73. package/dist/style/payment-instruments/payment-card.js +35 -0
  74. package/dist/style/utils/color-values.js +22 -0
  75. package/dist/style/vendor/framepay.js +34 -0
  76. package/dist/style/vendor/postmate.js +17 -0
  77. package/dist/style/views/confirmation.js +85 -0
  78. package/dist/style/views/index.js +29 -0
  79. package/dist/style/views/method-selector.js +20 -0
  80. package/dist/style/views/modal.js +93 -0
  81. package/dist/style/views/result.js +61 -0
  82. package/dist/style/views/summary.js +123 -0
  83. package/dist/utils/add-dom-element.js +12 -34
  84. package/dist/utils/format-currency.js +4 -4
  85. package/dist/utils/has-valid-css-selector.js +2 -2
  86. package/dist/utils/index.js +15 -31
  87. package/dist/utils/is-dom-element.js +1 -1
  88. package/dist/utils/process-property-as-dom-element.js +12 -17
  89. package/dist/utils/sleep.js +10 -0
  90. package/{src/components → dist/views}/__snapshots__/summary.spec.js.snap +7 -3
  91. package/dist/views/common/iframe/base-iframe.js +57 -0
  92. package/dist/views/common/iframe/event-listeners.js +50 -0
  93. package/dist/views/common/iframe/index.js +19 -0
  94. package/dist/views/common/iframe/method-iframe.js +33 -0
  95. package/dist/views/common/iframe/modal-iframe.js +38 -0
  96. package/dist/views/common/iframe/view-iframe.js +31 -0
  97. package/dist/views/common/render-utilities.js +11 -0
  98. package/dist/views/confirmation.js +82 -0
  99. package/dist/views/method-selector/__snapshots__/method-selector.spec.js.snap +3 -0
  100. package/dist/views/method-selector/express-methods/apple-pay.js +92 -0
  101. package/dist/views/method-selector/express-methods/google-pay.js +32 -0
  102. package/dist/views/method-selector/express-methods/paypal.js +19 -0
  103. package/dist/views/method-selector/generate-digital-wallet.js +59 -0
  104. package/dist/views/method-selector/generate-digital-wallet.spec.js +132 -0
  105. package/dist/views/method-selector/get-method-data.js +25 -0
  106. package/dist/views/method-selector/get-payment-methods.js +55 -0
  107. package/dist/views/method-selector/get-payment-methods.spec.js +44 -0
  108. package/dist/views/method-selector/index.js +133 -0
  109. package/dist/views/method-selector/method-selector.spec.js +139 -0
  110. package/dist/views/method-selector/mount-express-methods.js +69 -0
  111. package/dist/views/method-selector/mount-methods.js +78 -0
  112. package/dist/views/modal.js +83 -0
  113. package/dist/views/result.js +42 -0
  114. package/dist/views/summary.js +162 -0
  115. package/dist/views/summary.spec.js +148 -0
  116. package/package.json +12 -6
  117. package/src/events/base-event.js +35 -12
  118. package/src/events/events.spec.js +11 -0
  119. package/src/events/index.js +12 -6
  120. package/src/functions/destroy.js +22 -3
  121. package/src/functions/destroy.spec.js +63 -0
  122. package/src/functions/initialize.js +43 -20
  123. package/src/functions/initialize.spec.js +9 -7
  124. package/src/functions/mount/fetch-summary-data.js +29 -0
  125. package/src/functions/mount/fetch-summary-data.spec.js +41 -0
  126. package/src/functions/mount/index.js +312 -0
  127. package/src/functions/mount/mount.spec.js +171 -0
  128. package/src/functions/on.js +17 -14
  129. package/src/functions/on.spec.js +39 -29
  130. package/src/functions/purchase.js +24 -64
  131. package/src/functions/purchase.spec.js +19 -17
  132. package/src/functions/show.js +27 -7
  133. package/src/functions/show.spec.js +61 -0
  134. package/src/functions/update.js +50 -3
  135. package/src/functions/update.spec.js +107 -0
  136. package/src/i18n/i18n.spec.js +6 -4
  137. package/src/i18n/index.js +20 -12
  138. package/src/index.js +43 -49
  139. package/src/index.spec.js +11 -42
  140. package/src/loader/index.js +55 -39
  141. package/src/loader/loader.spec.js +30 -23
  142. package/src/storefront/index.js +9 -7
  143. package/src/storefront/models/plan-model.js +1 -1
  144. package/src/storefront/models/product-model.js +1 -1
  145. package/src/storefront/models/ready-to-pay-model.js +10 -4
  146. package/src/storefront/models/summary-model.js +8 -15
  147. package/src/storefront/plans.js +16 -12
  148. package/src/storefront/plans.spec.js +29 -37
  149. package/src/storefront/products.js +16 -12
  150. package/src/storefront/products.spec.js +28 -39
  151. package/src/storefront/purchase.js +8 -6
  152. package/src/storefront/purchase.spec.js +18 -17
  153. package/src/storefront/ready-to-pay.js +19 -13
  154. package/src/storefront/ready-to-pay.spec.js +41 -41
  155. package/src/storefront/storefront.spec.js +1 -1
  156. package/src/storefront/summary.js +14 -12
  157. package/src/storefront/summary.spec.js +37 -50
  158. package/src/style/base/__snapshots__/theme.spec.js.snap +52 -0
  159. package/src/style/base/index.js +63 -0
  160. package/src/style/base/theme.js +61 -0
  161. package/src/style/base/theme.spec.js +32 -0
  162. package/src/style/browserslist.js +1 -0
  163. package/src/style/components/address.js +55 -0
  164. package/src/style/components/button.js +54 -0
  165. package/src/style/components/divider.js +39 -0
  166. package/src/style/components/forms/checkbox.js +76 -0
  167. package/src/style/components/forms/field.js +44 -0
  168. package/src/style/components/forms/form.js +19 -0
  169. package/src/style/components/forms/input.js +36 -0
  170. package/src/style/components/forms/label.js +34 -0
  171. package/src/style/components/forms/select.js +54 -0
  172. package/src/style/components/forms/validation.js +25 -0
  173. package/src/style/components/icons.js +13 -0
  174. package/src/style/components/index.js +35 -0
  175. package/src/style/components/loader.js +41 -0
  176. package/src/style/components/methods.js +93 -0
  177. package/src/style/components/overlay.js +24 -0
  178. package/src/style/helpers/index.js +51 -0
  179. package/src/style/index.js +30 -0
  180. package/src/style/payment-instruments/content.js +8 -0
  181. package/src/style/payment-instruments/index.js +10 -0
  182. package/src/style/payment-instruments/payment-card.js +26 -0
  183. package/src/style/utils/color-values.js +9 -0
  184. package/src/style/vendor/framepay.js +25 -0
  185. package/src/style/vendor/postmate.js +8 -0
  186. package/src/style/views/confirmation.js +76 -0
  187. package/src/style/views/index.js +16 -0
  188. package/src/style/views/method-selector.js +11 -0
  189. package/src/style/views/modal.js +84 -0
  190. package/src/style/views/result.js +52 -0
  191. package/src/style/views/summary.js +114 -0
  192. package/src/utils/add-dom-element.js +12 -13
  193. package/src/utils/format-currency.js +4 -1
  194. package/src/utils/has-valid-css-selector.js +2 -2
  195. package/src/utils/index.js +2 -6
  196. package/src/utils/is-dom-element.js +1 -1
  197. package/src/utils/process-property-as-dom-element.js +27 -24
  198. package/src/utils/sleep.js +3 -0
  199. package/src/views/__snapshots__/summary.spec.js.snap +292 -0
  200. package/src/views/common/iframe/base-iframe.js +46 -0
  201. package/src/views/common/iframe/event-listeners.js +27 -0
  202. package/src/views/common/iframe/index.js +7 -0
  203. package/src/views/common/iframe/method-iframe.js +21 -0
  204. package/src/views/common/iframe/modal-iframe.js +27 -0
  205. package/src/views/common/iframe/view-iframe.js +18 -0
  206. package/src/views/common/render-utilities.js +4 -0
  207. package/src/views/confirmation.js +57 -0
  208. package/src/views/method-selector/__snapshots__/method-selector.spec.js.snap +3 -0
  209. package/src/views/method-selector/express-methods/apple-pay.js +78 -0
  210. package/src/views/method-selector/express-methods/google-pay.js +25 -0
  211. package/src/views/method-selector/express-methods/paypal.js +7 -0
  212. package/src/views/method-selector/generate-digital-wallet.js +44 -0
  213. package/src/views/method-selector/generate-digital-wallet.spec.js +131 -0
  214. package/src/{components/form → views/method-selector}/get-method-data.js +9 -5
  215. package/src/views/method-selector/get-payment-methods.js +40 -0
  216. package/src/views/method-selector/get-payment-methods.spec.js +40 -0
  217. package/src/views/method-selector/index.js +110 -0
  218. package/src/views/method-selector/method-selector.spec.js +146 -0
  219. package/src/views/method-selector/mount-express-methods.js +53 -0
  220. package/src/views/method-selector/mount-methods.js +71 -0
  221. package/src/views/modal.js +84 -0
  222. package/src/views/result.js +30 -0
  223. package/src/{components → views}/summary.js +90 -21
  224. package/src/views/summary.spec.js +170 -0
  225. package/tests/async-utilities.js +22 -0
  226. package/tests/mocks/rebilly-instruments-mock.js +105 -7
  227. package/dist/components/confirmation.js +0 -103
  228. package/dist/components/form/form.js +0 -110
  229. package/dist/components/form/form.spec.js +0 -135
  230. package/dist/components/form/get-method-data.js +0 -21
  231. package/dist/components/form/get-payment-methods.js +0 -42
  232. package/dist/components/form/method-selector.js +0 -61
  233. package/dist/components/form/mount-express-payment-methods.js +0 -102
  234. package/dist/components/form/process-digital-wallet-options.js +0 -20
  235. package/dist/components/form/zoid-helpers.js +0 -130
  236. package/dist/components/result.js +0 -66
  237. package/dist/components/summary.js +0 -60
  238. package/dist/components/summary.spec.js +0 -144
  239. package/dist/events/instrument-ready.js +0 -51
  240. package/dist/events/purchase-complete.js +0 -51
  241. package/dist/functions/mount.js +0 -311
  242. package/dist/functions/mount.spec.js +0 -203
  243. package/dist/styles/base-styles.js +0 -12
  244. package/dist/styles/flat-theme-object.js +0 -42
  245. package/dist/styles/framepay.js +0 -15
  246. package/dist/styles/main.js +0 -25
  247. package/dist/styles/payment-card.js +0 -12
  248. package/dist/styles/shade-tint-values-helper.js +0 -28
  249. package/dist/styles/style-variables.js +0 -43
  250. package/dist/utils/camel-case.js +0 -12
  251. package/dist/utils/kebab-case.js +0 -10
  252. package/dist/utils/un-kebab-case.js +0 -10
  253. package/src/components/confirmation.js +0 -77
  254. package/src/components/form/__snapshots__/form.spec.js.snap +0 -43
  255. package/src/components/form/form.js +0 -88
  256. package/src/components/form/form.spec.js +0 -109
  257. package/src/components/form/get-payment-methods.js +0 -32
  258. package/src/components/form/method-selector.js +0 -47
  259. package/src/components/form/mount-express-payment-methods.js +0 -84
  260. package/src/components/form/process-digital-wallet-options.js +0 -11
  261. package/src/components/form/zoid-helpers.js +0 -114
  262. package/src/components/result.js +0 -50
  263. package/src/components/summary.spec.js +0 -106
  264. package/src/events/instrument-ready.js +0 -11
  265. package/src/events/purchase-complete.js +0 -11
  266. package/src/functions/mount.js +0 -204
  267. package/src/functions/mount.spec.js +0 -172
  268. package/src/styles/base-styles.js +0 -741
  269. package/src/styles/flat-theme-object.js +0 -12
  270. package/src/styles/framepay.js +0 -30
  271. package/src/styles/main.js +0 -17
  272. package/src/styles/payment-card.js +0 -18
  273. package/src/styles/shade-tint-values-helper.js +0 -13
  274. package/src/styles/style-variables.js +0 -34
  275. package/src/utils/camel-case.js +0 -3
  276. package/src/utils/kebab-case.js +0 -3
  277. package/src/utils/un-kebab-case.js +0 -3
package/src/index.spec.js CHANGED
@@ -1,11 +1,15 @@
1
- import RebillyInstruments, {RebillyInstrumentsInstance} from './index';
1
+ import RebillyInstruments, { RebillyInstrumentsInstance } from './index';
2
+ import { avoidUnhandledPromises } from 'tests/async-utilities';
3
+ import { initialize } from './functions/initialize';
2
4
 
3
5
  describe('RebillyInstruments instance', () => {
4
6
  let rebillyInstruments;
5
7
 
6
- function setupInstance(config = {
7
- test: 'value'
8
- }) {
8
+ function setupInstance(
9
+ config = {
10
+ test: 'value'
11
+ }
12
+ ) {
9
13
  rebillyInstruments.initialize(config);
10
14
  }
11
15
 
@@ -17,23 +21,10 @@ describe('RebillyInstruments instance', () => {
17
21
  expect(RebillyInstruments).toBeInstanceOf(RebillyInstrumentsInstance);
18
22
  });
19
23
 
20
- it('should be initializable', () => {
21
- jest.spyOn(rebillyInstruments, 'initialize');
22
-
23
- const config = {
24
- test: 'value'
25
- };
26
- rebillyInstruments.initialize(config);
27
-
28
- expect(rebillyInstruments.initialize).toHaveBeenCalledTimes(1);
29
- expect(rebillyInstruments.initialize).toHaveBeenCalledWith(config);
30
- });
31
-
32
- it('should be mountable', () => {
24
+ it('should be mountable', async () => {
33
25
  jest.spyOn(rebillyInstruments, 'mount');
34
26
 
35
- document.body.innerHTML =
36
- `
27
+ document.body.innerHTML = `
37
28
  <div class="form-selector"></div>
38
29
  <div class="summary-selector"></div>
39
30
  `;
@@ -48,28 +39,7 @@ describe('RebillyInstruments instance', () => {
48
39
 
49
40
  expect(rebillyInstruments.mount).toHaveBeenCalledTimes(1);
50
41
  expect(rebillyInstruments.mount).toHaveBeenCalledWith(options);
51
- });
52
-
53
- it('should be updateable', () => {
54
- jest.spyOn(rebillyInstruments, 'update');
55
-
56
- const config = {
57
- test: 'value'
58
- };
59
- setupInstance();
60
- rebillyInstruments.update(config);
61
-
62
- expect(rebillyInstruments.update).toHaveBeenCalledTimes(1);
63
- expect(rebillyInstruments.update).toHaveBeenCalledWith(config);
64
- });
65
-
66
- it('should be destroyable', () => {
67
- jest.spyOn(rebillyInstruments, 'destroy');
68
-
69
- setupInstance();
70
- rebillyInstruments.destroy();
71
-
72
- expect(rebillyInstruments.destroy).toHaveBeenCalledTimes(1);
42
+ await avoidUnhandledPromises();
73
43
  });
74
44
 
75
45
  it('should be able to trigger a purchase', () => {
@@ -83,4 +53,3 @@ describe('RebillyInstruments instance', () => {
83
53
  expect(rebillyInstruments.purchase).toHaveBeenCalledTimes(1);
84
54
  });
85
55
  });
86
-
@@ -1,54 +1,70 @@
1
1
  import isDOMElement from '../utils/is-dom-element';
2
2
 
3
3
  export class Loader {
4
- constructor() {
5
- this.summary = [];
6
- this.form = [];
7
- this.DOM = {
8
- loading: `
9
- <div class="rebilly-instruments-loader active">
4
+ constructor() {
5
+ this.summary = [];
6
+ this.form = [];
7
+ this.modal = [];
8
+ this.DOM = {
9
+ loading: `
10
+ <div class="rebilly-instruments-loader is-active">
10
11
  <div class="rebilly-instruments-loader-spinner"></div>
11
12
  </div>
12
13
  `
13
- };
14
- }
14
+ };
15
+ }
16
+
17
+ addDOMElement({ section = 'form', el = null } = {}) {
18
+ const minHeight = '200px';
19
+
20
+ if (isDOMElement(el)) {
21
+ el.style.position = 'relative';
22
+ el.style.minHeight = minHeight;
15
23
 
16
- addDOMElement({section = 'form', el = null} = {}) {
17
- const minHeight = '200px';
24
+ this.DOM[section] = el;
25
+ }
26
+ }
18
27
 
19
- if (isDOMElement(el)) {
20
- el.style.position = 'relative';
21
- el.style.minHeight = minHeight;
22
- el.style.paddingTop = section === 'form' ? '8px' : '0px';
28
+ startLoading({ section = 'form', id = '' } = {}) {
29
+ this[section].push(id);
23
30
 
24
- this.DOM[section] = el;
25
- }
31
+ if (this.DOM?.[section]) {
32
+ if (!this.DOM[section].querySelector('.rebilly-instruments-loader')) {
33
+ this.DOM[section].innerHTML = this.DOM.loading;
34
+ } else {
35
+ this.DOM[section]
36
+ .querySelector('.rebilly-instruments-loader')
37
+ .classList.add('is-active');
38
+ }
26
39
  }
40
+ }
41
+
42
+ stopLoading({ section = 'form', id = '' } = {}) {
43
+ const idIndex = this[section].indexOf(id);
27
44
 
28
- startLoading({section = 'form', id = ''} = {}) {
29
- this[section].push(id);
30
-
31
- if (this.DOM?.[section]) {
32
- if (!this.DOM[section].querySelector('.rebilly-instruments-loader')) {
33
- this.DOM[section].innerHTML = this.DOM.loading;
34
- } else {
35
- this.DOM[section].querySelector('.rebilly-instruments-loader')
36
- .classList.add('active');
37
- }
38
- }
45
+ if (idIndex !== -1) {
46
+ this[section].splice(idIndex, 1);
39
47
  }
40
48
 
41
- stopLoading({section = 'form', id = ''} = {}) {
42
- const idIndex = this[section].indexOf(id);
43
-
44
- if (idIndex !== -1) {
45
- this[section].splice(idIndex, 1);
46
- }
47
-
48
- if (!this[section].length
49
- && this.DOM[section].querySelector('.rebilly-instruments-loader')) {
50
- this.DOM[section].querySelector('.rebilly-instruments-loader')
51
- .classList.remove('active');
52
- }
49
+ if (
50
+ !this[section].length &&
51
+ this.DOM[section].querySelector('.rebilly-instruments-loader')
52
+ ) {
53
+ this.DOM[section]
54
+ .querySelector('.rebilly-instruments-loader')
55
+ .classList.remove('is-active');
53
56
  }
57
+ }
58
+
59
+ clearAll() {
60
+ this.form.forEach((id) => {
61
+ this.stopLoading({ id });
62
+ });
63
+ this.summary.forEach((id) => {
64
+ this.stopLoading({ section: 'summary', id });
65
+ });
66
+ this.modal.forEach((id) => {
67
+ this.stopLoading({ section: 'modal', id });
68
+ });
69
+ }
54
70
  }
@@ -1,5 +1,5 @@
1
1
  import { Loader } from './index';
2
-
2
+
3
3
  describe('Loader Class', () => {
4
4
  let loader;
5
5
 
@@ -11,57 +11,64 @@ describe('Loader Class', () => {
11
11
  <div class="summary-selector"></div>
12
12
  `;
13
13
 
14
- loader.addDOMElement({el: document.querySelector('.form-selector')});
15
- loader.addDOMElement({section: 'summary', el: document.querySelector('.summary-selector')});
16
- })
14
+ loader.addDOMElement({ el: document.querySelector('.form-selector') });
15
+ loader.addDOMElement({
16
+ section: 'summary',
17
+ el: document.querySelector('.summary-selector')
18
+ });
19
+ });
17
20
 
18
21
  it('manage state of loading ids', () => {
19
- loader.startLoading({id: 'loadForm'});
20
- loader.startLoading({id: 'updateForm'});
22
+ loader.startLoading({ id: 'loadForm' });
23
+ loader.startLoading({ id: 'updateForm' });
21
24
 
22
25
  // Start loading state
23
- loader.startLoading({section: 'summary', id: 'loadSummary'});
24
- loader.startLoading({section: 'summary', id: 'updateSummary'});
26
+ loader.startLoading({ section: 'summary', id: 'loadSummary' });
27
+ loader.startLoading({ section: 'summary', id: 'updateSummary' });
25
28
 
26
29
  // Stop one loading state
27
- loader.stopLoading({id: 'loadForm'});
30
+ loader.stopLoading({ id: 'loadForm' });
28
31
 
29
32
  expect(loader.form.length).toEqual(1);
30
33
  expect(loader.summary.length).toEqual(2);
31
34
  });
32
35
 
33
36
  it('adds the loader HTML on element and removes the active class when stoped', () => {
34
- loader.startLoading({id: 'loadForm'});
37
+ loader.startLoading({ id: 'loadForm' });
35
38
 
36
39
  expect(loader.DOM.form.innerHTML).toMatch('rebilly-instruments-loader');
37
40
  expect(
38
- loader.DOM.form.querySelector('.rebilly-instruments-loader')
39
- .classList.contains('active')
41
+ loader.DOM.form
42
+ .querySelector('.rebilly-instruments-loader')
43
+ .classList.contains('is-active')
40
44
  ).toEqual(true);
41
45
 
42
- loader.stopLoading({id: 'loadForm'});
46
+ loader.stopLoading({ id: 'loadForm' });
43
47
 
44
48
  expect(
45
- loader.DOM.form.querySelector('.rebilly-instruments-loader')
46
- .classList.contains('active')
49
+ loader.DOM.form
50
+ .querySelector('.rebilly-instruments-loader')
51
+ .classList.contains('is-active')
47
52
  ).toEqual(false);
48
53
  });
49
54
 
50
55
  it('keeps loading when there are Ids on the element array', () => {
51
- loader.startLoading({id: 'loadForm'});
52
- loader.startLoading({id: 'updateForm'});
56
+ loader.startLoading({ id: 'loadForm' });
57
+ loader.startLoading({ id: 'updateForm' });
53
58
 
54
59
  expect(loader.DOM.form.innerHTML).toMatch('rebilly-instruments-loader');
55
60
  expect(
56
- loader.DOM.form.querySelector('.rebilly-instruments-loader')
57
- .classList.contains('active')
61
+ loader.DOM.form
62
+ .querySelector('.rebilly-instruments-loader')
63
+ .classList.contains('is-active')
58
64
  ).toEqual(true);
59
65
 
60
- loader.stopLoading({id: 'loadForm'});
61
-
66
+ loader.stopLoading({ id: 'loadForm' });
67
+
62
68
  expect(
63
- loader.DOM.form.querySelector('.rebilly-instruments-loader')
64
- .classList.contains('active')
69
+ loader.DOM.form
70
+ .querySelector('.rebilly-instruments-loader')
71
+ .classList.contains('is-active')
65
72
  ).toEqual(true);
66
73
  });
67
74
  });
@@ -1,7 +1,7 @@
1
- import {RebillyStorefrontAPI} from 'rebilly-js-sdk';
1
+ import { RebillyStorefrontAPI } from 'rebilly-js-sdk';
2
2
 
3
3
  export class StorefrontInstance {
4
- constructor ({
4
+ constructor({
5
5
  publishableKey = null,
6
6
  organizationId = null,
7
7
  mode = 'live',
@@ -17,15 +17,17 @@ export class StorefrontInstance {
17
17
  const api = RebillyStorefrontAPI({
18
18
  organizationId,
19
19
  sandbox: mode === 'sandbox',
20
- timeout: Number.isNaN(parseInt(timeout, 10)) ? 10000 : parseInt(timeout, 10),
21
- urls,
20
+ timeout: Number.isNaN(parseInt(timeout, 10))
21
+ ? 10000
22
+ : parseInt(timeout, 10),
23
+ urls
22
24
  });
23
-
25
+
24
26
  api.setPublishableKey(publishableKey);
25
-
27
+
26
28
  this.api = api;
27
29
  return this.api;
28
30
  }
29
31
  }
30
32
 
31
- export default (config = {}) => new StorefrontInstance(config)
33
+ export default (config = {}) => new StorefrontInstance(config);
@@ -14,7 +14,7 @@ export default class PlanModel {
14
14
  customFields = {},
15
15
  createdTime = '',
16
16
  updatedTime = '',
17
- invoiceTimeShift = {},
17
+ invoiceTimeShift = {}
18
18
  } = {}) {
19
19
  this.id = id;
20
20
  this.name = name;
@@ -8,7 +8,7 @@ export default class ProductModel {
8
8
  options = [],
9
9
  customFields = {},
10
10
  createdTime = '',
11
- updatedTime = '',
11
+ updatedTime = ''
12
12
  } = {}) {
13
13
  this.id = id;
14
14
  this.name = name;
@@ -1,12 +1,18 @@
1
1
  export class ReadyToPayFeatureModel {
2
2
  constructor({
3
3
  name = '',
4
+ // Google Pay fields
5
+ merchantName = '',
6
+ merchantOrigin = '',
7
+ // Plaid fields
4
8
  linkToken = '',
5
- expirationTime = '',
9
+ expirationTime = ''
6
10
  } = {}) {
7
11
  this.name = name;
12
+ this.merchantName = merchantName;
13
+ this.merchantOrigin = merchantOrigin;
8
14
  this.linkToken = linkToken;
9
- this.expirtationTime = expirationTime;
15
+ this.expirationTime = expirationTime;
10
16
  }
11
17
  }
12
18
 
@@ -16,7 +22,7 @@ export default class ReadyToPayModel {
16
22
  method = '',
17
23
  feature = null,
18
24
  brands = [],
19
- filters = [],
25
+ filters = []
20
26
  } = {}) {
21
27
  this.index = index;
22
28
  this.method = method;
@@ -24,4 +30,4 @@ export default class ReadyToPayModel {
24
30
  this.brands = brands;
25
31
  this.filters = filters;
26
32
  }
27
- }
33
+ }
@@ -1,4 +1,4 @@
1
- export class SummaryLineItemModel{
1
+ export class SummaryLineItemModel {
2
2
  constructor({
3
3
  type = '',
4
4
  description = '',
@@ -19,21 +19,14 @@ export class SummaryLineItemModel{
19
19
  }
20
20
 
21
21
  export class SummaryTaxModel {
22
- constructor({
23
- amount = '',
24
- description = ''
25
- } = {}) {
22
+ constructor({ amount = '', description = '' } = {}) {
26
23
  this.amount = amount;
27
24
  this.description = description;
28
25
  }
29
26
  }
30
27
 
31
28
  export class SummaryDiscountModel {
32
- constructor({
33
- couponId = '',
34
- amount = 0,
35
- description = ''
36
- } = {}) {
29
+ constructor({ couponId = '', amount = 0, description = '' } = {}) {
37
30
  this.couponId = couponId;
38
31
  this.amount = amount;
39
32
  this.description = description;
@@ -53,13 +46,13 @@ export default class SummaryModel {
53
46
  total = 0.0
54
47
  } = {}) {
55
48
  function map(array) {
56
- const list = (Array.isArray(array) ? array : []);
49
+ const list = Array.isArray(array) ? array : [];
57
50
  return {
58
51
  // eslint-disable-next-line new-cap
59
- to: (instance) => list.map(item => new instance(item))
60
- }
52
+ to: (instance) => list.map((item) => new instance(item))
53
+ };
61
54
  }
62
-
55
+
63
56
  this.currency = currency;
64
57
  this.lineItems = map(lineItems).to(SummaryLineItemModel);
65
58
  this.taxes = map(taxes).to(SummaryTaxModel);
@@ -70,4 +63,4 @@ export default class SummaryModel {
70
63
  this.discountsAmount = discountsAmount;
71
64
  this.total = total;
72
65
  }
73
- }
66
+ }
@@ -1,30 +1,34 @@
1
1
  import PlanModel from './models/plan-model';
2
2
 
3
- export async function FetchPlans ({
4
- data = null
5
- } = {}) {
6
- if (!this.storefront) {
3
+ export async function fetchPlans({ data = null, state = null }) {
4
+ if (!state.storefront) {
7
5
  throw new Error('Could not access rebilly-js-sdk instance');
8
6
  }
9
7
 
10
- if (!this.configs || !this.options) {
11
- throw new Error('Could not use Rebilly Instruments configurations or mount options to fetch Rebilly data');
8
+ if (!state.configs || !state.options) {
9
+ throw new Error(
10
+ 'Could not use Rebilly Instruments configurations or mount options to fetch Rebilly data'
11
+ );
12
12
  }
13
13
 
14
14
  try {
15
15
  const { lineItems } = data || {};
16
16
 
17
17
  const filterByPlanId = {
18
- filter: '',
19
- }
18
+ filter: ''
19
+ };
20
20
 
21
21
  if (lineItems) {
22
- filterByPlanId.filter = `id:${lineItems.map(item => item.planId).join(',')}`;
22
+ filterByPlanId.filter = `id:${lineItems
23
+ .map((item) => item.planId)
24
+ .join(',')}`;
23
25
  }
24
26
 
25
- const {items: planItems} = await this.storefront.plans.getAll(filterByPlanId);
26
- return planItems.map(({fields}) => new PlanModel(fields));
27
+ const { items: planItems } = await state.storefront.plans.getAll(
28
+ filterByPlanId
29
+ );
30
+ return planItems.map(({ fields }) => new PlanModel(fields));
27
31
  } catch (error) {
28
32
  throw error;
29
33
  }
30
- };
34
+ }
@@ -2,27 +2,21 @@ import { MockStorefront } 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
10
  class TestPlansInstance {
10
- constructor({
11
- configs = {},
12
- options = {}
13
- } = {}) {
11
+ constructor({ configs = {}, options = {} } = {}) {
14
12
  this.configs = configs;
15
13
  this.options = options;
16
14
  this.storefront = MockStorefront();
17
15
  }
18
-
19
- fetchPlans(...args) {
20
- return FetchPlans.apply(this, args);
21
- }
22
16
  }
23
-
24
- it ('can fetch plans', async () => {
25
- const testPlan = {name: 'Test Plan', id: 'test-plan-id-1'};
17
+
18
+ it('can fetch plans', async () => {
19
+ const testPlan = { name: 'Test Plan', id: 'test-plan-id-1' };
26
20
 
27
21
  when(get(`${storefrontURL}/plans`)).thenReturn(ok([testPlan]));
28
22
 
@@ -30,7 +24,7 @@ describe('Storefront API Plan', () => {
30
24
 
31
25
  jest.spyOn(instance.storefront.plans, 'getAll');
32
26
 
33
- const response = await instance.fetchPlans({});
27
+ const response = await fetchPlans({ state: instance });
34
28
 
35
29
  expect(instance.storefront.plans.getAll).toBeCalledTimes(1);
36
30
  expect(instance.storefront.plans.getAll).toBeCalledWith({
@@ -41,18 +35,22 @@ describe('Storefront API Plan', () => {
41
35
  expect(response).toEqual([new PlanModel(testPlan)]);
42
36
  });
43
37
 
44
- it ('can fetch plans with filter', async () => {
38
+ it('can fetch plans with filter', async () => {
45
39
  const instance = new TestPlansInstance();
46
40
 
47
41
  jest.spyOn(instance.storefront.plans, 'getAll');
48
42
 
49
- await instance.fetchPlans({
43
+ await fetchPlans({
44
+ state: instance,
50
45
  data: {
51
- lineItems: [{
52
- planId: 'test-plan-id-1'
53
- }, {
54
- planId: 'test-plan-id-2'
55
- }]
46
+ lineItems: [
47
+ {
48
+ planId: 'test-plan-id-1'
49
+ },
50
+ {
51
+ planId: 'test-plan-id-2'
52
+ }
53
+ ]
56
54
  }
57
55
  });
58
56
 
@@ -61,31 +59,25 @@ describe('Storefront API Plan', () => {
61
59
  });
62
60
  });
63
61
 
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');
62
+ it('should throw errors with no configs or options', async () => {
66
63
  const noConfigOrOptionsInstance = new TestPlansInstance({
67
64
  configs: null,
68
- options: null,
65
+ options: null
69
66
  });
67
+ await expectConfigurationError(
68
+ fetchPlans({ state: noConfigOrOptionsInstance })
69
+ );
70
+
70
71
  const noConfigInstance = new TestPlansInstance({
71
72
  configs: null,
72
- options: {},
73
+ options: {}
73
74
  });
75
+ await expectConfigurationError(fetchPlans({ state: noConfigInstance }));
76
+
74
77
  const noOptionsInstance = new TestPlansInstance({
75
78
  configs: {},
76
- options: null,
79
+ options: null
77
80
  });
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);
81
+ await expectConfigurationError(fetchPlans({ state: noOptionsInstance }));
90
82
  });
91
83
  });
@@ -1,30 +1,34 @@
1
1
  import ProductModel from './models/product-model';
2
2
 
3
- export async function FetchProducts ({
4
- data = null
5
- } = {}) {
6
- if (!this.storefront) {
3
+ export async function fetchProducts({ data = null, state }) {
4
+ if (!state.storefront) {
7
5
  throw new Error('Could not access rebilly-js-sdk instance');
8
6
  }
9
7
 
10
- if (!this.configs || !this.options) {
11
- throw new Error('Could not use Rebilly Instruments configurations or mount options to fetch Rebilly data');
8
+ if (!state.configs || !state.options) {
9
+ throw new Error(
10
+ 'Could not use Rebilly Instruments configurations or mount options to fetch Rebilly data'
11
+ );
12
12
  }
13
13
 
14
14
  try {
15
15
  const plansData = data || [];
16
16
 
17
17
  const filterByProductId = {
18
- filter: '',
19
- }
18
+ filter: ''
19
+ };
20
20
 
21
21
  if (plansData.length) {
22
- filterByProductId.filter = `id:${plansData.map(item => item.productId).join(',')}`;
22
+ filterByProductId.filter = `id:${plansData
23
+ .map((item) => item.productId)
24
+ .join(',')}`;
23
25
  }
24
26
 
25
- const {items: productItems} = await this.storefront.products.getAll(filterByProductId);
26
- return productItems.map(({fields}) => new ProductModel(fields));
27
+ const { items: productItems } = await state.storefront.products.getAll(
28
+ filterByProductId
29
+ );
30
+ return productItems.map(({ fields }) => new ProductModel(fields));
27
31
  } catch (error) {
28
32
  throw error;
29
33
  }
30
- };
34
+ }