@financial-times/n-conversion-forms 46.0.0 → 47.0.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.
@@ -1,390 +1,717 @@
1
- import { PaymentTerm } from './index';
2
- import { expectToRenderCorrectly } from '../test-jest/helpers/expect-to-render-correctly';
3
1
  import React from 'react';
4
2
  import Enzyme, { shallow } from 'enzyme';
5
3
  import Adapter from 'enzyme-adapter-react-16';
6
4
 
5
+ import { PaymentTerm } from './index';
6
+ import { expectToRenderCorrectly } from '../test-jest/helpers/expect-to-render-correctly';
7
+
7
8
  expect.extend(expectToRenderCorrectly);
8
9
  Enzyme.configure({ adapter: new Adapter() });
9
10
 
10
- describe('PaymentTerm', () => {
11
- it('render with defaults', () => {
12
- const props = {};
13
-
14
- expect(PaymentTerm).toRenderCorrectly(props);
15
- });
11
+ const buildOption = (overrides = {}) => ({
12
+ name: 'monthly',
13
+ price: '£20.00',
14
+ value: 'P1M',
15
+ amount: '20.00',
16
+ symbol: '£',
17
+ isTrial: false,
18
+ selected: false,
19
+ subscriptionAutoRenewTerm: true,
20
+ ...overrides,
21
+ });
16
22
 
17
- it('render with isPrintOrBundle', () => {
18
- const props = {
19
- isPrintOrBundle: true,
20
- };
23
+ describe('PaymentTerm', () => {
24
+ describe('default props are used', () => {
25
+ it('renders correctly', () => {
26
+ const props = {};
21
27
 
22
- expect(PaymentTerm).toRenderCorrectly(props);
28
+ expect(PaymentTerm).toRenderCorrectly(props);
29
+ });
23
30
  });
24
31
 
25
- ['annual', 'quarterly', 'monthly'].forEach((type) => {
26
- describe(`${type} option`, () => {
27
- it('render option', () => {
28
- const props = {
29
- options: [
30
- {
31
- name: type,
32
- value: type,
33
- price: '£20.00',
34
- },
35
- ],
36
- };
37
-
38
- expect(PaymentTerm).toRenderCorrectly(props);
32
+ describe('payment term input props', () => {
33
+ describe('option.isTrial is false', () => {
34
+ it('renders option.trialAmount as data-base-amount', () => {
35
+ const options = [
36
+ {
37
+ name: 'monthly',
38
+ price: '$5.00',
39
+ value: 'monthly',
40
+ monthlyPrice: '$5.00',
41
+ isTrial: false,
42
+ amount: 100,
43
+ trialAmount: 1,
44
+ },
45
+ ];
46
+ const wrapper = shallow(<PaymentTerm options={options} />);
47
+ expect(wrapper.find('input').prop('data-base-amount')).toBe(100);
39
48
  });
49
+ });
40
50
 
41
- it('render option with discount', () => {
42
- const props = {
43
- options: [
44
- {
45
- name: type,
46
- value: type,
47
- price: '£20.00',
48
- discount: '25% off',
49
- },
50
- ],
51
- };
52
-
53
- expect(PaymentTerm).toRenderCorrectly(props);
51
+ describe('option.isTrial is true', () => {
52
+ it('renders option.trialAmount as data-base-amount', () => {
53
+ const options = [
54
+ {
55
+ name: 'monthly',
56
+ price: '$5.00',
57
+ value: 'monthly',
58
+ monthlyPrice: '$5.00',
59
+ isTrial: true,
60
+ amount: 100,
61
+ trialAmount: 1,
62
+ },
63
+ ];
64
+ const wrapper = shallow(<PaymentTerm options={options} />);
65
+ expect(wrapper.find('input').prop('data-base-amount')).toBe(1);
54
66
  });
67
+ });
55
68
 
56
- it('render option with isTrial', () => {
57
- const props = {
58
- options: [
59
- {
60
- name: type,
61
- value: type,
62
- price: '£20.00',
63
- isTrial: true,
64
- },
65
- ],
66
- };
69
+ describe('option.selected is true', () => {
70
+ it('renders the option as selected', () => {
71
+ const options = [
72
+ buildOption({
73
+ selected: true,
74
+ }),
75
+ ];
76
+ const wrapper = shallow(<PaymentTerm options={options} />);
67
77
 
68
- expect(PaymentTerm).toRenderCorrectly(props);
78
+ expect(wrapper.find('input')).toHaveLength(1);
79
+ expect(wrapper.find('input').prop('defaultChecked')).toBe(true);
80
+ expect(wrapper.find('input').prop('id')).toBe('P1M');
81
+ expect(wrapper.find('label').prop('htmlFor')).toBe('P1M');
69
82
  });
83
+ });
70
84
 
71
- it('render option with selected', () => {
72
- const props = {
73
- options: [
74
- {
75
- name: type,
76
- value: type,
77
- price: '£20.00',
78
- selected: true,
79
- },
80
- ],
81
- };
85
+ describe('option.selected is false', () => {
86
+ it('does not render the option as selected', () => {
87
+ const options = [
88
+ buildOption({
89
+ selected: false,
90
+ }),
91
+ ];
92
+ const wrapper = shallow(<PaymentTerm options={options} />);
82
93
 
83
- expect(PaymentTerm).toRenderCorrectly(props);
94
+ expect(wrapper.find('input')).toHaveLength(1);
95
+ expect(wrapper.find('input').prop('defaultChecked')).toBeUndefined();
96
+ expect(wrapper.find('input').prop('id')).toBe('P1M');
97
+ expect(wrapper.find('label').prop('htmlFor')).toBe('P1M');
84
98
  });
99
+ });
100
+ });
85
101
 
86
- it('render option with trial', () => {
87
- const props = {
88
- options: [
89
- {
90
- name: type,
91
- value: type,
92
- price: '£20.00',
93
- isTrial: true,
94
- trialDuration: '6 weeks',
95
- trialPrice: '£1.00',
96
- },
97
- ],
98
- };
99
-
100
- expect(PaymentTerm).toRenderCorrectly(props);
102
+ describe('payment term option discount', () => {
103
+ describe('option.discount is true', () => {
104
+ describe('option.bestOffer is true', () => {
105
+ it('displays "Best offer"', () => {
106
+ const options = [
107
+ buildOption({
108
+ discount: '25%',
109
+ bestOffer: true,
110
+ }),
111
+ ];
112
+ const wrapper = shallow(<PaymentTerm options={options} />);
113
+
114
+ expect(wrapper.find('.ncf__payment-term__discount')).toHaveLength(1);
115
+ expect(wrapper.find('.ncf__payment-term__discount').text()).toBe(
116
+ 'Best offer'
117
+ );
118
+ });
101
119
  });
102
120
 
103
- it('render option with monthlyPrice', () => {
104
- const props = {
105
- options: [
106
- {
107
- name: type,
108
- value: type,
109
- price: '£20.00',
110
- monthlyPrice: '£1.67',
111
- },
112
- ],
113
- };
114
-
115
- expect(PaymentTerm).toRenderCorrectly(props);
121
+ describe('option.bestOffer is false', () => {
122
+ it('displays, e.g. "Save 25% off RRP" where the percentage is defined by the offer.discount value', () => {
123
+ const options = [
124
+ buildOption({
125
+ discount: '25%',
126
+ bestOffer: false,
127
+ }),
128
+ ];
129
+ const wrapper = shallow(<PaymentTerm options={options} />);
130
+
131
+ expect(wrapper.find('.ncf__payment-term__discount')).toHaveLength(1);
132
+ expect(wrapper.find('.ncf__payment-term__discount').text()).toBe(
133
+ 'Save 25% off RRP'
134
+ );
135
+ });
116
136
  });
117
137
  });
118
- });
119
138
 
120
- describe('isAutoRenewingSubscriptionTermType is true; isNonRenewingSubscriptionTermType is false', () => {
121
- describe('pre-defined option name (i.e. frequency)', () => {
122
- const ANNUAL_FREQUENCY = 'annual';
123
- const QUARTERLY_FREQUENCY = 'quarterly';
124
- const MONTHLY_FREQUENCY = 'monthly';
125
-
126
- [ANNUAL_FREQUENCY, QUARTERLY_FREQUENCY, MONTHLY_FREQUENCY].forEach(
127
- (frequency) => {
128
- const FREQUENCY_TO_RENEWAL_TEXT_MAP = {
129
- [ANNUAL_FREQUENCY]: 'Renews annually unless cancelled',
130
- [QUARTERLY_FREQUENCY]: 'Renews quarterly unless cancelled',
131
- [MONTHLY_FREQUENCY]: 'Renews monthly unless cancelled',
132
- };
133
-
134
- describe(`${frequency} option`, () => {
135
- const options = [
136
- {
137
- name: frequency,
138
- value: frequency,
139
- price: '£20.00',
140
- },
141
- ];
142
-
143
- it(`renders '${FREQUENCY_TO_RENEWAL_TEXT_MAP[frequency]}' when true`, () => {
144
- const wrapper = shallow(
145
- <PaymentTerm
146
- options={options}
147
- isAutoRenewingSubscriptionTermType={true}
148
- isNonRenewingSubscriptionTermType={false}
149
- />
150
- );
151
- expect(
152
- wrapper.find('.ncf__payment-term__renews-text').exists()
153
- ).toBe(true);
154
- expect(
155
- wrapper.find('.ncf__payment-term__renews-text').text()
156
- ).toBe(FREQUENCY_TO_RENEWAL_TEXT_MAP[frequency]);
157
- });
158
- });
159
- }
160
- );
161
- });
139
+ describe('option.discount is false', () => {
140
+ it('does not display any discount-related text', () => {
141
+ const options = [
142
+ buildOption({
143
+ discount: '',
144
+ }),
145
+ ];
146
+ const wrapper = shallow(<PaymentTerm options={options} />);
162
147
 
163
- describe('custom option with period provided', () => {
164
- const options = [
165
- {
166
- price: '£50.00',
167
- amount: '50.00',
168
- currency: 'GBP',
169
- value: 'P6M',
170
- },
171
- ];
172
-
173
- it('renders renewal text for custom terms that specify a period', () => {
174
- const wrapper = shallow(
175
- <PaymentTerm
176
- options={options}
177
- isAutoRenewingSubscriptionTermType={true}
178
- isNonRenewingSubscriptionTermType={false}
179
- />
180
- );
181
- expect(wrapper.find('.ncf__payment-term__renews-text').text()).toBe(
182
- 'Renews every 6 months unless cancelled'
148
+ expect(wrapper.find('.ncf__payment-term__discount').exists()).toBe(
149
+ false
183
150
  );
151
+ expect(wrapper.text()).not.toContain('Best offer');
152
+ expect(wrapper.text()).not.toContain('off RRP');
184
153
  });
185
154
  });
186
155
  });
187
156
 
188
- describe('isAutoRenewingSubscriptionTermType is false; isNonRenewingSubscriptionTermType is true', () => {
189
- describe('options include duration expressed in weeks', () => {
190
- const options = [
191
- {
192
- price: '£19.00',
193
- amount: '19.00',
194
- value: 'P8W',
195
- },
196
- ];
197
- const wrapper = shallow(
198
- <PaymentTerm
199
- options={options}
200
- isAutoRenewingSubscriptionTermType={false}
201
- isNonRenewingSubscriptionTermType={true}
202
- />
203
- );
204
-
205
- it('renders subscription term as title', () => {
157
+ describe('payment term option display name', () => {
158
+ describe('option.isTrial is true (and isPrintOrBundle and isDigitalEdition are both false)', () => {
159
+ it('prefixes the payment term option display name with "Trial: "', () => {
160
+ const options = [
161
+ buildOption({
162
+ name: 'annual',
163
+ value: 'P1Y',
164
+ isTrial: true,
165
+ trialDuration: '4 weeks',
166
+ trialPrice: '£1.00',
167
+ }),
168
+ ];
169
+ const wrapper = shallow(<PaymentTerm options={options} />);
170
+
206
171
  expect(wrapper.find('.ncf__payment-term__title').text()).toMatch(
207
- '8 weeks'
172
+ /^Trial: /
208
173
  );
209
174
  });
210
175
 
211
- it('renders description text that reflects that the non-renewing subscription requires a single payment that expresses the per duration cost for shorter durations', () => {
212
- expect(
213
- wrapper.find('.ncf__payment-term__description').text()
214
- ).toContain(
215
- 'Single £19.00 paymentThat’s equivalent to GBP9.50 per month'
216
- );
176
+ describe('custom option.displayName is provided', () => {
177
+ it('uses the custom option.displayName as the term display name', () => {
178
+ const options = [
179
+ buildOption({
180
+ name: 'annual',
181
+ value: 'P1Y',
182
+ isTrial: true,
183
+ displayName: 'Standard Digital Plus',
184
+ trialDuration: '4 weeks',
185
+ trialPrice: '£1.00',
186
+ }),
187
+ ];
188
+ const wrapper = shallow(<PaymentTerm options={options} />);
189
+
190
+ expect(wrapper.find('.ncf__payment-term__title').text()).toContain(
191
+ 'Trial: Standard Digital Plus - Annual'
192
+ );
193
+ });
194
+ });
195
+
196
+ describe('custom option.displayName is not provided', () => {
197
+ it('defaults to "Premium Digital"', () => {
198
+ const options = [
199
+ buildOption({
200
+ name: 'annual',
201
+ value: 'P1Y',
202
+ isTrial: true,
203
+ trialDuration: '4 weeks',
204
+ trialPrice: '£1.00',
205
+ }),
206
+ ];
207
+ const wrapper = shallow(<PaymentTerm options={options} />);
208
+
209
+ expect(wrapper.find('.ncf__payment-term__title').text()).toContain(
210
+ 'Trial: Premium Digital - Annual'
211
+ );
212
+ });
217
213
  });
218
214
  });
219
215
 
220
- describe('options include duration expressed in days', () => {
221
- const options = [
222
- {
223
- price: '£30.00',
224
- amount: '30.00',
225
- value: 'P90D',
226
- },
227
- ];
228
- const wrapper = shallow(
229
- <PaymentTerm
230
- options={options}
231
- isAutoRenewingSubscriptionTermType={false}
232
- isNonRenewingSubscriptionTermType={true}
233
- />
234
- );
235
-
236
- it('renders subscription term as title', () => {
237
- expect(wrapper.find('.ncf__payment-term__title').text()).toMatch(
238
- '90 days'
216
+ describe('option.isTrial is false', () => {
217
+ it('does not prefix the payment term option display name with "Trial: "', () => {
218
+ const options = [
219
+ buildOption({
220
+ name: 'annual',
221
+ value: 'P1Y',
222
+ isTrial: false,
223
+ }),
224
+ ];
225
+ const wrapper = shallow(<PaymentTerm options={options} />);
226
+
227
+ expect(wrapper.find('.ncf__payment-term__title').text()).not.toContain(
228
+ 'Trial: '
239
229
  );
240
230
  });
231
+ });
241
232
 
242
- it('renders description text that reflects that the non-renewing subscription requires a single payment that expresses the per duration cost for shorter durations', () => {
243
- expect(
244
- wrapper.find('.ncf__payment-term__description').text()
245
- ).toContain(
246
- 'Single £30.00 paymentThat’s equivalent to GBP10.00 per month'
233
+ describe('option.subscriptionAutoRenewTerm is true, i.e. auto-renewing subscription, and option.name is present', () => {
234
+ it('expresses the term period by using the capitalised option.name value', () => {
235
+ const options = [
236
+ buildOption({
237
+ name: 'annual',
238
+ subscriptionAutoRenewTerm: true,
239
+ }),
240
+ ];
241
+ const wrapper = shallow(<PaymentTerm options={options} />);
242
+
243
+ expect(wrapper.find('.ncf__payment-term__title').text()).toContain(
244
+ 'Annual'
247
245
  );
248
246
  });
249
247
  });
250
248
 
251
- describe('renewal text', () => {
252
- const options = [
253
- {
254
- price: '£19.00',
255
- amount: '19.00',
256
- value: 'P8W',
257
- },
258
- ];
249
+ describe('option.subscriptionAutoRenewTerm is false, i.e. non-renewing (single-term) subscription', () => {
250
+ describe('option.value is a valid period', () => {
251
+ it('expresses the term period as a human-readable duration derived from the option.value value', () => {
252
+ const options = [
253
+ buildOption({
254
+ displayName: 'Standard Digital',
255
+ isTrial: true,
256
+ subscriptionAutoRenewTerm: false,
257
+ value: 'P8W',
258
+ price: '£19.00',
259
+ amount: '19.00',
260
+ trialDuration: '4 weeks',
261
+ trialPrice: '£1.00',
262
+ }),
263
+ ];
264
+ const wrapper = shallow(
265
+ <PaymentTerm
266
+ options={options}
267
+ isAutoRenewingSubscriptionTermType={false}
268
+ isNonRenewingSubscriptionTermType={true}
269
+ />
270
+ );
271
+
272
+ expect(wrapper.find('.ncf__payment-term__title').text()).toContain(
273
+ 'Trial: Standard Digital - 8 weeks'
274
+ );
275
+ });
276
+ });
259
277
 
260
- it('does not render renewal text for custom terms', () => {
261
- const wrapper = shallow(
262
- <PaymentTerm
263
- options={options}
264
- isAutoRenewingSubscriptionTermType={false}
265
- isNonRenewingSubscriptionTermType={true}
266
- />
267
- );
268
- expect(wrapper.find('.ncf__payment-term__renews-text').exists()).toBe(
269
- false
270
- );
278
+ describe('option.value is a not valid period', () => {
279
+ it('uses the option.title value', () => {
280
+ const options = [
281
+ buildOption({
282
+ displayName: 'Standard Digital',
283
+ isTrial: true,
284
+ subscriptionAutoRenewTerm: false,
285
+ value: 'custom-term',
286
+ title: '12 Month Subscription',
287
+ price: '£100.00',
288
+ trialDuration: '4 weeks',
289
+ trialPrice: '£1.00',
290
+ }),
291
+ ];
292
+ const wrapper = shallow(
293
+ <PaymentTerm
294
+ options={options}
295
+ isAutoRenewingSubscriptionTermType={false}
296
+ isNonRenewingSubscriptionTermType={true}
297
+ />
298
+ );
299
+
300
+ expect(wrapper.find('.ncf__payment-term__title').text()).toContain(
301
+ 'Trial: Standard Digital - 12 Month Subscription'
302
+ );
303
+ });
271
304
  });
272
305
  });
273
306
  });
274
307
 
275
- describe('getDisplayName', () => {
276
- const baseOptions = {
277
- name: 'monthly',
278
- value: 'monthly',
279
- price: '£20.00',
280
- monthlyPrice: '£1.67',
281
- };
282
- describe('non-trial terms', () => {
283
- const options = [
284
- {
285
- ...baseOptions,
286
- isTrial: false,
287
- },
288
- ];
289
- it('renders with time period only if trial.option == false', () => {
308
+ describe('payment term option description', () => {
309
+ describe('option.isTrial is true', () => {
310
+ it('displays the trial duration', () => {
311
+ const options = [
312
+ buildOption({
313
+ isTrial: true,
314
+ displayName: 'Standard Digital',
315
+ trialDuration: '6 weeks',
316
+ trialPrice: '£1.00',
317
+ price: '£20.00',
318
+ value: 'P1M',
319
+ }),
320
+ ];
290
321
  const wrapper = shallow(<PaymentTerm options={options} />);
291
- expect(wrapper.find('.ncf__payment-term__label').text()).toMatch(
292
- /^Monthly .*$/
293
- );
322
+
323
+ expect(
324
+ wrapper.find('.ncf__payment-term__description').text()
325
+ ).toContain('6 weeks');
294
326
  });
295
- });
296
- describe('getDisplayName', () => {
297
- const trialOptions = {
298
- ...baseOptions,
299
- isTrial: true,
300
- };
301
- it('defaults to `Premium digital`', () => {
302
- const options = [trialOptions];
327
+
328
+ it('displays the trial price', () => {
329
+ const options = [
330
+ buildOption({
331
+ isTrial: true,
332
+ displayName: 'Standard Digital',
333
+ trialDuration: '6 weeks',
334
+ trialPrice: '£1.00',
335
+ price: '£20.00',
336
+ value: 'P1M',
337
+ }),
338
+ ];
303
339
  const wrapper = shallow(<PaymentTerm options={options} />);
304
- expect(wrapper.find('.ncf__payment-term__label').text()).toMatch(
305
- /^Trial: Premium Digital - Monthly .*$/
340
+
341
+ expect(wrapper.find('.ncf__payment-term__trial-price').text()).toBe(
342
+ '£1.00'
306
343
  );
307
344
  });
308
- it('renders using displayName if available', () => {
345
+
346
+ it('displays the trial price explanatory text', () => {
309
347
  const options = [
310
- {
311
- ...trialOptions,
312
- displayName: 'someDisplayName',
313
- },
348
+ buildOption({
349
+ isTrial: true,
350
+ displayName: 'Standard Digital',
351
+ trialDuration: '6 weeks',
352
+ trialPrice: '£1.00',
353
+ price: '£20.00',
354
+ value: 'P1M',
355
+ }),
314
356
  ];
315
357
  const wrapper = shallow(<PaymentTerm options={options} />);
316
- expect(wrapper.find('.ncf__payment-term__label').text()).toMatch(
317
- /^Trial: someDisplayName - Monthly .*/
358
+
359
+ expect(
360
+ wrapper.find('.ncf__payment-term__description').text()
361
+ ).toContain(
362
+ 'Unless you cancel during your trial you will be billed £20.00 per month after the trial period.'
318
363
  );
319
364
  });
320
365
  });
321
- });
322
366
 
323
- describe('[data-base-amount]', () => {
324
- it('renders option.amount as data-base-amount if isTrial is false', () => {
325
- const options = [
326
- {
327
- name: 'monthly',
328
- price: '$5.00',
329
- value: 'monthly',
330
- monthlyPrice: '$5.00',
331
- isTrial: false,
332
- amount: 100,
333
- trialAmount: 1,
334
- },
335
- ];
336
- const wrapper = shallow(<PaymentTerm options={options} />);
337
- expect(wrapper.find('input').prop('data-base-amount')).toBe(100);
338
- });
367
+ describe('option.isTrial is false', () => {
368
+ describe('option.value is a valid period', () => {
369
+ describe('option.subscriptionAutoRenewTerm is false, i.e. non-renewing (single-term) subscription', () => {
370
+ it('expresses price as a single payment', () => {
371
+ const options = [
372
+ buildOption({
373
+ isTrial: false,
374
+ subscriptionAutoRenewTerm: false,
375
+ value: 'P8W',
376
+ price: '£19.00',
377
+ amount: '19.00',
378
+ }),
379
+ ];
380
+ const wrapper = shallow(
381
+ <PaymentTerm
382
+ options={options}
383
+ isAutoRenewingSubscriptionTermType={false}
384
+ isNonRenewingSubscriptionTermType={true}
385
+ />
386
+ );
387
+
388
+ expect(
389
+ wrapper.find('.ncf__payment-term__description').text()
390
+ ).toContain('Single £19.00 payment');
391
+ });
392
+
393
+ it('does not describe a renewal period', () => {
394
+ const options = [
395
+ buildOption({
396
+ isTrial: false,
397
+ subscriptionAutoRenewTerm: false,
398
+ value: 'P8W',
399
+ price: '£19.00',
400
+ amount: '19.00',
401
+ }),
402
+ ];
403
+ const wrapper = shallow(
404
+ <PaymentTerm
405
+ options={options}
406
+ isAutoRenewingSubscriptionTermType={false}
407
+ isNonRenewingSubscriptionTermType={true}
408
+ />
409
+ );
410
+
411
+ expect(
412
+ wrapper.find('.ncf__payment-term__renews-text').exists()
413
+ ).toBe(false);
414
+ });
415
+ });
416
+
417
+ describe('option.subscriptionAutoRenewTerm is true, i.e. auto-renewing subscription', () => {
418
+ describe('offer term is 52 weeks or longer', () => {
419
+ it('expresses price as a single payment', () => {
420
+ const options = [
421
+ buildOption({
422
+ name: 'annual',
423
+ value: 'P1Y',
424
+ price: '£120.00',
425
+ amount: '120.00',
426
+ subscriptionAutoRenewTerm: true,
427
+ }),
428
+ ];
429
+ const wrapper = shallow(<PaymentTerm options={options} />);
430
+
431
+ expect(
432
+ wrapper.find('.ncf__payment-term__description').text()
433
+ ).toContain('Single £120.00 payment');
434
+ });
435
+ });
436
+
437
+ describe('offer term is shorter than 52 weeks', () => {
438
+ it('expresses price as a recurring payment', () => {
439
+ const options = [
440
+ buildOption({
441
+ name: 'quarterly',
442
+ value: 'P3M',
443
+ price: '£30.00',
444
+ amount: '30.00',
445
+ subscriptionAutoRenewTerm: true,
446
+ }),
447
+ ];
448
+ const wrapper = shallow(<PaymentTerm options={options} />);
449
+
450
+ expect(
451
+ wrapper.find('.ncf__payment-term__description').text()
452
+ ).toContain('£30.00 per 3 months');
453
+ });
454
+ });
455
+
456
+ it('describes the renewal period', () => {
457
+ const options = [
458
+ buildOption({
459
+ name: 'quarterly',
460
+ value: 'P3M',
461
+ price: '£30.00',
462
+ amount: '30.00',
463
+ subscriptionAutoRenewTerm: true,
464
+ }),
465
+ ];
466
+ const wrapper = shallow(<PaymentTerm options={options} />);
467
+
468
+ expect(
469
+ wrapper.find('.ncf__payment-term__renews-text')
470
+ ).toHaveLength(1);
471
+ expect(wrapper.find('.ncf__payment-term__renews-text').text()).toBe(
472
+ 'Renews every 3 months unless cancelled'
473
+ );
474
+ });
475
+ });
476
+
477
+ describe('offer term is 90 days or longer', () => {
478
+ describe('option.monthlyPrice is provided', () => {
479
+ describe('option.monthlyPrice value is "0"', () => {
480
+ it('displays the equivalent monthly price calculated from the option property values', () => {
481
+ const option = buildOption({
482
+ name: 'annual',
483
+ value: 'P1Y',
484
+ price: '£120.00',
485
+ amount: '120.00',
486
+ symbol: '£',
487
+ monthlyPrice: '0',
488
+ subscriptionAutoRenewTerm: false,
489
+ });
490
+ const wrapper = shallow(
491
+ <PaymentTerm
492
+ options={[option]}
493
+ isAutoRenewingSubscriptionTermType={false}
494
+ isNonRenewingSubscriptionTermType={true}
495
+ />
496
+ );
497
+
498
+ expect(
499
+ wrapper.find('.ncf__payment-term__monthly-price').text()
500
+ ).toBe('£10.00');
501
+ });
502
+ });
503
+
504
+ describe('option.monthlyPrice value can be parsed as a number, e.g. 54.17', () => {
505
+ it('displays the equivalent monthly price constructed from option.symbol and option.monthlyPrice values', () => {
506
+ const option = buildOption({
507
+ name: 'annual',
508
+ value: 'P1Y',
509
+ price: '£650.00',
510
+ amount: '650.00',
511
+ symbol: '£',
512
+ monthlyPrice: '54.17',
513
+ subscriptionAutoRenewTerm: false,
514
+ });
515
+ const wrapper = shallow(
516
+ <PaymentTerm
517
+ options={[option]}
518
+ isAutoRenewingSubscriptionTermType={false}
519
+ isNonRenewingSubscriptionTermType={true}
520
+ />
521
+ );
522
+
523
+ expect(
524
+ wrapper.find('.ncf__payment-term__monthly-price').text()
525
+ ).toBe('£54.17');
526
+ });
527
+ });
528
+
529
+ describe('option.monthlyPrice value cannot be pased as a number, e.g. "£54.17"', () => {
530
+ it('displays the equivalent monthly price derived directly from the option.monthlyPrice value', () => {
531
+ const option = buildOption({
532
+ name: 'annual',
533
+ value: 'P1Y',
534
+ price: '£650.00',
535
+ amount: '650.00',
536
+ symbol: '£',
537
+ monthlyPrice: '£54.17',
538
+ subscriptionAutoRenewTerm: false,
539
+ });
540
+ const wrapper = shallow(
541
+ <PaymentTerm
542
+ options={[option]}
543
+ isAutoRenewingSubscriptionTermType={false}
544
+ isNonRenewingSubscriptionTermType={true}
545
+ />
546
+ );
547
+
548
+ expect(
549
+ wrapper.find('.ncf__payment-term__monthly-price').text()
550
+ ).toBe('£54.17');
551
+ });
552
+ });
553
+ });
554
+
555
+ describe('option.monthlyPrice is not provided', () => {
556
+ it('displays the equivalent monthly price calculated from the option property values', () => {
557
+ const option = buildOption({
558
+ name: 'annual',
559
+ value: 'P1Y',
560
+ price: '£120.00',
561
+ amount: '120.00',
562
+ symbol: '£',
563
+ subscriptionAutoRenewTerm: false,
564
+ monthlyPrice: undefined,
565
+ });
566
+ const wrapper = shallow(
567
+ <PaymentTerm
568
+ options={[option]}
569
+ isAutoRenewingSubscriptionTermType={false}
570
+ isNonRenewingSubscriptionTermType={true}
571
+ />
572
+ );
573
+
574
+ expect(
575
+ wrapper.find('.ncf__payment-term__monthly-price').text()
576
+ ).toBe('£10.00');
577
+ });
578
+ });
579
+ });
580
+
581
+ describe('offer term is shorter than 90 days', () => {
582
+ it('does not display the equivalent monthly price', () => {
583
+ const options = [
584
+ buildOption({
585
+ value: 'P8W',
586
+ price: '£19.00',
587
+ amount: '19.00',
588
+ subscriptionAutoRenewTerm: false,
589
+ }),
590
+ ];
591
+ const wrapper = shallow(
592
+ <PaymentTerm
593
+ options={options}
594
+ isAutoRenewingSubscriptionTermType={false}
595
+ isNonRenewingSubscriptionTermType={true}
596
+ />
597
+ );
598
+
599
+ expect(
600
+ wrapper.find('.ncf__payment-term__equivalent-price').exists()
601
+ ).toBe(false);
602
+ expect(wrapper.text()).not.toContain('That’s equivalent to');
603
+ });
604
+ });
605
+ });
339
606
 
340
- it('renders option.trialAmount as data-base-amount if isTrial is true', () => {
341
- const options = [
342
- {
343
- name: 'monthly',
344
- price: '$5.00',
345
- value: 'monthly',
346
- monthlyPrice: '$5.00',
347
- isTrial: true,
348
- amount: 100,
349
- trialAmount: 1,
350
- },
351
- ];
352
- const wrapper = shallow(<PaymentTerm options={options} />);
353
- expect(wrapper.find('input').prop('data-base-amount')).toBe(1);
607
+ describe('option.value is not a valid period', () => {
608
+ it('renders a component using option custom properties', () => {
609
+ const options = [
610
+ {
611
+ title: 'Annual',
612
+ subTitle: '(Renews annually unless cancelled)',
613
+ price: '€ 270.00',
614
+ value: 270.0,
615
+ isTrial: false,
616
+ discount: '33%',
617
+ bestOffer: true,
618
+ selected: false,
619
+ chargeOnText: 'You will be charged on May 1, 2021',
620
+ },
621
+ ];
622
+ const wrapper = shallow(
623
+ <PaymentTerm
624
+ options={options}
625
+ showLegal={false}
626
+ largePrice={true}
627
+ />
628
+ );
629
+
630
+ expect(wrapper.find('.ncf__payment-term__title').text()).toContain(
631
+ 'Annual'
632
+ );
633
+ expect(wrapper.find('.ncf__payment-term__sub-title').text()).toBe(
634
+ '(Renews annually unless cancelled)'
635
+ );
636
+ expect(wrapper.find('.ncf__payment-term__large-price').text()).toBe(
637
+ '€ 270.00'
638
+ );
639
+ expect(
640
+ wrapper.find('.ncf__payment-term__charge-on-text').text()
641
+ ).toBe('You will be charged on May 1, 2021');
642
+ });
643
+ });
354
644
  });
355
645
  });
356
646
 
357
- describe('When using custom options', () => {
358
- it('renders when not using an option in nameMap but provides a custom props instead', () => {
359
- const props = {
360
- showLegal: false,
361
- largePrice: true,
362
- options: [
363
- {
364
- title: 'Annual',
365
- subTitle: '(Renews annually unless cancelled)',
366
- price: '€ 270.00',
367
- value: 270.0,
368
- isTrial: false,
369
- discount: '33%',
370
- bestOffer: true,
371
- selected: false,
372
- chargeOnText: 'You will be charged on May 1, 2021',
373
- },
374
- {
375
- title: '12 Month Subscription',
376
- price: '€ 300.00',
377
- value: 300.0,
378
- isTrial: false,
379
- discount: '10%',
380
- selected: true,
381
- chargeOnText: 'You will be charged on May 1, 2021',
382
- },
383
- ],
384
- optionsInARow: true,
385
- };
647
+ describe('payment term legal text', () => {
648
+ describe('showLegal is true', () => {
649
+ describe('isAutoRenewingSubscriptionTermType is true; isNonRenewingSubscriptionTermType is false', () => {
650
+ it('displays relevant legal text', () => {
651
+ const wrapper = shallow(
652
+ <PaymentTerm
653
+ options={[buildOption()]}
654
+ showLegal={true}
655
+ isAutoRenewingSubscriptionTermType={true}
656
+ isNonRenewingSubscriptionTermType={false}
657
+ />
658
+ );
659
+
660
+ expect(wrapper.find('.ncf__payment-term__legal').exists()).toBe(true);
661
+ expect(wrapper.find('.ncf__payment-term__legal').text()).toContain(
662
+ 'With all subscription types, we will automatically renew your subscription using the payment method provided unless you cancel before your renewal date.'
663
+ );
664
+ expect(wrapper.find('.ncf__payment-term__legal').text()).toContain(
665
+ 'We will notify you at least 14 days in advance'
666
+ );
667
+ expect(wrapper.find('.ncf__payment-term__legal').text()).toContain(
668
+ 'Terms & Conditions'
669
+ );
670
+ });
671
+ });
386
672
 
387
- expect(PaymentTerm).toRenderCorrectly(props);
673
+ describe('isAutoRenewingSubscriptionTermType is false; isNonRenewingSubscriptionTermType is true', () => {
674
+ it('displays relevant legal text; hides unrelated legal text', () => {
675
+ const wrapper = shallow(
676
+ <PaymentTerm
677
+ options={[buildOption()]}
678
+ showLegal={true}
679
+ isAutoRenewingSubscriptionTermType={false}
680
+ isNonRenewingSubscriptionTermType={true}
681
+ />
682
+ );
683
+
684
+ expect(wrapper.find('.ncf__payment-term__legal').exists()).toBe(true);
685
+ expect(wrapper.find('.ncf__payment-term__legal').text()).toContain(
686
+ 'Find out more about our cancellation policy in our Terms & Conditions.'
687
+ );
688
+ expect(
689
+ wrapper.find('.ncf__payment-term__legal').text()
690
+ ).not.toContain(
691
+ 'With all subscription types, we will automatically renew your subscription'
692
+ );
693
+ expect(
694
+ wrapper.find('.ncf__payment-term__legal').text()
695
+ ).not.toContain('We will notify you at least 14 days in advance');
696
+ });
697
+ });
698
+ });
699
+
700
+ describe('showLegal is false', () => {
701
+ it('hides legal text', () => {
702
+ const wrapper = shallow(
703
+ <PaymentTerm
704
+ options={[buildOption()]}
705
+ showLegal={false}
706
+ isAutoRenewingSubscriptionTermType={true}
707
+ isNonRenewingSubscriptionTermType={false}
708
+ />
709
+ );
710
+
711
+ expect(wrapper.find('.ncf__payment-term__legal').exists()).toBe(false);
712
+ expect(wrapper.text()).not.toContain('Terms & Conditions');
713
+ expect(wrapper.text()).not.toContain('automatically renew');
714
+ });
388
715
  });
389
716
  });
390
717
  });