import expect from 'expect';
import fetchMock from 'fetch-mock';
import {
  fetchExperimentsInMinexperiment,
  EXPERIMENTS_JSON_URL,
  MinexperimentResponse,
  MinexperimentType,
} from 'mweb/common/fetch/experiments';
import {
  ExperimentUUIDs,
  ExperimentNames,
  ExperimentMetadata,
  ExperimentGroups,
} from 'mweb/common/actions/experiments';

describe('fetchExperimentsInMinexperiment', () => {
  afterEach(() => fetchMock.restore());

  interface ExperimentTestCase {
    data: MinexperimentResponse;
    expected: ExperimentMetadata[];
  }

  const EXPERIMENT_TEST_CASES: ExperimentTestCase[] = [
    {
      data: {
        [ExperimentUUIDs.Test]: {
          uuid: ExperimentUUIDs.Test,
          name: ExperimentNames.Test,
          v: 0,
          t: MinexperimentType.DeviceId,
          groups: [
            {
              weight: 50,
              value: ExperimentGroups.Treatment,
            },
            {
              weight: 50,
              value: ExperimentGroups.Control,
            },
          ],
        },
        [ExperimentUUIDs.Branch]: {
          uuid: ExperimentUUIDs.Branch,
          name: ExperimentNames.Branch,
          v: 0,
          t: MinexperimentType.DeviceId,
          groups: [
            {
              weight: 5,
              value: ExperimentGroups.Treatment,
            },
            {
              weight: 95,
              value: ExperimentGroups.Control,
            },
          ],
        },
      },
      expected: [
        {
          uuid: ExperimentUUIDs.Test,
          name: ExperimentNames.Test,
          groups: [
            {
              weight: 50,
              value: ExperimentGroups.Treatment,
            },
            {
              weight: 50,
              value: ExperimentGroups.Control,
            },
          ],
        },
        {
          uuid: ExperimentUUIDs.Branch,
          name: ExperimentNames.Branch,
          groups: [
            {
              weight: 5,
              value: ExperimentGroups.Treatment,
            },
            {
              weight: 95,
              value: ExperimentGroups.Control,
            },
          ],
        },
      ],
    },
    {
      data: {
        '12345': {
          uuid: '12345',
          name: '12345',
          v: 0,
          t: MinexperimentType.DeviceId,
          groups: [
            {
              weight: 100,
              value: ExperimentGroups.Control,
            },
          ],
        },
        [ExperimentUUIDs.Test]: {
          uuid: ExperimentUUIDs.Test,
          name: ExperimentNames.Test,
          v: 230,
          t: MinexperimentType.DeviceId,
          groups: [
            {
              weight: 50,
              value: ExperimentGroups.Treatment,
            },
            {
              weight: 50,
              value: ExperimentGroups.Control,
            },
          ],
        },
        '67890': {
          uuid: '67890',
          name: '67890',
          v: 100,
          t: MinexperimentType.DeviceId,
          groups: [
            {
              weight: 100,
              value: ExperimentGroups.Treatment,
            },
          ],
        },
      },
      expected: [
        {
          uuid: ExperimentUUIDs.Test,
          name: ExperimentNames.Test,
          groups: [
            {
              weight: 50,
              value: ExperimentGroups.Treatment,
            },
            {
              weight: 50,
              value: ExperimentGroups.Control,
            },
          ],
        },
      ],
    },
    {
      data: {
        '12345': {
          uuid: '12345',
          name: '12345',
          v: 0,
          t: MinexperimentType.DeviceId,
          groups: [
            {
              weight: 100,
              value: ExperimentGroups.Control,
            },
          ],
        },
        '67890': {
          uuid: '67890',
          name: '67890',
          v: 100,
          t: MinexperimentType.DeviceId,
          groups: [
            {
              weight: 100,
              value: ExperimentGroups.Treatment,
            },
          ],
        },
      },
      expected: [],
    },
  ];

  EXPERIMENT_TEST_CASES.forEach(({ data, expected }) => {
    it('returns only the experiment data in ExperimentUUIDs', async () => {
      fetchMock.mock(EXPERIMENTS_JSON_URL, data);
      const experiments = await fetchExperimentsInMinexperiment();
      expect(experiments).toEqual(expected);
    });
  });

  it('returns an empty array on 404', async () => {
    fetchMock.mock(EXPERIMENTS_JSON_URL, 404);
    const experiments = await fetchExperimentsInMinexperiment();
    expect(experiments).toEqual([]);
  });

  it('returns an empty array on 500', async () => {
    fetchMock.mock(EXPERIMENTS_JSON_URL, 500);
    const experiments = await fetchExperimentsInMinexperiment();
    expect(experiments).toEqual([]);
  });
});
