diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/__tests__/evaluate-filter-conditions.util.spec.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/__tests__/evaluate-filter-conditions.util.spec.ts index bafe9cceb2..d29fbb4d75 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/__tests__/evaluate-filter-conditions.util.spec.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/__tests__/evaluate-filter-conditions.util.spec.ts @@ -804,6 +804,100 @@ describe('evaluateFilterConditions', () => { expect(evaluateFilterConditions({ filters: [filter2] })).toBe(true); expect(evaluateFilterConditions({ filters: [filter3] })).toBe(true); }); + + it('should match legacy Is operand on text by equality', () => { + const matching = createFilter( + ViewFilterOperand.IS, + 'World', + 'World', + 'TEXT', + ); + const substring = createFilter( + ViewFilterOperand.IS, + 'Hello World', + 'World', + 'TEXT', + ); + const notMatching = createFilter( + ViewFilterOperand.IS, + 'Hello', + 'World', + 'TEXT', + ); + + expect(evaluateFilterConditions({ filters: [matching] })).toBe(true); + expect(evaluateFilterConditions({ filters: [substring] })).toBe(false); + expect(evaluateFilterConditions({ filters: [notMatching] })).toBe( + false, + ); + }); + + it('should match legacy IsNot operand on text by inequality', () => { + const matching = createFilter( + ViewFilterOperand.IS_NOT, + 'Hello', + 'World', + 'TEXT', + ); + const notMatching = createFilter( + ViewFilterOperand.IS_NOT, + 'World', + 'World', + 'TEXT', + ); + + expect(evaluateFilterConditions({ filters: [matching] })).toBe(true); + expect(evaluateFilterConditions({ filters: [notMatching] })).toBe( + false, + ); + }); + + it('should match legacy Is operand on arrays by equality', () => { + const matching = createFilter( + ViewFilterOperand.IS, + ['apple', 'banana'], + ['apple', 'banana'], + 'MULTI_SELECT', + ); + const subset = createFilter( + ViewFilterOperand.IS, + ['apple', 'banana'], + ['apple'], + 'MULTI_SELECT', + ); + const notMatching = createFilter( + ViewFilterOperand.IS, + ['apple', 'banana'], + ['grape'], + 'MULTI_SELECT', + ); + + expect(evaluateFilterConditions({ filters: [matching] })).toBe(true); + expect(evaluateFilterConditions({ filters: [subset] })).toBe(false); + expect(evaluateFilterConditions({ filters: [notMatching] })).toBe( + false, + ); + }); + + it('should match legacy IsNot operand on arrays by set inequality', () => { + const matching = createFilter( + ViewFilterOperand.IS_NOT, + ['apple', 'banana'], + ['grape'], + 'MULTI_SELECT', + ); + const notMatching = createFilter( + ViewFilterOperand.IS_NOT, + ['apple', 'banana'], + ['apple', 'banana'], + 'MULTI_SELECT', + ); + + expect(evaluateFilterConditions({ filters: [matching] })).toBe(true); + expect(evaluateFilterConditions({ filters: [notMatching] })).toBe( + false, + ); + }); }); describe('empty operands', () => { diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/evaluate-filter-conditions.util.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/evaluate-filter-conditions.util.ts index b7db327389..f139bb7de2 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/evaluate-filter-conditions.util.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/evaluate-filter-conditions.util.ts @@ -4,6 +4,7 @@ import { isObject, isString, } from '@sniptt/guards'; +import isEqual from 'lodash.isequal'; import { Temporal } from 'temporal-polyfill'; import { type StepFilter, @@ -186,6 +187,10 @@ function evaluateTextAndArrayFilter( (isDefined(nullEquivalentRightValue) && isNotEmptyTextOrArray(filter.leftOperand)) ); + case ViewFilterOperand.IS: + return isEqual(filter.leftOperand, filter.rightOperand); + case ViewFilterOperand.IS_NOT: + return !isEqual(filter.leftOperand, filter.rightOperand); case ViewFilterOperand.IS_EMPTY: return !isNotEmptyTextOrArray(filter.leftOperand);