/**
 * `googlesitekit/modules` datastore: settings tests.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import Modules from 'googlesitekit-modules';
import { STORE_NAME } from './constants';
import settings from './settings';
import { createTestRegistry } from '../../../../../tests/js/utils';

describe( 'core/modules module settings panel', () => {
	let registry;
	let store;
	const slug = 'test-module';
	const nonExistentModuleSlug = 'not-module';
	const moduleStoreName = `modules/${ slug }`;

	beforeEach( () => {
		const storeDefinition = Modules.createModuleStore( moduleStoreName );
		const isModuleActive = ( state, moduleSlug ) => {
			return slug === moduleSlug ? true : null;
		};

		registry = createTestRegistry();
		store = registry.stores[ STORE_NAME ].store;
		registry.registerStore( STORE_NAME, Data.combineStores(
			store,
			{
				selectors: {
					isModuleActive,
				},
			},
			settings,
		) );

		registry.registerStore( moduleStoreName, Data.combineStores(
			storeDefinition,
		) );
	} );

	describe( 'reducer', () => {
		it( 'has the appropriate initial state', () => {
			expect( true ).toBeTruthy();
			const initialState = {};
			const initialStoreState = store.getState();

			// Ensure we have default state correct
			expect( Object.keys( initialStoreState ) ).toContain( 'panelState' );
			expect( initialStoreState.panelState ).toEqual( initialState );
		} );
	} );

	describe( 'selectors', () => {
		describe( 'getModuleSettingsPanelState', () => {
			it( 'gets module settings panel state', () => {
				// Default state for valid module is closed
				expect( registry.select( STORE_NAME ).getModuleSettingsPanelState( slug ) ).toBe( 'closed' );
				// Default state for invalid module is closed
				expect( registry.select( STORE_NAME ).getModuleSettingsPanelState( nonExistentModuleSlug ) ).toBe( null );

				registry.dispatch( STORE_NAME ).setModuleSettingsPanelState( slug, 'view' );
				expect( registry.select( STORE_NAME ).getModuleSettingsPanelState( slug ) ).toBe( 'view' );

				registry.dispatch( STORE_NAME ).setModuleSettingsPanelState( slug, 'closed' );
				expect( registry.select( STORE_NAME ).getModuleSettingsPanelState( slug ) ).toBe( 'closed' );

				registry.dispatch( STORE_NAME ).setModuleSettingsPanelState( slug, 'edit' );
				expect( registry.select( STORE_NAME ).getModuleSettingsPanelState( slug ) ).toBe( 'edit' );

				// If the value is edit, all other module settings panels which currently have a status of view or edit should automatically be set to locked.
				registry.dispatch( STORE_NAME ).setModuleSettingsPanelState( nonExistentModuleSlug, 'edit' );
				expect( registry.select( STORE_NAME ).getModuleSettingsPanelState( nonExistentModuleSlug ) ).toBe( 'edit' );
				expect( registry.select( STORE_NAME ).getModuleSettingsPanelState( slug ) ).toBe( 'locked' );

				// If the value is closed or view and previously the value was edit, all other module settings panels which currently have a status of locked should automatically be set to view.
				registry.dispatch( STORE_NAME ).setModuleSettingsPanelState( nonExistentModuleSlug, 'closed' );
				expect( registry.select( STORE_NAME ).getModuleSettingsPanelState( nonExistentModuleSlug ) ).toBe( 'closed' );
				expect( registry.select( STORE_NAME ).getModuleSettingsPanelState( slug ) ).toBe( 'view' );
			} );
		} );
	} );

	describe( 'actions', () => {
		describe( 'setModuleSettingsPanelState', () => {
			it( 'sets module settings panel state', () => {
				registry.dispatch( STORE_NAME ).setModuleSettingsPanelState( slug, 'closed' );
				let expectedPanelState = { ...store.getState().panelState, [ slug ]: 'closed' };
				expect( store.getState().panelState ).toEqual( expectedPanelState );

				registry.dispatch( STORE_NAME ).setModuleSettingsPanelState( slug, 'view' );
				expectedPanelState = { ...store.getState().panelState, [ slug ]: 'view' };
				expect( store.getState().panelState ).toEqual( expectedPanelState );

				registry.dispatch( STORE_NAME ).setModuleSettingsPanelState( slug, 'edit' );
				expectedPanelState = { ...store.getState().panelState, [ slug ]: 'edit' };
				expect( store.getState().panelState ).toEqual( expectedPanelState );

				expect( () => {
					registry.dispatch( STORE_NAME ).setModuleSettingsPanelState( slug, 'invalid' );
				} ).toThrow();
				// State shouldn't have changed with an invalid setting value.
				expect( store.getState().panelState ).toEqual( expectedPanelState );
			} );
		} );
	} );
} );

@@ -2135,12 +2135,27 @@
 t( '
-gets
+checks that default
  mod
@@ -2170,32 +2170,42 @@
 ings panel state
+ is closed
 ', () =%3E %7B%0A%09%09%09%09/
@@ -2203,56 +2203,8 @@
 %3E %7B%0A
-%09%09%09%09// Default state for valid module is closed%0A
 %09%09%09%09
@@ -2301,58 +2301,8 @@
  );%0A
-%09%09%09%09// Default state for invalid module is closed%0A
 %09%09%09%09
@@ -2404,25 +2404,102 @@
 Be( null );%0A
+%09%09%09%7D );%0A%09%09%09it( 'checks we can get every module settings panel state', () =%3E %7B
 %0A
-
 %09%09%09%09registry
@@ -3019,33 +3019,41 @@
 ( 'edit' );%0A
-%0A
 %09%09%09
-%09// I
+%7D );%0A%09%09%09it( 'i
 f the value 
@@ -3177,17 +3177,26 @@
 o locked
-.
+', () =%3E %7B
 %0A%09%09%09%09reg
@@ -3501,17 +3501,25 @@
  );%0A
-%0A
 %09%09%09
-%09// I
+%7D );%0A%09%09%09it( 'i
 f th
@@ -3688,16 +3688,26 @@
 to view.
+', () =%3E %7B
 %0A%09%09%09%09reg

Break up tests into individual cases.