mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-19 19:11:13 +00:00
feat(Data Table Node): Add new filters to node operation conditions (no-changelog) (#18942)
Co-authored-by: Charlie Kolb <charlie@n8n.io>
This commit is contained in:
@@ -6,7 +6,7 @@ import {
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import type { FieldEntry } from '../../common/constants';
|
||||
import { ANY_FILTER } from '../../common/constants';
|
||||
import { ANY_FILTER, ALL_FILTERS } from '../../common/constants';
|
||||
import { DATA_TABLE_ID_FIELD } from '../../common/fields';
|
||||
import { executeSelectMany } from '../../common/selectMany';
|
||||
|
||||
@@ -56,6 +56,7 @@ describe('selectMany utils', () => {
|
||||
// ASSERT
|
||||
expect(result).toEqual([{ json: { id: 1 } }]);
|
||||
});
|
||||
|
||||
it('should get a paginated amount of rows', async () => {
|
||||
// ARRANGE
|
||||
getManyRowsAndCount.mockReturnValueOnce({
|
||||
@@ -82,6 +83,7 @@ describe('selectMany utils', () => {
|
||||
expect(result[0]).toEqual({ json: { id: 0 } });
|
||||
expect(result[2344]).toEqual({ json: { id: 2344 } });
|
||||
});
|
||||
|
||||
it('should pass null through correctly', async () => {
|
||||
// ARRANGE
|
||||
getManyRowsAndCount.mockReturnValue({ data: [{ id: 1, colA: null }], count: 1 });
|
||||
@@ -92,6 +94,7 @@ describe('selectMany utils', () => {
|
||||
// ASSERT
|
||||
expect(result).toEqual([{ json: { id: 1, colA: null } }]);
|
||||
});
|
||||
|
||||
it('should panic if pagination gets out of sync', async () => {
|
||||
// ARRANGE
|
||||
getManyRowsAndCount.mockReturnValueOnce({
|
||||
@@ -113,5 +116,217 @@ describe('selectMany utils', () => {
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
describe('filter conditions', () => {
|
||||
it('should handle "eq" condition', async () => {
|
||||
// ARRANGE
|
||||
filters = [{ condition: 'eq', keyName: 'name', keyValue: 'John' }];
|
||||
getManyRowsAndCount.mockReturnValue({ data: [{ id: 1, name: 'John' }], count: 1 });
|
||||
|
||||
// ACT
|
||||
const result = await executeSelectMany(mockExecuteFunctions, 0, dataStoreProxy);
|
||||
|
||||
// ASSERT
|
||||
expect(result).toEqual([{ json: { id: 1, name: 'John' } }]);
|
||||
});
|
||||
|
||||
it('should handle "neq" condition', async () => {
|
||||
// ARRANGE
|
||||
filters = [{ condition: 'neq', keyName: 'name', keyValue: 'John' }];
|
||||
getManyRowsAndCount.mockReturnValue({ data: [{ id: 1, name: 'Jane' }], count: 1 });
|
||||
|
||||
// ACT
|
||||
const result = await executeSelectMany(mockExecuteFunctions, 0, dataStoreProxy);
|
||||
|
||||
// ASSERT
|
||||
expect(result).toEqual([{ json: { id: 1, name: 'Jane' } }]);
|
||||
});
|
||||
|
||||
it('should handle "gt" condition with numbers', async () => {
|
||||
// ARRANGE
|
||||
filters = [{ condition: 'gt', keyName: 'age', keyValue: 25 }];
|
||||
getManyRowsAndCount.mockReturnValue({ data: [{ id: 1, age: 30 }], count: 1 });
|
||||
|
||||
// ACT
|
||||
const result = await executeSelectMany(mockExecuteFunctions, 0, dataStoreProxy);
|
||||
|
||||
// ASSERT
|
||||
expect(result).toEqual([{ json: { id: 1, age: 30 } }]);
|
||||
});
|
||||
|
||||
it('should handle "gte" condition with numbers', async () => {
|
||||
// ARRANGE
|
||||
filters = [{ condition: 'gte', keyName: 'age', keyValue: 25 }];
|
||||
getManyRowsAndCount.mockReturnValue({
|
||||
data: [
|
||||
{ id: 1, age: 25 },
|
||||
{ id: 2, age: 30 },
|
||||
],
|
||||
count: 2,
|
||||
});
|
||||
|
||||
// ACT
|
||||
const result = await executeSelectMany(mockExecuteFunctions, 0, dataStoreProxy);
|
||||
|
||||
// ASSERT
|
||||
expect(result).toEqual([{ json: { id: 1, age: 25 } }, { json: { id: 2, age: 30 } }]);
|
||||
});
|
||||
|
||||
it('should handle "lt" condition with numbers', async () => {
|
||||
// ARRANGE
|
||||
filters = [{ condition: 'lt', keyName: 'age', keyValue: 30 }];
|
||||
getManyRowsAndCount.mockReturnValue({ data: [{ id: 1, age: 25 }], count: 1 });
|
||||
|
||||
// ACT
|
||||
const result = await executeSelectMany(mockExecuteFunctions, 0, dataStoreProxy);
|
||||
|
||||
// ASSERT
|
||||
expect(result).toEqual([{ json: { id: 1, age: 25 } }]);
|
||||
});
|
||||
|
||||
it('should handle "lte" condition with numbers', async () => {
|
||||
// ARRANGE
|
||||
filters = [{ condition: 'lte', keyName: 'age', keyValue: 30 }];
|
||||
getManyRowsAndCount.mockReturnValue({
|
||||
data: [
|
||||
{ id: 1, age: 25 },
|
||||
{ id: 2, age: 30 },
|
||||
],
|
||||
count: 2,
|
||||
});
|
||||
|
||||
// ACT
|
||||
const result = await executeSelectMany(mockExecuteFunctions, 0, dataStoreProxy);
|
||||
|
||||
// ASSERT
|
||||
expect(result).toEqual([{ json: { id: 1, age: 25 } }, { json: { id: 2, age: 30 } }]);
|
||||
});
|
||||
|
||||
it('should handle "like" condition with pattern matching', async () => {
|
||||
// ARRANGE
|
||||
filters = [{ condition: 'like', keyName: 'name', keyValue: '%Mar%' }];
|
||||
getManyRowsAndCount.mockReturnValue({ data: [{ id: 1, name: 'Anne-Marie' }], count: 1 });
|
||||
|
||||
// ACT
|
||||
const result = await executeSelectMany(mockExecuteFunctions, 0, dataStoreProxy);
|
||||
|
||||
// ASSERT
|
||||
expect(result).toEqual([{ json: { id: 1, name: 'Anne-Marie' } }]);
|
||||
});
|
||||
|
||||
it('should handle "ilike" condition with case-insensitive pattern matching', async () => {
|
||||
// ARRANGE
|
||||
filters = [{ condition: 'ilike', keyName: 'name', keyValue: '%mar%' }];
|
||||
getManyRowsAndCount.mockReturnValue({ data: [{ id: 1, name: 'Anne-Marie' }], count: 1 });
|
||||
|
||||
// ACT
|
||||
const result = await executeSelectMany(mockExecuteFunctions, 0, dataStoreProxy);
|
||||
|
||||
// ASSERT
|
||||
expect(result).toEqual([{ json: { id: 1, name: 'Anne-Marie' } }]);
|
||||
});
|
||||
|
||||
it('should handle multiple conditions with ANY_FILTER (OR logic - matches records satisfying either condition)', async () => {
|
||||
// ARRANGE
|
||||
filters = [
|
||||
{ condition: 'eq', keyName: 'status', keyValue: 'active' },
|
||||
{ condition: 'gt', keyName: 'age', keyValue: 50 },
|
||||
];
|
||||
getManyRowsAndCount.mockReturnValue({
|
||||
data: [{ id: 1, status: 'active', age: 25 }],
|
||||
count: 1,
|
||||
});
|
||||
|
||||
// ACT
|
||||
const result = await executeSelectMany(mockExecuteFunctions, 0, dataStoreProxy);
|
||||
|
||||
// ASSERT
|
||||
expect(result).toEqual([{ json: { id: 1, status: 'active', age: 25 } }]);
|
||||
});
|
||||
|
||||
it('should handle multiple conditions with ALL_FILTERS (AND logic - matches records satisfying all conditions)', async () => {
|
||||
// ARRANGE
|
||||
filters = [
|
||||
{ condition: 'eq', keyName: 'status', keyValue: 'active' },
|
||||
{ condition: 'gte', keyName: 'age', keyValue: 21 },
|
||||
];
|
||||
mockExecuteFunctions.getNodeParameter = jest.fn().mockImplementation((field) => {
|
||||
switch (field) {
|
||||
case DATA_TABLE_ID_FIELD:
|
||||
return dataTableId;
|
||||
case 'filters.conditions':
|
||||
return filters;
|
||||
case 'matchType':
|
||||
return ALL_FILTERS;
|
||||
}
|
||||
});
|
||||
getManyRowsAndCount.mockReturnValue({
|
||||
data: [{ id: 1, status: 'active', age: 25 }],
|
||||
count: 1,
|
||||
});
|
||||
|
||||
// ACT
|
||||
const result = await executeSelectMany(mockExecuteFunctions, 0, dataStoreProxy);
|
||||
|
||||
// ASSERT
|
||||
expect(result).toEqual([{ json: { id: 1, status: 'active', age: 25 } }]);
|
||||
});
|
||||
|
||||
it('should handle ALL_FILTERS excluding records that match only one condition (proves AND logic)', async () => {
|
||||
// ARRANGE
|
||||
filters = [
|
||||
{ condition: 'eq', keyName: 'status', keyValue: 'inactive' },
|
||||
{ condition: 'gte', keyName: 'age', keyValue: 21 },
|
||||
];
|
||||
mockExecuteFunctions.getNodeParameter = jest.fn().mockImplementation((field) => {
|
||||
switch (field) {
|
||||
case DATA_TABLE_ID_FIELD:
|
||||
return dataTableId;
|
||||
case 'filters.conditions':
|
||||
return filters;
|
||||
case 'matchType':
|
||||
return ALL_FILTERS;
|
||||
}
|
||||
});
|
||||
getManyRowsAndCount.mockReturnValue({
|
||||
data: [],
|
||||
count: 0,
|
||||
});
|
||||
|
||||
// ACT
|
||||
const result = await executeSelectMany(mockExecuteFunctions, 0, dataStoreProxy);
|
||||
|
||||
// ASSERT
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle ANY_FILTER including records that match only one condition (proves OR logic)', async () => {
|
||||
// ARRANGE
|
||||
filters = [
|
||||
{ condition: 'eq', keyName: 'status', keyValue: 'inactive' },
|
||||
{ condition: 'gte', keyName: 'age', keyValue: 21 },
|
||||
];
|
||||
mockExecuteFunctions.getNodeParameter = jest.fn().mockImplementation((field) => {
|
||||
switch (field) {
|
||||
case DATA_TABLE_ID_FIELD:
|
||||
return dataTableId;
|
||||
case 'filters.conditions':
|
||||
return filters;
|
||||
case 'matchType':
|
||||
return ANY_FILTER;
|
||||
}
|
||||
});
|
||||
getManyRowsAndCount.mockReturnValue({
|
||||
data: [{ id: 1, status: 'active', age: 25 }],
|
||||
count: 1,
|
||||
});
|
||||
|
||||
// ACT
|
||||
const result = await executeSelectMany(mockExecuteFunctions, 0, dataStoreProxy);
|
||||
|
||||
// ASSERT
|
||||
expect(result).toEqual([{ json: { id: 1, status: 'active', age: 25 } }]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user