* Added default layout for the site * App is in light mode by default. * App is in light mode by default.
155 lines
5.4 KiB
TypeScript
155 lines
5.4 KiB
TypeScript
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 = '<div class="layout-wrapper"></div>';
|
|
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");
|
|
});
|
|
});
|
|
});
|