@financial-times/n-conversion-forms 47.0.0 → 47.0.1

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,7 +1,7 @@
1
1
  {
2
2
  "branch": "",
3
3
  "repo": "n-conversion-forms",
4
- "version": "ee708c8d31911082aac962b8e0037926452196db",
5
- "tag": "v47.0.0",
6
- "buildNumber": "18511"
4
+ "version": "bf70543a972ad200ea2b1ef7555c5d7cf4e20be1",
5
+ "tag": "v47.0.1",
6
+ "buildNumber": "18612"
7
7
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  ".toolkitrc.yml": "XiiIocllEaT8xqKRCTpTbJ+yUyduDo5aEHARUQ3vJFfSe187Ci13PEs3bWL272GFJyNz2QgRQhdov2/+LFRKuw==",
3
- "package.json": "HfYBmW7sG27rD0HALPkm72vLS98cpd689DW7To1i07hwUJdC4BeaTLkXyAAYyN8UHuE4xJpf/TujsKcDYZ+1yw==",
3
+ "package.json": "QBfshsb3yvKX/+ogZ5/b81C1BfSdRcV5RZAv599ZTmGXV2w3Lt5k4FQOPWk//m1p3+B1FjXnfdsXISbJ42rlQA==",
4
4
  ".circleci/config.yml": "eph42EF3EsL7jvhiiC7D7vG3vGBAGBFVC+Ncmy4Dj4rUNzK8Rls0/cr+bEF/ttMN3J6iSL1xtCXKIJVrtZ4OSQ=="
5
5
  }
@@ -34,12 +34,12 @@ Basic.args = {
34
34
  ],
35
35
  };
36
36
 
