more test fixes

This commit is contained in:
Charlie Kolb 2025-10-17 09:51:16 +02:00
parent a180c30007
commit 7f5f7bb36d
No known key found for this signature in database
4 changed files with 54 additions and 34 deletions

View File

@ -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;
}

View File

@ -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) {

View File

@ -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', () => {

View File

@ -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> = {