
* feat(compute-parameters): add valueType with parse option and string by default * test(compute-parameters): write tests for valueType with parse and undefined * fix(compute-parameters): cover valueType = parse in nested objects * test(compute-parameters): cover valueType = 'parse' in nested non-primitives * fix(compute-parameters): mark fields optional
488 lines
15 KiB
JavaScript
488 lines
15 KiB
JavaScript
import { beforeEach, describe, it, expect } from 'vitest';
|
|
import { createExecutionStep } from '../../test/factories/execution-step.js';
|
|
import { createDropdownArgument, createDynamicArgument, createStringArgument } from '../../test/factories/app.js';
|
|
import computeParameters from './compute-parameters.js';
|
|
|
|
const computeVariable = (stepId, path) => `{{step.${stepId}.${path}}}`;
|
|
|
|
describe('Compute parameters helper', () => {
|
|
let executionStepOne,
|
|
executionStepTwo,
|
|
executionStepThree,
|
|
executionSteps;
|
|
|
|
beforeEach(async () => {
|
|
executionStepOne = await createExecutionStep({
|
|
dataOut: {
|
|
step1Key1: 'plain text value for step1Key1',
|
|
// eslint-disable-next-line no-loss-of-precision
|
|
step1Key2: 1267963836502380617,
|
|
step1Key3: '1267963836502380617',
|
|
step1Key4: {
|
|
step1Key4ChildKey1: 'plain text value for step1Key3ChildKey1',
|
|
// eslint-disable-next-line no-loss-of-precision
|
|
step1Key4ChildKey2: 1267963836502380617,
|
|
step1Key4ChildKey3: '3650238061712679638',
|
|
step1Key4ChildKey4: ["value1", "value2"],
|
|
}
|
|
}
|
|
});
|
|
|
|
executionStepTwo = await createExecutionStep({
|
|
dataOut: {
|
|
step2Key1: 'plain text value for step2Key1',
|
|
// eslint-disable-next-line no-loss-of-precision
|
|
step2Key2: 6502380617126796383,
|
|
step2Key3: '6502380617126796383',
|
|
step2Key4: {
|
|
step2Key4ChildKey1: 'plain text value for step2Key3ChildKey1',
|
|
// eslint-disable-next-line no-loss-of-precision
|
|
step2Key4ChildKey2: 6502380617126796383,
|
|
step2Key4ChildKey3: '6502380617312679638',
|
|
step2Key4ChildKey4: ["value1", "value2"],
|
|
}
|
|
}
|
|
});
|
|
|
|
executionStepThree = await createExecutionStep({
|
|
dataOut: {
|
|
step3Key1: 'plain text value for step3Key1',
|
|
// eslint-disable-next-line no-loss-of-precision
|
|
step3Key2: 123123,
|
|
step3Key3: '123123',
|
|
step3Key4: {
|
|
step3Key4ChildKey1: 'plain text value for step3Key3ChildKey1',
|
|
// eslint-disable-next-line no-loss-of-precision
|
|
step3Key4ChildKey2: 123123,
|
|
step3Key4ChildKey3: '123123',
|
|
step3Key4ChildKey4: ["value1", "value2"],
|
|
}
|
|
}
|
|
});
|
|
|
|
executionSteps = [executionStepOne, executionStepTwo, executionStepThree];
|
|
});
|
|
|
|
it('should resolve with parameters having no corresponding steps', () => {
|
|
const parameters = {
|
|
key1: `${computeVariable('non-existent-step-id', 'non-existent-key')}`,
|
|
key2: `"${computeVariable('non-existent-step-id', 'non-existent-key')}" is the value for non-existent-key`,
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, [], executionSteps);
|
|
const expectedParameters = {
|
|
key1: '',
|
|
key2: '"" is the value for non-existent-key',
|
|
}
|
|
|
|
expect(computedParameters).toStrictEqual(expectedParameters);
|
|
});
|
|
|
|
describe('with no parameters', () => {
|
|
it('should resolve empty object', () => {
|
|
const parameters = {};
|
|
|
|
const computedParameters = computeParameters(parameters, [], executionSteps);
|
|
|
|
expect(computedParameters).toStrictEqual(parameters);
|
|
});
|
|
});
|
|
|
|
describe('with string parameters', () => {
|
|
let stepArguments;
|
|
beforeEach(() => {
|
|
stepArguments = [
|
|
createStringArgument({
|
|
key: 'key1',
|
|
}),
|
|
];
|
|
});
|
|
|
|
it('should resolve as-is without variables', () => {
|
|
const parameters = {
|
|
key1: 'plain text',
|
|
key2: 'plain text',
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
|
|
expect(computedParameters).toStrictEqual(parameters);
|
|
});
|
|
|
|
it('should preserve leading and trailing spaces', () => {
|
|
const parameters = {
|
|
key1: ' plain text ',
|
|
key2: 'plain text ',
|
|
key3: ' plain text',
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
|
|
expect(computedParameters).toStrictEqual(parameters);
|
|
});
|
|
|
|
it('should compute variables correctly', () => {
|
|
const parameters = {
|
|
key1: `static text ${computeVariable(executionStepOne.stepId, 'step1Key1')}`,
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
const expectedParameters = {
|
|
key1: `static text plain text value for step1Key1`,
|
|
};
|
|
|
|
expect(computedParameters).toStrictEqual(expectedParameters);
|
|
});
|
|
|
|
describe('with variables containing JSON', () => {
|
|
describe('without explicit valueType defined', () => {
|
|
let stepArguments;
|
|
beforeEach(() => {
|
|
stepArguments = [
|
|
createStringArgument({
|
|
key: 'key1',
|
|
}),
|
|
];
|
|
});
|
|
|
|
it('should resolve text + JSON value as-is', () => {
|
|
const parameters = {
|
|
key1: 'prepended text {"key": "value"} ',
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, executionSteps);
|
|
|
|
expect(computedParameters).toStrictEqual(parameters);
|
|
});
|
|
|
|
it('should resolve stringified JSON parsed', () => {
|
|
const parameters = {
|
|
key1: '{"key1": "plain text", "key2": "119007199254740999"}',
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
const expectedParameters = {
|
|
key1: '{"key1": "plain text", "key2": "119007199254740999"}',
|
|
};
|
|
|
|
expect(computedParameters).toStrictEqual(expectedParameters);
|
|
});
|
|
|
|
it('should handle arrays at root level', () => {
|
|
const parameters = {
|
|
key1: '["value1", "value2"]',
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
const expectedParameters = {
|
|
key1: '["value1", "value2"]',
|
|
};
|
|
|
|
expect(computedParameters).toStrictEqual(expectedParameters);
|
|
});
|
|
|
|
it('should handle arrays in nested level', () => {
|
|
const parameters = {
|
|
key1: '{"items": ["value1", "value2"]}',
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
const expectedParameters = {
|
|
key1: '{"items": ["value1", "value2"]}',
|
|
};
|
|
|
|
expect(computedParameters).toStrictEqual(expectedParameters);
|
|
});
|
|
|
|
it('should compute mix variables correctly', () => {
|
|
const parameters = {
|
|
key1: `another static text ${computeVariable(executionStepThree.stepId, 'step3Key4.step3Key4ChildKey4')}`,
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
const expectedParameters = {
|
|
key1: `another static text ["value1","value2"]`,
|
|
};
|
|
|
|
expect(computedParameters).toStrictEqual(expectedParameters);
|
|
});
|
|
|
|
it('should compute variables correctly', () => {
|
|
const parameters = {
|
|
key1: `${computeVariable(executionStepThree.stepId, 'step3Key4.step3Key4ChildKey4')}`,
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
const expectedParameters = {
|
|
key1: '["value1","value2"]',
|
|
};
|
|
|
|
expect(computedParameters).toStrictEqual(expectedParameters);
|
|
});
|
|
|
|
it('should not parse non-primitives in nested arrays', () => {
|
|
const stepArguments = [
|
|
createDynamicArgument({
|
|
key: 'inputs',
|
|
})
|
|
];
|
|
|
|
const parameters = {
|
|
inputs: [
|
|
{
|
|
key: 'person',
|
|
value: '{ "name": "John Doe", "age": 32 }',
|
|
}
|
|
],
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
const expectedParameters = {
|
|
inputs: [
|
|
{
|
|
key: 'person',
|
|
value: '{ "name": "John Doe", "age": 32 }',
|
|
}
|
|
],
|
|
};
|
|
|
|
expect(computedParameters).toStrictEqual(expectedParameters);
|
|
});
|
|
});
|
|
|
|
describe(`with valueType as 'parse'`, () => {
|
|
let stepArguments;
|
|
beforeEach(() => {
|
|
stepArguments = [
|
|
createStringArgument({
|
|
key: 'key1',
|
|
valueType: 'parse',
|
|
}),
|
|
];
|
|
});
|
|
|
|
it('should resolve text + JSON value as-is', () => {
|
|
const parameters = {
|
|
key1: 'prepended text {"key": "value"} ',
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
|
|
expect(computedParameters).toStrictEqual(parameters);
|
|
});
|
|
|
|
it('should resolve stringified JSON parsed', () => {
|
|
const parameters = {
|
|
key1: '{"key1": "plain text", "key2": "119007199254740999"}',
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
const expectedParameters = {
|
|
key1: {
|
|
key1: 'plain text',
|
|
key2: '119007199254740999',
|
|
},
|
|
};
|
|
|
|
expect(computedParameters).toStrictEqual(expectedParameters);
|
|
});
|
|
|
|
it('should handle arrays at root level', () => {
|
|
const parameters = {
|
|
key1: '["value1", "value2"]',
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
const expectedParameters = {
|
|
key1: ['value1', 'value2'],
|
|
};
|
|
|
|
expect(computedParameters).toStrictEqual(expectedParameters);
|
|
});
|
|
|
|
it('should handle arrays in nested level', () => {
|
|
const parameters = {
|
|
key1: '{"items": ["value1", "value2"]}',
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
const expectedParameters = {
|
|
key1: {
|
|
items: ['value1', 'value2'],
|
|
}
|
|
};
|
|
|
|
expect(computedParameters).toStrictEqual(expectedParameters);
|
|
});
|
|
|
|
it('should compute and parse mix variables correctly', () => {
|
|
const parameters = {
|
|
key1: `another static text ${computeVariable(executionStepThree.stepId, 'step3Key4.step3Key4ChildKey4')}`,
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
const expectedParameters = {
|
|
key1: `another static text ["value1","value2"]`,
|
|
};
|
|
|
|
expect(computedParameters).toStrictEqual(expectedParameters);
|
|
});
|
|
|
|
it('should compute and parse variables correctly', () => {
|
|
const parameters = {
|
|
key1: `${computeVariable(executionStepThree.stepId, 'step3Key4.step3Key4ChildKey4')}`,
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
const expectedParameters = {
|
|
key1: ["value1", "value2"],
|
|
};
|
|
|
|
expect(computedParameters).toStrictEqual(expectedParameters);
|
|
});
|
|
|
|
it('should compute and parse variables in nested arrays correctly', () => {
|
|
const stepArguments = [
|
|
createDynamicArgument({
|
|
key: 'inputs',
|
|
fields: [
|
|
{
|
|
label: 'Key',
|
|
key: 'key',
|
|
required: true,
|
|
variables: true,
|
|
},
|
|
{
|
|
label: 'Value',
|
|
key: 'value',
|
|
required: true,
|
|
variables: true,
|
|
valueType: 'parse',
|
|
}
|
|
],
|
|
})
|
|
];
|
|
|
|
const parameters = {
|
|
inputs: [
|
|
{
|
|
key: 'person',
|
|
value: '{ "name": "John Doe", "age": 32 }',
|
|
}
|
|
],
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
const expectedParameters = {
|
|
inputs: [
|
|
{
|
|
key: 'person',
|
|
value: {
|
|
name: 'John Doe',
|
|
age: 32,
|
|
}
|
|
}
|
|
],
|
|
};
|
|
|
|
expect(computedParameters).toStrictEqual(expectedParameters);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('with number parameters', () => {
|
|
let stepArguments;
|
|
beforeEach(() => {
|
|
stepArguments = [
|
|
createStringArgument({
|
|
key: 'key1',
|
|
}),
|
|
createStringArgument({
|
|
key: 'key2',
|
|
}),
|
|
];
|
|
});
|
|
|
|
it('should resolve number larger than MAX_SAFE_INTEGER correctly', () => {
|
|
const parameters = {
|
|
// eslint-disable-next-line no-loss-of-precision
|
|
key1: 119007199254740999,
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
|
|
expect(computedParameters).toStrictEqual(parameters);
|
|
expect(computedParameters.key1 > Number.MAX_SAFE_INTEGER).toBe(true);
|
|
});
|
|
|
|
it('should resolve stringified number as-is', () => {
|
|
const parameters = {
|
|
key1: '119007199254740999',
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
|
|
expect(computedParameters).toStrictEqual(parameters);
|
|
});
|
|
|
|
it('should compute variables with int values correctly', () => {
|
|
const parameters = {
|
|
key1: `another static text ${computeVariable(executionStepThree.stepId, 'step3Key2')}`,
|
|
key2: `${computeVariable(executionStepThree.stepId, 'step3Key3')}`
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
const expectedParameters = {
|
|
key1: `another static text 123123`,
|
|
key2: `123123`
|
|
};
|
|
|
|
expect(computedParameters).toStrictEqual(expectedParameters);
|
|
});
|
|
|
|
it.todo('should compute variables with bigint values correctly', () => {
|
|
const parameters = {
|
|
key1: `another static text ${computeVariable(executionStepTwo.stepId, 'step2Key2')}`,
|
|
key2: `${computeVariable(executionStepTwo.stepId, 'step2Key3')}`
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
const expectedParameters = {
|
|
// The expected `key2` is computed wrongly.
|
|
key1: `another static text 6502380617126796383`,
|
|
key2: `6502380617126796383`
|
|
};
|
|
|
|
expect(computedParameters).toStrictEqual(expectedParameters);
|
|
});
|
|
});
|
|
|
|
describe('with boolean parameters', () => {
|
|
let stepArguments;
|
|
beforeEach(() => {
|
|
stepArguments = [
|
|
createDropdownArgument({
|
|
key: 'key1',
|
|
}),
|
|
createDropdownArgument({
|
|
key: 'key2',
|
|
}),
|
|
];
|
|
});
|
|
|
|
it('should resolve boolean as-is', () => {
|
|
const parameters = {
|
|
key1: true,
|
|
key2: false,
|
|
};
|
|
|
|
const computedParameters = computeParameters(parameters, stepArguments, executionSteps);
|
|
|
|
expect(computedParameters).toStrictEqual(parameters);
|
|
expect(computedParameters.key1).toBe(true);
|
|
expect(computedParameters.key2).toBe(false);
|
|
});
|
|
});
|
|
});
|