@justifi/webcomponents 4.12.1 → 4.13.0-rc.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 (173) hide show
  1. package/dist/cjs/{Business-c928bf29.js → Business-98686045.js} +27 -4
  2. package/dist/cjs/additional-questions-details_5.cjs.entry.js +4 -4
  3. package/dist/cjs/{business-additional-questions-schema-3813615c.js → business-additional-questions-schema-f8086f7a.js} +19 -9
  4. package/dist/cjs/business-form-options-fd1c0032.js +128 -0
  5. package/dist/cjs/{business-form-types-4b138bf2.js → business-form-types-29b2bad9.js} +0 -26
  6. package/dist/cjs/form-control-date_3.cjs.entry.js +2 -2
  7. package/dist/cjs/form-control-datepart_2.cjs.entry.js +1 -1
  8. package/dist/cjs/form-control-monetary.cjs.entry.js +7 -12
  9. package/dist/cjs/form-input-masks-0879c139.js +27 -0
  10. package/dist/cjs/{index-fc5339a5.js → index-d8e99b54.js} +352 -198
  11. package/dist/cjs/justifi-additional-questions-form-step_5.cjs.entry.js +10 -9
  12. package/dist/cjs/justifi-additional-questions_4.cjs.entry.js +7 -7
  13. package/dist/cjs/justifi-billing-form_4.cjs.entry.js +4 -4
  14. package/dist/cjs/justifi-business-details.cjs.entry.js +2 -2
  15. package/dist/cjs/justifi-business-form.cjs.entry.js +6 -5
  16. package/dist/cjs/justifi-business-list.cjs.entry.js +2 -2
  17. package/dist/cjs/justifi-business-owners.cjs.entry.js +1 -1
  18. package/dist/cjs/justifi-checkout-core.cjs.entry.js +9 -4
  19. package/dist/cjs/justifi-checkout.cjs.entry.js +26 -4
  20. package/dist/cjs/justifi-new-payment-method_4.cjs.entry.js +1 -1
  21. package/dist/cjs/justifi-owner-form.cjs.entry.js +6 -5
  22. package/dist/cjs/justifi-payment-provisioning.cjs.entry.js +1 -3
  23. package/dist/cjs/justifi-refund-form.cjs.entry.js +2 -1
  24. package/dist/cjs/loader.cjs.js +1 -1
  25. package/dist/cjs/{payload-parsers-58d3798e.js → payload-parsers-fe27be37.js} +65 -6
  26. package/dist/cjs/{state-options-4fbcb48a.js → state-options-4145f9b4.js} +0 -4
  27. package/dist/cjs/webcomponents.cjs.js +1 -1
  28. package/dist/collection/api/Business.js +26 -3
  29. package/dist/collection/components/business-details/additional-questions-details/additional-questions-details.js +2 -2
  30. package/dist/collection/components/business-details/generic-info-details/generic-info-details.js +2 -2
  31. package/dist/collection/components/business-forms/business-form/additional-questions/additional-questions.js +4 -2
  32. package/dist/collection/components/business-forms/business-form/business-core-info/business-core-info.js +2 -2
  33. package/dist/collection/components/business-forms/payment-provisioning/additional-questions/business-additional-questions-form-step.js +4 -2
  34. package/dist/collection/components/business-forms/payment-provisioning/business-core-info/business-core-info-form-step.js +3 -2
  35. package/dist/collection/components/business-forms/schemas/business-additional-questions-schema.js +16 -9
  36. package/dist/collection/components/business-forms/schemas/business-core-info-schema.js +5 -1
  37. package/dist/collection/components/business-forms/schemas/schema-helpers.js +3 -0
  38. package/dist/collection/components/business-forms/schemas/schema-validations.js +53 -6
  39. package/dist/collection/components/business-forms/utils/business-form-options.js +119 -0
  40. package/dist/collection/components/business-forms/utils/business-form-types.js +0 -23
  41. package/dist/collection/components/checkout/checkout-actions.js +28 -5
  42. package/dist/collection/components/checkout/checkout-core.js +30 -6
  43. package/dist/collection/components/checkout/payment-method-options.js +2 -18
  44. package/dist/collection/components/checkout/test/checkout-actions.spec.js +126 -0
  45. package/dist/collection/components/checkout/test/checkout-core.spec.js +127 -0
  46. package/dist/collection/components/checkout/test/checkout.spec.js +0 -153
  47. package/dist/collection/components/form/form-control-monetary.css +1812 -0
  48. package/dist/collection/components/form/form-control-monetary.js +24 -11
  49. package/dist/collection/components/form/test/form-control-monetary.spec.js +5 -3
  50. package/dist/collection/components/payment-method-form/payment-method-form.js +1 -1
  51. package/dist/collection/components/refund-form/refund-form.js +2 -1
  52. package/dist/collection/utils/form-input-masks.js +15 -0
  53. package/dist/collection/utils/state-options.js +0 -4
  54. package/dist/docs.json +93 -30
  55. package/dist/esm/{Business-6cb1b9c8.js → Business-6e0efa26.js} +28 -5
  56. package/dist/esm/additional-questions-details_5.entry.js +4 -4
  57. package/dist/esm/business-additional-questions-schema-8e742129.js +54 -0
  58. package/dist/esm/business-form-options-75c0a7ec.js +122 -0
  59. package/dist/esm/{business-form-types-5ba52d61.js → business-form-types-0d76133c.js} +1 -25
  60. package/dist/esm/form-control-date_3.entry.js +2 -2
  61. package/dist/esm/form-control-datepart_2.entry.js +1 -1
  62. package/dist/esm/form-control-monetary.entry.js +7 -12
  63. package/dist/esm/form-input-masks-0e18300f.js +22 -0
  64. package/dist/esm/{index-5eb05747.js → index-dc1350b1.js} +352 -198
  65. package/dist/esm/justifi-additional-questions-form-step_5.entry.js +10 -9
  66. package/dist/esm/justifi-additional-questions_4.entry.js +7 -7
  67. package/dist/esm/justifi-billing-form_4.entry.js +4 -4
  68. package/dist/esm/justifi-business-details.entry.js +2 -2
  69. package/dist/esm/justifi-business-form.entry.js +6 -5
  70. package/dist/esm/justifi-business-list.entry.js +2 -2
  71. package/dist/esm/justifi-business-owners.entry.js +1 -1
  72. package/dist/esm/justifi-checkout-core.entry.js +9 -4
  73. package/dist/esm/justifi-checkout.entry.js +27 -5
  74. package/dist/esm/justifi-new-payment-method_4.entry.js +1 -1
  75. package/dist/esm/justifi-owner-form.entry.js +6 -5
  76. package/dist/esm/justifi-payment-provisioning.entry.js +1 -3
  77. package/dist/esm/justifi-refund-form.entry.js +2 -1
  78. package/dist/esm/loader.js +1 -1
  79. package/dist/esm/{payload-parsers-3e817fe9.js → payload-parsers-73c12fa2.js} +57 -7
  80. package/dist/esm/{state-options-a356fb11.js → state-options-c0b757ad.js} +0 -4
  81. package/dist/esm/webcomponents.js +1 -1
  82. package/dist/module/Business.js +27 -4
  83. package/dist/module/additional-questions-details2.js +2 -2
  84. package/dist/module/additional-questions.js +18 -4
  85. package/dist/module/business-additional-questions-form-step.js +18 -4
  86. package/dist/module/business-additional-questions-schema.js +16 -9
  87. package/dist/module/business-address-schema.js +1 -1
  88. package/dist/module/business-core-info-form-step.js +10 -3
  89. package/dist/module/business-core-info-schema.js +5 -1
  90. package/dist/module/business-core-info.js +9 -3
  91. package/dist/module/business-form-options.js +122 -0
  92. package/dist/module/business-form-types.js +153 -24
  93. package/dist/module/business-identity-schema.js +1 -1
  94. package/dist/module/business-representative-form-step.js +1 -1
  95. package/dist/module/checkout-core.js +9 -5
  96. package/dist/module/form-control-monetary2.js +8 -12
  97. package/dist/module/form-input-masks.js +16 -1
  98. package/dist/module/generic-info-details2.js +2 -2
  99. package/dist/module/index2.js +352 -198
  100. package/dist/module/justifi-business-details.js +1 -1
  101. package/dist/module/justifi-business-form.js +3 -3
  102. package/dist/module/justifi-business-list.js +1 -1
  103. package/dist/module/justifi-checkout.js +27 -5
  104. package/dist/module/justifi-payment-provisioning.js +1 -1
  105. package/dist/module/justifi-refund-form.js +2 -1
  106. package/dist/module/legal-address-form-step.js +2 -2
  107. package/dist/module/owner-form.js +2 -2
  108. package/dist/module/payload-parsers.js +1 -104
  109. package/dist/module/payment-method-form.js +3 -3
  110. package/dist/module/payment-method-options.js +2 -2
  111. package/dist/module/state-options.js +0 -4
  112. package/dist/types/api/Business.d.ts +34 -5
  113. package/dist/types/api/services/checkout.service.d.ts +3 -3
  114. package/dist/types/components/business-forms/schemas/business-additional-questions-schema.d.ts +10 -4
  115. package/dist/types/components/business-forms/schemas/business-core-info-schema.d.ts +4 -0
  116. package/dist/types/components/business-forms/schemas/business-form-schema.d.ts +14 -4
  117. package/dist/types/components/business-forms/schemas/schema-helpers.d.ts +3 -0
  118. package/dist/types/components/business-forms/schemas/schema-validations.d.ts +9 -0
  119. package/dist/types/components/business-forms/utils/business-form-options.d.ts +21 -0
  120. package/dist/types/components/business-forms/utils/business-form-types.d.ts +0 -5
  121. package/dist/types/components/checkout/checkout-core.d.ts +3 -2
  122. package/dist/types/components/checkout/payment-method-options.d.ts +1 -1
  123. package/dist/types/components/form/form-control-monetary.d.ts +1 -0
  124. package/dist/types/components.d.ts +4 -2
  125. package/dist/types/utils/form-input-masks.d.ts +15 -0
  126. package/dist/webcomponents/{p-31e70d65.entry.js → p-19885f77.entry.js} +1 -1
  127. package/dist/webcomponents/p-2c4c5f0d.entry.js +1 -0
  128. package/dist/webcomponents/p-30b6ea06.entry.js +1 -0
  129. package/dist/webcomponents/p-31e8f29c.entry.js +1 -0
  130. package/dist/webcomponents/p-31fe7232.entry.js +1 -0
  131. package/dist/webcomponents/p-3496e37f.js +1 -0
  132. package/dist/webcomponents/{p-2fbe8823.entry.js → p-35e59bb5.entry.js} +1 -1
  133. package/dist/webcomponents/p-3917edbf.entry.js +1 -0
  134. package/dist/webcomponents/p-3934a3a8.entry.js +1 -0
  135. package/dist/webcomponents/p-3ffe6784.js +1 -0
  136. package/dist/webcomponents/p-49c349e7.js +1 -0
  137. package/dist/webcomponents/p-4d335a3d.entry.js +1 -0
  138. package/dist/webcomponents/p-4ff52695.entry.js +1 -0
  139. package/dist/webcomponents/p-525db3e8.js +1 -0
  140. package/dist/webcomponents/p-57fbd98d.js +1 -0
  141. package/dist/webcomponents/p-5a789239.entry.js +1 -0
  142. package/dist/webcomponents/{p-5f5e730c.entry.js → p-834cba99.entry.js} +1 -1
  143. package/dist/webcomponents/p-87d646c0.js +1 -0
  144. package/dist/webcomponents/{p-2bee72bd.entry.js → p-8da13f40.entry.js} +1 -1
  145. package/dist/webcomponents/p-935d6f55.js +1 -0
  146. package/dist/webcomponents/{p-71b8e2da.entry.js → p-ba454cd7.entry.js} +1 -1
  147. package/dist/webcomponents/p-ed6ca114.js +1 -0
  148. package/dist/webcomponents/p-ee68566f.entry.js +1 -0
  149. package/dist/webcomponents/{p-b9f04fb0.entry.js → p-f152d6b8.entry.js} +1 -1
  150. package/dist/webcomponents/p-f3cf3513.entry.js +1 -0
  151. package/dist/webcomponents/webcomponents.esm.js +1 -1
  152. package/package.json +2 -2
  153. package/dist/cjs/form-input-masks-efd44b8e.js +0 -11
  154. package/dist/esm/business-additional-questions-schema-228d86e0.js +0 -44
  155. package/dist/esm/form-input-masks-84875967.js +0 -7
  156. package/dist/webcomponents/p-01913426.js +0 -1
  157. package/dist/webcomponents/p-07080c01.entry.js +0 -1
  158. package/dist/webcomponents/p-0d371ff5.entry.js +0 -1
  159. package/dist/webcomponents/p-2319abaf.entry.js +0 -1
  160. package/dist/webcomponents/p-26fe62d6.entry.js +0 -1
  161. package/dist/webcomponents/p-31ccb5f0.entry.js +0 -1
  162. package/dist/webcomponents/p-4c705f56.js +0 -1
  163. package/dist/webcomponents/p-6078a370.js +0 -1
  164. package/dist/webcomponents/p-737473d8.js +0 -1
  165. package/dist/webcomponents/p-787d8f52.js +0 -1
  166. package/dist/webcomponents/p-889a83d2.js +0 -1
  167. package/dist/webcomponents/p-927150b4.entry.js +0 -1
  168. package/dist/webcomponents/p-93579716.js +0 -1
  169. package/dist/webcomponents/p-9b0e5c25.entry.js +0 -1
  170. package/dist/webcomponents/p-9e3f9e05.entry.js +0 -1
  171. package/dist/webcomponents/p-c1b92cec.entry.js +0 -1
  172. package/dist/webcomponents/p-c865cda8.entry.js +0 -1
  173. package/dist/webcomponents/p-edab5f2b.entry.js +0 -1
