@financial-times/n-conversion-forms 23.0.3 → 23.0.6

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 (43) hide show
  1. package/.circleci/config.yml +4 -4
  2. package/__mocks__/@financial-times/o-expander.js +9 -0
  3. package/__mocks__/@financial-times/o-forms-input.js +11 -0
  4. package/__mocks__/@financial-times/o-forms.js +40 -0
  5. package/build-state/npm-shrinkwrap.json +81 -172
  6. package/components/delivery-security-instructions.spec.js +3 -3
  7. package/components/graduation-date.spec.js +8 -8
  8. package/components/payment-term.spec.js +3 -3
  9. package/components/position.jsx +6 -3
  10. package/components/position.spec.js +15 -5
  11. package/components/responsibility.jsx +6 -3
  12. package/components/responsibility.spec.js +15 -5
  13. package/dist/position.js +6 -2
  14. package/dist/responsibility.js +6 -2
  15. package/helpers/index.spec.js +11 -0
  16. package/helpers/ncf-common-data.spec.js +34 -0
  17. package/helpers/ncf-countries.spec.js +136 -0
  18. package/jest.config.js +3 -0
  19. package/package.json +3 -2
  20. package/utils/app-banner.spec.js +68 -0
  21. package/utils/apple-pay.spec.js +177 -0
  22. package/utils/billing-country.spec.js +87 -0
  23. package/utils/billing-postcode.spec.js +138 -0
  24. package/utils/company-name.spec.js +3 -7
  25. package/utils/country.spec.js +87 -0
  26. package/utils/delivery-address-type.spec.js +24 -11
  27. package/utils/delivery-option-messages.spec.js +3 -3
  28. package/utils/delivery-option.spec.js +100 -15
  29. package/utils/delivery-postcode.spec.js +138 -0
  30. package/utils/delivery-start-date.spec.js +177 -0
  31. package/utils/email.spec.js +210 -0
  32. package/utils/event-notifier.spec.js +116 -0
  33. package/utils/form-element.spec.js +71 -0
  34. package/utils/loader.spec.js +161 -0
  35. package/utils/password.spec.js +65 -0
  36. package/utils/payment-term.spec.js +198 -0
  37. package/utils/payment-type.spec.js +136 -0
  38. package/utils/postcode.spec.js +122 -0
  39. package/utils/salesforce.spec.js +30 -0
  40. package/utils/submit.spec.js +81 -0
  41. package/utils/tracking.spec.js +174 -0
  42. package/utils/validation.spec.js +234 -0
  43. package/utils/zuora.spec.js +249 -0
@@ -5,27 +5,23 @@ import Enzyme, { mount } from 'enzyme';
5
5
  import Adapter from 'enzyme-adapter-react-16';
6
6
  Enzyme.configure({ adapter: new Adapter() });
7
7
 
