Skip to content

Conversation

@DelBiss
Copy link

@DelBiss DelBiss commented Jan 2, 2026

Addresses an issue where conditions with the 'not_equals' operator incorrectly evaluated undefined values. This change ensures that empty string comparisons correctly identify missing values in automation rules.

Fix #1932

Addresses an issue where conditions with the 'not_equals' operator incorrectly evaluated undefined values. This change ensures that empty string comparisons correctly identify missing values in automation rules.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 2, 2026

Important

Review skipped

Auto reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

return fieldValue == value;
case 'not_equals':
// overload the edge case where we use empty string to check if a value does not exist
if (value === '' && fieldValue === undefined) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be better to just do the inverse of equal?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've implemented it in the 2nd commit.

Simplifies the 'not_equals' condition evaluation in automations by reusing the 'equals' condition, improving code readability and consistency.

Fixes cpvalente#1932
Expanding test cases to cover various data types and edge case for each operators.
Unexpected behavior have been mark with a TO_DO.
expect(runTestCondition('null/undefined', null, 'equals', 'not-empty')).toBe(false);
expect(runTestCondition('boolean', false, 'equals', '')).toBe(false);

expect(runTestCondition('number', 0, 'equals', '')).toBe(true); // TO_DO: is this the desired behavior?
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This case is probably wrong, especially if false != <empty/no value>

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, this seems incorrect. I believe my suggestion for comparing values could improve this

it('should handle case sensitivity', () => {
// TO_DO: is this the desired behavior?
expect(runTestCondition('string', 'Title', 'contains', 'title')).toBe(false);
});
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contains only work on string, yet, it's case sensitive, contrary to equals.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a good observation, contains and equals should have similar implementations.
I would suggest that contains and not_contains should also be case insensitive. what do you think?

expect(runTestCondition('boolean', true, 'contains', 'true')).toBe(false);
expect(runTestCondition('boolean', false, 'contains', 'false')).toBe(false);
});

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a case that could go both way, especially if, on the client side, operation depends of field type.

But, my first instinct was that other type should match if theirs string representation match.
But again, that would be weird for boolean value that would alway contain a e.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the current implementation, contains only deals with string types. I think this is the correct way to do it

semantically boolean contains "rue" doesnt make sense

- Ensures that their is a default scenario.
- Fixing Deepsource issue "No default cases in switch statements JS-0047"
Copy link
Collaborator

@alex-Arc alex-Arc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for working on this.
the fix itself seams good, and you bring up some good questions in the tests
maybe we could start by merging the fix and take a bit more time to clean up the test

Copy link
Owner

@cpvalente cpvalente left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for these observations.

The code changes were slightly hard to parse since they were mixed with a refactoring of the test scenarios.

I suggest that we create a single PR for now.

  • add tests for the edge cases with equals and contains you have brought up using the existing abstractions
  • add fixes for equals as suggested
  • add changes for casing in contains

we can then review separately whether the tests benefit from an abstraction. In general we avoid abstractions in testing. At this level we dont want to do any "hiding" and prefer all the changes to be explicit, also abstractions could introduce issues at abstraction level which make things hard to debug

return fieldValue == value;
case 'not_equals':
return fieldValue != value;
return !evaluateCondition({ field, operator: 'equals', value });
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the previous code attempted a loose comparison to allow matching "12" to 12.
This is to simplify automations

However, it has the side effects of matching all the falsy values 0, undefined, null, ""

how about creating a new helper isEquivalentValue which resolves this

  • given two values of the same type, make a strict comparison ===
  • given two values of different types:
  • a) if the types are string a number, make a loose comparison ==
  • b) for all other cases return false

This could also help with the logic in the equals condition

it('should handle case sensitivity', () => {
// TO_DO: is this the desired behavior?
expect(runTestCondition('string', 'Title', 'contains', 'title')).toBe(false);
});
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a good observation, contains and equals should have similar implementations.
I would suggest that contains and not_contains should also be case insensitive. what do you think?

expect(runTestCondition('boolean', true, 'contains', 'true')).toBe(false);
expect(runTestCondition('boolean', false, 'contains', 'false')).toBe(false);
});

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the current implementation, contains only deals with string types. I think this is the correct way to do it

semantically boolean contains "rue" doesnt make sense

expect(runTestCondition('null/undefined', null, 'equals', 'not-empty')).toBe(false);
expect(runTestCondition('boolean', false, 'equals', '')).toBe(false);

expect(runTestCondition('number', 0, 'equals', '')).toBe(true); // TO_DO: is this the desired behavior?
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, this seems incorrect. I believe my suggestion for comparing values could improve this

@DelBiss
Copy link
Author

DelBiss commented Jan 6, 2026

I've removed the abstraction in the last commit.

But the Idea behind the abstraction was to have a better view of all the test and expected results.

Compare how those file look (look at line 104):

At first, I wanted even more abstraction with a matrix to generate all the test, but settle on this middle ground.

I will come back to this after my day job....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Automation filter 'not_equal' doesn't give the expected result when testing empty_value.

3 participants