Merge pull request #2125 from automatisch/aut-1322
test(connection): write model tests
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`Connection model > jsonSchema should have correct validations 1`] = `
|
||||
{
|
||||
"properties": {
|
||||
"appAuthClientId": {
|
||||
"format": "uuid",
|
||||
"type": "string",
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "string",
|
||||
},
|
||||
"data": {
|
||||
"type": "string",
|
||||
},
|
||||
"deletedAt": {
|
||||
"type": "string",
|
||||
},
|
||||
"draft": {
|
||||
"type": "boolean",
|
||||
},
|
||||
"formattedData": {
|
||||
"type": "object",
|
||||
},
|
||||
"id": {
|
||||
"format": "uuid",
|
||||
"type": "string",
|
||||
},
|
||||
"key": {
|
||||
"maxLength": 255,
|
||||
"minLength": 1,
|
||||
"type": "string",
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
},
|
||||
"userId": {
|
||||
"format": "uuid",
|
||||
"type": "string",
|
||||
},
|
||||
"verified": {
|
||||
"default": false,
|
||||
"type": "boolean",
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
"key",
|
||||
],
|
||||
"type": "object",
|
||||
}
|
||||
`;
|
@@ -160,35 +160,6 @@ class Connection extends Base {
|
||||
return this;
|
||||
}
|
||||
|
||||
// TODO: Make another abstraction like beforeSave instead of using
|
||||
// beforeInsert and beforeUpdate separately for the same operation.
|
||||
async $beforeInsert(queryContext) {
|
||||
await super.$beforeInsert(queryContext);
|
||||
|
||||
await this.checkEligibilityForCreation();
|
||||
|
||||
this.encryptData();
|
||||
}
|
||||
|
||||
async $beforeUpdate(opt, queryContext) {
|
||||
await super.$beforeUpdate(opt, queryContext);
|
||||
this.encryptData();
|
||||
}
|
||||
|
||||
async $afterFind() {
|
||||
this.decryptData();
|
||||
}
|
||||
|
||||
async $afterInsert(queryContext) {
|
||||
await super.$afterInsert(queryContext);
|
||||
Telemetry.connectionCreated(this);
|
||||
}
|
||||
|
||||
async $afterUpdate(opt, queryContext) {
|
||||
await super.$afterUpdate(opt, queryContext);
|
||||
Telemetry.connectionUpdated(this);
|
||||
}
|
||||
|
||||
async getApp() {
|
||||
if (!this.key) return null;
|
||||
|
||||
@@ -278,6 +249,35 @@ class Connection extends Base {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: Make another abstraction like beforeSave instead of using
|
||||
// beforeInsert and beforeUpdate separately for the same operation.
|
||||
async $beforeInsert(queryContext) {
|
||||
await super.$beforeInsert(queryContext);
|
||||
|
||||
await this.checkEligibilityForCreation();
|
||||
|
||||
this.encryptData();
|
||||
}
|
||||
|
||||
async $beforeUpdate(opt, queryContext) {
|
||||
await super.$beforeUpdate(opt, queryContext);
|
||||
this.encryptData();
|
||||
}
|
||||
|
||||
async $afterFind() {
|
||||
this.decryptData();
|
||||
}
|
||||
|
||||
async $afterInsert(queryContext) {
|
||||
await super.$afterInsert(queryContext);
|
||||
Telemetry.connectionCreated(this);
|
||||
}
|
||||
|
||||
async $afterUpdate(opt, queryContext) {
|
||||
await super.$afterUpdate(opt, queryContext);
|
||||
Telemetry.connectionUpdated(this);
|
||||
}
|
||||
}
|
||||
|
||||
export default Connection;
|
||||
|
163
packages/backend/src/models/connection.test.js
Normal file
163
packages/backend/src/models/connection.test.js
Normal file
@@ -0,0 +1,163 @@
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import AES from 'crypto-js/aes.js';
|
||||
import enc from 'crypto-js/enc-utf8.js';
|
||||
import appConfig from '../config/app.js';
|
||||
import AppAuthClient from './app-auth-client.js';
|
||||
import AppConfig from './app-config.js';
|
||||
import Base from './base.js';
|
||||
import Connection from './connection';
|
||||
import Step from './step.js';
|
||||
import User from './user.js';
|
||||
|
||||
describe('Connection model', () => {
|
||||
it('tableName should return correct name', () => {
|
||||
expect(Connection.tableName).toBe('connections');
|
||||
});
|
||||
|
||||
it('jsonSchema should have correct validations', () => {
|
||||
expect(Connection.jsonSchema).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('virtualAttributes should return correct attributes', () => {
|
||||
const virtualAttributes = Connection.virtualAttributes;
|
||||
|
||||
const expectedAttributes = ['reconnectable'];
|
||||
|
||||
expect(virtualAttributes).toStrictEqual(expectedAttributes);
|
||||
});
|
||||
|
||||
it('relationMappings should return correct associations', () => {
|
||||
const relationMappings = Connection.relationMappings();
|
||||
|
||||
const expectedRelations = {
|
||||
user: {
|
||||
relation: Base.BelongsToOneRelation,
|
||||
modelClass: User,
|
||||
join: {
|
||||
from: 'connections.user_id',
|
||||
to: 'users.id',
|
||||
},
|
||||
},
|
||||
steps: {
|
||||
relation: Base.HasManyRelation,
|
||||
modelClass: Step,
|
||||
join: {
|
||||
from: 'connections.id',
|
||||
to: 'steps.connection_id',
|
||||
},
|
||||
},
|
||||
triggerSteps: {
|
||||
relation: Base.HasManyRelation,
|
||||
modelClass: Step,
|
||||
join: {
|
||||
from: 'connections.id',
|
||||
to: 'steps.connection_id',
|
||||
},
|
||||
filter: expect.any(Function),
|
||||
},
|
||||
appConfig: {
|
||||
relation: Base.BelongsToOneRelation,
|
||||
modelClass: AppConfig,
|
||||
join: {
|
||||
from: 'connections.key',
|
||||
to: 'app_configs.key',
|
||||
},
|
||||
},
|
||||
appAuthClient: {
|
||||
relation: Base.BelongsToOneRelation,
|
||||
modelClass: AppAuthClient,
|
||||
join: {
|
||||
from: 'connections.app_auth_client_id',
|
||||
to: 'app_auth_clients.id',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
expect(relationMappings).toStrictEqual(expectedRelations);
|
||||
});
|
||||
|
||||
describe.todo('reconnectable');
|
||||
|
||||
describe('encryptData', () => {
|
||||
it('should return undefined if eligibleForEncryption is not true', async () => {
|
||||
vi.spyOn(Connection.prototype, 'eligibleForEncryption').mockReturnValue(
|
||||
false
|
||||
);
|
||||
|
||||
const connection = new Connection();
|
||||
|
||||
expect(connection.encryptData()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should encrypt formattedData and set it to data', async () => {
|
||||
vi.spyOn(Connection.prototype, 'eligibleForEncryption').mockReturnValue(
|
||||
true
|
||||
);
|
||||
|
||||
const formattedData = {
|
||||
key: 'value',
|
||||
};
|
||||
|
||||
const connection = new Connection();
|
||||
connection.formattedData = formattedData;
|
||||
connection.encryptData();
|
||||
|
||||
const expectedDecryptedValue = JSON.parse(
|
||||
AES.decrypt(connection.data, appConfig.encryptionKey).toString(enc)
|
||||
);
|
||||
|
||||
expect(formattedData).toStrictEqual(expectedDecryptedValue);
|
||||
expect(connection.data).not.toEqual(formattedData);
|
||||
});
|
||||
|
||||
it('should encrypt formattedData and remove formattedData', async () => {
|
||||
vi.spyOn(Connection.prototype, 'eligibleForEncryption').mockReturnValue(
|
||||
true
|
||||
);
|
||||
|
||||
const formattedData = {
|
||||
key: 'value',
|
||||
};
|
||||
|
||||
const connection = new Connection();
|
||||
connection.formattedData = formattedData;
|
||||
connection.encryptData();
|
||||
|
||||
expect(connection.formattedData).not.toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('decryptData', () => {
|
||||
it('should return undefined if eligibleForDecryption is not true', () => {
|
||||
vi.spyOn(Connection.prototype, 'eligibleForDecryption').mockReturnValue(
|
||||
false
|
||||
);
|
||||
|
||||
const connection = new Connection();
|
||||
|
||||
expect(connection.decryptData()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should decrypt data and set it to formattedData', async () => {
|
||||
vi.spyOn(Connection.prototype, 'eligibleForDecryption').mockReturnValue(
|
||||
true
|
||||
);
|
||||
|
||||
const formattedData = {
|
||||
key: 'value',
|
||||
};
|
||||
|
||||
const data = AES.encrypt(
|
||||
JSON.stringify(formattedData),
|
||||
appConfig.encryptionKey
|
||||
).toString();
|
||||
|
||||
const connection = new Connection();
|
||||
connection.data = data;
|
||||
connection.decryptData();
|
||||
|
||||
expect(connection.formattedData).toStrictEqual(formattedData);
|
||||
expect(connection.data).not.toEqual(formattedData);
|
||||
});
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user