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,112 @@
|
||||
import * as getMany from '../../../../v2/actions/base/getMany.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction } from '../helpers';
|
||||
|
||||
const bases = [
|
||||
{
|
||||
id: 'appXXX',
|
||||
name: 'base 1',
|
||||
permissionLevel: 'create',
|
||||
},
|
||||
{
|
||||
id: 'appYYY',
|
||||
name: 'base 2',
|
||||
permissionLevel: 'edit',
|
||||
},
|
||||
{
|
||||
id: 'appZZZ',
|
||||
name: 'base 3',
|
||||
permissionLevel: 'create',
|
||||
},
|
||||
];
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
apiRequest: jest.fn(async function () {
|
||||
return { bases };
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('Test AirtableV2, base => getMany', () => {
|
||||
it('should return all bases', async () => {
|
||||
const nodeParameters = {
|
||||
resource: 'base',
|
||||
returnAll: true,
|
||||
options: {},
|
||||
};
|
||||
|
||||
const response = await getMany.execute.call(createMockExecuteFunction(nodeParameters));
|
||||
|
||||
expect(transport.apiRequest).toHaveBeenCalledWith('GET', 'meta/bases');
|
||||
|
||||
expect(response).toEqual([
|
||||
{
|
||||
json: {
|
||||
id: 'appXXX',
|
||||
name: 'base 1',
|
||||
permissionLevel: 'create',
|
||||
},
|
||||
pairedItem: [
|
||||
{
|
||||
item: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
json: {
|
||||
id: 'appYYY',
|
||||
name: 'base 2',
|
||||
permissionLevel: 'edit',
|
||||
},
|
||||
pairedItem: [
|
||||
{
|
||||
item: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
json: {
|
||||
id: 'appZZZ',
|
||||
name: 'base 3',
|
||||
permissionLevel: 'create',
|
||||
},
|
||||
pairedItem: [
|
||||
{
|
||||
item: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should return one base with edit permission', async () => {
|
||||
const nodeParameters = {
|
||||
resource: 'base',
|
||||
returnAll: false,
|
||||
limit: 2,
|
||||
options: { permissionLevel: ['edit'] },
|
||||
};
|
||||
|
||||
const response = await getMany.execute.call(createMockExecuteFunction(nodeParameters));
|
||||
|
||||
expect(transport.apiRequest).toHaveBeenCalledWith('GET', 'meta/bases');
|
||||
|
||||
expect(response).toEqual([
|
||||
{
|
||||
json: {
|
||||
id: 'appYYY',
|
||||
name: 'base 2',
|
||||
permissionLevel: 'edit',
|
||||
},
|
||||
pairedItem: [
|
||||
{
|
||||
item: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,55 @@
|
||||
import { mockDeep } from 'jest-mock-extended';
|
||||
import get from 'lodash/get';
|
||||
import type { IExecuteFunctions } from 'n8n-workflow';
|
||||
|
||||
import * as getSchema from '../../../../v2/actions/base/getSchema.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
apiRequest: jest.fn(async function () {
|
||||
return { tables: [] };
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('Test AirtableV2, base => getSchema', () => {
|
||||
it('should return all bases', async () => {
|
||||
const nodeParameters = {
|
||||
resource: 'base',
|
||||
operation: 'getSchema',
|
||||
base: {
|
||||
value: '={{$json.id}}',
|
||||
},
|
||||
};
|
||||
|
||||
const items = [
|
||||
{
|
||||
json: { id: 'appYobase1' },
|
||||
},
|
||||
{
|
||||
json: { id: 'appYobase2' },
|
||||
},
|
||||
];
|
||||
|
||||
await getSchema.execute.call(
|
||||
mockDeep<IExecuteFunctions>({
|
||||
getInputData: jest.fn(() => items),
|
||||
getNodeParameter: jest.fn((param: string, itemIndex: number) => {
|
||||
if (param === 'base') {
|
||||
return items[itemIndex].json.id;
|
||||
}
|
||||
|
||||
return get(nodeParameters, param);
|
||||
}),
|
||||
}),
|
||||
items,
|
||||
);
|
||||
|
||||
expect(transport.apiRequest).toBeCalledTimes(2);
|
||||
expect(transport.apiRequest).toHaveBeenCalledWith('GET', 'meta/bases/appYobase1/tables');
|
||||
expect(transport.apiRequest).toHaveBeenCalledWith('GET', 'meta/bases/appYobase2/tables');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,39 @@
|
||||
import get from 'lodash/get';
|
||||
import { constructExecutionMetaData } from 'n8n-core';
|
||||
import type { IDataObject, IExecuteFunctions, IGetNodeParameterOptions, INode } from 'n8n-workflow';
|
||||
|
||||
export const node: INode = {
|
||||
id: '11',
|
||||
name: 'Airtable node',
|
||||
typeVersion: 2,
|
||||
type: 'n8n-nodes-base.airtable',
|
||||
position: [42, 42],
|
||||
parameters: {
|
||||
operation: 'create',
|
||||
},
|
||||
};
|
||||
|
||||
export const createMockExecuteFunction = (nodeParameters: IDataObject) => {
|
||||
const fakeExecuteFunction = {
|
||||
getInputData: jest.fn(() => {
|
||||
return [{ json: {} }];
|
||||
}),
|
||||
getNodeParameter: jest.fn(
|
||||
(
|
||||
parameterName: string,
|
||||
_itemIndex: number,
|
||||
fallbackValue?: IDataObject,
|
||||
options?: IGetNodeParameterOptions,
|
||||
) => {
|
||||
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
||||
return get(nodeParameters, parameter, fallbackValue);
|
||||
},
|
||||
),
|
||||
getNode: jest.fn(() => {
|
||||
return node;
|
||||
}),
|
||||
helpers: { constructExecutionMetaData: jest.fn(constructExecutionMetaData) },
|
||||
continueOnFail: jest.fn(() => false),
|
||||
} as unknown as IExecuteFunctions;
|
||||
return fakeExecuteFunction;
|
||||
};
|
||||
@@ -0,0 +1,208 @@
|
||||
import * as create from '../../../../v2/actions/record/create.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
apiRequest: jest.fn(async function () {
|
||||
return {};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('Test AirtableV2, create operation', () => {
|
||||
beforeEach(() => jest.clearAllMocks());
|
||||
|
||||
it('should create a record, autoMapInputData', async () => {
|
||||
const nodeParameters = {
|
||||
operation: 'create',
|
||||
columns: {
|
||||
mappingMode: 'autoMapInputData',
|
||||
value: {
|
||||
bar: 'bar 1',
|
||||
foo: 'foo 1',
|
||||
spam: 'eggs',
|
||||
},
|
||||
matchingColumns: [],
|
||||
schema: [
|
||||
{
|
||||
id: 'foo',
|
||||
displayName: 'foo',
|
||||
required: false,
|
||||
defaultMatch: false,
|
||||
display: true,
|
||||
type: 'string',
|
||||
},
|
||||
{
|
||||
id: 'bar',
|
||||
displayName: 'bar',
|
||||
required: false,
|
||||
defaultMatch: false,
|
||||
display: true,
|
||||
type: 'string',
|
||||
},
|
||||
{
|
||||
id: 'spam',
|
||||
displayName: 'spam',
|
||||
required: false,
|
||||
defaultMatch: false,
|
||||
display: true,
|
||||
type: 'string',
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
typecast: true,
|
||||
ignoreFields: 'spam',
|
||||
},
|
||||
};
|
||||
|
||||
const items = [
|
||||
{
|
||||
json: {
|
||||
foo: 'foo 1',
|
||||
spam: 'eggs',
|
||||
bar: 'bar 1',
|
||||
},
|
||||
},
|
||||
{
|
||||
json: {
|
||||
foo: 'foo 2',
|
||||
spam: 'eggs',
|
||||
bar: 'bar 2',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
await create.execute.call(
|
||||
createMockExecuteFunction(nodeParameters),
|
||||
items,
|
||||
'appYoLbase',
|
||||
'tblltable',
|
||||
);
|
||||
|
||||
expect(transport.apiRequest).toHaveBeenCalledTimes(2);
|
||||
expect(transport.apiRequest).toHaveBeenCalledWith('POST', 'appYoLbase/tblltable', {
|
||||
fields: {
|
||||
foo: 'foo 1',
|
||||
bar: 'bar 1',
|
||||
},
|
||||
typecast: true,
|
||||
});
|
||||
expect(transport.apiRequest).toHaveBeenCalledWith('POST', 'appYoLbase/tblltable', {
|
||||
fields: {
|
||||
foo: 'foo 2',
|
||||
bar: 'bar 2',
|
||||
},
|
||||
typecast: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should create a record, defineBelow', async () => {
|
||||
const nodeParameters = {
|
||||
operation: 'create',
|
||||
columns: {
|
||||
mappingMode: 'defineBelow',
|
||||
value: {
|
||||
bar: 'bar 1',
|
||||
foo: 'foo 1',
|
||||
},
|
||||
matchingColumns: [],
|
||||
schema: [
|
||||
{
|
||||
id: 'foo',
|
||||
displayName: 'foo',
|
||||
required: false,
|
||||
defaultMatch: false,
|
||||
display: true,
|
||||
type: 'string',
|
||||
},
|
||||
{
|
||||
id: 'bar',
|
||||
displayName: 'bar',
|
||||
required: false,
|
||||
defaultMatch: false,
|
||||
display: true,
|
||||
type: 'string',
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {},
|
||||
};
|
||||
|
||||
const items = [
|
||||
{
|
||||
json: {},
|
||||
},
|
||||
];
|
||||
|
||||
await create.execute.call(
|
||||
createMockExecuteFunction(nodeParameters),
|
||||
items,
|
||||
'appYoLbase',
|
||||
'tblltable',
|
||||
);
|
||||
|
||||
expect(transport.apiRequest).toHaveBeenCalledTimes(1);
|
||||
expect(transport.apiRequest).toHaveBeenCalledWith('POST', 'appYoLbase/tblltable', {
|
||||
fields: {
|
||||
foo: 'foo 1',
|
||||
bar: 'bar 1',
|
||||
},
|
||||
typecast: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('should skip validation if typecast option is true', async () => {
|
||||
const nodeParameters = {
|
||||
operation: 'create',
|
||||
columns: {
|
||||
mappingMode: 'defineBelow',
|
||||
value: {
|
||||
bar: 'bar 1',
|
||||
foo: 'foo 1',
|
||||
},
|
||||
matchingColumns: [],
|
||||
schema: [
|
||||
{
|
||||
id: 'foo',
|
||||
displayName: 'foo',
|
||||
required: false,
|
||||
defaultMatch: false,
|
||||
display: true,
|
||||
type: 'string',
|
||||
},
|
||||
{
|
||||
id: 'bar',
|
||||
displayName: 'bar',
|
||||
required: false,
|
||||
defaultMatch: false,
|
||||
display: true,
|
||||
type: 'string',
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
typecast: true,
|
||||
},
|
||||
};
|
||||
|
||||
const mockExecuteFunctions = createMockExecuteFunction(nodeParameters);
|
||||
await create.execute.call(mockExecuteFunctions, [{ json: {} }], 'appYoLbase', 'tblltable');
|
||||
|
||||
expect(mockExecuteFunctions.getNodeParameter).toHaveBeenCalledWith('columns.value', 0, [], {
|
||||
skipValidation: true,
|
||||
});
|
||||
|
||||
expect(transport.apiRequest).toHaveBeenCalledTimes(1);
|
||||
expect(transport.apiRequest).toHaveBeenCalledWith('POST', 'appYoLbase/tblltable', {
|
||||
fields: {
|
||||
foo: 'foo 1',
|
||||
bar: 'bar 1',
|
||||
},
|
||||
typecast: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
import * as deleteRecord from '../../../../v2/actions/record/deleteRecord.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
apiRequest: jest.fn(async function () {
|
||||
return {};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('Test AirtableV2, deleteRecord operation', () => {
|
||||
it('should delete a record', async () => {
|
||||
const nodeParameters = {
|
||||
operation: 'deleteRecord',
|
||||
id: 'recXXX',
|
||||
};
|
||||
|
||||
const items = [
|
||||
{
|
||||
json: {},
|
||||
},
|
||||
];
|
||||
|
||||
await deleteRecord.execute.call(
|
||||
createMockExecuteFunction(nodeParameters),
|
||||
items,
|
||||
'appYoLbase',
|
||||
'tblltable',
|
||||
);
|
||||
|
||||
expect(transport.apiRequest).toHaveBeenCalledTimes(1);
|
||||
expect(transport.apiRequest).toHaveBeenCalledWith('DELETE', 'appYoLbase/tblltable/recXXX');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
import * as get from '../../../../v2/actions/record/get.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
apiRequest: jest.fn(async function (method: string) {
|
||||
if (method === 'GET') {
|
||||
return {
|
||||
id: 'recXXX',
|
||||
fields: {
|
||||
foo: 'foo 1',
|
||||
bar: 'bar 1',
|
||||
},
|
||||
};
|
||||
}
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('Test AirtableV2, create operation', () => {
|
||||
it('should create a record, autoMapInputData', async () => {
|
||||
const nodeParameters = {
|
||||
operation: 'get',
|
||||
id: 'recXXX',
|
||||
options: {},
|
||||
};
|
||||
|
||||
const items = [
|
||||
{
|
||||
json: {},
|
||||
},
|
||||
];
|
||||
|
||||
const responce = await get.execute.call(
|
||||
createMockExecuteFunction(nodeParameters),
|
||||
items,
|
||||
'appYoLbase',
|
||||
'tblltable',
|
||||
);
|
||||
|
||||
expect(transport.apiRequest).toHaveBeenCalledTimes(1);
|
||||
expect(transport.apiRequest).toHaveBeenCalledWith('GET', 'appYoLbase/tblltable/recXXX');
|
||||
|
||||
expect(responce).toEqual([
|
||||
{
|
||||
json: {
|
||||
id: 'recXXX',
|
||||
foo: 'foo 1',
|
||||
bar: 'bar 1',
|
||||
},
|
||||
pairedItem: {
|
||||
item: 0,
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,152 @@
|
||||
import * as search from '../../../../v2/actions/record/search.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
apiRequest: jest.fn(async function (method: string) {
|
||||
if (method === 'GET') {
|
||||
return {
|
||||
records: [
|
||||
{
|
||||
id: 'recYYY',
|
||||
fields: {
|
||||
foo: 'foo 2',
|
||||
bar: 'bar 2',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
}),
|
||||
apiRequestAllItems: jest.fn(async function (method: string) {
|
||||
if (method === 'GET') {
|
||||
return {
|
||||
records: [
|
||||
{
|
||||
id: 'recYYY',
|
||||
fields: {
|
||||
foo: 'foo 2',
|
||||
bar: 'bar 2',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'recXXX',
|
||||
fields: {
|
||||
foo: 'foo 1',
|
||||
bar: 'bar 1',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('Test AirtableV2, search operation', () => {
|
||||
it('should return all records', async () => {
|
||||
const nodeParameters = {
|
||||
operation: 'search',
|
||||
filterByFormula: 'foo',
|
||||
returnAll: true,
|
||||
options: {
|
||||
fields: ['foo', 'bar'],
|
||||
view: {
|
||||
value: 'viwView',
|
||||
mode: 'list',
|
||||
},
|
||||
},
|
||||
sort: {
|
||||
property: [
|
||||
{
|
||||
field: 'bar',
|
||||
direction: 'desc',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const items = [
|
||||
{
|
||||
json: {},
|
||||
},
|
||||
];
|
||||
|
||||
const result = await search.execute.call(
|
||||
createMockExecuteFunction(nodeParameters),
|
||||
items,
|
||||
'appYoLbase',
|
||||
'tblltable',
|
||||
);
|
||||
|
||||
expect(transport.apiRequestAllItems).toHaveBeenCalledTimes(1);
|
||||
expect(transport.apiRequestAllItems).toHaveBeenCalledWith(
|
||||
'GET',
|
||||
'appYoLbase/tblltable',
|
||||
{},
|
||||
{
|
||||
fields: ['foo', 'bar'],
|
||||
filterByFormula: 'foo',
|
||||
sort: [{ direction: 'desc', field: 'bar' }],
|
||||
view: 'viwView',
|
||||
},
|
||||
);
|
||||
|
||||
expect(result).toHaveLength(2);
|
||||
expect(result[0]).toEqual({
|
||||
json: { id: 'recYYY', foo: 'foo 2', bar: 'bar 2' },
|
||||
pairedItem: [
|
||||
{
|
||||
item: 0,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('should return all records', async () => {
|
||||
const nodeParameters = {
|
||||
operation: 'search',
|
||||
filterByFormula: 'foo',
|
||||
returnAll: false,
|
||||
limit: 1,
|
||||
options: {
|
||||
fields: ['foo', 'bar'],
|
||||
},
|
||||
sort: {},
|
||||
};
|
||||
|
||||
const items = [
|
||||
{
|
||||
json: {},
|
||||
},
|
||||
];
|
||||
|
||||
const result = await search.execute.call(
|
||||
createMockExecuteFunction(nodeParameters),
|
||||
items,
|
||||
'appYoLbase',
|
||||
'tblltable',
|
||||
);
|
||||
|
||||
expect(transport.apiRequest).toHaveBeenCalledTimes(1);
|
||||
expect(transport.apiRequest).toHaveBeenCalledWith(
|
||||
'GET',
|
||||
'appYoLbase/tblltable',
|
||||
{},
|
||||
{ fields: ['foo', 'bar'], filterByFormula: 'foo', maxRecords: 1 },
|
||||
);
|
||||
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0]).toEqual({
|
||||
json: { id: 'recYYY', foo: 'foo 2', bar: 'bar 2' },
|
||||
pairedItem: [
|
||||
{
|
||||
item: 0,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,150 @@
|
||||
import type { MockProxy } from 'jest-mock-extended';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import type { IExecuteFunctions } from 'n8n-workflow';
|
||||
|
||||
import * as update from '../../../../v2/actions/record/update.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
apiRequest: jest.fn(async function () {
|
||||
return {};
|
||||
}),
|
||||
batchUpdate: jest.fn(async function () {
|
||||
return {};
|
||||
}),
|
||||
apiRequestAllItems: jest.fn(async function (method: string) {
|
||||
if (method === 'GET') {
|
||||
return {
|
||||
records: [
|
||||
{
|
||||
id: 'recYYY',
|
||||
fields: {
|
||||
foo: 'foo 2',
|
||||
bar: 'bar 2',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'recXXX',
|
||||
fields: {
|
||||
foo: 'foo 1',
|
||||
bar: 'bar 1',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('Test AirtableV2, update operation', () => {
|
||||
let mockExecuteFunctions: MockProxy<IExecuteFunctions>;
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should skip validation if typecast option is true', async () => {
|
||||
mockExecuteFunctions = mock<IExecuteFunctions>();
|
||||
mockExecuteFunctions.helpers.constructExecutionMetaData = jest.fn(() => []);
|
||||
mockExecuteFunctions.getNodeParameter.mockImplementation((key: string) => {
|
||||
if (key === 'columns.mappingMode') {
|
||||
return 'defineBelow';
|
||||
}
|
||||
if (key === 'columns.matchingColumns') {
|
||||
return ['id'];
|
||||
}
|
||||
if (key === 'options') {
|
||||
return {
|
||||
typecast: true,
|
||||
};
|
||||
}
|
||||
if (key === 'columns.value') {
|
||||
return {
|
||||
id: 'recXXX',
|
||||
field1: 'foo 1',
|
||||
field2: 'bar 1',
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
await update.execute.call(mockExecuteFunctions, [{ json: {} }], 'base', 'table');
|
||||
|
||||
expect(mockExecuteFunctions.getNodeParameter).toHaveBeenCalledWith('columns.value', 0, [], {
|
||||
skipValidation: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should update a record by id, autoMapInputData', async () => {
|
||||
const nodeParameters = {
|
||||
operation: 'update',
|
||||
columns: {
|
||||
mappingMode: 'autoMapInputData',
|
||||
matchingColumns: ['id'],
|
||||
},
|
||||
options: {},
|
||||
};
|
||||
|
||||
const items = [
|
||||
{
|
||||
json: {
|
||||
id: 'recXXX',
|
||||
foo: 'foo 1',
|
||||
bar: 'bar 1',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
await update.execute.call(
|
||||
createMockExecuteFunction(nodeParameters),
|
||||
items,
|
||||
'appYoLbase',
|
||||
'tblltable',
|
||||
);
|
||||
|
||||
expect(transport.batchUpdate).toHaveBeenCalledWith(
|
||||
'appYoLbase/tblltable',
|
||||
{ typecast: false },
|
||||
[{ fields: { bar: 'bar 1', foo: 'foo 1' }, id: 'recXXX' }],
|
||||
);
|
||||
});
|
||||
|
||||
it('should update a record by field name, autoMapInputData', async () => {
|
||||
const nodeParameters = {
|
||||
operation: 'update',
|
||||
columns: {
|
||||
mappingMode: 'autoMapInputData',
|
||||
matchingColumns: ['foo'],
|
||||
},
|
||||
options: {},
|
||||
};
|
||||
|
||||
const items = [
|
||||
{
|
||||
json: {
|
||||
id: 'recXXX',
|
||||
foo: 'foo 1',
|
||||
bar: 'bar 1',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
await update.execute.call(
|
||||
createMockExecuteFunction(nodeParameters),
|
||||
items,
|
||||
'appYoLbase',
|
||||
'tblltable',
|
||||
);
|
||||
|
||||
expect(transport.batchUpdate).toHaveBeenCalledWith(
|
||||
'appYoLbase/tblltable',
|
||||
{ typecast: false },
|
||||
[{ fields: { bar: 'bar 1', foo: 'foo 1', id: 'recXXX' }, id: 'recXXX' }],
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user