@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.
- package/.toolkitstate/ci.json +3 -3
- package/components/__snapshots__/payment-term.spec.js.snap +1 -1031
- package/components/payment-term.jsx +232 -207
- package/components/payment-term.spec.js +646 -319
- package/components/payment-term.stories.js +135 -24
- package/dist/payment-term.jsx +186 -145
- package/helpers/duration-helpers.js +104 -0
- package/helpers/duration-helpers.spec.js +175 -0
- package/helpers/index.js +4 -0
- package/helpers/index.spec.js +12 -0
- package/package.json +1 -1
- package/styles/payment-term.scss +5 -5
- package/styles/payment-type.scss +11 -2
|
@@ -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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
describe('PaymentTerm', () => {
|
|
24
|
+
describe('default props are used', () => {
|
|
25
|
+
it('renders correctly', () => {
|
|
26
|
+
const props = {};
|
|
21
27
|
|
|
22
|
-
|
|
28
|
+
expect(PaymentTerm).toRenderCorrectly(props);
|
|
29
|
+
});
|
|
23
30
|
});
|
|
24
31
|
|
|
25
|
-
|
|
26
|
-
describe(
|
|
27
|
-
it('
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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(
|
|
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
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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(
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
-
|
|
104
|
-
|
|
105
|
-
options
|
|
106
|
-
{
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
(
|
|
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
|
-
|
|
164
|
-
|
|
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('
|
|
189
|
-
describe('
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
-
|
|
172
|
+
/^Trial: /
|
|
208
173
|
);
|
|
209
174
|
});
|
|
210
175
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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('
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
<PaymentTerm
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
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
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
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('
|
|
252
|
-
|
|
253
|
-
{
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
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('
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
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
|
-
|
|
292
|
-
|
|
293
|
-
|
|
322
|
+
|
|
323
|
+
expect(
|
|
324
|
+
wrapper.find('.ncf__payment-term__description').text()
|
|
325
|
+
).toContain('6 weeks');
|
|
294
326
|
});
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
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
|
-
|
|
305
|
-
|
|
340
|
+
|
|
341
|
+
expect(wrapper.find('.ncf__payment-term__trial-price').text()).toBe(
|
|
342
|
+
'£1.00'
|
|
306
343
|
);
|
|
307
344
|
});
|
|
308
|
-
|
|
345
|
+
|
|
346
|
+
it('displays the trial price explanatory text', () => {
|
|
309
347
|
const options = [
|
|
310
|
-
{
|
|
311
|
-
|
|
312
|
-
displayName: '
|
|
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
|
-
|
|
317
|
-
|
|
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
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
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
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
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('
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
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
|
-
|
|
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
|
});
|