/* global describe: true, test:true, expect:true */
import { google as googleReducer, initialState } from '~/reducers/google';
import {
	SET_GOOGLE_INFO,
	GET_GOOGLE_TOKEN,
	GET_GOOGLE_TOKEN_SUCCESS,
	LOGOUT_SUCCESS,
	LOGOUT_FROM_GOOGLE_SUCCESS,
	GET_GOOGLE_TOKEN_ERROR,
	GET_GOOGLE_ALBUMS,
	GET_GOOGLE_CATEGORIES,
	GET_GOOGLE_ALBUMS_ERROR,
	GET_GOOGLE_CATEGORIES_ERROR,
	GET_GOOGLE_ALBUMS_SUCCESS,
	GET_GOOGLE_CATEGORIES_SUCCESS,
	GET_DYNAMIC_PLAYLISTS_ERROR,
	GET_DYNAMIC_PLAYLISTS_SUCCESS,
	GET_GOOGLE_ALBUM_CONTENT_SUCCESS,
} from '~/store/actionTypes';

import Factory from 'helper/factories/google';

describe('google reducer', () => {
	test('CASE 1: should return initial state', () => {
		expect(googleReducer(undefined, { type: 'Default' }))
			.toEqual(initialState);
	});

	test('CASE 2: should return state with Google info set when type is SET_GOOGLE_INFO', () => {
		const googleInfo = {
			email: 'user@gmail.com',
			photo: 'https://lh4.googleusercontent.com/photo.jpg',
			idToken: '{idToken}',
			id: '{id}',
			familyName: '{lastName}',
			serverAuthCode: '{serverAuthCode}',
			accessToken: '{accessToken}',
			givenName: '{firstName}',
			accessTokenExpirationDate: 3260.7057960033417,
			name: '{firstName} {lastName}',
		};
		const expectedState = { ...initialState, auth: googleInfo };
		const stateResult = googleReducer(initialState, {
			type: SET_GOOGLE_INFO, payload: googleInfo,
		});
		expect(stateResult).toEqual(expectedState);
	});

	test('CASE 3: should return state with meta set when type is GET_GOOGLE_TOKEN', () => {
		const expectedState = initialState;
		const stateResult = googleReducer(initialState, {
			type: GET_GOOGLE_TOKEN,
		});
		expect(stateResult).toEqual(expectedState);
	});

	test('CASE 4: should return state with Google set when type is GET_GOOGLE_TOKEN_SUCCESS', () => {
		const googleInfo = {
			email: 'user@gmail.com',
			photo: 'https://lh4.googleusercontent.com/photo.jpg',
			idToken: '{idToken}',
			id: '{id}',
			familyName: '{lastName}',
			serverAuthCode: '{serverAuthCode}',
			accessToken: '{accessToken}',
			givenName: '{firstName}',
			accessTokenExpirationDate: 3260.7057960033417,
			name: '{firstName} {lastName}',
		};
		const googleToken = { googleId: googleInfo.email, valid: true };
		const expectedState = {
			...initialState,
			auth: googleInfo,
		};
		const stateResult = googleReducer({ ...initialState, auth: googleInfo }, {
			type: GET_GOOGLE_TOKEN_SUCCESS,
			payload: { googleToken },
		});
		expect(stateResult).toEqual(expectedState);
	});

	test('CASE 5: should return state with Google unset when type is GET_GOOGLE_TOKEN_SUCCESS and server Token is invalid', () => {
		const googleInfo = {
			email: 'user@gmail.com',
			photo: 'https://lh4.googleusercontent.com/photo.jpg',
			idToken: '{idToken}',
			id: '{id}',
			familyName: '{lastName}',
			serverAuthCode: '{serverAuthCode}',
			accessToken: '{accessToken}',
			givenName: '{firstName}',
			accessTokenExpirationDate: 3260.7057960033417,
			name: '{firstName} {lastName}',
		};
		const googleToken = { googleId: googleInfo.email, valid: false };
		const expectedState = {
			...initialState,
			auth: {},
		};
		const stateResult = googleReducer({ ...initialState, auth: googleInfo }, {
			type: GET_GOOGLE_TOKEN_SUCCESS,
			payload: { googleToken },
		});
		expect(stateResult).toEqual(expectedState);
	});

	test('CASE 6: should return state with Google unset when type is GET_GOOGLE_TOKEN_SUCCESS and server Token is valid but googleId does not match the email', () => {
		const googleInfo = {
			email: 'user@gmail.com',
			photo: 'https://lh4.googleusercontent.com/photo.jpg',
			idToken: '{idToken}',
			id: '{id}',
			familyName: '{lastName}',
			serverAuthCode: '{serverAuthCode}',
			accessToken: '{accessToken}',
			givenName: '{firstName}',
			accessTokenExpirationDate: 3260.7057960033417,
			name: '{firstName} {lastName}',
		};
		const googleToken = { googleId: 'other@gmail.com', valid: true };
		const expectedState = {
			...initialState,
			auth: {},
		};
		const stateResult = googleReducer({ ...initialState, auth: googleInfo }, {
			type: GET_GOOGLE_TOKEN_SUCCESS,
			payload: { googleToken },
		});
		expect(stateResult).toEqual(expectedState);
	});

	test('CASE 7: should return state with meta loading set to false when actionType is GET_GOOGLE_TOKEN_ERROR', () => {
		const expectedState = initialState;
		const stateResult = googleReducer(initialState, {
			type: GET_GOOGLE_TOKEN_ERROR,
		});
		expect(stateResult).toEqual(expectedState);
	});

	test('CASE 7: should return initialState when actionType is LOGOUT_FROM_GOOGLE_SUCCESS', () => {
		const stateResult = googleReducer(initialState, {
			type: LOGOUT_FROM_GOOGLE_SUCCESS,
		});
		expect(stateResult).toEqual(initialState);
	});

	test('CASE 8: should return initialState when actionType is LOGOUT_SUCCESS', () => {
		const stateResult = googleReducer(initialState, {
			type: LOGOUT_SUCCESS,
		});
		expect(stateResult).toEqual(initialState);
	});

	test('CASE 9: should return loading for albums set to true when actionType is GET_GOOGLE_ALBUMS', () => {
		const expectedState = {
			...initialState,
			meta: { loading: { ...initialState.meta.loading, albums: true } },
		};
		const stateResult = googleReducer(initialState, {
			type: GET_GOOGLE_ALBUMS,
		});
		expect(stateResult).toEqual(expectedState);
	});

	test('CASE 10: should return loading for categories set to true when actionType is GET_GOOGLE_CATEGORIES', () => {
		const expectedState = {
			...initialState,
			meta: { loading: { ...initialState.meta.loading, categories: true } },
		};
		const stateResult = googleReducer(initialState, {
			type: GET_GOOGLE_CATEGORIES,
		});
		expect(stateResult).toEqual(expectedState);
	});

	test('CASE 11: should return loading for categories set to false when actionType is GET_GOOGLE_ALBUMS_ERROR', () => {
		const expectedState = {
			...initialState,
			meta: { loading: { ...initialState.meta.loading, categories: false } },
		};
		const stateResult = googleReducer(initialState, {
			type: GET_GOOGLE_ALBUMS_ERROR,
		});
		expect(stateResult).toEqual(expectedState);
	});

	test('CASE 12: should return loading for categories set to false when actionType is GET_GOOGLE_CATEGORIES_ERROR', () => {
		const expectedState = {
			...initialState,
			meta: { loading: { ...initialState.meta.loading, categories: false } },
		};
		const stateResult = googleReducer(initialState, {
			type: GET_GOOGLE_CATEGORIES_ERROR,
		});
		expect(stateResult).toEqual(expectedState);
	});

	test('CASE 12: should return albums with alreadySynced set correctly when actionType is GET_GOOGLE_ALBUMS_SUCCESS', () => {
		const googleId = 'user@gmail.com';
		const playlists = Factory.buildList('DynamicPlaylist', 4, { googleId });
		const albums = Factory.buildList('GoogleAlbum', 2);
		const prevState = {
			auth: { email: googleId },
			categories: [],
			albums: [],
			allPhotos: {},
			playlists,
			meta: { loading: { albums: false, categories: false } },
		};
		const expectedState = {
			...prevState,
			meta: { loading: { ...initialState.meta.loading, categories: false } },
			albums: [
				{ title: 'Album 1', id: 'album1', alreadySynced: true },
				{ title: 'Album 2', id: 'album2', alreadySynced: true },
			],
			allPhotos: {},
		};
		const stateResult = googleReducer(prevState, {
			type: GET_GOOGLE_ALBUMS_SUCCESS,
			payload: albums,
		});
		expect(stateResult).toEqual(expectedState);
	});

	test('CASE 13: should return categories with alreadySynced set correctly when actionType is GET_GOOGLE_CATEGORIES_SUCCESS', () => {
		const googleId = 'user@gmail.com';
		const playlists = Factory.buildList('DynamicPlaylist', 4, { googleId });
		const categories = [
			{ id: 'ANIMAL' },
			{ id: 'PEOPLE' },
			{ id: 'LANDSCAPE' },
		];
		const prevState = {
			auth: { email: googleId },
			categories: [],
			albums: [],
			playlists,
			meta: { loading: { albums: false, categories: false } },
		};
		const expectedState = {
			...prevState,
			meta: { loading: { ...initialState.meta.loading, categories: false } },
			categories: [
				{ id: 'ANIMAL', alreadySynced: true },
				{ id: 'PEOPLE', alreadySynced: true },
				{ id: 'LANDSCAPE' },
			],
			allPhotos: { alreadySynced: false },
		};
		const stateResult = googleReducer(prevState, {
			type: GET_GOOGLE_CATEGORIES_SUCCESS,
			payload: { categories, allPhotos: {} },
		});
		expect(stateResult).toEqual(expectedState);
	});

	test('CASE 14: should return alreadySynced set correctly when actionType is GET_DYNAMIC_PLAYLISTS_SUCCESS', () => {
		const googleId = 'user@gmail.com';
		const playlists = Factory.buildList('DynamicPlaylist', 4, { googleId });
		const albums = Factory.buildList('GoogleAlbum', 2);
		const categories = [
			{ id: 'ANIMAL' },
			{ id: 'PEOPLE' },
			{ id: 'LANDSCAPE' },
		];
		const prevState = {
			auth: { email: googleId },
			categories,
			albums,
			playlists: [],
			meta: { loading: { albums: false, categories: false } },
			allPhotos: {},
		};
		const expectedState = {
			...prevState,
			meta: { loading: { albums: false, categories: false } },
			categories: [
				{ id: 'ANIMAL', alreadySynced: true },
				{ id: 'PEOPLE', alreadySynced: true },
				{ id: 'LANDSCAPE' },
			],
			albums,
			playlists,
			allPhotos: { alreadySynced: false },
		};
		const stateResult = googleReducer(prevState, {
			type: GET_DYNAMIC_PLAYLISTS_SUCCESS,
			payload: { google: playlists },
		});
		expect(stateResult).toEqual(expectedState);
	});


	test('CASE 15: should return categories with alreadySynced set correctly when actionType is GET_DYNAMIC_PLAYLISTS_ERROR', () => {
		const stateResult = googleReducer(initialState, {
			type: GET_DYNAMIC_PLAYLISTS_ERROR,
		});
		expect(stateResult).toEqual(initialState);
	});

	test('CASE 16: should return album with mediaItems set correctly when actionType is GET_GOOGLE_ALBUM_CONTENT_SUCCESS', () => {
		const googleId = 'user@gmail.com';
		const playlists = Factory.buildList('DynamicPlaylist', 4, { googleId });
		const albums = Factory.buildList('GoogleAlbum', 1);
		const prevState = {
			auth: { email: googleId },
			albums,
			playlists,
			meta: { loading: { albums: false, categories: false } },
		};

		const payload = {
			title: albums[0].title,
			id: albums[0].id,
			mediaItems: [
				{ id: 'AGj1epUmh4wiG3g2bKOKDoclVoRTsE-_STHFhWdUdhvR142wa0wx4-y-rb9mYq2363Cr0_Gid19iJw4' },
				{ id: 'AGj1epWNpu29AtPtEyX3ICRDLOcxyUxhCt45UG1C4swn1me84xFxculsQDCJaclsC3mBeX54MBM7HL8' },
				{ id: 'AGj1epWAvBQE-WStq6wzHkv-4oW28J154cd5SU4KDCUTL-XB9hJdxyT7GCaOLett4qVyRXFFmYHpYJ4' },
			],
		};

		const expectedState = {
			...prevState,
			meta: { loading: { albums: false, categories: false } },
			albums: [payload],
			playlists,
		};

		const stateResult = googleReducer(prevState, {
			type: GET_GOOGLE_ALBUM_CONTENT_SUCCESS, payload,
		});
		expect(stateResult).toEqual(expectedState);
	});
});
