Files
n8n-enterprise-unlocked/packages/nodes-base/nodes/Supabase/tests/Supabase.node.test.ts
2025-07-01 15:05:40 +02:00

203 lines
5.2 KiB
TypeScript

import { mock } from 'jest-mock-extended';
import get from 'lodash/get';
import {
type IDataObject,
type IExecuteFunctions,
type IGetNodeParameterOptions,
type INodeExecutionData,
type IPairedItemData,
NodeOperationError,
} from 'n8n-workflow';
import * as utils from '../GenericFunctions';
import { Supabase } from '../Supabase.node';
describe('Test Supabase Node', () => {
const node = new Supabase();
const input = [{ json: {} }];
const mockRequestWithAuthentication = jest.fn().mockResolvedValue([]);
beforeEach(() => {
jest.clearAllMocks();
});
const createMockExecuteFunction = (
nodeParameters: IDataObject,
continueOnFail: boolean = false,
) => {
const fakeExecuteFunction = {
getCredentials: jest.fn().mockResolvedValue({
host: 'https://api.supabase.io',
serviceRole: 'service_role',
}),
getNodeParameter(
parameterName: string,
itemIndex: number,
fallbackValue?: IDataObject,
options?: IGetNodeParameterOptions,
) {
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
const parameterValue = get(nodeParameters, parameter, fallbackValue);
if ((parameterValue as IDataObject)?.nodeOperationError) {
throw new NodeOperationError(mock(), 'Get Options Error', { itemIndex });
}
return parameterValue;
},
getNode() {
return node;
},
continueOnFail: () => continueOnFail,
getInputData: () => input,
helpers: {
requestWithAuthentication: mockRequestWithAuthentication,
constructExecutionMetaData: (
_inputData: INodeExecutionData[],
_options: { itemData: IPairedItemData | IPairedItemData[] },
) => [],
returnJsonArray: (_jsonData: IDataObject | IDataObject[]) => [],
},
} as unknown as IExecuteFunctions;
return fakeExecuteFunction;
};
it('should allow filtering on the same field multiple times', async () => {
const supabaseApiRequest = jest
.spyOn(utils, 'supabaseApiRequest')
.mockImplementation(async () => {
return [];
});
const fakeExecuteFunction = createMockExecuteFunction({
resource: 'row',
operation: 'getAll',
returnAll: true,
filterType: 'manual',
matchType: 'allFilters',
tableId: 'my_table',
filters: {
conditions: [
{
condition: 'gt',
keyName: 'created_at',
keyValue: '2025-01-02 08:03:43.952051+00',
},
{
condition: 'lt',
keyName: 'created_at',
keyValue: '2025-01-02 08:07:36.102231+00',
},
],
},
});
await node.execute.call(fakeExecuteFunction);
expect(supabaseApiRequest).toHaveBeenCalledWith(
'GET',
'/my_table',
{},
{
and: '(created_at.gt.2025-01-02 08:03:43.952051+00,created_at.lt.2025-01-02 08:07:36.102231+00)',
offset: 0,
},
);
supabaseApiRequest.mockRestore();
});
it('should not set schema headers if no custom schema is used', async () => {
const fakeExecuteFunction = createMockExecuteFunction({
resource: 'row',
operation: 'getAll',
returnAll: true,
useCustomSchema: false,
schema: 'public',
tableId: 'my_table',
});
await node.execute.call(fakeExecuteFunction);
expect(mockRequestWithAuthentication).toHaveBeenCalledWith(
'supabaseApi',
expect.objectContaining({
method: 'GET',
headers: expect.objectContaining({
Prefer: 'return=representation',
}),
uri: 'https://api.supabase.io/rest/v1/my_table',
}),
);
});
it('should set the schema headers for GET calls if custom schema is used', async () => {
const fakeExecuteFunction = createMockExecuteFunction({
resource: 'row',
operation: 'getAll',
returnAll: true,
useCustomSchema: true,
schema: 'custom_schema',
tableId: 'my_table',
});
await node.execute.call(fakeExecuteFunction);
expect(mockRequestWithAuthentication).toHaveBeenCalledWith(
'supabaseApi',
expect.objectContaining({
method: 'GET',
headers: expect.objectContaining({
'Accept-Profile': 'custom_schema',
Prefer: 'return=representation',
}),
uri: 'https://api.supabase.io/rest/v1/my_table',
}),
);
});
it('should set the schema headers for POST calls if custom schema is used', async () => {
const fakeExecuteFunction = createMockExecuteFunction({
resource: 'row',
operation: 'create',
returnAll: true,
useCustomSchema: true,
schema: 'custom_schema',
tableId: 'my_table',
});
await node.execute.call(fakeExecuteFunction);
expect(mockRequestWithAuthentication).toHaveBeenCalledWith(
'supabaseApi',
expect.objectContaining({
method: 'POST',
headers: expect.objectContaining({
'Content-Profile': 'custom_schema',
Prefer: 'return=representation',
}),
uri: 'https://api.supabase.io/rest/v1/my_table',
}),
);
});
it('should show descriptive message when error is caught', async () => {
const fakeExecuteFunction = createMockExecuteFunction({
resource: 'row',
operation: 'create',
returnAll: true,
useCustomSchema: true,
schema: '',
tableId: 'my_table',
});
fakeExecuteFunction.helpers.requestWithAuthentication = jest.fn().mockRejectedValue({
description: 'Something when wrong',
message: 'error',
});
await expect(node.execute.call(fakeExecuteFunction)).rejects.toHaveProperty(
'message',
'error: Something when wrong',
);
});
});