first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
import type { ILoadOptionsFunctions } from 'n8n-workflow';
|
||||
import { NodeOperationError } from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
getSheetHeaderRow,
|
||||
getSheetHeaderRowAndAddColumn,
|
||||
getSheetHeaderRowAndSkipEmpty,
|
||||
getSheetHeaderRowWithGeneratedColumnNames,
|
||||
getSheets,
|
||||
} from '../../../v2/methods/loadOptions';
|
||||
|
||||
jest.mock('../../../v2/helpers/GoogleSheets.utils');
|
||||
|
||||
const mockGoogleSheetInstance = {
|
||||
spreadsheetGetSheets: jest.fn(),
|
||||
spreadsheetGetSheet: jest.fn(),
|
||||
getData: jest.fn(),
|
||||
testFilter: jest.fn(),
|
||||
};
|
||||
|
||||
jest.mock('../../../v2/helpers/GoogleSheet', () => ({
|
||||
GoogleSheet: jest.fn().mockImplementation(() => mockGoogleSheetInstance),
|
||||
}));
|
||||
|
||||
describe('Google Sheets Functions', () => {
|
||||
let mockLoadOptionsFunctions: Partial<ILoadOptionsFunctions>;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
mockLoadOptionsFunctions = {
|
||||
getNodeParameter: jest.fn((paramName: string) => {
|
||||
if (paramName === 'documentId') {
|
||||
return { mode: 'mode', value: 'value' };
|
||||
}
|
||||
if (paramName === 'sheetName') {
|
||||
return { mode: 'Sheet1', value: 'Sheet1' };
|
||||
}
|
||||
}),
|
||||
getNode: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
describe('getSheets', () => {
|
||||
it('should return an empty array if documentId is null', async () => {
|
||||
mockLoadOptionsFunctions.getNodeParameter = jest.fn().mockReturnValue(null);
|
||||
|
||||
const result = await getSheets.call(mockLoadOptionsFunctions as ILoadOptionsFunctions);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should throw an error if no data is returned', async () => {
|
||||
mockGoogleSheetInstance.spreadsheetGetSheets.mockResolvedValue(undefined);
|
||||
|
||||
await expect(
|
||||
getSheets.call(mockLoadOptionsFunctions as ILoadOptionsFunctions),
|
||||
).rejects.toThrow(NodeOperationError);
|
||||
});
|
||||
|
||||
it('should return sheets with GRID type', async () => {
|
||||
mockGoogleSheetInstance.spreadsheetGetSheets.mockResolvedValue({
|
||||
sheets: [
|
||||
{ properties: { sheetType: 'GRID', title: 'Sheet1', sheetId: '123' } },
|
||||
{ properties: { sheetType: 'OTHER', title: 'Sheet2', sheetId: '456' } },
|
||||
],
|
||||
});
|
||||
|
||||
const result = await getSheets.call(mockLoadOptionsFunctions as ILoadOptionsFunctions);
|
||||
expect(result).toEqual([{ name: 'Sheet1', value: '123' }]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSheetHeaderRow', () => {
|
||||
it('should return an empty array if documentId is null', async () => {
|
||||
mockLoadOptionsFunctions.getNodeParameter = jest.fn().mockReturnValue(null);
|
||||
|
||||
const result = await getSheetHeaderRow.call(
|
||||
mockLoadOptionsFunctions as ILoadOptionsFunctions,
|
||||
);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should throw an error if no data is returned', async () => {
|
||||
mockGoogleSheetInstance.spreadsheetGetSheet.mockResolvedValue({
|
||||
title: 'Sheet1',
|
||||
});
|
||||
mockGoogleSheetInstance.getData.mockResolvedValue(undefined);
|
||||
|
||||
await expect(
|
||||
getSheetHeaderRow.call(mockLoadOptionsFunctions as ILoadOptionsFunctions),
|
||||
).rejects.toThrow(NodeOperationError);
|
||||
});
|
||||
|
||||
it('should return column headers', async () => {
|
||||
mockGoogleSheetInstance.spreadsheetGetSheet.mockResolvedValue({
|
||||
title: 'Sheet1',
|
||||
});
|
||||
mockGoogleSheetInstance.getData.mockResolvedValue([['Header1', 'Header2', 'Header3']]);
|
||||
mockGoogleSheetInstance.testFilter.mockReturnValue(['Header1', 'Header2', 'Header3']);
|
||||
|
||||
const result = await getSheetHeaderRow.call(
|
||||
mockLoadOptionsFunctions as ILoadOptionsFunctions,
|
||||
);
|
||||
expect(result).toEqual([
|
||||
{ name: 'Header1', value: 'Header1' },
|
||||
{ name: 'Header2', value: 'Header2' },
|
||||
{ name: 'Header3', value: 'Header3' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSheetHeaderRowAndAddColumn', () => {
|
||||
it('should add a new column and exclude the column to match on', async () => {
|
||||
mockGoogleSheetInstance.spreadsheetGetSheet.mockResolvedValue({
|
||||
title: 'Sheet1',
|
||||
});
|
||||
mockGoogleSheetInstance.getData.mockResolvedValue([['Header1']]);
|
||||
mockGoogleSheetInstance.testFilter.mockReturnValue(['Header1']);
|
||||
|
||||
const result = await getSheetHeaderRowAndAddColumn.call(
|
||||
mockLoadOptionsFunctions as ILoadOptionsFunctions,
|
||||
);
|
||||
|
||||
expect(result).toEqual([
|
||||
{ name: 'Header1', value: 'Header1' },
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased
|
||||
{ name: 'New column ...', value: 'newColumn' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSheetHeaderRowWithGeneratedColumnNames', () => {
|
||||
it('should generate column names for empty values', async () => {
|
||||
mockGoogleSheetInstance.spreadsheetGetSheet.mockResolvedValue({
|
||||
title: 'Sheet1',
|
||||
});
|
||||
mockGoogleSheetInstance.getData.mockResolvedValue([['', 'Header1', '']]);
|
||||
mockGoogleSheetInstance.testFilter.mockReturnValue(['', 'Header1', '']);
|
||||
|
||||
const result = await getSheetHeaderRowWithGeneratedColumnNames.call(
|
||||
mockLoadOptionsFunctions as ILoadOptionsFunctions,
|
||||
);
|
||||
|
||||
expect(result).toEqual([
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased
|
||||
{ name: 'col_1', value: 'col_1' },
|
||||
{ name: 'Header1', value: 'Header1' },
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased
|
||||
{ name: 'col_3', value: 'col_3' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSheetHeaderRowAndSkipEmpty', () => {
|
||||
it('should skip columns with empty values', async () => {
|
||||
mockGoogleSheetInstance.spreadsheetGetSheet.mockResolvedValue({
|
||||
title: 'Sheet1',
|
||||
});
|
||||
mockGoogleSheetInstance.getData.mockResolvedValue([['', 'Header1', '']]);
|
||||
mockGoogleSheetInstance.testFilter.mockReturnValue(['', 'Header1', '']);
|
||||
|
||||
const result = await getSheetHeaderRowAndSkipEmpty.call(
|
||||
mockLoadOptionsFunctions as ILoadOptionsFunctions,
|
||||
);
|
||||
|
||||
expect(result).toEqual([{ name: 'Header1', value: 'Header1' }]);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user