import expect from 'expect';

import createTestState from 'mtest/helpers/createTestState';
import { makeFakeGame } from 'mtest/fetchMocks/games';

import {
  getGameDetails,
  convertGameAlias,
  getGameNameForGameAlias,
  getGameDetailsForGameAlias,
} from 'mweb/common/selectors/data/games';

describe('game data selectors', () => {
  describe('getGameDetails', () => {
    const game = makeFakeGame();
    const state = createTestState({
      data: {
        games: {
          gameDetails: {
            [game.name]: game,
          },
        },
      },
    });

    it('returns details for a  loaded game', () => {
      expect(getGameDetails(state, game.name)).toEqual(game);
    });

    it('returns undefined for a non-loaded game', () => {
      expect(getGameDetails(state, 'SmallAndy')).toEqual(undefined);
    });
  });

  describe('convertGameAlias', () => {
    const state = createTestState({
      data: {
        games: {
          gameNameLookup: {
            game: 'Game',
          },
        },
      },
    });

    it('returns game name when alias is resolvable', () => {
      expect(convertGameAlias(state, 'game')).toEqual('Game');
    });

    it('returns undefined when alias is not resolvable', () => {
      expect(convertGameAlias(state, 'game1')).toEqual(undefined);
    });
  });

  describe('getGameNameForGameAlias', () => {
    it('short circuits if alias is canonical name', () => {
      const game = makeFakeGame();
      const state = createTestState({
        data: {
          games: {
            gameDetails: {
              [game.name]: game,
            },
          },
        },
      });

      expect(getGameNameForGameAlias(state, game.name)).toEqual(game.name);
    });

    it('falls back to using the lookup if non-canonical match and alias is resolvable', () => {
      const state = createTestState({
        data: {
          games: {
            gameNameLookup: {
              game: 'Game',
            },
          },
        },
      });

      expect(getGameNameForGameAlias(state, 'game')).toEqual('Game');
    });

    it('returns undefined when alias is not resolvable', () => {
      const state = createTestState({
        data: {
          games: {
            gameNameLookup: {
              game: 'Game',
            },
          },
        },
      });
      expect(getGameNameForGameAlias(state, 'game1')).toEqual(undefined);
    });
  });

  describe('getGameDetailsForGameAlias', () => {
    it('returns a game object via short circuit when the alias is canonical and the game is loaded', () => {
      const game = makeFakeGame();
      const state = createTestState({
        data: {
          games: {
            gameDetails: {
              [game.name]: game,
            },
          },
        },
      });
      expect(getGameDetailsForGameAlias(state, game.name)).toEqual(game);
    });

    it('returns a game object when the alias is resolvable and the game is loaded', () => {
      const game = makeFakeGame();
      const state = createTestState({
        data: {
          games: {
            gameNameLookup: {
              [game.name.toUpperCase()]: game.name,
            },
            gameDetails: {
              [game.name]: game,
            },
          },
        },
      });
      expect(
        getGameDetailsForGameAlias(state, game.name.toUpperCase()),
      ).toEqual(game);
    });

    it('returns undefined when the alias is resolvable but the game is not loaded', () => {
      const gameName = 'game';
      const state = createTestState({
        data: {
          games: {
            gameNameLookup: {
              [gameName]: gameName,
            },
          },
        },
      });
      expect(getGameDetailsForGameAlias(state, gameName)).toEqual(undefined);
    });

    it('returns undefined when the alias is unresolvable', () => {
      const state = createTestState();
      expect(getGameDetailsForGameAlias(state, 'game')).toEqual(undefined);
    });
  });
});
