import { TextEncoder, TextDecoder } from 'util'; import ProductIdentifiersSection from '../features/order-ship/booking/product-identifiers-section'; import type { ProductIdentifierLine } from '../shared/utils/productIdentifierLines'; let renderToStaticMarkup: ( element: JSX.Element ) => string; beforeAll( async () => { // react-dom/server needs these, which the jsdom test environment lacks. Object.assign( globalThis, { TextEncoder, TextDecoder } ); ( { renderToStaticMarkup } = await import( 'react-dom/server' ) ); } ); const render = ( lines: ProductIdentifierLine[], blocking = false ) => renderToStaticMarkup( ); const line = ( over: Partial< ProductIdentifierLine > = {} ): ProductIdentifierLine => ( { itemIndex: 0, name: 'Ceramic mug', fields: [ { key: 'merchantProductId', label: 'Item SKU', value: 'SKU-1', required: true, maxLength: 64, order: 1 }, { key: 'manufacturerProductId', label: 'Manufacturer ID', value: '', required: true, maxLength: 32, order: 2 }, { key: 'standardProductId', label: 'Barcode', value: '4006381333931', required: false, maxLength: 32, order: 3 }, ], ...over, } ); describe( 'ProductIdentifiersSection', () => { it( 'renders nothing when no item needs a code', () => { expect( render( [] ) ).toBe( '' ); } ); it( 'shows the heading, the item and a field for each identifier with its value', () => { const html = render( [ line() ] ); expect( html ).toContain( 'Product codes for EU customs' ); expect( html ).toContain( 'Ceramic mug' ); expect( html ).toContain( 'Item SKU' ); expect( html ).toContain( 'Manufacturer ID' ); expect( html ).toContain( 'value="SKU-1"' ); expect( html ).toContain( 'value="4006381333931"' ); } ); it( 'marks the required fields and the optional barcode', () => { const html = render( [ line() ] ); expect( html ).toContain( 'Item SKU *' ); expect( html ).toContain( 'Manufacturer ID *' ); expect( html ).toContain( 'Barcode (optional)' ); } ); it( 'gives each field a stable id and the width the server enforces', () => { const html = render( [ line( { itemIndex: 2 } ) ] ); expect( html ).toContain( 'id="p2g-identifier-2-merchantProductId"' ); expect( html ).toContain( 'maxLength="64"' ); expect( html ).toContain( 'maxLength="32"' ); } ); it( 'says the changes are for this booking only', () => { expect( render( [ line() ] ) ).toContain( 'apply to this booking only' ); } ); it( 'says why booking is held while a required code is missing', () => { expect( render( [ line() ], true ) ).toContain( 'Enter the required codes to continue.' ); expect( render( [ line() ], false ) ).not.toContain( 'Enter the required codes to continue.' ); } ); it( 'shows every item, in order', () => { const html = render( [ line( { name: 'Ceramic mug' } ), line( { itemIndex: 1, name: 'Wooden spoon' } ), ] ); expect( html.indexOf( 'Ceramic mug' ) ).toBeLessThan( html.indexOf( 'Wooden spoon' ) ); } ); } );