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

Update MHR unit tests - Part 1 #1630

Merged
merged 5 commits into from
Nov 28, 2023
Merged
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
4 changes: 2 additions & 2 deletions ppr-ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions ppr-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "ppr-ui",
"version": "3.0.3",
"version": "3.0.4",
"private": true,
"appName": "Assets UI",
"sbcName": "SBC Common Components",
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview",
"serve": "vite dev",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this different from npm run dev?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vite preview starts localhost with files from /dist , while vite dev has a hot module reload.

"lint": "eslint . --ext .js,.ts,.vue",
"test:unit": "vitest run",
"test:coverage": "vitest run --coverage"
1 change: 1 addition & 0 deletions ppr-ui/src/components/common/Attention.vue
Original file line number Diff line number Diff line change
@@ -65,6 +65,7 @@ export default defineComponent({
},
sectionNumber: {
type: Number,
default: null,
required: false
},
validate: {
1 change: 1 addition & 0 deletions ppr-ui/src/components/common/ButtonFooter.vue
Original file line number Diff line number Diff line change
@@ -208,6 +208,7 @@ export default defineComponent({
return props.navConfig[i]
}
}
return null
})
})
const cancel = () => {
8 changes: 5 additions & 3 deletions ppr-ui/src/components/common/Remarks.vue
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@
<v-col cols="3">
<label
for="remarks-textarea"
class="generic-label"
class="generic-label side-label"
:class="{ 'error-text': showBorderError }"
>
{{ content.sideLabel }}
@@ -75,11 +75,13 @@ export default defineComponent({
},
additionalRemarks: {
type: String,
required: false
required: false,
default: ''
},
sectionNumber: {
type: Number,
required: false
required: false,
default: null
},
content: {
type: Object as () => ContentIF,
Original file line number Diff line number Diff line change
@@ -22,13 +22,13 @@
>
<template v-if="!isMhrManufacturerRegistration">
<v-radio-group
id="certification-option-btns"
v-model="certificationOption"
class="mt-0"
class="mt-0 certification-option-btns"
inline
hideDetails="true"
:disabled="hasNoCertification"
:class="{ 'disabled-radio': hasNoCertification }"
data-test-id="certification-option-btns"
>
<v-radio
id="csa-option"
@@ -152,7 +152,6 @@
class="mt-8 pt-0 mb-n4 float-left"
/>
<v-tooltip
id="no-certification-tooltip"
location="top"
contentClass="top-tooltip"
transition="fade-transition"
@@ -162,6 +161,7 @@
class="ml-2 mt-12"
color="primary"
v-bind="props"
data-test-id="no-certification-tooltip"
>
mdi-information-outline
</v-icon>
@@ -344,7 +344,7 @@ export default defineComponent({
:deep(.theme--light.v-icon.mdi-close) {
color: $primary-blue !important;
}
#certification-option-btns {
.certification-option-btns {
:deep(.v-selection-control--dirty) {
border: 1px solid $app-blue;
background-color: white;
2 changes: 1 addition & 1 deletion ppr-ui/src/components/unitNotes/UnitNoteReview.vue
Original file line number Diff line number Diff line change
@@ -301,7 +301,7 @@ export default defineComponent({
onMounted(() => {
// scroll to top
setTimeout(() => {
document.getElementById('unit-note-review-confirm').scrollIntoView({ behavior: 'smooth' })
document.getElementById('unit-note-review-confirm')?.scrollIntoView({ behavior: 'smooth' })
}, 500)
})

1 change: 1 addition & 0 deletions ppr-ui/src/components/userAccess/ServiceAgreement.vue
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
color="primary"
class="mt-2"
:ripple="false"
data-test-id="download-agreement-btn"
@click="downloadServiceAgreement"
>
<img
3 changes: 2 additions & 1 deletion ppr-ui/tests/setup.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// // setup.ts
import { afterEach, beforeAll, vi } from 'vitest'
import { config } from '@vue/test-utils'
import { dataTestId } from './unit/plugins'
import { createPinia, setActivePinia } from 'pinia'
import vuetify from '@/plugins/vuetify'
import * as matchers from 'vitest-axe/matchers'
@@ -15,7 +16,7 @@ const pinia = createPinia()
setActivePinia(createPinia())

// Add properties to the wrapper
config.global.plugins.push([vuetify, pinia])
config.global.plugins.push([vuetify, pinia, dataTestId])
// Suppress Vue warnings
config.global.config.warnHandler = () => null
global.css = { supports: () => false }
68 changes: 29 additions & 39 deletions ppr-ui/tests/unit/HomeCertification.spec.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,53 @@
// Libraries
import Vue, { nextTick } from 'vue'
import Vuetify from 'vuetify'
import { nextTick } from 'vue'
import { useStore } from '../../src/store/store'
import { Wrapper } from '@vue/test-utils'

// Components
import { HomeCertification } from '@/components/mhrRegistration'
import { SharedDatePicker } from '@/components/common'
import flushPromises from 'flush-promises'
import { MhrRegistrationType } from '@/resources'
import { mockedManufacturerAuthRoles } from './test-data'
import { HomeCertificationOptions, AuthRoles, ProductCode } from '@/enums'
import { createComponent } from './utils'

Vue.use(Vuetify)
import { createComponent, getTestId } from './utils'
import { InputFieldDatePicker } from '@/components/common'

const store = useStore()

describe('Home Certification - staff', () => {
let wrapper: Wrapper<any>
let wrapper

beforeAll(async () => {
await store.setAuthRoles([AuthRoles.PPR_STAFF, AuthRoles.STAFF, AuthRoles.MHR, AuthRoles.PPR])
})

beforeEach(async () => {
wrapper = await createComponent(HomeCertification, {})
wrapper = await createComponent(HomeCertification, { appReady: true })
await store.setMhrHomeDescription({ key: 'certificationOption', value: null })
await store.setMhrHomeDescription({ key: 'hasNoCertification', value: null })
wrapper.vm.certificationOption = null
wrapper.vm.hasNoCertification = false
await nextTick()
await flushPromises()
})
afterEach(() => {
wrapper.destroy()
})

afterAll(async () => {
await store.setAuthRoles([])
})

it('renders base component with default sub components', async () => {
expect(wrapper.findComponent(HomeCertification).exists()).toBe(true)
expect(wrapper.findComponent(SharedDatePicker).exists()).toBe(false)
expect(wrapper.findComponent(InputFieldDatePicker).exists()).toBe(false)
})

it('renders with default values', async () => {
/// Verify Radio grp
expect(wrapper.find('#certification-option-btns').exists()).toBe(true)
expect(wrapper.find(getTestId('certification-option-btns')).exists()).toBe(true)

// Verify Forms hidden before radio btn selection
expect(wrapper.find('#csa-form').isVisible()).toBe(false)
expect(wrapper.find('#engineer-form').isVisible()).toBe(false)
expect(wrapper.find('#no-certification-checkbox').isVisible()).toBe(true)
expect(wrapper.find('#no-certification-tooltip').exists()).toBe(true)
expect(wrapper.find(getTestId('no-certification-tooltip')).exists()).toBe(true)
})

it('opens the CSA Form when selected', async () => {
@@ -63,7 +56,7 @@ describe('Home Certification - staff', () => {
expect(wrapper.find('#engineer-form').isVisible()).toBe(false)

// Click the btn
await wrapper.find('#csa-option').trigger('click')
await wrapper.find('#csa-option').setValue(true)

// Verify CSA Form
expect(wrapper.find('#csa-form').isVisible()).toBe(true)
@@ -82,7 +75,7 @@ describe('Home Certification - staff', () => {
expect(wrapper.find('#engineer-form').isVisible()).toBe(false)

// Click the btn
await wrapper.find('#engineer-option').trigger('click')
await wrapper.find('#engineer-option').setValue(true)

// Verify Engineer Form
expect(wrapper.find('#engineer-form').isVisible()).toBe(true)
@@ -101,7 +94,7 @@ describe('Home Certification - staff', () => {
expect(wrapper.find('#engineer-form').isVisible()).toBe(false)

// Click the btn
await wrapper.find('#engineer-option').trigger('click')
await wrapper.find('#engineer-option').setValue(true)

// Verify Engineer Form
expect(wrapper.find('#engineer-form').isVisible()).toBe(true)
@@ -116,7 +109,7 @@ describe('Home Certification - staff', () => {
// Verify Form Toggle

// Click the btn
await wrapper.find('#csa-option').trigger('click')
await wrapper.find('#csa-option').setValue(true)

// Verify CSA Form
expect(wrapper.find('#csa-form').isVisible()).toBe(true)
@@ -131,39 +124,39 @@ describe('Home Certification - staff', () => {

it('renders the DatePicker for the engineer option', async () => {
// Click the btn
await wrapper.find('#engineer-option').trigger('click')
expect(wrapper.findComponent(SharedDatePicker).exists()).toBe(true)
await wrapper.find('#engineer-option').setValue(true)
expect(wrapper.findComponent(InputFieldDatePicker).exists()).toBe(true)
})

it('collapses form if no certification checkbox is selected', async () => {
await wrapper.find('#csa-option').trigger('click')
await wrapper.find('#csa-option').setValue(true)
expect(wrapper.find('#csa-form').isVisible()).toBe(true)

await wrapper.find('#no-certification-checkbox').trigger('click')
await wrapper.find('#no-certification-checkbox').setValue(true)
expect(wrapper.find('#csa-form').isVisible()).toBe(false)
})

it('disables buttons if no certification checkbox is selected', async () => {
await wrapper.find('#no-certification-checkbox').trigger('click')
await wrapper.find('#no-certification-checkbox').setValue(false)

expect(wrapper.find('#csa-option').attributes('disabled')).toBe('disabled')
expect(wrapper.find('#engineer-option').attributes('disabled')).toBe('disabled')
expect(wrapper.find('#csa-option').getCurrentComponent().props.disabled).toBe(false)
expect(wrapper.find('#engineer-option').getCurrentComponent().props.disabled).toBe(false)

// Enables button after unselected
await wrapper.find('#no-certification-checkbox').trigger('click')
expect(wrapper.find('#csa-option').attributes('disabled')).toBe(undefined)
expect(wrapper.find('#engineer-option').attributes('disabled')).toBe(undefined)
await wrapper.find('#no-certification-checkbox').setValue(true)
expect(wrapper.find('#csa-option').getCurrentComponent().props.disabled).toBe(true)
expect(wrapper.find('#engineer-option').getCurrentComponent().props.disabled).toBe(true)
})

it('sets the home certification section to valid if no certification checkbox is selected', async () => {
expect(store.getMhrRegistrationValidationModel.yourHomeValid.homeCertificationValid).toBe(false)
await wrapper.find('#no-certification-checkbox').trigger('click')
await wrapper.find('#no-certification-checkbox').setValue(true)
expect(store.getMhrRegistrationValidationModel.yourHomeValid.homeCertificationValid).toBe(true)
})
})

describe('Home Certification - manufacturer', () => {
let wrapper: Wrapper<any>
let wrapper

beforeAll(async () => {
await store.setAuthRoles(mockedManufacturerAuthRoles)
@@ -174,30 +167,27 @@ describe('Home Certification - manufacturer', () => {
})

beforeEach(async () => {
wrapper = await createComponent(HomeCertification, {})
wrapper = await createComponent(HomeCertification, { appReady: true })
await nextTick()
await flushPromises()
})
afterEach(() => {
wrapper.destroy()
})

afterAll(async () => {
await store.setAuthRoles(null)
await store.setAuthRoles([])
await store.setRegistrationType(null)
})

it('renders base component with correct sub components', async () => {
expect(wrapper.findComponent(HomeCertification).exists()).toBe(true)
expect(wrapper.findComponent(SharedDatePicker).exists()).toBe(false)
expect(wrapper.findComponent(InputFieldDatePicker).exists()).toBe(false)

/// Verify Radio group does not exist
expect(wrapper.find('#certification-option-btns').exists()).toBe(false)
expect(wrapper.find(getTestId('certification-option-btns')).exists()).toBe(false)

// Verify only csa-form is shown
expect(wrapper.find('#csa-form').isVisible()).toBe(true)
expect(wrapper.find('#engineer-form').exists()).toBe(false)
expect(wrapper.find('#no-certification').exists()).toBe(false)
expect(wrapper.find('#no-certification-tooltip').exists()).toBe(false)
expect(wrapper.find(getTestId('no-certification-tooltip')).exists()).toBe(false)
})
})
40 changes: 5 additions & 35 deletions ppr-ui/tests/unit/HomeLandOwnership.spec.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,18 @@
// Libraries
import Vue, { nextTick } from 'vue'
import Vuetify from 'vuetify'
import { mount, createLocalVue, Wrapper } from '@vue/test-utils'
import { nextTick } from 'vue'

// Components
import { HomeLandOwnership } from '@/components/mhrRegistration'
import flushPromises from 'flush-promises'
import { getTestId } from './utils'
import { createPinia, setActivePinia } from 'pinia'
import { createComponent, getTestId } from './utils'
import { useStore } from '../../src/store/store'

Vue.use(Vuetify)

const vuetify = new Vuetify({})
setActivePinia(createPinia())
const store = useStore()
/**
* Creates and mounts a component, so that it can be tested.
*
* @returns a Wrapper<SearchBar> object with the given parameters.
*/
function createComponent (): Wrapper<any> {
const localVue = createLocalVue()
localVue.use(Vuetify)

document.body.setAttribute('data-app', 'true')
return mount((HomeLandOwnership as any), {
localVue,
propsData: {},
store,
vuetify
})
}

describe('Home Land Ownership', () => {
let wrapper: Wrapper<any>
let wrapper

beforeEach(async () => {
wrapper = createComponent()
await nextTick()
await flushPromises()
})
afterEach(() => {
wrapper.destroy()
wrapper = await createComponent(HomeLandOwnership)
})

it('renders base component', async () => {
@@ -52,7 +22,7 @@ describe('Home Land Ownership', () => {
it('ownership checkbox performs as expected', async () => {
expect(store.getMhrRegistrationOwnLand).toBe(false)
expect(wrapper.find(getTestId('ownership-checkbox'))).toBeTruthy()
wrapper.find(getTestId('ownership-checkbox')).setChecked()
wrapper.find(getTestId('ownership-checkbox')).find('input[type="checkbox"]').setValue(true)
await nextTick()
expect(store.getMhrRegistrationOwnLand).toBe(true)
})
44 changes: 6 additions & 38 deletions ppr-ui/tests/unit/HomeSections.spec.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,25 @@
// Libraries
import Vue, { nextTick } from 'vue'
import Vuetify from 'vuetify'
import { createPinia, setActivePinia } from 'pinia'
import { useStore } from '../../src/store/store'

import { mount, createLocalVue, Wrapper } from '@vue/test-utils'

// Components
import { HomeSections } from '@/components/mhrRegistration'
import AddEditHomeSections from '@/components/mhrRegistration/YourHome/AddEditHomeSections.vue'
import HomeSectionsTable from '@/components/tables/mhr/HomeSectionsTable.vue'
import { AddEditHomeSections, HomeSections } from '@/components/mhrRegistration'
import { mockedHomeSections } from './test-data/mock-home-sections'
import { createComponent } from './utils'
import { HomeSectionsTable } from '@/components/tables/mhr'

Vue.use(Vuetify)

const vuetify = new Vuetify({})
setActivePinia(createPinia())
const store = useStore()

const addEditHomeSectionBtn = '.add-home-section-btn'
const sectionCounter = '#section-count'
const errorText = '.error-text'

/**
* Creates and mounts a component, so that it can be tested.
*
* @returns a Wrapper<SearchBar> object with the given parameters.
*/
function createComponent (): Wrapper<any> {
const localVue = createLocalVue()

localVue.use(Vuetify)
document.body.setAttribute('data-app', 'true')
return mount((HomeSections as any), {
localVue,
propsData: {},
store,
vuetify
})
}

describe('Home Sections', () => {
let wrapper: Wrapper<any>
let wrapper

beforeEach(async () => {
// Set home sections default
await store.setMhrHomeDescription({ key: 'sections', value: [] })

wrapper = createComponent()
})
afterEach(() => {
wrapper.destroy()
wrapper = await createComponent(HomeSections)
})

it('renders base component with sub components', async () => {
@@ -81,8 +50,7 @@ describe('Home Sections', () => {
// Verify hidden by default
expect(wrapper.findComponent(AddEditHomeSections).exists()).toBe(false)
await wrapper.find(addEditHomeSectionBtn).trigger('click')

expect(wrapper.find(addEditHomeSectionBtn).attributes('disabled')).toBe('disabled')
expect(wrapper.find(addEditHomeSectionBtn).getCurrentComponent().props.disabled).toBe(true)
})

it('counts the added Home Sections', async () => {
42 changes: 10 additions & 32 deletions ppr-ui/tests/unit/MHRSearch.spec.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
// Libraries
import Vue from 'vue'
import Vuetify from 'vuetify'
import VueRouter from 'vue-router'
import { createPinia, setActivePinia } from 'pinia'
import { useStore } from '../../src/store/store'
import { shallowMount, createLocalVue } from '@vue/test-utils'

// Components
import { SearchedResultMhr } from '@/components/tables'
import { MHRSearch } from '@/views'

// Other
import mockRouter from './MockRouter'
import { mockedMHRSearchResponse } from './test-data'
import { UIMHRSearchTypes } from '@/enums'
import { RouteNames, UIMHRSearchTypes } from '@/enums'
import { createComponent } from './utils'
import { nextTick } from 'vue'

Vue.use(Vuetify)

const vuetify = new Vuetify({})
setActivePinia(createPinia())
const store = useStore()

// Prevent the warning "[Vuetify] Unable to locate target [data-app]"
@@ -32,27 +24,12 @@ const folioHeader = '#results-folio-header'

describe('Search component', () => {
let wrapper: any
const { assign } = window.location

beforeEach(async () => {
// mock the window.location.assign function
delete window.location
window.location = { assign: jest.fn() } as any

// create a Local Vue and install router on it
const localVue = createLocalVue()
localVue.use(VueRouter)
const router = mockRouter.mock()
await router.push({ name: 'mhr-search' })
wrapper = shallowMount((MHRSearch as any), { localVue, store, router, vuetify })
})

afterEach(() => {
window.location.assign = assign
wrapper.destroy()
wrapper = await createComponent(MHRSearch, { appReady: true }, RouteNames.MHRSEARCH)
})

it('renders Search View with base components', () => {
it('renders Search View with base components', async () => {
expect(wrapper.findComponent(MHRSearch).exists()).toBe(true)
// doesn't render unless there are results
expect(wrapper.find(searchMeta).exists()).toBe(false)
@@ -61,16 +38,17 @@ describe('Search component', () => {
expect(wrapper.find(folioHeader).exists()).toBe(false)
expect(wrapper.findComponent(SearchedResultMhr).exists()).toBe(false)
})

it('renders the Results component and displays search data elements with filled result set.', async () => {
await store.setManufacturedHomeSearchResults(mockedMHRSearchResponse[UIMHRSearchTypes.MHRMHR_NUMBER])
await nextTick()
expect(wrapper.find(noResultsInfo).exists()).toBe(false)
expect(wrapper.findComponent(SearchedResultMhr).exists()).toBe(true)
})

it('renders the Results component and displays search data elements with empty result set.', async () => {
const response = mockedMHRSearchResponse[UIMHRSearchTypes.MHRMHR_NUMBER]
response.totalResultsSize = 0
response.results = []
await store.setManufacturedHomeSearchResults(response)
await store.setManufacturedHomeSearchResults({ ...mockedMHRSearchResponse[UIMHRSearchTypes.MHRMHR_NUMBER], totalResultsSize: 0, results: [] })
await nextTick()
expect(wrapper.find(noResultsInfo).exists()).toBe(true)
expect(wrapper.findComponent(SearchedResultMhr).exists()).toBe(true)
})
36 changes: 4 additions & 32 deletions ppr-ui/tests/unit/MhrCivicAddress.spec.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,16 @@
import Vue, { nextTick } from 'vue'
import Vuetify from 'vuetify'
import { createPinia, setActivePinia } from 'pinia'
import { useStore } from '../../src/store/store'
import { nextTick } from 'vue'

import { mount, createLocalVue, Wrapper } from '@vue/test-utils'
import { HomeCivicAddress } from '@/components/mhrRegistration/HomeLocation'

Vue.use(Vuetify)
setActivePinia(createPinia())
const store = useStore()
const vuetify = new Vuetify({})

/**
* Creates and mounts a component, so that it can be tested.
* @returns a Wrapper object with the given parameters.
*/
function createComponent (): Wrapper<any> {
const localVue = createLocalVue()

return mount((HomeCivicAddress as any), {
localVue,
store,
vuetify
})
}
import { createComponent } from './utils'

// Error message class selector
const ERROR_MSG = '.error--text .v-messages__message'

describe('mhr home civic address', () => {
let wrapper: Wrapper<any>
let wrapper

beforeEach(async () => {
wrapper = createComponent()
})
afterEach(() => {
wrapper.destroy()
wrapper = await createComponent(HomeCivicAddress)
})

it('renders the component', async () => {
@@ -52,9 +27,6 @@ describe('mhr home civic address', () => {
const civicAddressSection = wrapper.findComponent(HomeCivicAddress)
expect(civicAddressSection.exists()).toBe(true)

const street = civicAddressSection.find('.street-address')
expect(civicAddressSection.exists()).toBe(true)

expect(civicAddressSection.findAll(ERROR_MSG).length).toBe(0)
await nextTick()
expect(civicAddressSection.findAll(ERROR_MSG).length).toBe(0)
69 changes: 6 additions & 63 deletions ppr-ui/tests/unit/MhrRegistration.spec.ts
Original file line number Diff line number Diff line change
@@ -1,73 +1,26 @@
// Libraries
import Vue from 'vue'
import Vuetify from 'vuetify'
import { createPinia, setActivePinia } from 'pinia'
import { useStore } from '../../src/store/store'
import VueRouter from 'vue-router'
import { createLocalVue, mount, Wrapper } from '@vue/test-utils'

// local components
import { MhrRegistration } from '@/views'
import ButtonFooter from '@/components/common/ButtonFooter.vue'
import { ButtonFooter } from '@/components/common'
import { Stepper, StickyContainer } from '@/components/common'
import { MhrRegistrationType } from '@/resources'
import { defaultFlagSet } from '@/utils'
import mockRouter from './MockRouter'
import { RouteNames } from '@/enums'
import { mockedManufacturerAuthRoles } from './test-data'
import { createComponent } from './utils'

Vue.use(Vuetify)

const vuetify = new Vuetify({})
setActivePinia(createPinia())
const store = useStore()

/**
* Creates and mounts a component, so that it can be tested.
*
* @returns a Wrapper<any> object with the given parameters.
*/
function createComponent (): Wrapper<any> {
const localVue = createLocalVue()
localVue.use(Vuetify)
localVue.use(VueRouter)
const router = mockRouter.mock()
router.push({
name: RouteNames.YOUR_HOME
})

document.body.setAttribute('data-app', 'true')
return mount((MhrRegistration as any), {
localVue,
store,
propsData: {
appReady: true
},
vuetify,
stubs: { Affix: true },
router
})
}

describe('Mhr Registration', () => {
let wrapper: Wrapper<any>
const currentAccount = {
id: 'test_id'
}
sessionStorage.setItem('KEYCLOAK_TOKEN', 'token')
sessionStorage.setItem('CURRENT_ACCOUNT', JSON.stringify(currentAccount))
sessionStorage.setItem('AUTH_API_URL', 'https://bcregistry-bcregistry-mock.apigee.net/mockTarget/auth/api/v1/')
let wrapper: any

beforeEach(async () => {
// Staff with MHR enabled
defaultFlagSet['mhr-registration-enabled'] = true
await store.setRegistrationType(MhrRegistrationType)

wrapper = createComponent()
})

afterEach(() => {
wrapper.destroy()
wrapper = await createComponent(MhrRegistration, { appReady: true }, RouteNames.YOUR_HOME)
})

it('renders and displays the Mhr Registration View', async () => {
@@ -86,24 +39,14 @@ describe('Mhr Registration', () => {
})

describe('Mhr Manufacturer Registration', () => {
let wrapper: Wrapper<any>
const currentAccount = {
id: 'test_id'
}
sessionStorage.setItem('KEYCLOAK_TOKEN', 'token')
sessionStorage.setItem('CURRENT_ACCOUNT', JSON.stringify(currentAccount))
sessionStorage.setItem('AUTH_API_URL', 'https://bcregistry-bcregistry-mock.apigee.net/mockTarget/auth/api/v1/')
let wrapper: any

beforeEach(async () => {
defaultFlagSet['mhr-registration-enabled'] = true
await store.setAuthRoles(mockedManufacturerAuthRoles)
await store.setRegistrationType(MhrRegistrationType)

wrapper = createComponent()
})

afterEach(() => {
wrapper.destroy()
wrapper = await createComponent(MhrRegistration, { appReady: true }, RouteNames.YOUR_HOME)
})

it('renders and displays the Mhr Registration View', async () => {
72 changes: 13 additions & 59 deletions ppr-ui/tests/unit/MhrReviewConfirm.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
// Libraries
import Vue, { nextTick } from 'vue'
import Vuetify from 'vuetify'
import VueRouter from 'vue-router'
import { createPinia, setActivePinia } from 'pinia'
import { nextTick } from 'vue'
import { useStore } from '../../src/store/store'
import { createLocalVue, mount, Wrapper } from '@vue/test-utils'

// Local Components
import { MhrReviewConfirm } from '@/views'
@@ -13,50 +9,20 @@ import { HomeLocationReview, HomeOwnersReview,
import { AccountInfo, Attention, CautionBox, CertifyInformation,
ContactUsToggle, FolioOrReferenceNumber, FormField } from '@/components/common'
import { HomeTenancyTypes, ProductCode, RouteNames, HomeCertificationOptions } from '@/enums'
import mockRouter from './MockRouter'
import { mockedFractionalOwnership, mockedPerson } from './test-data/mock-mhr-registration'
import { MhrRegistrationHomeOwnerGroupIF, MhrRegistrationHomeOwnerIF } from '@/interfaces/mhr-registration-interfaces'
import { getTestId } from './utils'
import { createComponent, getTestId } from './utils'
import { HomeOwnersTable } from '@/components/mhrRegistration/HomeOwners'
import { MhrRegistrationType } from '@/resources'
import { mockedAccountInfo, mockedManufacturerAuthRoles } from './test-data'
import { defaultFlagSet } from '@/utils'
import { StaffPayment } from '@bcrs-shared-components/staff-payment'
import { StaffPayment } from '@/components/common'
import { HomeSections } from '@/components/mhrRegistration'

Vue.use(Vuetify)

const vuetify = new Vuetify({})
setActivePinia(createPinia())
const store = useStore()

/**
* Creates and mounts a component, so that it can be tested.
*
* @returns a Wrapper<any> object with the given parameters.
*/
function createComponent (): Wrapper<any> {
const localVue = createLocalVue()
localVue.use(Vuetify)
document.body.setAttribute('data-app', 'true')
localVue.use(VueRouter)
const router = mockRouter.mock()
router.push({ name: RouteNames.MHR_REVIEW_CONFIRM })

return mount(MhrReviewConfirm, {
localVue,
propsData: {
appReady: true,
isJestRunning: true
},
router,
store,
vuetify
})
}

describe('Mhr Review Confirm registration', () => {
let wrapper: Wrapper<any>
let wrapper
sessionStorage.setItem('KEYCLOAK_TOKEN', 'token')
const currentAccount = {
id: 'test_id'
@@ -65,12 +31,11 @@ describe('Mhr Review Confirm registration', () => {
sessionStorage.setItem('AUTH_API_URL', 'https://bcregistry-bcregistry-mock.apigee.net/mockTarget/auth/api/v1/')
const reviewConfirmState = store.getMhrRegistrationValidationModel.reviewConfirmValid

afterEach(() => {
wrapper.destroy()
beforeEach(async () => {
wrapper = await createComponent(MhrReviewConfirm, { appReady: true }, RouteNames.MHR_REVIEW_CONFIRM)
})

it('mounts with the correct components', () => {
wrapper = createComponent()
it('mounts with the correct components', async () => {
expect(wrapper.findComponent(MhrReviewConfirm).exists()).toBe(true)
expect(wrapper.findComponent(YourHomeReview).exists()).toBe(true)
expect(wrapper.findComponent(SubmittingPartyReview).exists()).toBe(true)
@@ -86,14 +51,11 @@ describe('Mhr Review Confirm registration', () => {
})

it('verifies Authorization default values', async () => {
wrapper = createComponent()
expect(wrapper.vm.authorizationValid).toBe(false)
expect(wrapper.vm.isValidatingApp).toBe(false)
})

it('prompts Authorization validation', async () => {
wrapper = createComponent()

// Verify defaults
expect(wrapper.vm.authorizationValid).toBe(false)
expect(wrapper.vm.isValidatingApp).toBe(false)
@@ -108,8 +70,6 @@ describe('Mhr Review Confirm registration', () => {
})

it('should show correct Home Ownership section (without a Group)', async () => {
wrapper = createComponent()

const owners = [mockedPerson] as MhrRegistrationHomeOwnerIF[]
const homeOwnerGroup = [{ groupId: 1, owners: owners }] as MhrRegistrationHomeOwnerGroupIF[]

@@ -140,7 +100,6 @@ describe('Mhr Review Confirm registration', () => {
})

it('should show correct Home Ownership section (with a Group)', async () => {
wrapper = createComponent()
wrapper.vm.setShowGroups(true)

const owners = [mockedPerson] as MhrRegistrationHomeOwnerIF[]
@@ -177,7 +136,6 @@ describe('Mhr Review Confirm registration', () => {
})

it('does not show portions of yourHomeReview and SubmittingPartyReview if no data was entered', async () => {
wrapper = createComponent()
const yourHomeReview = wrapper.findComponent(YourHomeReview)
expect(yourHomeReview.exists()).toBeTruthy()
expect(yourHomeReview.findComponent(HomeSections).exists()).toBe(false)
@@ -193,7 +151,7 @@ describe('Mhr Review Confirm registration', () => {
})

describe('Mhr Manufacturer Registration Review and Confirm', () => {
let wrapper: Wrapper<any>
let wrapper
const currentAccount = {
id: 'test_id'
}
@@ -209,11 +167,7 @@ describe('Mhr Manufacturer Registration Review and Confirm', () => {
})

beforeEach(async () => {
wrapper = createComponent()
})

afterEach(() => {
wrapper.destroy()
wrapper = await createComponent(MhrReviewConfirm, { appReady: true }, RouteNames.MHR_REVIEW_CONFIRM)
})

afterAll(async () => {
@@ -243,12 +197,12 @@ describe('Mhr Manufacturer Registration Review and Confirm', () => {
it('correctly set attention and folio', async () => {
store.setMhrAttentionReference('TEST 123')
store.setFolioOrReferenceNumber('TEST 245')
wrapper = createComponent()
wrapper = await createComponent(MhrReviewConfirm, { appReady: true }, RouteNames.MHR_REVIEW_CONFIRM)
await nextTick()
const attention = wrapper.findComponent(Attention)
const folio = wrapper.findComponent(FolioOrReferenceNumber)
expect((attention.findComponent(FormField) as Wrapper<any>).vm.inputModel).toBe('TEST 123')
expect((folio.findComponent(FormField) as Wrapper<any>).vm.inputModel).toBe('TEST 245')
expect(attention.findComponent(FormField).vm.inputModel).toBe('TEST 123')
expect(folio.findComponent(FormField).vm.inputModel).toBe('TEST 245')
})

it('incorrect behavior if no certification checkbox is checked', async () => {
@@ -292,7 +246,7 @@ describe('Mhr Manufacturer Registration Review and Confirm', () => {
it('incorrect behavior in home certification - Engineer Inspection', async () => {
const yourHomeReview = wrapper.findComponent(YourHomeReview)
expect(yourHomeReview.exists()).toBeTruthy()
await store.setMhrHomeDescription({key: 'certificationOption',
await store.setMhrHomeDescription({key: 'certificationOption',
value: HomeCertificationOptions.ENGINEER_INSPECTION})
await nextTick()
expect(yourHomeReview.find(getTestId('home-certification-header-1-eng')).text()).toBe('Engineer\'s Name')
65 changes: 18 additions & 47 deletions ppr-ui/tests/unit/MhrUnitNote.spec.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
import Vue, { nextTick } from 'vue'
import Vuetify from 'vuetify'
import { createPinia, setActivePinia } from 'pinia'
import { nextTick } from 'vue'
import { useStore } from '../../src/store/store'
import VueRouter from 'vue-router'
import { createLocalVue, mount, Wrapper } from '@vue/test-utils'
import mockRouter from './MockRouter'
import { Wrapper } from '@vue/test-utils'

import { MhrUnitNote } from '@/views'
import { RouteNames, UnitNoteDocTypes } from '@/enums'
import { getTestId, setupMockStaffUser } from './utils'
import { createComponent, getTestId, setupMockStaffUser } from './utils'
import { UnitNotesInfo } from '@/resources/unitNotes'
import { Attention, CertifyInformation, ContactInformation, DocumentId, Remarks } from '@/components/common'
import { Attention, CertifyInformation, ContactInformation, DocumentId, Remarks, StaffPayment } from '@/components/common'
import {
EffectiveDate,
ExpiryDate,
UnitNoteAdd,
UnitNoteReview,
UnitNoteReviewDetailsTable
} from '@/components/unitNotes'
import { StaffPayment } from '@bcrs-shared-components/staff-payment'
import { MhrUnitNoteValidationStateIF } from '@/interfaces'
import { isEqual } from 'lodash'
import {
@@ -31,33 +26,11 @@ import {
import { mockedCancelPublicNote, mockedUnitNotes5 } from './test-data'
import { useMhrUnitNote } from '@/composables'

Vue.use(Vuetify)

const vuetify = new Vuetify({})
setActivePinia(createPinia())
const store = useStore()

function createComponent (): Wrapper<any> {
const localVue = createLocalVue()
localVue.use(Vuetify)
localVue.use(VueRouter)
const router = mockRouter.mock()
router.push({
name: RouteNames.MHR_INFORMATION_NOTE
})

document.body.setAttribute('data-app', 'true')
return mount(MhrUnitNote as any, {
localVue,
router,
stubs: { Affix: true },
vuetify
})
}

async function createUnitNoteComponent (unitNoteType: UnitNoteDocTypes) {
await store.setMhrUnitNoteType(unitNoteType)
return createComponent()
return await createComponent(MhrUnitNote, { appReady: true }, RouteNames.MHR_INFORMATION_NOTE )
}

// Go to Unit Note Review & Confirm screen and return its component for further testing
@@ -74,21 +47,19 @@ async function getReviewConfirmComponent (wrapper: Wrapper<any>): Promise<Wrappe
return reviewConfirmComponent
}

describe('MHR Unit Note Filing', () => {
describe('MHR Unit Note Filing', async () => {
let wrapper: Wrapper<any>
setupMockStaffUser()
await setupMockStaffUser()

const UNIT_NOTE_DOC_TYPE = UnitNoteDocTypes.NOTICE_OF_CAUTION

afterEach(() => {
wrapper.destroy()
// wrapper.destroy()
})

it('renders MhrUnitNote component and related sub-components', async () => {
wrapper = await createUnitNoteComponent(UnitNoteDocTypes.NOTICE_OF_CAUTION)

await createUnitNoteComponent(UnitNoteDocTypes.NOTICE_OF_CAUTION)

expect(wrapper.vm.$route.name).toBe(RouteNames.MHR_INFORMATION_NOTE)
expect(wrapper.exists()).toBeTruthy()

@@ -195,13 +166,13 @@ describe('MHR Unit Note Filing', () => {
expect(wrapper.findAll('.border-error-left').length).toBe(3)

// select past date in EffectiveDate to trigger validation
UnitNoteReviewComponent.findComponent(EffectiveDate).findAll('input[type=radio]').at(1).trigger('click')
await UnitNoteReviewComponent.findComponent(EffectiveDate).findAll('input[type=radio]').at(1).setValue(true)

const expiryDateRadioButtons = UnitNoteReviewComponent.findComponent(ExpiryDate).findAll('input[type=radio]')
// should be two radio buttons for this Unit Note type
expect(expiryDateRadioButtons.length).toBe(2)
// select future date in ExpiryDate to trigger validation
expiryDateRadioButtons.at(1).trigger('click')
await expiryDateRadioButtons.at(1).setValue(true)

await nextTick()
expect(wrapper.findAll('.border-error-left').length).toBe(5)
@@ -221,7 +192,7 @@ describe('MHR Unit Note Filing', () => {
expect(wrapper.findAll('.border-error-left').length).toBe(4)

// select past date in EffectiveDate to trigger validation
UnitNoteReviewComponent.findComponent(EffectiveDate).findAll('input[type=radio]').at(1).trigger('click')
await UnitNoteReviewComponent.findComponent(EffectiveDate).findAll('input[type=radio]').at(1).setValue(true)

const expiryDateRadioButtons = UnitNoteReviewComponent.findComponent(ExpiryDate).findAll('input[type=radio]')
// should be no radio buttons for this Unit Note type
@@ -254,7 +225,7 @@ describe('MHR Unit Note Filing', () => {
expect(PersonGivingNoticeComponent.findAll('.error-text').length).toBeGreaterThan(0)

// check the checkbox
await UnitNoteAddComponent.find('#no-person-giving-notice-checkbox').trigger('click')
await UnitNoteAddComponent.find('#no-person-giving-notice-checkbox').setValue(true)
await nextTick()
expect(store.getMhrUnitNote.hasNoPersonGivingNotice).toBe(true)

@@ -267,7 +238,7 @@ describe('MHR Unit Note Filing', () => {
expect(PersonGivingNoticeComponent.findAll('.error-text').length).toBe(0)

// uncheck the checkbox
await UnitNoteAddComponent.find('#no-person-giving-notice-checkbox').trigger('click')
await UnitNoteAddComponent.find('#no-person-giving-notice-checkbox').setValue(false)
await nextTick()
expect(store.getMhrUnitNote.hasNoPersonGivingNotice).toBe(false)

@@ -278,7 +249,7 @@ describe('MHR Unit Note Filing', () => {
expect(PersonGivingNoticeComponent.find('#contact-info').classes('v-card--disabled')).toBe(false)

// recheck check box
await UnitNoteAddComponent.find('#no-person-giving-notice-checkbox').trigger('click')
await UnitNoteAddComponent.find('#no-person-giving-notice-checkbox').setValue(true)
await nextTick()
expect(store.getMhrUnitNote.hasNoPersonGivingNotice).toBe(true)

@@ -339,7 +310,7 @@ describe('MHR Unit Note Filing', () => {
)

expect(additionalRemarksCheckbox.exists()).toBeTruthy()
additionalRemarksCheckbox.trigger('click')
additionalRemarksCheckbox.find('input').setValue(true)

const ContactInformationComponent = UnitNoteAddComponent.findComponent(ContactInformation)

@@ -391,20 +362,20 @@ describe('MHR Unit Note Filing', () => {
it('Notice of Redemption (NRED): renders Landing & Review pages', async () => {
const noticeOfTaxSale = mockedUnitNotes5[0]
// simulate clicking on File Notice of Redemption (for Notice of Tax Sale)
const noticeOfRedemption = useMhrUnitNote()
const noticeOfRedemption = await useMhrUnitNote()
.prefillUnitNote(noticeOfTaxSale, UnitNoteDocTypes.NOTICE_OF_REDEMPTION)

await store.setMhrUnitNote(noticeOfRedemption)
await nextTick()
wrapper = await createUnitNoteComponent(UnitNoteDocTypes.NOTICE_OF_REDEMPTION)
await nextTick()

expect(wrapper.find(getTestId('cau-exp-note')).exists()).toBeFalsy()
const header = wrapper.find(getTestId('unit-note-add')).find('h1').text()
expect(header).toContain(UnitNotesInfo[UnitNoteDocTypes.NOTICE_OF_REDEMPTION].header)

expect(wrapper.findComponent(DocumentId).vm.$props.documentId).toBe('') // doc id should be cleared out
expect(wrapper.findComponent(Remarks).vm.$props.unitNoteRemarks).toBe(noticeOfTaxSale.remarks)
expect(wrapper.findComponent(Remarks).find('.generic-label').text()).toBe(remarksContent.sideLabelCancelNote)
expect(wrapper.findComponent(Remarks).find('.side-label').text()).toBe(remarksContent.sideLabel)

const UnitNoteReviewComponent = await getReviewConfirmComponent(wrapper)
const UnitNoteReviewTable = UnitNoteReviewComponent.findComponent(UnitNoteReviewDetailsTable)
35 changes: 4 additions & 31 deletions ppr-ui/tests/unit/OtherInformation.spec.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,11 @@
import Vue, { nextTick } from 'vue'
import Vuetify from 'vuetify'
import { createPinia, setActivePinia } from 'pinia'
import { useStore } from '../../src/store/store'
import { mount, createLocalVue, Wrapper } from '@vue/test-utils'
import { getTestId } from './utils'
import { createComponent, getTestId } from './utils'
import { OtherInformation } from '@/components/mhrRegistration'

Vue.use(Vuetify)
setActivePinia(createPinia())
const store = useStore()

/**
* Creates and mounts a component, so that it can be tested.
*
* @returns a Wrapper object with the given parameters.
*/
function createComponent (): Wrapper<any> {
const localVue = createLocalVue()
return mount((OtherInformation as any), {
localVue,
store
})
}

describe('Other Information component', () => {
let wrapper: Wrapper<any>
let wrapper

beforeEach(async () => {
wrapper = createComponent()
})
afterEach(() => {
wrapper.destroy()
wrapper = await createComponent(OtherInformation)
})

it('renders the component', async () => {
@@ -39,9 +14,7 @@ describe('Other Information component', () => {

it('show error message for Other Information input', async () => {
wrapper.find(getTestId('otherRemarks')).exists()
wrapper.find(getTestId('otherRemarks')).setValue('x'.repeat(150))
await nextTick()
await nextTick()
await wrapper.find(getTestId('otherRemarks')).find('textarea').setValue('x'.repeat(150))

const messages = wrapper.findAll('.v-messages__message')
expect(messages.length).toBe(1)
13 changes: 4 additions & 9 deletions ppr-ui/tests/unit/QsInformation.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { QsInformation } from '@/views'
import { createComponent, setupMockUser } from './utils'
import { Wrapper } from '@vue/test-utils'
import { createComponent, getTestId, setupMockUser } from './utils'
import { defaultFlagSet } from '@/utils'
import { createPinia, setActivePinia } from 'pinia'
import { useStore } from '@/store/store'
@@ -12,8 +11,9 @@ setActivePinia(createPinia())
const store = useStore()

describe('QsInformation', () => {
let wrapper: Wrapper<any> | any
let wrapper
const subProduct = MhrSubTypes.LAWYERS_NOTARIES
window.URL.createObjectURL = vi.fn();

beforeAll(async () => {
defaultFlagSet['mhr-user-access-enabled'] = true
@@ -29,10 +29,6 @@ describe('QsInformation', () => {
await flushPromises()
})

afterEach(() => {
wrapper.destroy()
})

it('renders the component', () => {
expect(wrapper.exists()).toBe(true)
})
@@ -54,8 +50,7 @@ describe('QsInformation', () => {
expect(heading.exists()).toBe(true)
expect(heading.text()).toBe('Service Agreement')

const downloadBtn = serviceAgreementSection.find('v-btn')
expect(downloadBtn.exists()).toBe(true)
expect(serviceAgreementSection.find(getTestId('download-agreement-btn')).exists()).toBe(true)
// Add more assertions for the content of the section if needed.
})

20 changes: 5 additions & 15 deletions ppr-ui/tests/unit/QsReviewConfirm.spec.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import { QsReviewConfirm } from '@/views'
import { createComponent, setupMockUser } from './utils'
import { Wrapper } from '@vue/test-utils'
import { convertDate, defaultFlagSet } from '@/utils'
import { createPinia, setActivePinia } from 'pinia'
import { useStore } from '@/store/store'
import { MhrSubTypes } from '@/enums'
import Vue from 'vue'
import flushPromises from 'flush-promises'
import Vuetify from 'vuetify'
import { Authorization, ConfirmRequirements, ListRequirements } from '@/components/userAccess/ReviewConfirm'
import { mockedAccountInfo } from './test-data'

Vue.use(Vuetify)
setActivePinia(createPinia())
const store = useStore()

describe('QsReviewConfirm', () => {
let wrapper: Wrapper<any, Element>
let wrapper
const subProduct = MhrSubTypes.LAWYERS_NOTARIES

const authorization = {
@@ -40,14 +34,10 @@ describe('QsReviewConfirm', () => {
})

beforeEach(async () => {
wrapper = await createComponent(QsReviewConfirm)
wrapper = await await createComponent(QsReviewConfirm)
await flushPromises()
})

afterEach(() => {
wrapper.destroy()
})

it('renders the component', () => {
expect(wrapper.exists()).toBe(true)
expect(wrapper.findComponent(ConfirmRequirements).exists()).toBe(true)
@@ -62,7 +52,7 @@ describe('QsReviewConfirm', () => {
expect(accountInfoComponent.props('title')).toBe('Submitting Party for this Application')
expect(accountInfoComponent.props('tooltipContent'))
.toContain('The default Submitting Party is based on your BC Registries user account information.')
expect(accountInfoComponent.props('accountInfo')).toBe(mockedAccountInfo)
expect(accountInfoComponent.props('accountInfo')).toStrictEqual(mockedAccountInfo)
})

it('Confirm requirements works as expected', async () => {
@@ -90,7 +80,7 @@ describe('QsReviewConfirm', () => {
expect(checkboxText.exists()).toBe(true)
expect(checkboxText.text()).toBe('I confirm and agree to all of the above requirements.')

await confirmationCheckboxContainer.find('.confirmation-checkbox').find('input').trigger('click')
await confirmationCheckboxContainer.find('input').setValue(true)

expect(store.getMhrQsIsRequirementsConfirmed).toBe(true)
})
@@ -123,7 +113,7 @@ describe('QsReviewConfirm', () => {
expect(store.getMhrQsAuthorization.authorizationName).toBe('Hello its me')
expect(checkboxText.text().includes(store.getMhrQsAuthorization.authorizationName)).toBe(true)

await authorizationCheckbox.trigger('click')
await authorizationCheckbox.setValue(true)

expect(store.getMhrQsAuthorization.isAuthorizationConfirmed).toBe(true)
})
12 changes: 3 additions & 9 deletions ppr-ui/tests/unit/QsSelectAccess.spec.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
import { QsSelectAccess } from '@/views'
import { FormCard, SubProductSelector } from '@/components/common'
import { setupMockUser } from './utils'
import { mount, Wrapper } from '@vue/test-utils'
import { createComponent } from './utils'
import { defaultFlagSet } from '@/utils'

describe('QsSelectAccess', () => {
let wrapper: Wrapper<any>
let wrapper
defaultFlagSet['mhr-user-access-enabled'] = true
setupMockUser()

beforeEach(async () => {
wrapper = await mount(QsSelectAccess as any)
})

afterEach(() => {
wrapper.destroy()
wrapper = await createComponent(QsSelectAccess)
})

it('renders the component', () => {
36 changes: 5 additions & 31 deletions ppr-ui/tests/unit/SimpleHelpToggle.spec.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,26 @@
// Libraries
import Vue from 'vue'
import Vuetify from 'vuetify'
import { createLocalVue, mount, Wrapper } from '@vue/test-utils'

// Components
import { SimpleHelpToggle } from '@/components/common'

// Utilities
import { getTestId } from './utils'

Vue.use(Vuetify)
const vuetify = new Vuetify({})

/**
* Creates and mounts a component, so that it can be tested.
*
* @returns a Wrapper<Any> object with the given parameters.
*/
function createComponent (propsData: any): Wrapper<any> {
const localVue = createLocalVue()
localVue.use(Vuetify)

return mount((SimpleHelpToggle as any), {
localVue,
propsData,
vuetify
})
}
import { createComponent, getTestId } from './utils'

describe('SimpleHelpToggle', () => {
it('renders the component properly', () => {
const wrapper: Wrapper<any> = createComponent({ toggleButtonTitle: 'test' })
it('renders the component properly', async () => {
const wrapper = await createComponent(SimpleHelpToggle, { toggleButtonTitle: 'test' })
expect(wrapper.findComponent(SimpleHelpToggle).exists()).toBe(true)
const toggleButton = wrapper.find(getTestId('help-toggle-btn'))
expect(toggleButton.text()).toBe('test')
expect(toggleButton.text().includes('Hide')).toBe(false)
})

it('has the proper hide text - default hide text', async () => {
const wrapper: Wrapper<any> = createComponent({ toggleButtonTitle: 'test' })
const wrapper = await createComponent(SimpleHelpToggle, { toggleButtonTitle: 'test' })
const toggleButton = wrapper.find(getTestId('help-toggle-btn'))
await toggleButton.trigger('click')
expect(toggleButton.text()).not.toBe('test')
expect(toggleButton.text()).toBe('Hide Help')
})

it('has the proper hide text - none default hide text', async () => {
const wrapper: Wrapper<any> = createComponent({ toggleButtonTitle: 'test', defaultHideText: false })
const wrapper = await createComponent(SimpleHelpToggle, { toggleButtonTitle: 'test', defaultHideText: false })
const toggleButton = wrapper.find(getTestId('help-toggle-btn'))
await toggleButton.trigger('click')
expect(toggleButton.text()).not.toBe('test')
19 changes: 7 additions & 12 deletions ppr-ui/tests/unit/SortingIcon.spec.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,26 @@
import { mount } from '@vue/test-utils'
import { SortingIcon } from '@/components/tables/common'
import { nextTick } from 'vue'
import { getTestId } from './utils'
import { createComponent, getTestId } from './utils'

describe('SortingIcon', () => {
let wrapper

beforeEach(() => {
wrapper = mount((SortingIcon as any), {
propsData: {
sortAsc: false
}
})
beforeEach(async () => {
wrapper = await createComponent(SortingIcon, { sortAsc: false })
})

it('should emit sortEvent with false when not sorted and clicked', async () => {
await wrapper.find('v-icon').trigger('click')
await wrapper.find(getTestId('up-arrow-icon')).trigger('click')

expect(wrapper.emitted('sortEvent')).toBeTruthy()
expect(wrapper.emitted('sortEvent')[0][0]).toBe(false)
})

it('should emit sortEvent with true when sorted and clicked', async () => {
wrapper.setProps({ sortAsc: true })
wrapper = await createComponent(SortingIcon, { sortAsc: true })
await nextTick()

await wrapper.find('v-icon').trigger('click')
await wrapper.find(getTestId('down-arrow-icon')).trigger('click')
await nextTick()

expect(wrapper.emitted('sortEvent')).toBeTruthy()
@@ -41,7 +36,7 @@ describe('SortingIcon', () => {
})

it('should render the down arrow icon when desc', async () => {
wrapper.setProps({ sortAsc: true })
wrapper = await createComponent(SortingIcon, { sortAsc: true })
await nextTick()

const upArrowIcon = wrapper.find(getTestId('up-arrow-icon'))
22 changes: 22 additions & 0 deletions ppr-ui/tests/unit/plugins/data-test-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { DOMWrapper, config } from '@vue/test-utils'

export const dataTestId = (wrapper) => {
function findByTestId(selector) {
const dataSelector = `[data-test-id='${selector}']`
const element = wrapper.element.querySelector(dataSelector)
return new DOMWrapper(element)
}

function findInputByTestId(selector) {
Copy link
Collaborator Author

@dimak1 dimak1 Nov 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cameron-eyds this is the plugin and function to get id+input field. We can run it diretly on the wrapper. Makes tests a bit cleaner. eg. await wrapper.findInputByTestId('manufacturer-model').setValue('x'.repeat(70))

const dataSelector = `[data-test-id='${selector}']`
const element = wrapper.element.querySelector(dataSelector)
return new DOMWrapper(element).find('input')
}

return {
findByTestId,
findInputByTestId
}
}

config.plugins.VueWrapper.install(dataTestId)
1 change: 1 addition & 0 deletions ppr-ui/tests/unit/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './data-test-id'

Unchanged files with check annotations Beta

const setCollateralValidAndEmit = (valid): void => {
setCollateralValid(valid)
context.emit('setCollateralValid', valid)

Check failure on line 267 in ppr-ui/src/components/collateral/Collateral.vue

GitHub Actions / linting (20.5.1)

The "setCollateralValid" event has been triggered but not declared on `emits` option
}
const setVehicleCollateralOpen = (isOpen): void => {
localState.vehicleCollateralOpen = isOpen
context.emit('collateralOpen', localState.vehicleCollateralOpen || localState.generalCollateralOpen)

Check failure on line 272 in ppr-ui/src/components/collateral/Collateral.vue

GitHub Actions / linting (20.5.1)

The "collateralOpen" event has been triggered but not declared on `emits` option
}
const setGeneralCollateralOpen = (isOpen): void => {
localState.generalCollateralOpen = isOpen
context.emit('collateralOpen', localState.vehicleCollateralOpen || localState.generalCollateralOpen)

Check failure on line 276 in ppr-ui/src/components/collateral/Collateral.vue

GitHub Actions / linting (20.5.1)

The "collateralOpen" event has been triggered but not declared on `emits` option
}
const vehiclesValid = (): boolean => {
localState.summaryView = val
})
watch(() => localState.collateral.vehicleCollateral, (val: VehicleCollateralIF[]) => {

Check failure on line 294 in ppr-ui/src/components/collateral/Collateral.vue

GitHub Actions / linting (20.5.1)

'val' is defined but never used
if ((vehiclesValid() || localState.collateral?.generalCollateral?.length > 0 ||
registrationType === APIRegistrationTypes.TRANSITION_TAX_LIEN) &&
// vehicle collateral is optional for Income Tax registration type
}
setGeneralCollateral(newGeneralCollateral)
}
emit('closeGenColAmend', true)

Check failure on line 180 in ppr-ui/src/components/collateral/generalCollateral/GenColAmend.vue

GitHub Actions / linting (20.5.1)

The "closeGenColAmend" event has been triggered but not declared on `emits` option
}
const resetFormAndData = () => {
emit('closeGenColAmend', true)

Check failure on line 184 in ppr-ui/src/components/collateral/generalCollateral/GenColAmend.vue

GitHub Actions / linting (20.5.1)

The "closeGenColAmend" event has been triggered but not declared on `emits` option
}
/** Called when general collateral updates */
<p class="ProseMirror pt-3 ma-0">
<span
style="white-space: pre-wrap;"
v-html="lastGeneralCollateral.descriptionDelete"

Check warning on line 115 in ppr-ui/src/components/collateral/generalCollateral/GenColSummary.vue

GitHub Actions / linting (20.5.1)

'v-html' directive can lead to XSS attack
/>
</p>
</div>
<p class="ProseMirror pt-3 ma-0">
<span
style="white-space: pre-wrap;"
v-html="lastGeneralCollateral.descriptionAdd"

Check warning on line 133 in ppr-ui/src/components/collateral/generalCollateral/GenColSummary.vue

GitHub Actions / linting (20.5.1)

'v-html' directive can lead to XSS attack
/>
</p>
</div>
<p class="pt-3 ma-0 pr-6">
<span
style="white-space: pre-wrap;"
v-html="item.descriptionDelete"

Check warning on line 188 in ppr-ui/src/components/collateral/generalCollateral/GenColSummary.vue

GitHub Actions / linting (20.5.1)

'v-html' directive can lead to XSS attack
/>
</p>
</div>
<p class="pt-3 ma-0 pr-6">
<span
style="white-space: pre-wrap;"
v-html="item.descriptionAdd"

Check warning on line 206 in ppr-ui/src/components/collateral/generalCollateral/GenColSummary.vue

GitHub Actions / linting (20.5.1)

'v-html' directive can lead to XSS attack
/>
</p>
</div>
>
<span
style="white-space: pre-wrap;"
v-html="item.description"

Check warning on line 232 in ppr-ui/src/components/collateral/generalCollateral/GenColSummary.vue

GitHub Actions / linting (20.5.1)

'v-html' directive can lead to XSS attack
/>
</p>
</div>
v-if="generalCollateral.length > 0"
class="ma-0"
>
<span v-html="generalCollateral[0].description" />

Check warning on line 248 in ppr-ui/src/components/collateral/generalCollateral/GenColSummary.vue

GitHub Actions / linting (20.5.1)

'v-html' directive can lead to XSS attack
</p>
</div>
</v-container>
})
const initGenColAmend = () => {
emit('initGenColAmend', true)

Check failure on line 393 in ppr-ui/src/components/collateral/generalCollateral/GenColSummary.vue

GitHub Actions / linting (20.5.1)

The "initGenColAmend" event has been triggered but not declared on `emits` option
}
const undo = () => {
localState.activeIndex = index
localState.addEditInProgress = true
localState.showEditVehicle[index] = true
context.emit('collateralOpen', true)

Check failure on line 583 in ppr-ui/src/components/collateral/vehicleCollateral/VehicleCollateral.vue

GitHub Actions / linting (20.5.1)

The "collateralOpen" event has been triggered but not declared on `emits` option
}
const initAdd = () => {
localState.addEditInProgress = true
localState.showAddVehicle = true
context.emit('collateralOpen', true)

Check failure on line 589 in ppr-ui/src/components/collateral/vehicleCollateral/VehicleCollateral.vue

GitHub Actions / linting (20.5.1)

The "collateralOpen" event has been triggered but not declared on `emits` option
}
const resetData = () => {
localState.addEditInProgress = false
localState.showAddVehicle = false
localState.showEditVehicle = [false]
context.emit('collateralOpen', false)

Check failure on line 597 in ppr-ui/src/components/collateral/vehicleCollateral/VehicleCollateral.vue

GitHub Actions / linting (20.5.1)

The "collateralOpen" event has been triggered but not declared on `emits` option
}
const undo = (index: number): void => {
:class="{ 'alert-box': setAlert }"
>
<slot name="prependSLot" />
<p><b>{{ setImportantWord }}:</b> <span v-html="setMsg" /></p>

Check warning on line 7 in ppr-ui/src/components/common/CautionBox.vue

GitHub Actions / linting (20.5.1)

'v-html' directive can lead to XSS attack
<slot name="appendSLot" />
</div>
</template>
>
<span
class="step__label__text"
v-html="step.text"

Check warning on line 62 in ppr-ui/src/components/common/Stepper.vue

GitHub Actions / linting (20.5.1)

'v-html' directive can lead to XSS attack
/>
</v-btn>
<v-btn
>
<p
class="step__label__text__current"
v-html="step.text"

Check warning on line 76 in ppr-ui/src/components/common/Stepper.vue

GitHub Actions / linting (20.5.1)

'v-html' directive can lead to XSS attack
/>
</v-btn>
</div>
v-if="subProduct.note"
class="sub-product-note mt-2 ml-8 mb-6"
>
<strong>Note:</strong> <span v-html="subProduct.note" />

Check warning on line 48 in ppr-ui/src/components/common/SubProductSelector.vue

GitHub Actions / linting (20.5.1)

'v-html' directive can lead to XSS attack
</p>
<v-divider
v-if="index !== subProductConfig.length - 1"