Skip to content

Commit

Permalink
add unit test to BE
Browse files Browse the repository at this point in the history
FLPATH-798
https://issues.redhat.com/browse/FLPATH-798

Signed-off-by: Yaron Dayagi <[email protected]>
  • Loading branch information
ydayagi committed Dec 27, 2023
1 parent 781b37e commit be30796
Show file tree
Hide file tree
Showing 4 changed files with 338 additions and 0 deletions.
1 change: 1 addition & 0 deletions plugins/notifications-backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
},
"devDependencies": {
"@backstage/backend-test-utils": "^0.2.7",
"@backstage/catalog-model": "^1.4.3",
"@backstage/cli": "0.23.0",
"@types/supertest": "2.0.16",
"knex-mock-client": "2.0.0",
Expand Down
109 changes: 109 additions & 0 deletions plugins/notifications-backend/src/service/db.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { mockServices } from '@backstage/backend-test-utils';

import { initDB } from './db';

describe('db', () => {
beforeAll(() => {});
it('init ok', async () => {
const dbClient = await initDB(
mockServices.rootConfig({
data: {
client: 'better-sqlite3',
connection: {
filename: ':memory:',
},
useNullAsDefault: true,
},
}),
);

await Promise.all([
dbClient.schema
.hasTable('messages')
.then(exists => expect(exists).toBeTruthy()),
dbClient.schema
.hasTable('users')
.then(exists => expect(exists).toBeTruthy()),
dbClient.schema
.hasTable('groups')
.then(exists => expect(exists).toBeTruthy()),
dbClient.schema
.hasTable('actions')
.then(exists => expect(exists).toBeTruthy()),
]);

expect(dbClient.client.config.connection.database).toEqual(
'backstage_plugin_notifications',
);

await dbClient.destroy();
});

it('set DB name and knex config', async () => {
const dbClient = await initDB(
mockServices.rootConfig({
data: {
client: 'better-sqlite3',
connection: {
filename: ':memory:',
database: 'testdb',
},
useNullAsDefault: true,
knexConfig: {
pool: {
min: 1,
max: 1,
},
},
},
}),
);

expect(dbClient.client.config.connection.database).toEqual('testdb');
expect(dbClient.client.config.pool.min).toEqual(1);

await dbClient.destroy();
});

it('set plugin config', async () => {
const dbClient = await initDB(
mockServices.rootConfig({
data: {
client: 'better-sqlite3',
connection: {
filename: ':memory:',
database: 'testdb',
},
useNullAsDefault: true,
knexConfig: {
pool: {
min: 1,
max: 1,
},
},
plugin: {
notifications: {
connection: {
filename: 'plugin',
database: 'plugin',
},
knexConfig: {
pool: {
min: 3,
max: 3,
},
},
},
},
},
}),
);

expect(dbClient.client.config.connection.database).toEqual('plugin');
expect(dbClient.client.config.connection.filename).toEqual('plugin');
expect(dbClient.client.config.pool.min).toEqual(3);
expect(dbClient.client.config.pool.max).toEqual(3);

await dbClient.destroy();
});
});
2 changes: 2 additions & 0 deletions plugins/notifications-backend/src/service/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export async function initDB(dbConfig: Config): Promise<Knex<any, any>> {
dbConfig.getOptional('plugin.notifications.knexConfig'),
dbConfig.get(),
dbConfig.getOptional('knexConfig'),
dbConfig.getOptional('plugin.notifications'),
dbConfig.getOptional('plugin.notifications.knexConfig'),
);
const dbClient = knex(knexConfig);

Expand Down
226 changes: 226 additions & 0 deletions plugins/notifications-backend/src/service/handlers.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
import { mockServices } from '@backstage/backend-test-utils';
import { CatalogClient } from '@backstage/catalog-client';
import { Entity } from '@backstage/catalog-model';

import { Knex } from 'knex';

import { initDB } from './db';
import {
createNotification,
getNotifications,
getNotificationsCount,
setRead,
} from './handlers';

describe('handlers', () => {
//
// create global test vars
//
let dbClient: Knex<any, any>;
let catalogClient: CatalogClient;
const catalogUser = 'test';
const catalogGroup = 'test';
const userEntity: Entity = {
apiVersion: 'v1',
kind: 'user',
metadata: {
name: catalogUser,
},
spec: {
memberOf: ['test'],
},
};
const groupEntity: Entity = {
apiVersion: 'v1',
kind: 'group',
metadata: {
name: catalogGroup,
},
};

//
// initialize global test vars
//
beforeAll(async () => {
dbClient = await initDB(
mockServices.rootConfig({
data: {
client: 'better-sqlite3',
connection: ':memory:',
useNullAsDefault: true,
},
}),
);

catalogClient = new CatalogClient({
discoveryApi: {
getBaseUrl: jest.fn(),
},
fetchApi: {
fetch: jest.fn(),
},
});

catalogClient.getEntityByRef = jest
.fn()
.mockImplementation(async (s: string): Promise<Entity | undefined> => {
const args = s.split(':', 2);
const kind = args[0];
const entity = args[1];

switch (kind) {
case 'user':
if (entity === catalogUser) {
return userEntity;
}
break;
case 'group':
if (entity === catalogGroup) {
return groupEntity;
}
break;
default:
return undefined;
}

return undefined;
});
});

//
// tests
//
it('getNotifications - 0 notifications', async () => {
const notifications = await getNotifications(
dbClient,
catalogClient,
{ user: catalogUser },
undefined,
undefined,
{},
);
expect(Array.isArray(notifications)).toBeTruthy();
});

it('getNotifications - unknown user', async () => {
let hadError = false;

expect.assertions(1);
try {
await getNotifications(
dbClient,
catalogClient,
{},
undefined,
undefined,
{},
);
} catch (e) {
if (e instanceof Error) {
hadError = true;
}
}

expect(hadError).toBeTruthy();
});

it('getNotificationsCount - 0 notifications', async () => {
const result = await getNotificationsCount(dbClient, catalogClient, {
user: catalogUser,
});
expect(result.count).toEqual(0);
});

it('create and get - user notification', async () => {
const before = new Date();
before.setMilliseconds(0);

const resultCreate = await createNotification(dbClient, catalogClient, {
origin: 'test',
title: 'test',
targetUsers: [catalogUser],
});

const after = new Date();

expect(resultCreate.messageId).toBeTruthy();

const resultGet = await getNotifications(
dbClient,
catalogClient,
{ user: catalogUser },
undefined,
undefined,
{},
);

const createdDate = new Date(resultGet[0].created);

expect(resultGet).toHaveLength(1);
expect(createdDate >= before).toBeTruthy();
expect(createdDate < after).toBeTruthy();
expect(resultGet[0].isSystem).toBeFalsy();
});

it('create and get - system notification', async () => {
const before = new Date();
before.setMilliseconds(0);

const resultCreate = await createNotification(dbClient, catalogClient, {
origin: 'test',
title: 'test',
});

const after = new Date();

expect(resultCreate.messageId).toBeTruthy();

const resultGet = await getNotifications(
dbClient,
catalogClient,
{ user: catalogUser, messageScope: 'system' },
undefined,
undefined,
{},
);

const createdDate = new Date(resultGet[0].created);

expect(resultGet).toHaveLength(1);
expect(createdDate >= before).toBeTruthy();
expect(createdDate < after).toBeTruthy();
expect(resultGet[0].isSystem).toBeTruthy();
});

it('mark as read', async () => {
const resultGet = await getNotifications(
dbClient,
catalogClient,
{ user: catalogUser, messageScope: 'all' },
undefined,
undefined,
{},
);

const setReadPromises: Promise<void>[] = [];

resultGet.forEach(async notification => {
setReadPromises.push(
setRead(dbClient, notification.id, catalogUser, true),
);
});

await Promise.all(setReadPromises);

const resultGetRead = await getNotifications(
dbClient,
catalogClient,
{ user: catalogUser, messageScope: 'all', read: true },
undefined,
undefined,
{},
);

expect(resultGetRead).toHaveLength(resultGet.length);
});
});

0 comments on commit be30796

Please sign in to comment.