test(connection): write model tests

This commit is contained in:
Ali BARIN
2024-10-14 10:58:50 +00:00
parent 8268cd4d09
commit 0f77a1ec03
3 changed files with 243 additions and 29 deletions

View File

@@ -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",
}
`;

View File

@@ -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;

View 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);
});
});
});