@@ -1,4 +1,3 @@
1
- import { BusinessType } from "../../../api/Business";
2
1
  export var BusinessFormServerErrors;
3
2
  (function (BusinessFormServerErrors) {
4
3
  BusinessFormServerErrors["fetchData"] = "Error retrieving business data";
@@ -23,25 +22,3 @@ export var OwnerFormClickActions;
23
22
  OwnerFormClickActions["addOwnerForm"] = "addOwnerForm";
24
23
  OwnerFormClickActions["updateOwner"] = "updateOwner";
25
24
  })(OwnerFormClickActions || (OwnerFormClickActions = {}));
26
- export const BusinessTypeOptions = [
27
- {
28
- label: 'Choose business type',
29
- value: '',
30
- },
31
- {
32
- label: 'Individual',
33
- value: BusinessType.individual,
34
- },
35
- {
36
- label: 'For Profit',
37
- value: BusinessType.for_profit,
38
- },
39
- {
40
- label: 'Non Profit',
41
- value: BusinessType.non_profit,
42
- },
43
- {
44
- label: 'Government Entity',
45
- value: BusinessType.government_entity,
46
- },
47
- ];
@@ -1,5 +1,7 @@
1
- import { getErrorMessage } from "../../api/services/utils";
1
+ import { ComponentErrorSeverity } from "../../api/ComponentError";
2
+ import { getErrorCode, getErrorMessage } from "../../api/services/utils";
2
3
  export const makeGetCheckout = ({ authToken, checkoutId, service }) => async ({ onSuccess, onError }) => {
4
+ var _a;
3
5
  try {
4
6
  const response = await service.fetchCheckout(authToken, checkoutId);
5
7
  if (!response.error) {
@@ -8,14 +10,25 @@ export const makeGetCheckout = ({ authToken, checkoutId, service }) => async ({
8
10
  }
9
11
  else {
10
12
  const responseError = getErrorMessage(response.error);
11
- return onError(responseError);
13
+ const code = getErrorCode((_a = response.error) === null || _a === void 0 ? void 0 : _a.code);
14
+ return onError({
15
+ error: responseError,
16
+ code,
17
+ severity: ComponentErrorSeverity.ERROR,
18
+ });
12
19
  }
13
20
  }
14
21
  catch (error) {
15
- return onError(error.message || error);
22
+ const code = getErrorCode(error === null || error === void 0 ? void 0 : error.code);
23
+ return onError({
24
+ error: error.message || error,
25
+ code,
26
+ severity: ComponentErrorSeverity.ERROR,
27
+ });
16
28
  }
17
29
  };
18
30
  export const makeCheckoutComplete = ({ authToken, checkoutId, service }) => async ({ payment, onSuccess, onError }) => {
31
+ var _a;
19
32
  try {
20
33
  const response = await service.complete(authToken, checkoutId, payment);
21
34
  if (!response.error) {
@@ -24,10 +37,20 @@ export const makeCheckoutComplete = ({ authToken, checkoutId, service }) => asyn
24
37
  }
25
38
  else {
26
39
  const responseError = getErrorMessage(response.error);
27
- return onError(responseError);
40
+ const code = getErrorCode((_a = response.error) === null || _a === void 0 ? void 0 : _a.code);
41
+ return onError({
42
+ error: responseError,
43
+ code,
44
+ severity: ComponentErrorSeverity.ERROR,
45
+ });
28
46
  }
29
47
  }
30
48
  catch (error) {
31
- return onError(error.message || error);
49
+ const code = getErrorCode(error === null || error === void 0 ? void 0 : error.code);
50
+ return onError({
51
+ error: error.message || error,
52
+ code,
53
+ severity: ComponentErrorSeverity.ERROR,
54
+ });
32
55
  }
33
56
  };
@@ -20,7 +20,6 @@ export class CheckoutCore {
20
20
  this.serverError = false;
21
21
  this.errorMessage = '';
22
22
  this.creatingNewPaymentMethod = false;
23
- this.selectedPaymentMethodToken = undefined;
24
23
  }
25
24
  componentWillLoad() {
26
25
  if (this.getCheckout) {
@@ -40,10 +39,15 @@ export class CheckoutCore {
40
39
  this.checkout = new Checkout(checkout);
41
40
  this.isLoading = false;
42
41
  },
43
- onError: (errorMessage) => {
44
- this.errorMessage = errorMessage;
42
+ onError: ({ error, code, severity }) => {
43
+ this.errorMessage = error;
45
44
  this.isLoading = false;
46
- },
45
+ this.errorEvent.emit({
46
+ errorCode: code,
47
+ message: error,
48
+ severity,
49
+ });
50
+ }
47
51
  });
48
52
  }
49
53
  ;
@@ -201,8 +205,7 @@ export class CheckoutCore {
201
205
  "checkout": {},
202
206
  "serverError": {},
203
207
  "errorMessage": {},
204
- "creatingNewPaymentMethod": {},
205
- "selectedPaymentMethodToken": {}
208
+ "creatingNewPaymentMethod": {}
206
209
  };
207
210
  }
