test(Harvest Node): Add unit tests for User resource (#31083)

Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Declan Carroll <declan@n8n.io>
This commit is contained in:
n8n-cat-bot[bot] 2026-05-25 18:09:42 +01:00 committed by GitHub
parent 5d7b5e6bd2
commit 28b7ef2593
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -0,0 +1,151 @@
import type { MockProxy } from 'jest-mock-extended';
import { mock } from 'jest-mock-extended';
import type {
IDataObject,
IExecuteFunctions,
INode,
INodeExecutionData,
IPairedItemData,
} from 'n8n-workflow';
import { NodeApiError } from 'n8n-workflow';
import * as GenericFunctions from '../GenericFunctions';
import { Harvest } from '../Harvest.node';
jest.mock('../GenericFunctions');
describe('Harvest Node', () => {
let harvest: Harvest;
let mockExecuteFunctions: MockProxy<IExecuteFunctions>;
const mockHarvestApiRequest = GenericFunctions.harvestApiRequest as jest.MockedFunction<
typeof GenericFunctions.harvestApiRequest
>;
const mockGetAllResource = GenericFunctions.getAllResource as jest.MockedFunction<
typeof GenericFunctions.getAllResource
>;
const mockNode: INode = {
id: 'test-node-id',
name: 'Harvest',
type: 'n8n-nodes-base.harvest',
typeVersion: 1,
position: [0, 0],
parameters: {},
};
beforeEach(() => {
harvest = new Harvest();
mockExecuteFunctions = mock<IExecuteFunctions>({
helpers: {
constructExecutionMetaData: jest.fn(
(
data: INodeExecutionData[],
options: { itemData: IPairedItemData | IPairedItemData[] },
) => {
const itemIndex =
(Array.isArray(options?.itemData)
? options.itemData[0]?.item
: options?.itemData?.item) ?? 0;
return data.map((item) => ({ ...item, pairedItem: { item: itemIndex } }));
},
),
returnJsonArray: jest.fn((data: IDataObject | IDataObject[]) =>
Array.isArray(data) ? data.map((d) => ({ json: d })) : [{ json: data }],
),
},
});
jest.clearAllMocks();
mockExecuteFunctions.getInputData.mockReturnValue([{ json: {} }]);
mockExecuteFunctions.getNode.mockReturnValue(mockNode);
mockExecuteFunctions.continueOnFail.mockReturnValue(false);
});
describe('User resource', () => {
it('should return all users on getAll', async () => {
mockExecuteFunctions.getNodeParameter.mockImplementation((paramName: string) => {
const params: Record<string, string> = {
resource: 'user',
operation: 'getAll',
};
return params[paramName];
});
const mockUsers = [
{ id: 1, first_name: 'Alice', last_name: 'Anderson', email: 'alice@example.com' },
{ id: 2, first_name: 'Bob', last_name: 'Brown', email: 'bob@example.com' },
];
mockGetAllResource.mockResolvedValue(mockUsers);
const result = await harvest.execute.call(mockExecuteFunctions);
expect(mockGetAllResource).toHaveBeenCalledWith('users', 0);
expect(result).toEqual([
[
{ json: mockUsers[0], pairedItem: { item: 0 } },
{ json: mockUsers[1], pairedItem: { item: 0 } },
],
]);
});
it('should call the users/{id} endpoint on get', async () => {
mockExecuteFunctions.getNodeParameter.mockImplementation((paramName: string) => {
const params: Record<string, string> = {
resource: 'user',
operation: 'get',
id: '42',
};
return params[paramName];
});
const mockUser = { id: 42, first_name: 'Carol', last_name: 'Clarke' };
mockHarvestApiRequest.mockResolvedValue(mockUser);
const result = await harvest.execute.call(mockExecuteFunctions);
expect(mockHarvestApiRequest).toHaveBeenCalledWith('GET', {}, 'users/42');
expect(result).toEqual([[{ json: mockUser, pairedItem: { item: 0 } }]]);
});
});
describe('Error handling', () => {
it('should propagate a NodeApiError from the API request', async () => {
mockExecuteFunctions.getNodeParameter.mockImplementation((paramName: string) => {
const params: Record<string, string> = {
resource: 'user',
operation: 'get',
id: '999',
};
return params[paramName];
});
const apiError = new NodeApiError(mockNode, {
message: 'Unauthorized',
httpCode: '401',
});
mockHarvestApiRequest.mockRejectedValue(apiError);
await expect(harvest.execute.call(mockExecuteFunctions)).rejects.toThrow(NodeApiError);
});
it('should surface the error on the item when continueOnFail is true', async () => {
mockExecuteFunctions.continueOnFail.mockReturnValue(true);
mockExecuteFunctions.getNodeParameter.mockImplementation((paramName: string) => {
const params: Record<string, string> = {
resource: 'user',
operation: 'get',
id: '999',
};
return params[paramName];
});
mockHarvestApiRequest.mockRejectedValue(new Error('User not found'));
const result = await harvest.execute.call(mockExecuteFunctions);
expect(result).toEqual([[{ json: { error: 'User not found' }, pairedItem: { item: 0 } }]]);
});
});
});