diff --git a/src/views/Graph.vue b/src/views/Graph.vue
index 8d3c012d8..1bfb45323 100644
--- a/src/views/Graph.vue
+++ b/src/views/Graph.vue
@@ -622,17 +622,6 @@ export default {
})
return nodesFiltered
},
- checkForNode (nodeName, cyclePoint, nodes) {
- // checks the 'edges' array to see if edge is present
- const nodePath = this.workflowIDs[0]
- const nodeId = `${nodePath}//${cyclePoint}/${nodeName}`
- const nodeSearch = nodes.find((node) => { return node.id === nodeId })
- if (nodeSearch === -1) {
- return null
- } else {
- return nodeSearch
- }
- },
createEdge (edgeType, sourceName, targetName, sourceCyclePoint, targetCyclePoint) {
// adds a new edge object to 'edges' array
const edgePath = this.workflowIDs[0]
@@ -722,20 +711,6 @@ export default {
})
return edgesFiltered
},
- checkForEdge (sourceName, targetName, cyclePoint, edges) {
- const edgePath = this.workflowIDs[0]
- const edgeSearchTerm = `${edgePath}//$edge|${cyclePoint}/${sourceName}|${cyclePoint}/${targetName}`
-
- const edgeSearch = edges.filter((edge) => {
- const stringSearch = edge.id.indexOf(edgeSearchTerm)
- if (stringSearch === -1) {
- return false
- } else {
- return true
- }
- })
- return edgeSearch
- },
checkForEdgeBySource (sourceName, cyclePoint, edges) {
const edgePath = this.workflowIDs[0]
const edgeSearchTerm = `${edgePath}//${cyclePoint}/${sourceName}`
@@ -915,11 +890,6 @@ export default {
return x
}, {})
},
- getNodeByFamilyAndCycle (family, cycle) {
- Object.values(this.cylcTree.$index).find((node) => {
- return node.name === family && node.tokens.cycle === cycle
- })
- },
addSubgraph (dotcode, pointer, graphSections) {
pointer.children.forEach((key, i) => {
const value = key
diff --git a/tests/unit/views/graphv2utils.js b/tests/unit/views/graph-utils.js
similarity index 51%
rename from tests/unit/views/graphv2utils.js
rename to tests/unit/views/graph-utils.js
index c7d6ad377..ee1d362b7 100644
--- a/tests/unit/views/graphv2utils.js
+++ b/tests/unit/views/graph-utils.js
@@ -1,17 +1,19 @@
import { Tokens } from '@/utils/uid'
-const nodeSuceeded =
+const nodeSucceeded =
{
- id: 'user/one/run1//1/succeeded',
+ id: 'user/one/run1//2/succeeded',
name: 'succeeded',
node: {
+ name: 'succeeded',
firstParent: {
- id: 'user/one/run1//1/SUCCEEDED'
+ id: 'user/one/run1//2/SUCCEEDED'
}
},
tokens: {
cycle: '2'
- }
+ },
+ children: []
}
const nodeRetrying =
@@ -19,27 +21,40 @@ const nodeRetrying =
id: 'user/one/run1//1/retrying',
name: 'retrying',
node: {
+ name: 'retrying',
firstParent: {
id: 'user/one/run1//1/BAD'
}
},
tokens: {
cycle: '1'
- }
+ },
+ children: [
+ {
+ id: 'user/one/run1//1/retrying/01',
+ name: 'retrying',
+ },
+ {
+ id: 'user/one/run1//1/retrying/02',
+ name: 'retrying',
+ }
+ ]
}
const nodeSleepy =
{
- id: 'user/one/run1//1/sleepy',
+ id: 'user/one/run1//2/sleepy',
name: 'sleepy',
node: {
+ name: 'sleepy',
firstParent: {
id: 'user/one/run1//1/root'
}
},
tokens: {
cycle: '2'
- }
+ },
+ children: []
}
const nodeFailed =
@@ -47,13 +62,14 @@ const nodeFailed =
id: 'user/one/run1//1/failed',
name: 'failed',
node: {
+ name: 'failed',
firstParent: {
id: 'user/one/run1//1/BAD'
}
},
tokens: {
cycle: '1'
- }
+ },
}
const nodeNamespaceRoot =
@@ -61,10 +77,12 @@ const nodeNamespaceRoot =
id: 'user/one/run1//$namespace|root',
name: 'root',
node: {
+ name: 'root',
parents: [],
childFamilies: [{ name: 'GOOD' }, { name: 'BAD' }],
childTasks: [{ name: 'checkpoint' }, { name: 'sleepy' }, { name: 'waiting' }]
- }
+ },
+ tokens: { cycle: undefined }
}
const nodeNamespaceBad =
@@ -72,10 +90,12 @@ const nodeNamespaceBad =
id: 'user/one/run1//$namespace|BAD',
name: 'BAD',
node: {
+ name: 'root',
parents: [{ name: 'root' }],
childFamilies: [],
childTasks: [{ name: 'retrying' }, { name: 'failed' }]
- }
+ },
+ tokens: { cycle: undefined }
}
const nodeNamespaceGood =
@@ -83,10 +103,12 @@ const nodeNamespaceGood =
id: 'user/one/run1//$namespace|GOOD',
name: 'GOOD',
node: {
+ name: 'GOOD',
parents: [{ name: 'root' }],
childFamilies: [{ name: 'SUCCEEDED' }],
childTasks: [{ name: 'retrying' }, { name: 'failed' }]
- }
+ },
+ tokens: { cycle: undefined }
}
const nodeNamespaceSucceeded =
@@ -94,41 +116,90 @@ const nodeNamespaceSucceeded =
id: 'user/one/run1//$namespace|SUCCEEDED',
name: 'SUCCEEDED',
node: {
+ name: 'GOOD',
parents: [{ name: 'GOOD' }],
childFamilies: [],
childTasks: [{ name: 'succeeded' }, { name: 'eventually_succeeded' }]
- }
+ },
+ tokens: { cycle: undefined }
}
const workflows = [
{
id: '~user/one',
+ node: {
+ firstParent: {
+ id: ''
+ }
+ },
children: [
{
id: '~user/one//1',
+ tokens: { cycle: 1 },
+ node: {
+ firstParent: {
+ id: ''
+ }
+ },
children: [
{
id: '~user/one//1/eventually_succeeded',
+ tokens: { cycle: 1 },
+ node: {
+ firstParent: {
+ id: 'user/one/run1//1/SUCCEEDED'
+ }
+ },
children: [
{
id: '~user/one//1/eventually_succeeded/3',
+ tokens: { cycle: 1 },
+ node: {
+ firstParent: {
+ id: 'user/one/run1//1/SUCCEEDED'
+ }
+ },
children: [],
},
{
id: '~user/one//1/eventually_succeeded/2',
+ tokens: { cycle: 1 },
+ node: {
+ firstParent: {
+ id: 'user/one/run1//1/SUCCEEDED'
+ }
+ },
children: [],
},
{
id: '~user/one//1/eventually_succeeded/1',
+ tokens: { cycle: 1 },
+ node: {
+ firstParent: {
+ id: 'user/one/run1//1/SUCCEEDED'
+ }
+ },
children: [],
},
],
},
{
id: '~user/one//1/failed',
+ tokens: { cycle: 1 },
+ node: {
+ firstParent: {
+ id: 'user/one/run1//1/BAD'
+ }
+ },
children: [
{
id: '~user/one//1/failed/1',
+ tokens: { cycle: 1 },
+ node: {
+ firstParent: {
+ id: 'user/one/run1//1/BAD'
+ }
+ },
children: [],
},
],
@@ -150,13 +221,49 @@ const nodes = [
nodeFailed,
nodeRetrying,
nodeSleepy,
- nodeSuceeded
+ nodeSucceeded
+]
+
+const edges = [
+ {
+ id: 'user/one/run1//$edge|1/succeeded|1/failed',
+ name: 'user/one/run1//$edge|1/succeeded|1/failed',
+ parent: 'user/one/run1',
+ node: {
+ id: 'user/one/run1//$edge|1/succeeded|1/failed',
+ source: 'user/one/run1//1/succeeded',
+ target: 'user/one/run1//1/failed',
+ __typename: 'Edge'
+ }
+ },
+ {
+ id: 'user/one/run1//$edge|1/failed|1/checkpoint',
+ name: 'user/one/run1//$edge|1/failed|1/checkpoint',
+ parent: 'user/one/run1',
+ node: {
+ id: 'user/one/run1//$edge|1/failed|1/checkpoint',
+ source: 'user/one/run1//1/failed',
+ target: 'user/one/run1//1/checkpoint',
+ __typename: 'Edge'
+ }
+ },
+ {
+ id: 'user/one/run1//$edge|2/sleepy|1/failed',
+ name: 'user/one/run1//$edge|2/sleepy|1/failed',
+ parent: 'user/one/run1',
+ node: {
+ id: 'user/one/run1//$edge|2/sleepy|1/failed',
+ source: 'user/one/run1//2/sleepy',
+ target: 'user/one/run1//1/failed',
+ __typename: 'Edge'
+ }
+ }
]
const cylcTree = {
$index: {
- 'user/one/run1//1/succeeded': nodeSuceeded,
- 'user/one/run1//1/sleepy': nodeSleepy,
+ 'user/one/run1//1/succeeded': nodeSucceeded,
+ 'user/one/run1//2/sleepy': nodeSleepy,
'user/one/run1//1/retrying': nodeRetrying,
'user/one/run1//1/failed': nodeFailed,
'user/one/run1//$namespace|root': nodeNamespaceRoot,
@@ -166,23 +273,6 @@ const cylcTree = {
}
}
-// const getFamilies = (nodes) => {
-// if (!groupFamily) return
-// return nodes.reduce((x, y) => {
-// if (y.node.firstParent) {
-// (x[y.node.firstParent.id.split('/')[y.node.firstParent.id.split('/').length - 1]] ||= []).push(y)
-// }
-// return x
-// }, {})
-// }
-
-const getCycles = (nodes) => {
- return nodes.reduce((x, y) => {
- (x[y.tokens.cycle] ||= []).push(y)
- return x
- }, {})
-}
-
const namespaces = () => {
return workflows[0]?.$namespaces || []
}
@@ -190,8 +280,7 @@ const namespaces = () => {
export {
workflows,
nodes,
+ edges,
cylcTree,
- // getFamilies,
- getCycles,
namespaces
}
diff --git a/tests/unit/views/graph.vue.spec.js b/tests/unit/views/graph.vue.spec.js
new file mode 100644
index 000000000..54caa161e
--- /dev/null
+++ b/tests/unit/views/graph.vue.spec.js
@@ -0,0 +1,624 @@
+/* Copyright (C) NIWA & British Crown (Met Office) & Contributors.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see . */
+
+import { mount } from '@vue/test-utils'
+import { createStore } from 'vuex'
+import sinon from 'sinon'
+import storeOptions from '@/store/options'
+import Graph from '@/views/Graph.vue'
+import User from '@/model/User.model'
+import WorkflowService from '@/services/workflow.service'
+import { workflows, cylcTree, nodes, edges, namespaces } from './graph-utils.js'
+
+chai.config.truncateThreshold = 0
+
+describe('Graph view', () => {
+ let store, $workflowService
+ beforeEach(() => {
+ store = createStore(storeOptions)
+ const user = new User({ username: 'cylc', permissions: [], owner: 'owner' })
+ store.commit('user/SET_USER', user)
+ $workflowService = sinon.createStubInstance(WorkflowService)
+ sinon.stub(Graph.methods, 'mountSVGPanZoom')
+ })
+ afterEach(() => { sinon.restore() })
+
+ it('gets cycles', async () => {
+ const wrapper = mount(Graph, {
+ shallow: true,
+ global: {
+ plugins: [store],
+ mocks: { $workflowService }
+ },
+ props: {
+ workflowName: 'one',
+ },
+ computed: {
+ workflows () {
+ return workflows
+ },
+ namespaces () {
+ return namespaces()
+ },
+ cylcTree () {
+ return cylcTree
+ }
+ }
+ })
+
+ expect(wrapper.vm.getCycles(nodes)).toMatchObject(
+ {
+ 1: [
+ {
+ id: 'user/one/run1//1/failed',
+ name: 'failed',
+ node: {
+ firstParent: {
+ id: 'user/one/run1//1/BAD'
+ }
+ },
+ tokens: {
+ cycle: '1'
+ }
+ },
+ {
+ id: 'user/one/run1//1/retrying',
+ name: 'retrying',
+ node: {
+ firstParent: {
+ id: 'user/one/run1//1/BAD'
+ }
+ },
+ tokens: {
+ cycle: '1'
+ }
+ }
+ ],
+ 2: [
+ {
+ id: 'user/one/run1//2/sleepy',
+ name: 'sleepy',
+ node: {
+ firstParent: {
+ id: 'user/one/run1//1/root'
+ }
+ },
+ tokens: {
+ cycle: '2'
+ }
+ },
+ {
+ id: 'user/one/run1//2/succeeded',
+ name: 'succeeded',
+ node: {
+ firstParent: {
+ id: 'user/one/run1//2/SUCCEEDED'
+ }
+ },
+ tokens: {
+ cycle: '2'
+ }
+ }
+ ]
+ }
+ )
+ })
+
+ it('it gets families', async () => {
+ const wrapper = mount(Graph, {
+ shallow: true,
+ global: {
+ plugins: [store],
+ mocks: { $workflowService }
+ },
+ props: {
+ workflowName: 'one',
+ },
+ computed: {
+ workflows () {
+ return workflows
+ },
+ namespaces () {
+ return namespaces()
+ },
+ cylcTree () {
+ return cylcTree
+ }
+ }
+ })
+
+ expect(wrapper.vm.getFamilies(nodes)).toMatchObject(
+ {
+ BAD: [
+ {
+ id: 'user/one/run1//1/failed',
+ name: 'failed',
+ node: {
+ firstParent: {
+ id: 'user/one/run1//1/BAD'
+ }
+ },
+ tokens: {
+ cycle: '1'
+ }
+ },
+ {
+ id: 'user/one/run1//1/retrying',
+ name: 'retrying',
+ node: {
+ firstParent: {
+ id: 'user/one/run1//1/BAD'
+ }
+ },
+ tokens: {
+ cycle: '1'
+ }
+ }
+ ],
+ SUCCEEDED: [
+ {
+ id: 'user/one/run1//2/succeeded',
+ name: 'succeeded',
+ node: {
+ firstParent: {
+ id: 'user/one/run1//2/SUCCEEDED'
+ }
+ },
+ tokens: {
+ cycle: '2'
+ }
+ }
+ ],
+ root: [
+ {
+ id: 'user/one/run1//2/sleepy',
+ name: 'sleepy',
+ node: {
+ firstParent: {
+ id: 'user/one/run1//1/root'
+ }
+ },
+ tokens: {
+ cycle: '2'
+ }
+ }
+ ]
+ }
+ )
+ })
+
+ it('it gets all children look up object', async () => {
+ const wrapper = mount(Graph, {
+ shallow: true,
+ global: {
+ plugins: [store],
+ mocks: { $workflowService }
+ },
+ props: {
+ workflowName: 'one',
+ },
+ computed: {
+ workflows () {
+ return workflows
+ },
+ namespaces () {
+ return namespaces()
+ },
+ cylcTree () {
+ return cylcTree
+ }
+ }
+ })
+
+ wrapper.vm.getAllChildrenLookUp()
+
+ expect(wrapper.vm.allChilderenLookUp).toMatchObject(
+ {
+ 'user/one/run1//$namespace|BAD': [
+ {
+ children: undefined,
+ id: 'user/one/run1//$namespace|BAD',
+ name: 'BAD'
+ }
+ ],
+ 'user/one/run1//$namespace|GOOD': [
+ {
+ children: undefined,
+ id: 'user/one/run1//$namespace|GOOD',
+ name: 'GOOD'
+ }
+ ],
+ 'user/one/run1//$namespace|SUCCEEDED': [
+ {
+ children: undefined,
+ id: 'user/one/run1//$namespace|SUCCEEDED',
+ name: 'SUCCEEDED'
+ }
+ ],
+ 'user/one/run1//$namespace|root': [
+ {
+ children: undefined,
+ id: 'user/one/run1//$namespace|root',
+ name: 'root'
+ }
+ ],
+ 'user/one/run1//1/failed': [
+ {
+ children: undefined,
+ id: 'user/one/run1//1/failed',
+ name: 'failed'
+ }
+ ],
+ 'user/one/run1//1/retrying': [
+ {
+ children: [
+ {
+ id: 'user/one/run1//1/retrying/01',
+ name: 'retrying'
+ },
+ {
+ id: 'user/one/run1//1/retrying/02',
+ name: 'retrying'
+ }
+ ],
+ id: 'user/one/run1//1/retrying',
+ name: 'retrying',
+ },
+ {
+ id: 'user/one/run1//1/retrying/01',
+ name: 'retrying',
+ children: undefined
+ },
+ {
+ id: 'user/one/run1//1/retrying/02',
+ name: 'retrying',
+ children: undefined
+ }
+ ]
+ }
+ )
+ })
+
+ it('it gets all parents look up object', async () => {
+ const wrapper = mount(Graph, {
+ shallow: true,
+ global: {
+ plugins: [store],
+ mocks: { $workflowService }
+ },
+ props: {
+ workflowName: 'one',
+ },
+ computed: {
+ workflows () {
+ return workflows
+ },
+ namespaces () {
+ return namespaces()
+ },
+ cylcTree () {
+ return cylcTree
+ }
+ }
+ })
+
+ wrapper.vm.getAllParentLookUp()
+
+ expect(wrapper.vm.allParentLookUp).toMatchObject(
+ {
+ BAD: ['root'],
+ GOOD: ['root'],
+ SUCCEEDED: ['GOOD', 'root'],
+ root: []
+ }
+ )
+ })
+
+ it('it gets tree', async () => {
+ const wrapper = mount(Graph, {
+ shallow: true,
+ global: {
+ plugins: [store],
+ mocks: { $workflowService }
+ },
+ props: {
+ workflowName: 'one',
+ },
+ computed: {
+ workflows () {
+ return workflows
+ },
+ namespaces () {
+ return namespaces()
+ },
+ cylcTree () {
+ return cylcTree
+ }
+ }
+ })
+
+ // wrapper.vm.nextTick()
+ expect(wrapper.vm.getTree()).toMatchObject(
+ [
+ {
+ children: [
+ {
+ children: [],
+ disabled: false,
+ id: 3,
+ name: 'SUCCEEDED',
+ },
+ ],
+ disabled: false,
+ id: 2,
+ name: 'GOOD',
+ },
+ {
+ children: [],
+ disabled: false,
+ id: 4,
+ name: 'BAD',
+ },
+ ]
+ )
+ })
+
+ it('it gets checks for edge by source', async () => {
+ const wrapper = mount(Graph, {
+ shallow: true,
+ global: {
+ plugins: [store],
+ mocks: { $workflowService }
+ },
+ props: {
+ workflowName: 'one',
+ },
+ computed: {
+ workflows () {
+ return workflows
+ },
+ namespaces () {
+ return namespaces()
+ },
+ cylcTree () {
+ return cylcTree
+ },
+ workflowIDs () {
+ return ['user/one/run1']
+ }
+ }
+ })
+ expect(wrapper.vm.checkForEdgeBySource('failed', '1', edges)).toMatchObject(
+ [
+ {
+ id: 'user/one/run1//$edge|1/failed|1/checkpoint',
+ name: 'user/one/run1//$edge|1/failed|1/checkpoint',
+ parent: 'user/one/run1',
+ node: {
+ id: 'user/one/run1//$edge|1/failed|1/checkpoint',
+ source: 'user/one/run1//1/failed',
+ target: 'user/one/run1//1/checkpoint',
+ __typename: 'Edge'
+ }
+ }
+ ]
+ )
+ })
+
+ it('it gets checks for edge by target', async () => {
+ const wrapper = mount(Graph, {
+ shallow: true,
+ global: {
+ plugins: [store],
+ mocks: { $workflowService }
+ },
+ props: {
+ workflowName: 'one',
+ },
+ computed: {
+ workflows () {
+ return workflows
+ },
+ namespaces () {
+ return namespaces()
+ },
+ cylcTree () {
+ return cylcTree
+ },
+ workflowIDs () {
+ return ['user/one/run1']
+ }
+ }
+ })
+ expect(wrapper.vm.checkForEdgeByTarget('checkpoint', '1', edges)).toMatchObject(
+ [
+ {
+ id: 'user/one/run1//$edge|1/failed|1/checkpoint',
+ name: 'user/one/run1//$edge|1/failed|1/checkpoint',
+ parent: 'user/one/run1',
+ node: {
+ id: 'user/one/run1//$edge|1/failed|1/checkpoint',
+ source: 'user/one/run1//1/failed',
+ target: 'user/one/run1//1/checkpoint',
+ __typename: 'Edge'
+ }
+ }
+ ]
+ )
+ })
+
+ it('it removes edge node by source', async () => {
+ const wrapper = mount(Graph, {
+ shallow: true,
+ global: {
+ plugins: [store],
+ mocks: { $workflowService }
+ },
+ props: {
+ workflowName: 'one',
+ },
+ computed: {
+ workflows () {
+ return workflows
+ },
+ namespaces () {
+ return namespaces()
+ },
+ cylcTree () {
+ return cylcTree
+ },
+ workflowIDs () {
+ return ['user/one/run1']
+ }
+ }
+ })
+ // in this test we remove the first edge with a source of 'user/one/run1//1/sleepy'
+ wrapper.vm.getAllChildrenLookUp()
+ const config = wrapper.vm.allChilderenLookUp['user/one/run1//2/sleepy'][0]
+ const edgeCheckSource = wrapper.vm.checkForEdgeBySource(config.name, '2', edges)
+ const removedEdges = []
+
+ expect(wrapper.vm.removeEdgeBySource(edgeCheckSource, edges, removedEdges, config, '2')).toMatchObject(
+ [
+ // the returned edges array with the edge removed
+ [
+ {
+ id: 'user/one/run1//$edge|1/succeeded|1/failed',
+ name: 'user/one/run1//$edge|1/succeeded|1/failed',
+ parent: 'user/one/run1',
+ node: {
+ id: 'user/one/run1//$edge|1/succeeded|1/failed',
+ source: 'user/one/run1//1/succeeded',
+ target: 'user/one/run1//1/failed',
+ __typename: 'Edge'
+ }
+ },
+ {
+ id: 'user/one/run1//$edge|1/failed|1/checkpoint',
+ name: 'user/one/run1//$edge|1/failed|1/checkpoint',
+ parent: 'user/one/run1',
+ node: {
+ id: 'user/one/run1//$edge|1/failed|1/checkpoint',
+ source: 'user/one/run1//1/failed',
+ target: 'user/one/run1//1/checkpoint',
+ __typename: 'Edge'
+ }
+ }
+ ],
+ // the returned removed edges array
+ [
+ {
+ id: 'user/one/run1//$edge|2/sleepy|1/failed',
+ name: 'user/one/run1//$edge|2/sleepy|1/failed',
+ parent: 'user/one/run1',
+ node: {
+ id: 'user/one/run1//$edge|2/sleepy|1/failed',
+ source: 'user/one/run1//2/sleepy',
+ target: 'user/one/run1//1/failed',
+ __typename: 'Edge'
+ }
+ }
+ ]
+ ]
+ )
+ })
+
+ it('it removes edge node by target', async () => {
+ const wrapper = mount(Graph, {
+ shallow: true,
+ global: {
+ plugins: [store],
+ mocks: { $workflowService }
+ },
+ props: {
+ workflowName: 'one',
+ },
+ computed: {
+ workflows () {
+ return workflows
+ },
+ namespaces () {
+ return namespaces()
+ },
+ cylcTree () {
+ return cylcTree
+ },
+ workflowIDs () {
+ return ['user/one/run1']
+ }
+ }
+ })
+ // in this test we remove the first edge with a target of 'user/one/run1//1/failed'
+ wrapper.vm.getAllChildrenLookUp()
+ const config = wrapper.vm.allChilderenLookUp['user/one/run1//1/failed'][0]
+ const edgeCheckTarget = wrapper.vm.checkForEdgeByTarget(config.name, '1', edges)
+ const removedEdges = []
+
+ expect(wrapper.vm.removeEdgeByTarget(edgeCheckTarget, edges, removedEdges)).toMatchObject(
+ [
+ // the returned edges array with the edge removed
+ [
+ {
+ id: 'user/one/run1//$edge|1/succeeded|1/failed',
+ name: 'user/one/run1//$edge|1/succeeded|1/failed',
+ parent: 'user/one/run1',
+ node: {
+ id: 'user/one/run1//$edge|1/succeeded|1/failed',
+ source: 'user/one/run1//1/succeeded',
+ target: 'user/one/run1//1/failed',
+ __typename: 'Edge'
+ }
+ },
+ {
+ id: 'user/one/run1//$edge|1/failed|1/checkpoint',
+ name: 'user/one/run1//$edge|1/failed|1/checkpoint',
+ parent: 'user/one/run1',
+ node: {
+ id: 'user/one/run1//$edge|1/failed|1/checkpoint',
+ source: 'user/one/run1//1/failed',
+ target: 'user/one/run1//1/checkpoint',
+ __typename: 'Edge'
+ }
+ }
+ ],
+ // the returned removed edges array
+ [
+ {
+ id: 'user/one/run1//$edge|1/succeeded|1/failed',
+ name: 'user/one/run1//$edge|1/succeeded|1/failed',
+ parent: 'user/one/run1',
+ node: {
+ id: 'user/one/run1//$edge|1/succeeded|1/failed',
+ source: 'user/one/run1//1/succeeded',
+ target: 'user/one/run1//1/failed',
+ __typename: 'Edge'
+ }
+ },
+ {
+ id: 'user/one/run1//$edge|2/sleepy|1/failed',
+ name: 'user/one/run1//$edge|2/sleepy|1/failed',
+ parent: 'user/one/run1',
+ node: {
+ id: 'user/one/run1//$edge|2/sleepy|1/failed',
+ source: 'user/one/run1//2/sleepy',
+ target: 'user/one/run1//1/failed',
+ __typename: 'Edge'
+ }
+ }
+ ]
+ ]
+ )
+ })
+})
diff --git a/tests/unit/views/graphv2.vue.spec.js b/tests/unit/views/graphv2.vue.spec.js
deleted file mode 100644
index 971705438..000000000
--- a/tests/unit/views/graphv2.vue.spec.js
+++ /dev/null
@@ -1,206 +0,0 @@
-/* Copyright (C) NIWA & British Crown (Met Office) & Contributors.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see . */
-
-import { workflows, cylcTree, nodes, namespaces, getCycles } from './graphv2utils.js'
-
-chai.config.truncateThreshold = 0
-
-let groupFamily
-const getFamilies = (nodes) => {
- if (!groupFamily) return
- return nodes.reduce((x, y) => {
- if (y.node.firstParent) {
- (x[y.node.firstParent.id.split('/')[y.node.firstParent.id.split('/').length - 1]] ||= []).push(y)
- }
- return x
- }, {})
-}
-
-let allParentLookUp = {}
-const namespaces2 = namespaces()
-
-const getAllParentLookUp = () => {
- allParentLookUp = {}
- namespaces2.forEach((namespace) => {
- const array = []
- let parents = namespace.node.parents
- while (parents.length) {
- parents.forEach((parent) => {
- const childTokens = workflows[0].tokens.clone({ cycle: `$namespace|${parent.name}` })
- const childNode = cylcTree.$index[childTokens.id]
- array.push(childNode.name)
- parents = childNode.node.parents
- })
- }
- allParentLookUp[namespace.name] = array
- })
- return allParentLookUp
-}
-
-describe('Graph view', () => {
- it('gets namespaces', async () => {
- expect(namespaces()).toMatchObject([
- {
- id: 'user/one/run1//$namespace|BAD',
- name: 'BAD'
- },
- {
- id: 'user/one/run1//$namespace|GOOD',
- name: 'GOOD'
- },
- {
- id: 'user/one/run1//$namespace|root',
- name: 'root'
- },
- {
- id: 'user/one/run1//$namespace|SUCCEEDED',
- name: 'SUCCEEDED'
- },
- ])
- })
-
- it('gets families', async () => {
- expect(getFamilies(nodes)).toMatchObject(undefined)
- groupFamily = ['GOOD']
- expect(getFamilies(nodes)).toMatchObject(
- {
- BAD: [
- {
- id: 'user/one/run1//1/failed',
- name: 'failed',
- node: {
- firstParent: {
- id: 'user/one/run1//1/BAD'
- }
- },
- tokens: {
- cycle: '1'
- }
- },
- {
- id: 'user/one/run1//1/retrying',
- name: 'retrying',
- node: {
- firstParent: {
- id: 'user/one/run1//1/BAD'
- }
- },
- tokens: {
- cycle: '1'
- }
- }
- ],
- SUCCEEDED: [
- {
- id: 'user/one/run1//1/succeeded',
- name: 'succeeded',
- node: {
- firstParent: {
- id: 'user/one/run1//1/SUCCEEDED'
- }
- },
- tokens: {
- cycle: '2'
- }
- }
- ],
- root: [
- {
- id: 'user/one/run1//1/sleepy',
- name: 'sleepy',
- node: {
- firstParent: {
- id: 'user/one/run1//1/root'
- }
- },
- tokens: {
- cycle: '2'
- }
- }
- ]
- }
- )
- })
-
- it('gets cycles', async () => {
- expect(getCycles(nodes)).toMatchObject(
- {
- 1: [
- {
- id: 'user/one/run1//1/failed',
- name: 'failed',
- node: {
- firstParent: {
- id: 'user/one/run1//1/BAD'
- }
- },
- tokens: {
- cycle: '1'
- }
- },
- {
- id: 'user/one/run1//1/retrying',
- name: 'retrying',
- node: {
- firstParent: {
- id: 'user/one/run1//1/BAD'
- }
- },
- tokens: {
- cycle: '1'
- }
- }
- ],
- 2: [
- {
- id: 'user/one/run1//1/sleepy',
- name: 'sleepy',
- node: {
- firstParent: {
- id: 'user/one/run1//1/root'
- }
- },
- tokens: {
- cycle: '2'
- }
- },
- {
- id: 'user/one/run1//1/succeeded',
- name: 'succeeded',
- node: {
- firstParent: {
- id: 'user/one/run1//1/SUCCEEDED'
- }
- },
- tokens: {
- cycle: '2'
- }
- }
- ]
- },
- )
- })
-
- it('gets allParentLookUp', async () => {
- expect(getAllParentLookUp()).toMatchObject(
- {
- BAD: ['root'],
- GOOD: ['root'],
- root: [],
- SUCCEEDED: ['GOOD', 'root']
- }
- )
- })
-})