/*
 * Copyright © 2016-2018 European Support Limited
 *
 * 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.
 */

import GlobalModal, {GlobalModalView, mapStateToProps} from 'src/nfvo-components/modal/GlobalModal.js';
import React from 'react';
import ShallowRenderer from 'react-test-renderer/shallow';
import store from 'sdc-app/AppStore.js';
import {actionTypes, typeEnum} from 'src/nfvo-components/modal/GlobalModalConstants.js';

const title = 'TITLE';
const msg = 'message';

describe('Global Modal tests: ', function () {
	it (' mapStateToProps exists', function () {
		expect(mapStateToProps).toBeTruthy();
	});

	it ('mapStateToProps should return show as true', () => {
		let state = {
			modal: {
				type: ''
			}
		};
		let props = mapStateToProps(state);
		expect(props.show).toEqual(true);
	});

	it('modal should show with default values', () => {
		store.dispatch({
			type: actionTypes.GLOBAL_MODAL_SHOW,
			data: {
				title,
				msg
			}
		});
		const modal = store.getState().modal;
		expect(modal).toBeTruthy();
		expect(modal.title).toBe(title);
		expect(modal.msg).toBe(msg);
	});

	it('global modal should show with type success with connected component', () => {
		store.dispatch({type: actionTypes.GLOBAL_MODAL_SHOW, data: {title, msg}});

		expect(store.getState().modal).toBeTruthy();

		const renderer = new ShallowRenderer();
		renderer.render(<GlobalModal store={store}/>);
		let renderedOutput = renderer.getRenderOutput();
		expect(renderedOutput).toBeTruthy();

	});


	it('global modal should show with type success with connected component and closed after', () => {
		store.dispatch({type: actionTypes.GLOBAL_MODAL_SHOW, data: {title, msg}});

		expect(store.getState().modal).toBeTruthy();
		const renderer = new ShallowRenderer();
		renderer.render(<GlobalModal store={store}/>);
		let renderedOutput = renderer.getRenderOutput();
		expect(renderedOutput).toBeTruthy();

		store.dispatch({type: actionTypes.GLOBAL_MODAL_CLOSE});
		expect(store.getState().modal).toBe(null);
	});


	it('checking component default render', ()=> {
		expect(window.document).toBeTruthy();
		const renderer = new ShallowRenderer();
		renderer.render(<GlobalModalView show={true} type={typeEnum.WARNING} title={title} msg={msg} onDeclined={()=>{}} />);
		const globalModalView = renderer.getRenderOutput();
		expect(globalModalView).toBeTruthy();
});

});

