diff --git a/lib/network-query/__tests__/filter.test.js b/lib/network-query/__tests__/filter.test.js index b26ac6b79..d0d84f139 100644 --- a/lib/network-query/__tests__/filter.test.js +++ b/lib/network-query/__tests__/filter.test.js @@ -245,7 +245,26 @@ describe('filter', () => { }); describe('Edges', () => { - it('can filter edges by type', () => { + + it('can filter nodes by edge and trim orphaned edges', () => { + const filterConfig = { + rules: [ + generateRuleConfig('edge', { + type: 'band', + operator: operators.EXISTS, + }), + ] + }; + + const filter = getFilter(filterConfig); + const result = filter(network); + const names = result.nodes.map( + (node) => node[entityAttributesProperty].name, + ) + expect(names).toEqual(['William', 'Theodore']); + expect(result.edges.length).toEqual(2); // should be band edge AND friend edge between valid nodes + }) + it('can filter nodes by edge type', () => { const filterConfig = { rules: [ generateRuleConfig('edge', { @@ -262,7 +281,7 @@ describe('filter', () => { (node) => node[entityAttributesProperty].name, ); expect(names).toEqual(['William', 'Theodore', 'Rufus']); - expect(result.edges.length).toEqual(3); + expect(result.edges.length).toEqual(4); }); it.todo('can filter edges by type (not)'); @@ -282,7 +301,7 @@ describe('filter', () => { const filter = getFilter(filterConfig); const result = filter(network); - expect(result.edges.length).toEqual(2); + expect(result.edges.length).toEqual(4); }); }); }); diff --git a/lib/network-query/__tests__/rules.test.js b/lib/network-query/__tests__/rules.test.js index f3b62d0ef..85448a702 100644 --- a/lib/network-query/__tests__/rules.test.js +++ b/lib/network-query/__tests__/rules.test.js @@ -232,7 +232,7 @@ describe('rules', () => { const { nodeNames, edges } = runRuleHelper(ruleConfig); expect(nodeNames).toEqual(['William', 'Theodore', 'Rufus']); - expect(edges.length).toEqual(2); + expect(edges.length).toEqual(3); }); it('NOT_EXISTS', () => { @@ -248,7 +248,7 @@ describe('rules', () => { 'Phone Box', 'Pillar Box', ]); - expect(edges.length).toEqual(2); + expect(edges.length).toEqual(3); }); describe('attribute rules', () => { @@ -281,7 +281,7 @@ describe('rules', () => { const { nodeNames, edges } = runRuleHelper(ruleConfig); expect(nodeNames).toEqual(['Theodore', 'Rufus']); - expect(edges.length).toEqual(1); + expect(edges.length).toEqual(2); }); it('GREATER_THAN', () => { @@ -307,7 +307,7 @@ describe('rules', () => { const { nodeNames, edges } = runRuleHelper(ruleConfig); expect(nodeNames).toEqual(['Theodore', 'Rufus']); - expect(edges.length).toEqual(1); + expect(edges.length).toEqual(2); }); it('GREATER_THAN_OR_EQUAL', () => { @@ -333,7 +333,7 @@ describe('rules', () => { const { nodeNames, edges } = runRuleHelper(ruleConfig); expect(nodeNames).toEqual(['Theodore', 'Rufus']); - expect(edges.length).toEqual(1); + expect(edges.length).toEqual(2); }); }); }); diff --git a/lib/network-query/filter.js b/lib/network-query/filter.js index de3a31e24..8ae79b114 100644 --- a/lib/network-query/filter.js +++ b/lib/network-query/filter.js @@ -2,7 +2,7 @@ import { entityPrimaryKeyProperty } from '@codaco/shared-consts'; import { getRule } from './rules'; // remove orphaned edges -const trimEdges = (network) => { +export const trimEdges = (network) => { const uids = new Set( network.nodes.map((node) => node[entityPrimaryKeyProperty]), ); diff --git a/lib/network-query/rules.js b/lib/network-query/rules.js index af637ae4f..35b030ee3 100644 --- a/lib/network-query/rules.js +++ b/lib/network-query/rules.js @@ -2,8 +2,8 @@ import { entityAttributesProperty, entityPrimaryKeyProperty, } from '@codaco/shared-consts'; -import { operators } from './predicate'; -import predicate from './predicate'; +import { trimEdges } from './filter'; +import predicate, { operators } from './predicate'; const singleEdgeRule = ({ type, attribute, operator, value: other }) => @@ -62,6 +62,8 @@ const singleNodeRule = // Reduce edges to any that match the rule // Filter nodes by the resulting edges +// Remove orphaned edges from original edges +// Return filtered nodes and valid, non-orphaned edges const edgeRule = ({ attribute, operator, type, value: other }) => (nodes, edges) => { @@ -93,9 +95,16 @@ const edgeRule = edgeMap.includes(node[entityPrimaryKeyProperty]), ); + // remove orphaned edges + + const validEdges = trimEdges({ + nodes: filteredNodes, + edges: edges, + }).edges; + return { nodes: filteredNodes, - edges: filteredEdges, + edges: validEdges, }; };