import { productIdentifierFields } from '../shared/utils/productIdentifiers'; import { orderToCheckoutValidatePayload } from '../features/order-ship/utils/orderToCheckoutValidatePayload'; import ordersToCheckoutValidatePayload from '../features/orders/utils/ordersToCheckoutValidatePayload'; import type { Order, PluginSettings, Quote } from '../types'; const ids = { merchant_product_id: 'PID-A', manufacturer_product_id: 'MFR-A-1001', standard_product_id: '4006381333931', }; // ------------------------------------------------------------------------- describe( 'productIdentifierFields', () => { it( 'maps the three identifiers to checkout keys', () => { expect( productIdentifierFields( { product_identifiers: ids } ) ).toEqual( { merchantProductId: 'PID-A', manufacturerProductId: 'MFR-A-1001', standardProductId: '4006381333931', } ); } ); it( 'leaves out empty and blank ones, so nothing blank is sent', () => { expect( productIdentifierFields( { product_identifiers: { merchant_product_id: 'PID-B', manufacturer_product_id: '', standard_product_id: ' ', }, } ) ).toEqual( { merchantProductId: 'PID-B' } ); } ); it( 'trims what it keeps', () => { expect( productIdentifierFields( { product_identifiers: { merchant_product_id: ' PID-A ' }, } ) ).toEqual( { merchantProductId: 'PID-A' } ); } ); it( 'returns nothing when the line has no identifiers', () => { expect( productIdentifierFields( {} ) ).toEqual( {} ); expect( productIdentifierFields( { product_identifiers: {} } ) ).toEqual( {} ); } ); } ); // ------------------------------------------------------------------------- const settings = { shipping: { country: 'GB', contactName: 'Shop', email: 's@example.com', town: 'London', property: '1', postcode: 'SW1A 1AA', street: 'Street', }, tax: {}, packages: [], overrides: {}, } as unknown as PluginSettings; const quote = { service: { slug: 'service-slug' }, tags: [], availableExtras: [], dates: [], } as unknown as Quote; const orderWith = ( items: object[] ) => ( { id: 1502, shipping: { name: 'Test Customer', company: '', address_1: 'Rue de Rivoli', address_2: '', city: 'Paris', state: '', postcode: '75001', country: 'FR', phone: '', }, customer: { name: 'Test Customer', email: 'test@example.com' }, items, cheapestQuote: quote, } ) as unknown as Order; const item = ( over: object = {} ) => ( { product_id: 1, variation_id: 0, name: 'Ceramic mug', quantity: 2, total: '20.00', dimensions: { length: 10, width: 10, height: 10, weight: 0.5 }, tariff_code: '691110', country_of_manufacture: 'GB', product_identifiers: ids, ...over, } ); describe( 'orderToCheckoutValidatePayload (single order)', () => { it( 'carries the identifiers in each parcel content line', () => { const payload = orderToCheckoutValidatePayload( orderWith( [ item() ] ), settings, quote, [] ); const content = payload?.items[ 0 ].parcels[ 0 ].contents?.[ 0 ]; expect( content ).toMatchObject( { merchantProductId: 'PID-A', manufacturerProductId: 'MFR-A-1001', standardProductId: '4006381333931', tariffCode: '691110', countryOfManufacture: 'GB', } ); } ); it( 'sends only the identifiers a line has', () => { const payload = orderToCheckoutValidatePayload( orderWith( [ item( { product_identifiers: { merchant_product_id: 'PID-B', manufacturer_product_id: '', standard_product_id: '', }, } ), ] ), settings, quote, [] ); const content = payload?.items[ 0 ].parcels[ 0 ].contents?.[ 0 ]; expect( content?.merchantProductId ).toBe( 'PID-B' ); expect( content ).not.toHaveProperty( 'manufacturerProductId' ); expect( content ).not.toHaveProperty( 'standardProductId' ); } ); it( 'is unchanged for a line with no identifiers', () => { const payload = orderToCheckoutValidatePayload( orderWith( [ item( { product_identifiers: undefined } ) ] ), settings, quote, [] ); const content = payload?.items[ 0 ].parcels[ 0 ].contents?.[ 0 ]; expect( content ).not.toHaveProperty( 'merchantProductId' ); expect( content?.tariffCode ).toBe( '691110' ); } ); } ); describe( 'ordersToCheckoutValidatePayload (bulk)', () => { it( 'carries the identifiers for every line of every order', () => { const payload = ordersToCheckoutValidatePayload( { orders: [ orderWith( [ item(), item( { name: 'Wooden spoon' } ) ] ), { ...orderWith( [ item() ] ), id: 1503 } as Order, ], settings, } ); expect( payload?.items ).toHaveLength( 2 ); const first = payload?.items[ 0 ].parcels[ 0 ].contents; expect( first ).toHaveLength( 2 ); expect( first?.every( ( c ) => c.merchantProductId === 'PID-A' ) ).toBe( true ); expect( payload?.items[ 1 ].parcels[ 0 ].contents?.[ 0 ] ).toMatchObject( { manufacturerProductId: 'MFR-A-1001', } ); } ); it( 'leaves out the identifiers a line does not have', () => { const payload = ordersToCheckoutValidatePayload( { orders: [ orderWith( [ item( { product_identifiers: {} } ) ] ) ], settings, } ); const content = payload?.items[ 0 ].parcels[ 0 ].contents?.[ 0 ]; expect( content ).not.toHaveProperty( 'merchantProductId' ); expect( content?.countryOfManufacture ).toBe( 'GB' ); } ); } ); describe( 'orderToCheckoutValidatePayload IOSS number', () => { const build = ( total: string, ioss?: string | null ) => orderToCheckoutValidatePayload( orderWith( [ item( { total } ) ] ), settings, quote, [], { ioss } )?.items[ 0 ].customs; it( 'sends the number it is given, as the caller has already checked eligibility', () => { expect( build( '20.00', '123456789012' )?.ioss ).toBe( '123456789012' ); } ); it( 'applies no flat 150 limit of its own: an order of any size keeps the number', () => { // The limit is the API\'s (converted to the store currency), decided by the caller. expect( build( '500.00', '123456789012' )?.ioss ).toBe( '123456789012' ); } ); it( 'sends null when no number was given', () => { expect( build( '20.00' )?.ioss ).toBeNull(); expect( build( '20.00', null )?.ioss ).toBeNull(); } ); } );