Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: communication consumers tests #1249

Merged
merged 19 commits into from
Mar 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/src/modules/communication/communication.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { SlackArchiveChannelConsumer } from 'src/modules/communication/consumers
import { SlackCommunicationConsumer } from 'src/modules/communication/consumers/slack-communication.consumer';
import { SlackArchiveChannelProducer } from 'src/modules/communication/producers/slack-archive-channel.producer';
import { SlackCommunicationProducer } from 'src/modules/communication/producers/slack-communication.producer';
import { SlackAddUserToChannelConsumer } from './consumers/slack-add-user-channel.consummer';
import { SlackAddUserToChannelConsumer } from './consumers/slack-add-user-channel.consumer';
import { SlackMergeBoardConsumer } from './consumers/slack-merge-board.consumer';
import { SlackResponsibleConsumer } from './consumers/slack-responsible.consumer';
import { SlackSendMessageConsumer } from './consumers/slack-send-message.consumer';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { DeepMocked, createMock } from '@golevelup/ts-jest';
import { Test, TestingModule } from '@nestjs/testing';
import { TYPES } from 'src/modules/communication/interfaces/types';
import { AddUserMainChannelType } from '../dto/types';
import { Job } from 'bull';
import { SlackAddUserToChannelConsumer } from './slack-add-user-channel.consumer';
import { AddUserIntoChannelApplicationInterface } from '../interfaces/communication.application.interface copy';
import { Logger } from '@nestjs/common';

const newUserMock = {
id: 1,
data: {
email: 'someEmail@gmail.com'
}
};

describe('SlackAddUserToChannelConsumer', () => {
let consumer: SlackAddUserToChannelConsumer;
let addUserIntoChannelAppMock: DeepMocked<AddUserIntoChannelApplicationInterface>;

beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
SlackAddUserToChannelConsumer,
{
provide: TYPES.application.SlackAddUserIntoChannelApplication,
useValue: createMock<AddUserIntoChannelApplicationInterface>()
}
]
}).compile();
consumer = module.get<SlackAddUserToChannelConsumer>(SlackAddUserToChannelConsumer);
addUserIntoChannelAppMock = module.get(TYPES.application.SlackAddUserIntoChannelApplication);
});

beforeEach(() => {
jest.clearAllMocks();
jest.restoreAllMocks();
});

it('should be defined', () => {
expect(consumer).toBeDefined();
});

describe('communication', () => {
it('should call AddUserIntoChannelApplication.execute once with job.data', async () => {
await consumer.communication(newUserMock as unknown as Job<AddUserMainChannelType>);
expect(addUserIntoChannelAppMock.execute).toHaveBeenNthCalledWith(1, newUserMock.data.email);
});
});

