Skip to content

Commit

Permalink
Merge pull request #80 from jujaga/test/fe-coverage
Browse files Browse the repository at this point in the history
Frontend Unit Test Additions
  • Loading branch information
loneil authored Oct 28, 2020
2 parents 1e80163 + 75e216b commit 0e86066
Show file tree
Hide file tree
Showing 23 changed files with 563 additions and 60 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ Create, edit and publish forms.
│ ├── docs/ - OpenAPI 3.0 Specification
│ └── forms/ - Models, Controllers, Routes for the forms
└── tests/ - Node.js backend web application tests
components/ - Form.io Custom Components Library
load-test/ - Standalone CHEFS load testing utility
openshift/ - OpenShift-deployment and shared pipeline files
CODE-OF-CONDUCT.md - Code of Conduct
COMPLIANCE.yaml - BCGov PIA/STRA compliance status
Expand Down
7 changes: 3 additions & 4 deletions app/frontend/src/views/user/Root.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

<script>
import { mapGetters } from 'vuex';
import rbacService from '@/services/rbacService';
import { rbacService } from '@/services';
export default {
name: 'User',
Expand All @@ -53,11 +53,10 @@ export default {
},
computed: {
...mapGetters('auth', [
'hasResourceRoles',
'userName',
'fullName',
'token',
'tokenParsed',
'fullName',
'userName'
]),
},
created() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuetify from 'vuetify';

import BaseCopyToClipboard from '@/components/base/BaseCopyToClipboard.vue';

const localVue = createLocalVue();
localVue.use(Vuetify);

describe('BaseCopyToClipboard.vue', () => {
it('renders', () => {
const wrapper = shallowMount(BaseCopyToClipboard, {
localVue,
propsData: { copyText: 'test' }
});

expect(wrapper.text()).toMatch('Copy to clipboard');
});

it('clipboardSuccessHandler behaves correctly', () => {
const wrapper = shallowMount(BaseCopyToClipboard, {
localVue,
propsData: { copyText: 'test' }
});
wrapper.vm.clipboardSuccessHandler();

expect(wrapper.vm.clipSnackbar.on).toBeTruthy();
expect(wrapper.vm.clipSnackbar.text).toMatch('Link copied to clipboard');
expect(wrapper.vm.clipSnackbar.color).toEqual('info');
expect(wrapper.emitted().copied).toBeTruthy();
});

it('clipboardErrorHandler behaves correctly', () => {
const wrapper = shallowMount(BaseCopyToClipboard, {
localVue,
propsData: { copyText: 'test' }
});
wrapper.vm.clipboardErrorHandler();

expect(wrapper.vm.clipSnackbar.on).toBeTruthy();
expect(wrapper.vm.clipSnackbar.text).toMatch('Error attempting to copy to clipboard');
expect(wrapper.vm.clipSnackbar.color).toEqual('error');
});
});
19 changes: 19 additions & 0 deletions app/frontend/tests/unit/components/base/BaseImagePopout.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuetify from 'vuetify';

import BaseImagePopout from '@/components/base/BaseImagePopout.vue';

const localVue = createLocalVue();
localVue.use(Vuetify);

describe('BaseImagePopout.vue', () => {
it('renders', () => {
const wrapper = shallowMount(BaseImagePopout, {
localVue,
propsData: { src: 'test' }
});

expect(wrapper.html()).toMatch('v-hover');
expect(wrapper.html()).toMatch('v-dialog');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';

import BaseNotificationBar from '@/components/base/BaseNotificationBar.vue';

const localVue = createLocalVue();
localVue.use(Vuex);

describe('BaseNotificationBar.vue', () => {
let mockDeleteNotification = jest.fn();
let store;

beforeEach(() => {
store = new Vuex.Store({
modules: {
notifications: {
namespaced: true,
actions: {
deleteNotification: mockDeleteNotification
}
}
}
});
});

afterEach(() => {
mockDeleteNotification.mockClear();
});

it('renders', () => {
const msg = 'test';
const wrapper = shallowMount(BaseNotificationBar, {
localVue,
propsData: { notification: { message: msg, type: 'error' } },
store
});

expect(wrapper.html()).toMatch('v-alert');
expect(wrapper.text()).toMatch(msg);
});

it('alertClosed behaves correctly', () => {
const wrapper = shallowMount(BaseNotificationBar, {
localVue,
propsData: { notification: { message: 'test', type: 'error' } },
store
});
wrapper.vm.alertClosed();

expect(mockDeleteNotification).toHaveBeenCalledTimes(1);
});

it('clears timeout before destroy', () => {
const wrapper = shallowMount(BaseNotificationBar, {
localVue,
propsData: { notification: { message: 'test', type: 'error' } },
store
});
wrapper.destroy();

expect(wrapper.vm.timeout).not.toBeNull();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';

import BaseNotificationContainer from '@/components/base/BaseNotificationContainer.vue';

const localVue = createLocalVue();
localVue.use(Vuex);

describe('BaseNotificationContainer.vue', () => {
let store;

beforeEach(() => {
store = new Vuex.Store({
modules: {
notifications: {
namespaced: true,
state: {
notifications: []
}
}
}
});
});

it('renders', () => {
const wrapper = shallowMount(BaseNotificationContainer, {
localVue,
store,
stubs: ['BaseNotificationBar']
});

expect(wrapper.html()).toMatch('notification-container');
});
});
62 changes: 62 additions & 0 deletions app/frontend/tests/unit/views/Form.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';

import { formService } from '@/services';
import Form from '@/views/Form.vue';

const localVue = createLocalVue();

describe('Form.vue', () => {
const mockConsoleError = jest.spyOn(console, 'error');
const readFormSpy = jest.spyOn(formService, 'readForm');

beforeEach(() => {
mockConsoleError.mockReset();
readFormSpy.mockReset();
});

afterAll(() => {
mockConsoleError.mockRestore();
readFormSpy.mockRestore();
});

it('renders without formId', () => {
const wrapper = shallowMount(Form, {
localVue,
stubs: ['router-view'],
});

expect(wrapper.html()).toMatch('router-view');
expect(readFormSpy).toHaveBeenCalledTimes(0);
});

it('renders with formId correctly', async () => {
const name = 'test';
readFormSpy.mockImplementation(() => ({ data: { name: name } }));
const wrapper = shallowMount(Form, {
localVue,
propsData: { formId: '123' },
stubs: ['router-view'],
});
await localVue.nextTick();

expect(wrapper.html()).toMatch('router-view');
expect(readFormSpy).toHaveBeenCalledTimes(1);
expect(wrapper.vm.formName).toMatch(name);
});

it('renders with formId and logs error', async () => {
readFormSpy.mockImplementation(() => {
throw new Error('error');
});
const wrapper = shallowMount(Form, {
localVue,
propsData: { formId: '123' },
stubs: ['router-view'],
});
await localVue.nextTick();

expect(wrapper.html()).toMatch('router-view');
expect(readFormSpy).toHaveBeenCalledTimes(1);
expect(wrapper.vm.formName).toMatch('');
});
});
19 changes: 6 additions & 13 deletions app/frontend/tests/unit/views/NotFound.spec.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
import { shallowMount } from '@vue/test-utils';
import Vuetify from 'vuetify';
import { createLocalVue, shallowMount } from '@vue/test-utils';
import VueRouter from 'vue-router';

import NotFound from '@/views/NotFound.vue';

describe('NotFound.vue', () => {
let router;
let vuetify;

beforeEach(() => {
router = new VueRouter();
vuetify = new Vuetify();
});
const localVue = createLocalVue();
localVue.use(VueRouter);

describe('NotFound.vue', () => {
it('renders', () => {
const wrapper = shallowMount(NotFound, {
vuetify,
router,
stubs: ['router-link', 'router-view']
localVue,
stubs: ['router-link']
});

expect(wrapper.text()).toMatch('404: Page not found. :(');
Expand Down
15 changes: 15 additions & 0 deletions app/frontend/tests/unit/views/User.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import User from '@/views/User.vue';

const localVue = createLocalVue();

describe('User.vue', () => {
it('renders', () => {
const wrapper = shallowMount(User, {
localVue,
stubs: ['router-view']
});

expect(wrapper.html()).toMatch('router-view');
});
});
73 changes: 73 additions & 0 deletions app/frontend/tests/unit/views/form/Design.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';

import Design from '@/views/form/Design.vue';

const localVue = createLocalVue();
localVue.use(Vuex);

describe('Design.vue', () => {
const mockWindowConfirm = jest.spyOn(window, 'confirm');
const mockFormGetter = jest.fn();
let store;

beforeEach(() => {
store = new Vuex.Store({
modules: {
form: {
namespaced: true,
getters: {
form: mockFormGetter
}
}
}
});
});

afterEach(() => {
mockWindowConfirm.mockReset();
mockFormGetter.mockReset();
});

afterAll(() => {
mockWindowConfirm.mockRestore();
});

it('renders', () => {
const wrapper = shallowMount(Design, {
localVue,
store,
stubs: ['BaseSecure', 'FormDesigner']
});

expect(wrapper.html()).toMatch('basesecure');
});

it('beforeRouteLeave guard works when not dirty', () => {
mockFormGetter.mockReturnValue({ isDirty: false });
const next = jest.fn();
const wrapper = shallowMount(Design, {
localVue,
store,
stubs: ['BaseSecure', 'FormDesigner']
});
Design.beforeRouteLeave.call(wrapper.vm, undefined, undefined, next);

expect(next).toHaveBeenCalledTimes(1);
expect(mockWindowConfirm).toHaveBeenCalledTimes(0);
});

it('beforeRouteLeave guard works when not dirty', () => {
mockFormGetter.mockReturnValue({ isDirty: true });
const next = jest.fn();
const wrapper = shallowMount(Design, {
localVue,
store,
stubs: ['BaseSecure', 'FormDesigner']
});
Design.beforeRouteLeave.call(wrapper.vm, undefined, undefined, next);

expect(next).toHaveBeenCalledTimes(1);
expect(mockWindowConfirm).toHaveBeenCalledTimes(1);
});
});
16 changes: 16 additions & 0 deletions app/frontend/tests/unit/views/form/Preview.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';

import Preview from '@/views/form/Preview.vue';

const localVue = createLocalVue();

describe('Preview.vue', () => {
it('renders', () => {
const wrapper = shallowMount(Preview, {
localVue,
stubs: ['BaseSecure', 'FormViewer']
});

expect(wrapper.html()).toMatch('basesecure');
});
});
Loading

0 comments on commit 0e86066

Please sign in to comment.