import { afterEach, beforeEach, describe, expect, it } from "vitest"; import { mount, type VueWrapper } from "@vue/test-utils"; import Topbar from "~/layouts/default/Topbar.vue"; describe("Topbar.vue", () => { let wrapper: VueWrapper; beforeEach(() => { document.documentElement.className = ""; document.body.innerHTML = '
'; wrapper = mount(Topbar); }); afterEach(() => { if (wrapper) { wrapper.unmount(); } }); describe("Component Rendering", () => { it("loads without crashing", () => { expect(wrapper.exists()).toBe(true); expect(wrapper.find(".layout-topbar").exists()).toBe(true); }); it("renders the logo image and text", () => { const logo = wrapper.find(".layout-topbar-logo"); expect(logo.exists()).toBe(true); expect(logo.find("img").attributes("alt")).toBe("Two stick silhouettes admiring fireworks in the sky"); expect(logo.text()).toContain("Glowing Fiesta"); }); it("renders the menu toggle button", () => { const menuButton = wrapper.find(".layout-menu-button"); expect(menuButton.exists()).toBe(true); expect(menuButton.find(".pi-bars").exists()).toBe(true); }); it("renders the dark mode toggle button", () => { const darkModeButton = wrapper.find(".layout-topbar-action-highlight"); expect(darkModeButton.exists()).toBe(true); }); it("renders the topbar menu items", () => { const menuButtons = wrapper.findAll(".layout-topbar-menu button"); expect(menuButtons).toHaveLength(3); expect(menuButtons[0].text()).toContain("Calendar"); expect(menuButtons[1].text()).toContain("Messages"); expect(menuButtons[2].text()).toContain("Profile"); }); }); describe("Dark Mode Toggle", () => { it("starts with sun icon (light mode)", () => { const darkModeButton = wrapper.find(".layout-topbar-action-highlight"); expect(darkModeButton.find(".pi-sun").exists()).toBe(true); expect(darkModeButton.find(".pi-moon").exists()).toBe(false); }); it("toggles to moon icon when clicked", async () => { const darkModeButton = wrapper.find(".layout-topbar-action-highlight"); await darkModeButton.trigger("click"); expect(darkModeButton.find(".pi-moon").exists()).toBe(true); expect(darkModeButton.find(".pi-sun").exists()).toBe(false); }); it("removes app-dark class when toggled off", async () => { expect(document.documentElement.classList.contains("app-dark")).toBe(false); const darkModeButton = wrapper.find(".layout-topbar-action-highlight"); // Toggle on await darkModeButton.trigger("click"); expect(document.documentElement.classList.contains("app-dark")).toBe(true); // Toggle off await darkModeButton.trigger("click"); expect(document.documentElement.classList.contains("app-dark")).toBe(false); }); it("updates isDarkTheme ref when toggled", async () => { const darkModeButton = wrapper.find(".layout-topbar-action-highlight"); expect(wrapper.vm.isDarkTheme).toBe(false); await darkModeButton.trigger("click"); expect(wrapper.vm.isDarkTheme).toBe(true); await darkModeButton.trigger("click"); expect(wrapper.vm.isDarkTheme).toBe(false); }); }); describe("Menu Toggle", () => { it("toggles layout-static-inactive class on layout wrapper", async () => { const menuButton = wrapper.find(".layout-menu-button"); const layoutWrapper = document.querySelector(".layout-wrapper"); expect(layoutWrapper?.classList.contains("layout-static-inactive")).toBe(false); await menuButton.trigger("click"); expect(layoutWrapper?.classList.contains("layout-static-inactive")).toBe(true); await menuButton.trigger("click"); expect(layoutWrapper?.classList.contains("layout-static-inactive")).toBe(false); }); it("handles missing layout wrapper gracefully", async () => { document.body.innerHTML = ""; const menuButton = wrapper.find(".layout-menu-button"); // Should not throw error expect(() => menuButton.trigger("click")).not.toThrow(); }); }); describe("Logo Link", () => { it("links to home page", () => { const logoLink = wrapper.find(".layout-topbar-logo"); expect(logoLink.exists()).toBe(true); }); it("has correct image source", () => { const img = wrapper.find(".layout-topbar-logo img"); expect(img.attributes("src")).toContain("logo.png"); }); }); describe("Topbar Actions", () => { it("renders Calendar action button with icon", () => { const buttons = wrapper.findAll(".layout-topbar-menu button"); const calendarButton = buttons[0]; expect(calendarButton.find(".pi-calendar").exists()).toBe(true); expect(calendarButton.text()).toContain("Calendar"); }); it("renders Messages action button with icon", () => { const buttons = wrapper.findAll(".layout-topbar-menu button"); const messagesButton = buttons[1]; expect(messagesButton.find(".pi-inbox").exists()).toBe(true); expect(messagesButton.text()).toContain("Messages"); }); it("renders Profile action button with icon", () => { const buttons = wrapper.findAll(".layout-topbar-menu button"); const profileButton = buttons[2]; expect(profileButton.find(".pi-user").exists()).toBe(true); expect(profileButton.text()).toContain("Profile"); }); }); });