Files
goauto/web/tests/unit/layout/AppMain.spec.js
T

115 lines
3.8 KiB
JavaScript

import { flushPromises, mount } from '@vue/test-utils'
import { h, nextTick } from 'vue'
import { createMemoryHistory, createRouter } from 'vue-router'
import AppMain from '@/layout/components/AppMain.vue'
function createStatefulPage(name, mounted) {
return {
name,
data() {
return { value: '' }
},
mounted,
render() {
return h('input', {
'data-test': name,
value: this.value,
onInput: event => {
this.value = event.target.value
}
})
}
}
}
async function mountAppMain(routes, cachedViews, initialPath) {
const router = createRouter({
history: createMemoryHistory(),
routes
})
await router.push(initialPath)
await router.isReady()
const wrapper = mount(AppMain, {
global: {
plugins: [router],
mocks: {
$store: {
state: {
tagsView: { cachedViews },
settings: { fixedHeader: false, tagsView: true }
}
}
}
}
})
await flushPromises()
await nextTick()
return { router, wrapper }
}
async function navigate(router, path) {
await router.push(path)
await flushPromises()
await nextTick()
}
describe('AppMain route cache', () => {
it('restores a named page instance after switching tabs', async() => {
const mounted = { pageA: 0, pageB: 0 }
const PageA = createStatefulPage('StatefulPageA', () => mounted.pageA++)
const PageB = createStatefulPage('StatefulPageB', () => mounted.pageB++)
const { router, wrapper } = await mountAppMain([
{ path: '/page-a', name: 'StatefulPageA', component: PageA },
{ path: '/page-b', name: 'StatefulPageB', component: PageB }
], ['StatefulPageA', 'StatefulPageB'], '/page-a')
await wrapper.get('[data-test="StatefulPageA"]').setValue('retained state')
await navigate(router, '/page-b')
await navigate(router, '/page-a')
expect(wrapper.get('[data-test="StatefulPageA"]').element.value).toBe('retained state')
expect(mounted).toEqual({ pageA: 1, pageB: 1 })
wrapper.unmount()
})
it('keeps separate cached instances for dynamic routes with the same name', async() => {
let mountCount = 0
const DictDataPage = createStatefulPage('DictDataPage', () => mountCount++)
const { router, wrapper } = await mountAppMain([
{ path: '/dict/data/:dictId', name: 'DictDataPage', component: DictDataPage }
], ['DictDataPage'], '/dict/data/1')
await wrapper.get('[data-test="DictDataPage"]').setValue('dict 1')
await navigate(router, '/dict/data/2')
await wrapper.get('[data-test="DictDataPage"]').setValue('dict 2')
await navigate(router, '/dict/data/3')
await wrapper.get('[data-test="DictDataPage"]').setValue('dict 3')
await navigate(router, '/dict/data/1')
expect(wrapper.get('[data-test="DictDataPage"]').element.value).toBe('dict 1')
await navigate(router, '/dict/data/2')
expect(wrapper.get('[data-test="DictDataPage"]').element.value).toBe('dict 2')
await navigate(router, '/dict/data/3')
expect(wrapper.get('[data-test="DictDataPage"]').element.value).toBe('dict 3')
expect(mountCount).toBe(3)
wrapper.unmount()
})
it('does not use RouterView directly inside KeepAlive or Transition', async() => {
const warn = jest.spyOn(console, 'warn').mockImplementation(() => {})
const Page = createStatefulPage('WarningCheckPage', () => {})
const { wrapper } = await mountAppMain([
{ path: '/warning-check', name: 'WarningCheckPage', component: Page }
], ['WarningCheckPage'], '/warning-check')
const routerViewWarnings = warn.mock.calls.filter(args => args.some(arg =>
typeof arg === 'string' && arg.includes('RouterView can no longer be used directly inside')
))
expect(routerViewWarnings).toHaveLength(0)
wrapper.unmount()
warn.mockRestore()
})
})