describe('onCompleted', () => {
it('should call Logger with string containing a email ', async () => {
const spyLogger = jest.spyOn(Logger.prototype, 'verbose');
const result: boolean[] = [true];
await consumer.onCompleted(newUserMock as unknown as Job<AddUserMainChannelType>, result);
expect(spyLogger).toHaveBeenNthCalledWith(1, expect.stringContaining('someEmail@gmail.com'));
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,5 @@ export class SlackAddUserToChannelConsumer extends SlackCommunicationEventListen
!result[0] ? 'not' : ''
} added to the main channel`
);
this.saveLog(
`User with email: ${job.data.email} was ${!result[0] ? 'not' : ''} added to the main channel`
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { DeepMocked, createMock } from '@golevelup/ts-jest';
import { Test, TestingModule } from '@nestjs/testing';
import { TYPES } from 'src/modules/communication/interfaces/types';
import { ArchiveChannelData } from '../dto/types';
import { Job } from 'bull';
import { SlackArchiveChannelConsumer } from './slack-archive-channel.consumer';
import { ArchiveChannelApplicationInterface } from '../interfaces/archive-channel.application.interface';
import { Logger } from '@nestjs/common';

const archiveChannelDataMock = {
id: 1,
data: {
type: 'CHANNEL_ID',
data: { id: '1', slackChannelId: 'someSlackId' },
cascade: true
}
};

describe('SlackArchiveChannelConsumer', () => {
let consumer: SlackArchiveChannelConsumer;
let archiveChannelAppMock: DeepMocked<ArchiveChannelApplicationInterface>;

beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
SlackArchiveChannelConsumer,
{
provide: TYPES.application.SlackArchiveChannelApplication,
useValue: createMock<ArchiveChannelApplicationInterface>()
}
]
}).compile();
consumer = module.get<SlackArchiveChannelConsumer>(SlackArchiveChannelConsumer);
archiveChannelAppMock = module.get(TYPES.application.SlackArchiveChannelApplication);
});

beforeEach(() => {
jest.clearAllMocks();
jest.restoreAllMocks();
});

it('should be defined', () => {
expect(consumer).toBeDefined();
});

describe('communication', () => {
it('should call ArchiveChannelApplication.execute once with job.data', async () => {
await consumer.communication(archiveChannelDataMock as unknown as Job<ArchiveChannelData>);

expect(archiveChannelAppMock.execute).toHaveBeenNthCalledWith(1, archiveChannelDataMock.data);
});

it('should call Logger when type CHANNEL_ID', async () => {
const spyLogger = jest.spyOn(Logger.prototype, 'verbose');
//Type 'CHANNEL_ID'
await consumer.communication(archiveChannelDataMock as unknown as Job<ArchiveChannelData>);
expect(spyLogger).toBeCalledTimes(1);
});
it('should call Logger when type BOARD', async () => {
const spyLogger = jest.spyOn(Logger.prototype, 'verbose');
archiveChannelDataMock.data.type = 'BOARD';
//Type 'BOARD'
await consumer.communication(archiveChannelDataMock as unknown as Job<ArchiveChannelData>);
expect(spyLogger).toBeCalledTimes(1);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Logger } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import { Job } from 'bull';
import { BoardType } from '../dto/types';
import { SlackCommunicationEventListeners } from './slack-communication-event-listeners';
import { TeamDto } from 'src/modules/communication/dto/team.dto';

const BoardTypeMock = {
id: 1,
data: {}
};

describe('SlackCommunicationEventListeners', () => {
let listener: SlackCommunicationEventListeners<BoardType, TeamDto>;

beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [SlackCommunicationEventListeners]
}).compile();
listener = module.get<SlackCommunicationEventListeners<BoardType, TeamDto>>(
SlackCommunicationEventListeners
);

listener.logger = new Logger();
});

beforeEach(() => {
jest.clearAllMocks();
jest.restoreAllMocks();
});

it('should be defined', () => {
expect(listener).toBeDefined();
});

it('should call logger.verbose onCompleted', () => {
const spyLogger = jest.spyOn(Logger.prototype, 'verbose');
listener.onCompleted(BoardTypeMock as unknown as Job<BoardType>, undefined);
expect(spyLogger).toHaveBeenNthCalledWith(1, expect.stringContaining('1'));
});

it('should call logger.verbose onFailed', () => {
const spyLogger = jest.spyOn(Logger.prototype, 'error').mockImplementation(jest.fn());
listener.onFailed(BoardTypeMock as unknown as Job<BoardType>, 'someError');
expect(spyLogger).toHaveBeenCalledTimes(1);
});

it('should call logger.error onError', () => {
const spyLogger = jest.spyOn(Logger.prototype, 'error').mockImplementation(jest.fn());
listener.onError(new Error('someError'));
expect(spyLogger).toHaveBeenCalledTimes(1);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import { OnQueueCompleted, OnQueueError, OnQueueFailed, Process } from '@nestjs/bull';
import { Logger } from '@nestjs/common';
import { Job } from 'bull';
import { createWriteStream } from 'fs';

export class SlackCommunicationEventListeners<T, R> {
constructor(public logger: Logger) {}
Expand All @@ -13,9 +12,8 @@ export class SlackCommunicationEventListeners<T, R> {

// https://github.com/OptimalBits/bull/blob/develop/REFERENCE.md#events
@OnQueueCompleted()
async onCompleted(job: Job<T>, result: R[]) {
async onCompleted(job: Job<T>, _result: R[]) {
this.logger.verbose(`Completed Job id: "${job.id}"`);
this.saveLog(result);
}

@OnQueueFailed()
Expand All @@ -27,14 +25,4 @@ export class SlackCommunicationEventListeners<T, R> {
onError(error: Error) {
this.logger.error(`Error on queue: "${JSON.stringify(error)}"`);
}

saveLog(data: any) {
try {
const stream = createWriteStream('slackLog.txt', { flags: 'a' });
stream.write(`${JSON.stringify(data)}\n`);
stream.end();
} catch (error) {
this.logger.error(error);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { DeepMocked, createMock } from '@golevelup/ts-jest';
import { Test, TestingModule } from '@nestjs/testing';
import { TYPES } from 'src/modules/communication/interfaces/types';
import { TYPES as BOARD_TYPES } from 'src/modules/boards/interfaces/types';
import { BoardType } from '../dto/types';
import { Job } from 'bull';
import { SlackCommunicationConsumer } from './slack-communication.consumer';
import { CommunicationApplicationInterface } from '../interfaces/communication.application.interface';
import { UpdateBoardServiceInterface } from 'src/modules/boards/interfaces/services/update.board.service.interface';
import { Logger } from '@nestjs/common';
import { UserFactory } from 'src/libs/test-utils/mocks/factories/user-factory';
import { TeamDto } from 'src/modules/communication/dto/team.dto';

const BoardTypeMock = {
id: 1,
data: {
id: 'someId',
title: 'someTitle',
isSubBoard: true,
dividedBoards: 'BoardType[]',
team: null,
users: '',
slackChannelId: 'someSlackChannelId',
boardNumber: 1
}
};

const result = [
{
name: 'someName',
normalName: 'normalName',
boardId: 'someBoardId',
channelId: 'someChannelId',
type: 'team',
for: 'member',
participants: UserFactory.createMany(2),
teamNumber: 2
}
];

describe('SlackCommunicationConsumer', () => {
let consumer: SlackCommunicationConsumer;
let communicationAppMock: DeepMocked<CommunicationApplicationInterface>;
let updateBoardServiceMock: DeepMocked<UpdateBoardServiceInterface>;

beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
SlackCommunicationConsumer,
{
provide: TYPES.application.SlackCommunicationApplication,
useValue: createMock<CommunicationApplicationInterface>()
},
{
provide: BOARD_TYPES.services.UpdateBoardService,
useValue: createMock<UpdateBoardServiceInterface>()
}
]
}).compile();
consumer = module.get<SlackCommunicationConsumer>(SlackCommunicationConsumer);
communicationAppMock = module.get(TYPES.application.SlackCommunicationApplication);
updateBoardServiceMock = module.get(BOARD_TYPES.services.UpdateBoardService);
});

beforeEach(() => {
jest.clearAllMocks();
jest.restoreAllMocks();
});

it('should be defined', () => {
expect(consumer).toBeDefined();
});

describe('communication', () => {
it('should call application.execute once with job.data', async () => {
await consumer.communication(BoardTypeMock as unknown as Job<BoardType>);
expect(communicationAppMock.execute).toHaveBeenNthCalledWith(1, BoardTypeMock.data);
});

it('should call Logger when type BOARD', async () => {
const spyLogger = jest.spyOn(Logger.prototype, 'verbose');
await consumer.communication(BoardTypeMock as unknown as Job<BoardType>);
expect(spyLogger).toBeCalledTimes(1);
});
});

describe('onCompleted', () => {
it('should call Logger once', async () => {
const spyLogger = jest.spyOn(Logger.prototype, 'verbose');
await consumer.onCompleted(
BoardTypeMock as unknown as Job<BoardType>,
result as unknown as TeamDto[]
);
expect(spyLogger).toBeCalledTimes(1);
});
it('should call updateBoardService once', async () => {
await consumer.onCompleted(
BoardTypeMock as unknown as Job<BoardType>,
result as unknown as TeamDto[]
);
expect(updateBoardServiceMock.updateChannelId).toBeCalledTimes(1);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,5 @@ export class SlackCommunicationConsumer extends SlackCommunicationEventListeners
override async onCompleted(job: Job<BoardType>, result: TeamDto[]) {
this.logger.verbose(`Completed Job id: "${job.id}"`);
this.updateBoardService.updateChannelId(result);
this.saveLog(result);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { DeepMocked, createMock } from '@golevelup/ts-jest';
import { Test, TestingModule } from '@nestjs/testing';
import { TYPES } from 'src/modules/communication/interfaces/types';
import { MergeBoardType } from '../dto/types';
import { Job } from 'bull';
import { SlackMergeBoardConsumer } from './slack-merge-board.consumer';
import { MergeBoardApplicationInterface } from '../interfaces/merge-board.application.interface';

const mergeBoardTypeMock = {
id: 1,
data: {
teamNumber: 1,
responsiblesChannelId: 'someResponsiblesChannelId',
isLastSubBoard: true,
boardId: 'someBoardId',
mainBoardId: 'mainBoardId'
}
};

describe('SlackMergeBoardConsumer', () => {
let consumer: SlackMergeBoardConsumer;
let applicationMock: DeepMocked<MergeBoardApplicationInterface>;

beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
SlackMergeBoardConsumer,
{
provide: TYPES.application.SlackMergeBoardApplication,
useValue: createMock<MergeBoardApplicationInterface>()
}
]
}).compile();
consumer = module.get<SlackMergeBoardConsumer>(SlackMergeBoardConsumer);
applicationMock = module.get(TYPES.application.SlackMergeBoardApplication);
});

beforeEach(() => {
jest.clearAllMocks();
jest.restoreAllMocks();
});

it('should be defined', () => {
expect(consumer).toBeDefined();
});

it('should call application.execute once with job.data', async () => {
await consumer.communication(mergeBoardTypeMock as unknown as Job<MergeBoardType>);
expect(applicationMock.execute).toHaveBeenNthCalledWith(1, mergeBoardTypeMock.data);
});
});
Loading