Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ export default {
let total = ref(0)
const search = ref(props.initialValue.name)

let debouncedGetIndividualData = null

const getIndividualData = async (searchVal, page = currentPage.value) => {
loading.value = true
let filterOptions = {
Expand Down Expand Up @@ -115,8 +113,11 @@ export default {
loading.value = false
}

// Created here, not in onMounted: v-autocomplete syncs its search model while
// it mounts, so the watcher below can run before the parent's onMounted hook.
const debouncedGetIndividualData = debounce(getIndividualData, 300)

onMounted(() => {
debouncedGetIndividualData = debounce(getIndividualData, 300)
debouncedGetIndividualData(search.value)
})

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { flushPromises, mount } from "@vue/test-utils"
import { afterEach, beforeEach, expect, test, vi } from "vitest"
import { createVuetify } from "vuetify"
import * as components from "vuetify/components"
import * as directives from "vuetify/directives"

const getAll = vi.fn(() => Promise.resolve({ data: { items: [], total: 0 } }))
vi.mock("@/individual/api", () => ({ default: { getAll: (...args) => getAll(...args) } }))

import ParticipantSelect from "@/components/ParticipantSelect.vue"

const vuetify = createVuetify({ components, directives })

beforeEach(() => {
vi.useFakeTimers()
getAll.mockClear()
})
afterEach(() => vi.useRealTimers())

test("a search change before onMounted still queries individuals instead of throwing", async () => {
const errors = []
const onRejection = (event) => errors.push(event.reason)
window.addEventListener("unhandledrejection", onRejection)

// v-autocomplete syncs its search model while it mounts, which is before the
// parent's onMounted hook: the debounced loader must already exist by then.
const wrapper = mount(ParticipantSelect, {
props: { modelValue: [] },
global: { plugins: [vuetify], config: { errorHandler: (e) => errors.push(e) } },
})
await flushPromises()
vi.advanceTimersByTime(300)
await flushPromises()
window.removeEventListener("unhandledrejection", onRejection)

expect(errors.map(String)).toEqual([])
expect(getAll).toHaveBeenCalled()
wrapper.unmount()
})
Loading