// @flow
import React from 'react';
import { expect } from 'chai';
import { mount } from 'enzyme';
import sinon from 'sinon';
import { spies } from '@test';

import { AlgorithmEditor as C } from '.';
import {  getValidAlgorithmObj as getValidObj } from '@helpers/beat';

import testAlgs from '@test/test_algs.json';
import testDfs from '@test/test_dfs.json';
import testLibs from '@test/test_libs.json';

const libs = [];
const dfs = [];

describe('<AlgorithmEditor />', () => {
	let wrapper;

	afterEach(() => {
		if(wrapper && wrapper.unmount)
			wrapper.unmount();
	});

	const aTestAlg = {
		name: 'test/non-analyzer-alg/1',
		contents: {
			language: 'python',
			description: 'A basic algorithm as a sanity test for the AlgorithmEditor',
			groups: [
				{
					name: 'group_1',
					inputs: {
						'input_1': { type: 'test/df/1' },
					},
					outputs: {
						'output_1': { type: 'test/df/2' },
					},
				}
			],
			uses: {
				'library_1': 'a/lib/1',
			},
			parameters: {
				'parameter_1': {
					type: 'string',
					choice: [
						'choice_1',
						'choice_2',
						'choice_3',
					],
					default: 'choice_1',
				}
			},
			// non-analyzer
			splittable: false,
			schema_version: 3.0,
			api_version: 2.0,
			type: 'sequential',
		}

	};

	describe('accepts', () => {
		const algs = [
			aTestAlg,
		].concat(testAlgs.map(a => getValidObj(a)));

		algs.forEach(function(alg){
			const saveFunc = () => {};
			const updateFunc = () => {};
			it(`${ alg.name }`, () => {
				wrapper = mount(
					<C
						data={getValidObj(alg)}
						algorithms={algs}
						dataformats={dfs}
						libraries={libs}
						saveFunc={saveFunc}
						updateFunc={updateFunc}
					/>
				);

				expect(wrapper).to.have.props(
					['data', 'algorithms', 'dataformats', 'libraries', 'saveFunc', 'updateFunc']
				).deep.equal(
					[alg, algs, dfs, libs, saveFunc, updateFunc]
				);
			});
		});
	});

	describe('creates', () => {
		it('user/integers_echo/1', () => {
			const saveFunc = sinon.spy();
			const _updateFunc = (obj) => {
				wrapper.setProps && wrapper.setProps({ data: obj });
			};
			const updateFunc = sinon.spy(_updateFunc);
			const algName = 'user/integers_echo/1';
			wrapper = mount(
				<C
					data={getValidObj({name: algName, contents: {}})}
					algorithms={[]}
					dataformats={testDfs}
					libraries={testLibs}
					saveFunc={saveFunc}
					updateFunc={updateFunc}
				/>
			);

			expect(wrapper).to.have.props(
				['data', 'algorithms', 'dataformats', 'libraries', 'saveFunc', 'updateFunc']
			);

			expect(wrapper.props().data).to.have.property('name', algName);

			wrapper.find('#algSplittable input').prop('onChange')( { target: { checked: true }});
			expect(updateFunc.callCount).to.equal(1);
			expect(wrapper.props().data.contents).to.have.property('splittable', true);

			expect(updateFunc.callCount).to.equal(1);
			expect(wrapper.props().data.contents).to.have.property('groups').with.lengthOf(1);
			expect(wrapper.props().data.contents.groups[0]).to.have.property('inputs');
			expect(wrapper.props().data.contents.groups[0]).to.have.property('outputs');

			expect(wrapper.props().data.contents.groups[0]).to.have.property('name', 'group');

			wrapper.find('.algInput').find('CacheInput').prop('onChange')( { target: { value: 'in_data' }});
			expect(updateFunc.callCount).to.equal(2);
			wrapper.find('.algOutput').find('CacheInput').prop('onChange')( { target: { value: 'out_data' }});
			expect(updateFunc.callCount).to.equal(3);

			const ioType = 'system/integer/1';
			wrapper.find('.algInput select').prop('onChange')( { target: { value: ioType }});
			expect(updateFunc.callCount).to.equal(4);
			wrapper.find('.algOutput select').prop('onChange')( { target: { value: ioType }});
			expect(updateFunc.callCount).to.equal(5);

			expect(wrapper.props().data.contents.groups[0].inputs).to.have.deep.property('in_data', { type: ioType });
			expect(wrapper.props().data.contents.groups[0].outputs).to.have.deep.property('out_data', { type: ioType });

			expect(wrapper.props().data.contents).to.deep.equal({
				description: '',
				'groups': [
					{
						'inputs': {
							'in_data': {
								'type': 'system/integer/1'
							}
						},
						'name': 'group',
						'outputs': {
							'out_data': {
								'type': 'system/integer/1'
							}
						}
					}
				],
				parameters: {},
				uses: {},
				'splittable': true,
				'language': 'python',
				schema_version: 3.0,
				api_version: 2.0,
				type: 'sequential',
			});
		});

		it('user/integers_add/1', () => {
			const saveFunc = sinon.spy();
			const _updateFunc = (obj) => {
				wrapper.setProps && wrapper.setProps({ data: obj });
			};
			const updateFunc = sinon.spy(_updateFunc);
			const algName = 'user/integers_add/1';
			wrapper = mount(
				<C
					data={getValidObj({name: algName, contents: {}})}
					algorithms={[]}
					dataformats={testDfs}
					libraries={testLibs}
					saveFunc={saveFunc}
					updateFunc={updateFunc}
				/>
			);

			expect(wrapper).to.have.props(
				['data', 'algorithms', 'dataformats', 'libraries', 'saveFunc', 'updateFunc']
			);

			expect(wrapper.props().data).to.have.property('name', algName);

			wrapper.find('#algSplittable input').prop('onChange')( { target: { checked: true }});
			expect(wrapper.props().data.contents).to.have.property('splittable', true);

			expect(wrapper.props().data.contents).to.have.property('groups').with.lengthOf(1);
			expect(wrapper.props().data.contents.groups[0]).to.have.property('inputs');
			expect(wrapper.props().data.contents.groups[0]).to.have.property('outputs');

			expect(wrapper.props().data.contents.groups[0]).to.have.property('name', 'group');

			wrapper.find('.algInput').find('CacheInput').prop('onChange')( { target: { value: 'in_data' }});
			wrapper.find('.algOutput').find('CacheInput').prop('onChange')( { target: { value: 'out_data' }});

			const ioType = 'system/integer/1';
			wrapper.find('.algInput select').prop('onChange')( { target: { value: ioType }});
			wrapper.find('.algOutput select').prop('onChange')( { target: { value: ioType }});

			expect(wrapper.props().data.contents.groups[0].inputs).to.have.deep.property('in_data', { type: ioType });
			expect(wrapper.props().data.contents.groups[0].outputs).to.have.deep.property('out_data', { type: ioType });

			wrapper.find('a')
			.findWhere(w => {
				const html = w.html();
				return html && html.includes('Parameters');
			})
			.at(0)
			.simulate('click');

			wrapper.find('button#newParameterBtn').simulate('click');

			wrapper.find('CacheInput[placeholder="Parameter name..."]').prop('onChange')( { target: { value: 'offset' }});
			wrapper.find('[tabId="1"] select').prop('onChange')( { target: { value: 'int32' }});
			wrapper.find('input[placeholder="Default"]').simulate('change', { target: { value: '1' }});

			expect(wrapper.props().data.contents.parameters).to.have.deep.property('offset', {
				'default': '1',
				'type': 'int32',
				'description': '',
			});

			wrapper.find('a')
			.findWhere(w => {
				const html = w.html();
				return html && html.includes('Libraries');
			})
			.at(0)
			.simulate('click');

			wrapper.find('button#newLibraryBtn').simulate('click');

			wrapper.find('[tabId="2"] CacheInput[type="text"]').prop('onChange')( { target: { value: 'lib' }});
			wrapper.find('[tabId="2"] select').prop('onChange')( { target: { value: 'user/thelib/1' }});

			expect(wrapper.props().data.contents.uses).to.have.property('lib', 'user/thelib/1');

			expect(wrapper.props().data.contents).to.deep.equal({
				description: '',
				'groups': [
					{
						'inputs': {
							'in_data': {
								'type': 'system/integer/1'
							}
						},
						'name': 'group',
						'outputs': {
							'out_data': {
								'type': 'system/integer/1'
							}
						}
					}
				],
				'parameters': {
					'offset': {
						'default': '1',
						'type': 'int32',
						description: '',
					}
				},
				'uses': {
					'lib': 'user/thelib/1'
				},
				'splittable': true,
				'language': 'python',
				schema_version: 3.0,
				api_version: 2.0,
				type: 'sequential',
			});
		});

		it('user/integers_echo_analyzer/1', () => {
			const saveFunc = sinon.spy();
			const _updateFunc = (obj) => {
				wrapper.setProps && wrapper.setProps({ data: obj });
			};
			const updateFunc = sinon.spy(_updateFunc);
			const algName = 'user/integer_echo_analyzer/1';
			wrapper = mount(
				<C
					data={getValidObj({name: algName, contents: {}})}
					algorithms={[]}
					dataformats={testDfs}
					libraries={testLibs}
					saveFunc={saveFunc}
					updateFunc={updateFunc}
				/>
			);

			expect(wrapper).to.have.props(
				['data', 'algorithms', 'dataformats', 'libraries', 'saveFunc', 'updateFunc']
			);

			expect(wrapper.props().data).to.have.property('name', algName);

			wrapper.find('#algAnalyzer input').prop('onChange')( { target: { checked: true }});
			expect(wrapper.props().data.contents).to.have.property('results');

			expect(wrapper.props().data.contents).to.have.property('groups').with.lengthOf(1);
			expect(wrapper.props().data.contents.groups[0]).to.have.property('inputs');
			expect(wrapper.props().data.contents.groups[0]).to.not.have.property('outputs');

			expect(wrapper.props().data.contents.groups[0]).to.have.property('name', 'group');

			wrapper.find('.algInput').find('CacheInput').prop('onChange')( { target: { value: 'in_data' }});

			const ioType = 'system/integer/1';
			wrapper.find('.algInput select').prop('onChange')( { target: { value: ioType }});

			expect(wrapper.props().data.contents.groups[0].inputs).to.have.deep.property('in_data', { type: ioType });

			wrapper.find('a')
			.findWhere(w => {
				const html = w.html();
				return html && html.includes('Results');
			})
			.at(0)
			.simulate('click');

			wrapper.find('button#newResultBtn').simulate('click');
			wrapper.find('button#newResultBtn').simulate('click');
			wrapper.find('button#newResultBtn').simulate('click');
			wrapper.find('button#newResultBtn').simulate('click');

			wrapper.find('[tabId="3"] CacheInput[type="text"]').at(0).prop('onChange')( { target: { value: 'roc' }});
			wrapper.find('[tabId="3"] select').at(0).prop('onChange')( { target: { value: 'plot/isoroc/1' }});

			wrapper.find('[tabId="3"] CacheInput[type="text"]').at(1).prop('onChange')( { target: { value: 'plot' }});
			wrapper.find('[tabId="3"] select').at(1).prop('onChange')( { target: { value: 'plot/scatter/1' }});

			wrapper.find('[tabId="3"] CacheInput[type="text"]').at(2).prop('onChange')( { target: { value: 'out_data' }});
			wrapper.find('[tabId="3"] select').at(2).prop('onChange')( { target: { value: 'int32' }});

			wrapper.find('[tabId="3"] CacheInput[type="text"]').at(3).prop('onChange')( { target: { value: 'bar_plot' }});
			wrapper.find('[tabId="3"] select').at(3).prop('onChange')( { target: { value: 'plot/bar/1' }});

			expect(wrapper.props().data.contents.results).to.deep.equal({
				'roc': {
					'type': 'plot/isoroc/1',
					'display': false
				},
				'plot': {
					'type': 'plot/scatter/1',
					'display': false
				},
				'out_data': {
					'type': 'int32',
					'display': false
				},
				'bar_plot': {
					'type': 'plot/bar/1',
					'display': false
				}
			});

			expect(wrapper.props().data.contents).to.deep.equal({
				description: '',
				'groups': [
					{
						'inputs': {
							'in_data': {
								'type': 'system/integer/1'
							}
						},
						'name': 'group'
					}
				],
				parameters: {},
				uses: {},
				'language': 'python',
				'results': {
					'roc': {
						'type': 'plot/isoroc/1',
						'display': false
					},
					'plot': {
						'type': 'plot/scatter/1',
						'display': false
					},
					'out_data': {
						'type': 'int32',
						'display': false
					},
					'bar_plot': {
						'type': 'plot/bar/1',
						'display': false
					}
				},
				schema_version: 3.0,
				api_version: 2.0,
				type: 'sequential',
			});
		});

		it('user/integers_echo_ignore/1', () => {
			const saveFunc = sinon.spy();
			const _updateFunc = (obj) => {
				wrapper.setProps && wrapper.setProps({ data: obj });
			};
			const updateFunc = sinon.spy(_updateFunc);
			const algName = 'user/integers_echo/1';
			wrapper = mount(
				<C
					data={getValidObj({name: algName, contents: {}})}
					algorithms={[]}
					dataformats={testDfs}
					libraries={testLibs}
					saveFunc={saveFunc}
					updateFunc={updateFunc}
				/>
			);

			expect(wrapper).to.have.props(
				['data', 'algorithms', 'dataformats', 'libraries', 'saveFunc', 'updateFunc']
			);

			expect(wrapper.props().data).to.have.property('name', algName);

			wrapper.find('#algSplittable input').prop('onChange')( { target: { checked: true }});
			expect(wrapper.props().data.contents).to.have.property('splittable', true);

			wrapper.find('button#newGroupBtn').simulate('click');

			expect(wrapper.props().data.contents).to.have.property('groups').with.lengthOf(2);
			expect(wrapper.props().data.contents.groups[0]).to.have.property('inputs');
			expect(wrapper.props().data.contents.groups[0]).to.have.property('outputs');
			expect(wrapper.props().data.contents.groups[1]).to.have.property('inputs');
			expect(wrapper.props().data.contents.groups[1]).to.not.have.property('outputs');

			// Group 1
			expect(wrapper.props().data.contents.groups[0]).to.have.property('name', 'group');

			wrapper.find('#endpoint0 .algInput').find('CacheInput').prop('onChange')( { target: { value: 'in_data' }});
			wrapper.find('#endpoint0 .algOutput').find('CacheInput').prop('onChange')( { target: { value: 'out_data' }});

			const ioType = 'system/integer/1';
			wrapper.find('#endpoint0 .algInput select').prop('onChange')( { target: { value: ioType }});
			wrapper.find('#endpoint0 .algOutput select').prop('onChange')( { target: { value: ioType }});

			expect(wrapper.props().data.contents.groups[0].inputs).to.have.deep.property('in_data', { type: ioType });
			expect(wrapper.props().data.contents.groups[0].outputs).to.have.deep.property('out_data', { type: ioType });

			// Group 2
			expect(wrapper.props().data.contents.groups[1]).to.have.property('name', 'group0');

			wrapper.find('#endpoint1 button#newInputBtn').simulate('click');

			wrapper.find('#endpoint1 .algInput').find('CacheInput').prop('onChange')( { target: { value: 'in_data2' }});
			wrapper.find('#endpoint1 .algInput select').prop('onChange')( { target: { value: ioType }});
			expect(wrapper.props().data.contents.groups[1].inputs).to.have.deep.property('in_data2', { type: ioType });

			expect(wrapper.props().data.contents).to.be.deep.equal({
				description: '',
				'groups': [
					{
						'inputs': {
							'in_data': {
								'type': 'system/integer/1'
							}
						},
						'name': 'group',
						'outputs': {
							'out_data': {
								'type': 'system/integer/1'
							}
						}
					},
					{
						'inputs': {
							'in_data2': {
								'type': 'system/integer/1'
							}
						},
						'name': 'group0'
					}
				],
				parameters: {},
				uses: {},
				'splittable': true,
				'language': 'python',
				schema_version: 3.0,
				api_version: 2.0,
				type: 'sequential',
			});
		});

		it('system/integers_echo_sleep/1', () => {
			const saveFunc = sinon.spy();
			const _updateFunc = (obj) => {
				wrapper.setProps && wrapper.setProps({ data: obj });
			};
			const updateFunc = sinon.spy(_updateFunc);
			const algName = 'user/integers_echo_sleep/1';
			wrapper = mount(
				<C
					data={getValidObj({name: algName, contents: {}})}
					algorithms={[]}
					dataformats={testDfs}
					libraries={testLibs}
					saveFunc={saveFunc}
					updateFunc={updateFunc}
				/>
			);

			expect(wrapper).to.have.props(
				['data', 'algorithms', 'dataformats', 'libraries', 'saveFunc', 'updateFunc']
			);

			expect(wrapper.props().data).to.have.property('name', algName);

			wrapper.find('#algSplittable input').prop('onChange')( { target: { checked: true }});
			expect(wrapper.props().data.contents).to.have.property('splittable', true);

			expect(wrapper.props().data.contents).to.have.property('groups').with.lengthOf(1);
			expect(wrapper.props().data.contents.groups[0]).to.have.property('inputs');
			expect(wrapper.props().data.contents.groups[0]).to.have.property('outputs');

			expect(wrapper.props().data.contents.groups[0]).to.have.property('name', 'group');

			wrapper.find('.algInput').find('CacheInput').prop('onChange')( { target: { value: 'in_data' }});
			wrapper.find('.algOutput').find('CacheInput').prop('onChange')( { target: { value: 'out_data' }});

			const ioType = 'system/integer/1';
			wrapper.find('.algInput select').prop('onChange')( { target: { value: ioType }});
			wrapper.find('.algOutput select').prop('onChange')( { target: { value: ioType }});

			expect(wrapper.props().data.contents.groups[0].inputs).to.have.deep.property('in_data', { type: ioType });
			expect(wrapper.props().data.contents.groups[0].outputs).to.have.deep.property('out_data', { type: ioType });

			wrapper.find('a')
			.findWhere(w => {
				const html = w.html();
				return html && html.includes('Parameters');
			})
			.at(0)
			.simulate('click');

			wrapper.find('button#newParameterBtn').simulate('click');

			wrapper.find('CacheInput[placeholder="Parameter name..."]').prop('onChange')( { target: { value: 'delay' }});
			wrapper.find('[tabId="1"] select').prop('onChange')( { target: { value: 'uint32' }});
			wrapper.find('input[placeholder="Default"]').simulate('change', { target: { value: '30' }});
			wrapper.find('input[placeholder="Description"]').simulate('change', { target: { value: 'Time to sleep in seconds' }});

			expect(wrapper.props().data.contents.parameters).to.have.deep.property('delay', {
				'default': '30',
				'type': 'uint32',
				'description': 'Time to sleep in seconds',
			});

			expect(wrapper.props().data.contents).to.be.deep.equal({
				description: '',
				uses: {},
				'language': 'python',
				'splittable': true,
				'groups': [
					{
						'name': 'group',
						'inputs': {
							'in_data': {
								'type': 'system/integer/1'
							}
						},
						'outputs': {
							'out_data': {
								'type': 'system/integer/1'
							}
						}
					}
				],
				'parameters': {
					'delay': {
						'default': '30',
						'type': 'uint32',
						'description': 'Time to sleep in seconds'
					}
				},
				schema_version: 3.0,
				api_version: 2.0,
				type: 'sequential',
			});
		});

		it('user/integers_mean_analyzer/1', () => {
			const saveFunc = sinon.spy();
			const _updateFunc = (obj) => {
				wrapper.setProps && wrapper.setProps({ data: obj });
			};
			const updateFunc = sinon.spy(_updateFunc);
			const algName = 'user/integers_mean_analyzer/1';
			wrapper = mount(
				<C
					data={getValidObj({name: algName, contents: {}})}
					algorithms={[]}
					dataformats={testDfs}
					libraries={testLibs}
					saveFunc={saveFunc}
					updateFunc={updateFunc}
				/>
			);

			expect(wrapper).to.have.props(
				['data', 'algorithms', 'dataformats', 'libraries', 'saveFunc', 'updateFunc']
			);

			expect(wrapper.props().data).to.have.property('name', algName);

			wrapper.find('#algAnalyzer input').prop('onChange')( { target: { checked: true }});
			expect(wrapper.props().data.contents).to.have.property('results');

			expect(wrapper.props().data.contents).to.have.property('groups').with.lengthOf(1);
			expect(wrapper.props().data.contents.groups[0]).to.have.property('inputs');
			expect(wrapper.props().data.contents.groups[0]).to.not.have.property('outputs');

			expect(wrapper.props().data.contents.groups[0]).to.have.property('name', 'group');

			wrapper.find('.algInput').find('CacheInput').prop('onChange')( { target: { value: 'in_data' }});

			const ioType = 'system/integer/1';
			wrapper.find('.algInput select').prop('onChange')( { target: { value: ioType }});

			expect(wrapper.props().data.contents.groups[0].inputs).to.have.deep.property('in_data', { type: ioType });

			wrapper.find('a')
			.findWhere(w => {
				const html = w.html();
				return html && html.includes('Results');
			})
			.at(0)
			.simulate('click');

			wrapper.find('button#newResultBtn').simulate('click');
			wrapper.find('button#newResultBtn').simulate('click');

			wrapper.find('[tabId="3"] CacheInput[type="text"]').at(0).prop('onChange')( { target: { value: 'plot' }});
			wrapper.find('[tabId="3"] select').at(0).prop('onChange')( { target: { value: 'plot/scatter/1' }});

			wrapper.find('[tabId="3"] CacheInput[type="text"]').at(1).prop('onChange')( { target: { value: 'out_data' }});
			wrapper.find('[tabId="3"] select').at(1).prop('onChange')( { target: { value: 'float32' }});

			expect(wrapper.props().data.contents.results).to.deep.equal({
				'plot': {
					'type': 'plot/scatter/1',
					'display': false,
				},
				'out_data': {
					'type': 'float32',
					'display': false
				},
			});

			expect(wrapper.props().data.contents).to.deep.equal({
				description: '',
				uses: {},
				parameters: {},
				'language': 'python',
				'groups': [
					{
						name: 'group',
						'inputs': {
							'in_data': {
								'type': 'system/integer/1'
							}
						}
					}
				],
				'results': {
					'out_data': {
						'type': 'float32',
						'display': false
					},
					'plot': {
						'type': 'plot/scatter/1',
						'display': false
					}
				},
				schema_version: 3.0,
				api_version: 2.0,
				type: 'sequential',
			});
		});
	});

	describe('regression', () => {
		it(`adds an output and removes results when toggling from analyzer to normal`, () => {
			const contents = {
				description: '',
				uses: {},
				parameters: {},
				'language': 'python',
				'groups': [
					{
						name: 'group',
						'inputs': {
							'in_data': {
								'type': 'system/integer/1'
							}
						}
					}
				],
				'results': {
					'out_data': {
						'type': 'float32',
						'display': false
					},
					'plot': {
						'type': 'plot/scatter/1',
						'display': false
					}
				}
			};
			const saveFunc = sinon.spy();
			const _updateFunc = (obj) => {
				wrapper.setProps && wrapper.setProps({ data: obj });
			};
			const updateFunc = sinon.spy(_updateFunc);
			const algName = 'user/integers_mean_analyzer/1';
			const obj = {
				name: algName,
				contents,
			};
			wrapper = mount(
				<C
					data={getValidObj(obj)}
					algorithms={[]}
					dataformats={testDfs}
					libraries={testLibs}
					saveFunc={saveFunc}
					updateFunc={updateFunc}
				/>
			);

			expect(wrapper).to.have.props(
				['data', 'algorithms', 'dataformats', 'libraries', 'saveFunc', 'updateFunc']
			);

			expect(wrapper.props().data).to.have.property('name', algName);

			wrapper.find('#algAnalyzer input').prop('onChange')( { target: { checked: false }});
			expect(wrapper.props().data.contents).to.not.have.property('results');

			expect(wrapper.props().data.contents).to.have.property('groups').with.lengthOf(1);
			expect(wrapper.props().data.contents.groups[0]).to.have.property('inputs');
			expect(wrapper.props().data.contents.groups[0]).to.have.property('outputs');
			expect(wrapper.props().data.contents.groups[0].outputs).to.have.deep.property('output', {
				type: ''
			});
		});

		it(`properly sets schema_version, api_version, and "type"`, () => {
			const saveFunc = sinon.spy();
			const _updateFunc = (obj) => {
				wrapper.setProps && wrapper.setProps({ data: obj });
			};
			const updateFunc = sinon.spy(_updateFunc);
			const algName = aTestAlg.name;
			wrapper = mount(
				<C
					data={aTestAlg}
					algorithms={[]}
					dataformats={testDfs}
					libraries={testLibs}
					saveFunc={saveFunc}
					updateFunc={updateFunc}
				/>
			);

			wrapper.find('Input[type="select"]#schemaversion').prop('onChange')({ target: { value: 2.0 }});
			wrapper.find('Input[type="select"]#algtype').prop('onChange')({ target: { value: 'autonomous' }});

			expect(wrapper.props().data.contents.schema_version).to.equal(2.0);
			expect(wrapper.props().data.contents.type).to.equal('autonomous');
			expect(wrapper.props().data.contents).to.deep.equal({
				...aTestAlg.contents,
				schema_version: 2.0,
				type: 'autonomous',
			});

			expect(wrapper.find('.badge-success').exists());
		});

		it.only(`limits parameter types to simple, non-complex types`, () => {
			const saveFunc = sinon.spy();
			const _updateFunc = (obj) => {
				wrapper.setProps && wrapper.setProps({ data: obj });
			};
			const updateFunc = sinon.spy(_updateFunc);
			const algName = aTestAlg.name;
			wrapper = mount(
				<C
					data={aTestAlg}
					algorithms={[]}
					dataformats={testDfs}
					libraries={testLibs}
					saveFunc={saveFunc}
					updateFunc={updateFunc}
				/>
			);

			wrapper.find('a')
			.findWhere(w => {
				const html = w.html();
				return html && html.includes('Parameters');
			})
			.at(0)
			.simulate('click');

			const typeSelect = wrapper.find('ParameterCreate select.custom-select');
			const typeOptions = [
				<option>Type...</option>,
				<option value="int8">int8</option>,
				<option value="int16">int16</option>,
				<option value="int32">int32</option>,
				<option value="int64">int64</option>,
				<option value="uint8">uint8</option>,
				<option value="uint16">uint16</option>,
				<option value="uint32">uint32</option>,
				<option value="uint64">uint64</option>,
				<option value="float32">float32</option>,
				<option value="float64">float64</option>,
				<option value="bool">bool</option>,
				<option value="string">string</option>,
			];
			expect(typeSelect.children()).to.have.lengthOf(typeOptions.length);
			expect(typeSelect.containsAllMatchingElements(typeOptions)).to.equal(true);
		});
	});
});
