Skip to content

Commit

Permalink
Merge pull request #771 from Financial-Times/accommodate-termed-subsc…
Browse files Browse the repository at this point in the history
…ription-term-type

Accommodate 'Termed' subscriptionTermType
  • Loading branch information
andygout committed Nov 28, 2023
2 parents dbf4d85 + edad0d4 commit 028fb82
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 5 deletions.
48 changes: 48 additions & 0 deletions components/accept-terms-subscription.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export function AcceptTermsSubscription({
isPrintProduct = false,
isSingleTerm = false,
is7DayPassExperiment = false,
isTermedSubscriptionTermType = false,
isTransition = false,
transitionType = null,
isDeferredBilling = false,
Expand Down Expand Up @@ -88,6 +89,52 @@ export function AcceptTermsSubscription({
);
}

if (isTermedSubscriptionTermType) {
return (
<div {...divProps}>
<ul className="o-typography-list ncf__accept-terms-list">
<li>
<span className="terms-transition terms-transition--immediate">
I give consent for the chosen payment method to be charged automatically.
</span>
</li>
<li>
<span className="terms-transition terms-transition--immediate">
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.
</span>
</li>
<li>
<span className="terms-transition">
Please see here for the complete{' '}
<a
className="ncf__link--external"
href="http://help.ft.com/help/legal-privacy/terms-conditions/"
target="_blank"
rel="noopener noreferrer"
>
Terms &amp; Conditions
</a>
.
</span>
</li>
</ul>
<label className={labelClassName} htmlFor="termsAcceptance">
<input {...inputProps} />
<span className="o-forms-input__label">
I agree to the above terms &amp; conditions.
</span>
<p className="o-forms-input__error">
Please accept our terms &amp; conditions
</p>
</label>
</div>
);
}

const transitionTerms = isTransition && (
<>
{!isSingleTerm && (
Expand Down Expand Up @@ -261,6 +308,7 @@ AcceptTermsSubscription.propTypes = {
isPrintProduct: PropTypes.bool,
isSingleTerm: PropTypes.bool,
is7DayPassExperiment: PropTypes.bool,
isTermedSubscriptionTermType: PropTypes.bool,
isTransition: PropTypes.bool,
transitionType: PropTypes.string,
isDeferredBilling: PropTypes.bool,
Expand Down
22 changes: 22 additions & 0 deletions components/accept-terms-subscription.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,28 @@ describe('AcceptTermsSubscription', () => {
expect(transitionTerms.exists()).toBe(true);
});

it('renders the transition terms when isTermedSubscriptionTermType prop is true', () => {
const props = {
isTermedSubscriptionTermType: true,
};

const component = mount(<AcceptTermsSubscription {...props} />);

const transitionTerms1 = component.find('.terms-transition').at(0);
const transitionTerms2 = component.find('.terms-transition').at(1);
const transitionTerms3 = component.find('.terms-transition').at(2);

expect(transitionTerms1.text()).toEqual(
'I give consent for the chosen payment method to be charged automatically.'
);
expect(transitionTerms2.text()).toEqual(
'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.'
);
expect(transitionTerms3.text()).toEqual(
'Please see here for the complete Terms & Conditions.'
);
});

it('does not render the transition terms when transitionType prop is null', () => {
const props = {
transitionType: null,
Expand Down
8 changes: 8 additions & 0 deletions components/accept-terms-subscription.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ IsSingleTerm.args = {
isSingleTerm: true,
};

export const TermedSubscriptionTermType = (args) => (
<AcceptTermsSubscription {...args} />
);

TermedSubscriptionTermType.args = {
isTermedSubscriptionTermType: true,
};

export const IsTransition = (args) => <AcceptTermsSubscription {...args} />;

IsTransition.args = {
Expand Down
22 changes: 17 additions & 5 deletions components/payment-term.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ export function PaymentTerm({
optionsInARow = false,
billingCountry = '',
is7DayPassExperiment = false,
isTermedSubscriptionTermType = false,
}) {
/**
* Compute monthly price for given term name
* @param {number} amount price in number format
* @param {string} currency country id of the currency
* @param {string} period PxY (yearly) or PxM (montly) where x is the amount of years/months
* @param {string} period (expressed in IS0 8601 duration format): e.g. PxY (yearly) or PxM (montly) where x is the amount of years/months
* @returns {string}
*/
const getMontlyPriceFromPeriod = (amount, currency, period) => {
Expand All @@ -33,13 +34,22 @@ export function PaymentTerm({
/**
* returns period converted to time if found
* otherwise returns empty string to avoid show information not mapped
* @param {string} period PxY (yearly) or PxM (montly) where x is the amount of years/months
* @param {string} period (expressed in IS0 8601 duration format): PxY (yearly), PxM (montly), or PxW, where x is the amount of years/months/weeks
* @returns {string}
*/
const getTimeFromPeriod = (period) => {
const freq =
period.substring(period.length - 1) === 'Y' ? 'years' : 'months';
const periodUnitCodeToWordMap = {
Y: 'years',
M: 'months',
W: 'weeks',
};

const periodUnitCode = period.substring(period.length - 1);

const freq = periodUnitCodeToWordMap[periodUnitCode] || '';

const amount = period.substring(1, period.length - 1);

return period ? `${amount} ${freq}` : '';
};

Expand Down Expand Up @@ -177,6 +187,7 @@ export function PaymentTerm({
</span>
),
renewsText: (renewalPeriod) =>
!isTermedSubscriptionTermType &&
Boolean(renewalPeriod) && (
<p className="ncf__payment-term__renews-text">
Renews every {renewalPeriod} unless cancelled
Expand Down Expand Up @@ -371,7 +382,7 @@ export function PaymentTerm({

{showLegal && (
<div className="ncf__payment-term__legal">
{isFixedTermOffer ? (
{isTermedSubscriptionTermType || isFixedTermOffer ? (
<p>
Find out more about our cancellation policy in our{' '}
<a
Expand Down Expand Up @@ -443,6 +454,7 @@ PaymentTerm.propTypes = {
})
),
isFixedTermOffer: PropTypes.bool,
isTermedSubscriptionTermType: PropTypes.bool,
offerDisplayName: PropTypes.string,
showLegal: PropTypes.bool,
largePrice: PropTypes.bool,
Expand Down
26 changes: 26 additions & 0 deletions components/payment-term.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,32 @@ describe('PaymentTerm', () => {
});
});

describe('given isTermedSubscriptionTermType is true', () => {
const options = [
{
name: '8 weeks',
price: '£19.00',
amount: '19.00',
value: 'P8W',
},
];
const wrapper = shallow(
<PaymentTerm options={options} isTermedSubscriptionTermType={true} />
);

it('renders subscription term as title', () => {
expect(wrapper.find('.ncf__payment-term__title').text()).toMatch(
'8 weeks'
);
});

it('renders description text that reflects that the termed subscription requires a single payment that expresses the per duration cost for shorter durations', () => {
expect(wrapper.find('.ncf__payment-term__description').text()).toContain(
'Single £19.00 paymentThat’s equivalent to GBP9.50 per month'
);
});
});

describe('getDisplayName', () => {
const baseOptions = {
name: 'monthly',
Expand Down
19 changes: 19 additions & 0 deletions components/payment-term.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,25 @@ SevenDayPassExperimentOffer.args = {
offerDisplayName: '7-day pass',
};

export const TermedSubscriptionTermType = (args) => (
<div className="ncf">
<Fieldset>
<PaymentTerm {...args} />
</Fieldset>
</div>
);
TermedSubscriptionTermType.args = {
options: [
{
name: '8 weeks',
price: '£19.00',
amount: '19.00',
value: 'P8W',
},
],
isTermedSubscriptionTermType: true,
};

export const RenewOffers = (args) => (
<div className="ncf">
<Fieldset>
Expand Down

0 comments on commit 028fb82

Please sign in to comment.