first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
This commit is contained in:
+524
@@ -0,0 +1,524 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Test Summarize Node, aggregateAndSplitData should handle multiple split field values containing null when convertKeysToString is false: split-field-with-spaces-array 1`] = `
|
||||
[
|
||||
{
|
||||
"pairedItems": [
|
||||
0,
|
||||
],
|
||||
"returnData": {
|
||||
"Product": "Widget A",
|
||||
"Warehouse": "WH1",
|
||||
"appended_Warehouse": [
|
||||
"WH1",
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
"pairedItems": [
|
||||
2,
|
||||
],
|
||||
"returnData": {
|
||||
"Product": "Widget A",
|
||||
"Warehouse": null,
|
||||
"appended_Warehouse": [
|
||||
null,
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
"pairedItems": [
|
||||
1,
|
||||
],
|
||||
"returnData": {
|
||||
"Product": null,
|
||||
"Warehouse": "WH2",
|
||||
"appended_Warehouse": [
|
||||
"WH2",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Test Summarize Node, aggregateAndSplitData should handle multiple split field values containing null when convertKeysToString is false: split-field-with-spaces-result 1`] = `
|
||||
{
|
||||
"fieldName": "Product",
|
||||
"splits": Map {
|
||||
"Widget A" => {
|
||||
"fieldName": "Warehouse",
|
||||
"splits": Map {
|
||||
"WH1" => {
|
||||
"pairedItems": [
|
||||
0,
|
||||
],
|
||||
"returnData": {
|
||||
"appended_Warehouse": [
|
||||
"WH1",
|
||||
],
|
||||
},
|
||||
},
|
||||
null => {
|
||||
"pairedItems": [
|
||||
2,
|
||||
],
|
||||
"returnData": {
|
||||
"appended_Warehouse": [
|
||||
null,
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
null => {
|
||||
"fieldName": "Warehouse",
|
||||
"splits": Map {
|
||||
"WH2" => {
|
||||
"pairedItems": [
|
||||
1,
|
||||
],
|
||||
"returnData": {
|
||||
"appended_Warehouse": [
|
||||
"WH2",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test Summarize Node, aggregateAndSplitData should handle multiple split field values containing null when convertKeysToString is true: split-field-with-spaces-array 1`] = `
|
||||
[
|
||||
{
|
||||
"pairedItems": [
|
||||
0,
|
||||
],
|
||||
"returnData": {
|
||||
"Product": "Widget A",
|
||||
"Warehouse": "WH1",
|
||||
"appended_Warehouse": [
|
||||
"WH1",
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
"pairedItems": [
|
||||
2,
|
||||
],
|
||||
"returnData": {
|
||||
"Product": "Widget A",
|
||||
"Warehouse": "null",
|
||||
"appended_Warehouse": [
|
||||
null,
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
"pairedItems": [
|
||||
1,
|
||||
],
|
||||
"returnData": {
|
||||
"Product": "null",
|
||||
"Warehouse": "WH2",
|
||||
"appended_Warehouse": [
|
||||
"WH2",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Test Summarize Node, aggregateAndSplitData should handle multiple split field values containing null when convertKeysToString is true: split-field-with-spaces-result 1`] = `
|
||||
{
|
||||
"fieldName": "Product",
|
||||
"splits": Map {
|
||||
"Widget A" => {
|
||||
"fieldName": "Warehouse",
|
||||
"splits": Map {
|
||||
"WH1" => {
|
||||
"pairedItems": [
|
||||
0,
|
||||
],
|
||||
"returnData": {
|
||||
"appended_Warehouse": [
|
||||
"WH1",
|
||||
],
|
||||
},
|
||||
},
|
||||
"null" => {
|
||||
"pairedItems": [
|
||||
2,
|
||||
],
|
||||
"returnData": {
|
||||
"appended_Warehouse": [
|
||||
null,
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"null" => {
|
||||
"fieldName": "Warehouse",
|
||||
"splits": Map {
|
||||
"WH2" => {
|
||||
"pairedItems": [
|
||||
1,
|
||||
],
|
||||
"returnData": {
|
||||
"appended_Warehouse": [
|
||||
"WH2",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test Summarize Node, aggregateAndSplitData should handle split field values containing spaces when convertKeysToString is not set: split-field-with-spaces-array 1`] = `
|
||||
[
|
||||
{
|
||||
"pairedItems": [
|
||||
0,
|
||||
2,
|
||||
],
|
||||
"returnData": {
|
||||
"Product": "Widget A",
|
||||
"appended_Warehouse": [
|
||||
"WH1",
|
||||
"WH3",
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
"pairedItems": [
|
||||
1,
|
||||
],
|
||||
"returnData": {
|
||||
"Product": "Widget B",
|
||||
"appended_Warehouse": [
|
||||
"WH2",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Test Summarize Node, aggregateAndSplitData should handle split field values containing spaces when convertKeysToString is not set: split-field-with-spaces-result 1`] = `
|
||||
{
|
||||
"fieldName": "Product",
|
||||
"splits": Map {
|
||||
"Widget A" => {
|
||||
"pairedItems": [
|
||||
0,
|
||||
2,
|
||||
],
|
||||
"returnData": {
|
||||
"appended_Warehouse": [
|
||||
"WH1",
|
||||
"WH3",
|
||||
],
|
||||
},
|
||||
},
|
||||
"Widget B" => {
|
||||
"pairedItems": [
|
||||
1,
|
||||
],
|
||||
"returnData": {
|
||||
"appended_Warehouse": [
|
||||
"WH2",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test Summarize Node, aggregateAndSplitData should handle split field values containing spaces when convertKeysToString is true: split-field-with-spaces-array 1`] = `
|
||||
[
|
||||
{
|
||||
"pairedItems": [
|
||||
0,
|
||||
2,
|
||||
],
|
||||
"returnData": {
|
||||
"Product": "Widget A",
|
||||
"appended_Warehouse": [
|
||||
"WH1",
|
||||
"WH3",
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
"pairedItems": [
|
||||
1,
|
||||
],
|
||||
"returnData": {
|
||||
"Product": "Widget B",
|
||||
"appended_Warehouse": [
|
||||
"WH2",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Test Summarize Node, aggregateAndSplitData should handle split field values containing spaces when convertKeysToString is true: split-field-with-spaces-result 1`] = `
|
||||
{
|
||||
"fieldName": "Product",
|
||||
"splits": Map {
|
||||
"Widget A" => {
|
||||
"pairedItems": [
|
||||
0,
|
||||
2,
|
||||
],
|
||||
"returnData": {
|
||||
"appended_Warehouse": [
|
||||
"WH1",
|
||||
"WH3",
|
||||
],
|
||||
},
|
||||
},
|
||||
"Widget B" => {
|
||||
"pairedItems": [
|
||||
1,
|
||||
],
|
||||
"returnData": {
|
||||
"appended_Warehouse": [
|
||||
"WH2",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test Summarize Node, aggregateAndSplitData should not convert numbers to strings: array 1`] = `
|
||||
[
|
||||
{
|
||||
"pairedItems": [
|
||||
0,
|
||||
],
|
||||
"returnData": {
|
||||
"Qty": 1,
|
||||
"Sku": 12345,
|
||||
"appended_Warehouse": [
|
||||
"BER_0G",
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
"pairedItems": [
|
||||
1,
|
||||
],
|
||||
"returnData": {
|
||||
"Qty": 2,
|
||||
"Sku": 12345,
|
||||
"appended_Warehouse": [
|
||||
"BER_0L",
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
"pairedItems": [
|
||||
2,
|
||||
],
|
||||
"returnData": {
|
||||
"Qty": 1,
|
||||
"Sku": 6534563534,
|
||||
"appended_Warehouse": [
|
||||
"BER_0L",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Test Summarize Node, aggregateAndSplitData should not convert numbers to strings: result 1`] = `
|
||||
{
|
||||
"fieldName": "Sku",
|
||||
"splits": Map {
|
||||
12345 => {
|
||||
"fieldName": "Qty",
|
||||
"splits": Map {
|
||||
1 => {
|
||||
"pairedItems": [
|
||||
0,
|
||||
],
|
||||
"returnData": {
|
||||
"appended_Warehouse": [
|
||||
"BER_0G",
|
||||
],
|
||||
},
|
||||
},
|
||||
2 => {
|
||||
"pairedItems": [
|
||||
1,
|
||||
],
|
||||
"returnData": {
|
||||
"appended_Warehouse": [
|
||||
"BER_0L",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
6534563534 => {
|
||||
"fieldName": "Qty",
|
||||
"splits": Map {
|
||||
1 => {
|
||||
"pairedItems": [
|
||||
2,
|
||||
],
|
||||
"returnData": {
|
||||
"appended_Warehouse": [
|
||||
"BER_0L",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test Summarize Node, aggregateAndSplitData should not convert strings to numbers: array 1`] = `
|
||||
[
|
||||
{
|
||||
"pairedItems": [
|
||||
0,
|
||||
],
|
||||
"returnData": {
|
||||
"Qty": "1",
|
||||
"Sku": "012345",
|
||||
"appended_Warehouse": [
|
||||
"BER_0G",
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
"pairedItems": [
|
||||
1,
|
||||
],
|
||||
"returnData": {
|
||||
"Qty": "2",
|
||||
"Sku": "012345",
|
||||
"appended_Warehouse": [
|
||||
"BER_0L",
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
"pairedItems": [
|
||||
2,
|
||||
],
|
||||
"returnData": {
|
||||
"Qty": "1",
|
||||
"Sku": "06534563534",
|
||||
"appended_Warehouse": [
|
||||
"BER_0L",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Test Summarize Node, aggregateAndSplitData should not convert strings to numbers: result 1`] = `
|
||||
{
|
||||
"fieldName": "Sku",
|
||||
"splits": Map {
|
||||
"012345" => {
|
||||
"fieldName": "Qty",
|
||||
"splits": Map {
|
||||
"1" => {
|
||||
"pairedItems": [
|
||||
0,
|
||||
],
|
||||
"returnData": {
|
||||
"appended_Warehouse": [
|
||||
"BER_0G",
|
||||
],
|
||||
},
|
||||
},
|
||||
"2" => {
|
||||
"pairedItems": [
|
||||
1,
|
||||
],
|
||||
"returnData": {
|
||||
"appended_Warehouse": [
|
||||
"BER_0L",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"06534563534" => {
|
||||
"fieldName": "Qty",
|
||||
"splits": Map {
|
||||
"1" => {
|
||||
"pairedItems": [
|
||||
2,
|
||||
],
|
||||
"returnData": {
|
||||
"appended_Warehouse": [
|
||||
"BER_0L",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Test Summarize Node, aggregateAndSplitData with skipEmptySplitFields=true should skip empty split fields: array 1`] = `
|
||||
[
|
||||
{
|
||||
"pairedItems": [
|
||||
0,
|
||||
3,
|
||||
],
|
||||
"returnData": {
|
||||
"Sku": 12345,
|
||||
"concatenated_Warehouse": "BER_0G//{"name":"BER_0G3"}",
|
||||
},
|
||||
},
|
||||
{
|
||||
"pairedItems": [
|
||||
2,
|
||||
],
|
||||
"returnData": {
|
||||
"Sku": "{}",
|
||||
"concatenated_Warehouse": "BER_0L",
|
||||
},
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Test Summarize Node, aggregateAndSplitData with skipEmptySplitFields=true should skip empty split fields: result 1`] = `
|
||||
{
|
||||
"fieldName": "Sku",
|
||||
"splits": Map {
|
||||
12345 => {
|
||||
"pairedItems": [
|
||||
0,
|
||||
3,
|
||||
],
|
||||
"returnData": {
|
||||
"concatenated_Warehouse": "BER_0G//{"name":"BER_0G3"}",
|
||||
},
|
||||
},
|
||||
"{}" => {
|
||||
"pairedItems": [
|
||||
2,
|
||||
],
|
||||
"returnData": {
|
||||
"concatenated_Warehouse": "BER_0L",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
import { NodeOperationError, type IExecuteFunctions, type IDataObject } from 'n8n-workflow';
|
||||
|
||||
import { checkIfFieldExists, type Aggregations } from '../../utils';
|
||||
|
||||
describe('Test Summarize Node, checkIfFieldExists', () => {
|
||||
let mockExecuteFunctions: IExecuteFunctions;
|
||||
|
||||
beforeEach(() => {
|
||||
mockExecuteFunctions = {
|
||||
getNode: jest.fn().mockReturnValue({ name: 'test-node' }),
|
||||
} as unknown as IExecuteFunctions;
|
||||
});
|
||||
|
||||
const items = [{ a: 1 }, { b: 2 }, { c: 3 }];
|
||||
|
||||
it('should not throw error if all fields exist', () => {
|
||||
const aggregations: Aggregations = [
|
||||
{ aggregation: 'sum', field: 'a' },
|
||||
{ aggregation: 'count', field: 'c' },
|
||||
];
|
||||
const getValue = (item: IDataObject, field: string) => item[field];
|
||||
expect(() => {
|
||||
checkIfFieldExists.call(mockExecuteFunctions, items, aggregations, getValue);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should throw NodeOperationError if any field does not exist', () => {
|
||||
const aggregations: Aggregations = [
|
||||
{ aggregation: 'sum', field: 'b' },
|
||||
{ aggregation: 'count', field: 'd' },
|
||||
];
|
||||
const getValue = (item: IDataObject, field: string) => item[field];
|
||||
expect(() => {
|
||||
checkIfFieldExists.call(mockExecuteFunctions, items, aggregations, getValue);
|
||||
}).toThrow(NodeOperationError);
|
||||
});
|
||||
|
||||
it("should throw NodeOperationError with error message containing the field name that doesn't exist", () => {
|
||||
const aggregations: Aggregations = [{ aggregation: 'count', field: 'D' }];
|
||||
const getValue = (item: IDataObject, field: string) => item[field];
|
||||
expect(() => {
|
||||
checkIfFieldExists.call(mockExecuteFunctions, items, aggregations, getValue);
|
||||
}).toThrow("The field 'D' does not exist in any items");
|
||||
});
|
||||
|
||||
it('should not throw error if field is empty string', () => {
|
||||
const aggregations: Aggregations = [{ aggregation: 'count', field: '' }];
|
||||
const getValue = (item: IDataObject, field: string) => item[field];
|
||||
expect(() => {
|
||||
checkIfFieldExists.call(mockExecuteFunctions, items, aggregations, getValue);
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,77 @@
|
||||
import type { MockProxy } from 'jest-mock-extended';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import type { IExecuteFunctions } from 'n8n-workflow';
|
||||
import { NodeOperationError } from 'n8n-workflow';
|
||||
|
||||
import { Summarize } from '../../Summarize.node';
|
||||
import type { Aggregations } from '../../utils';
|
||||
|
||||
let summarizeNode: Summarize;
|
||||
let mockExecuteFunctions: MockProxy<IExecuteFunctions>;
|
||||
|
||||
describe('Test Summarize Node, execute', () => {
|
||||
beforeEach(() => {
|
||||
summarizeNode = new Summarize();
|
||||
mockExecuteFunctions = mock<IExecuteFunctions>({
|
||||
getNode: jest.fn().mockReturnValue({ name: 'test-node' }),
|
||||
getNodeParameter: jest.fn(),
|
||||
getInputData: jest.fn(),
|
||||
helpers: {
|
||||
constructExecutionMetaData: jest.fn().mockReturnValue([]),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should handle field not found with hints if version > 1', async () => {
|
||||
mockExecuteFunctions.getInputData.mockReturnValue([{ json: { someField: 1 } }]);
|
||||
mockExecuteFunctions.getNode.mockReturnValue({
|
||||
id: '1',
|
||||
name: 'test-node',
|
||||
type: 'test-type',
|
||||
position: [0, 0],
|
||||
parameters: {},
|
||||
typeVersion: 1.1,
|
||||
});
|
||||
mockExecuteFunctions.getNodeParameter
|
||||
.mockReturnValueOnce({}) // options
|
||||
.mockReturnValueOnce('') // fieldsToSplitBy
|
||||
.mockReturnValueOnce([{ field: 'nonexistentField', aggregation: 'sum' }]); // fieldsToSummarize
|
||||
|
||||
const result = await summarizeNode.execute.call(mockExecuteFunctions);
|
||||
|
||||
expect(result).toEqual([[{ json: { sum_nonexistentField: 0 }, pairedItem: [{ item: 0 }] }]]);
|
||||
expect(mockExecuteFunctions.addExecutionHints).toHaveBeenCalledWith({
|
||||
location: 'outputPane',
|
||||
message: "The field 'nonexistentField' does not exist in any items",
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw error if node version is < 1.1 and fields not found', async () => {
|
||||
const items = [{ json: { a: 1, b: 2, c: 3 } }];
|
||||
const aggregations: Aggregations = [
|
||||
{ aggregation: 'sum', field: 'b' },
|
||||
{ aggregation: 'count', field: 'd' },
|
||||
];
|
||||
|
||||
mockExecuteFunctions.getNode.mockReturnValue({
|
||||
id: '1',
|
||||
name: 'test-node',
|
||||
type: 'test-type',
|
||||
position: [0, 0],
|
||||
parameters: {},
|
||||
typeVersion: 1,
|
||||
});
|
||||
mockExecuteFunctions.getInputData.mockReturnValue(items);
|
||||
mockExecuteFunctions.getNodeParameter
|
||||
.mockReturnValueOnce({}) // options
|
||||
.mockReturnValueOnce('') // fieldsToSplitBy
|
||||
.mockReturnValueOnce(aggregations); // fieldsToSummarize
|
||||
await expect(async () => {
|
||||
await summarizeNode.execute.bind(mockExecuteFunctions)();
|
||||
}).rejects.toThrow(NodeOperationError);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,314 @@
|
||||
import {
|
||||
fieldValueGetter,
|
||||
aggregateAndSplitData,
|
||||
flattenAggregationResultToArray,
|
||||
type Aggregations,
|
||||
} from '../../utils';
|
||||
|
||||
describe('Test Summarize Node, aggregateAndSplitData', () => {
|
||||
test('should not convert strings to numbers', () => {
|
||||
const data = [
|
||||
{
|
||||
Sku: '012345',
|
||||
Warehouse: 'BER_0G',
|
||||
Qty: '1',
|
||||
_itemIndex: 0,
|
||||
},
|
||||
{
|
||||
Sku: '012345',
|
||||
Warehouse: 'BER_0L',
|
||||
Qty: '2',
|
||||
_itemIndex: 1,
|
||||
},
|
||||
{
|
||||
Sku: '06534563534',
|
||||
Warehouse: 'BER_0L',
|
||||
Qty: '1',
|
||||
_itemIndex: 2,
|
||||
},
|
||||
];
|
||||
|
||||
const aggregations: Aggregations = [
|
||||
{
|
||||
aggregation: 'append',
|
||||
field: 'Warehouse',
|
||||
includeEmpty: true,
|
||||
},
|
||||
];
|
||||
|
||||
const result = aggregateAndSplitData({
|
||||
splitKeys: ['Sku', 'Qty'],
|
||||
inputItems: data,
|
||||
fieldsToSummarize: aggregations,
|
||||
options: { continueIfFieldNotFound: true },
|
||||
getValue: fieldValueGetter(),
|
||||
});
|
||||
expect(result).toMatchSnapshot('result');
|
||||
expect(flattenAggregationResultToArray(result)).toMatchSnapshot('array');
|
||||
});
|
||||
|
||||
test('should not convert numbers to strings', () => {
|
||||
const data = [
|
||||
{
|
||||
Sku: 12345,
|
||||
Warehouse: 'BER_0G',
|
||||
Qty: 1,
|
||||
_itemIndex: 0,
|
||||
},
|
||||
{
|
||||
Sku: 12345,
|
||||
Warehouse: 'BER_0L',
|
||||
Qty: 2,
|
||||
_itemIndex: 1,
|
||||
},
|
||||
{
|
||||
Sku: 6534563534,
|
||||
Warehouse: 'BER_0L',
|
||||
Qty: 1,
|
||||
_itemIndex: 2,
|
||||
},
|
||||
];
|
||||
|
||||
const aggregations: Aggregations = [
|
||||
{
|
||||
aggregation: 'append',
|
||||
field: 'Warehouse',
|
||||
includeEmpty: true,
|
||||
},
|
||||
];
|
||||
|
||||
const result = aggregateAndSplitData({
|
||||
splitKeys: ['Sku', 'Qty'],
|
||||
inputItems: data,
|
||||
fieldsToSummarize: aggregations,
|
||||
options: { continueIfFieldNotFound: true },
|
||||
getValue: fieldValueGetter(),
|
||||
});
|
||||
expect(result).toMatchSnapshot('result');
|
||||
expect(flattenAggregationResultToArray(result)).toMatchSnapshot('array');
|
||||
});
|
||||
|
||||
test('should handle split field values containing spaces when convertKeysToString is not set', () => {
|
||||
const data = [
|
||||
{
|
||||
Product: 'Widget A',
|
||||
Warehouse: 'WH1',
|
||||
Qty: '5',
|
||||
_itemIndex: 0,
|
||||
},
|
||||
{
|
||||
Product: 'Widget B',
|
||||
Warehouse: 'WH2',
|
||||
Qty: '3',
|
||||
_itemIndex: 1,
|
||||
},
|
||||
{
|
||||
Product: 'Widget A',
|
||||
Warehouse: 'WH3',
|
||||
Qty: '2',
|
||||
_itemIndex: 2,
|
||||
},
|
||||
];
|
||||
|
||||
const aggregations: Aggregations = [
|
||||
{
|
||||
aggregation: 'append',
|
||||
field: 'Warehouse',
|
||||
includeEmpty: true,
|
||||
},
|
||||
];
|
||||
|
||||
const result = aggregateAndSplitData({
|
||||
splitKeys: ['Product'],
|
||||
inputItems: data,
|
||||
fieldsToSummarize: aggregations,
|
||||
options: { continueIfFieldNotFound: true },
|
||||
getValue: fieldValueGetter(),
|
||||
});
|
||||
|
||||
expect(result).toMatchSnapshot('split-field-with-spaces-result');
|
||||
expect(flattenAggregationResultToArray(result)).toMatchSnapshot(
|
||||
'split-field-with-spaces-array',
|
||||
);
|
||||
});
|
||||
|
||||
test('should handle split field values containing spaces when convertKeysToString is true', () => {
|
||||
const data = [
|
||||
{
|
||||
Product: 'Widget A',
|
||||
Warehouse: 'WH1',
|
||||
Qty: '5',
|
||||
_itemIndex: 0,
|
||||
},
|
||||
{
|
||||
Product: 'Widget B',
|
||||
Warehouse: 'WH2',
|
||||
Qty: '3',
|
||||
_itemIndex: 1,
|
||||
},
|
||||
{
|
||||
Product: 'Widget A',
|
||||
Warehouse: 'WH3',
|
||||
Qty: '2',
|
||||
_itemIndex: 2,
|
||||
},
|
||||
];
|
||||
|
||||
const aggregations: Aggregations = [
|
||||
{
|
||||
aggregation: 'append',
|
||||
field: 'Warehouse',
|
||||
includeEmpty: true,
|
||||
},
|
||||
];
|
||||
|
||||
const result = aggregateAndSplitData({
|
||||
splitKeys: ['Product'],
|
||||
inputItems: data,
|
||||
fieldsToSummarize: aggregations,
|
||||
options: { continueIfFieldNotFound: true },
|
||||
getValue: fieldValueGetter(),
|
||||
convertKeysToString: true,
|
||||
});
|
||||
|
||||
expect(result).toMatchSnapshot('split-field-with-spaces-result');
|
||||
expect(flattenAggregationResultToArray(result)).toMatchSnapshot(
|
||||
'split-field-with-spaces-array',
|
||||
);
|
||||
});
|
||||
|
||||
test('should handle multiple split field values containing null when convertKeysToString is true', () => {
|
||||
const data = [
|
||||
{
|
||||
Product: 'Widget A',
|
||||
Warehouse: 'WH1',
|
||||
Qty: '5',
|
||||
_itemIndex: 0,
|
||||
},
|
||||
{
|
||||
Product: null,
|
||||
Warehouse: 'WH2',
|
||||
Qty: '3',
|
||||
_itemIndex: 1,
|
||||
},
|
||||
{
|
||||
Product: 'Widget A',
|
||||
Warehouse: null,
|
||||
Qty: '2',
|
||||
_itemIndex: 2,
|
||||
},
|
||||
];
|
||||
|
||||
const aggregations: Aggregations = [
|
||||
{
|
||||
aggregation: 'append',
|
||||
field: 'Warehouse',
|
||||
includeEmpty: true,
|
||||
},
|
||||
];
|
||||
|
||||
const result = aggregateAndSplitData({
|
||||
splitKeys: ['Product', 'Warehouse'],
|
||||
inputItems: data,
|
||||
fieldsToSummarize: aggregations,
|
||||
options: { continueIfFieldNotFound: true },
|
||||
getValue: fieldValueGetter(),
|
||||
convertKeysToString: true,
|
||||
});
|
||||
|
||||
expect(result).toMatchSnapshot('split-field-with-spaces-result');
|
||||
expect(flattenAggregationResultToArray(result)).toMatchSnapshot(
|
||||
'split-field-with-spaces-array',
|
||||
);
|
||||
});
|
||||
|
||||
test('should handle multiple split field values containing null when convertKeysToString is false', () => {
|
||||
const data = [
|
||||
{
|
||||
Product: 'Widget A',
|
||||
Warehouse: 'WH1',
|
||||
Qty: '5',
|
||||
_itemIndex: 0,
|
||||
},
|
||||
{
|
||||
Product: null,
|
||||
Warehouse: 'WH2',
|
||||
Qty: '3',
|
||||
_itemIndex: 1,
|
||||
},
|
||||
{
|
||||
Product: 'Widget A',
|
||||
Warehouse: null,
|
||||
Qty: '2',
|
||||
_itemIndex: 2,
|
||||
},
|
||||
];
|
||||
|
||||
const aggregations: Aggregations = [
|
||||
{
|
||||
aggregation: 'append',
|
||||
field: 'Warehouse',
|
||||
includeEmpty: true,
|
||||
},
|
||||
];
|
||||
|
||||
const result = aggregateAndSplitData({
|
||||
splitKeys: ['Product', 'Warehouse'],
|
||||
inputItems: data,
|
||||
fieldsToSummarize: aggregations,
|
||||
options: { continueIfFieldNotFound: true },
|
||||
getValue: fieldValueGetter(),
|
||||
convertKeysToString: false,
|
||||
});
|
||||
|
||||
expect(result).toMatchSnapshot('split-field-with-spaces-result');
|
||||
expect(flattenAggregationResultToArray(result)).toMatchSnapshot(
|
||||
'split-field-with-spaces-array',
|
||||
);
|
||||
});
|
||||
|
||||
describe('with skipEmptySplitFields=true', () => {
|
||||
test('should skip empty split fields', () => {
|
||||
const data = [
|
||||
{
|
||||
Sku: 12345,
|
||||
Warehouse: 'BER_0G',
|
||||
_itemIndex: 0,
|
||||
},
|
||||
{
|
||||
Warehouse: 'BER_0L',
|
||||
_itemIndex: 1,
|
||||
},
|
||||
{
|
||||
Sku: {},
|
||||
Warehouse: 'BER_0L',
|
||||
_itemIndex: 2,
|
||||
},
|
||||
{
|
||||
Sku: 12345,
|
||||
Warehouse: { name: 'BER_0G3' },
|
||||
_itemIndex: 3,
|
||||
},
|
||||
];
|
||||
|
||||
const aggregations: Aggregations = [
|
||||
{
|
||||
aggregation: 'concatenate',
|
||||
field: 'Warehouse',
|
||||
separateBy: 'other',
|
||||
customSeparator: '//',
|
||||
},
|
||||
];
|
||||
|
||||
const result = aggregateAndSplitData({
|
||||
splitKeys: ['Sku'],
|
||||
inputItems: data,
|
||||
fieldsToSummarize: aggregations,
|
||||
options: { continueIfFieldNotFound: true, skipEmptySplitFields: true },
|
||||
getValue: fieldValueGetter(),
|
||||
});
|
||||
expect(result).toMatchSnapshot('result');
|
||||
expect(flattenAggregationResultToArray(result)).toMatchSnapshot('array');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user