src/app/components/Ad/Amp/index.test.tsx

Summary

Maintainability
A
0 mins
Test Coverage
import React from 'react';
import { RequestContextProvider } from '#contexts/RequestContext';
import { FRONT_PAGE } from '#app/routes/utils/pageTypes';
import AmpAd, { AMP_ACCESS_FETCH } from './index';
import { render } from '../../react-testing-library-with-providers';
import { ServiceContext } from '../../../contexts/ServiceContext';
import latinDiacritics from '../../ThemeProvider/fontScripts/latinWithDiacritics';
import { SlotType } from '../types';

const adJsonAttributes = (slotType: SlotType) => ({
  targeting: {
    slot: slotType,
    asset_type: 'index',
    channel: 'afrique',
  },
});

const adTranslations = {
  ads: {
    advertisementLabel: 'Publicités',
  },
};

const adWithContext = (slotType: SlotType, showAdPlaceholder = false) => (
  <RequestContextProvider
    bbcOrigin="https://www.test.bbc.com"
    isAmp
    isApp={false}
    pageType={FRONT_PAGE}
    service="afrique"
    pathname="/"
  >
    <ServiceContext.Provider
      value={{
        service: 'afrique',
        dir: 'ltr',
        script: latinDiacritics,
        // @ts-expect-error partial data required for testing
        translations: adTranslations,
        showAdPlaceholder,
      }}
    >
      <AmpAd slotType={slotType} />
    </ServiceContext.Provider>
  </RequestContextProvider>
);

describe('AMP Ads', () => {
  const originalConfigUrl = process.env.SIMORGH_CONFIG_URL;

  beforeAll(() => {
    process.env.SIMORGH_CONFIG_URL = 'https://mock-toggles-endpoint.bbc.co.uk';
  });

  afterAll(() => {
    process.env.SIMORGH_CONFIG_URL = originalConfigUrl;
  });

  describe('Snapshots', () => {
    it('should correctly render an AMP leaderboard ad', () => {
      const { container } = render(adWithContext('leaderboard'), {
        service: 'afrique',
      });
      expect(container).toMatchSnapshot();
    });

    it('should correctly render an AMP mpu ad', () => {
      const { container } = render(adWithContext('mpu'), {
        service: 'afrique',
      });
      expect(container).toMatchSnapshot();
    });
  });

  describe('Assertions', () => {
    it('should not render ad placeholder in UK when showAdPlaceholder in service config is false', () => {
      const { getByLabelText } = render(
        <div className="amp-geo-group-eea amp-geo-group-gbOrUnknown">
          {adWithContext('leaderboard', false)}
        </div>,
      );

      expect(getByLabelText('Publicités')).not.toBeVisible();
    });

    it('should render ad placeholder in UK when showAdPlaceholder in service config is true', () => {
      const { getByLabelText } = render(
        <div className="amp-geo-group-eea amp-geo-group-gbOrUnknown">
          {adWithContext('leaderboard', true)}
        </div>,
      );

      expect(getByLabelText('Publicités')).toBeVisible();
    });

    it.each`
      location           | className
      ${'europe'}        | ${'amp-geo-group-eea'}
      ${'rest of world'} | ${''}
    `(
      'should render ad placeholder outside of the UK - $location',
      ({ className }) => {
        const { getByLabelText } = render(
          <div className={className}>{adWithContext('leaderboard')}</div>,
        );

        expect(getByLabelText('Publicités')).toBeVisible();
      },
    );

    it('should render two leaderboard ads', () => {
      const { container } = render(adWithContext('leaderboard'));
      const ampAd = container.querySelectorAll('amp-ad');

      expect(ampAd.length).toBe(2);
    });

    it('should display leaderboard ad with values for all of the needed attributes', () => {
      const { container } = render(adWithContext('leaderboard'));

      const ampAd = container.querySelectorAll('amp-ad');
      ampAd.forEach(ad => {
        expect(ad).toHaveAttribute('data-block-on-consent', 'default');
        expect(ad).toHaveAttribute('data-npa-on-unknown-consent', 'true');
        expect(ad).toHaveAttribute('media');
        expect(ad).toHaveAttribute('type');
        expect(ad).toHaveAttribute('width');
        expect(ad).toHaveAttribute('height');
        expect(ad).toHaveAttribute('data-multi-size');
        expect(ad).toHaveAttribute('data-slot');
        expect(ad).toHaveAttribute('data-amp-slot-index');
        expect(ad).toHaveAttribute('data-a4a-upgrade-type');
        expect(ad).toHaveAttribute(
          'json',
          JSON.stringify(adJsonAttributes('leaderboard')),
        );
      });
    });

    it('should render one mpu ad', () => {
      const { container } = render(adWithContext('mpu'));
      const ampAd = container.querySelectorAll('amp-ad');

      expect(ampAd.length).toBe(1);
    });

    it('should display mpu ad with values for all of the needed attributes', () => {
      const { container } = render(adWithContext('mpu'));

      const ampAd = container.querySelectorAll('amp-ad');
      ampAd.forEach(ad => {
        expect(ad).toHaveAttribute('data-block-on-consent', 'default');
        expect(ad).toHaveAttribute('data-npa-on-unknown-consent', 'true');
        expect(ad).toHaveAttribute('type');
        expect(ad).toHaveAttribute('width');
        expect(ad).toHaveAttribute('height');
        expect(ad).toHaveAttribute('data-multi-size');
        expect(ad).toHaveAttribute('data-slot');
        expect(ad).toHaveAttribute('data-amp-slot-index');
        expect(ad).toHaveAttribute('data-a4a-upgrade-type');
        expect(ad).toHaveAttribute(
          'json',
          JSON.stringify(adJsonAttributes('mpu')),
        );
      });
    });

    it('should render an `advertisement` label', () => {
      const { container } = render(adWithContext('leaderboard'));
      const links = container.querySelectorAll('a');
      const advertisementLabel = links && links[0];
      expect(advertisementLabel.textContent).toEqual('Publicités');
      expect(advertisementLabel).toHaveAttribute('tabIndex', '-1');
    });
  });

  describe('AMP_ACCESS_FETCH', () => {
    it('should retrieve data from the correct endpoint', () => {
      const ampAccessFetch = jest.fn().mockImplementation(AMP_ACCESS_FETCH);
      const ampAccessData = ampAccessFetch('afrique');
      const expectedReturn =
        'https://mock-toggles-endpoint.bbc.co.uk?application=simorgh&service=afrique';

      expect(ampAccessFetch).toHaveReturned();
      expect(ampAccessFetch).toHaveBeenCalledWith('afrique');
      expect(ampAccessData.type).toEqual('script');
      expect(JSON.parse(ampAccessData.props.children).authorization).toEqual(
        expectedReturn,
      );
    });
  });
});