import { getLocalVue } from "@tests/vitest/helpers"; import { mount } from "@vue/test-utils"; import flushPromises from "flush-promises"; import { createPinia, setActivePinia } from "pinia"; import { describe, expect, it, vi } from "vitest"; import { useServerMock } from "@/api/client/__mocks__"; import RoleForm from "./RoleForm.vue"; const { server, http } = useServerMock(); const localVue = getLocalVue(); const mockPush = vi.fn(); vi.mock("vue-router/composables", () => ({ useRouter: () => ({ push: (...args) => mockPush(...args), }), })); vi.mock("@/composables/filter/filter.js", () => { const { ref } = require("vue"); return { useFilterObjectArray: () => ref([]), }; }); function mountTarget() { setActivePinia(createPinia()); return mount(RoleForm, { localVue, stubs: { FontAwesomeIcon: true, FormSelection: true, BButton: true, BAlert: true, }, directives: { localize: () => {}, }, }); } describe("RoleForm.vue", () => { it("renders loading spinner initially", async () => { const wrapper = mountTarget(); expect(wrapper.findComponent({ name: "LoadingSpan" }).exists()).toBe(true); await flushPromises(); expect(wrapper.findComponent({ name: "LoadingSpan" }).exists()).toBe(false); }); it("shows error alert if groups fetch fails", async () => { server.use(http.get("/api/groups", ({ response }) => response(500).json({ err_msg: "Groups failed" }))); const wrapper = mountTarget(); await flushPromises(); const alert = wrapper.findComponent({ name: "BAlert" }); expect(alert.exists()).toBe(true); expect(alert.text()).toContain("Groups failed"); }); it("shows error alert if roles fetch fails", async () => { server.use(http.get("/api/groups", ({ response }) => response(200).json([{ id: "g1", name: "Group 1" }]))); server.use(http.get("/api/roles", ({ response }) => response(500).json({ err_msg: "Roles failed" }))); const wrapper = mountTarget(); await flushPromises(); const alert = wrapper.findComponent({ name: "BAlert" }); expect(alert.exists()).toBe(true); expect(alert.text()).toContain("Roles failed"); }); it("shows validation error if required fields are missing", async () => { server.use(http.get("/api/groups", ({ response }) => response(200).json([]))); server.use(http.get("/api/roles", ({ response }) => response(200).json([]))); const wrapper = mountTarget(); await flushPromises(); await wrapper.find("#role-submit").trigger("click"); await flushPromises(); const alert = wrapper.findComponent({ name: "BAlert" }); expect(alert.exists()).toBe(true); expect(alert.text()).toContain("Please complete all required inputs."); }); it("submits with correct data", async () => { server.use(http.get("/api/groups", ({ response }) => response(200).json([{ id: "g1", name: "Group 1" }]))); server.use(http.get("/api/roles", ({ response }) => response(200).json([{ id: "u1", name: "User 1" }]))); server.use( http.post("/api/roles", async ({ request, response }) => { const body = await request.json(); expect(body.name).toBe("Test Role"); expect(body.description).toBe("Test Description"); expect(body.group_ids).toEqual(["g1"]); expect(body.user_ids).toEqual(["u1"]); return response(200).json({ id: "new-role" }); }), ); const wrapper = mountTarget(); await flushPromises(); await wrapper.find("#role-name").setValue("Test Role"); await wrapper.find("#role-description").setValue("Test Description"); wrapper.vm.groupIds = ["g1"]; wrapper.vm.userIds = ["u1"]; await wrapper.find("#role-submit").trigger("click"); await flushPromises(); expect(mockPush).toHaveBeenCalledWith("/admin/roles"); }); it("shows API error if creation fails", async () => { server.use(http.get("/api/groups", ({ response }) => response(200).json([]))); server.use(http.get("/api/roles", ({ response }) => response(200).json([]))); server.use(http.post("/api/roles", ({ response }) => response(400).json({ err_msg: "Creation failed" }))); const wrapper = mountTarget(); await flushPromises(); await wrapper.find("#role-name").setValue("Bad Role"); await wrapper.find("#role-description").setValue("Bad Description"); await wrapper.find("#role-submit").trigger("click"); await flushPromises(); const alert = wrapper.findComponent({ name: "BAlert" }); expect(alert.exists()).toBe(true); expect(alert.text()).toContain("Failed to create role"); }); });