/*-
 * ============LICENSE_START=======================================================
 * ONAP CLAMP
 * ================================================================================
 * Copyright (C) 2019 AT&T Intellectual Property. All rights
 *                             reserved.
 * ================================================================================
 * 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
 *
 * http://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.
 * ============LICENSE_END============================================
 * ===================================================================
 *
 */
import React from 'react';
import { shallow } from 'enzyme';
import LoopUI from './LoopUI';

import LoopCache from './api/LoopCache';
import LoopActionService from './api/LoopActionService';
import LoopService from './api/LoopService';

describe('Verify LoopUI', () => {
	beforeEach(() => {
		fetch.resetMocks();
		fetch.mockImplementation(() => {
			return Promise.resolve({
				ok: true,
				status: 200,
				text: () => "testUser"

			});
		});
	})

	const loopCache = new LoopCache({
		"name": "LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca",
		"components": {
			"POLICY": {
				"componentState": {
					"stateName": "UNKNOWN",
					"description": "The policies defined have NOT yet been created on the policy engine"
				}
			},
			"DCAE": {
				"componentState": {
					"stateName": "BLUEPRINT_DEPLOYED",
					"description": "The DCAE blueprint has been found in the DCAE inventory but not yet instancianted for this loop"
				}
			}
		}
	});

	it('Test the render method', async () => {
		const flushPromises = () => new Promise(setImmediate);

		const component = shallow(<LoopUI />)
		component.setState({
			loopName: "testLoopName",
			showAlert: false 
		});
		await flushPromises();
		expect(component).toMatchSnapshot();
	});

	test('Test closeLoop method', () => {
		const historyMock = { push: jest.fn() };
		const component = shallow(<LoopUI history={historyMock}/>)
		const instance = component.instance();
		instance.closeLoop();
			
		expect(component.state('loopName')).toEqual("Empty (NO loop loaded yet)");
		expect(historyMock.push.mock.calls[0]).toEqual([ '/']);
	})

	test('Test logout method', async () => {
		const flushPromises = () => new Promise(setImmediate);
		const component = shallow(<LoopUI />)
		const instance = component.instance();
		instance.logout();
		await flushPromises();
		expect(component.state('userName')).toEqual("testUser");
	})

	test('Test loadLoop method refresh suc', async () => {
		const historyMock = { push: jest.fn() };
		LoopService.getLoop = jest.fn().mockImplementation(() => {
			return Promise.resolve({
				ok: true,
				status: 200,
				text: () => {}
			});
		});

		LoopActionService.refreshStatus = jest.fn().mockImplementation(() => {
			return Promise.resolve({name: "LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca"});
		});

		const flushPromises = () => new Promise(setImmediate);
		const component = shallow(<LoopUI history={historyMock}/>)
		const instance = component.instance();
		instance.loadLoop("LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca");

		await flushPromises();

		const resLoopCache = instance.getLoopCache();
			
		expect(resLoopCache.getComponentStates()).toBeUndefined();
		expect(component.state('loopName')).toEqual("LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca");
	})

	test('Test loadLoop method refresh fail', async () => {
		const historyMock = { push: jest.fn() };
		LoopService.getLoop = jest.fn().mockImplementation(() => {
			return Promise.resolve({
			name: "LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca",
			"components": {
				"POLICY": {
					"componentState": {
						"stateName": "UNKNOWN",
						"description": "The policies defined have NOT yet been created on the policy engine"
					}
				},
				"DCAE": {
					"componentState": {
						"stateName": "BLUEPRINT_DEPLOYED",
						"description": "The DCAE blueprint has been found in the DCAE inventory but not yet instancianted for this loop"
					}
				}
			}});
		});

		LoopActionService.refreshStatus = jest.fn().mockImplementation(() => {
			return Promise.reject({error: "whatever"});
		});

		const flushPromises = () => new Promise(setImmediate);
		const component = shallow(<LoopUI history={historyMock}/>)
		const instance = component.instance();
		instance.loadLoop("LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca");

		await flushPromises();

		const resLoopCache = instance.getLoopCache();
			
		expect(resLoopCache).toEqual(loopCache);
		expect(component.state('loopName')).toEqual("LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca");
	})

	test('Test alert methods', () => {
		const component = shallow(<LoopUI />)
		expect(component.state('showAlert')).toEqual(false);

		const instance = component.instance();
		instance.showAlert("testAlert");
		expect(component.state('showAlert')).toEqual(true);
		expect(component.state('showMessage')).toEqual("testAlert");

		instance.disableAlert();
			
		expect(component.state('showAlert')).toEqual(false);
	})
});
