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

refactor: usecase of get board service #1338

Merged
merged 12 commits into from
Apr 4, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { Inject, Injectable } from '@nestjs/common';
import * as User from 'src/modules/users/interfaces/types';
import * as TeamUsers from 'src/modules/teamUsers/interfaces/types';
import * as Boards from 'src/modules/boards/interfaces/types';
import { GetBoardApplicationInterface } from 'src/modules/boards/interfaces/applications/get.board.application.interface';
import { GetUserServiceInterface } from 'src/modules/users/interfaces/services/get.user.service.interface';
import { StatisticsAuthUserUseCaseInterface } from '../interfaces/applications/statistics.auth.use-case.interface';
import { GetTeamUserServiceInterface } from 'src/modules/teamUsers/interfaces/services/get.team.user.service.interface';
import { GetBoardServiceInterface } from 'src/modules/boards/interfaces/services/get.board.service.interface';
CatiaAntunes96 marked this conversation as resolved.
Show resolved Hide resolved

@Injectable()
export default class StatisticsAuthUserUseCase implements StatisticsAuthUserUseCaseInterface {
Expand All @@ -14,8 +14,8 @@ export default class StatisticsAuthUserUseCase implements StatisticsAuthUserUseC
private getUserService: GetUserServiceInterface,
@Inject(TeamUsers.TYPES.services.GetTeamUserService)
private getTeamUserService: GetTeamUserServiceInterface,
@Inject(Boards.TYPES.applications.GetBoardApplication)
private getBoardService: GetBoardApplicationInterface
@Inject(Boards.TYPES.services.GetBoardService)
private getBoardService: GetBoardServiceInterface
) {}