8
- const { JSDOM } = require('jsdom');
9
-
10
8
  describe('Delivery Option - Util', () => {
11
9
  describe('Get an instance of the util class', () => {
12
- it('should throw an error since the component is not found', () => {
13
- const dom = new JSDOM(`
14
- <!DOCTYPE html>
15
- <html>
16
- <head></head>
17
- <body></body>
18
- </html>
19
- `);
20
- const document = dom.window.document;
10
+ it('throws an error if document element isn not passed in', () => {
11
+ expect(() => {
12
+ new DeliveryOptionUtil();
13
+ }).toThrow();
14
+ });
21
15
 
16
+ it('throws an error since the component is not found', () => {
22
17
  expect(() => {
23
18
  new DeliveryOptionUtil(document);
24
19
  }).toThrow();
25
20
  });
26
21
  });
22
+
27
23
  describe('Show/Hide Items for Delivery Option Change', () => {
28
- it('should swap between hide and show two items by adding and removing the related classes', () => {
24
+ it('swapes between hide and show two items by adding and removing the related classes', () => {
29
25
  const props = {
30
26
  country: 'GBR',
31
27
  options: [
@@ -38,14 +34,13 @@ describe('Delivery Option - Util', () => {
38
34
  <DeliveryOption {...props} />
39
35
  </Form>
40
36
  );
41
- const dom = new JSDOM(`
37
+ document.body.innerHTML = `
42
38
  <!DOCTYPE html>
43
39
  <html>
44
40
  <head></head>
45
41
  <body>${component.html()}</body>
46
42
  </html>
47
- `);
48
- const document = dom.window.document;
43
+ `;
49
44
 
50
45
  const deliveryoptionUtilInstance = new DeliveryOptionUtil(document);
51
46
  expect(deliveryoptionUtilInstance).toBeDefined();
@@ -61,4 +56,94 @@ describe('Delivery Option - Util', () => {
61
56
  expect(document.querySelector('.ncf__hidden #HD')).toBe(null);
62
57
  });
63
58
  });
59
+
60
+ describe('handleDeliveryOptionChange', () => {
61
+ let deliveryOption1Listener;
62
+ let deliveryOption2Listener;
63
+ let formStub;
64
+
65
+ beforeEach(() => {
66
+ deliveryOption1Listener = jest.fn();
67
+ deliveryOption2Listener = jest.fn();
68
+
69
+ formStub = {
70
+ elements: {
71
+ deliveryOption: [
72
+ { addEventListener: deliveryOption1Listener },
73
+ { addEventListener: deliveryOption2Listener },
74
+ ],
75
+ },
76
+ };
77
+
78
+ document.querySelector = jest.fn(() => formStub);
79
+ document.querySelectorAll = jest.fn(() => []);
80
+ });
81
+
82
+ afterEach(() => {
83
+ jest.clearAllMocks();
84
+ });
85
+
86
+ describe('can handle an array', () => {
87
+ it('binds the given callback to the change event on the delivery option fields', async () => {
88
+ let deliveryOptionUtil = new DeliveryOptionUtil(document);
89
+ let callback = jest.fn();
90
+ deliveryOptionUtil.handleDeliveryOptionChange(callback);
91
+
92
+ expect(deliveryOption1Listener).toHaveBeenCalledWith(
93
+ 'change',
94
+ callback
95
+ );
96
+ expect(deliveryOption2Listener).toHaveBeenCalledWith(
97
+ 'change',
98
+ callback
99
+ );
100
+ });
101
+ });
102
+
103
+ describe('can handle a single node element', () => {
104
+ let deliveryOptionUtil;
105
+ let callback;
106
+
107
+ beforeEach(() => {
108
+ const props = {
109
+ country: 'GBR',
110
+ options: [
111
+ { value: 'HD', isSelected: true, isValidDeliveryOption: true },
112
+ { value: 'PV', isSelected: false, isValidDeliveryOption: true },
113
+ ],
114
+ };
115
+ const component = mount(
116
+ <Form>
117
+ <DeliveryOption {...props} />
118
+ </Form>
119
+ );
120
+ document.body.innerHTML = `
121
+ <!DOCTYPE html>
122
+ <html>
123
+ <head></head>
124
+ <body>${component.html()}</body>
125
+ </html>
126
+ `;
127
+
128
+ document.querySelector = jest.fn(() => formStub);
129
+
130
+ deliveryOptionUtil = new DeliveryOptionUtil(document);
131
+ callback = jest.fn();
132
+ });
133
+
134
+ it('can handle having only one form element', () => {
135
+ expect(() => {
136
+ deliveryOptionUtil.handleDeliveryOptionChange(callback);
137
+ }).not.toThrow();
138
+ });
139
+
140
+ it('adds the event listener', () => {
141
+ jest.spyOn(formStub.elements.deliveryOption[0], 'addEventListener');
142
+ deliveryOptionUtil.handleDeliveryOptionChange(callback);
143
+ expect(
144
+ formStub.elements.deliveryOption[0].addEventListener
145
+ ).toHaveBeenCalledWith('change', callback);
146
+ });
147
+ });
148
+ });
64
149
  });
@@ -0,0 +1,138 @@
1
+ const DeliveryPostcode = require('./delivery-postcode');
2
+
3
+ describe('DeliveryPostcode', () => {
4
+ let deliveryPostcode;
5
+ let querySelectorStub;
6
+ let querySelectorAllStub;
7
+
8
+ beforeEach(() => {
9
+ const document = {
10
+ querySelector: () => {
11
+ return {
12
+ querySelectorAll: () => {},
13
+ querySelector: () => {},
14
+ };
15
+ },
16
+ };
17
+ deliveryPostcode = new DeliveryPostcode(
18
+ document,
19
+ '.ncf #deliveryPostcodeField'
20
+ );
21
+ querySelectorStub = jest.spyOn(deliveryPostcode.$el, 'querySelector');
22
+ querySelectorAllStub = jest.spyOn(deliveryPostcode.$el, 'querySelectorAll');
23
+ });
24
+
25
+ afterEach(() => {
26
+ jest.clearAllMocks();
27
+ });
28
+
29
+ it('returns an element', () => {
30
+ expect(deliveryPostcode.$el).toBeDefined();
31
+ });
32
+
33
+ describe('changePostcodeReferenceForCountry', () => {
34
+ beforeEach(() => {
35
+ querySelectorStub.mockReturnValue({ innerHTML: '' });
36
+ querySelectorAllStub.mockReturnValue([
37
+ { innerHTML: '' },
38
+ { innerHTML: '' },
39
+ ]);
40
+ });
41
+
42
+ describe('postcode reference name', () => {
43
+ it('calls querySelector with [data-reference]', () => {
44
+ deliveryPostcode.changePostcodeReferenceForCountry = 'GBR';
45
+ expect(querySelectorAllStub).toHaveBeenCalledWith(
46
+ '[data-reference=postcode]'
47
+ );
48
+ });
49
+
50
+ it('sets postcodeReference to post code by default', () => {
51
+ const expectedResponse = [
52
+ { innerHTML: 'postcode' },
53
+ { innerHTML: 'postcode' },
54
+ ];
55
+ deliveryPostcode.changePostcodeReferenceForCountry = 'GBR';
56
+ expect(deliveryPostcode.reference).toEqual(expectedResponse);
57
+ });
58
+
59
+ it('sets postcodeReference to zip code when country code is USA', () => {
60
+ const expectedResponse = [
61
+ { innerHTML: 'zip code' },
62
+ { innerHTML: 'zip code' },
63
+ ];
64
+ deliveryPostcode.changePostcodeReferenceForCountry = 'USA';
65
+ expect(deliveryPostcode.reference).toEqual(expectedResponse);
66
+ });
67
+
68
+ it('sets postcodeReference to postal code when country code is Canada', () => {
69
+ const expectedResponse = [
70
+ { innerHTML: 'postal code' },
71
+ { innerHTML: 'postal code' },
72
+ ];
73
+ deliveryPostcode.changePostcodeReferenceForCountry = 'CAN';
74
+ expect(deliveryPostcode.reference).toEqual(expectedResponse);
75
+ });
76
+ });
77
+
78
+ describe('placeholder', () => {
79
+ it('calls querySelector with span input', () => {
80
+ querySelectorStub.mockReturnValue({
81
+ placeholder: 'Enter your postcode',
82
+ });
83
+ deliveryPostcode.changePostcodeReferenceForCountry = 'GBR';
84
+ expect(querySelectorStub).toHaveBeenCalledWith('input');
85
+ });
86
+
87
+ it('sets postcode placeholder to `Enter your postcode` by default', () => {
88
+ querySelectorStub.mockReturnValue({
89
+ placeholder: 'Enter your zip code',
90
+ });
91
+ deliveryPostcode.changePostcodeReferenceForCountry = 'GBR';
92
+ expect(deliveryPostcode.postcodeInput.placeholder).toEqual(
93
+ 'Enter your postcode'
94
+ );
95
+ });
96
+
97
+ it('sets postcode placeholder to `Enter your zip code` when country code is USA', () => {
98
+ querySelectorStub.mockReturnValue({
99
+ placeholder: 'Enter your postcode',
100
+ });
101
+ deliveryPostcode.changePostcodeReferenceForCountry = 'USA';
102
+ expect(deliveryPostcode.postcodeInput.placeholder).toEqual(
103
+ 'Enter your zip code'
104
+ );
105
+ });
106
+
107
+ it('sets postcode placeholder to `Enter your postal code` when country code is Canada', () => {
108
+ querySelectorStub.mockReturnValue({
109
+ placeholder: 'Enter your zip code',
110
+ });
111
+ deliveryPostcode.changePostcodeReferenceForCountry = 'CAN';
112
+ expect(deliveryPostcode.postcodeInput.placeholder).toEqual(
113
+ 'Enter your postal code'
114
+ );
115
+ });
116
+ });
117
+ });
118
+
119
+ describe('getPostcodeReferenceByCountry', () => {
120
+ it('returns post code by default ', () => {
121
+ expect(DeliveryPostcode.getPostcodeReferenceByCountry('ZAR')).toEqual(
122
+ 'postcode'
123
+ );
124
+ });
125
+
126
+ it('returns postal code when country is Canada', () => {
127
+ expect(DeliveryPostcode.getPostcodeReferenceByCountry('CAN')).toEqual(
128
+ 'postal code'
129
+ );
130
+ });
131
+
132
+ it('returns zip code when country is USA', () => {
133
+ expect(DeliveryPostcode.getPostcodeReferenceByCountry('USA')).toEqual(
134
+ 'zip code'
135
+ );
136
+ });
137
+ });
138
+ });
@@ -0,0 +1,177 @@
1
+ jest.mock('fetchres');
2
+ const fetchres = require('fetchres');
3
+ const DeliveryStartDate = require('./delivery-start-date');
4
+
5
+ describe('DeliveryStartDate', () => {
6
+ let document;
7
+ let startDateContainer;
8
+ let startDateFieldStub;
9
+ let startDateTextStub;
10
+ let dateTestInput;
11
+ let csrfFieldElement;
12
+
13
+ beforeEach(() => {
14
+ fetchres.json = jest.fn((response) => response.json());
15
+ global.fetch = jest.fn(() =>
16
+ Promise.resolve({
17
+ status: 200,
18
+ })
19
+ );
20
+
21
+ dateTestInput = {
22
+ setAttribute: jest.fn(),
23
+ };
24
+ startDateContainer = {
25
+ classList: { add: jest.fn(), remove: jest.fn() },
26
+ };
27
+ startDateFieldStub = {
28
+ value: '2019-02-16',
29
+ setAttribute: jest.fn(),
30
+ removeAttribute: jest.fn(),
31
+ };
32
+ startDateTextStub = { innerHTML: 'Saturday 16th of February 2019' };
33
+ csrfFieldElement = { value: '1234567890' };
34
+
35
+ document = {
36
+ querySelector: jest.fn((elementIdentifier) => {
37
+ const classMapping = {
38
+ '#deliveryStartDateField .o-forms-input': startDateContainer,
39
+ '#deliveryStartDate': startDateFieldStub,
40
+ '.js-start-date-text': startDateTextStub,
41
+ '.ncf #csrfToken': csrfFieldElement,
42
+ };
43
+
44
+ return classMapping[elementIdentifier] || false;
45
+ }),
46
+ createElement: jest.fn((elementType) => {
47
+ return elementType === 'input' ? dateTestInput : false;
48
+ }),
49
+ };
50
+ });
51
+
52
+ afterEach(() => {
53
+ fetch.mockClear();
54
+ jest.clearAllMocks();
55
+ });
56
+
57
+ describe('constructor', () => {
58
+ it('throws an error if document element is not passed in', () => {
59
+ expect(() => {
60
+ new DeliveryStartDate();
61
+ }).toThrow();
62
+ });
63
+
64
+ it('throws an error if delivery start date element does not exist on the page', () => {
65
+ expect(() => {
66
+ document.querySelector = () => {};
67
+ new DeliveryStartDate(document);
68
+ }).toThrow();
69
+ });
70
+ });
71
+
72
+ describe('handleDeliveryStartDateChange', () => {
73
+ let startDateUtil;
74
+ let startDateChangeResult;
75
+
76
+ async function setup () {
77
+ global.fetch = jest.fn(() =>
78
+ Promise.resolve({
79
+ json: () =>
80
+ Promise.resolve({
81
+ firstDeliveryDate: '2019-04-13',
82
+ firstDeliveryDateString: 'Saturday 13th of April 2019',
83
+ }),
84
+ })
85
+ );
86
+
87
+ startDateUtil = new DeliveryStartDate(document);
88
+ startDateChangeResult = await startDateUtil.handleDeliveryStartDateChange(
89
+ '/api/path',
90
+ () => {
91
+ return { foo: 'bar' };
92
+ }
93
+ );
94
+ }
95
+
96
+ it('does only call the api if the field has a value', async () => {
97
+ delete startDateFieldStub.value;
98
+ await setup();
99
+ expect(fetch).not.toHaveBeenCalled();
100
+ });
101
+
102
+ it('makes a call to the api for the start date', async () => {
103
+ await setup();
104
+ expect(fetch).toHaveBeenCalled();
105
+ expect(fetch).toHaveBeenCalledWith(
106
+ '/api/path',
107
+ expect.objectContaining({
108
+ method: 'POST',
109
+ credentials: 'include',
110
+ headers: {
111
+ 'CSRF-Token': '1234567890',
112
+ 'Content-Type': 'application/json',
113
+ },
114
+ body: JSON.stringify({
115
+ foo: 'bar',
116
+ startDate: '2019-02-16',
117
+ }),
118
+ })
119
+ );
120
+ });
121
+
122
+ it('updates the page according to the response from the API call', async () => {
123
+ await setup();
124
+ expect(startDateFieldStub.value).toEqual('2019-04-13');
125
+ expect(startDateTextStub.innerHTML).toEqual(
126
+ 'Saturday 13th of April 2019'
127
+ );
128
+ });
129
+
130
+ it('clears errors and return true if the fetch call succeeds', async () => {
131
+ await setup();
132
+ expect(startDateContainer.classList.remove).toHaveBeenCalledWith(
133
+ 'o-forms-input--invalid'
134
+ );
135
+ expect(startDateChangeResult).toBe(true);
136
+ });
137
+
138
+ it('displays an error and return false if the fetch call errors', async () => {
139
+ global.fetch = jest.fn(() => Promise.reject('API is down'));
140
+ startDateUtil = new DeliveryStartDate(document);
141
+
142
+ let startDateChangeResult =
143
+ await startDateUtil.handleDeliveryStartDateChange(
144
+ '/api/path',
145
+ () => {}
146
+ );
147
+
148
+ expect(startDateContainer.classList.add).toHaveBeenCalledWith(
149
+ 'o-forms-input--invalid'
150
+ );
151
+ expect(startDateChangeResult).toBe(false);
152
+ });
153
+ });
154
+
155
+ describe('enable', () => {
156
+ it('enables the start date field', () => {
157
+ let startDateUtil = new DeliveryStartDate(document);
158
+ startDateUtil.enable();
159
+
160
+ expect(startDateFieldStub.removeAttribute).toHaveBeenCalledWith(
161
+ 'disabled'
162
+ );
163
+ });
164
+ });
165
+
166
+ describe('disable', () => {
167
+ it('disables the start date field', () => {
168
+ let startDateUtil = new DeliveryStartDate(document);
169
+ startDateUtil.disable();
170
+
171
+ expect(startDateFieldStub.setAttribute).toHaveBeenCalledWith(
172
+ 'disabled',
173
+ 'true'
174
+ );
175
+ });
176
+ });
177
+ });
@@ -0,0 +1,210 @@
1
+ jest.mock('fetchres');
2
+ const fetchres = require('fetchres');
3
+ const Email = require('./email');
4
+
5
+ describe('Email', () => {
6
+ let document;
7
+ let emailElement;
8
+ let emailConfirmElement;
9
+ let emailConfirmFieldElement;
10
+ let csrfFieldElement;
11
+
12
+ beforeEach(() => {
13
+ emailElement = { addEventListener: () => {} };
14
+ emailConfirmElement = { addEventListener: () => {} };
15
+ emailConfirmFieldElement = {
16
+ classList: { add: () => {}, remove: () => {} },
17
+ };
18
+ csrfFieldElement = { value: '1234567890' };
19
+
20
+ document = {
21
+ querySelector: (selector) => {
22
+ if (selector.indexOf('#emailConfirmField') !== -1) {
23
+ return emailConfirmFieldElement;
24
+ } else if (selector.indexOf('#emailConfirm') !== -1) {
25
+ return emailConfirmElement;
26
+ } else if (selector.indexOf('#csrfToken') !== -1) {
27
+ return csrfFieldElement;
28
+ } else {
29
+ return emailElement;
30
+ }
31
+ },
32
+ };
33
+ jest.spyOn(emailElement, 'addEventListener');
34
+ jest.spyOn(emailConfirmElement, 'addEventListener');
35
+ jest.spyOn(emailConfirmFieldElement.classList, 'add');
36
+ jest.spyOn(emailConfirmFieldElement.classList, 'remove');
37
+
38
+ fetchres.json = jest.fn((response) => response.json());
39
+ global.fetch = jest.fn(() =>
40
+ Promise.resolve({
41
+ status: 200,
42
+ })
43
+ );
44
+ });
45
+
46
+ afterEach(() => {
47
+ fetch.mockClear();
48
+ jest.clearAllMocks();
49
+ });
50
+
51
+ describe('constructor', () => {
52
+ it('throws an error if document element is not passed in', () => {
53
+ expect(() => {
54
+ new Email();
55
+ }).toThrow();
56
+ });
57
+
58
+ it('throws an error if email confirm element does not exist on the page', () => {
59
+ expect(() => {
60
+ document.querySelector = () => {};
61
+ new Email(document);
62
+ }).toThrow();
63
+ });
64
+
65
+ it('throws an error if email element does not exist on the page', () => {
66
+ expect(() => {
67
+ document.querySelector = (selector) => {
68
+ if (selector.indexOf('#emailConfirmField') !== -1) {
69
+ return emailConfirmFieldElement;
70
+ }
71
+ };
72
+ new Email(document);
73
+ }).toThrow();
74
+ });
75
+
76
+ it('adds event listener to email element', () => {
77
+ new Email(document);
78
+ expect(emailElement.addEventListener).toHaveBeenCalledTimes(1);
79
+ });
80
+
81
+ it('adds addEventListener to email confirm element', () => {
82
+ new Email(document);
83
+ expect(emailConfirmElement.addEventListener).toHaveBeenCalledTimes(1);
84
+ });
85
+ });
86
+
87
+ describe('checkMatch', () => {
88
+ it('adds the error class if the fields do not match', () => {
89
+ emailElement.value = 'password';
90
+ emailConfirmElement.value = 'pass';
91
+
92
+ let email = new Email(document);
93
+ email.checkMatch();
94
+
95
+ expect(emailConfirmFieldElement.classList.add).toHaveBeenCalledTimes(1);
96
+ });
97
+
98
+ it('removes the error class if the fields match', () => {
99
+ emailElement.value = 'password';
100
+ emailConfirmElement.value = 'password';
101
+
102
+ let email = new Email(document);
103
+ email.checkMatch();
104
+
105
+ expect(emailConfirmFieldElement.classList.remove).toHaveBeenCalledTimes(
106
+ 1
107
+ );
108
+ });
109
+
110
+ it('does only check if valid if emailConfirm field has a value.', () => {
111
+ emailElement.value = 'password';
112
+ emailConfirmElement.value = '';
113
+
114
+ let email = new Email(document);
115
+ email.checkMatch();
116
+
117
+ expect(emailConfirmFieldElement.classList.add).not.toHaveBeenCalled();
118
+ expect(emailConfirmFieldElement.classList.remove).not.toHaveBeenCalled();
119
+ });
120
+ });
121
+
122
+ describe('Email Exists', () => {
123
+ const url = '/foo';
124
+ let email;
125
+ let onFound;
126
+ let onNotFound;
127
+
128
+ beforeEach(() => {
129
+ onFound = jest.fn();
130
+ onNotFound = jest.fn();
131
+
132
+ email = new Email(document);
133
+ });
134
+
135
+ it('adds an additional event listener to the email field', () => {
136
+ email.registerEmailExistsCheck(url, onFound, onNotFound);
137
+ // Check it's called twice since by default we bind a change listener in the constructor.
138
+ expect(emailElement.addEventListener).toHaveBeenCalledTimes(2);
139
+ });
140
+
141
+ it('returns the handler function so it can potentially be unregistered', () => {
142
+ let handler = email.registerEmailExistsCheck(url, onFound, onNotFound);
143
+ expect(handler).toBeInstanceOf(Function);
144
+ });
145
+
146
+ it('calls the onNotFound callback if the email field has no value.', () => {
147
+ email.handleEmailExistsChange(url, onFound, onNotFound);
148
+ expect(onFound).not.toHaveBeenCalled();
149
+ expect(onNotFound).toHaveBeenCalled();
150
+ });
151
+
152
+ it('calls the specified url with the correct params if the email field has a value', () => {
153
+ emailElement.value = 'test@example.com';
154
+ email.handleEmailExistsChange(url, onFound, onNotFound);
155
+
156
+ expect(fetch).toHaveBeenCalledWith(
157
+ url,
158
+ expect.objectContaining({
159
+ method: 'POST',
160
+ credentials: 'include',
161
+ headers: {
162
+ 'Content-Type': 'application/json',
163
+ },
164
+ body: JSON.stringify({
165
+ email: 'test@example.com',
166
+ csrfToken: '1234567890',
167
+ }),
168
+ })
169
+ );
170
+ });
171
+
172
+ it('calls the onNotFound callback if the call to the url fails', async () => {
173
+ global.fetch = jest.fn(() => Promise.reject('API is down'));
174
+
175
+ emailElement.value = 'test@example.com';
176
+ await email.handleEmailExistsChange(url, onFound, onNotFound);
177
+
178
+ expect(onFound).not.toHaveBeenCalled();
179
+ expect(onNotFound).toHaveBeenCalled();
180
+ });
181
+
182
+ it('calls the onFound callback if the user exists', async () => {
183
+ global.fetch = jest.fn(() =>
184
+ Promise.resolve({
185
+ json: () => Promise.resolve(true),
186
+ })
187
+ );
188
+
189
+ emailElement.value = 'test@example.com';
190
+ await email.handleEmailExistsChange(url, onFound, onNotFound);
191
+
192
+ expect(onFound).toHaveBeenCalled();
193
+ expect(onNotFound).not.toHaveBeenCalled();
194
+ });
195
+
196
+ it('calls the onNotFound callback if the user does not exist', async () => {
197
+ global.fetch = jest.fn(() =>
198
+ Promise.resolve({
199
+ json: () => Promise.resolve(false),
200
+ })
201
+ );
202
+
203
+ emailElement.value = 'test@example.com';
204
+ await email.handleEmailExistsChange(url, onFound, onNotFound);
205
+
206
+ expect(onFound).not.toHaveBeenCalled();
207
+ expect(onNotFound).toHaveBeenCalled();
208
+ });
209
+ });
210
+ });