import {getMediaPage} from './mediaPageService';
import http from '@/http';

const mockedHttp = http as jest.Mocked<typeof http>;

function collection(pages: Record<string, unknown>[]) {
  return {status: 200, data: {'hydra:member': pages}};
}

const pageFr = {
  pagId: 1,
  pagSlug: 'mentions-legales',
  pagLangue: 'fr',
  pagTitre: 'Mentions légales',
  pagContenu: '<p>Éditeur</p>',
  pagMaj: null,
};

const pageEn = {...pageFr, pagId: 2, pagLangue: 'en', pagTitre: 'Legal notice', pagContenu: '<p>Publisher</p>'};

describe('mediaPageService', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('shouldReturnThePageInTheRequestedLocale', async () => {
    mockedHttp.get.mockResolvedValueOnce(collection([pageEn]));

    expect(await getMediaPage('mentions-legales', 'en')).toEqual({
      slug: 'mentions-legales',
      langue: 'en',
      titre: 'Legal notice',
      contenu: '<p>Publisher</p>',
    });
    expect(mockedHttp.get).toHaveBeenCalledTimes(1);
    expect(mockedHttp.get).toHaveBeenCalledWith('/media_pages?pagSlug=mentions-legales&pagLangue=en');
  });

  it('shouldFallBackToFrenchWhenTheLocaleHasNoContent', async () => {
    mockedHttp.get
      .mockResolvedValueOnce(collection([{...pageEn, pagContenu: null}]))
      .mockResolvedValueOnce(collection([pageFr]));

    expect(await getMediaPage('mentions-legales', 'en')).toEqual({
      slug: 'mentions-legales',
      langue: 'fr',
      titre: 'Mentions légales',
      contenu: '<p>Éditeur</p>',
    });
    expect(mockedHttp.get).toHaveBeenCalledTimes(2);
    expect(mockedHttp.get).toHaveBeenLastCalledWith('/media_pages?pagSlug=mentions-legales&pagLangue=fr');
  });

  it('shouldFallBackToFrenchWhenTheLocaleDoesNotExist', async () => {
    mockedHttp.get
      .mockResolvedValueOnce(collection([]))
      .mockResolvedValueOnce(collection([pageFr]));

    expect((await getMediaPage('mentions-legales', 'de'))?.langue).toBe('fr');
  });

  it('shouldReturnNullWhenNoVersionHasContent', async () => {
    mockedHttp.get
      .mockResolvedValueOnce(collection([]))
      .mockResolvedValueOnce(collection([{...pageFr, pagContenu: ''}]));

    expect(await getMediaPage('mentions-legales', 'en')).toBeNull();
    expect(mockedHttp.get).toHaveBeenCalledTimes(2);
  });

  it('shouldNotRetryFrenchWhenFrenchIsAlreadyEmpty', async () => {
    mockedHttp.get.mockResolvedValueOnce(collection([]));

    expect(await getMediaPage('mentions-legales', 'fr')).toBeNull();
    expect(mockedHttp.get).toHaveBeenCalledTimes(1);
  });

  it('shouldReturnNullWhenTheApiFails', async () => {
    mockedHttp.get.mockRejectedValueOnce(new Error('Network error'));

    expect(await getMediaPage('mentions-legales', 'fr')).toBeNull();
  });
});
