mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-31 00:37:10 +02:00
fix(Google Sheets Node): Allow column reorder and insertion without erroring (#30621)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
78e4bcbbdf
commit
85f5221312
|
|
@ -473,18 +473,18 @@ describe('Test Google Sheets, lookupValues', () => {
|
|||
});
|
||||
|
||||
describe('Test Google Sheets, checkForSchemaChanges', () => {
|
||||
it('should not to throw error', async () => {
|
||||
const node: INode = {
|
||||
id: '1',
|
||||
name: 'Google Sheets',
|
||||
typeVersion: 4.4,
|
||||
type: 'n8n-nodes-base.googleSheets',
|
||||
position: [60, 760],
|
||||
parameters: {
|
||||
operation: 'append',
|
||||
},
|
||||
};
|
||||
const node: INode = {
|
||||
id: '1',
|
||||
name: 'Google Sheets',
|
||||
typeVersion: 4.4,
|
||||
type: 'n8n-nodes-base.googleSheets',
|
||||
position: [60, 760],
|
||||
parameters: {
|
||||
operation: 'append',
|
||||
},
|
||||
};
|
||||
|
||||
it('should not throw when columns match exactly', () => {
|
||||
expect(() =>
|
||||
checkForSchemaChanges(node, ['id', 'name', 'data'], [
|
||||
{ id: 'id' },
|
||||
|
|
@ -493,18 +493,8 @@ describe('Test Google Sheets, checkForSchemaChanges', () => {
|
|||
] as ResourceMapperField[]),
|
||||
).not.toThrow();
|
||||
});
|
||||
it('should throw error when columns were renamed', async () => {
|
||||
const node: INode = {
|
||||
id: '1',
|
||||
name: 'Google Sheets',
|
||||
typeVersion: 4.4,
|
||||
type: 'n8n-nodes-base.googleSheets',
|
||||
position: [60, 760],
|
||||
parameters: {
|
||||
operation: 'append',
|
||||
},
|
||||
};
|
||||
|
||||
it('should throw when a schema column is missing from the sheet', () => {
|
||||
expect(() =>
|
||||
checkForSchemaChanges(node, ['id', 'name', 'data'], [
|
||||
{ id: 'id' },
|
||||
|
|
@ -514,18 +504,7 @@ describe('Test Google Sheets, checkForSchemaChanges', () => {
|
|||
).toThrow("Column names were updated after the node's setup");
|
||||
});
|
||||
|
||||
it('should filter out empty columns without throwing an error', async () => {
|
||||
const node: INode = {
|
||||
id: '1',
|
||||
name: 'Google Sheets',
|
||||
typeVersion: 4.4,
|
||||
type: 'n8n-nodes-base.googleSheets',
|
||||
position: [60, 760],
|
||||
parameters: {
|
||||
operation: 'append',
|
||||
},
|
||||
};
|
||||
|
||||
it('should filter out empty columns without throwing', () => {
|
||||
expect(() =>
|
||||
checkForSchemaChanges(node, ['', '', 'id', 'name', 'data'], [
|
||||
{ id: 'id' },
|
||||
|
|
@ -534,6 +513,42 @@ describe('Test Google Sheets, checkForSchemaChanges', () => {
|
|||
] as ResourceMapperField[]),
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not throw when columns are reordered', () => {
|
||||
expect(() =>
|
||||
checkForSchemaChanges(node, ['data', 'id', 'name'], [
|
||||
{ id: 'id' },
|
||||
{ id: 'name' },
|
||||
{ id: 'data' },
|
||||
] as ResourceMapperField[]),
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not throw when new columns are inserted', () => {
|
||||
expect(() =>
|
||||
checkForSchemaChanges(node, ['id', 'owner_email', 'name', 'data'], [
|
||||
{ id: 'id' },
|
||||
{ id: 'name' },
|
||||
{ id: 'data' },
|
||||
] as ResourceMapperField[]),
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it('should throw and list only the missing columns', () => {
|
||||
try {
|
||||
checkForSchemaChanges(node, ['id', 'name'], [
|
||||
{ id: 'id' },
|
||||
{ id: 'name' },
|
||||
{ id: 'data' },
|
||||
] as ResourceMapperField[]);
|
||||
fail('Expected checkForSchemaChanges to throw');
|
||||
} catch (error) {
|
||||
expect(error.message).toBe("Column names were updated after the node's setup");
|
||||
expect(error.description).toBe(
|
||||
"Refresh the columns list in the 'Column to Match On' parameter. Missing columns: data",
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('Test Google Sheets, getSpreadsheetId', () => {
|
||||
|
|
|
|||
|
|
@ -360,26 +360,19 @@ export function checkForSchemaChanges(
|
|||
columnNames: string[],
|
||||
schema: ResourceMapperField[],
|
||||
) {
|
||||
const updatedColumnNames: Array<{ oldName: string; newName: string }> = [];
|
||||
// RMC filters out empty columns so do the same here
|
||||
columnNames = columnNames.filter((col) => col !== '');
|
||||
const liveColumns = new Set(columnNames.filter((col) => col !== ''));
|
||||
|
||||
// if sheet does not contain ROW_NUMBER ignore it as data come from read rows operation
|
||||
const schemaColumns = columnNames.includes(ROW_NUMBER)
|
||||
const schemaColumns = liveColumns.has(ROW_NUMBER)
|
||||
? schema.map((s) => s.id)
|
||||
: schema.filter((s) => s.id !== ROW_NUMBER).map((s) => s.id);
|
||||
|
||||
for (const [columnIndex, columnName] of columnNames.entries()) {
|
||||
const schemaEntry = schemaColumns[columnIndex];
|
||||
if (schemaEntry === undefined) break;
|
||||
if (columnName !== schemaEntry) {
|
||||
updatedColumnNames.push({ oldName: schemaEntry, newName: columnName });
|
||||
}
|
||||
}
|
||||
const missingColumns = schemaColumns.filter((col) => !liveColumns.has(col));
|
||||
|
||||
if (updatedColumnNames.length) {
|
||||
if (missingColumns.length) {
|
||||
throw new NodeOperationError(node, "Column names were updated after the node's setup", {
|
||||
description: `Refresh the columns list in the 'Column to Match On' parameter. Updated columns: ${updatedColumnNames.map((c) => `${c.oldName} -> ${c.newName}`).join(', ')}`,
|
||||
description: `Refresh the columns list in the 'Column to Match On' parameter. Missing columns: ${missingColumns.join(', ')}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user