mirror of https://github.com/nocodb/nocodb
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
742 lines
23 KiB
742 lines
23 KiB
import { expect, test } from '@playwright/test'; |
|
import { DashboardPage } from '../pages/Dashboard'; |
|
import setup from '../setup'; |
|
import makeServer from '../setup/server'; |
|
import { WebhookFormPage } from '../pages/Dashboard/WebhookForm'; |
|
import { isSubset } from './utils/general'; |
|
import { Api, UITypes } from 'nocodb-sdk'; |
|
import { isMysql, isPg, isSqlite } from '../setup/db'; |
|
|
|
const hookPath = 'http://localhost:9090/hook'; |
|
let api: Api<any>; |
|
|
|
// clear server data |
|
async function clearServerData({ request }) { |
|
// clear stored data in server |
|
await request.get(hookPath + '/clear'); |
|
|
|
// ensure stored message count is 0 |
|
const response = await request.get(hookPath + '/count'); |
|
await expect(await response.json()).toBe(0); |
|
} |
|
|
|
async function getWebhookResponses({ request, count = 1 }) { |
|
let response; |
|
|
|
// retry since there can be lag between the time the hook is triggered and the time the server receives the request |
|
for (let i = 0; i < 20; i++) { |
|
response = await request.get(hookPath + '/count'); |
|
if ((await response.json()) === count) { |
|
break; |
|
} |
|
await new Promise(resolve => setTimeout(resolve, 100)); |
|
} |
|
await expect(await response.json()).toBe(count); |
|
|
|
response = await request.get(hookPath + '/all'); |
|
return await response.json(); |
|
} |
|
|
|
async function verifyHookTrigger(count: number, value: string, request, expectedData?: any) { |
|
// Retry since there can be lag between the time the hook is triggered and the time the server receives the request |
|
let response; |
|
|
|
// retry since there can be lag between the time the hook is triggered and the time the server receives the request |
|
for (let i = 0; i < 20; i++) { |
|
response = await request.get(hookPath + '/count'); |
|
if ((await response.json()) === count) { |
|
break; |
|
} |
|
await new Promise(resolve => setTimeout(resolve, 150)); |
|
} |
|
await expect(await response.json()).toBe(count); |
|
|
|
if (count) { |
|
let response; |
|
|
|
// retry since there can be lag between the time the hook is triggered and the time the server receives the request |
|
for (let i = 0; i < 20; i++) { |
|
response = await request.get(hookPath + '/last'); |
|
const rspJson = await response.json(); |
|
if (rspJson.data.rows[0].Title === value) { |
|
break; |
|
} |
|
await new Promise(resolve => setTimeout(resolve, 150)); |
|
} |
|
const rspJson = await response.json(); |
|
await expect(rspJson?.data?.rows[0]?.Title).toBe(value); |
|
if (expectedData) { |
|
await expect(isSubset(rspJson, expectedData)).toBe(true); |
|
} |
|
} |
|
} |
|
|
|
async function buildExpectedResponseData(type, value, oldValue?) { |
|
const expectedData = { |
|
type: 'records.after.insert', |
|
data: { |
|
table_name: 'Test', |
|
view_name: 'Test', |
|
rows: [ |
|
{ |
|
Title: 'Poole', |
|
}, |
|
], |
|
}, |
|
}; |
|
|
|
expectedData.type = type; |
|
expectedData.data.rows[0].Title = value; |
|
|
|
if (oldValue) { |
|
expectedData.data['previous_rows'] = []; |
|
expectedData.data['previous_rows'][0] = { |
|
Title: oldValue, |
|
}; |
|
} |
|
|
|
return expectedData; |
|
} |
|
|
|
test.describe.serial('Webhook', () => { |
|
// start a server locally for webhook tests |
|
|
|
let dashboard: DashboardPage, webhook: WebhookFormPage; |
|
let context: any; |
|
|
|
test.beforeAll(async () => { |
|
await makeServer(); |
|
}); |
|
|
|
test.beforeEach(async ({ page }) => { |
|
context = await setup({ page, isEmptyProject: true }); |
|
dashboard = new DashboardPage(page, context.project); |
|
webhook = dashboard.webhookForm; |
|
|
|
api = new Api({ |
|
baseURL: `http://localhost:8080/`, |
|
headers: { |
|
'xc-auth': context.token, |
|
}, |
|
}); |
|
}); |
|
|
|
test('CRUD', async ({ request, page }) => { |
|
// Waiting for the server to start |
|
await page.waitForTimeout(1000); |
|
|
|
// close 'Team & Auth' tab |
|
await clearServerData({ request }); |
|
await dashboard.closeTab({ title: 'Team & Auth' }); |
|
await dashboard.treeView.createTable({ title: 'Test' }); |
|
|
|
// create |
|
// |
|
// hook order |
|
// hook-1: after insert |
|
// - verify trigger after insert |
|
// - verify no trigger after edit |
|
// - verify no trigger after delete |
|
|
|
// after insert hook |
|
await webhook.create({ |
|
title: 'hook-1', |
|
event: 'After Insert', |
|
}); |
|
await clearServerData({ request }); |
|
await dashboard.grid.addNewRow({ |
|
index: 0, |
|
columnHeader: 'Title', |
|
value: 'Poole', |
|
}); |
|
await verifyHookTrigger(1, 'Poole', request, buildExpectedResponseData('records.after.insert', 'Poole')); |
|
|
|
// trigger edit row & delete row |
|
// verify that the hook is not triggered (count doesn't change in this case) |
|
await dashboard.grid.editRow({ index: 0, value: 'Delaware' }); |
|
await verifyHookTrigger(1, 'Poole', request); |
|
await dashboard.grid.deleteRow(0); |
|
await verifyHookTrigger(1, 'Poole', request); |
|
|
|
/////////////////////////////////////////////////////////////////////////// |
|
|
|
// update |
|
// |
|
// hook order |
|
// hook-1: after insert |
|
// hook-2: after update |
|
// - verify trigger after insert |
|
// - verify trigger after edit |
|
// - verify no trigger after delete |
|
|
|
// after update hook |
|
await webhook.create({ |
|
title: 'hook-2', |
|
event: 'After Update', |
|
}); |
|
|
|
await clearServerData({ request }); |
|
await dashboard.grid.addNewRow({ |
|
index: 0, |
|
columnHeader: 'Title', |
|
value: 'Poole', |
|
}); |
|
await verifyHookTrigger(1, 'Poole', request, buildExpectedResponseData('records.after.insert', 'Poole')); |
|
await dashboard.grid.editRow({ index: 0, value: 'Delaware' }); |
|
await verifyHookTrigger( |
|
2, |
|
'Delaware', |
|
request, |
|
buildExpectedResponseData('records.after.update', 'Delaware', 'Poole') |
|
); |
|
await dashboard.grid.deleteRow(0); |
|
await verifyHookTrigger(2, 'Delaware', request); |
|
|
|
/////////////////////////////////////////////////////////////////////////// |
|
|
|
// hook order |
|
// hook-1: after insert |
|
// hook-2: after update |
|
// hook-3: after delete |
|
// - verify trigger after insert |
|
// - verify trigger after edit |
|
// - verify trigger after delete |
|
|
|
// after delete hook |
|
await webhook.create({ |
|
title: 'hook-3', |
|
event: 'After Delete', |
|
}); |
|
await clearServerData({ request }); |
|
await dashboard.grid.addNewRow({ |
|
index: 0, |
|
columnHeader: 'Title', |
|
value: 'Poole', |
|
}); |
|
await verifyHookTrigger(1, 'Poole', request, buildExpectedResponseData('records.after.insert', 'Poole')); |
|
await dashboard.grid.editRow({ index: 0, value: 'Delaware' }); |
|
await verifyHookTrigger( |
|
2, |
|
'Delaware', |
|
request, |
|
buildExpectedResponseData('records.after.update', 'Delaware', 'Poole') |
|
); |
|
await dashboard.grid.deleteRow(0); |
|
await verifyHookTrigger(3, 'Delaware', request, buildExpectedResponseData('records.after.delete', 'Delaware')); |
|
|
|
/////////////////////////////////////////////////////////////////////////// |
|
|
|
// modify webhook |
|
|
|
// hook order |
|
// hook-1: after delete |
|
// hook-2: after delete |
|
// hook-3: after delete |
|
// - verify no trigger after insert |
|
// - verify no trigger after edit |
|
// - verify trigger after delete |
|
|
|
await webhook.open({ index: 0 }); |
|
await webhook.configureWebhook({ |
|
title: 'hook-1-modified', |
|
event: 'After Delete', |
|
}); |
|
await webhook.save(); |
|
await webhook.close(); |
|
await webhook.open({ index: 1 }); |
|
await webhook.configureWebhook({ |
|
title: 'hook-2-modified', |
|
event: 'After Delete', |
|
}); |
|
await webhook.save(); |
|
await webhook.close(); |
|
|
|
await clearServerData({ request }); |
|
await dashboard.grid.addNewRow({ |
|
index: 0, |
|
columnHeader: 'Title', |
|
value: 'Poole', |
|
}); |
|
|
|
// for insert & edit, the hook should not be triggered (count doesn't change in this case) |
|
await verifyHookTrigger(0, 'Poole', request); |
|
await dashboard.grid.editRow({ index: 0, value: 'Delaware' }); |
|
await verifyHookTrigger(0, 'Delaware', request); |
|
await dashboard.grid.deleteRow(0); |
|
|
|
// for delete, the hook should be triggered (thrice in this case) |
|
await verifyHookTrigger(3, 'Delaware', request, buildExpectedResponseData('records.after.delete', 'Delaware')); |
|
|
|
/////////////////////////////////////////////////////////////////////////// |
|
|
|
// delete webhook |
|
|
|
// hook order |
|
// hook-1: - |
|
// hook-2: - |
|
// hook-3: - |
|
// - verify no trigger after insert |
|
// - verify no trigger after edit |
|
// - verify no trigger after delete |
|
|
|
await webhook.delete({ index: 0 }); |
|
await webhook.delete({ index: 0 }); |
|
await webhook.delete({ index: 0 }); |
|
|
|
await clearServerData({ request }); |
|
await dashboard.grid.addNewRow({ |
|
index: 0, |
|
columnHeader: 'Title', |
|
value: 'Poole', |
|
}); |
|
await verifyHookTrigger(0, '', request); |
|
await dashboard.grid.editRow({ index: 0, value: 'Delaware' }); |
|
await verifyHookTrigger(0, '', request); |
|
await dashboard.grid.deleteRow(0); |
|
await verifyHookTrigger(0, '', request); |
|
}); |
|
|
|
test('webhook Conditional webhooks', async ({ request }) => { |
|
test.slow(); |
|
|
|
await clearServerData({ request }); |
|
// close 'Team & Auth' tab |
|
await dashboard.closeTab({ title: 'Team & Auth' }); |
|
await dashboard.treeView.createTable({ title: 'Test' }); |
|
|
|
// after insert hook |
|
await webhook.create({ |
|
title: 'hook-1', |
|
event: 'After Insert', |
|
}); |
|
// after insert hook |
|
await webhook.create({ |
|
title: 'hook-2', |
|
event: 'After Update', |
|
}); |
|
// after insert hook |
|
await webhook.create({ |
|
title: 'hook-3', |
|
event: 'After Delete', |
|
}); |
|
|
|
await webhook.open({ index: 0 }); |
|
await webhook.addCondition({ |
|
column: 'Title', |
|
operator: 'is like', |
|
value: 'Poole', |
|
save: true, |
|
}); |
|
|
|
await webhook.open({ index: 1 }); |
|
await webhook.addCondition({ |
|
column: 'Title', |
|
operator: 'is like', |
|
value: 'Poole', |
|
save: true, |
|
}); |
|
|
|
await webhook.open({ index: 2 }); |
|
await webhook.addCondition({ |
|
column: 'Title', |
|
operator: 'is like', |
|
value: 'Poole', |
|
save: true, |
|
}); |
|
|
|
/////////////////////////////////////////////////////////////////////////// |
|
|
|
// webhook with condition |
|
|
|
// hook order |
|
// hook-1: after insert where Title is like 'Poole' |
|
// hook-2: after update where Title is like 'Poole' |
|
// hook-3: after delete where Title is like 'Poole' |
|
// - verify trigger after insert gets triggered only when Title is like 'Poole' |
|
// - verify trigger after edit gets triggered only when Title is like 'Poole' |
|
// - verify trigger after delete gets triggered only when Title is like 'Poole' |
|
|
|
await clearServerData({ request }); |
|
await dashboard.grid.addNewRow({ |
|
index: 0, |
|
columnHeader: 'Title', |
|
value: 'Poole', |
|
}); |
|
await dashboard.grid.addNewRow({ |
|
index: 1, |
|
columnHeader: 'Title', |
|
value: 'Delaware', |
|
}); |
|
await verifyHookTrigger(1, 'Poole', request, buildExpectedResponseData('records.after.insert', 'Poole')); |
|
await dashboard.grid.editRow({ index: 0, value: 'Delaware' }); |
|
await dashboard.grid.editRow({ index: 1, value: 'Poole' }); |
|
await verifyHookTrigger( |
|
2, |
|
'Poole', |
|
request, |
|
buildExpectedResponseData('records.after.update', 'Poole', 'Delaware') |
|
); |
|
await dashboard.grid.deleteRow(1); |
|
await dashboard.grid.deleteRow(0); |
|
await verifyHookTrigger(3, 'Poole', request, buildExpectedResponseData('records.after.delete', 'Poole')); |
|
|
|
/////////////////////////////////////////////////////////////////////////// |
|
|
|
// webhook after conditions are removed |
|
|
|
// hook order |
|
// hook-1: after insert |
|
// hook-2: after update |
|
// hook-3: after delete |
|
// - verify trigger after insert gets triggered when Title is like 'Poole' or not |
|
// - verify trigger after edit gets triggered when Title is like 'Poole' or not |
|
// - verify trigger after delete gets triggered when Title is like 'Poole' or not |
|
await webhook.open({ index: 2 }); |
|
await webhook.deleteCondition({ save: true }); |
|
await webhook.open({ index: 1 }); |
|
await webhook.deleteCondition({ save: true }); |
|
await webhook.open({ index: 0 }); |
|
await webhook.deleteCondition({ save: true }); |
|
|
|
await clearServerData({ request }); |
|
await dashboard.grid.addNewRow({ |
|
index: 0, |
|
columnHeader: 'Title', |
|
value: 'Poole', |
|
}); |
|
await dashboard.grid.addNewRow({ |
|
index: 1, |
|
columnHeader: 'Title', |
|
value: 'Delaware', |
|
}); |
|
await verifyHookTrigger(2, 'Delaware', request, buildExpectedResponseData('records.after.insert', 'Delaware')); |
|
await dashboard.grid.editRow({ index: 0, value: 'Delaware' }); |
|
await dashboard.grid.editRow({ index: 1, value: 'Poole' }); |
|
await verifyHookTrigger( |
|
4, |
|
'Poole', |
|
request, |
|
buildExpectedResponseData('records.after.update', 'Poole', 'Delaware') |
|
); |
|
await dashboard.grid.deleteRow(1); |
|
await dashboard.grid.deleteRow(0); |
|
await verifyHookTrigger(6, 'Delaware', request, buildExpectedResponseData('records.after.delete', 'Delaware')); |
|
}); |
|
|
|
test('Bulk operations', async ({ request, page }) => { |
|
async function verifyBulkOperationTrigger(rsp, type) { |
|
for (let i = 0; i < rsp.length; i++) { |
|
expect(rsp[i].type).toBe(type); |
|
expect(rsp[i].data.table_name).toBe('numberBased'); |
|
expect(rsp[i].data.view_name).toBe('numberBased'); |
|
|
|
// only for insert, rows inserted will not be returned in response. just count |
|
if (type === 'records.after.bulkInsert') { |
|
expect(rsp[i].data.rows_inserted).toBe(50); |
|
} else if (type === 'records.after.bulkUpdate') { |
|
expect(rsp[i].data.rows.length).toBe(50); |
|
expect(rsp[i].data.previous_rows.length).toBe(50); |
|
|
|
// verify records |
|
for (let j = 0; j < rsp[i].data.rows.length; j++) { |
|
expect(+rsp[i].data.rows[j].Number).toBe(111 * (j + 1)); |
|
expect(+rsp[i].data.previous_rows[j].Number).toBe(100 * (j + 1)); |
|
} |
|
} else if (type === 'records.after.bulkDelete') { |
|
expect(rsp[i].data.rows.length).toBe(50); |
|
|
|
// verify records |
|
for (let j = 0; j < rsp[i].data.rows.length; j++) { |
|
expect(+rsp[i].data.rows[j].Number).toBe(111 * (j + 1)); |
|
} |
|
} |
|
} |
|
} |
|
|
|
// Waiting for the server to start |
|
await page.waitForTimeout(1000); |
|
|
|
// close 'Team & Auth' tab |
|
await dashboard.closeTab({ title: 'Team & Auth' }); |
|
|
|
const columns = [ |
|
{ |
|
column_name: 'Id', |
|
title: 'Id', |
|
uidt: UITypes.ID, |
|
}, |
|
{ |
|
column_name: 'Number', |
|
title: 'Number', |
|
uidt: UITypes.Number, |
|
}, |
|
]; |
|
let project, table; |
|
|
|
try { |
|
project = await api.project.read(context.project.id); |
|
table = await api.base.tableCreate(context.project.id, project.bases?.[0].id, { |
|
table_name: 'numberBased', |
|
title: 'numberBased', |
|
columns: columns, |
|
}); |
|
} catch (e) { |
|
console.error(e); |
|
} |
|
|
|
await page.reload(); |
|
await dashboard.treeView.openTable({ title: 'numberBased' }); |
|
|
|
// create after insert webhook |
|
await webhook.create({ |
|
title: 'hook-1', |
|
event: 'After Bulk Insert', |
|
}); |
|
await webhook.create({ |
|
title: 'hook-1', |
|
event: 'After Bulk Update', |
|
}); |
|
await webhook.create({ |
|
title: 'hook-1', |
|
event: 'After Bulk Delete', |
|
}); |
|
|
|
await clearServerData({ request }); |
|
const rowAttributesForInsert = Array.from({ length: 50 }, (_, i) => ({ |
|
Id: i + 1, |
|
Number: (i + 1) * 100, |
|
})); |
|
await api.dbTableRow.bulkCreate('noco', context.project.id, table.id, rowAttributesForInsert); |
|
await page.reload(); |
|
// 50 records inserted, we expect 2 webhook responses |
|
let rsp = await getWebhookResponses({ request, count: 1 }); |
|
await verifyBulkOperationTrigger(rsp, 'records.after.bulkInsert'); |
|
|
|
// bulk update all rows |
|
await clearServerData({ request }); |
|
// build rowAttributes for update to contain all the ids & their value set to 100 |
|
const rowAttributesForUpdate = Array.from({ length: 50 }, (_, i) => ({ |
|
Id: i + 1, |
|
Number: (i + 1) * 111, |
|
})); |
|
|
|
await api.dbTableRow.bulkUpdate('noco', context.project.id, table.id, rowAttributesForUpdate); |
|
await page.reload(); |
|
// 50 records updated, we expect 2 webhook responses |
|
rsp = await getWebhookResponses({ request, count: 1 }); |
|
await verifyBulkOperationTrigger(rsp, 'records.after.bulkUpdate'); |
|
|
|
// bulk delete all rows |
|
await clearServerData({ request }); |
|
const rowAttributesForDelete = Array.from({ length: 50 }, (_, i) => ({ Id: i + 1 })); |
|
|
|
await api.dbTableRow.bulkDelete('noco', context.project.id, table.id, rowAttributesForDelete); |
|
await page.reload(); |
|
rsp = await getWebhookResponses({ request, count: 1 }); |
|
await verifyBulkOperationTrigger(rsp, 'records.after.bulkDelete'); |
|
}); |
|
|
|
test('Virtual columns', async ({ request, page }) => { |
|
let cityTable, countryTable; |
|
const cityColumns = [ |
|
{ |
|
column_name: 'Id', |
|
title: 'Id', |
|
uidt: UITypes.ID, |
|
}, |
|
{ |
|
column_name: 'City', |
|
title: 'City', |
|
uidt: UITypes.SingleLineText, |
|
pv: true, |
|
}, |
|
{ |
|
column_name: 'CityCode', |
|
title: 'CityCode', |
|
uidt: UITypes.Number, |
|
}, |
|
]; |
|
const countryColumns = [ |
|
{ |
|
column_name: 'Id', |
|
title: 'Id', |
|
uidt: UITypes.ID, |
|
}, |
|
{ |
|
column_name: 'Country', |
|
title: 'Country', |
|
uidt: UITypes.SingleLineText, |
|
pv: true, |
|
}, |
|
{ |
|
column_name: 'CountryCode', |
|
title: 'CountryCode', |
|
uidt: UITypes.Number, |
|
}, |
|
]; |
|
|
|
try { |
|
const project = await api.project.read(context.project.id); |
|
cityTable = await api.base.tableCreate(context.project.id, project.bases?.[0].id, { |
|
table_name: 'City', |
|
title: 'City', |
|
columns: cityColumns, |
|
}); |
|
countryTable = await api.base.tableCreate(context.project.id, project.bases?.[0].id, { |
|
table_name: 'Country', |
|
title: 'Country', |
|
columns: countryColumns, |
|
}); |
|
|
|
const cityRowAttributes = [ |
|
{ City: 'Mumbai', CityCode: 23 }, |
|
{ City: 'Pune', CityCode: 33 }, |
|
{ City: 'Delhi', CityCode: 43 }, |
|
{ City: 'Bangalore', CityCode: 53 }, |
|
]; |
|
await api.dbTableRow.bulkCreate('noco', context.project.id, cityTable.id, cityRowAttributes); |
|
|
|
const countryRowAttributes = [ |
|
{ Country: 'India', CountryCode: 1 }, |
|
{ Country: 'USA', CountryCode: 2 }, |
|
{ Country: 'UK', CountryCode: 3 }, |
|
{ Country: 'Australia', CountryCode: 4 }, |
|
]; |
|
await api.dbTableRow.bulkCreate('noco', context.project.id, countryTable.id, countryRowAttributes); |
|
|
|
// create LTAR Country has-many City |
|
countryTable = await api.dbTableColumn.create(countryTable.id, { |
|
column_name: 'CityList', |
|
title: 'CityList', |
|
uidt: UITypes.LinkToAnotherRecord, |
|
parentId: countryTable.id, |
|
childId: cityTable.id, |
|
type: 'hm', |
|
}); |
|
|
|
// Create Lookup column in Country table |
|
countryTable = await api.dbTableColumn.create(countryTable.id, { |
|
column_name: 'CityCodeLookup', |
|
title: 'CityCodeLookup', |
|
uidt: UITypes.Lookup, |
|
fk_relation_column_id: countryTable.columns.filter(c => c.title === 'CityList')[0].id, |
|
fk_lookup_column_id: cityTable.columns.filter(c => c.title === 'CityCode')[0].id, |
|
}); |
|
|
|
// Create Rollup column in Country table |
|
countryTable = await api.dbTableColumn.create(countryTable.id, { |
|
column_name: 'CityCodeRollup', |
|
title: 'CityCodeRollup', |
|
uidt: UITypes.Rollup, |
|
fk_relation_column_id: countryTable.columns.filter(c => c.title === 'CityList')[0].id, |
|
fk_rollup_column_id: cityTable.columns.filter(c => c.title === 'CityCode')[0].id, |
|
rollup_function: 'count', |
|
}); |
|
|
|
// Create links |
|
await api.dbTableRow.nestedAdd('noco', context.project.title, countryTable.title, 1, 'hm', 'CityList', '1'); |
|
await api.dbTableRow.nestedAdd('noco', context.project.title, countryTable.title, 1, 'hm', 'CityList', '2'); |
|
await api.dbTableRow.nestedAdd('noco', context.project.title, countryTable.title, 2, 'hm', 'CityList', '3'); |
|
await api.dbTableRow.nestedAdd('noco', context.project.title, countryTable.title, 3, 'hm', 'CityList', '4'); |
|
|
|
// create formula column |
|
countryTable = await api.dbTableColumn.create(countryTable.id, { |
|
column_name: 'CityCodeFormula', |
|
title: 'CityCodeFormula', |
|
uidt: UITypes.Formula, |
|
formula_raw: '({Id} * 100)', |
|
}); |
|
} catch (e) { |
|
console.log(e); |
|
} |
|
|
|
await page.reload(); |
|
await dashboard.treeView.openTable({ title: 'Country' }); |
|
|
|
// create after update webhook |
|
// after update hook |
|
await webhook.create({ |
|
title: 'hook-2', |
|
event: 'After Update', |
|
}); |
|
|
|
// clear server data |
|
await clearServerData({ request }); |
|
|
|
// edit first record |
|
await dashboard.grid.editRow({ index: 0, columnHeader: 'Country', value: 'INDIA', networkValidation: false }); |
|
const rsp = await getWebhookResponses({ request, count: 1 }); |
|
|
|
const expectedData = { |
|
type: 'records.after.update', |
|
data: { |
|
table_name: 'Country', |
|
view_name: 'Country', |
|
previous_rows: [ |
|
{ |
|
Id: 1, |
|
Country: 'India', |
|
CountryCode: '1', |
|
CityCodeRollup: '2', |
|
CityCodeFormula: 100, |
|
CityList: [ |
|
{ |
|
Id: 1, |
|
City: 'Mumbai', |
|
}, |
|
{ |
|
Id: 2, |
|
City: 'Pune', |
|
}, |
|
], |
|
CityCodeLookup: ['23', '33'], |
|
}, |
|
], |
|
rows: [ |
|
{ |
|
Id: 1, |
|
Country: 'INDIA', |
|
CountryCode: '1', |
|
CityCodeRollup: '2', |
|
CityCodeFormula: 100, |
|
CityList: [ |
|
{ |
|
Id: 1, |
|
City: 'Mumbai', |
|
}, |
|
{ |
|
Id: 2, |
|
City: 'Pune', |
|
}, |
|
], |
|
CityCodeLookup: ['23', '33'], |
|
}, |
|
], |
|
}, |
|
}; |
|
|
|
if (isSqlite(context) || isMysql(context)) { |
|
// @ts-ignore |
|
expectedData.data.previous_rows[0].CountryCode = 1; |
|
// @ts-ignore |
|
expectedData.data.rows[0].CountryCode = 1; |
|
// @ts-ignore |
|
expectedData.data.previous_rows[0].CityCodeRollup = 2; |
|
// @ts-ignore |
|
expectedData.data.rows[0].CityCodeRollup = 2; |
|
// @ts-ignore |
|
expectedData.data.previous_rows[0].CityCodeLookup = [23, 33]; |
|
// @ts-ignore |
|
expectedData.data.rows[0].CityCodeLookup = [23, 33]; |
|
|
|
if (isMysql(context)) { |
|
// @ts-ignore |
|
expectedData.data.previous_rows[0].CityCodeFormula = '100'; |
|
// @ts-ignore |
|
expectedData.data.rows[0].CityCodeFormula = '100'; |
|
} |
|
} |
|
|
|
await expect(isSubset(rsp[0], expectedData)).toBe(true); |
|
}); |
|
});
|
|
|