From 9d38f2a0471275a38dad2588775f8719ffe4eaa5 Mon Sep 17 00:00:00 2001 From: lana-k Date: Tue, 2 Feb 2021 23:48:24 +0100 Subject: [PATCH] add test for Tabs component --- tests/unit/components/Tabs.spec.js | 232 +++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 tests/unit/components/Tabs.spec.js diff --git a/tests/unit/components/Tabs.spec.js b/tests/unit/components/Tabs.spec.js new file mode 100644 index 0000000..5259f2b --- /dev/null +++ b/tests/unit/components/Tabs.spec.js @@ -0,0 +1,232 @@ +import { expect } from 'chai' +import { shallowMount, mount, createWrapper } from '@vue/test-utils' +import { mutations } from '@/store' +import Vuex from 'vuex' +import Tabs from '@/components/Tabs.vue' +import Tab from '@/components/Tab.vue' + +describe('Tabs.vue', () => { + it('Renders start guide when there is no opened tabs', () => { + // mock store state + const state = { + tabs: [] + } + const store = new Vuex.Store({ state }) + + // mount the component + const wrapper = shallowMount(Tabs, { store }) + + // check start-guide visibility + expect(wrapper.find('#start-guide').isVisible()).to.equal(true) + }) + + it('Renders tabs', () => { + // mock store state + const state = { + tabs: [ + { id: 1, name: 'foo', query: 'select * from foo', chart: [], isUnsaved: false }, + { id: 2, name: null, tempName: 'Untitled', query: '', chart: [], isUnsaved: true } + ], + currentTabId: 2 + } + const store = new Vuex.Store({ state }) + + // mount the component + const wrapper = shallowMount(Tabs, { store }) + + // check start-guide visibility + expect(wrapper.find('#start-guide').isVisible()).to.equal(false) + + // check tabs + expect(wrapper.findAllComponents(Tab)).to.have.lengthOf(2) + + const firstTab = wrapper.findAll('.tab').at(0) + expect(firstTab.text()).to.include('foo') + expect(firstTab.find('.star').isVisible()).to.equal(false) + expect(firstTab.classes()).to.not.include('tab-selected') + + const secondTab = wrapper.findAll('.tab').at(1) + expect(secondTab.text()).to.include('Untitled') + expect(secondTab.find('.star').isVisible()).to.equal(true) + expect(secondTab.classes()).to.include('tab-selected') + }) + + it('Selects the tab on click', async () => { + // mock store state + const state = { + tabs: [ + { id: 1, name: 'foo', query: 'select * from foo', chart: [], isUnsaved: false }, + { id: 2, name: null, tempName: 'Untitled', query: '', chart: [], isUnsaved: true } + ], + currentTabId: 2 + } + + const store = new Vuex.Store({ state, mutations }) + + // mount the component + const wrapper = shallowMount(Tabs, { store }) + + // click on the first tab + const firstTab = wrapper.findAll('.tab').at(0) + await firstTab.trigger('click') + + // check that first tab is the current now + expect(firstTab.classes()).to.include('tab-selected') + const secondTab = wrapper.findAll('.tab').at(1) + expect(secondTab.classes()).to.not.include('tab-selected') + expect(state.currentTabId).to.equal(1) + }) + + it("Deletes the tab on close if it's saved", async () => { + // mock store state + const state = { + tabs: [ + { id: 1, name: 'foo', query: 'select * from foo', chart: [], isUnsaved: false }, + { id: 2, name: null, tempName: 'Untitled', query: '', chart: [], isUnsaved: true } + ], + currentTabId: 2 + } + + const store = new Vuex.Store({ state, mutations }) + + // mount the component + const wrapper = mount(Tabs, { store, stubs: ['router-link'] }) + + // click on the close icon of the first tab + const firstTabCloseIcon = wrapper.findAll('.tab').at(0).find('.close-icon') + await firstTabCloseIcon.trigger('click') + + // check that the only one tab left and it's opened + expect(wrapper.findAllComponents(Tab)).to.have.lengthOf(1) + + const firstTab = wrapper.findAll('.tab').at(0) + expect(firstTab.text()).to.include('Untitled') + expect(firstTab.find('.star').isVisible()).to.equal(true) + expect(firstTab.classes()).to.include('tab-selected') + }) + + it("Doesn't delete tab on close if user cancel closing", async () => { + // mock store state + const state = { + tabs: [ + { id: 1, name: 'foo', query: 'select * from foo', chart: [], isUnsaved: false }, + { id: 2, name: null, tempName: 'Untitled', query: '', chart: [], isUnsaved: true } + ], + currentTabId: 2 + } + + const store = new Vuex.Store({ state, mutations }) + + // mount the component + const wrapper = mount(Tabs, { store, stubs: ['router-link'] }) + + // click on the close icon of the second tab + const secondTabCloseIcon = wrapper.findAll('.tab').at(1).find('.close-icon') + await secondTabCloseIcon.trigger('click') + + // check that Close Tab dialog is visible + const modal = wrapper.find('[data-modal="close-warn"]') + expect(modal.exists()).to.equal(true) + + // find Cancel in the dialog + const cancelBtn = wrapper + .findAll('.dialog-buttons-container button').wrappers + .find(button => button.text() === 'Cancel') + + // click Cancel in the dialog + await cancelBtn.trigger('click') + + // check that tab is still opened + expect(wrapper.findAllComponents(Tab)).to.have.lengthOf(2) + + // check that the dialog is closed + expect(wrapper.find('[data-modal="close-warn"]').exists()).to.equal(false) + }) + + it('Closes without saving', async () => { + // mock store state + const state = { + tabs: [ + { id: 1, name: 'foo', query: 'select * from foo', chart: [], isUnsaved: false }, + { id: 2, name: null, tempName: 'Untitled', query: '', chart: [], isUnsaved: true } + ], + currentTabId: 2 + } + + const store = new Vuex.Store({ state, mutations }) + + // mount the component + const wrapper = mount(Tabs, { store, stubs: ['router-link'] }) + + // click on the close icon of the second tab + const secondTabCloseIcon = wrapper.findAll('.tab').at(1).find('.close-icon') + await secondTabCloseIcon.trigger('click') + + // find 'Close without saving' in the dialog + const closeBtn = wrapper + .findAll('.dialog-buttons-container button').wrappers + .find(button => button.text() === 'Close without saving') + + // click 'Close without saving' in the dialog + await closeBtn.trigger('click') + + // check that tab is closed + expect(wrapper.findAllComponents(Tab)).to.have.lengthOf(1) + const firstTab = wrapper.findAll('.tab').at(0) + expect(firstTab.text()).to.include('foo') + expect(firstTab.find('.star').isVisible()).to.equal(false) + expect(firstTab.classes()).to.include('tab-selected') + + // check that 'saveQuery' event was not emited + const rootWrapper = createWrapper(wrapper.vm.$root) + expect(rootWrapper.emitted('saveQuery')).to.equal(undefined) + + // check that the dialog is closed + expect(wrapper.find('[data-modal="close-warn"]').exists()).to.equal(false) + }) + + it('Closes with saving', async () => { + // mock store state + const state = { + tabs: [ + { id: 1, name: 'foo', query: 'select * from foo', chart: [], isUnsaved: false }, + { id: 2, name: null, tempName: 'Untitled', query: '', chart: [], isUnsaved: true } + ], + currentTabId: 2 + } + + const store = new Vuex.Store({ state, mutations }) + + // mount the component + const wrapper = mount(Tabs, { store, stubs: ['router-link'] }) + + // click on the close icon of the second tab + const secondTabCloseIcon = wrapper.findAll('.tab').at(1).find('.close-icon') + await secondTabCloseIcon.trigger('click') + + // find 'Save and close' in the dialog + const closeBtn = wrapper + .findAll('.dialog-buttons-container button').wrappers + .find(button => button.text() === 'Save and close') + + // click 'Save and close' in the dialog + await closeBtn.trigger('click') + + // pretend like saving is completed - trigger 'querySaved' on $root + await wrapper.vm.$root.$emit('querySaved') + + // check that tab is closed + expect(wrapper.findAllComponents(Tab)).to.have.lengthOf(1) + const firstTab = wrapper.findAll('.tab').at(0) + expect(firstTab.text()).to.include('foo') + expect(firstTab.find('.star').isVisible()).to.equal(false) + expect(firstTab.classes()).to.include('tab-selected') + + // check that 'saveQuery' event was emited + const rootWrapper = createWrapper(wrapper.vm.$root) + expect(rootWrapper.emitted('saveQuery')).to.have.lengthOf(1) + + // check that the dialog is closed + expect(wrapper.find('[data-modal="close-warn"]').exists()).to.equal(false) + }) +})