/** * External dependencies */ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; /** * Internal dependencies */ import { useCampaignTypes, useCampaigns } from '~/marketing/hooks'; import { Campaigns } from './Campaigns'; jest.mock( '~/marketing/hooks', () => ( { useCampaigns: jest.fn(), useCampaignTypes: jest.fn(), } ) ); jest.mock( '~/marketing/components', () => { const originalModule = jest.requireActual( '~/marketing/components' ); return { __esModule: true, ...originalModule, CreateNewCampaignModal: () =>
Mocked CreateNewCampaignModal
, }; } ); /** * Create a test campaign data object. */ const createTestCampaign = ( programId: string ) => { return { id: `google-listings-and-ads|${ programId }`, title: `Campaign ${ programId }`, description: '', cost: `USD 30`, manageUrl: `https://wc1.test/wp-admin/admin.php?page=wc-admin&path=/google/dashboard&subpath=/campaigns/edit&programId=${ programId }`, icon: 'https://woocommerce.com/wp-content/uploads/2021/06/woo-GoogleListingsAds-jworee.png', channelName: 'Google Listings and Ads', channelSlug: 'google-listings-and-ads', }; }; describe( 'Campaigns component', () => { it( 'renders a TablePlaceholder when loading is in progress', () => { ( useCampaigns as jest.Mock ).mockReturnValue( { loading: true, error: undefined, data: undefined, meta: undefined, } ); ( useCampaignTypes as jest.Mock ).mockReturnValue( { loading: true, } ); const { container } = render( ); const tablePlaceholder = container.querySelector( 'div.woocommerce-table__table.is-loading' ); expect( tablePlaceholder ).toBeInTheDocument(); } ); it( 'renders an error message when loading is done and data is undefined', () => { ( useCampaigns as jest.Mock ).mockReturnValue( { loading: false, error: {}, data: undefined, meta: undefined, } ); ( useCampaignTypes as jest.Mock ).mockReturnValue( { loading: false, } ); render( ); expect( screen.getByText( 'An unexpected error occurred.' ) ).toBeInTheDocument(); } ); it( 'renders an info message when loading is done and data is an empty array', () => { ( useCampaigns as jest.Mock ).mockReturnValue( { loading: false, error: undefined, data: [], meta: { total: 0, }, } ); ( useCampaignTypes as jest.Mock ).mockReturnValue( { loading: false, } ); render( ); expect( screen.getByText( 'Advertise with marketing campaigns' ) ).toBeInTheDocument(); } ); it( 'renders a table with campaign info and without pagination when loading is done and data is an array with length no more than page size', () => { ( useCampaigns as jest.Mock ).mockReturnValue( { loading: false, error: undefined, data: [ createTestCampaign( '1' ) ], meta: { total: 1, }, } ); ( useCampaignTypes as jest.Mock ).mockReturnValue( { loading: false, } ); const { container } = render( ); expect( screen.getByText( 'Campaign 1' ) ).toBeInTheDocument(); expect( screen.getByText( 'USD 30' ) ).toBeInTheDocument(); const pagination = container.querySelector( '.woocommerce-pagination' ); expect( pagination ).not.toBeInTheDocument(); } ); it( 'renders a table with campaign info and with pagination when loading is done and data is an array with length more than page size', async () => { ( useCampaigns as jest.Mock ).mockReturnValue( { loading: false, error: undefined, data: [ createTestCampaign( '1' ), createTestCampaign( '2' ), createTestCampaign( '3' ), createTestCampaign( '4' ), createTestCampaign( '5' ), createTestCampaign( '6' ), ], meta: { total: 6, }, } ); ( useCampaignTypes as jest.Mock ).mockReturnValue( { loading: false, } ); render( ); // Campaign info. expect( screen.getByText( 'Campaign 1' ) ).toBeInTheDocument(); // Pagination. expect( screen.getByText( 'Page 1 of 2' ) ).toBeInTheDocument(); // Click on the next button to go to next page. await userEvent.click( screen.getByRole( 'button', { name: 'Next Page' } ) ); // Campaign info in the second page. expect( screen.getByText( 'Campaign 6' ) ).toBeInTheDocument(); } ); it( 'does not render a "Create new campaign" button in the card header when there are no campaign types', async () => { ( useCampaigns as jest.Mock ).mockReturnValue( { loading: false, error: undefined, data: [ createTestCampaign( '1' ) ], meta: { total: 1, }, } ); ( useCampaignTypes as jest.Mock ).mockReturnValue( { loading: false, data: [], } ); render( ); expect( screen.queryByRole( 'button', { name: 'Create new campaign' } ) ).not.toBeInTheDocument(); } ); it( 'renders a "Create new campaign" button in the card header when there are campaign types, and upon clicking, displays the "Create a new campaign" modal', async () => { ( useCampaigns as jest.Mock ).mockReturnValue( { loading: false, error: undefined, data: [ createTestCampaign( '1' ) ], meta: { total: 1, }, } ); ( useCampaignTypes as jest.Mock ).mockReturnValue( { loading: false, data: [ { id: 'google-ads', name: 'Google Ads', description: 'Boost your product listings with a campaign that is automatically optimized to meet your goals.', channel: { slug: 'google-listings-and-ads', name: 'Google Listings & Ads', }, create_url: 'https://wc1.test/wp-admin/admin.php?page=wc-admin&path=/google/dashboard&subpath=/campaigns/create', icon_url: 'https://woocommerce.com/wp-content/uploads/2021/06/woo-GoogleListingsAds-jworee.png', }, ], } ); render( ); await userEvent.click( screen.getByRole( 'button', { name: 'Create new campaign' } ) ); // Mocked CreateNewCampaignModal should be displayed. expect( screen.getByText( 'Mocked CreateNewCampaignModal' ) ).toBeInTheDocument(); } ); } );