From d9a736b6c95f7b7723f8af72b87f44e5baaec187 Mon Sep 17 00:00:00 2001 From: Will Sheldon <114631109+wssheldon@users.noreply.github.com> Date: Mon, 4 Dec 2023 09:37:42 -0800 Subject: [PATCH] Get all items for Pri, Sev, Type, and Project in `SearchPopover` component and add tests (#4079) * Add tests for SearchPopover * Get all items for Pri, Sev, Type, and Project * Remove duplicate menu test * Move itemsPerPage option to onMounted API calls --- .../priority/CasePrioritySearchPopover.vue | 3 +- .../severity/CaseSeveritySearchPopover.vue | 3 +- .../src/case/type/CaseTypeSearchPopover.vue | 3 +- .../src/project/ProjectSearchPopover.vue | 3 +- .../dispatch/src/tests/SearchPopover.spec.js | 213 ++++++++++++++++++ 5 files changed, 221 insertions(+), 4 deletions(-) create mode 100644 src/dispatch/static/dispatch/src/tests/SearchPopover.spec.js diff --git a/src/dispatch/static/dispatch/src/case/priority/CasePrioritySearchPopover.vue b/src/dispatch/static/dispatch/src/case/priority/CasePrioritySearchPopover.vue index e6f40770347d..0c72ad93bba2 100644 --- a/src/dispatch/static/dispatch/src/case/priority/CasePrioritySearchPopover.vue +++ b/src/dispatch/static/dispatch/src/case/priority/CasePrioritySearchPopover.vue @@ -19,7 +19,8 @@ const casePriorities: Ref = ref([]) onMounted(async () => { try { - const response = await CasePriorityApi.getAll() + const options = { itemsPerPage: -1 } + const response = await CasePriorityApi.getAll(options) casePriorities.value = response.data.items.map((item: any) => item.name) } catch (error) { console.error("Error fetching priorities:", error) diff --git a/src/dispatch/static/dispatch/src/case/severity/CaseSeveritySearchPopover.vue b/src/dispatch/static/dispatch/src/case/severity/CaseSeveritySearchPopover.vue index fad86bd0abd3..c5d8ef22589d 100644 --- a/src/dispatch/static/dispatch/src/case/severity/CaseSeveritySearchPopover.vue +++ b/src/dispatch/static/dispatch/src/case/severity/CaseSeveritySearchPopover.vue @@ -19,7 +19,8 @@ const caseSeveritys: Ref = ref([]) onMounted(async () => { try { - const response = await CaseSeverityApi.getAll() + const options = { itemsPerPage: -1 } + const response = await CaseSeverityApi.getAll(options) caseSeveritys.value = response.data.items.map((item: any) => item.name) } catch (error) { console.error("Error fetching case severities:", error) diff --git a/src/dispatch/static/dispatch/src/case/type/CaseTypeSearchPopover.vue b/src/dispatch/static/dispatch/src/case/type/CaseTypeSearchPopover.vue index 8bc5652d823a..a7f47a39cc15 100644 --- a/src/dispatch/static/dispatch/src/case/type/CaseTypeSearchPopover.vue +++ b/src/dispatch/static/dispatch/src/case/type/CaseTypeSearchPopover.vue @@ -19,7 +19,8 @@ const caseTypes: Ref = ref([]) onMounted(async () => { try { - const response = await CaseTypeApi.getAll() + const options = { itemsPerPage: -1 } + const response = await CaseTypeApi.getAll(options) caseTypes.value = response.data.items.map((item: any) => item.name) } catch (error) { console.error("Error fetching case types:", error) diff --git a/src/dispatch/static/dispatch/src/project/ProjectSearchPopover.vue b/src/dispatch/static/dispatch/src/project/ProjectSearchPopover.vue index 86f178a6eeb2..39c3633302d2 100644 --- a/src/dispatch/static/dispatch/src/project/ProjectSearchPopover.vue +++ b/src/dispatch/static/dispatch/src/project/ProjectSearchPopover.vue @@ -20,7 +20,8 @@ const projects: Ref = ref([]) onMounted(async () => { try { - const response = await ProjectApi.getAll() + const options = { itemsPerPage: -1 } + const response = await ProjectApi.getAll(options) projects.value = response.data.items.map((item: any) => item.name) } catch (error) { console.error("Error fetching projects:", error) diff --git a/src/dispatch/static/dispatch/src/tests/SearchPopover.spec.js b/src/dispatch/static/dispatch/src/tests/SearchPopover.spec.js new file mode 100644 index 000000000000..10298707ef96 --- /dev/null +++ b/src/dispatch/static/dispatch/src/tests/SearchPopover.spec.js @@ -0,0 +1,213 @@ +import { mount } from "@vue/test-utils" +import { expect, test } from "vitest" +import { createVuetify } from "vuetify" +import * as components from "vuetify/components" +import * as directives from "vuetify/directives" +import Hotkey from "@/atomics/Hotkey.vue" +import SearchPopover from "@/components/SearchPopover.vue" + +const vuetify = createVuetify({ + components, + directives, +}) + +global.ResizeObserver = require("resize-observer-polyfill") + +test("mounts correctly", () => { + const wrapper = mount(SearchPopover, { + props: { + hotkeys: ["a", "b", "c"], + initialValue: "Initial", + items: ["Item 1", "Item 2", "Item 3"], + label: "Label", + }, + global: { + plugins: [vuetify], + components: { + Hotkey, + }, + }, + }) + + expect(wrapper.exists()).toBe(true) +}) + +test("toggles menu on button click", async () => { + const wrapper = mount(SearchPopover, { + props: { + hotkeys: ["a", "b", "c"], + initialValue: "Initial", + items: ["Item 1", "Item 2", "Item 3"], + label: "Label", + }, + global: { + plugins: [vuetify], + components: { + Hotkey, + }, + }, + }) + + // assert that menu is not visible initially + expect(wrapper.vm.menu).toBe(false) + + // find the button and trigger click event + await wrapper.find(".menu-activator").trigger("click") + + // assert that menu is visible after click + expect(wrapper.vm.menu).toBe(true) +}) + +test("updates selectedItem when selectItem is called", async () => { + const wrapper = mount(SearchPopover, { + props: { + hotkeys: ["a", "b", "c"], + initialValue: "Initial", + items: ["Item 1", "Item 2", "Item 3"], + label: "Label", + }, + global: { + plugins: [vuetify], + components: { + Hotkey, + }, + }, + }) + + // assert that selectedItem is initialValue initially + expect(wrapper.vm.selectedItem).toBe("Initial") + + // call selectItem method + await wrapper.vm.selectItem("Item 2") + + // assert that selectedItem is updated + expect(wrapper.vm.selectedItem).toBe("Item 2") +}) + +test("updates searchQuery when text field input changes", async () => { + const wrapper = mount(SearchPopover, { + props: { + hotkeys: ["a", "b", "c"], + initialValue: "Initial", + items: ["Item 1", "Item 2", "Item 3"], + label: "Label", + }, + global: { + plugins: [vuetify], + components: { + Hotkey, + }, + }, + }) + + // find the button and trigger click event + await wrapper.find(".menu-activator").trigger("click") + + // assert that searchQuery is empty initially + expect(wrapper.vm.searchQuery).toBe("") + + // find the text field and trigger input event + await wrapper.findComponent({ name: "v-text-field" }).setValue("Item 2") + + // assert that searchQuery is updated + expect(wrapper.vm.searchQuery).toBe("Item 2") +}) + +test("filters items based on searchQuery", async () => { + const wrapper = mount(SearchPopover, { + props: { + hotkeys: ["a", "b", "c"], + initialValue: "Initial", + items: ["Apple", "Banana", "Cherry"], + label: "Label", + }, + global: { + plugins: [vuetify], + components: { + Hotkey, + }, + }, + }) + + // find the button and trigger click event + await wrapper.find(".menu-activator").trigger("click") + + // assert that all items are present initially + expect(wrapper.vm.filteredItems).toEqual(["Apple", "Banana", "Cherry"]) + + // simulate user input in the text field + await wrapper.findComponent({ name: "v-text-field" }).setValue("an") + + // assert that items are filtered based on searchQuery + expect(wrapper.vm.filteredItems).toEqual(["Banana"]) +}) + +test("emits item-selected when an item is selected", async () => { + const wrapper = mount(SearchPopover, { + props: { + hotkeys: ["a", "b", "c"], + initialValue: "Initial", + items: ["Apple", "Banana", "Cherry"], + label: "Label", + }, + global: { + plugins: [vuetify], + components: { + Hotkey, + }, + }, + }) + + // call selectItem method + await wrapper.vm.selectItem("Banana") + + // assert that 'item-selected' event is emitted with the correct item + expect(wrapper.emitted()).toHaveProperty("item-selected") + expect(wrapper.emitted()["item-selected"]).toEqual([["Banana"]]) +}) + +test("updates selectedItem when initialValue prop changes", async () => { + const wrapper = mount(SearchPopover, { + props: { + hotkeys: ["a", "b", "c"], + initialValue: "Initial", + items: ["Apple", "Banana", "Cherry"], + label: "Label", + }, + global: { + plugins: [vuetify], + components: { + Hotkey, + }, + }, + }) + + // change initialValue prop + await wrapper.setProps({ initialValue: "New Value" }) + + // assert that selectedItem is updated + expect(wrapper.vm.selectedItem).toBe("New Value") +}) + +test("updates items when items prop changes", async () => { + const wrapper = mount(SearchPopover, { + props: { + hotkeys: ["a", "b", "c"], + initialValue: "Initial", + items: ["Apple", "Banana", "Cherry"], + label: "Label", + }, + global: { + plugins: [vuetify], + components: { + Hotkey, + }, + }, + }) + + // change items prop + await wrapper.setProps({ items: ["Item 1", "Item 2", "Item 3"] }) + + // assert that items is updated + expect(wrapper.vm.items).toEqual(["Item 1", "Item 2", "Item 3"]) +})