2
0
mirror of https://github.com/tenrok/vue-meta.git synced 2026-05-26 12:04:04 +03:00
Files
vue-meta/test/unit/plugin-browser.test.js
T
Pim 024e7c5a62 feat: add basic support for multiple apps on one page (#373)
* feat: add an appId to tags to support multiple apps

* feat: show warning on calling () on non-vuemeta components

* feat: always use appId ssr for server-generated apps

* test: update tests for appId

* chore: update circleci to only run audit for dependencies

* fix: dont set data-vue-meta attribute on title

it has no use on the client as we use document.title there. Which also means the appId listed would be wrong once the title is updated by another app then the ssr app

* chore: remove unused import

* chore: improve not supported message
2019-06-06 10:40:15 +02:00

184 lines
5.7 KiB
JavaScript

import { triggerUpdate, batchUpdate } from '../../src/client/update'
import { mount, vmTick, VueMetaBrowserPlugin, loadVueMetaPlugin } from '../utils'
import { defaultOptions } from '../../src/shared/constants'
jest.mock('../../src/client/update')
jest.mock('../../package.json', () => ({
version: 'test-version'
}))
describe('plugin', () => {
let Vue
beforeEach(() => jest.clearAllMocks())
beforeAll(() => (Vue = loadVueMetaPlugin(true)))
test('not loaded when no metaInfo defined', () => {
const warn = jest.spyOn(console, 'warn').mockImplementation(() => {})
const instance = new Vue()
expect(instance.$meta).toEqual(expect.any(Function))
expect(instance.$meta().inject).toEqual(expect.any(Function))
expect(instance.$meta().refresh).toEqual(expect.any(Function))
expect(instance.$meta().getOptions).toEqual(expect.any(Function))
expect(instance.$meta().inject()).not.toBeDefined()
expect(warn).toHaveBeenCalledTimes(1)
expect(instance.$meta().refresh()).not.toBeDefined()
expect(warn).toHaveBeenCalledTimes(2)
instance.$meta().getOptions()
expect(warn).toHaveBeenCalledTimes(3)
warn.mockRestore()
})
test('is loaded', () => {
const instance = new Vue({ metaInfo: {} })
expect(instance.$meta).toEqual(expect.any(Function))
expect(instance.$meta().inject).toEqual(expect.any(Function))
expect(instance.$meta().refresh).toEqual(expect.any(Function))
expect(instance.$meta().getOptions).toEqual(expect.any(Function))
expect(instance.$meta().inject()).toBeUndefined()
expect(instance.$meta().refresh()).toBeDefined()
const options = instance.$meta().getOptions()
expect(options).toBeDefined()
expect(options.keyName).toBe(defaultOptions.keyName)
})
test('component has _hasMetaInfo set to true', () => {
const Component = Vue.component('test-component', {
template: '<div>Test</div>',
[defaultOptions.keyName]: {
title: 'Hello World'
}
})
const { vm } = mount(Component, { localVue: Vue })
expect(vm._hasMetaInfo).toBe(true)
})
test('plugin sets package version', () => {
expect(VueMetaBrowserPlugin.version).toBe('test-version')
})
test('updates can be paused and resumed', async () => {
const { batchUpdate: _batchUpdate } = jest.requireActual('../../src/client/update')
const batchUpdateSpy = batchUpdate.mockImplementation(_batchUpdate)
// because triggerUpdate & batchUpdate reside in the same file we cant mock them both,
// so just recreate the triggerUpdate fn by copying its implementation
const triggerUpdateSpy = triggerUpdate.mockImplementation((vm, hookName) => {
if (vm.$root._vueMeta.initialized && !vm.$root._vueMeta.paused) {
// batch potential DOM updates to prevent extraneous re-rendering
batchUpdateSpy(() => vm.$meta().refresh())
}
})
const Component = Vue.component('test-component', {
metaInfo() {
return {
title: this.title
}
},
props: {
title: {
type: String,
default: ''
}
},
template: '<div>Test</div>'
})
let title = 'first title'
const wrapper = mount(Component, {
localVue: Vue,
propsData: {
title
}
})
// no batchUpdate on initialization
expect(wrapper.vm.$root._vueMeta.initialized).toBe(false)
expect(wrapper.vm.$root._vueMeta.paused).toBeFalsy()
expect(triggerUpdateSpy).toHaveBeenCalledTimes(1)
expect(batchUpdateSpy).not.toHaveBeenCalled()
jest.clearAllMocks()
await vmTick(wrapper.vm)
title = 'second title'
wrapper.setProps({ title })
// batchUpdate on normal update
expect(wrapper.vm.$root._vueMeta.initialized).toBe(true)
expect(wrapper.vm.$root._vueMeta.paused).toBeFalsy()
expect(triggerUpdateSpy).toHaveBeenCalledTimes(1)
expect(batchUpdateSpy).toHaveBeenCalledTimes(1)
jest.clearAllMocks()
wrapper.vm.$meta().pause()
title = 'third title'
wrapper.setProps({ title })
// no batchUpdate when paused
expect(wrapper.vm.$root._vueMeta.initialized).toBe(true)
expect(wrapper.vm.$root._vueMeta.paused).toBe(true)
expect(triggerUpdateSpy).toHaveBeenCalledTimes(1)
expect(batchUpdateSpy).not.toHaveBeenCalled()
jest.clearAllMocks()
const { metaInfo } = wrapper.vm.$meta().resume()
expect(metaInfo.title).toBe(title)
})
test('updates are batched', async () => {
jest.useFakeTimers()
const { batchUpdate: _batchUpdate } = jest.requireActual('../../src/client/update')
const batchUpdateSpy = batchUpdate.mockImplementation(_batchUpdate)
const refreshSpy = jest.fn()
// because triggerUpdate & batchUpdate reside in the same file we cant mock them both,
// so just recreate the triggerUpdate fn by copying its implementation
triggerUpdate.mockImplementation((vm, hookName) => {
if (vm.$root._vueMeta.initialized && !vm.$root._vueMeta.paused) {
// batch potential DOM updates to prevent extraneous re-rendering
batchUpdateSpy(refreshSpy)
}
})
const Component = Vue.component('test-component', {
metaInfo() {
return {
title: this.title
}
},
props: {
title: {
type: String,
default: ''
}
},
template: '<div>Test</div>'
})
let title = 'first title'
const wrapper = mount(Component, {
localVue: Vue,
propsData: {
title
}
})
await vmTick(wrapper.vm)
jest.clearAllMocks()
title = 'second title'
wrapper.setProps({ title })
jest.advanceTimersByTime(2)
expect(refreshSpy).not.toHaveBeenCalled()
jest.advanceTimersByTime(10)
expect(refreshSpy).toHaveBeenCalled()
})
})