Skip to content
Snippets Groups Projects
Commit c932f9be authored by Bastien Abadie's avatar Bastien Abadie
Browse files

Merge branch 'fix-tabs-default' into 'master'

Fix default value handling on Tabs component without v-model

Closes #963

See merge request !1244
parents 11225ed2 c40dbbcb
No related branches found
No related tags found
1 merge request!1244Fix default value handling on Tabs component without v-model
import assert from 'assert'
import AsyncComputed from 'vue-async-computed'
import Vuex from 'vuex'
import { shallowMount, createLocalVue, RouterLinkStub } from '@vue/test-utils'
import store from '~/test/store'
import Main from '~/vue/Corpus/Main'
import Tabs from '~/vue/Tabs'
const localVue = createLocalVue()
localVue.use(Vuex)
localVue.use(AsyncComputed)
describe('Corpus/Main.vue', () => {
beforeEach(() => {
store.state.corpora.corpora.corpusid = {
id: 'corpusid',
name: 'Le Corpus',
rights: ['read', 'write', 'admin']
}
})
afterEach(() => {
store.reset()
})
it('only displays a creation form without a corpus ID', async () => {
const wrapper = shallowMount(Main, {
store,
localVue,
stubs: {
RouterLink: RouterLinkStub,
// Allow just the Tabs component as an actual component, not a stub
Tabs
}
})
await store.actionsCompleted()
assert.deepStrictEqual(store.history, [])
// No tabs are displayed
assert.ok(!wrapper.find('.tabs').exists())
const editionForm = wrapper.get('editionform-stub')
assert.deepStrictEqual(editionForm.props(), { corpusId: null })
})
it('includes all tabs with a corpus ID', async () => {
const wrapper = shallowMount(Main, {
store,
localVue,
stubs: {
RouterLink: RouterLinkStub,
Tabs
},
propsData: {
corpusId: 'corpusid'
}
})
await store.actionsCompleted()
assert.deepStrictEqual(store.history, [
{
action: 'corpora/get',
payload: {
id: 'corpusid'
}
}
])
const tabs = wrapper.findAll('.tabs ul li').wrappers
assert.deepStrictEqual(
tabs.map(tab => [tab.text(), tab.classes('is-active')]),
[
['Details', true],
['Types', false],
['Allowed metadata', false],
['Classes', false],
['Members', false]
]
)
const editionForm = wrapper.get('editionform-stub')
assert.deepStrictEqual(editionForm.props(), { corpusId: 'corpusid' })
})
})
import assert from 'assert'
import { shallowMount } from '@vue/test-utils'
import Tabs from '~/vue/Tabs'
describe('Tabs.vue', () => {
it('supports no tabs', () => {
const wrapper = shallowMount(Tabs, {
propsData: {
tabs: {}
}
})
assert.ok(!wrapper.find('div.tabs ul li').exists())
assert.strictEqual(wrapper.vm.selected, '')
})
it('displays available tabs', () => {
const wrapper = shallowMount(Tabs, {
propsData: {
tabs: {
tab1: 'First tab',
tab2: 'Second tab'
}
},
slots: {
tab1: 'First tab content',
tab2: 'Second tab content'
}
})
const tabs = wrapper.findAll('div.tabs ul li').wrappers
assert.strictEqual(tabs.length, 2)
const [tab1, tab2] = tabs
assert.strictEqual(tab1.text(), 'First tab')
assert.ok(tab1.classes('is-active'))
assert.strictEqual(tab2.text(), 'Second tab')
assert.ok(!tab2.classes('is-active'))
assert.strictEqual(wrapper.vm.selected, 'tab1')
assert.ok(wrapper.text().includes('First tab content'))
})
it('hides tabs with auto-hide when there is only one tab', () => {
const wrapper = shallowMount(Tabs, {
propsData: {
tabs: {
tab1: 'First tab'
},
autoHide: true
},
slots: {
tab1: 'First tab content'
}
})
assert.ok(!wrapper.find('div.tabs').exists())
assert.strictEqual(wrapper.vm.selected, 'tab1')
assert.strictEqual(wrapper.text(), 'First tab content')
})
it('handles switching on tabs with clicks', async () => {
const wrapper = shallowMount(Tabs, {
propsData: {
tabs: {
tab1: 'First tab',
tab2: 'Second tab'
}
},
slots: {
tab1: 'First tab content',
tab2: 'Second tab content'
}
})
const tabs = wrapper.findAll('div.tabs ul li').wrappers
assert.strictEqual(tabs.length, 2)
const [tab1, tab2] = tabs
assert.strictEqual(tab1.text(), 'First tab')
assert.ok(tab1.classes('is-active'))
assert.strictEqual(tab2.text(), 'Second tab')
assert.ok(!tab2.classes('is-active'))
assert.strictEqual(wrapper.vm.selected, 'tab1')
assert.ok(wrapper.text().includes('First tab content'))
/*
* .emitted() returns an object with a null prototype,
* which does not play well with deepStrictEqual
*/
assert.deepStrictEqual({ ...wrapper.emitted() }, {
input: [['tab1']]
})
await tab2.trigger('click')
assert.strictEqual(wrapper.vm.selected, 'tab2')
assert.ok(!tab1.classes('is-active'))
assert.ok(tab2.classes('is-active'))
assert.ok(wrapper.text().includes('Second tab content'))
assert.deepStrictEqual({ ...wrapper.emitted() }, {
input: [['tab1'], ['tab2']]
})
})
it('handles switching tabs via v-model', async () => {
const wrapper = shallowMount(Tabs, {
propsData: {
tabs: {
tab1: 'First tab',
tab2: 'Second tab'
},
value: 'tab2'
},
slots: {
tab1: 'First tab content',
tab2: 'Second tab content'
}
})
const tabs = wrapper.findAll('div.tabs ul li').wrappers
assert.strictEqual(tabs.length, 2)
const [tab1, tab2] = tabs
assert.strictEqual(tab1.text(), 'First tab')
assert.ok(!tab1.classes('is-active'))
assert.strictEqual(tab2.text(), 'Second tab')
assert.ok(tab2.classes('is-active'))
assert.strictEqual(wrapper.vm.selected, 'tab2')
assert.ok(wrapper.text().includes('Second tab content'))
assert.deepStrictEqual({ ...wrapper.emitted() }, {
input: [['tab1'], ['tab2']]
})
await wrapper.setProps({ value: 'tab1' })
assert.strictEqual(wrapper.vm.selected, 'tab1')
assert.ok(tab1.classes('is-active'))
assert.ok(!tab2.classes('is-active'))
assert.ok(wrapper.text().includes('First tab content'))
assert.deepStrictEqual({ ...wrapper.emitted() }, {
input: [['tab1'], ['tab2'], ['tab1']]
})
})
it('handles changes in tabs', async () => {
const wrapper = shallowMount(Tabs, {
propsData: {
tabs: {
tab1: 'First tab',
tab2: 'Second tab'
}
},
slots: {
tab1: 'First tab content',
tab2: 'Second tab content',
tab3: 'Third tab content'
}
})
const tabs = wrapper.findAll('div.tabs ul li').wrappers
assert.strictEqual(tabs.length, 2)
const [tab1, tab2] = tabs
assert.strictEqual(tab1.text(), 'First tab')
assert.ok(tab1.classes('is-active'))
assert.strictEqual(tab2.text(), 'Second tab')
assert.ok(!tab2.classes('is-active'))
assert.strictEqual(wrapper.vm.selected, 'tab1')
assert.deepStrictEqual({ ...wrapper.emitted() }, {
input: [['tab1']]
})
await wrapper.setProps({
tabs: {
tab2: 'Second tab',
tab3: 'Third tab'
}
})
assert.strictEqual(wrapper.findAll('div.tabs ul li').wrappers.length, 2)
const tab3 = wrapper.get('div.tabs ul li:last-child')
assert.strictEqual(tab2.text(), 'Second tab')
assert.ok(tab2.classes('is-active'))
assert.strictEqual(tab3.text(), 'Third tab')
assert.ok(!tab3.classes('is-active'))
assert.strictEqual(wrapper.vm.selected, 'tab2')
assert.deepStrictEqual({ ...wrapper.emitted() }, {
input: [['tab1'], ['tab2']]
})
})
})
......@@ -17,7 +17,7 @@
You are not allowed to edit this project.
</div>
<Tabs :tabs="tabs" class="is-medium" auto-hide>
<Tabs :tabs="tabs" auto-hide>
<template v-slot:details>
<EditionForm :corpus-id="corpusId" />
</template>
......
......@@ -64,7 +64,11 @@ export default {
}),
methods: {
select (tab) {
if (tab && !this.tabs[tab]) throw new Error(`Unknown tab ${tab}`)
/*
* Either there are no defined tabs at all, and we can select the default empty value,
* or there are tabs and we can only select a tab that exists.
*/
if ((Object.keys(this.tabs).length || tab) && !this.tabs[tab]) throw new Error(`Unknown tab ${tab}`)
this.selected = tab
this.$emit('input', tab)
}
......@@ -77,7 +81,7 @@ export default {
immediate: true,
handler (newValue) {
if (!newValue) this.select('')
else if (!newValue[this.selected]) this.select(Object.keys(newValue)[0])
else if (!newValue[this.selected]) this.select(Object.keys(newValue)[0] ?? '')
}
},
/*
......@@ -86,7 +90,7 @@ export default {
value: {
immediate: true,
handler (newValue) {
if (this.selected !== newValue) this.select(newValue)
if (newValue && this.selected !== newValue) this.select(newValue)
}
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment