@financial-times/n-conversion-forms 32.3.2 → 32.4.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,6 +1,6 @@
1
1
  {
2
2
  "branch": "",
3
3
  "repo": "n-conversion-forms",
4
- "version": "dbf4d85ef93c98eced9c5d9293344ff7542f492d",
5
- "tag": "v32.3.2"
4
+ "version": "028fb82534567b6f0bb602afb409c47306fd4671",
5
+ "tag": "v32.4.0"
6
6
  }
@@ -10,6 +10,7 @@ export function AcceptTermsSubscription({
10
10
  isPrintProduct = false,
11
11
  isSingleTerm = false,
12
12
  is7DayPassExperiment = false,
13
+ isTermedSubscriptionTermType = false,
13
14
  isTransition = false,
14
15
  transitionType = null,
15
16
  isDeferredBilling = false,
@@ -88,6 +89,52 @@ export function AcceptTermsSubscription({
88
89
  );
89
90
  }
90
91
 
92
+ if (isTermedSubscriptionTermType) {
93
+ return (
94
+ <div {...divProps}>
95
+ <ul className="o-typography-list ncf__accept-terms-list">
96
+ <li>
97
+ <span className="terms-transition terms-transition--immediate">
98
+ I give consent for the chosen payment method to be charged automatically.
99
+ </span>
100
+ </li>
101
+ <li>
102
+ <span className="terms-transition terms-transition--immediate">
103
+ By placing your order subject to the Terms & Conditions (save for section 2) referred to
104
+ below, you are waiving your statutory right to cancel our contract within 14 days of
105
+ payment. Your payment is a one-time payment collected at the time of checkout, and
106
+ unsubscribing or cancelling at any point (whether before or after the 14-day period)
107
+ will not entitle you to a refund.
108
+ </span>
109
+ </li>
110
+ <li>
111
+ <span className="terms-transition">
112
+ Please see here for the complete{' '}
113
+ <a
114
+ className="ncf__link--external"
115
+ href="http://help.ft.com/help/legal-privacy/terms-conditions/"
116
+ target="_blank"
117
+ rel="noopener noreferrer"
118
+ >
119
+ Terms &amp; Conditions
120
+ </a>
121
+ .
122
+ </span>
123
+ </li>
124
+ </ul>
125
+ <label className={labelClassName} htmlFor="termsAcceptance">
126
+ <input {...inputProps} />
127
+ <span className="o-forms-input__label">
128
+ I agree to the above terms &amp; conditions.
129
+ </span>
130
+ <p className="o-forms-input__error">
131
+ Please accept our terms &amp; conditions
132
+ </p>
133
+ </label>
134
+ </div>
135
+ );
136
+ }
137
+
91
138
  const transitionTerms = isTransition && (
92
139
  <>
93
140
  {!isSingleTerm && (
@@ -261,6 +308,7 @@ AcceptTermsSubscription.propTypes = {
261
308
  isPrintProduct: PropTypes.bool,
262
309
  isSingleTerm: PropTypes.bool,
263
310
  is7DayPassExperiment: PropTypes.bool,
311
+ isTermedSubscriptionTermType: PropTypes.bool,
264
312
  isTransition: PropTypes.bool,
265
313
  transitionType: PropTypes.string,
266
314
  isDeferredBilling: PropTypes.bool,
@@ -70,6 +70,28 @@ describe('AcceptTermsSubscription', () => {
70
70
  expect(transitionTerms.exists()).toBe(true);
71
71
  });
72
72
 
73
+ it('renders the transition terms when isTermedSubscriptionTermType prop is true', () => {
74
+ const props = {
75
+ isTermedSubscriptionTermType: true,
76
+ };
77
+
78
+ const component = mount(<AcceptTermsSubscription {...props} />);
79
+
80
+ const transitionTerms1 = component.find('.terms-transition').at(0);
81
+ const transitionTerms2 = component.find('.terms-transition').at(1);
82
+ const transitionTerms3 = component.find('.terms-transition').at(2);
83
+
84
+ expect(transitionTerms1.text()).toEqual(
85
+ 'I give consent for the chosen payment method to be charged automatically.'
86
+ );
87
+ expect(transitionTerms2.text()).toEqual(
88
+ 'By placing your order subject to the Terms & Conditions (save for section 2) referred to below, you are waiving your statutory right to cancel our contract within 14 days of payment. Your payment is a one-time payment collected at the time of checkout, and unsubscribing or cancelling at any point (whether before or after the 14-day period) will not entitle you to a refund.'
89
+ );
90
+ expect(transitionTerms3.text()).toEqual(
91
+ 'Please see here for the complete Terms & Conditions.'
92
+ );
93
+ });
94
+
73
95
  it('does not render the transition terms when transitionType prop is null', () => {
74
96
  const props = {
75
97
  transitionType: null,
@@ -30,6 +30,14 @@ IsSingleTerm.args = {
30
30
  isSingleTerm: true,
31
31
  };
32
32
 
33
+ export const TermedSubscriptionTermType = (args) => (
34
+ <AcceptTermsSubscription {...args} />
35
+ );
36
+
37
+ TermedSubscriptionTermType.args = {
38
+ isTermedSubscriptionTermType: true,
39
+ };
40
+
33
41
  export const IsTransition = (args) => <AcceptTermsSubscription {...args} />;
34
42
 
35
43
  IsTransition.args = {
@@ -16,12 +16,13 @@ export function PaymentTerm({
16
16
  optionsInARow = false,
17
17
  billingCountry = '',
18
18
  is7DayPassExperiment = false,
19
+ isTermedSubscriptionTermType = false,
19
20
  }) {
20
21
  /**
21
22
  * Compute monthly price for given term name
22
23
  * @param {number} amount price in number format
23
24
  * @param {string} currency country id of the currency
24
- * @param {string} period PxY (yearly) or PxM (montly) where x is the amount of years/months
25
+ * @param {string} period (expressed in IS0 8601 duration format): e.g. PxY (yearly) or PxM (montly) where x is the amount of years/months
25
26
  * @returns {string}
26
27
  */
27
28
  const getMontlyPriceFromPeriod = (amount, currency, period) => {
@@ -33,13 +34,22 @@ export function PaymentTerm({
33
34
  /**
34
35
  * returns period converted to time if found
35
36
  * otherwise returns empty string to avoid show information not mapped
36
- * @param {string} period PxY (yearly) or PxM (montly) where x is the amount of years/months
37
+ * @param {string} period (expressed in IS0 8601 duration format): PxY (yearly), PxM (montly), or PxW, where x is the amount of years/months/weeks
37
38
  * @returns {string}
38
39
  */
39
40
  const getTimeFromPeriod = (period) => {
40
- const freq =
41
- period.substring(period.length - 1) === 'Y' ? 'years' : 'months';
41
+ const periodUnitCodeToWordMap = {
42
+ Y: 'years',
43
+ M: 'months',
44
+ W: 'weeks',
45
+ };
46
+
47
+ const periodUnitCode = period.substring(period.length - 1);
48
+
49
+ const freq = periodUnitCodeToWordMap[periodUnitCode] || '';
50
+
42
51
  const amount = period.substring(1, period.length - 1);
52
+
43
53
  return period ? `${amount} ${freq}` : '';
44
54
  };
45
55
 
@@ -177,6 +187,7 @@ export function PaymentTerm({
177
187
  </span>
178
188
  ),
179
189
  renewsText: (renewalPeriod) =>
190
+ !isTermedSubscriptionTermType &&
180
191
  Boolean(renewalPeriod) && (
181
192
  <p className="ncf__payment-term__renews-text">
182
193
  Renews every {renewalPeriod} unless cancelled
@@ -371,7 +382,7 @@ export function PaymentTerm({
371
382
 
372
383
  {showLegal && (
373
384
  <div className="ncf__payment-term__legal">
374
- {isFixedTermOffer ? (
385
+ {isTermedSubscriptionTermType || isFixedTermOffer ? (
375
386
  <p>
376
387
  Find out more about our cancellation policy in our{' '}
377
388
  <a
@@ -443,6 +454,7 @@ PaymentTerm.propTypes = {
443
454
  })
444
455
  ),
445
456
  isFixedTermOffer: PropTypes.bool,
457
+ isTermedSubscriptionTermType: PropTypes.bool,
446
458
  offerDisplayName: PropTypes.string,
447
459
  showLegal: PropTypes.bool,
448
460
  largePrice: PropTypes.bool,
@@ -184,6 +184,32 @@ describe('PaymentTerm', () => {
184
184
  });
185
185
  });
186
186
 
187
+ describe('given isTermedSubscriptionTermType is true', () => {
188
+ const options = [
189
+ {
190
+ name: '8 weeks',
191
+ price: '£19.00',
192
+ amount: '19.00',
193
+ value: 'P8W',
194
+ },
195
+ ];
196
+ const wrapper = shallow(
197
+ <PaymentTerm options={options} isTermedSubscriptionTermType={true} />
198
+ );
199
+
200
+ it('renders subscription term as title', () => {
201
+ expect(wrapper.find('.ncf__payment-term__title').text()).toMatch(
202
+ '8 weeks'
203
+ );
204
+ });
205
+
206
+ it('renders description text that reflects that the termed subscription requires a single payment that expresses the per duration cost for shorter durations', () => {
207
+ expect(wrapper.find('.ncf__payment-term__description').text()).toContain(
208
+ 'Single £19.00 paymentThat’s equivalent to GBP9.50 per month'
209
+ );
210
+ });
211
+ });
212
+
187
213
  describe('getDisplayName', () => {
188
214
  const baseOptions = {
189
215
  name: 'monthly',
@@ -129,6 +129,25 @@ SevenDayPassExperimentOffer.args = {
129
129
  offerDisplayName: '7-day pass',
130
130
  };
131
131
 
132
+ export const TermedSubscriptionTermType = (args) => (
133
+ <div className="ncf">
134
+ <Fieldset>
135
+ <PaymentTerm {...args} />
136
+ </Fieldset>
137
+ </div>
138
+ );
139
+ TermedSubscriptionTermType.args = {
140
+ options: [
141
+ {
142
+ name: '8 weeks',
143
+ price: '£19.00',
144
+ amount: '19.00',
145
+ value: 'P8W',
146
+ },
147
+ ],
148
+ isTermedSubscriptionTermType: true,
149
+ };
150
+
132
151
  export const RenewOffers = (args) => (
133
152
  <div className="ncf">
134
153
  <Fieldset>
@@ -26,6 +26,8 @@ function AcceptTermsSubscription(_ref) {
26
26
  isSingleTerm = _ref$isSingleTerm === void 0 ? false : _ref$isSingleTerm,
27
27
  _ref$is7DayPassExperi = _ref.is7DayPassExperiment,
28
28
  is7DayPassExperiment = _ref$is7DayPassExperi === void 0 ? false : _ref$is7DayPassExperi,
29
+ _ref$isTermedSubscrip = _ref.isTermedSubscriptionTermType,
30
+ isTermedSubscriptionTermType = _ref$isTermedSubscrip === void 0 ? false : _ref$isTermedSubscrip,
29
31
  _ref$isTransition = _ref.isTransition,
30
32
  isTransition = _ref$isTransition === void 0 ? false : _ref$isTransition,
31
33
  _ref$transitionType = _ref.transitionType,
@@ -74,6 +76,29 @@ function AcceptTermsSubscription(_ref) {
74
76
  className: "o-forms-input__error"
75
77
  }, "Please accept our terms & conditions")));
76
78
  }
79
+ if (isTermedSubscriptionTermType) {
80
+ return /*#__PURE__*/_react["default"].createElement("div", divProps, /*#__PURE__*/_react["default"].createElement("ul", {
81
+ className: "o-typography-list ncf__accept-terms-list"
82
+ }, /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
83
+ className: "terms-transition terms-transition--immediate"
84
+ }, "I give consent for the chosen payment method to be charged automatically.")), /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
85
+ className: "terms-transition terms-transition--immediate"
86
+ }, "By placing your order subject to the Terms & Conditions (save for section 2) referred to below, you are waiving your statutory right to cancel our contract within 14 days of payment. Your payment is a one-time payment collected at the time of checkout, and unsubscribing or cancelling at any point (whether before or after the 14-day period) will not entitle you to a refund.")), /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
87
+ className: "terms-transition"
88
+ }, "Please see here for the complete", ' ', /*#__PURE__*/_react["default"].createElement("a", {
89
+ className: "ncf__link--external",
90
+ href: "http://help.ft.com/help/legal-privacy/terms-conditions/",
91
+ target: "_blank",
92
+ rel: "noopener noreferrer"
93
+ }, "Terms & Conditions"), "."))), /*#__PURE__*/_react["default"].createElement("label", {
94
+ className: labelClassName,
95
+ htmlFor: "termsAcceptance"
96
+ }, /*#__PURE__*/_react["default"].createElement("input", inputProps), /*#__PURE__*/_react["default"].createElement("span", {
97
+ className: "o-forms-input__label"
98
+ }, "I agree to the above terms & conditions."), /*#__PURE__*/_react["default"].createElement("p", {
99
+ className: "o-forms-input__error"
100
+ }, "Please accept our terms & conditions")));
101
+ }
77
102
  var transitionTerms = isTransition && /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, !isSingleTerm && /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
78
103
  className: "terms-transition"
79
104
  }, "I give consent for my chosen payment method to be charged automatically at the end of each subscription term until I cancel it by contacting", ' ', /*#__PURE__*/_react["default"].createElement("a", {
@@ -144,6 +169,7 @@ AcceptTermsSubscription.propTypes = {
144
169
  isPrintProduct: _propTypes["default"].bool,
145
170
  isSingleTerm: _propTypes["default"].bool,
146
171
  is7DayPassExperiment: _propTypes["default"].bool,
172
+ isTermedSubscriptionTermType: _propTypes["default"].bool,
147
173
  isTransition: _propTypes["default"].bool,
148
174
  transitionType: _propTypes["default"].string,
149
175
  isDeferredBilling: _propTypes["default"].bool
@@ -35,12 +35,14 @@ function PaymentTerm(_ref) {
35
35
  _ref$billingCountry = _ref.billingCountry,
36
36
  billingCountry = _ref$billingCountry === void 0 ? '' : _ref$billingCountry,
37
37
  _ref$is7DayPassExperi = _ref.is7DayPassExperiment,
38
- is7DayPassExperiment = _ref$is7DayPassExperi === void 0 ? false : _ref$is7DayPassExperi;
38
+ is7DayPassExperiment = _ref$is7DayPassExperi === void 0 ? false : _ref$is7DayPassExperi,
39
+ _ref$isTermedSubscrip = _ref.isTermedSubscriptionTermType,
40
+ isTermedSubscriptionTermType = _ref$isTermedSubscrip === void 0 ? false : _ref$isTermedSubscrip;
39
41
  /**
40
42
  * Compute monthly price for given term name
41
43
  * @param {number} amount price in number format
42
44
  * @param {string} currency country id of the currency
43
- * @param {string} period PxY (yearly) or PxM (montly) where x is the amount of years/months
45
+ * @param {string} period (expressed in IS0 8601 duration format): e.g. PxY (yearly) or PxM (montly) where x is the amount of years/months
44
46
  * @returns {string}
45
47
  */
46
48
  var getMontlyPriceFromPeriod = function getMontlyPriceFromPeriod(amount, currency, period) {
@@ -55,11 +57,17 @@ function PaymentTerm(_ref) {
55
57
  /**
56
58
  * returns period converted to time if found
57
59
  * otherwise returns empty string to avoid show information not mapped
58
- * @param {string} period PxY (yearly) or PxM (montly) where x is the amount of years/months
60
+ * @param {string} period (expressed in IS0 8601 duration format): PxY (yearly), PxM (montly), or PxW, where x is the amount of years/months/weeks
59
61
  * @returns {string}
60
62
  */
61
63
  var getTimeFromPeriod = function getTimeFromPeriod(period) {
62
- var freq = period.substring(period.length - 1) === 'Y' ? 'years' : 'months';
64
+ var periodUnitCodeToWordMap = {
65
+ Y: 'years',
66
+ M: 'months',
67
+ W: 'weeks'
68
+ };
69
+ var periodUnitCode = period.substring(period.length - 1);
70
+ var freq = periodUnitCodeToWordMap[periodUnitCode] || '';
63
71
  var amount = period.substring(1, period.length - 1);
64
72
  return period ? "".concat(amount, " ").concat(freq) : '';
65
73
  };
@@ -171,7 +179,7 @@ function PaymentTerm(_ref) {
171
179
  }, _monthlyPrice), ' ', "per month");
172
180
  },
173
181
  renewsText: function renewsText(renewalPeriod) {
174
- return Boolean(renewalPeriod) && /*#__PURE__*/_react["default"].createElement("p", {
182
+ return !isTermedSubscriptionTermType && Boolean(renewalPeriod) && /*#__PURE__*/_react["default"].createElement("p", {
175
183
  className: "ncf__payment-term__renews-text"
176
184
  }, "Renews every ", renewalPeriod, " unless cancelled");
177
185
  }
@@ -276,7 +284,7 @@ function PaymentTerm(_ref) {
276
284
  return createPaymentTerm(option);
277
285
  })), showLegal && /*#__PURE__*/_react["default"].createElement("div", {
278
286
  className: "ncf__payment-term__legal"
279
- }, isFixedTermOffer ? /*#__PURE__*/_react["default"].createElement("p", null, "Find out more about our cancellation policy in our", ' ', /*#__PURE__*/_react["default"].createElement("a", {
287
+ }, isTermedSubscriptionTermType || isFixedTermOffer ? /*#__PURE__*/_react["default"].createElement("p", null, "Find out more about our cancellation policy in our", ' ', /*#__PURE__*/_react["default"].createElement("a", {
280
288
  className: "ncf__link--external",
281
289
  href: "https://help.ft.com/legal-privacy/terms-and-conditions/",
282
290
  title: "FT Legal Terms and Conditions help page",
@@ -316,6 +324,7 @@ PaymentTerm.propTypes = {
316
324
  fulfilmentOption: _propTypes["default"].string
317
325
  })),
318
326
  isFixedTermOffer: _propTypes["default"].bool,
327
+ isTermedSubscriptionTermType: _propTypes["default"].bool,
319
328
  offerDisplayName: _propTypes["default"].string,
320
329
  showLegal: _propTypes["default"].bool,
321
330
  largePrice: _propTypes["default"].bool,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/n-conversion-forms",
3
- "version": "32.3.2",
3
+ "version": "32.4.0",
4
4
  "description": "Containing jsx components and styles for forms included on Accounts and Acqusition apps (next-signup, next-profile, next-retention, etc).",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {