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

ALCS-2345 Added unit tests #1948

Merged
merged 2 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
import { Test, TestingModule } from '@nestjs/testing';
import { NoticeOfIntentTagController } from './notice-of-intent-tag.controller';
import { NoticeOfIntentTagService } from './notice-of-intent-tag.service';
import { DeepMocked } from '@golevelup/nestjs-testing';
import { createMock, DeepMocked } from '@golevelup/nestjs-testing';
import { ClsService } from 'nestjs-cls';
import { mockKeyCloakProviders } from '../../../../test/mocks/mockTypes';
import {
initNoticeOfIntentMockEntity,
initNoticeOfIntentWithTagsMockEntity,
initTagMockEntity,
} from '../../../../test/mocks/mockEntities';
import { NoticeOfIntentTagDto } from './notice-of-intent-tag.dto';

describe('NoticeOfIntentTagController', () => {
let controller: NoticeOfIntentTagController;
let tagService: DeepMocked<NoticeOfIntentTagService>;
let noiTagService: DeepMocked<NoticeOfIntentTagService>;

const mockNoticeOfIntentEntityWithoutTags = initNoticeOfIntentMockEntity();
mockNoticeOfIntentEntityWithoutTags.tags = [];
const mockNoticeOfIntentEntityWithTags = initNoticeOfIntentWithTagsMockEntity();
const mockTagEntity = initTagMockEntity();

beforeEach(async () => {
noiTagService = createMock();
const module: TestingModule = await Test.createTestingModule({
controllers: [NoticeOfIntentTagController],
providers: [
{ provide: NoticeOfIntentTagService, useValue: tagService },
{ provide: NoticeOfIntentTagService, useValue: noiTagService },
{
provide: ClsService,
useValue: {},
Expand All @@ -28,4 +40,31 @@ describe('NoticeOfIntentTagController', () => {
it('should be defined', () => {
expect(controller).toBeDefined();
});

it('should return tags for the noi', async () => {
noiTagService.getNoticeOfIntentTags.mockResolvedValue([mockTagEntity]);

const result = await controller.getApplicationTags('noi_1');
expect(noiTagService.getNoticeOfIntentTags).toHaveBeenCalledTimes(1);
expect(result[0].name).toEqual('tag-name');
});

it('should create tags', async () => {
noiTagService.addTagToNoticeOfIntent.mockResolvedValue(mockNoticeOfIntentEntityWithTags);

const mockTagDto = new NoticeOfIntentTagDto();
mockTagDto.tagName = 'tag-name';

const result = await controller.addTagToApplication('noi_1', mockTagDto);
expect(noiTagService.addTagToNoticeOfIntent).toHaveBeenCalledTimes(1);
expect(result.tags[0].name).toEqual('tag-name');
});

it('should remove tags', async () => {
noiTagService.removeTagFromNoticeOfIntent.mockResolvedValue(mockNoticeOfIntentEntityWithoutTags);

const result = await controller.removeTagFromApplication('noi_1', 'tag-name');
expect(noiTagService.removeTagFromNoticeOfIntent).toHaveBeenCalledTimes(1);
expect(result.tags.length).toEqual(0);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,42 @@ import { NoticeOfIntent } from '../notice-of-intent.entity';
import { createMock, DeepMocked } from '@golevelup/nestjs-testing';
import { Repository } from 'typeorm';
import { Tag } from '../../tag/tag.entity';
import {
initNoticeOfIntentMockEntity,
initNoticeOfIntentWithTagsMockEntity,
initTagMockEntity,
} from '../../../../test/mocks/mockEntities';
import { ServiceNotFoundException, ServiceValidationException } from '@app/common/exceptions/base.exception';

describe('NoticeOfIntentTagService', () => {
let service: NoticeOfIntentTagService;
let noiRepository: DeepMocked<Repository<NoticeOfIntent>>;
let tagRepository: DeepMocked<Repository<Tag>>;
let noiRepositoryMock: DeepMocked<Repository<NoticeOfIntent>>;
let tagRepositoryMock: DeepMocked<Repository<Tag>>;

let mockNoiEntityWithoutTags: NoticeOfIntent;
let mockNoiEntityWithTags: NoticeOfIntent;
let mockNoiEntityWithDifferentTags: NoticeOfIntent;
let mockTagEntity: Tag;

beforeEach(async () => {
noiRepository = createMock();
tagRepositoryMock = createMock();
noiRepositoryMock = createMock();
mockNoiEntityWithoutTags = initNoticeOfIntentMockEntity();
mockNoiEntityWithTags = initNoticeOfIntentWithTagsMockEntity();
mockNoiEntityWithDifferentTags = initNoticeOfIntentWithTagsMockEntity();
mockNoiEntityWithDifferentTags.tags[0].name = 'tag-name-2';
mockNoiEntityWithDifferentTags.tags[0].uuid = 'tag-uuid-2';
mockTagEntity = initTagMockEntity();
const module: TestingModule = await Test.createTestingModule({
providers: [
NoticeOfIntentTagService,
{
provide: getRepositoryToken(NoticeOfIntent),
useValue: noiRepository,
useValue: noiRepositoryMock,
},
{
provide: getRepositoryToken(Tag),
useValue: tagRepository,
useValue: tagRepositoryMock,
},
],
}).compile();
Expand All @@ -33,4 +51,75 @@ describe('NoticeOfIntentTagService', () => {
it('should be defined', () => {
expect(service).toBeDefined();
});

it('should add tag to the noi if not existing', async () => {
noiRepositoryMock.findOne.mockResolvedValue(mockNoiEntityWithoutTags);
tagRepositoryMock.findOne.mockResolvedValue(mockTagEntity);
noiRepositoryMock.save.mockResolvedValue(mockNoiEntityWithTags);

await service.addTagToNoticeOfIntent('app_1', 'tag-name');
expect(mockNoiEntityWithoutTags.tags.length).toEqual(1);
expect(noiRepositoryMock.save).toHaveBeenCalledTimes(1);
});

it('should raise an error if noi is not found', async () => {
noiRepositoryMock.findOne.mockResolvedValue(null);

await expect(service.addTagToNoticeOfIntent('noi-1', 'tag-name')).rejects.toThrow(ServiceNotFoundException);
});

it('should throw an error if tag is not found', async () => {
noiRepositoryMock.findOne.mockResolvedValue(mockNoiEntityWithoutTags);
tagRepositoryMock.findOne.mockResolvedValue(null);

await expect(service.addTagToNoticeOfIntent('noi-1', 'tag-name')).rejects.toThrow(ServiceNotFoundException);
});

it('should raise an error if the noi already has the tag', async () => {
noiRepositoryMock.findOne.mockResolvedValue(mockNoiEntityWithTags);
tagRepositoryMock.findOne.mockResolvedValue(mockTagEntity);

await expect(service.addTagToNoticeOfIntent('noi-1', 'tag-name')).rejects.toThrow(ServiceValidationException);
});

it('should throw an error if the noi does not have any tags when deleting', async () => {
noiRepositoryMock.findOne.mockResolvedValue(mockNoiEntityWithoutTags);
tagRepositoryMock.findOne.mockResolvedValue(mockTagEntity);

await expect(service.removeTagFromNoticeOfIntent('noi-1', 'tag-name')).rejects.toThrow(ServiceValidationException);
});

it('should throw an error if the noi does not have the tag requested when deleting', async () => {
noiRepositoryMock.findOne.mockResolvedValue(mockNoiEntityWithDifferentTags);
tagRepositoryMock.findOne.mockResolvedValue(mockTagEntity);

await expect(service.removeTagFromNoticeOfIntent('noi-1', 'tag-name')).rejects.toThrow(ServiceValidationException);
});

it('should delete the tag from noi if exists', async () => {
noiRepositoryMock.findOne.mockResolvedValue(mockNoiEntityWithTags);
tagRepositoryMock.findOne.mockResolvedValue(mockTagEntity);
noiRepositoryMock.save.mockResolvedValue(mockNoiEntityWithoutTags);

await service.removeTagFromNoticeOfIntent('noi-1', 'tag-name');
expect(mockNoiEntityWithTags.tags.length).toEqual(0);
expect(noiRepositoryMock.save).toHaveBeenCalledTimes(1);
});

it('should return noi tags', async () => {
noiRepositoryMock.findOne.mockResolvedValue(mockNoiEntityWithTags);
tagRepositoryMock.findOne.mockResolvedValue(mockTagEntity);

const result = await service.getNoticeOfIntentTags('noi-1');
expect(result).toBeTruthy();
expect(result.length).toEqual(1);
});

it('should return empty array if noi does not have tags', async () => {
noiRepositoryMock.findOne.mockResolvedValue(mockNoiEntityWithoutTags);

const result = await service.getNoticeOfIntentTags('noi-1');
expect(result).toEqual([]);
expect(result.length).toEqual(0);
});
});
47 changes: 47 additions & 0 deletions services/apps/alcs/test/mocks/mockEntities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import { AssigneeDto, UserDto } from '../../src/user/user.dto';
import { User } from '../../src/user/user.entity';
import { TagCategory } from '../../src/alcs/tag/tag-category/tag-category.entity';
import { Tag } from '../../src/alcs/tag/tag.entity';
import { NoticeOfIntent } from '../../src/alcs/notice-of-intent/notice-of-intent.entity';
import { NoticeOfIntentType } from '../../src/alcs/notice-of-intent/notice-of-intent-type/notice-of-intent-type.entity';

const initCardStatusMockEntity = (): CardStatus => {
const cardStatus = new CardStatus();
Expand Down Expand Up @@ -115,6 +117,19 @@ const initApplicationTypeMockEntity = (): ApplicationType => {
return applicationType;
};

const initNoticeOfIntentTypeMockEntity = (): NoticeOfIntentType => {
const noticeOfIntentType = new NoticeOfIntentType();
noticeOfIntentType.code = 'type_1';
noticeOfIntentType.description = 'noi desc 1';
noticeOfIntentType.label = 'noi_label';
noticeOfIntentType.shortLabel = 'short_label';
noticeOfIntentType.auditDeletedDateAt = new Date(1, 1, 1, 1, 1, 1, 1);
noticeOfIntentType.auditCreatedAt = new Date(1, 1, 1, 1, 1, 1, 1);
noticeOfIntentType.auditUpdatedAt = new Date(1, 1, 1, 1, 1, 1, 1);

return noticeOfIntentType;
};

const initUserMockEntity = (): User => {
const user = new User();
user.familyName = 'familyName';
Expand Down Expand Up @@ -207,6 +222,28 @@ const initApplicationMockEntity = (fileNumber?: string): Application => {
return applicationEntity;
};

const initNoticeOfIntentMockEntity = (fileNumber?: string): NoticeOfIntent => {
const noticeOfIntentEntity = new NoticeOfIntent();
noticeOfIntentEntity.fileNumber = fileNumber ?? 'app_1';
noticeOfIntentEntity.applicant = 'applicant 1';
noticeOfIntentEntity.uuid = '1111-1111-1111-1111';
noticeOfIntentEntity.auditDeletedDateAt = new Date(1, 1, 1, 1, 1, 1, 1);
noticeOfIntentEntity.auditCreatedAt = new Date(1, 1, 1, 1, 1, 1, 1);
noticeOfIntentEntity.auditUpdatedAt = new Date(1, 1, 1, 1, 1, 1, 1);
noticeOfIntentEntity.card = initCardMockEntity();
noticeOfIntentEntity.cardUuid = noticeOfIntentEntity.card.uuid;
noticeOfIntentEntity.type = initNoticeOfIntentTypeMockEntity();
noticeOfIntentEntity.card.highPriority = false;
noticeOfIntentEntity.region = {
code: 'fake',
label: 'fake',
auditCreatedAt: new Date(1, 1, 1, 1, 1, 1, 1),
auditUpdatedAt: new Date(1, 1, 1, 1, 1, 1, 1),
} as ApplicationRegion;

return noticeOfIntentEntity;
};

const initApplicationWithTagsMockEntity = (): Application => {
const applicationEntity = initApplicationMockEntity();
const tagEntity = initTagMockEntity();
Expand All @@ -215,6 +252,14 @@ const initApplicationWithTagsMockEntity = (): Application => {
return applicationEntity;
};

const initNoticeOfIntentWithTagsMockEntity = (): NoticeOfIntent => {
const noticeOfIntentEntity = initNoticeOfIntentMockEntity();
const tagEntity = initTagMockEntity();
noticeOfIntentEntity.tags = [];
noticeOfIntentEntity.tags.push(tagEntity);
return noticeOfIntentEntity;
};

const initMockUserDto = (assignee?: User): UserDto => {
const userEntity = assignee ?? initUserMockEntity();
const userDto = new UserDto();
Expand Down Expand Up @@ -369,4 +414,6 @@ export {
initTagCategoryMockEntity,
initTagMockEntity,
initApplicationWithTagsMockEntity,
initNoticeOfIntentMockEntity,
initNoticeOfIntentWithTagsMockEntity,
};