Skip to content

Commit

Permalink
Merge pull request #96 from bcgov/chore/unit-tests
Browse files Browse the repository at this point in the history
Frontend unit tests
  • Loading branch information
kyle1morel authored Jun 25, 2024
2 parents 1d33924 + a8a1b38 commit 8180d00
Show file tree
Hide file tree
Showing 8 changed files with 710 additions and 0 deletions.
138 changes: 138 additions & 0 deletions app/tests/unit/controllers/note.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,3 +257,141 @@ describe('listNotes', () => {
expect(next).toHaveBeenCalledTimes(1);
});
});

describe('deleteNote', () => {
const next = jest.fn();

// Mock service calls
const deleteNoteSpy = jest.spyOn(noteService, 'deleteNote');

it('should return 200 if deletion is successful', async () => {
const req = {
params: { noteId: '123-123' },
currentUser: CURRENT_USER
};

const deletedNote = {
noteId: '123-123',
activityId: '123',
bringForwardDate: null,
bringForwardState: null,
note: 'Some not text',
noteType: 'GENERAL',
title: 'Note title',
isDeleted: true
};

deleteNoteSpy.mockResolvedValue(deletedNote);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
await noteController.deleteNote(req as any, res as any, next);

expect(deleteNoteSpy).toHaveBeenCalledTimes(1);
expect(deleteNoteSpy).toHaveBeenCalledWith(req.params.noteId);
expect(res.status).toHaveBeenCalledWith(200);
expect(res.json).toHaveBeenCalledWith(deletedNote);
});

it('calls next if the note service fails to delete the note', async () => {
const req = {
params: { noteId: '123-123' },
currentUser: CURRENT_USER
};

deleteNoteSpy.mockImplementationOnce(() => {
throw new Error();
});

// eslint-disable-next-line @typescript-eslint/no-explicit-any
await noteController.deleteNote(req as any, res as any, next);

expect(deleteNoteSpy).toHaveBeenCalledTimes(1);
expect(deleteNoteSpy).toHaveBeenCalledWith(req.params.noteId);
expect(res.status).toHaveBeenCalledTimes(0);
expect(next).toHaveBeenCalledTimes(1);
});
});
describe('updateNote', () => {
const next = jest.fn();

// Mock service calls
const updateNoteSpy = jest.spyOn(noteService, 'updateNote');
const getCurrentUserIdSpy = jest.spyOn(userService, 'getCurrentUserId');
const getCurrentIdentitySpy = jest.spyOn(utils, 'getCurrentIdentity');

it('should return 200 if update is successful', async () => {
const req = {
body: {
noteId: '123-123',
activityId: '123',
bringForwardDate: null,
bringForwardState: null,
note: 'Updated note text',
noteType: 'GENERAL',
title: 'Updated Note title'
},
currentUser: CURRENT_USER
};

const USR_IDENTITY = 'xxxy';
const USR_ID = 'abc-123';

const updated = {
noteId: '123-123',
activityId: '123',
bringForwardDate: null,
bringForwardState: null,
note: 'Updated note text',
noteType: 'GENERAL',
title: 'Updated Note title',
isDeleted: false
};

updateNoteSpy.mockResolvedValue(updated);
getCurrentIdentitySpy.mockReturnValue(USR_IDENTITY);
getCurrentUserIdSpy.mockResolvedValue(USR_ID);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
await noteController.updateNote(req as any, res as any, next);

expect(getCurrentIdentitySpy).toHaveBeenCalledTimes(1);
expect(getCurrentIdentitySpy).toHaveBeenCalledWith(CURRENT_USER, NIL);
expect(getCurrentUserIdSpy).toHaveBeenCalledTimes(1);
expect(getCurrentUserIdSpy).toHaveBeenCalledWith(USR_IDENTITY, NIL);
expect(updateNoteSpy).toHaveBeenCalledTimes(1);
expect(updateNoteSpy).toHaveBeenCalledWith({ ...req.body, createdBy: USR_ID, updatedAt: expect.any(String) });
expect(res.status).toHaveBeenCalledWith(200);
expect(res.json).toHaveBeenCalledWith(updated);
});

it('calls next if the note service fails to update the note', async () => {
const req = {
body: {
noteId: '123-123',
activityId: '123',
bringForwardDate: null,
bringForwardState: null,
note: 'Updated note text',
noteType: 'GENERAL',
title: 'Updated Note title'
},
currentUser: CURRENT_USER
};

const USR_ID = 'abc-123';

getCurrentUserIdSpy.mockResolvedValue(USR_ID);

updateNoteSpy.mockImplementationOnce(() => {
throw new Error();
});

// eslint-disable-next-line @typescript-eslint/no-explicit-any
await noteController.updateNote(req as any, res as any, next);

expect(updateNoteSpy).toHaveBeenCalledTimes(1);
expect(updateNoteSpy).toHaveBeenCalledWith({ ...req.body, createdBy: USR_ID, updatedAt: expect.any(String) });
expect(res.status).toHaveBeenCalledTimes(0);
expect(next).toHaveBeenCalledTimes(1);
});
});
85 changes: 85 additions & 0 deletions frontend/tests/unit/components/file/DocumentCard.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { createTestingPinia } from '@pinia/testing';
import { mount } from '@vue/test-utils';

import DocumentCard from '@/components/file/DocumentCard.vue';
import { userService } from '@/services';
import { StorageKey } from '@/utils/enums/application';
import PrimeVue from 'primevue/config';
import ConfirmationService from 'primevue/confirmationservice';
import ToastService from 'primevue/toastservice';

import type { AxiosResponse } from 'axios';
import type { Document } from '@/types';

const useUserService = vi.spyOn(userService, 'searchUsers');

vi.mock('vue-router', () => ({
useRouter: () => ({
push: vi.fn(),
replace: vi.fn()
})
}));

const currentDate = new Date().toISOString();

const testDocument: Document = {
createdBy: 'testCreatedBy',
createdAt: currentDate,
updatedBy: 'testUpdatedAt',
updatedAt: currentDate,
documentId: 'documentUUID', // Primary Key
activityId: 'activityUUID',
filename: 'test file name',
mimeType: 'test mime type',
filesize: 123,
createdByFullName: 'test user'
};

const wrapperSettings = (testDocumentProp = testDocument) => ({
props: {
document: testDocumentProp
},
global: {
plugins: [
() =>
createTestingPinia({
initialState: {
auth: {
user: {}
}
}
}),
PrimeVue,
ConfirmationService,
ToastService
],
stubs: ['font-awesome-icon']
}
});

beforeEach(() => {
sessionStorage.setItem(
StorageKey.CONFIG,
JSON.stringify({
oidc: {
authority: 'abc',
clientId: '123'
}
})
);

vi.clearAllMocks();

useUserService.mockResolvedValue({ data: [{ fullName: 'dummyName' }] } as AxiosResponse);
});

afterEach(() => {
sessionStorage.clear();
});

describe('DocumentCard', () => {
it('renders component', async () => {
const wrapper = mount(DocumentCard, wrapperSettings());
expect(wrapper).toBeTruthy();
});
});
87 changes: 87 additions & 0 deletions frontend/tests/unit/components/file/FileSelectModal.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { createTestingPinia } from '@pinia/testing';
import { mount } from '@vue/test-utils';

import FileSelectModal from '@/components/file/FileSelectModal.vue';
import { userService } from '@/services';
import { StorageKey } from '@/utils/enums/application';
import PrimeVue from 'primevue/config';
import ConfirmationService from 'primevue/confirmationservice';
import ToastService from 'primevue/toastservice';

import type { AxiosResponse } from 'axios';
import type { Document } from '@/types';

const useUserService = vi.spyOn(userService, 'searchUsers');

vi.mock('vue-router', () => ({
useRouter: () => ({
push: vi.fn(),
replace: vi.fn()
})
}));

const currentDate = new Date().toISOString();

const testDocument: Array<Document> = [
{
createdBy: 'testCreatedBy',
createdAt: currentDate,
updatedBy: 'testUpdatedAt',
updatedAt: currentDate,
documentId: 'documentUUID', // Primary Key
activityId: 'activityUUID',
filename: 'test file name',
mimeType: 'test mime type',
filesize: 123,
createdByFullName: 'test user'
}
];

const wrapperSettings = (testDocumentProp = testDocument) => ({
props: {
documents: testDocumentProp
},
global: {
plugins: [
() =>
createTestingPinia({
initialState: {
auth: {
user: {}
}
}
}),
PrimeVue,
ConfirmationService,
ToastService
],
stubs: ['font-awesome-icon']
}
});

beforeEach(() => {
sessionStorage.setItem(
StorageKey.CONFIG,
JSON.stringify({
oidc: {
authority: 'abc',
clientId: '123'
}
})
);

vi.clearAllMocks();

useUserService.mockResolvedValue({ data: [{ fullName: 'dummyName' }] } as AxiosResponse);
});

afterEach(() => {
sessionStorage.clear();
});

describe('DocumentCard', () => {
it('renders component', async () => {
const wrapper = mount(FileSelectModal, wrapperSettings());
expect(wrapper).toBeTruthy();
});
});
71 changes: 71 additions & 0 deletions frontend/tests/unit/components/file/FileUpload.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { createTestingPinia } from '@pinia/testing';
import { mount } from '@vue/test-utils';

import FileUpload from '@/components/file/FileUpload.vue';
import { userService } from '@/services';
import { StorageKey } from '@/utils/enums/application';
import PrimeVue from 'primevue/config';
import ConfirmationService from 'primevue/confirmationservice';
import ToastService from 'primevue/toastservice';

import type { AxiosResponse } from 'axios';

const useUserService = vi.spyOn(userService, 'searchUsers');

vi.mock('vue-router', () => ({
useRouter: () => ({
push: vi.fn(),
replace: vi.fn()
})
}));

const activityId = 'activityUUID';

const wrapperSettings = () => ({
props: {
activityId: activityId
},
global: {
plugins: [
() =>
createTestingPinia({
initialState: {
auth: {
user: {}
}
}
}),
PrimeVue,
ConfirmationService,
ToastService
],
stubs: ['font-awesome-icon']
}
});

beforeEach(() => {
sessionStorage.setItem(
StorageKey.CONFIG,
JSON.stringify({
oidc: {
authority: 'abc',
clientId: '123'
}
})
);

vi.clearAllMocks();

useUserService.mockResolvedValue({ data: [{ fullName: 'dummyName' }] } as AxiosResponse);
});

afterEach(() => {
sessionStorage.clear();
});

describe('FileUpload', () => {
it('renders component', async () => {
const wrapper = mount(FileUpload, wrapperSettings());
expect(wrapper).toBeTruthy();
});
});
Loading

0 comments on commit 8180d00

Please sign in to comment.