37
- export const UKPaperVoucherAutoReniewingDeliveryOptions = (args) => (
37
+ export const UKPaperVoucherAutoRenewingDeliveryOptions = (args) => (
38
38
  <div className="ncf">
39
39
  <DeliveryOption {...args} />
40
40
  </div>
41
41
  );
42
- UKPaperVoucherAutoReniewingDeliveryOptions.args = {
42
+ UKPaperVoucherAutoRenewingDeliveryOptions.args = {
43
43
  country: 'GBR',
44
44
  options: [
45
45
  {
@@ -1,13 +1,9 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import classNames from 'classnames';
4
- import { Period, Monthly } from '@financial-times/n-pricing';
4
+ import { Period, Price } from '@financial-times/n-pricing';
5
5
 
6
- import {
7
- getDurationFromISO8601Value,
8
- is52WeeksOrLonger,
9
- is90DaysOrLonger,
10
- } from '../helpers';
6
+ import { getDurationFromISO8601Value, is52WeeksOrLonger } from '../helpers';
11
7
 
12
8
  export function PaymentTerm({
13
9
  fieldId = 'paymentTermField',
@@ -90,16 +86,20 @@ export function PaymentTerm({
90
86
  };
91
87
 
92
88
  /**
93
- * Compute monthly price for given term name.
94
- * @returns {string}
89
+ * Compute monthly price for given term name, if the term if 90 days or longer.
90
+ * @returns {string | undefined}
95
91
  */
96
- const getMonthlyPriceFromPeriod = () => {
97
- const periodObj = new Period(option.value);
98
- const monthlyPrice = periodObj.calculatePrice('P1M', option.amount);
99
- return new Monthly({
100
- value: monthlyPrice,
101
- symbol: option.symbol,
102
- }).getAmount('monthly');
92
+ const getCalculatedMonthlyPriceIfEligible = () => {
93
+ const priceObject = new Price(
94
+ {
95
+ value: option.amount,
96
+ symbol: option.symbol,
97
+ },
98
+ {
99
+ period: option.value,
100
+ }
101
+ );
102
+ return priceObject.getMonthlyEquivalentIf90DaysOrLonger()?.amount.value;
103
103
  };
104
104
 
105
105
  /**
@@ -158,7 +158,7 @@ export function PaymentTerm({
158
158
  };
159
159
 
160
160
  /**
161
- * Returns elements that include the text describing how regularly an auto-reniewing subscription will renew.
161
+ * Returns elements that include the text describing how regularly an auto-renewing subscription will renew.
162
162
  * @returns {React.ReactElement}
163
163
  */
164
164
  const getRenewalPeriodText = () => {
@@ -173,28 +173,46 @@ export function PaymentTerm({
173
173
 
174
174
  /**
175
175
  * Returns elements that include the text describing the monthly equivalent of the subscription.
176
- * @returns {string}
176
+ * Returns null if the term is shorter than 90 days
177
+ * @returns {string | null}
177
178
  */
178
179
  const getEquivalentMonthlyPrice = () => {
179
- if (Boolean(option.monthlyPrice) && option.monthlyPrice !== '0') {
180
+ const calculatedMonthlyPrice = getCalculatedMonthlyPriceIfEligible();
181
+
182
+ if (!calculatedMonthlyPrice) {
183
+ return null;
184
+ }
185
+
186
+ const hasValidMonthlyPrice =
187
+ option.monthlyPrice !== null &&
188
+ option.monthlyPrice !== undefined &&
189
+ option.monthlyPrice !== '' &&
190
+ option.monthlyPrice !== '0';
191
+
192
+ if (hasValidMonthlyPrice) {
180
193
  return isNaN(option.monthlyPrice)
181
194
  ? option.monthlyPrice
182
195
  : `${option.symbol}${option.monthlyPrice}`;
183
196
  }
184
197
 
185
- return getMonthlyPriceFromPeriod();
198
+ return calculatedMonthlyPrice;
186
199
  };
187
200
 
188
201
  /**
189
- * Returns elements that include the text describing the monthly equivalent of the subscription.
190
- * @returns {React.ReactElement}
202
+ * Returns elements that include the text describing the monthly equivalent of the subscription, if available.
203
+ * @returns {React.ReactElement | null}
191
204
  */
192
205
  const getEquivalentMonthlyPriceText = () => {
206
+ const equivalentMonthlyPrice = getEquivalentMonthlyPrice();
207
+
208
+ if (!equivalentMonthlyPrice) {
209
+ return null;
210
+ }
193
211
  return (
194
212
  <span className="ncf__payment-term__equivalent-price">
195
213
  That’s equivalent to{' '}
196
214
  <span className="ncf__payment-term__monthly-price">
197
- {getEquivalentMonthlyPrice()}
215
+ {equivalentMonthlyPrice}
198
216
  </span>{' '}
199
217
  per month
200
218
  </span>
@@ -261,9 +279,7 @@ export function PaymentTerm({
261
279
  return (
262
280
  <div className="ncf__payment-term__description">
263
281
  {getPriceText()}
264
-
265
- {is90DaysOrLonger(option.value) && getEquivalentMonthlyPriceText()}
266
-
282
+ {getEquivalentMonthlyPriceText()}
267
283
  {option.subscriptionAutoRenewTerm && getRenewalPeriodText()}
268
284
  </div>
269
285
  );
@@ -8,6 +8,20 @@ import { expectToRenderCorrectly } from '../test-jest/helpers/expect-to-render-c
8
8
  expect.extend(expectToRenderCorrectly);
9
9
  Enzyme.configure({ adapter: new Adapter() });
10
10
 
11
+ const mockGetMonthlyEquivalentIf90DaysOrLonger = jest.fn();
12
+
13
+ jest.mock('@financial-times/n-pricing', () => {
14
+ const actual = jest.requireActual('@financial-times/n-pricing');
15
+
16
+ return {
17
+ ...actual,
18
+ Price: jest.fn().mockImplementation(() => ({
19
+ getMonthlyEquivalentIf90DaysOrLonger:
20
+ mockGetMonthlyEquivalentIf90DaysOrLonger,
21
+ })),
22
+ };
23
+ });
24
+
11
25
  const buildOption = (overrides = {}) => ({
12
26
  name: 'monthly',
13
27
  price: '£20.00',
@@ -21,6 +35,10 @@ const buildOption = (overrides = {}) => ({
21
35
  });
22
36
 
23
37
  describe('PaymentTerm', () => {
38
+ beforeEach(() => {
39
+ mockGetMonthlyEquivalentIf90DaysOrLonger.mockReset();
40
+ });
41
+
24
42
  describe('default props are used', () => {
25
43
  it('renders correctly', () => {
26
44
  const props = {};
@@ -478,6 +496,9 @@ describe('PaymentTerm', () => {
478
496
  describe('option.monthlyPrice is provided', () => {
479
497
  describe('option.monthlyPrice value is "0"', () => {
480
498
  it('displays the equivalent monthly price calculated from the option property values', () => {
499
+ mockGetMonthlyEquivalentIf90DaysOrLonger.mockReturnValue({
500
+ amount: { value: '£10.00' },
501
+ });
481
502
  const option = buildOption({
482
503
  name: 'annual',
483
504
  value: 'P1Y',
@@ -503,6 +524,9 @@ describe('PaymentTerm', () => {
503
524
 
504
525
  describe('option.monthlyPrice value can be parsed as a number, e.g. 54.17', () => {
505
526
  it('displays the equivalent monthly price constructed from option.symbol and option.monthlyPrice values', () => {
527
+ mockGetMonthlyEquivalentIf90DaysOrLonger.mockReturnValue({
528
+ amount: { value: '£99.99' }, // This value should be ignored in favour of the option.monthlyPrice value
529
+ });
506
530
  const option = buildOption({
507
531
  name: 'annual',
508
532
  value: 'P1Y',
@@ -526,8 +550,11 @@ describe('PaymentTerm', () => {
526
550
  });
527
551
  });
528
552
 
529
- describe('option.monthlyPrice value cannot be pased as a number, e.g. "£54.17"', () => {
553
+ describe('option.monthlyPrice value cannot be parsed as a number, e.g. "£54.17"', () => {
530
554
  it('displays the equivalent monthly price derived directly from the option.monthlyPrice value', () => {
555
+ mockGetMonthlyEquivalentIf90DaysOrLonger.mockReturnValue({
556
+ amount: { value: '£99.99' }, // This value should be ignored in favour of the option.monthlyPrice value
557
+ });
531
558
  const option = buildOption({
532
559
  name: 'annual',
533
560
  value: 'P1Y',
@@ -554,6 +581,9 @@ describe('PaymentTerm', () => {
554
581
 
555
582
  describe('option.monthlyPrice is not provided', () => {
556
583
  it('displays the equivalent monthly price calculated from the option property values', () => {
584
+ mockGetMonthlyEquivalentIf90DaysOrLonger.mockReturnValue({
585
+ amount: { value: '£10.00' },
586
+ });
557
587
  const option = buildOption({
558
588
  name: 'annual',
559
589
  value: 'P1Y',
@@ -580,6 +610,7 @@ describe('PaymentTerm', () => {
580
610
 
581
611
  describe('offer term is shorter than 90 days', () => {
582
612
  it('does not display the equivalent monthly price', () => {
613
+ mockGetMonthlyEquivalentIf90DaysOrLonger.mockReturnValue(undefined);
583
614
  const options = [
584
615
  buildOption({
585
616
  value: 'P8W',
@@ -103,16 +103,18 @@ function PaymentTerm(_ref) {
103
103
  };
104
104
 
105
105
  /**
106
- * Compute monthly price for given term name.
107
- * @returns {string}
106
+ * Compute monthly price for given term name, if the term if 90 days or longer.
107
+ * @returns {string | undefined}
108
108
  */
109
- var getMonthlyPriceFromPeriod = function getMonthlyPriceFromPeriod() {
110
- var periodObj = new _nPricing.Period(option.value);
111
- var monthlyPrice = periodObj.calculatePrice('P1M', option.amount);
112
- return new _nPricing.Monthly({
113
- value: monthlyPrice,
109
+ var getCalculatedMonthlyPriceIfEligible = function getCalculatedMonthlyPriceIfEligible() {
110
+ var _priceObject$getMonth;
111
+ var priceObject = new _nPricing.Price({
112
+ value: option.amount,
114
113
  symbol: option.symbol
115
- }).getAmount('monthly');
114
+ }, {
115
+ period: option.value
116
+ });
117
+ return (_priceObject$getMonth = priceObject.getMonthlyEquivalentIf90DaysOrLonger()) === null || _priceObject$getMonth === void 0 ? void 0 : _priceObject$getMonth.amount.value;
116
118
  };
117
119
 
118
120
  /**
@@ -155,7 +157,7 @@ function PaymentTerm(_ref) {
155
157
  };
156
158
 
157
159
  /**
158
- * Returns elements that include the text describing how regularly an auto-reniewing subscription will renew.
160
+ * Returns elements that include the text describing how regularly an auto-renewing subscription will renew.
159
161
  * @returns {React.ReactElement}
160
162
  */
161
163
  var getRenewalPeriodText = function getRenewalPeriodText() {
@@ -168,25 +170,35 @@ function PaymentTerm(_ref) {
168
170
 
169
171
  /**
170
172
  * Returns elements that include the text describing the monthly equivalent of the subscription.
171
- * @returns {string}
173
+ * Returns null if the term is shorter than 90 days
174
+ * @returns {string | null}
172
175
  */
173
176
  var getEquivalentMonthlyPrice = function getEquivalentMonthlyPrice() {
174
- if (Boolean(option.monthlyPrice) && option.monthlyPrice !== '0') {
177
+ var calculatedMonthlyPrice = getCalculatedMonthlyPriceIfEligible();
178
+ if (!calculatedMonthlyPrice) {
179
+ return null;
180
+ }
181
+ var hasValidMonthlyPrice = option.monthlyPrice !== null && option.monthlyPrice !== undefined && option.monthlyPrice !== '' && option.monthlyPrice !== '0';
182
+ if (hasValidMonthlyPrice) {
175
183
  return isNaN(option.monthlyPrice) ? option.monthlyPrice : "".concat(option.symbol).concat(option.monthlyPrice);
176
184
  }
177
- return getMonthlyPriceFromPeriod();
185
+ return calculatedMonthlyPrice;
178
186
  };
179
187
 
180
188
  /**
181
- * Returns elements that include the text describing the monthly equivalent of the subscription.
182
- * @returns {React.ReactElement}
189
+ * Returns elements that include the text describing the monthly equivalent of the subscription, if available.
190
+ * @returns {React.ReactElement | null}
183
191
  */
184
192
  var getEquivalentMonthlyPriceText = function getEquivalentMonthlyPriceText() {
193
+ var equivalentMonthlyPrice = getEquivalentMonthlyPrice();
194
+ if (!equivalentMonthlyPrice) {
195
+ return null;
196
+ }
185
197
  return /*#__PURE__*/_react["default"].createElement("span", {
186
198
  className: "ncf__payment-term__equivalent-price"
187
199
  }, "That\u2019s equivalent to", ' ', /*#__PURE__*/_react["default"].createElement("span", {
188
200
  className: "ncf__payment-term__monthly-price"
189
- }, getEquivalentMonthlyPrice()), ' ', "per month");
201
+ }, equivalentMonthlyPrice), ' ', "per month");
190
202
  };
191
203
 
192
204
  /**
@@ -230,7 +242,7 @@ function PaymentTerm(_ref) {
230
242
  if (isValidPeriod(option.value)) {
231
243
  return /*#__PURE__*/_react["default"].createElement("div", {
232
244
  className: "ncf__payment-term__description"
233
- }, getPriceText(), (0, _helpers.is90DaysOrLonger)(option.value) && getEquivalentMonthlyPriceText(), option.subscriptionAutoRenewTerm && getRenewalPeriodText());
245
+ }, getPriceText(), getEquivalentMonthlyPriceText(), option.subscriptionAutoRenewTerm && getRenewalPeriodText());
234
246
  }
235
247
  return /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("span", {
236
248
  className: largePrice ? 'ncf__payment-term__large-price' : ''
@@ -45,7 +45,6 @@ const DAYS_IN_A_YEAR = 365; // Disregarding leap years
45
45
  const DAYS_IN_A_MONTH = 30; // Approximate
46
46
  const DAYS_IN_A_WEEK = 7;
47
47
 
48
- const DAYS_IN_90_DAYS = 90;
49
48
  const DAYS_IN_52_WEEKS = 52 * DAYS_IN_A_WEEK;
50
49
 
51
50
  /**
@@ -85,20 +84,7 @@ const is52WeeksOrLonger = (iso8601Duration) => {
85
84
  return totalDays >= DAYS_IN_52_WEEKS;
86
85
  };
87
86
 
88
- /**
89
- * Approximate check of whether an ISO 8601 duration is 90 days or longer.
90
- * @param {string} iso8601Duration
91
- * @returns {boolean}
92
- */
93
- const is90DaysOrLonger = (iso8601Duration) => {
94
- const totalDays = parseISODurationToDays(iso8601Duration);
95
- if (totalDays === null) return false;
96
-
97
- return totalDays >= DAYS_IN_90_DAYS;
98
- };
99
-
100
87
  module.exports = {
101
88
  getDurationFromISO8601Value,
102
89
  is52WeeksOrLonger,
103
- is90DaysOrLonger,
104
90
  };
@@ -1,7 +1,6 @@
1
1
  const {
2
2
  getDurationFromISO8601Value,
3
3
  is52WeeksOrLonger,
4
- is90DaysOrLonger,
5
4
  } = require('./duration-helpers');
6
5
 
7
6
  describe('Duration Utils', () => {
@@ -140,36 +139,4 @@ describe('Duration Utils', () => {
140
139
  });
141
140
  });
142
141
  });
143
-
144
- describe('is90DaysOrLonger', () => {
145
- describe('returns true for durations >= 90 days', () => {
146
- const DURATIONS_OF_90_DAYS_OR_MORE = [
147
- 'P3Y',
148
- 'P26M',
149
- 'P2Y',
150
- 'P13M',
151
- 'P1Y',
152
- 'P52W',
153
- 'P6M',
154
- 'P13W',
155
- 'P3M',
156
- ];
157
-
158
- DURATIONS_OF_90_DAYS_OR_MORE.forEach((duration) => {
159
- it(`returns true for ${duration}`, () => {
160
- expect(is90DaysOrLonger(duration)).toBe(true);
161
- });
162
- });
163
- });
164
-
165
- describe('returns false for durations < 90 days', () => {
166
- const DURATIONS_OF_LESS_THAN_90_DAYS = ['P8W', 'P1M'];
167
-
168
- DURATIONS_OF_LESS_THAN_90_DAYS.forEach((duration) => {
169
- it(`returns false for ${duration}`, () => {
170
- expect(is90DaysOrLonger(duration)).toBe(false);
171
- });
172
- });
173
- });
174
- });
175
142
  });
package/helpers/index.js CHANGED
@@ -17,5 +17,4 @@ module.exports = {
17
17
  getDurationFromISO8601Value:
18
18
  require('./duration-helpers').getDurationFromISO8601Value,
19
19
  is52WeeksOrLonger: require('./duration-helpers').is52WeeksOrLonger,
20
- is90DaysOrLonger: require('./duration-helpers').is90DaysOrLonger,
21
20
  };
@@ -53,8 +53,4 @@ describe('helpers', () => {
53
53
  it('export is52WeeksOrLonger', () => {
54
54
  expect(helpers).toHaveProperty('is52WeeksOrLonger');
55
55
  });
56
-
57
- it('export is90DaysOrLonger', () => {
58
- expect(helpers).toHaveProperty('is90DaysOrLonger');
59
- });
60
56
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/n-conversion-forms",
3
- "version": "47.0.0",
3
+ "version": "47.0.1",
4
4
  "description": "Containing jsx components and styles for forms included on Accounts and Acquisition apps (next-signup, next-profile, next-retention, etc).",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -25,7 +25,7 @@
25
25
  "homepage": "https://github.com/Financial-Times/n-conversion-forms#readme",
26
26
  "dependencies": {
27
27
  "@babel/runtime": "^7.23.9",
28
- "@financial-times/n-pricing": "8.0.0",
28
+ "@financial-times/n-pricing": "8.1.1",
29
29
  "classnames": "2.5.1",
30
30
  "fetchres": "1.7.2",
31
31
  "lodash.get": "4.4.2",
@@ -61,10 +61,6 @@
61
61
  margin-bottom: var(--o3-spacing-3xs);
62
62
  width: 100%;
63
63
 
64
- &:last-child {
65
- margin-bottom: 0;
66
- }
67
-
68
64
  label {
69
65
  float: none;
70
66
  width: 100%;