fix(API): Allow false as a dependant value for public api json schema validation (#15858)

This commit is contained in:
Guillaume Jacquart
2025-05-30 14:11:21 +02:00
committed by GitHub
parent 4459c7e7b1
commit 5a8899c4c9
2 changed files with 77 additions and 1 deletions

View File

@@ -0,0 +1,71 @@
import type { GenericValue, IDataObject, INodeProperties } from 'n8n-workflow';
import type { IDependency } from '@/public-api/types';
import { toJsonSchema } from '../credentials.service';
describe('CredentialsService', () => {
describe('toJsonSchema', () => {
it('should add "false" displayOptions.show dependant value as allof condition', () => {
const properties: INodeProperties[] = [
{ name: 'field1', type: 'string', required: true, displayName: 'Field 1', default: '' },
{
name: 'field2',
type: 'options',
required: true,
options: [
{ value: 'opt1', name: 'opt1' },
{ value: 'opt2', name: 'opt2' },
],
displayName: 'Field 2',
default: 'opt1',
},
{
name: 'field3',
type: 'string',
displayName: 'Field 3',
default: '',
displayOptions: {
show: {
field2: [false], // boolean false as dependant value
},
},
},
];
const schema = toJsonSchema(properties);
// Cast properties as IDataObject
const props = schema.properties as IDataObject;
expect(props).toBeDefined();
expect(props.field1).toEqual({ type: 'string' });
expect(props.field2).toEqual({
type: 'string',
enum: ['opt1', 'opt2'],
});
expect(props.field3).toEqual({ type: 'string' });
// field1 and field2 required globally, field3 required conditionally
expect(schema.required).toEqual(expect.arrayContaining(['field1', 'field2']));
expect(schema.required).not.toContain('field3');
const allOf = schema.allOf as GenericValue[] | IDataObject[];
expect(Array.isArray(allOf)).toBe(true);
expect(allOf?.length).toBeGreaterThan(0);
const condition = allOf?.find((cond) => (cond as any).if?.properties?.field2) as IDependency;
expect(condition).toBeDefined();
expect((condition.if?.properties as any).field2).toEqual({
enum: [false], // boolean false as dependant value
});
// then block requires field3 when field2 === false
expect(condition.then?.allOf.some((req: any) => req.required?.includes('field3'))).toBe(true);
// else block forbids field3 when field2 !== false
expect(
condition.else?.allOf.some((notReq: any) => notReq.not?.required?.includes('field3')),
).toBe(true);
});
});
});

View File

@@ -206,7 +206,12 @@ export function toJsonSchema(properties: INodeProperties[]): IDataObject {
const displayOptionsValues = property.displayOptions.show[dependantName];
let dependantValue: DisplayCondition | string | number | boolean = '';
if (displayOptionsValues && Array.isArray(displayOptionsValues) && displayOptionsValues[0]) {
if (
displayOptionsValues &&
Array.isArray(displayOptionsValues) &&
displayOptionsValues[0] !== undefined &&
displayOptionsValues[0] !== null
) {
dependantValue = displayOptionsValues[0];
}