UNPKG

@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
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'); }); }); }); });