/* global describe: true, test:true, expect:true */
import { albums as albumsReducer, initialState } from '~/reducers/albums';
import _ from 'lodash';
import {
	GET_ALBUMS,
	CREATE_ALBUM,
	GET_ALBUMS_SUCCESS,
	GET_ALBUMS_ERROR,
	CREATE_ALBUM_ERROR,
	GET_ALBUM_CONTENT,
	GET_ALBUM_CONTENT_SUCCESS,
	GET_ALBUM_CONTENT_ERROR,
	CREATE_ALBUM_SUCCESS,
	LOGOUT_SUCCESS,

} from '~/store/actionTypes';
import {
	DEFAULT_ALBUM_NAME,
	DEFAULT_ALBUM_TYPE,
} from '~/store/contentTypes';

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

	test('CASE 2: should return state with loading when type is GET_ALBUMS or CREATE_ALBUM', () => {
		const expectedState = { ...initialState, meta: { ...initialState.meta, loading: true } };
		expect(albumsReducer(initialState, { type: GET_ALBUMS })).toEqual(expectedState);
		expect(albumsReducer(initialState, { type: CREATE_ALBUM })).toEqual(expectedState);
	});

	test('CASE 3: should return albums with meta property when type is GET_ALBUMS_SUCCESS', () => {
		const albums = [{ id: 1 }, { id: 2 }];
		const stateResult = albumsReducer(undefined, { type: GET_ALBUMS_SUCCESS, payload: { albums } });
		expect(stateResult).toHaveProperty('albums');
		expect(stateResult.albums).toHaveLength(albums.length);
		stateResult.albums.forEach(album => {
			expect(album).toHaveProperty('meta');
		});
	});

	test('CASE 5: should return correct state when type is GET_ALBUMS_ERROR or CREATE_ALBUM_ERROR', () => {
		const albumErr = new Error('getAlbumsError');
		const expectedState = { ...initialState, meta: { error: albumErr, loading: false } };
		expect(albumsReducer(initialState, {
			type: GET_ALBUMS_ERROR,
			payload: { error: albumErr },
		})).toEqual(expectedState);
		expect(albumsReducer(initialState, {
			type: CREATE_ALBUM_ERROR,
			payload: { error: albumErr },
		})).toEqual(expectedState);
	});

	test('CASE 6: should return state with album loading to TRUE when type is GET_ALBUM_CONTENT', () => {
		const albums = [{ id: 1 }, { id: 2 }];
		const payload = {
			albumId: 1,
		};
		const originalState = { ...initialState, albums, meta: { error: '' } };
		const stateResult = albumsReducer({ ...originalState, albums, meta: { error: '' } }, {
			type: GET_ALBUM_CONTENT,
			payload,
		});
		const expectedStateAlbums = [
			{ id: 1, meta: { error: '', loading: true } },
			{ id: 2 },
		];
		expect(stateResult.albums).toEqual(expectedStateAlbums);
	});

	test('CASE 7: should return state with album content when type is GET_ALBUM_CONTENT_SUCCESS', () => {
		const albums = [{ id: 1 }, { id: 2 }];
		const content = [
			{ id: 5 }, // photo id
			{ id: 4 }, // photo id
		];
		const payload = {
			albumId: 1,
			content,
		};
		const originalState = { ...initialState, albums, meta: { error: '' } };
		const stateResult = albumsReducer({ ...originalState, albums, meta: { error: '' } }, {
			type: GET_ALBUM_CONTENT_SUCCESS,
			payload,
		});
		expect(stateResult.albums[0]).toHaveProperty('content', _.orderBy(content, ['id'], ['desc']));
		// expect(stateResult.albums[0]).toHaveProperty('cover');
		// expect(stateResult.albums[0]).toHaveProperty('thumbs');
	});

	test('CASE 8: should return state with album error when type is GET_ALBUM_CONTENT_ERROR', () => {
		const albums = [{ id: 1 }, { id: 2 }];
		const albumErr = new Error('getAlbumsContentError');
		const payload = {
			albumId: 1,
			error: albumErr,
		};
		const originalState = { ...initialState, albums, meta: { error: '' } };
		const stateResult = albumsReducer({ ...originalState, albums, meta: { error: '' } }, {
			type: GET_ALBUM_CONTENT_ERROR,
			payload,
		});
		const expectedStateAlbums = [
			{ id: 1, meta: { error: albumErr, loading: false } },
			{ id: 2 },
		];
		expect(stateResult.albums).toEqual(expectedStateAlbums);
	});

	test('CASE 9: should add album on CREATE_ALBUM_SUCCESS with meta', () => {
		const albums = [{ id: 2 }, { id: 3 }];
		const payload = {
			album: { id: 1 },
		};
		const originalState = { ...initialState, albums, meta: { error: '' } };
		const stateResult = albumsReducer({ albums, ...originalState, meta: { error: '' } }, {
			type: CREATE_ALBUM_SUCCESS,
			payload,
		});
		const expectedStateAlbums = [
			{ id: 1, meta: { error: '', loading: false } },
			{ id: 2 },
			{ id: 3 },
		];
		expect(stateResult.albums).toEqual(expectedStateAlbums);
	});

	test('CASE 10: should empty the state on LOGOUT_SUCCESS', () => {
		const existingState = [{ id: 1 }, { id: 2 }];
		expect(albumsReducer(existingState, { type: LOGOUT_SUCCESS }))
			.toEqual(initialState);
	});

	test('CASE 11: should return albums with defaultAlbumId property when type is GET_ALBUMS_SUCCESS', () => {
		const albums = [{ id: 1, name: DEFAULT_ALBUM_NAME, type: DEFAULT_ALBUM_TYPE }, { id: 2 }];
		const stateResult = albumsReducer(undefined, { type: GET_ALBUMS_SUCCESS, payload: { albums } });
		expect(stateResult).toHaveProperty('albums');
		expect(stateResult).toHaveProperty('defaultAlbumId');
		expect(stateResult.albums).toHaveLength(albums.length);
		expect(stateResult.defaultAlbumId).toEqual(1);
		stateResult.albums.forEach(album => {
			expect(album).toHaveProperty('meta');
		});
	});
	test('CASE 12: should return albums with defaultAlbumId 0 property when type is GET_ALBUMS_SUCCESS', () => {
		const albums = [{ id: 1 }, { id: 2 }];
		const stateResult = albumsReducer(undefined, { type: GET_ALBUMS_SUCCESS, payload: { albums } });
		expect(stateResult).toHaveProperty('albums');
		expect(stateResult).toHaveProperty('defaultAlbumId');
		expect(stateResult.albums).toHaveLength(albums.length);
		expect(stateResult.defaultAlbumId).toEqual(0);
		stateResult.albums.forEach(album => {
			expect(album).toHaveProperty('meta');
		});
	});
});
