From d15a70b188bcbe42e37af43287f202090ad84c6a Mon Sep 17 00:00:00 2001 From: rwood-moz Date: Wed, 25 Mar 2026 16:37:54 -0400 Subject: [PATCH] Add the rest of the vue.js component tests --- test/components/SwitchToggle.test.js | 170 +++++++++++++++++++++++++++ test/components/SyncCard.test.js | 158 +++++++++++++++++++++++++ 2 files changed, 328 insertions(+) create mode 100644 test/components/SwitchToggle.test.js create mode 100644 test/components/SyncCard.test.js diff --git a/test/components/SwitchToggle.test.js b/test/components/SwitchToggle.test.js new file mode 100644 index 0000000..23c6181 --- /dev/null +++ b/test/components/SwitchToggle.test.js @@ -0,0 +1,170 @@ +import { describe, it, expect, afterEach } from 'vitest'; +import { mount } from '@vue/test-utils'; +import SwitchToggle from '@/components/SwitchToggle.vue'; + + +describe('SwitchToggle', () => { + var wrapper; + + // build out test cases for variants/options + const testCases = [ + { + label: 'This is the toggle label', + noLegend: false, + modelValue: false, + active: false, + disabled: false, + dataTestid: 'standard-switch-toggle', + }, + { + label: 'Turn some option on or off', + noLegend: true, + modelValue: false, + active: false, + disabled: false, + dataTestid: 'switch-toggle-no-legend', + }, + { + label: 'Do you want this option on?', + noLegend: false, + modelValue: false, + active: false, + disabled: false, + dataTestid: 'switch-toggle-not-active', + }, + { + label: 'Select yes or no', + noLegend: false, + modelValue: true, + active: false, + disabled: false, + dataTestid: 'switch-toggle-on-by-default', + }, + { + label: 'Some option label', + noLegend: false, + modelValue: false, + active: false, + disabled: true, + dataTestid: 'switch-toggle-disabled', + }, + ]; + + afterEach(() => { + wrapper.unmount(); + }); + + it.each(testCases)('renders correctly with the given options', + async ({ label, noLegend, modelValue, active, disabled, dataTestid }) => { + const ourProps = { + name: 'toggle-switch', + label: label, + noLegend: noLegend, + modelValue: modelValue, + active: active, + disabled: disabled, + dataTestid: dataTestid, + }; + + wrapper = mount(SwitchToggle, { + propsData: ourProps, + }); + + expect(wrapper.props()).toEqual(ourProps); + + // find, verify exists and is visible + const toggleSel = `[data-testid=${ourProps['dataTestid']}]`; + const toggle = wrapper.find(toggleSel); + expect(toggle.exists()).toBe(true); + expect(toggle.isVisible()).toBe(true); + expect(toggle.attributes().name).toBe(ourProps['name']); + + // verify toggle switch label text is displayed + const toggleLbl = wrapper.findAll('div').filter(itemWrapper => { + return itemWrapper.text() === ourProps['label']; + }); + expect(toggleLbl[0].exists()).toBe(true); + expect(toggleLbl[0].text()).toBe(ourProps['label']); + + // verify toggle value + if (ourProps['modelValue']) { + expect(toggle.attributes().checked).not.toBeUndefined(); + } else { + expect(toggle.attributes().checked).toBeUndefined(); + } + + // legend ('off' and 'on' labels) is/is not displayed depending on noLegend prop + const toggleLegendLbls = wrapper.findAll('.toggle-label'); + if (ourProps['noLegend']) { + expect(toggleLegendLbls.length).toBe(0); + } else { + expect(toggleLegendLbls.length).toBe(2); + expect(toggleLegendLbls[0].text()).toBe('Off'); + expect(toggleLegendLbls[1].text()).toBe('On'); + } + + // if disabled set, verify + if(ourProps['disabled']) { + expect(toggle.attributes().disabled).not.toBeUndefined(); + } else { + expect(toggle.attributes().disabled).toBeUndefined(); + } + }); + + it('able to toggle the switch on and off by clicking on it', async () => { + const ourProps = { + name: 'toggle-switch', + label: 'Toggle label', + noLegend: false, + disabled: false, + dataTestid: 'switch-toggle-test', + }; + + wrapper = mount(SwitchToggle, { + propsData: ourProps, + }); + + // verify toggle switch is off/unchecked + const toggleSel = `[data-testid=${ourProps['dataTestid']}]`; + const toggle = wrapper.find(toggleSel); + expect(toggle.exists()).toBe(true); + expect(toggle.attributes().checked).toBeUndefined(); + + // click on it, verify click event generated and is now turned on/checked + await toggle.trigger('click'); + expect(wrapper.emitted()['click'].length).toBe(1); + expect(toggle.attributes().checked).not.toBeUndefined(); + + // now click on it again to turn it back off + await toggle.trigger('click'); + expect(wrapper.emitted()['click'].length).toBe(2); + expect(toggle.attributes().checked).toBeUndefined(); + }); + + it('unable to toggle the switch when disabled', async () => { + const ourProps = { + name: 'toggle-switch', + label: 'Toggle label', + noLegend: false, + modelValue: false, + disabled: true, + dataTestid: 'switch-toggle-test-disabled', + }; + + wrapper = mount(SwitchToggle, { + propsData: ourProps, + }); + + const toggleSel = `[data-testid=${ourProps['dataTestid']}]`; + const toggle = wrapper.find(toggleSel); + expect(toggle.exists()).toBe(true); + expect(toggle.attributes().checked).toBeUndefined(); + + // click on it, verify click event not generated since is disabled + await toggle.trigger('click'); + expect(wrapper.emitted()['click']).toBeUndefined(); + + // toggle should still be in previous state (off) + expect(toggle.attributes().checked).toBeUndefined(); + }); +}); diff --git a/test/components/SyncCard.test.js b/test/components/SyncCard.test.js new file mode 100644 index 0000000..a457f4c --- /dev/null +++ b/test/components/SyncCard.test.js @@ -0,0 +1,158 @@ +import { describe, it, expect, afterEach } from 'vitest'; +import { mount } from '@vue/test-utils'; +import SyncCard from '@/components/SyncCard.vue'; +import CalendarIcon from '@/assets/svg/icons/calendar.svg'; +import { nextTick } from 'vue'; + + +describe('SyncCard', () => { + var wrapper; + + const cardOpts = [ + { + "key": 0, + "label": "Calendar One", + "checked": true + }, + { + "key": 1, + "label": "Calendar Two", + "checked": false + }, + { + "key": 2, + "label": "Calendar Three", + "checked": false + }, + { + "key": 3, + "label": "Calendar Four", + "checked": false + }, + ]; + + const calIcon = ` + + Calendar Icon + + ` + + const ourProps = { + title: 'Please select calendar(s)', + modelValue: cardOpts, + dataTestid: 'test-sync-card', + }; + + const ourSlots = { + icon: calIcon, + }; + + afterEach(() => { + wrapper.unmount(); + }); + + it('renders correctly', async () => { + wrapper = mount(SyncCard, { + propsData: ourProps, + slots: ourSlots, + }); + + expect(wrapper.props()).toEqual(ourProps); + + const syncCardSel = `[data-testid=${ourProps['dataTestid']}]`; + const syncCard = wrapper.find(syncCardSel); + expect(syncCard.exists()).toBe(true); + expect(syncCard.isVisible()).toBe(true); + + // header icon, text, selected count + const syncCardHdrIcon = wrapper.find('.icon-calendar'); + expect(syncCardHdrIcon.exists()).toBe(true); + const syncCardHdrTitle = wrapper.find('div.title'); + expect(syncCardHdrTitle.exists()).toBe(true); + expect(syncCardHdrTitle.text()).toBe(ourProps['title']); + const syncCardSelected = wrapper.find('div.selected'); + expect(syncCardSelected.exists()).toBe(true); + expect(syncCardSelected.text()).toBe('1 Selected'); // only 1 is checked in our cardOpts + + // verify select all button is displayed + const selAllBtn = wrapper.find('button.select-all'); + expect(selAllBtn.exists()).toBe(true); + expect(selAllBtn.isVisible()).toBe(true); + expect(selAllBtn.text()).toBe('Select All'); + + // verify each list item on the card + const cardList = syncCard.findAll('li.row'); + expect(cardList.length).toBe(ourProps['modelValue'].length); + + cardList.forEach((item, index) => { + // go thru each, check label and checked/unchecked as expected + expect(item.text()).toBe(ourProps['modelValue'][index]['label']); + const cardItemCbox = item.find('input.tbpro-checkbox'); + expect(cardItemCbox.exists()).toBe(true); + expect(cardItemCbox.isVisible()).toBe(true); + expect(cardItemCbox.element.checked).toBe(ourProps['modelValue'][index]['checked']); + }); + }); + + it('able to select an unselected item on the card', async () => { + wrapper = mount(SyncCard, { + propsData: ourProps, + slots: ourSlots, + }); + + // verify the second option on the card list is unchecked + const syncCardSel = `[data-testid=${ourProps['dataTestid']}]`; + const syncCard = wrapper.find(syncCardSel); + const cardList = syncCard.findAll('li.row'); + const cardItem2Cbox = cardList[1].find('input.tbpro-checkbox'); + expect(cardItem2Cbox.element.checked).toBe(false); + + // click on our second option/checkbox on our sync card to turn it on / checked, verify + await cardItem2Cbox.trigger('click'); + expect(wrapper.emitted().click, 'expected click event to have been emitted').toBeTruthy(); + expect(wrapper.emitted()['click'].length).toBe(1); + expect(cardItem2Cbox.element.checked).toBe(true); + }); + + it('select all button selects all items on the card', async () => { + wrapper = mount(SyncCard, { + propsData: ourProps, + slots: ourSlots, + }); + + // click the select all button + const selAllBtn = wrapper.find('button.select-all'); + await selAllBtn.trigger('click'); + expect(wrapper.emitted().click, 'expected click event to have been emitted').toBeTruthy(); + expect(wrapper.emitted()['click'].length).toBe(1); + + // verify each sync card option is now checked on + const syncCardSel = `[data-testid=${ourProps['dataTestid']}]`; + const syncCard = wrapper.find(syncCardSel); + const cardList = syncCard.findAll('li.row'); + cardList.forEach((item, index) => { + const cardItemCbox = item.find('input.tbpro-checkbox'); + expect(cardItemCbox.element.checked).toBe(true); + }); + }); + + it('clicking on a selected card item deselects it', async () => { + wrapper = mount(SyncCard, { + propsData: ourProps, + slots: ourSlots, + }); + + // verify the first option on the card list is checked on + const syncCardSel = `[data-testid=${ourProps['dataTestid']}]`; + const syncCard = wrapper.find(syncCardSel); + const cardList = syncCard.findAll('li.row'); + const cardItem1Cbox = cardList[0].find('input.tbpro-checkbox'); + expect(cardItem1Cbox.element.checked).toBe(true); + + // click on the first option/checkbox and verify it is no longer checked on + await cardItem1Cbox.trigger('click'); + expect(wrapper.emitted().click, 'expected click event to have been emitted').toBeTruthy(); + expect(wrapper.emitted()['click'].length).toBe(1); + expect(cardItem1Cbox.element.checked).toBe(false); + }); +});