public async execute(userId: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import { CreateBoardUserServiceInterface } from 'src/modules/boardUsers/interfac
import faker from '@faker-js/faker';
import { BoardDtoFactory } from 'src/libs/test-utils/mocks/factories/dto/boardDto-factory.mock';
import { CreateBoardServiceInterface } from '../interfaces/services/create.board.service.interface';
import { UseCase } from 'src/libs/interfaces/use-case.interface';
import CreateBoardUseCaseDto from '../dto/useCase/create-board.use-case.dto';
import Board from '../entities/board.schema';
import { CreateBoardUseCase } from './create-board.use-case';

describe('CreateBoardUseCase', () => {
let createBoardMock: CreateBoardUseCase;
let useCase: UseCase<CreateBoardUseCaseDto, Board>;
let createBoardServiceMock: DeepMocked<CreateBoardServiceInterface>;

beforeAll(async () => {
Expand All @@ -22,7 +25,7 @@ describe('CreateBoardUseCase', () => {
]
}).compile();

createBoardMock = module.get<CreateBoardUseCase>(CreateBoardUseCase);
useCase = module.get(CreateBoardUseCase);

createBoardServiceMock = module.get(Boards.TYPES.services.CreateBoardService);
});
Expand All @@ -32,15 +35,15 @@ describe('CreateBoardUseCase', () => {
});

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

describe('execute', () => {
it('should be called with argument of type createBoardUseCaseDto', async () => {
const boardData = BoardDtoFactory.create();
const userId = faker.datatype.uuid();

await createBoardMock.execute({ userId, boardData });
await useCase.execute({ userId, boardData });

expect(createBoardServiceMock.create).toBeCalledWith(boardData, userId);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import * as BoardUsers from 'src/modules/boardUsers/interfaces/types';
import * as Boards from 'src/modules/boards/interfaces/types';
import * as Users from 'src/modules/users/interfaces/types';
import { DeepMocked, createMock } from '@golevelup/ts-jest';
import { duplicateBoardUseCase } from '../boards.providers';
import { UseCase } from 'src/libs/interfaces/use-case.interface';
import Board from '../entities/board.schema';
import { CreateBoardUserServiceInterface } from 'src/modules/boardUsers/interfaces/services/create.board.user.service.interface';
Expand All @@ -14,7 +13,7 @@ import faker from '@faker-js/faker';
import { GetUserServiceInterface } from 'src/modules/users/interfaces/services/get.user.service.interface';
import { BoardFactory } from 'src/libs/test-utils/mocks/factories/board-factory.mock';
import { UserFactory } from 'src/libs/test-utils/mocks/factories/user-factory';
import { DuplicateBoardDto } from './duplicate-board.use-case';
import { DuplicateBoardDto, DuplicateBoardUseCase } from './duplicate-board.use-case';

describe('DuplicateBoardUseCase', () => {
let duplicateBoardMock: UseCase<DuplicateBoardDto, Board>;
Expand All @@ -26,7 +25,7 @@ describe('DuplicateBoardUseCase', () => {
beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
duplicateBoardUseCase,
DuplicateBoardUseCase,
{
provide: Users.TYPES.services.GetUserService,
useValue: createMock<GetUserServiceInterface>()
Expand All @@ -46,9 +45,7 @@ describe('DuplicateBoardUseCase', () => {
]
}).compile();

duplicateBoardMock = module.get<UseCase<DuplicateBoardDto, Board>>(
Boards.TYPES.applications.DuplicateBoardUseCase
);
duplicateBoardMock = module.get(DuplicateBoardUseCase);

getUserServiceMock = module.get(Users.TYPES.services.GetUserService);
getBoardServiceMock = module.get(Boards.TYPES.services.GetBoardService);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class DuplicateBoardUseCase implements UseCase<DuplicateBoardDto, Board>
private createBoardUserService: CreateBoardUserServiceInterface
) {}

async execute({ boardId, userId, boardTitle }) {
async execute({ boardId, userId, boardTitle }: DuplicateBoardDto) {
const currentUser = await this.getUserService.getById(userId);

if (!currentUser) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { Test, TestingModule } from '@nestjs/testing';
import * as Boards from 'src/modules/boards/interfaces/types';
import { DeepMocked, createMock } from '@golevelup/ts-jest';
import { GetBoardServiceInterface } from '../interfaces/services/get.board.service.interface';
import faker from '@faker-js/faker';
import { BoardFactory } from 'src/libs/test-utils/mocks/factories/board-factory.mock';
import { TeamFactory } from 'src/libs/test-utils/mocks/factories/team-factory.mock';
import { UseCase } from 'src/libs/interfaces/use-case.interface';
import GetAllBoardsUseCaseDto from '../dto/useCase/get-all-boards.use-case.dto';
import BoardsPaginatedPresenter from '../presenter/boards-paginated.presenter';
import { GetAllBoardsUseCase } from './get-all-boards.use-case';

const teams = TeamFactory.createMany(2);
const teamIds = teams.map((team) => team._id);
const boards = BoardFactory.createMany(5, [
{ isSubBoard: false, team: teamIds[0] },
{ isSubBoard: false, team: teamIds[0] },
{ isSubBoard: false, team: null },
{ isSubBoard: false, team: teamIds[1] },
{ isSubBoard: true, team: teamIds[1] }
]);
const boardIds = boards.map((board) => board._id);

const userId = faker.datatype.uuid();

describe('GetAllBoardsUseCase', () => {
let useCase: UseCase<GetAllBoardsUseCaseDto, BoardsPaginatedPresenter>;
let getBoardServiceMock: DeepMocked<GetBoardServiceInterface>;

beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
GetAllBoardsUseCase,
{
provide: Boards.TYPES.services.GetBoardService,
useValue: createMock<GetBoardServiceInterface>()
}
]
}).compile();

useCase = module.get(GetAllBoardsUseCase);
getBoardServiceMock = module.get(Boards.TYPES.services.GetBoardService);
});

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

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

describe('execute', () => {
it('should return all the boards of a team', async () => {
const filterBoardsResponse = boards.filter(
(board) => !board.isSubBoard && String(board.team) === teams[0]._id
);

const teamBoards = { boards: filterBoardsResponse, hasNextPage: false, page: 1 };

getBoardServiceMock.getBoards.mockResolvedValue(teamBoards);

const result = await useCase.execute({
team: teams[0]._id,
userId,
isSAdmin: false,
page: 0,
size: 10
});

expect(getBoardServiceMock.getBoards).toBeCalledTimes(1);

expect(result).toEqual(teamBoards);
});

it('should return all the boards for a superAdmin', async () => {
const filterBoardsResponse = boards.filter((board) => !board.isSubBoard && board.team);

const allBoards = { boards: filterBoardsResponse, hasNextPage: false, page: 1 };

getBoardServiceMock.getBoards.mockResolvedValue(allBoards);

const result = await useCase.execute({
team: null,
userId,
isSAdmin: true,
page: 0,
size: 10
});

expect(getBoardServiceMock.getAllBoardIdsAndTeamIdsOfUser).toBeCalledTimes(1);
expect(getBoardServiceMock.getBoards).toBeCalledTimes(1);

expect(result).toEqual(allBoards);
});

it('should return all the boards of a regular user', async () => {
const filterBoardsResponse = boards.filter(
(board) =>
!board.isSubBoard &&
(boardIds.includes(board._id) || teamIds.includes(String(board.team)))
);

const allBoards = { boards: filterBoardsResponse, hasNextPage: false, page: 1 };

getBoardServiceMock.getBoards.mockResolvedValue(allBoards);

const result = await useCase.execute({
team: null,
userId,
isSAdmin: false,
page: 0,
size: 10
});

expect(getBoardServiceMock.getAllBoardIdsAndTeamIdsOfUser).toBeCalledTimes(1);
expect(getBoardServiceMock.getBoards).toBeCalledTimes(1);

expect(result).toEqual(allBoards);
});
});
});
57 changes: 57 additions & 0 deletions backend/src/modules/boards/applications/get-all-boards.use-case.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { UseCase } from 'src/libs/interfaces/use-case.interface';
import { Inject, Injectable } from '@nestjs/common';
import { GetBoardServiceInterface } from '../interfaces/services/get.board.service.interface';
import { TYPES } from '../interfaces/types';
import GetAllBoardsUseCaseDto from '../dto/useCase/get-all-boards.use-case.dto';
import BoardsPaginatedPresenter from '../presenter/boards-paginated.presenter';
CatiaAntunes96 marked this conversation as resolved.
Show resolved Hide resolved

@Injectable()
export class GetAllBoardsUseCase
implements UseCase<GetAllBoardsUseCaseDto, BoardsPaginatedPresenter>
{
constructor(
@Inject(TYPES.services.GetBoardService)
private getBoardService: GetBoardServiceInterface
) {}

execute({ team, userId, isSAdmin, page, size }: GetAllBoardsUseCaseDto) {
if (team) {
return this.getTeamBoards(team, page, size);
}

if (isSAdmin) return this.getSuperAdminBoards(userId, page, size);

return this.getBoardsOfUser(userId, page, size);
}

private async getSuperAdminBoards(userId: string, page: number, size?: number) {
const { boardIds } = await this.getBoardService.getAllBoardIdsAndTeamIdsOfUser(userId);

const query = {
$and: [{ isSubBoard: false }, { $or: [{ _id: { $in: boardIds } }, { team: { $ne: null } }] }]
};

return this.getBoardService.getBoards(false, query, page, size);
}

private async getBoardsOfUser(userId: string, page: number, size?: number) {
const { boardIds, teamIds } = await this.getBoardService.getAllBoardIdsAndTeamIdsOfUser(userId);

const query = {
$and: [
{ isSubBoard: false },
{ $or: [{ _id: { $in: boardIds } }, { team: { $in: teamIds } }] }
]
};

return this.getBoardService.getBoards(false, query, page, size);
}

private getTeamBoards(teamId: string, page: number, size?: number) {
const query = {
$and: [{ isSubBoard: false }, { $or: [{ team: teamId }] }]
};

return this.getBoardService.getBoards(false, query, page, size);
}
}
Loading