fix(Postgres Node): RMC do not mark collumn as required if identity_generation is BY DEFAULT (#13752)

Co-authored-by: Dana <152518854+dana-gill@users.noreply.github.com>
This commit is contained in:
Michael Kret
2025-03-13 07:35:50 +02:00
committed by GitHub
parent ec8a719efa
commit b5632545c5
7 changed files with 149 additions and 9 deletions

View File

@@ -713,6 +713,51 @@ describe('Test PostgresV2, insert operation', () => {
expect(hasJsonDataTypeInSchemaSpy).toHaveBeenCalledWith(columnsInfo);
});
});
it('should insert default values if no values are provided', async () => {
const nodeParameters: IDataObject = {
schema: {
__rl: true,
mode: 'list',
value: 'public',
},
table: {
__rl: true,
value: 'my_table',
mode: 'list',
},
dataMode: 'defineBelow',
valuesToSend: {
values: [],
},
options: { nodeVersion: 2.6 },
};
const columnsInfo: ColumnInfo[] = [
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO', udt_name: '' },
];
const nodeOptions = nodeParameters.options as IDataObject;
await insert.execute.call(
createMockExecuteFunction(nodeParameters),
runQueries,
items,
nodeOptions,
createMockDb(columnsInfo),
pgPromise(),
);
expect(runQueries).toHaveBeenCalledWith(
[
{
query: 'INSERT INTO $1:name.$2:name DEFAULT VALUES RETURNING *',
values: ['public', 'my_table', {}],
},
],
items,
nodeOptions,
);
});
});
describe('Test PostgresV2, select operation', () => {

View File

@@ -0,0 +1,88 @@
import type { MockProxy } from 'jest-mock-extended';
import { mock } from 'jest-mock-extended';
import type { ILoadOptionsFunctions } from 'n8n-workflow';
import { getMappingColumns } from '../../v2/methods/resourceMapping';
jest.mock('../../transport', () => {
const originalModule = jest.requireActual('../../transport');
return {
...originalModule,
configurePostgres: jest.fn(async () => ({ db: {} })),
};
});
jest.mock('../../v2/helpers/utils', () => {
const originalModule = jest.requireActual('../../v2/helpers/utils');
return {
...originalModule,
getEnums: jest.fn(() => []),
getEnumValues: jest.fn(),
getTableSchema: jest.fn(() => [
{
column_name: 'id',
data_type: 'bigint',
is_nullable: 'NO',
udt_name: 'int8',
column_default: null,
identity_generation: 'BY DEFAULT',
is_generated: 'NEVER',
},
{
column_name: 'name',
data_type: 'text',
is_nullable: 'YES',
udt_name: 'text',
column_default: null,
identity_generation: null,
is_generated: 'NEVER',
},
]),
};
});
describe('Postgres, resourceMapping', () => {
let loadOptionsFunctions: MockProxy<ILoadOptionsFunctions>;
beforeEach(() => {
loadOptionsFunctions = mock<ILoadOptionsFunctions>();
});
afterEach(() => {
jest.resetAllMocks();
});
it('should mark id as not required if identity_generation is "BY_DEFAULT"', async () => {
loadOptionsFunctions.getCredentials.mockResolvedValue({});
loadOptionsFunctions.getNodeParameter.mockReturnValueOnce('public');
loadOptionsFunctions.getNodeParameter.mockReturnValueOnce('test_table');
loadOptionsFunctions.getNodeParameter.mockReturnValueOnce('insert');
const fields = await getMappingColumns.call(loadOptionsFunctions);
expect(fields).toEqual({
fields: [
{
canBeUsedToMatch: true,
defaultMatch: true,
display: true,
displayName: 'id',
id: 'id',
options: undefined,
required: false,
type: 'number',
},
{
canBeUsedToMatch: true,
defaultMatch: false,
display: true,
displayName: 'name',
id: 'name',
options: undefined,
required: false,
type: 'string',
},
],
});
});
});

View File

@@ -146,15 +146,15 @@ describe('Test PostgresV2, parsePostgresError', () => {
it('should update message with syntax error', () => {
// eslint-disable-next-line n8n-local-rules/no-unneeded-backticks
const errorMessage = String.raw`syntax error at or near "seelect"`;
const errorMessage = String.raw`syntax error at or near "select"`;
const error = new Error();
error.message = errorMessage;
const parsedError = parsePostgresError(node, error, [
{ query: 'seelect * from my_table', values: [] },
{ query: 'select * from my_table', values: [] },
]);
expect(parsedError).toBeDefined();
expect(parsedError.message).toEqual('Syntax error at line 1 near "seelect"');
expect(parsedError.message).toEqual('Syntax error at line 1 near "select"');
expect(parsedError instanceof NodeOperationError).toEqual(true);
});
});
@@ -201,7 +201,7 @@ describe('Test PostgresV2, addWhereClauses', () => {
expect(updatedValues).toEqual(['public', 'my_table', 'id', '1', 'foo', 'select 2']);
});
it('should ignore incorect combine conition ad use AND', () => {
it('should ignore incorrect combine condition ad use AND', () => {
const query = 'SELECT * FROM $1:name.$2:name';
const values = ['public', 'my_table'];
const whereClauses = [
@@ -246,7 +246,7 @@ describe('Test PostgresV2, addSortRules', () => {
expect(updatedQuery).toEqual('SELECT * FROM $1:name.$2:name ORDER BY $3:name DESC');
expect(updatedValues).toEqual(['public', 'my_table', 'id']);
});
it('should ignore incorect direction', () => {
it('should ignore incorrect direction', () => {
const query = 'SELECT * FROM $1:name.$2:name';
const values = ['public', 'my_table'];
const sortRules = [{ column: 'id', direction: 'SELECT * FROM my_table' }];
@@ -340,7 +340,7 @@ describe('Test PostgresV2, replaceEmptyStringsByNulls', () => {
});
describe('Test PostgresV2, prepareItem', () => {
it('should convert fixedColections values to object', () => {
it('should convert fixedCollection values to object', () => {
const values = [
{
column: 'id',