208
211
  static get events() {
@@ -227,6 +230,27 @@ export class CheckoutCore {
227
230
  }
228
231
  }
229
232
  }
233
+ }, {
234
+ "method": "errorEvent",
235
+ "name": "error-event",
236
+ "bubbles": true,
237
+ "cancelable": true,
238
+ "composed": true,
239
+ "docs": {
240
+ "tags": [],
241
+ "text": ""
242
+ },
243
+ "complexType": {
244
+ "original": "ComponentError",
245
+ "resolved": "ComponentError",
246
+ "references": {
247
+ "ComponentError": {
248
+ "location": "import",
249
+ "path": "../../api/ComponentError",
250
+ "id": "src/api/ComponentError.ts::ComponentError"
251
+ }
252
+ }
253
+ }
230
254
  }];
231
255
  }
232
256
  static get methods() {
@@ -11,8 +11,8 @@ export class PaymentMethodOptions {
11
11
  this.accountId = undefined;
12
12
  this.iframeOrigin = config.iframeOrigin;
13
13
  this.savedPaymentMethods = [];
14
- this.selectedPaymentMethodId = undefined;
15
14
  this.paymentAmount = undefined;
15
+ this.selectedPaymentMethodId = undefined;
16
16
  this.paymentMethodOptions = [];
17
17
  }
18
18
  paymentMethodsChanged() {
@@ -202,23 +202,6 @@ export class PaymentMethodOptions {
202
202
  },
203
203
  "defaultValue": "[]"
204
204
  },
205
- "selectedPaymentMethodId": {
206
- "type": "string",
207
- "mutable": false,
208
- "complexType": {
209
- "original": "string",
210
- "resolved": "string",
211
- "references": {}
212
- },
213
- "required": false,
214
- "optional": false,
215
- "docs": {
216
- "tags": [],
217
- "text": ""
218
- },
219
- "attribute": "selected-payment-method-id",
220
- "reflect": false
221
- },
222
205
  "paymentAmount": {
223
206
  "type": "string",
224
207
  "mutable": false,
@@ -240,6 +223,7 @@ export class PaymentMethodOptions {
240
223
  }
241
224
  static get states() {
242
225
  return {
226
+ "selectedPaymentMethodId": {},
243
227
  "paymentMethodOptions": {}
244
228
  };
245
229
  }
@@ -0,0 +1,126 @@
1
+ import { makeGetCheckout, makeCheckoutComplete } from "../checkout-actions";
2
+ import mockResponse from "../../../../../../mockData/mockGetCheckoutSuccess.json";
3
+ import { Checkout } from "../../../api/Checkout";
4
+ import { API_NOT_AUTHENTICATED_ERROR } from "../../../api/shared";
5
+ // Mocks
6
+ jest.mock('../../../api/services/utils.ts', () => ({
7
+ getErrorMessage: jest.fn(),
8
+ }));
9
+ const mockService = {
10
+ fetchCheckout: jest.fn(),
11
+ complete: jest.fn(),
12
+ };
13
+ // Test Suite
14
+ describe('makeGetCheckout', () => {
15
+ const checkoutId = '123';
16
+ const authToken = 'token';
17
+ afterEach(() => {
18
+ jest.clearAllMocks();
19
+ });
20
+ it('calls onSuccess with a new Checkout instance on successful fetch', async () => {
21
+ mockService.fetchCheckout.mockResolvedValue(mockResponse);
22
+ const onSuccess = jest.fn();
23
+ const onError = jest.fn();
24
+ const getCheckout = makeGetCheckout({
25
+ checkoutId,
26
+ authToken,
27
+ service: mockService,
28
+ });
29
+ await getCheckout({ onSuccess, onError });
30
+ expect(onSuccess).toHaveBeenCalledWith({
31
+ checkout: new Checkout(mockResponse.data),
32
+ });
33
+ expect(onError).not.toHaveBeenCalled();
34
+ });
35
+ it('calls onError with an error message on fetch error', async () => {
36
+ mockService.fetchCheckout.mockResolvedValue(API_NOT_AUTHENTICATED_ERROR);
37
+ const onSuccess = jest.fn();
38
+ const onError = jest.fn();
39
+ const getCheckout = makeGetCheckout({
40
+ checkoutId,
41
+ authToken,
42
+ service: mockService,
43
+ });
44
+ await getCheckout({ onSuccess, onError });
45
+ expect(onError).toHaveBeenCalledWith({
46
+ error: 'Not Authenticated',
47
+ code: 'not-authenticated',
48
+ severity: 'error',
49
+ });
50
+ });
51
+ it('calls onError with an error message on fetch exception', async () => {
52
+ const error = new Error('Network error');
53
+ mockService.fetchCheckout.mockRejectedValue(error);
54
+ const onSuccess = jest.fn();
55
+ const onError = jest.fn();
56
+ const getCheckout = makeGetCheckout({
57
+ checkoutId,
58
+ authToken,
59
+ service: mockService,
60
+ });
61
+ await getCheckout({ onSuccess, onError });
62
+ expect(onError).toHaveBeenCalledWith({
63
+ error: error.message,
64
+ code: 'fetch-error',
65
+ severity: 'error',
66
+ });
67
+ });
68
+ });
69
+ describe('makeCheckoutComplete', () => {
70
+ const checkoutId = '123';
71
+ const authToken = 'token';
72
+ afterEach(() => {
73
+ jest.clearAllMocks();
74
+ });
75
+ it('calls onSuccess with checkout complete response data', async () => {
76
+ mockService.complete.mockResolvedValue(mockResponse);
77
+ const payment = { payment_mode: 'ecom', payment_token: '123' };
78
+ const onSuccess = jest.fn();
79
+ const onError = jest.fn();
80
+ const completeCheckout = makeCheckoutComplete({
81
+ checkoutId,
82
+ authToken,
83
+ service: mockService,
84
+ });
85
+ await completeCheckout({ payment, onSuccess, onError });
86
+ expect(onSuccess).toHaveBeenCalledWith({
87
+ checkout: new Checkout(mockResponse.data),
88
+ });
89
+ expect(onError).not.toHaveBeenCalled();
90
+ });
91
+ it('calls onError with an error message on post error', async () => {
92
+ mockService.complete.mockResolvedValue(API_NOT_AUTHENTICATED_ERROR);
93
+ const payment = { payment_mode: 'ecom', payment_token: '123' };
94
+ const onSuccess = jest.fn();
95
+ const onError = jest.fn();
96
+ const completeCheckout = makeCheckoutComplete({
97
+ checkoutId,
98
+ authToken,
99
+ service: mockService,
100
+ });
101
+ await completeCheckout({ payment, onSuccess, onError });
102
+ expect(onError).toHaveBeenCalledWith({
103
+ error: 'Not Authenticated',
104
+ code: 'not-authenticated',
105
+ severity: 'error',
106
+ });
107
+ });
108
+ it('calls onError with an error message on fetch exception', async () => {
109
+ const error = new Error('Network error');
110
+ mockService.complete.mockRejectedValue(error);
111
+ const payment = { payment_mode: 'ecom', payment_token: '123' };
112
+ const onSuccess = jest.fn();
113
+ const onError = jest.fn();
114
+ const completeCheckout = makeCheckoutComplete({
115
+ checkoutId,
116
+ authToken,
117
+ service: mockService,
118
+ });
119
+ await completeCheckout({ payment, onSuccess, onError });
120
+ expect(onError).toHaveBeenCalledWith({
121
+ error: error.message,
122
+ code: 'fetch-error',
123
+ severity: 'error',
124
+ });
125
+ });
126
+ });
@@ -0,0 +1,127 @@
1
+ import { h } from "@stencil/core";
2
+ import { newSpecPage } from "@stencil/core/testing";
3
+ import { CheckoutCore } from "../checkout-core";
4
+ import { makeCheckoutComplete, makeGetCheckout } from "../checkout-actions";
5
+ import { Checkout } from "../../../api/Checkout";
6
+ import { API_NOT_AUTHENTICATED_ERROR } from "../../../api/shared";
7
+ import mockGetCheckoutSuccess from "./../../../../../../mockData/mockGetCheckoutSuccess.json";
8
+ import mockPostCheckoutSuccess from "./../../../../../../mockData/mockPostCheckoutSuccess.json";
9
+ import { PaymentMethodOptions } from "../payment-method-options";
10
+ describe('justifi-checkout-core', () => {
11
+ it('should display loading state correclty', async () => {
12
+ const page = await newSpecPage({
13
+ components: [CheckoutCore],
14
+ template: () => h("justifi-checkout-core", null),
15
+ });
16
+ await page.waitForChanges();
17
+ expect(page.root).toMatchSnapshot();
18
+ });
19
+ it('should display error state correctly', async () => {
20
+ const getCheckout = makeGetCheckout({
21
+ checkoutId: '',
22
+ authToken: '',
23
+ service: {
24
+ fetchCheckout: async () => ({ error: 'error' }),
25
+ },
26
+ });
27
+ const page = await newSpecPage({
28
+ components: [CheckoutCore],
29
+ template: () => h("checkout-core", { getCheckout: getCheckout }),
30
+ });
31
+ await page.waitForChanges();
32
+ expect(page.root).toMatchSnapshot();
33
+ });
34
+ it('should set checkout correctly to state', async () => {
35
+ const getCheckout = makeGetCheckout({
36
+ checkoutId: '',
37
+ authToken: '',
38
+ service: {
39
+ fetchCheckout: async () => mockGetCheckoutSuccess,
40
+ },
41
+ });
42
+ const page = await newSpecPage({
43
+ components: [CheckoutCore],
44
+ template: () => h("justifi-checkout-core", { getCheckout: getCheckout }),
45
+ });
46
+ await page.waitForChanges();
47
+ const expectedCheckout = new Checkout(mockGetCheckoutSuccess.data);
48
+ expect(page.rootInstance.checkout).toEqual(expectedCheckout);
49
+ expect(page.root).toMatchSnapshot();
50
+ });
51
+ it('should emit error event when fetch fails', async () => {
52
+ const getCheckout = makeGetCheckout({
53
+ authToken: '',
54
+ checkoutId: '',
55
+ service: {
56
+ fetchCheckout: jest.fn().mockRejectedValue(new Error('Fetch error')),
57
+ },
58
+ });
59
+ const errorSpy = jest.fn();
60
+ const page = await newSpecPage({
61
+ components: [CheckoutCore],
62
+ template: () => h("justifi-checkout-core", { getCheckout: getCheckout, "onError-event": errorSpy }),
63
+ });
64
+ await page.waitForChanges();
65
+ expect(errorSpy).toHaveBeenCalledWith(expect.objectContaining({
66
+ detail: {
67
+ errorCode: 'fetch-error',
68
+ message: 'Fetch error',
69
+ severity: 'error',
70
+ }
71
+ }));
72
+ });
73
+ it('should emit error event when API returns error', async () => {
74
+ const getCheckout = makeGetCheckout({
75
+ authToken: '',
76
+ checkoutId: '',
77
+ service: {
78
+ fetchCheckout: jest.fn().mockResolvedValue(API_NOT_AUTHENTICATED_ERROR),
79
+ },
80
+ });
81
+ const errorSpy = jest.fn();
82
+ const page = await newSpecPage({
83
+ components: [CheckoutCore],
84
+ template: () => h("justifi-checkout-core", { getCheckout: getCheckout, "onError-event": errorSpy }),
85
+ });
86
+ await page.waitForChanges();
87
+ expect(errorSpy).toHaveBeenCalledWith(expect.objectContaining({
88
+ detail: {
89
+ errorCode: 'not-authenticated',
90
+ message: 'Not Authenticated',
91
+ severity: 'error',
92
+ }
93
+ }));
94
+ });
95
+ it('emits "submitted" event upon submit request completion', async () => {
96
+ const getCheckout = makeGetCheckout({
97
+ authToken: '',
98
+ checkoutId: '',
99
+ service: {
100
+ fetchCheckout: async () => mockGetCheckoutSuccess,
101
+ }
102
+ });
103
+ const checkoutComplete = makeCheckoutComplete({
104
+ authToken: '',
105
+ checkoutId: '',
106
+ service: {
107
+ fetchCheckout: async () => mockPostCheckoutSuccess,
108
+ }
109
+ });
110
+ const submittedSpy = jest.fn();
111
+ const page = await newSpecPage({
112
+ components: [CheckoutCore, PaymentMethodOptions],
113
+ template: () => h("justifi-checkout-core", { getCheckout: getCheckout, complete: checkoutComplete, onSubmitted: submittedSpy }),
114
+ });
115
+ await page.waitForChanges();
116
+ // mock resolved payment method (token) / select payment method
117
+ const instance = page.rootInstance;
118
+ instance.paymentMethodOptionsRef = { resolvePaymentMethod: jest.fn().mockResolvedValue({ token: '123' }) };
119
+ // Submit the form
120
+ const submitButton = page.root.shadowRoot.querySelector('button[type="submit"]');
121
+ submitButton.click();
122
+ await page.waitForChanges();
123
+ expect(submittedSpy).toHaveBeenCalledWith(expect.objectContaining({
124
+ detail: { "code": "fetch-error", "error": "service.complete is not a function", "severity": "error" }
125
+ }));
126
+ });
127
+ });
@@ -1,8 +1,6 @@
1
1
  import { newSpecPage } from "@stencil/core/testing";
2
2
  import { Checkout } from "../checkout";
3
3
  import { CheckoutCore } from "../checkout-core";
4
- // import { PaymentMethodTypes } from '../../../api';
5
- // import { BillingFormFields } from '../../billing-form/billing-form-schema';
6
4
  describe('justifi-checkout', () => {
7
5
  it('renders', async () => {
8
6
  const page = await newSpecPage({
@@ -12,155 +10,4 @@ describe('justifi-checkout', () => {
12
10
  await page.waitForChanges();
13
11
  expect(page.root).toMatchSnapshot();
14
12
  });
15
- // it('should update selectedPaymentMethodType when paymentMethodSelected event is fired', async () => {
16
- // // Mock component
17
- // const mockComponent = new Checkout();
18
- // mockComponent.selectedPaymentMethodType = PaymentMethodTypes.card;
19
- // // Define the event details
20
- // const detail = PaymentMethodTypes.bankAccount;
21
- // const event = new CustomEvent('paymentMethodSelected', { detail });
22
- // // Simulate the event
23
- // mockComponent.paymentMethodSelectedHandler(event);
24
- // // Assertion
25
- // expect(mockComponent.selectedPaymentMethodType).toBe(PaymentMethodTypes.bankAccount);
26
- // });
27
- // // Props Testing
28
- // it('should have the expected default properties', () => {
29
- // const checkout = new Checkout();
30
- // // Assert that the properties exist and have the expected default values
31
- // expect(checkout).toHaveProperty('bankAccount', undefined);
32
- // expect(checkout).toHaveProperty('card', undefined);
33
- // expect(checkout).toHaveProperty('email', undefined);
34
- // expect(checkout).toHaveProperty('iframeOrigin', undefined);
35
- // expect(checkout).toHaveProperty('clientId', undefined);
36
- // expect(checkout).toHaveProperty('accountId', undefined);
37
- // expect(checkout).toHaveProperty('submitButtonText', undefined);
38
- // });
39
- // // Method Testing
40
- // it('should correctly fill billing form when fillBillingForm method is called', async () => {
41
- // // Mock child component
42
- // const mockBillingFormRef = {
43
- // fill: jest.fn(),
44
- // };
45
- // // Mock component
46
- // const mockComponent = new Checkout();
47
- // // Cast to any to bypass type checker and directly set private property
48
- // (mockComponent as any).billingFormRef = mockBillingFormRef;
49
- // // Define the fields to fill the billing form
50
- // const fields: BillingFormFields = {
51
- // name: 'John Doe',
52
- // address_line1: '123 Main St',
53
- // address_line2: 'Apt 4B',
54
- // address_city: 'Townsville',
55
- // address_state: 'TS',
56
- // address_postal_code: '12345',
57
- // };
58
- // // Call the method
59
- // await mockComponent.fillBillingForm(fields);
60
- // // Check that the child component's fill method was called with the correct arguments
61
- // expect(mockBillingFormRef.fill).toHaveBeenCalledWith(fields);
62
- // });
63
- // it('should submit the form correctly and trigger the "submitted" event with the correct payload when submit method is called', async () => {
64
- // // Mock billingFormRef and paymentMethodFormRef
65
- // const mockBillingFormRef = {
66
- // validate: jest.fn().mockResolvedValue({ isValid: true }),
67
- // getValues: jest.fn().mockResolvedValue({ name: 'John Doe' }),
68
- // };
69
- // const mockPaymentMethodFormRef = {
70
- // validate: jest.fn().mockResolvedValue({ isValid: true }),
71
- // tokenize: jest.fn().mockResolvedValue({ token: 'abc123' }),
72
- // };
73
- // // Mock component
74
- // const mockComponent = new Checkout();
75
- // // Cast to any to bypass type checker and directly set private properties
76
- // (mockComponent as any).billingFormRef = mockBillingFormRef;
77
- // (mockComponent as any).paymentMethodFormRef = mockPaymentMethodFormRef;
78
- // // Mock event
79
- // const mockEvent = { preventDefault: jest.fn() };
80
- // // Mock event emitter
81
- // const mockEmitter = { emit: jest.fn() };
82
- // mockComponent.submitted = mockEmitter as any;
83
- // // Call submit method
84
- // await mockComponent.submit(mockEvent);
85
- // // Expectations
86
- // expect(mockEvent.preventDefault).toHaveBeenCalled();
87
- // expect(mockBillingFormRef.validate).toHaveBeenCalled();
88
- // expect(mockPaymentMethodFormRef.validate).toHaveBeenCalled();
89
- // expect(mockBillingFormRef.getValues).toHaveBeenCalled();
90
- // expect(mockPaymentMethodFormRef.tokenize).toHaveBeenCalledWith(mockComponent.clientId, { name: 'John Doe' }, mockComponent.accountId);
91
- // expect(mockEmitter.emit).toHaveBeenCalledWith({ token: 'abc123' });
92
- // });
93
- // // Event Testing
94
- // it('should fire the "submitted" event with correct data when the form is submitted', async () => {
95
- // // Mock billingFormRef and paymentMethodFormRef
96
- // const mockBillingFormRef = {
97
- // validate: jest.fn().mockResolvedValue({ isValid: true }),
98
- // getValues: jest.fn().mockResolvedValue({
99
- // name: 'John Doe',
100
- // address_line1: 'Address 1',
101
- // address_line2: 'Address 2',
102
- // address_city: 'City',
103
- // address_state: 'State',
104
- // address_postal_code: 'Postal Code',
105
- // }),
106
- // };
107
- // const mockPaymentMethodFormRef = {
108
- // validate: jest.fn().mockResolvedValue({ isValid: true }),
109
- // tokenize: jest.fn().mockResolvedValue({ token: 'abc123' }),
110
- // };
111
- // // Mock component
112
- // const mockComponent = new Checkout();
113
- // // Cast to any to bypass type checker and directly set private properties
114
- // (mockComponent as any).billingFormRef = mockBillingFormRef;
115
- // (mockComponent as any).paymentMethodFormRef = mockPaymentMethodFormRef;
116
- // // Mock event
117
- // const mockEvent = { preventDefault: jest.fn() };
118
- // // Mock event emitter
119
- // const mockEmitter = { emit: jest.fn() };
120
- // mockComponent.submitted = mockEmitter as any;
121
- // // Call submit method
122
- // await mockComponent.submit(mockEvent);
123
- // // Define expected payload
124
- // const expectedPayload = { token: 'abc123' };
125
- // // Expectations
126
- // expect(mockEmitter.emit).toHaveBeenCalledWith(expectedPayload);
127
- // });
128
- // // Render Testing
129
- // it('should correctly render the child components based on the given props and state', async () => {
130
- // // Set up new Checkout with specific props and state
131
- // const component = new Checkout();
132
- // component.iframeOrigin = 'https://example.com';
133
- // component.clientId = 'abc123';
134
- // component.accountId = 'def456';
135
- // // Cast to any to bypass type checker and directly set private properties
136
- // (component as any).submitButtonEnabled = true;
137
- // (component as any).selectedPaymentMethodType = PaymentMethodTypes.card;
138
- // (component as any).allowedPaymentMethodTypes = [PaymentMethodTypes.card, PaymentMethodTypes.bankAccount];
139
- // // Render the component
140
- // const { root } = await newSpecPage({
141
- // components: [Checkout],
142
- // html: '<justifi-checkout payment-method-form-type="card" iframe-origin="https://example.com"></justifi-checkout>',
143
- // });
144
- // // Assert that the rendered output is correct
145
- // expect(root).toEqualHtml(`
146
- // <justifi-checkout iframe-origin="https://example.com" payment-method-form-type="card">
147
- // <mock:shadow-root>
148
- // <form class="gy-3 row">
149
- // <div class="col-12">
150
- // <justifi-payment-method-form iframe-origin="https://example.com" payment-method-form-type="card"></justifi-payment-method-form>
151
- // </div>
152
- // <div class="col-12">
153
- // <justifi-billing-form legend="Billing Info"></justifi-billing-form>
154
- // </div>
155
- // <slot name="insurance"></slot>
156
- // <div class="col-12">
157
- // <button class="btn btn-primary jfi-submit-button" type="submit">
158
- // Submit
159
- // </button>
160
- // </div>
161
- // </form>
162
- // </mock:shadow-root>
163
- // </justifi-checkout>
164
- // `);
165
- // });
166
13
  });