import { getLocalVue } from "@tests/vitest/helpers"; import { mount, type Wrapper } from "@vue/test-utils"; import flushPromises from "flush-promises"; import { beforeEach, describe, expect, it } from "vitest"; import { useServerMock } from "@/api/client/__mocks__"; import type { BrowsableFilesSourcePlugin, CreatedEntry } from "@/api/remoteFiles"; import RDMDestinationSelector from "./RDMDestinationSelector.vue"; import FilesInput from "@/components/FilesDialog/FilesInput.vue"; const localVue = getLocalVue(true); const CREATE_RECORD_BTN = "#create-record-button"; const FAKE_RDM_SOURCE_URI = "gxfiles://test-uri"; const FAKE_RDM_EXISTING_RECORD_URI = "gxfiles://test-uri/test-record"; const FAKE_RECORD_NAME = "test record name"; const FAKE_ENTRY: CreatedEntry = { uri: FAKE_RDM_SOURCE_URI, name: FAKE_RECORD_NAME, external_link: "http://example.com", }; const { server, http } = useServerMock(); async function initWrapper(fileSource?: BrowsableFilesSourcePlugin) { server.use( http.post("/api/remote_files", ({ response }) => { return response(200).json(FAKE_ENTRY); }), ); const wrapper = mount(RDMDestinationSelector as object, { propsData: { fileSource, }, localVue, }); await flushPromises(); return wrapper; } describe("RDMDestinationSelector", () => { let wrapper: Wrapper; beforeEach(async () => { wrapper = await initWrapper(); }); describe("Select new record", () => { beforeEach(async () => { await selectExportChoice("new"); }); it("enables the create new record button when the required fields are filled in", async () => { expect(wrapper.find(CREATE_RECORD_BTN).attributes("aria-disabled")).toBeTruthy(); await setRecordNameInput(FAKE_RECORD_NAME); await setRDMSourceInput(FAKE_RDM_SOURCE_URI); expect(wrapper.find(CREATE_RECORD_BTN).attributes("aria-disabled")).toBeFalsy(); }); it("emits onRecordSelected when the create new record button is clicked", async () => { expect(wrapper.emitted("onRecordSelected")).toBeFalsy(); await setRecordNameInput(FAKE_RECORD_NAME); await setRDMSourceInput(FAKE_RDM_SOURCE_URI); await clickCreateNewRecordButton(); const emitted = wrapper.emitted("onRecordSelected"); expect(emitted).toBeTruthy(); expect(emitted?.at(0)[0]).toEqual(FAKE_ENTRY.uri); }); }); describe("Select existing record", () => { beforeEach(async () => { await selectExportChoice("existing"); }); it("emits onRecordSelected event when the existing record is selected", async () => { expect(wrapper.emitted("onRecordSelected")).toBeFalsy(); await setRDMDirectoryInput(FAKE_RDM_EXISTING_RECORD_URI); const emitted = wrapper.emitted("onRecordSelected"); expect(emitted).toBeTruthy(); expect(emitted?.at(0)[0]).toEqual(FAKE_RDM_EXISTING_RECORD_URI); }); }); describe("Pre-select specific File Source", () => { const PRESELECTED_FILE_SOURCE_ID = "test-file-source"; const PRESELECTED_FILE_SOURCE_URI = "gxfiles://preselected-file-source"; beforeEach(async () => { const specificFileSource: BrowsableFilesSourcePlugin = { id: PRESELECTED_FILE_SOURCE_ID, label: "Test File Source", doc: "Test File Source Description", uri_root: PRESELECTED_FILE_SOURCE_URI, writable: true, browsable: true, type: "rdm", supports: { pagination: false, search: false, sorting: false, }, }; wrapper = await initWrapper(specificFileSource); }); describe("Select new record", () => { beforeEach(async () => { await selectExportChoice("new", PRESELECTED_FILE_SOURCE_ID); }); it("enables the create new record button only by setting the record name", async () => { expect(wrapper.find(CREATE_RECORD_BTN).attributes("aria-disabled")).toBeTruthy(); await setRecordNameInput(FAKE_RECORD_NAME); expect(wrapper.find(CREATE_RECORD_BTN).attributes("aria-disabled")).toBeFalsy(); }); it("emits onRecordSelected event when the create new record button is clicked", async () => { expect(wrapper.emitted("onRecordSelected")).toBeFalsy(); await setRecordNameInput(FAKE_RECORD_NAME); await clickCreateNewRecordButton(); const emitted = wrapper.emitted("onRecordSelected"); expect(emitted).toBeTruthy(); expect(emitted?.at(0)[0]).toEqual(FAKE_ENTRY.uri); }); }); describe("Select existing record", () => { beforeEach(async () => { await selectExportChoice("existing", PRESELECTED_FILE_SOURCE_ID); }); it("emits onRecordSelected event when the existing record is selected", async () => { expect(wrapper.emitted("onRecordSelected")).toBeFalsy(); const fakeRecordUri = `${PRESELECTED_FILE_SOURCE_URI}/preselected-test-record`; await setRDMDirectoryInput(fakeRecordUri); const emitted = wrapper.emitted("onRecordSelected"); expect(emitted).toBeTruthy(); expect(emitted?.at(0)[0]).toEqual(fakeRecordUri); }); }); }); async function selectExportChoice(choice: string, fileSourceId?: string) { const suffix = fileSourceId ? `${fileSourceId}` : "any"; const exportChoice = wrapper.find(`#radio-${choice}-${suffix}`); await exportChoice.setChecked(true); } async function setRDMSourceInput(newValue: string) { const component = wrapper.findComponent(FilesInput); expect(component.attributes("placeholder")).toContain("source"); component.vm.$emit("input", newValue); await flushPromises(); } async function setRDMDirectoryInput(newValue: string) { const component = wrapper.findComponent(FilesInput); expect(component.attributes("placeholder")).toContain("directory"); component.vm.$emit("input", newValue); await flushPromises(); } async function setRecordNameInput(newValue: string) { const recordNameInput = wrapper.find("#record-name-input"); await recordNameInput.setValue(newValue); } async function clickCreateNewRecordButton() { const createRecordButton = wrapper.find(CREATE_RECORD_BTN); expect(createRecordButton.attributes("aria-disabled")).toBeFalsy(); await createRecordButton.trigger("click"); await flushPromises(); } });