n8n/packages/nodes-base/nodes/Microsoft/Sql/test/utils.test.ts
Michael Kret a739245332
fix(Microsoft SQL Node): Prevent SQL injection (#7467)
Github issue / Community forum post (link here to close automatically):

---------

Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
2023-10-24 12:36:44 +03:00

146 lines
3 KiB
TypeScript

import { Request } from 'mssql';
import type { IDataObject } from 'n8n-workflow';
import {
configurePool,
deleteOperation,
insertOperation,
updateOperation,
} from '../GenericFunctions';
describe('MSSQL tests', () => {
let querySpy: jest.SpyInstance<void, Parameters<Request['query']>>;
let request: Request;
const assertParameters = (parameters: unknown[][] | IDataObject) => {
if (Array.isArray(parameters)) {
parameters.forEach((values, rowIndex) => {
values.forEach((value, index) => {
const received = (request.parameters[`r${rowIndex}v${index}`] as IDataObject).value;
expect(received).toEqual(value);
});
});
} else {
for (const key in parameters) {
expect((request.parameters[key] as IDataObject).value).toEqual(parameters[key]);
}
}
};
beforeEach(() => {
jest.resetAllMocks();
querySpy = jest.spyOn(Request.prototype, 'query').mockImplementation(async function (
this: Request,
) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
request = this;
return [
[
[
{
recordsets: [],
recordset: undefined,
output: {},
rowsAffected: [0],
},
],
],
];
});
});
it('should perform insert operation', async () => {
const pool = configurePool({});
const tables = {
users: {
'id, name, age, active': [
{
id: 1,
name: 'Sam',
age: 31,
active: false,
},
{
id: 3,
name: 'Jon',
age: null,
active: true,
},
{
id: 4,
name: undefined,
age: 25,
active: false,
},
],
},
};
await insertOperation(tables, pool);
expect(querySpy).toHaveBeenCalledTimes(1);
expect(querySpy).toHaveBeenCalledWith(
'INSERT INTO [users] ([id], [name], [age], [active]) VALUES (@r0v0, @r0v1, @r0v2, @r0v3), (@r1v0, @r1v1, @r1v2, @r1v3), (@r2v0, @r2v1, @r2v2, @r2v3);',
);
assertParameters([
[1, 'Sam', 31, false],
[3, 'Jon', null, true],
[4, null, 25, false],
]);
});
it('should perform update operation', async () => {
const pool = configurePool({});
const tables = {
users: {
'name, age, active': [
{
name: 'Greg',
age: 43,
active: 0,
updateKey: 'id',
id: 2,
},
],
},
};
await updateOperation(tables, pool);
expect(querySpy).toHaveBeenCalledTimes(1);
expect(querySpy).toHaveBeenCalledWith(
'UPDATE [users] SET [name] = @v0, [age] = @v1, [active] = @v2 WHERE id = @condition;',
);
assertParameters({
v0: 'Greg',
v1: 43,
v2: 0,
condition: 2,
});
});
it('should perform delete operation', async () => {
const pool = configurePool({});
const tables = {
users: {
id: [
{
json: {
id: 2,
},
pairedItem: {
item: 0,
input: undefined,
},
},
],
},
};
await deleteOperation(tables, pool);
expect(querySpy).toHaveBeenCalledTimes(1);
expect(querySpy).toHaveBeenCalledWith('DELETE FROM [users] WHERE [id] IN (@v0);');
assertParameters({ v0: 2 });
});
});