From 31c314b71585e6f673783f58f4df6f62e1c4596f Mon Sep 17 00:00:00 2001
From: Jaden Diefenbaugh <jaden.diefenbaugh@idiap.ch>
Date: Mon, 8 Oct 2018 11:11:29 -0700
Subject: [PATCH] [js][tc] reset blocks sync channel when it has no conns to
 it, #120

---
 .../components/toolchain/ToolchainEditor.jsx  | 27 ++++++++++++----
 .../toolchain/ToolchainEditor.spec.jsx        | 32 +++++++++++++++++++
 2 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/conda/js/src/components/toolchain/ToolchainEditor.jsx b/conda/js/src/components/toolchain/ToolchainEditor.jsx
index 991b6830..2d6c9cfb 100644
--- a/conda/js/src/components/toolchain/ToolchainEditor.jsx
+++ b/conda/js/src/components/toolchain/ToolchainEditor.jsx
@@ -39,7 +39,7 @@ import * as Selectors from '@store/selectors.js';
 import type { FlattenedDatabaseEntry } from '@store/selectors';
 
 import Block from './ToolchainBlock.jsx';
-import type { BlockType, ConnectionType, BlockSet, Group, Contents } from '@helpers/toolchainTypes';
+import type { NormalBlock, AnalyzerBlock, BlockType, ConnectionType, BlockSet, Group, Contents } from '@helpers/toolchainTypes';
 import { connectionToId } from './ToolchainConnection.jsx';
 import ValidSchemaBadge from '../ValidSchemaBadge.jsx';
 import CacheInput from '../CacheInput.jsx';
@@ -653,12 +653,27 @@ export class ToolchainEditor extends React.PureComponent<Props, State> {
 		.reduce((cs, [name, rep]) => ({...cs, [name]: rep}), {})
 		;
 
+		const newConns = this.props.data.contents.connections.filter(c => {
+			if(c.from === cn.from && c.to === cn.to)
+				return false;
+			return true;
+		});
+
+		// if the given block has no conns to it, the syncd channel should become ''
+		const removeInvalidChannels = (b: NormalBlock | AnalyzerBlock): NormalBlock | AnalyzerBlock => {
+			if(newConns.find(c => c.to.split('.')[0] == b.name))
+				return b;
+
+			return {
+				...b,
+				synchronized_channel: '',
+			};
+		};
+
 		const newContents = {
-			connections: this.props.data.contents.connections.filter(c => {
-				if(c.from === cn.from && c.to === cn.to)
-					return false;
-				return true;
-			}),
+			connections: newConns,
+			blocks: this.props.data.contents.blocks.map(b => removeInvalidChannels(b)),
+			analyzers: this.props.data.contents.analyzers.map(b => removeInvalidChannels(b)),
 			representation: rep,
 		};
 
diff --git a/conda/js/src/components/toolchain/ToolchainEditor.spec.jsx b/conda/js/src/components/toolchain/ToolchainEditor.spec.jsx
index 6291a71a..6c3dbf5f 100644
--- a/conda/js/src/components/toolchain/ToolchainEditor.spec.jsx
+++ b/conda/js/src/components/toolchain/ToolchainEditor.spec.jsx
@@ -1028,5 +1028,37 @@ describe('<ToolchainEditor />', function() {
 			expect(data.contents.representation.connections).to.not.have.property('training_data.species/training_data.species');
 			expect(data.contents.connections.findIndex(c => c.from == conToDel.from && c.to == conToDel.to)).to.equal(-1);
 		});
+
+		it('Properly deletes conns between training_data & training_alg, and clears training_alg sync channel', async () => {
+			const conToDel = { from: 'training_data.species', to: 'training_alg.species', channel: 'training_data' };
+			const conToDel2 = { from: 'training_data.measurements', to: 'training_alg.measurements', channel: 'training_data' };
+			const tc = getValidObj(getIrisTc());
+			wrapper = mount(
+				<C
+					data={tc}
+					sets={sets}
+					protocols={protocols}
+					toolchains={state.toolchain}
+					databases={state.database}
+					normalAlgorithms={normalAlgorithms}
+					analyzerAlgorithms={analyzerAlgorithms}
+					saveFunc={saveFunc}
+					updateFunc={updateFunc}
+				/>
+			);
+
+			// change testing_alg.lda_machine to testing_alg.lda
+			expect(wrapper.exists('#training_data-species-training_alg-species')).to.equal(true);
+			expect(wrapper.exists('#training_data-measurements-training_alg-measurements')).to.equal(true);
+			wrapper.instance().handleConnectionContextMenu({}, { clicked: 'delete', connection: conToDel });
+			wrapper.update();
+			wrapper.instance().handleConnectionContextMenu({}, { clicked: 'delete', connection: conToDel2 });
+			wrapper.update();
+			expect(wrapper.exists('#training_data-species-training_alg-species')).to.equal(false);
+			expect(wrapper.exists('#training_data-measurements-training_alg-measurements')).to.equal(false);
+
+			const data = wrapper.props().data;
+			expect(data.contents.blocks.find(b => b.name == 'training_alg')).to.have.property('synchronized_channel', '');
+		});
 	});
 });
-- 
GitLab