mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-31 08:46:58 +02:00
more test fixes
This commit is contained in:
parent
a180c30007
commit
7f5f7bb36d
|
|
@ -20,6 +20,7 @@ import type { DataTableColumn } from '../data-table-column.entity';
|
|||
import type { DataTableUserTableName } from '../data-table.types';
|
||||
|
||||
import { NotFoundError } from '@/errors/response-errors/not-found.error';
|
||||
import { parsePath, toPostgresPath, toSQLitePath } from './path-utils';
|
||||
|
||||
export function toDslColumns(columns: DataTableCreateColumnSchema[]): DslColumn[] {
|
||||
return columns.map((col) => {
|
||||
|
|
@ -42,7 +43,7 @@ export function toDslColumns(columns: DataTableCreateColumnSchema[]): DslColumn[
|
|||
});
|
||||
}
|
||||
|
||||
function dataTableColumnTypeToSql(
|
||||
export function dataTableColumnTypeToSql(
|
||||
type: DataTableCreateColumnSchema['type'],
|
||||
dbType: DataSourceOptions['type'],
|
||||
) {
|
||||
|
|
@ -372,3 +373,49 @@ export function toTableName(dataTableId: string): DataTableUserTableName {
|
|||
export function toTableId(tableName: DataTableUserTableName) {
|
||||
return tableName.replace(/.*data_table_user_/, '');
|
||||
}
|
||||
|
||||
export function resolvePath(
|
||||
ref: string,
|
||||
dbType: DataSourceOptions['type'],
|
||||
value: unknown,
|
||||
path?: string,
|
||||
) {
|
||||
if (path) {
|
||||
const pathArray = parsePath(path);
|
||||
if (dbType === 'postgres') {
|
||||
const base = `${ref}${toPostgresPath(pathArray)}`;
|
||||
if (typeof value === 'number') {
|
||||
return `(${base})::numeric`;
|
||||
}
|
||||
if (value instanceof Date) {
|
||||
return `(${base})::timestamp`;
|
||||
}
|
||||
if (typeof value === 'boolean') {
|
||||
return `(${base})::boolean`;
|
||||
}
|
||||
|
||||
// by converting to text by default we end up with `true` for an equals NULL check
|
||||
// both for cases where the key exists and is literally NULL and where it doesn't exist
|
||||
return `(${base})::text`;
|
||||
} else {
|
||||
// this is mostly for sqlite, behavior in MariaDB and MySQL mostly aligns though there are subtle
|
||||
// difference we don't care for in the face of imminent removal of support
|
||||
const path = toSQLitePath(pathArray);
|
||||
const base = `json_extract(${ref}, '${path.replaceAll("'", "\\'")}')`;
|
||||
if (typeof value === 'number') {
|
||||
return `CAST(${base} as ${dataTableColumnTypeToSql('number', dbType)})`;
|
||||
}
|
||||
if (value instanceof Date) {
|
||||
return `CAST(${base} as ${dataTableColumnTypeToSql('date', dbType)}})`;
|
||||
}
|
||||
if (typeof value === 'boolean') {
|
||||
return `CAST(${base} as ${dataTableColumnTypeToSql('boolean', dbType)}})`;
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
return `CAST(${base} AS ${dataTableColumnTypeToSql('string', dbType)}})`;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,15 +163,10 @@ export function dataObjectToApiInput(
|
|||
if (v === undefined || v === null) return [k, null];
|
||||
|
||||
if (Array.isArray(v)) {
|
||||
const z = v as GenericValue[] | IDataObject[];
|
||||
return [
|
||||
k,
|
||||
z.map((x) =>
|
||||
typeof x === 'object' && x !== null
|
||||
? dataObjectToApiInput(x as IDataObject, node, row)
|
||||
: (x ?? null),
|
||||
),
|
||||
];
|
||||
throw new NodeOperationError(
|
||||
node,
|
||||
`unexpected array input '${JSON.stringify(v)}' in row ${row}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (v instanceof Date) {
|
||||
|
|
|
|||
|
|
@ -107,18 +107,6 @@ describe('dataObjectToApiInput', () => {
|
|||
expect(result.createdAt).toBeInstanceOf(Date);
|
||||
expect((result.createdAt as Date).toISOString()).toBe('2025-09-01T12:00:00.000Z');
|
||||
});
|
||||
|
||||
it('should handle date-like objects where toISOString throws', () => {
|
||||
const dateLikeObject = {
|
||||
toISOString: () => {
|
||||
throw new Error('toISOString failed');
|
||||
},
|
||||
};
|
||||
const input = { createdAt: dateLikeObject, name: 'test' };
|
||||
|
||||
expect(() => dataObjectToApiInput(input, mockNode, 0)).toThrow(NodeOperationError);
|
||||
expect(() => dataObjectToApiInput(input, mockNode, 0)).toThrow('unexpected object input');
|
||||
});
|
||||
});
|
||||
|
||||
describe('error cases', () => {
|
||||
|
|
@ -134,17 +122,8 @@ describe('dataObjectToApiInput', () => {
|
|||
it('should throw error for plain objects', () => {
|
||||
const input = { metadata: { key: 'value' } };
|
||||
|
||||
expect(() => dataObjectToApiInput(input, mockNode, 0)).toThrow(NodeOperationError);
|
||||
expect(() => dataObjectToApiInput(input, mockNode, 0)).toThrow(
|
||||
'unexpected object input \'{"key":"value"}\' in row 0',
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw error for objects without toISOString method', () => {
|
||||
const input = { config: { setting1: true, setting2: 'value' } };
|
||||
|
||||
expect(() => dataObjectToApiInput(input, mockNode, 0)).toThrow(NodeOperationError);
|
||||
expect(() => dataObjectToApiInput(input, mockNode, 0)).toThrow('unexpected object input');
|
||||
const result = dataObjectToApiInput(input, mockNode, 0);
|
||||
expect(result).toEqual(input);
|
||||
});
|
||||
|
||||
test('dataObjectToApiInput throws on invalid date-like object', () => {
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ export type DataTableColumnJsType =
|
|||
| boolean
|
||||
| Date
|
||||
| { [k: string | number]: DataTableColumnJsType }
|
||||
| DataTableColumnJsType[]
|
||||
| null;
|
||||
|
||||
export const DATA_TABLE_SYSTEM_COLUMN_TYPE_MAP: Record<string, DataTableColumnType> = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user