Skip to content

Commit 14a04fe

Browse files
committed
fix: condition builder + tests
1 parent 1a9c0b7 commit 14a04fe

2 files changed

Lines changed: 118 additions & 10 deletions

File tree

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { describe, expect, it } from '@jest/globals';
2+
import ConditionBuilder from './conditionBuilder';
3+
import NullCondition from './condition/nullCondition';
4+
import OrCondition from './condition/orCondition';
5+
import AndCondition from './condition/andCondition';
6+
7+
describe('Condition Builder', () => {
8+
const conditionWithoutClass: Condition = {
9+
field: 'testField',
10+
class: null,
11+
value: null,
12+
operator: '',
13+
};
14+
15+
const conditionBuilder = new ConditionBuilder({
16+
'testField': {
17+
} as FieldInterface,
18+
'testField2': {
19+
} as FieldInterface,
20+
});
21+
22+
it('build() returns an array with a NullCondition if no conditions or faulty value are provided', () => {
23+
const nullConditionEmptyArray = conditionBuilder.build([]);
24+
const nullConditionFaultyValue = conditionBuilder.build(null);
25+
expect(nullConditionEmptyArray).toHaveLength(1);
26+
expect(nullConditionEmptyArray[0]).toBeInstanceOf(NullCondition);
27+
expect(nullConditionFaultyValue).toHaveLength(1);
28+
expect(nullConditionFaultyValue[0]).toBeInstanceOf(NullCondition);
29+
});
30+
31+
it('build() returns an array with NullConditions faulty array items are provided', () => {
32+
const nullConditionFaultyValue = conditionBuilder.build(['item', []]);
33+
expect(nullConditionFaultyValue).toHaveLength(2);
34+
expect(nullConditionFaultyValue[0]).toBeInstanceOf(NullCondition);
35+
expect(nullConditionFaultyValue[1]).toBeInstanceOf(NullCondition);
36+
});
37+
38+
it('build() returns an array with a NullCondition if conditionSet doesnt contain valid conditionalData', () => {
39+
const faultyItemType = conditionBuilder.build([['item', 'item']]);
40+
const faultyObjectMissingFieldName = conditionBuilder.build([[{operator: '==', value: 1}]]);
41+
const faultyObjectMissingValue = conditionBuilder.build([[{field: 'field', operator: '=='}]]);
42+
const faultyObjectMissingOperator = conditionBuilder.build([[{field: 'field', value: 1}]]);
43+
expect(faultyItemType).toHaveLength(1);
44+
expect(faultyItemType[0]).toBeInstanceOf(NullCondition);
45+
expect(faultyObjectMissingFieldName).toHaveLength(1);
46+
expect(faultyObjectMissingFieldName[0]).toBeInstanceOf(NullCondition);
47+
expect(faultyObjectMissingValue).toHaveLength(1);
48+
expect(faultyObjectMissingValue[0]).toBeInstanceOf(NullCondition);
49+
expect(faultyObjectMissingOperator).toHaveLength(1);
50+
expect(faultyObjectMissingOperator[0]).toBeInstanceOf(NullCondition);
51+
});
52+
53+
it('build() returns an array with a NullCondition fieldName doesnt exist in class param fields (fieldsObject)', () => {
54+
const faultyItemType = conditionBuilder.build([[createConditionSet('unknownField', 1, '==')]]);
55+
expect(faultyItemType).toHaveLength(1);
56+
expect(faultyItemType[0]).toBeInstanceOf(NullCondition);
57+
});
58+
59+
it('build() returns an array with an OrCondition if one valid item is provided', () => {
60+
const faultyItemType = conditionBuilder.build([[createConditionSet()]]);
61+
expect(faultyItemType).toHaveLength(1);
62+
expect(faultyItemType[0]).toBeInstanceOf(OrCondition);
63+
});
64+
65+
it('build() returns an array with an AndConditions if more than one valid item is provided', () => {
66+
const faultyItemType = conditionBuilder.build([[createConditionSet(), createConditionSet()]]);
67+
expect(faultyItemType).toHaveLength(1);
68+
expect(faultyItemType[0]).toBeInstanceOf(AndCondition);
69+
});
70+
71+
it('build() returns an array with an AndConditions as long as one item is valid', () => {
72+
const faultyItemType = conditionBuilder.build([[createConditionSet(), createConditionSet('unknownField')]]);
73+
expect(faultyItemType).toHaveLength(1);
74+
expect(faultyItemType[0]).toBeInstanceOf(AndCondition);
75+
});
76+
77+
it('build() returns an array with a NullCondition if multiple invalid items', () => {
78+
const faultyItemType = conditionBuilder.build([[createConditionSet('unknownField'), createConditionSet('unknownField')]]);
79+
expect(faultyItemType).toHaveLength(1);
80+
expect(faultyItemType[0]).toBeInstanceOf(NullCondition);
81+
});
82+
});
83+
84+
function createConditionSet(field: any = 'testField', value: any = 1, operator: any = '==') {
85+
return {
86+
field: field,
87+
value: value,
88+
operator: operator,
89+
};
90+
}

source/js/conditions/conditionBuilder.ts

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ import NullCondition from "./condition/nullCondition";
33
import OrCondition from "./condition/orCondition";
44

55
class ConditionBuilder implements ConditionBuilderInterface {
6-
constructor(private fields: FieldsObject) {
7-
8-
}
6+
constructor(private fields: FieldsObject) {}
97

108
public build(conditions: any): ConditionInterface[] {
119
if (!Array.isArray(conditions) || conditions.length === 0) {
@@ -16,17 +14,25 @@ class ConditionBuilder implements ConditionBuilderInterface {
1614
conditions.forEach(conditionSet => {
1715
if (!Array.isArray(conditionSet) || conditionSet.length === 0) {
1816
conditionsList.push(new NullCondition());
17+
return;
1918
}
2019

2120
if (conditionSet.length === 1) {
22-
conditionSet[0].class = this.fields[conditionSet[0].field] ?? null;
23-
conditionsList.push(new OrCondition(conditionSet[0]));
21+
if (this.checkConditionValidity(conditionSet[0])) {
22+
conditionSet[0].class = this.fields[conditionSet[0].field];
23+
conditionsList.push(new OrCondition(conditionSet[0]));
24+
}
2425
} else {
25-
conditionSet.forEach((condition: Condition) => {
26-
condition.class = this.fields[condition.field] ?? null;
27-
});
28-
29-
conditionsList.push(new AndCondition(conditionSet));
26+
const validConditions = conditionSet
27+
.filter((condition: Condition) => this.checkConditionValidity(condition))
28+
.map((condition: Condition) => ({
29+
...condition,
30+
class: this.fields[condition.field]
31+
}));
32+
33+
if (validConditions.length > 0) {
34+
conditionsList.push(new AndCondition(validConditions));
35+
}
3036
}
3137
});
3238

@@ -36,6 +42,18 @@ class ConditionBuilder implements ConditionBuilderInterface {
3642

3743
return [new NullCondition()];
3844
}
45+
46+
private checkConditionValidity(condition: any): boolean {
47+
if (typeof condition !== 'object') {
48+
return false;
49+
}
50+
51+
if (!('field' in condition) || !('operator' in condition) || !('value' in condition) || !this.fields[condition.field]) {
52+
return false;
53+
}
54+
55+
return true;
56+
}
3957
}
4058

4159
export default ConditionBuilder;

0 commit comments

Comments
 (0)