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

This commit is contained in:
2026-03-17 16:22:57 +03:30
commit 3d5eaf9445
15349 changed files with 2847338 additions and 0 deletions
@@ -0,0 +1,141 @@
/* eslint-disable n8n-nodes-base/node-param-display-name-miscased */
import { NodeApiError } from 'n8n-workflow';
import {
baserowApiRequest,
baserowApiRequestAllItems,
getJwtToken,
getFieldNamesAndIds,
toOptions,
TableFieldMapper,
} from '../GenericFunctions';
describe('Baserow > GenericFunctions', () => {
const mockExecuteFunctions: any = {
helpers: {
request: jest.fn(),
},
getCredentials: jest.fn().mockResolvedValue({
username: 'nathan@n8n.io',
password: 'this-is-a-fake-password',
host: 'https://api.baserow.io',
}),
getNodeParameter: jest.fn(),
getNode: jest.fn(),
};
beforeEach(() => {
jest.clearAllMocks();
});
describe('baserowApiRequest', () => {
it('should return data on success', async () => {
mockExecuteFunctions.helpers.request.mockResolvedValue({ success: true });
const result = await baserowApiRequest.call(
mockExecuteFunctions,
'GET',
'/endpoint',
'testJwt',
);
expect(result).toEqual({ success: true });
expect(mockExecuteFunctions.helpers.request).toHaveBeenCalled();
});
it('should throw NodeApiError on failure', async () => {
mockExecuteFunctions.helpers.request.mockRejectedValue({ error: 'fail' });
await expect(
baserowApiRequest.call(mockExecuteFunctions, 'GET', '/endpoint', 'testJwt'),
).rejects.toThrow(NodeApiError);
});
});
describe('baserowApiRequestAllItems', () => {
it('should accumulate all pages', async () => {
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce(true) // returnAll
.mockReturnValue(1000); // limit
mockExecuteFunctions.helpers.request
.mockResolvedValueOnce({ results: [{ data: 1 }], next: 'page2' })
.mockResolvedValueOnce({ results: [{ data: 2 }], next: null });
const result = await baserowApiRequestAllItems.call(
mockExecuteFunctions,
'GET',
'/endpoint',
'testJwt',
{},
{},
);
expect(result).toEqual([{ data: 1 }, { data: 2 }]);
});
});
describe('getJwtToken', () => {
it('should return a token', async () => {
mockExecuteFunctions.helpers.request.mockResolvedValue({ token: 'mockToken' });
const result = await getJwtToken.call(mockExecuteFunctions, {
username: 'nathan@n8n.io',
password: 'this-is-a-fake-password',
host: 'https://api.baserow.io',
});
expect(result).toBe('mockToken');
});
it('should throw NodeApiError if request fails', async () => {
mockExecuteFunctions.helpers.request.mockRejectedValue({ error: 'fail' });
await expect(
getJwtToken.call(mockExecuteFunctions, {
username: 'nathan@n8n.io',
password: 'this-is-a-fake-password',
host: 'https://api.baserow.io',
}),
).rejects.toThrow(NodeApiError);
});
});
describe('getFieldNamesAndIds', () => {
it('should return field names and ids', async () => {
mockExecuteFunctions.helpers.request.mockResolvedValue([
{ id: 1, name: 'field1' },
{ id: 2, name: 'field2' },
]);
const result = await getFieldNamesAndIds.call(mockExecuteFunctions, '1', 'testJwt');
expect(result).toEqual({
names: ['field1', 'field2'],
ids: ['field_1', 'field_2'],
});
});
});
describe('toOptions', () => {
it('should map items to options', () => {
const result = toOptions([
{ id: 1, name: 'field1' },
{ id: 2, name: 'field2' },
]);
expect(result).toEqual([
{ name: 'field1', value: 1 },
{ name: 'field2', value: 2 },
]);
});
});
describe('TableFieldMapper', () => {
it('should create name-to-id and id-to-name mappings', () => {
const mapper = new TableFieldMapper();
mapper.createMappings([
{ id: 1, name: 'field1' },
{ id: 2, name: 'field2' },
]);
expect(mapper.nameToIdMapping).toEqual({
field1: 'field_1',
field2: 'field_2',
});
expect(mapper.idToNameMapping).toEqual({
field_1: 'field1',
field_2: 'field2',
});
});
});
});
@@ -0,0 +1,85 @@
export const fieldsResponse = [
{
id: 3799030,
table_id: 482710,
name: 'Name',
order: 0,
type: 'text',
primary: true,
read_only: false,
immutable_type: false,
immutable_properties: false,
description: null,
text_default: '',
},
{
id: 3799031,
table_id: 482710,
name: 'Notes',
order: 1,
type: 'long_text',
primary: false,
read_only: false,
immutable_type: false,
immutable_properties: false,
description: null,
long_text_enable_rich_text: false,
},
{
id: 3799032,
table_id: 482710,
name: 'Active',
order: 2,
type: 'boolean',
primary: false,
read_only: false,
immutable_type: false,
immutable_properties: false,
description: null,
},
];
export const getResponse = {
id: 1,
order: '1.00000000000000000000',
field_3799030: 'Foo',
field_3799031: 'bar',
field_3799032: false,
};
export const getAllResponse = {
count: 2,
next: null,
previous: null,
results: [
{
id: 1,
order: '1.00000000000000000000',
field_3799030: 'Foo',
field_3799031: 'bar',
field_3799032: false,
},
{
id: 2,
order: '2.00000000000000000000',
field_3799030: 'Bar',
field_3799031: 'foo',
field_3799032: true,
},
],
};
export const createResponse = {
id: 3,
order: '3.00000000000000000000',
field_3799030: 'Nathan',
field_3799031: 'testing',
field_3799032: false,
};
export const updateResponse = {
id: 3,
order: '3.00000000000000000000',
field_3799030: 'Nathan',
field_3799031: 'testing',
field_3799032: true,
};
@@ -0,0 +1,328 @@
{
"name": "Baserow Test Workflow",
"nodes": [
{
"parameters": {},
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [-20, 400],
"id": "fccdbab1-aa37-4606-8744-520e19a90a01",
"name": "When clicking Execute workflow"
},
{
"parameters": {
"operation": "get",
"databaseId": 199364,
"tableId": 482710,
"rowId": "1"
},
"type": "n8n-nodes-base.baserow",
"typeVersion": 1,
"position": [200, 0],
"id": "56b90399-9400-4fff-84b5-75430102119d",
"name": "Baserow > Get",
"credentials": {
"baserowApi": {
"id": "SWSFqWDWdnC74WMJ",
"name": "NodeQA"
}
}
},
{
"parameters": {
"databaseId": 199364,
"tableId": 482710,
"limit": 2,
"additionalOptions": {}
},
"type": "n8n-nodes-base.baserow",
"typeVersion": 1,
"position": [200, 200],
"id": "8a183257-3297-4ec9-bcae-aefb1f563355",
"name": "Baserow > Get Many",
"credentials": {
"baserowApi": {
"id": "SWSFqWDWdnC74WMJ",
"name": "NodeQA"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [420, 0],
"id": "5afa3206-a796-41dc-a2c5-54b5b9f2fbf4",
"name": "GetResponse"
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [420, 200],
"id": "d61f9e61-856a-4590-aad1-d7ef88e7185b",
"name": "GetMany Response"
},
{
"parameters": {
"operation": "create",
"databaseId": 199364,
"tableId": 482710,
"fieldsUi": {
"fieldValues": [
{
"fieldId": 3799030,
"fieldValue": "Nathan"
},
{
"fieldId": 3799031,
"fieldValue": "testing"
}
]
}
},
"type": "n8n-nodes-base.baserow",
"typeVersion": 1,
"position": [200, 400],
"id": "e3c5b6c4-b4b3-40ac-8d12-2a240c174e81",
"name": "Baserow > Create",
"credentials": {
"baserowApi": {
"id": "SWSFqWDWdnC74WMJ",
"name": "NodeQA"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [420, 400],
"id": "bb7648a4-1d81-421f-927d-0942325db4c9",
"name": "Create Response"
},
{
"parameters": {
"operation": "update",
"databaseId": 199364,
"tableId": 482710,
"rowId": "3",
"fieldsUi": {
"fieldValues": [
{
"fieldId": 3799032,
"fieldValue": "true"
}
]
}
},
"type": "n8n-nodes-base.baserow",
"typeVersion": 1,
"position": [200, 600],
"id": "557a163a-0d60-4dbf-b4e0-342533b56ad5",
"name": "Baserow > Update",
"credentials": {
"baserowApi": {
"id": "SWSFqWDWdnC74WMJ",
"name": "NodeQA"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [420, 600],
"id": "34992c77-25d1-4af4-a667-ca452049908d",
"name": "Update Response"
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [420, 800],
"id": "76e75c2a-2c6e-4307-ad67-fbc3d442ea53",
"name": "Delete Response"
},
{
"parameters": {
"operation": "delete",
"databaseId": 199364,
"tableId": 482710,
"rowId": "3"
},
"type": "n8n-nodes-base.baserow",
"typeVersion": 1,
"position": [200, 800],
"id": "f1c84a01-f514-49c2-a54e-548b15dc91fd",
"name": "Baserow > Delete",
"credentials": {
"baserowApi": {
"id": "SWSFqWDWdnC74WMJ",
"name": "NodeQA"
}
}
}
],
"pinData": {
"GetResponse": [
{
"json": {
"id": 1,
"order": "1.00000000000000000000",
"Name": "Foo",
"Notes": "bar",
"Active": false
}
}
],
"GetMany Response": [
{
"json": {
"id": 1,
"order": "1.00000000000000000000",
"Name": "Foo",
"Notes": "bar",
"Active": false
}
},
{
"json": {
"id": 2,
"order": "2.00000000000000000000",
"Name": "Bar",
"Notes": "foo",
"Active": true
}
}
],
"Create Response": [
{
"json": {
"id": 3,
"order": "3.00000000000000000000",
"Name": "Nathan",
"Notes": "testing",
"Active": false
}
}
],
"Update Response": [
{
"json": {
"id": 3,
"order": "3.00000000000000000000",
"Name": "Nathan",
"Notes": "testing",
"Active": true
}
}
],
"Delete Response": [
{
"json": {
"success": true
}
}
]
},
"connections": {
"When clicking Execute workflow": {
"main": [
[
{
"node": "Baserow > Get",
"type": "main",
"index": 0
},
{
"node": "Baserow > Get Many",
"type": "main",
"index": 0
},
{
"node": "Baserow > Create",
"type": "main",
"index": 0
},
{
"node": "Baserow > Update",
"type": "main",
"index": 0
},
{
"node": "Baserow > Delete",
"type": "main",
"index": 0
}
]
]
},
"Baserow > Get": {
"main": [
[
{
"node": "GetResponse",
"type": "main",
"index": 0
}
]
]
},
"Baserow > Get Many": {
"main": [
[
{
"node": "GetMany Response",
"type": "main",
"index": 0
}
]
]
},
"Baserow > Create": {
"main": [
[
{
"node": "Create Response",
"type": "main",
"index": 0
}
]
]
},
"Baserow > Update": {
"main": [
[
{
"node": "Update Response",
"type": "main",
"index": 0
}
]
]
},
"Baserow > Delete": {
"main": [
[
{
"node": "Delete Response",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "72dbd4c1-80b9-4a22-a298-7bcd577e2f0c",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "0fa937d34dcabeff4bd6480d3b42cc95edf3bc20e6810819086ef1ce2623639d"
},
"id": "2IrLMcqSSFfSyj76",
"tags": []
}
@@ -0,0 +1,59 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import {
createResponse,
fieldsResponse,
getAllResponse,
getResponse,
updateResponse,
} from './apiResponses';
describe('Baserow > Workflows', () => {
const credentials = {
baserowApi: {
host: 'https://api.baserow.io',
username: 'nathan@n8n.io',
password: 'fake-password',
},
};
describe('Run workflow', () => {
beforeAll(() => {
const mock = nock('https://api.baserow.io');
// Baserow > Get Token
mock
.persist()
.post('/api/user/token-auth/', { username: 'nathan@n8n.io', password: 'fake-password' })
.reply(200, {
token: 'fake-jwt-token',
});
// Baserow > Get Fields
mock.get('/api/database/fields/table/482710/').reply(200, fieldsResponse);
// Baserow > Get Row
mock.get('/api/database/rows/table/482710/1/').reply(200, getResponse);
// Baserow > Get all rows
mock
.get('/api/database/rows/table/482710/')
.query({ page: 1, size: 100 })
.reply(200, getAllResponse);
// Baserow > Create Row
mock
.post('/api/database/rows/table/482710/', {
field_3799030: 'Nathan',
field_3799031: 'testing',
})
.reply(200, createResponse);
// Baserow > Update Row
mock
.patch('/api/database/rows/table/482710/3/', {
field_3799032: 'true',
})
.reply(200, updateResponse);
// Baserow > Delete Row
mock.delete('/api/database/rows/table/482710/3/').reply(200, {});
});
new NodeTestHarness().setupTests({ credentials });
});
});