/*
 * Copyright © 2016-2017 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 React from 'react';
import ShallowRenderer from 'react-test-renderer/shallow';
import {mapStateToProps } from 'sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js';
import LicenseModelCreationView from 'sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx';
import {LicenseModelCreationFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js';

describe('License Model Creation Module Tests', function() {
	it ('mapStateToProps mapper exists', () => {
		expect(mapStateToProps).toBeTruthy();
	});

	it ('should return empty data', () => {
		let state = {
			licenseModelList: [],
			licenseModel: {
				licenseModelCreation: {
					data: {}
				}
			},
			users: {
				usersList: []
			}
		};
		let props = mapStateToProps(state);
		expect(props.data).toEqual({});
	});

	it ('should return vlm names list', () => {
		let state = {
			licenseModelList: [{
				name: 'vlm1',
				id: 'vlm1_id'
			}, {
				name: 'vlm2',
				id: 'vlm2_id'
			}],
			licenseModel: {
				licenseModelCreation: {
					data: {}
				}
			},
			users: {
				usersList: []
			}
		};
		let props = mapStateToProps(state);
		expect(props.data).toEqual({});
		expect(props.VLMNames).toEqual({vlm1: 'vlm1_id', vlm2: 'vlm2_id'});
	});

	it('simple jsx test', () => {
		let data = LicenseModelCreationFactory.build();
		const renderer = new ShallowRenderer();
		renderer.render(
			<LicenseModelCreationView
				data={data}
				onDataChanged={() => {}}
				onValidateForm={() => {}}
				onSubmit={() => {}}
				onCancel={() => {}}/>
			);
		var renderedOutput = renderer.getRenderOutput();
		expect(renderedOutput).toBeTruthy();
	});
});
