@financial-times/n-conversion-forms
Version:
Containing jsx components and styles for forms included on Accounts and Acquisition apps (next-signup, next-profile, next-retention, etc).
718 lines (652 loc) • 20.7 kB
JavaScript
import React from 'react';
import Enzyme, { shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { PaymentTerm } from './index';
import { expectToRenderCorrectly } from '../test-jest/helpers/expect-to-render-correctly';
expect.extend(expectToRenderCorrectly);
Enzyme.configure({ adapter: new Adapter() });
const buildOption = (overrides = {}) => ({
name: 'monthly',
price: '£20.00',
value: 'P1M',
amount: '20.00',
symbol: '£',
isTrial: false,
selected: false,
subscriptionAutoRenewTerm: true,
...overrides,
});
describe('PaymentTerm', () => {
describe('default props are used', () => {
it('renders correctly', () => {
const props = {};
expect(PaymentTerm).toRenderCorrectly(props);
});
});
describe('payment term input props', () => {
describe('option.isTrial is false', () => {
it('renders option.trialAmount as data-base-amount', () => {
const options = [
{
name: 'monthly',
price: '$5.00',
value: 'monthly',
monthlyPrice: '$5.00',
isTrial: false,
amount: 100,
trialAmount: 1,
},
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(wrapper.find('input').prop('data-base-amount')).toBe(100);
});
});
describe('option.isTrial is true', () => {
it('renders option.trialAmount as data-base-amount', () => {
const options = [
{
name: 'monthly',
price: '$5.00',
value: 'monthly',
monthlyPrice: '$5.00',
isTrial: true,
amount: 100,
trialAmount: 1,
},
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(wrapper.find('input').prop('data-base-amount')).toBe(1);
});
});
describe('option.selected is true', () => {
it('renders the option as selected', () => {
const options = [
buildOption({
selected: true,
}),
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(wrapper.find('input')).toHaveLength(1);
expect(wrapper.find('input').prop('defaultChecked')).toBe(true);
expect(wrapper.find('input').prop('id')).toBe('P1M');
expect(wrapper.find('label').prop('htmlFor')).toBe('P1M');
});
});
describe('option.selected is false', () => {
it('does not render the option as selected', () => {
const options = [
buildOption({
selected: false,
}),
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(wrapper.find('input')).toHaveLength(1);
expect(wrapper.find('input').prop('defaultChecked')).toBeUndefined();
expect(wrapper.find('input').prop('id')).toBe('P1M');
expect(wrapper.find('label').prop('htmlFor')).toBe('P1M');
});
});
});
describe('payment term option discount', () => {
describe('option.discount is true', () => {
describe('option.bestOffer is true', () => {
it('displays "Best offer"', () => {
const options = [
buildOption({
discount: '25%',
bestOffer: true,
}),
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(wrapper.find('.ncf__payment-term__discount')).toHaveLength(1);
expect(wrapper.find('.ncf__payment-term__discount').text()).toBe(
'Best offer'
);
});
});
describe('option.bestOffer is false', () => {
it('displays, e.g. "Save 25% off RRP" where the percentage is defined by the offer.discount value', () => {
const options = [
buildOption({
discount: '25%',
bestOffer: false,
}),
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(wrapper.find('.ncf__payment-term__discount')).toHaveLength(1);
expect(wrapper.find('.ncf__payment-term__discount').text()).toBe(
'Save 25% off RRP'
);
});
});
});
describe('option.discount is false', () => {
it('does not display any discount-related text', () => {
const options = [
buildOption({
discount: '',
}),
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(wrapper.find('.ncf__payment-term__discount').exists()).toBe(
false
);
expect(wrapper.text()).not.toContain('Best offer');
expect(wrapper.text()).not.toContain('off RRP');
});
});
});
describe('payment term option display name', () => {
describe('option.isTrial is true (and isPrintOrBundle and isDigitalEdition are both false)', () => {
it('prefixes the payment term option display name with "Trial: "', () => {
const options = [
buildOption({
name: 'annual',
value: 'P1Y',
isTrial: true,
trialDuration: '4 weeks',
trialPrice: '£1.00',
}),
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(wrapper.find('.ncf__payment-term__title').text()).toMatch(
/^Trial: /
);
});
describe('custom option.displayName is provided', () => {
it('uses the custom option.displayName as the term display name', () => {
const options = [
buildOption({
name: 'annual',
value: 'P1Y',
isTrial: true,
displayName: 'Standard Digital Plus',
trialDuration: '4 weeks',
trialPrice: '£1.00',
}),
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(wrapper.find('.ncf__payment-term__title').text()).toContain(
'Trial: Standard Digital Plus - Annual'
);
});
});
describe('custom option.displayName is not provided', () => {
it('defaults to "Premium Digital"', () => {
const options = [
buildOption({
name: 'annual',
value: 'P1Y',
isTrial: true,
trialDuration: '4 weeks',
trialPrice: '£1.00',
}),
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(wrapper.find('.ncf__payment-term__title').text()).toContain(
'Trial: Premium Digital - Annual'
);
});
});
});
describe('option.isTrial is false', () => {
it('does not prefix the payment term option display name with "Trial: "', () => {
const options = [
buildOption({
name: 'annual',
value: 'P1Y',
isTrial: false,
}),
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(wrapper.find('.ncf__payment-term__title').text()).not.toContain(
'Trial: '
);
});
});
describe('option.subscriptionAutoRenewTerm is true, i.e. auto-renewing subscription, and option.name is present', () => {
it('expresses the term period by using the capitalised option.name value', () => {
const options = [
buildOption({
name: 'annual',
subscriptionAutoRenewTerm: true,
}),
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(wrapper.find('.ncf__payment-term__title').text()).toContain(
'Annual'
);
});
});
describe('option.subscriptionAutoRenewTerm is false, i.e. non-renewing (single-term) subscription', () => {
describe('option.value is a valid period', () => {
it('expresses the term period as a human-readable duration derived from the option.value value', () => {
const options = [
buildOption({
displayName: 'Standard Digital',
isTrial: true,
subscriptionAutoRenewTerm: false,
value: 'P8W',
price: '£19.00',
amount: '19.00',
trialDuration: '4 weeks',
trialPrice: '£1.00',
}),
];
const wrapper = shallow(
<PaymentTerm
options={options}
isAutoRenewingSubscriptionTermType={false}
isNonRenewingSubscriptionTermType={true}
/>
);
expect(wrapper.find('.ncf__payment-term__title').text()).toContain(
'Trial: Standard Digital - 8 weeks'
);
});
});
describe('option.value is a not valid period', () => {
it('uses the option.title value', () => {
const options = [
buildOption({
displayName: 'Standard Digital',
isTrial: true,
subscriptionAutoRenewTerm: false,
value: 'custom-term',
title: '12 Month Subscription',
price: '£100.00',
trialDuration: '4 weeks',
trialPrice: '£1.00',
}),
];
const wrapper = shallow(
<PaymentTerm
options={options}
isAutoRenewingSubscriptionTermType={false}
isNonRenewingSubscriptionTermType={true}
/>
);
expect(wrapper.find('.ncf__payment-term__title').text()).toContain(
'Trial: Standard Digital - 12 Month Subscription'
);
});
});
});
});
describe('payment term option description', () => {
describe('option.isTrial is true', () => {
it('displays the trial duration', () => {
const options = [
buildOption({
isTrial: true,
displayName: 'Standard Digital',
trialDuration: '6 weeks',
trialPrice: '£1.00',
price: '£20.00',
value: 'P1M',
}),
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(
wrapper.find('.ncf__payment-term__description').text()
).toContain('6 weeks');
});
it('displays the trial price', () => {
const options = [
buildOption({
isTrial: true,
displayName: 'Standard Digital',
trialDuration: '6 weeks',
trialPrice: '£1.00',
price: '£20.00',
value: 'P1M',
}),
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(wrapper.find('.ncf__payment-term__trial-price').text()).toBe(
'£1.00'
);
});
it('displays the trial price explanatory text', () => {
const options = [
buildOption({
isTrial: true,
displayName: 'Standard Digital',
trialDuration: '6 weeks',
trialPrice: '£1.00',
price: '£20.00',
value: 'P1M',
}),
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(
wrapper.find('.ncf__payment-term__description').text()
).toContain(
'Unless you cancel during your trial you will be billed £20.00 per month after the trial period.'
);
});
});
describe('option.isTrial is false', () => {
describe('option.value is a valid period', () => {
describe('option.subscriptionAutoRenewTerm is false, i.e. non-renewing (single-term) subscription', () => {
it('expresses price as a single payment', () => {
const options = [
buildOption({
isTrial: false,
subscriptionAutoRenewTerm: false,
value: 'P8W',
price: '£19.00',
amount: '19.00',
}),
];
const wrapper = shallow(
<PaymentTerm
options={options}
isAutoRenewingSubscriptionTermType={false}
isNonRenewingSubscriptionTermType={true}
/>
);
expect(
wrapper.find('.ncf__payment-term__description').text()
).toContain('Single £19.00 payment');
});
it('does not describe a renewal period', () => {
const options = [
buildOption({
isTrial: false,
subscriptionAutoRenewTerm: false,
value: 'P8W',
price: '£19.00',
amount: '19.00',
}),
];
const wrapper = shallow(
<PaymentTerm
options={options}
isAutoRenewingSubscriptionTermType={false}
isNonRenewingSubscriptionTermType={true}
/>
);
expect(
wrapper.find('.ncf__payment-term__renews-text').exists()
).toBe(false);
});
});
describe('option.subscriptionAutoRenewTerm is true, i.e. auto-renewing subscription', () => {
describe('offer term is 52 weeks or longer', () => {
it('expresses price as a single payment', () => {
const options = [
buildOption({
name: 'annual',
value: 'P1Y',
price: '£120.00',
amount: '120.00',
subscriptionAutoRenewTerm: true,
}),
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(
wrapper.find('.ncf__payment-term__description').text()
).toContain('Single £120.00 payment');
});
});
describe('offer term is shorter than 52 weeks', () => {
it('expresses price as a recurring payment', () => {
const options = [
buildOption({
name: 'quarterly',
value: 'P3M',
price: '£30.00',
amount: '30.00',
subscriptionAutoRenewTerm: true,
}),
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(
wrapper.find('.ncf__payment-term__description').text()
).toContain('£30.00 per 3 months');
});
});
it('describes the renewal period', () => {
const options = [
buildOption({
name: 'quarterly',
value: 'P3M',
price: '£30.00',
amount: '30.00',
subscriptionAutoRenewTerm: true,
}),
];
const wrapper = shallow(<PaymentTerm options={options} />);
expect(
wrapper.find('.ncf__payment-term__renews-text')
).toHaveLength(1);
expect(wrapper.find('.ncf__payment-term__renews-text').text()).toBe(
'Renews every 3 months unless cancelled'
);
});
});
describe('offer term is 90 days or longer', () => {
describe('option.monthlyPrice is provided', () => {
describe('option.monthlyPrice value is "0"', () => {
it('displays the equivalent monthly price calculated from the option property values', () => {
const option = buildOption({
name: 'annual',
value: 'P1Y',
price: '£120.00',
amount: '120.00',
symbol: '£',
monthlyPrice: '0',
subscriptionAutoRenewTerm: false,
});
const wrapper = shallow(
<PaymentTerm
options={[option]}
isAutoRenewingSubscriptionTermType={false}
isNonRenewingSubscriptionTermType={true}
/>
);
expect(
wrapper.find('.ncf__payment-term__monthly-price').text()
).toBe('£10.00');
});
});
describe('option.monthlyPrice value can be parsed as a number, e.g. 54.17', () => {
it('displays the equivalent monthly price constructed from option.symbol and option.monthlyPrice values', () => {
const option = buildOption({
name: 'annual',
value: 'P1Y',
price: '£650.00',
amount: '650.00',
symbol: '£',
monthlyPrice: '54.17',
subscriptionAutoRenewTerm: false,
});
const wrapper = shallow(
<PaymentTerm
options={[option]}
isAutoRenewingSubscriptionTermType={false}
isNonRenewingSubscriptionTermType={true}
/>
);
expect(
wrapper.find('.ncf__payment-term__monthly-price').text()
).toBe('£54.17');
});
});
describe('option.monthlyPrice value cannot be pased as a number, e.g. "£54.17"', () => {
it('displays the equivalent monthly price derived directly from the option.monthlyPrice value', () => {
const option = buildOption({
name: 'annual',
value: 'P1Y',
price: '£650.00',
amount: '650.00',
symbol: '£',
monthlyPrice: '£54.17',
subscriptionAutoRenewTerm: false,
});
const wrapper = shallow(
<PaymentTerm
options={[option]}
isAutoRenewingSubscriptionTermType={false}
isNonRenewingSubscriptionTermType={true}
/>
);
expect(
wrapper.find('.ncf__payment-term__monthly-price').text()
).toBe('£54.17');
});
});
});
describe('option.monthlyPrice is not provided', () => {
it('displays the equivalent monthly price calculated from the option property values', () => {
const option = buildOption({
name: 'annual',
value: 'P1Y',
price: '£120.00',
amount: '120.00',
symbol: '£',
subscriptionAutoRenewTerm: false,
monthlyPrice: undefined,
});
const wrapper = shallow(
<PaymentTerm
options={[option]}
isAutoRenewingSubscriptionTermType={false}
isNonRenewingSubscriptionTermType={true}
/>
);
expect(
wrapper.find('.ncf__payment-term__monthly-price').text()
).toBe('£10.00');
});
});
});
describe('offer term is shorter than 90 days', () => {
it('does not display the equivalent monthly price', () => {
const options = [
buildOption({
value: 'P8W',
price: '£19.00',
amount: '19.00',
subscriptionAutoRenewTerm: false,
}),
];
const wrapper = shallow(
<PaymentTerm
options={options}
isAutoRenewingSubscriptionTermType={false}
isNonRenewingSubscriptionTermType={true}
/>
);
expect(
wrapper.find('.ncf__payment-term__equivalent-price').exists()
).toBe(false);
expect(wrapper.text()).not.toContain('That’s equivalent to');
});
});
});
describe('option.value is not a valid period', () => {
it('renders a component using option custom properties', () => {
const options = [
{
title: 'Annual',
subTitle: '(Renews annually unless cancelled)',
price: '€ 270.00',
value: 270.0,
isTrial: false,
discount: '33%',
bestOffer: true,
selected: false,
chargeOnText: 'You will be charged on May 1, 2021',
},
];
const wrapper = shallow(
<PaymentTerm
options={options}
showLegal={false}
largePrice={true}
/>
);
expect(wrapper.find('.ncf__payment-term__title').text()).toContain(
'Annual'
);
expect(wrapper.find('.ncf__payment-term__sub-title').text()).toBe(
'(Renews annually unless cancelled)'
);
expect(wrapper.find('.ncf__payment-term__large-price').text()).toBe(
'€ 270.00'
);
expect(
wrapper.find('.ncf__payment-term__charge-on-text').text()
).toBe('You will be charged on May 1, 2021');
});
});
});
});
describe('payment term legal text', () => {
describe('showLegal is true', () => {
describe('isAutoRenewingSubscriptionTermType is true; isNonRenewingSubscriptionTermType is false', () => {
it('displays relevant legal text', () => {
const wrapper = shallow(
<PaymentTerm
options={[buildOption()]}
showLegal={true}
isAutoRenewingSubscriptionTermType={true}
isNonRenewingSubscriptionTermType={false}
/>
);
expect(wrapper.find('.ncf__payment-term__legal').exists()).toBe(true);
expect(wrapper.find('.ncf__payment-term__legal').text()).toContain(
'With all subscription types, we will automatically renew your subscription using the payment method provided unless you cancel before your renewal date.'
);
expect(wrapper.find('.ncf__payment-term__legal').text()).toContain(
'We will notify you at least 14 days in advance'
);
expect(wrapper.find('.ncf__payment-term__legal').text()).toContain(
'Terms & Conditions'
);
});
});
describe('isAutoRenewingSubscriptionTermType is false; isNonRenewingSubscriptionTermType is true', () => {
it('displays relevant legal text; hides unrelated legal text', () => {
const wrapper = shallow(
<PaymentTerm
options={[buildOption()]}
showLegal={true}
isAutoRenewingSubscriptionTermType={false}
isNonRenewingSubscriptionTermType={true}
/>
);
expect(wrapper.find('.ncf__payment-term__legal').exists()).toBe(true);
expect(wrapper.find('.ncf__payment-term__legal').text()).toContain(
'Find out more about our cancellation policy in our Terms & Conditions.'
);
expect(
wrapper.find('.ncf__payment-term__legal').text()
).not.toContain(
'With all subscription types, we will automatically renew your subscription'
);
expect(
wrapper.find('.ncf__payment-term__legal').text()
).not.toContain('We will notify you at least 14 days in advance');
});
});
});
describe('showLegal is false', () => {
it('hides legal text', () => {
const wrapper = shallow(
<PaymentTerm
options={[buildOption()]}
showLegal={false}
isAutoRenewingSubscriptionTermType={true}
isNonRenewingSubscriptionTermType={false}
/>
);
expect(wrapper.find('.ncf__payment-term__legal').exists()).toBe(false);
expect(wrapper.text()).not.toContain('Terms & Conditions');
expect(wrapper.text()).not.toContain('automatically renew');
});
});
});
});