import expect from 'expect';
import fetchMock from 'fetch-mock';
import {
  mockEvent,
  mockEventWithoutGame,
  mockEventUnsupportedType,
  mockEventNotFound,
  mockPremiereEvent,
  EVENT_ID,
  EVENT_PAYLOAD,
  EVENT_PAYLOAD_WITHOUT_GAME,
  PREMIERE_EVENT_PAYLOAD,
} from 'mtest/fetchMocks/event';
import {
  fetchEvent,
  compileFetchEventsOperation,
  EventDataPayload,
} from 'mweb/common/fetch/events';

interface FetchEventTestCase {
  description: string;
  mocker: () => void;
  expected: EventDataPayload | null;
}

describe('fetchEvent', () => {
  afterEach(() => {
    expect(fetchMock.done()).toEqual(true);
    fetchMock.restore();
  });

  const testCases: FetchEventTestCase[] = [
    {
      description: 'fetches an event',
      mocker: mockEvent,
      expected: EVENT_PAYLOAD,
    },
    {
      description: 'fetches an event with no game',
      mocker: mockEventWithoutGame,
      expected: EVENT_PAYLOAD_WITHOUT_GAME,
    },
    {
      description: 'fetches a premiere event',
      mocker: mockPremiereEvent,
      expected: PREMIERE_EVENT_PAYLOAD,
    },
    {
      description: 'returns null when an event type is not supported',
      mocker: mockEventUnsupportedType,
      expected: null,
    },
    {
      description: 'returns null when an event type does not exist',
      mocker: mockEventNotFound,
      expected: null,
    },
  ];

  testCases.forEach(({ description, mocker, expected }) => {
    it(description, () => {
      mocker();
      return fetchEvent(EVENT_ID).then(result => {
        expect(
          JSON.parse((fetchMock.calls().matched[0][1] as any).body),
        ).toEqual({
          query: compileFetchEventsOperation(),
          operationName: 'EventQuery',
          variables: {
            eventID: EVENT_ID,
          },
        });
        expect(result).toEqual(expected);
      });
    });
  });
});
