parent
7b34c27290
commit
0cec9f5afd
123 changed files with 4685 additions and 3607 deletions
|
|
@ -1,11 +1,186 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import { mount, type VueWrapper } from "@vue/test-utils";
|
||||
import Sidebar from "~/layouts/default/Sidebar.vue";
|
||||
import { mount } from "@vue/test-utils";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import SidebarLayout from "~/layouts/default/Sidebar.vue";
|
||||
import { ref } from "vue";
|
||||
import type * as SidebarUI from "~/components/ui/sidebar";
|
||||
|
||||
describe("Sidebar.vue", () => {
|
||||
it("loads without crashing", () => {
|
||||
const wrapper: VueWrapper = mount(Sidebar, {});
|
||||
expect(wrapper.exists()).toBe(true);
|
||||
expect(wrapper.find(".layout-sidebar").exists()).toBe(true);
|
||||
const { useSidebarMock } = vi.hoisted(() => ({
|
||||
useSidebarMock: vi.fn(),
|
||||
}));
|
||||
|
||||
// Mock the UI components and hook
|
||||
vi.mock("~/components/ui/sidebar", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof SidebarUI>();
|
||||
const { ref } = await import("vue");
|
||||
const MockComponent = {
|
||||
template: "<div><slot /></div>",
|
||||
inheritAttrs: false,
|
||||
};
|
||||
|
||||
// Default implementation
|
||||
useSidebarMock.mockReturnValue({
|
||||
isMobile: ref(false),
|
||||
state: ref("expanded"),
|
||||
openMobile: ref(false),
|
||||
setOpenMobile: vi.fn(),
|
||||
});
|
||||
|
||||
return {
|
||||
...actual,
|
||||
Sidebar: MockComponent,
|
||||
SidebarContent: MockComponent,
|
||||
SidebarFooter: MockComponent,
|
||||
SidebarGroup: MockComponent,
|
||||
SidebarHeader: MockComponent,
|
||||
SidebarMenu: MockComponent,
|
||||
SidebarMenuItem: MockComponent,
|
||||
SidebarMenuButton: MockComponent,
|
||||
SidebarRail: MockComponent,
|
||||
SidebarMenuSub: MockComponent,
|
||||
SidebarMenuSubButton: MockComponent,
|
||||
SidebarMenuSubItem: MockComponent,
|
||||
useSidebar: useSidebarMock,
|
||||
};
|
||||
});
|
||||
|
||||
// Mock other UI components to avoid rendering complexity
|
||||
vi.mock("~/components/ui/dropdown-menu", () => {
|
||||
const MockComponent = { template: "<div><slot /></div>" };
|
||||
return {
|
||||
DropdownMenu: MockComponent,
|
||||
DropdownMenuContent: MockComponent,
|
||||
DropdownMenuGroup: MockComponent,
|
||||
DropdownMenuItem: MockComponent,
|
||||
DropdownMenuLabel: MockComponent,
|
||||
DropdownMenuSeparator: MockComponent,
|
||||
DropdownMenuTrigger: MockComponent,
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("~/components/ui/collapsible", () => {
|
||||
const MockComponent = { template: "<div><slot /></div>" };
|
||||
return {
|
||||
Collapsible: MockComponent,
|
||||
CollapsibleContent: MockComponent,
|
||||
CollapsibleTrigger: MockComponent,
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("~/components/ui/avatar", () => {
|
||||
const MockComponent = { template: "<div><slot /></div>" };
|
||||
return {
|
||||
Avatar: MockComponent,
|
||||
AvatarFallback: MockComponent,
|
||||
AvatarImage: MockComponent,
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("@/components/ui/sheet", () => {
|
||||
const MockComponent = { template: "<div><slot /></div>" };
|
||||
return {
|
||||
Sheet: MockComponent,
|
||||
SheetContent: MockComponent,
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("@/components/ui/sheet/SheetDescription.vue", () => ({
|
||||
default: { template: "<div><slot /></div>" },
|
||||
}));
|
||||
vi.mock("@/components/ui/sheet/SheetHeader.vue", () => ({
|
||||
default: { template: "<div><slot /></div>" },
|
||||
}));
|
||||
vi.mock("lucide-vue-next", () => {
|
||||
const MockIcon = { template: '<svg class="lucide-mock" />' };
|
||||
return {
|
||||
BadgeCheck: MockIcon,
|
||||
Bell: MockIcon,
|
||||
ChevronRight: MockIcon,
|
||||
ChevronsUpDown: MockIcon,
|
||||
CreditCard: MockIcon,
|
||||
BookOpen: MockIcon,
|
||||
HandCoins: MockIcon,
|
||||
LogOut: MockIcon,
|
||||
Settings2: MockIcon,
|
||||
Sparkles: MockIcon,
|
||||
SquareTerminal: MockIcon,
|
||||
};
|
||||
});
|
||||
|
||||
describe("SidebarLayout", () => {
|
||||
it("renders the header correctly", () => {
|
||||
useSidebarMock.mockReturnValue({
|
||||
isMobile: ref(false),
|
||||
state: ref("expanded"),
|
||||
openMobile: ref(false),
|
||||
setOpenMobile: vi.fn(),
|
||||
});
|
||||
|
||||
const wrapper = mount(SidebarLayout, {
|
||||
props: {
|
||||
collapsible: "icon",
|
||||
},
|
||||
});
|
||||
expect(wrapper.text()).toContain("Glowing Fiesta");
|
||||
expect(wrapper.text()).toContain("v1.0.0");
|
||||
});
|
||||
|
||||
it("renders sidebar content correctly", () => {
|
||||
const wrapper = mount(SidebarLayout);
|
||||
const text = wrapper.text();
|
||||
|
||||
// Navigation groups
|
||||
expect(text).toContain("Playground");
|
||||
expect(text).toContain("Documentation");
|
||||
expect(text).toContain("Settings");
|
||||
|
||||
// User information
|
||||
expect(text).toContain("Liviu");
|
||||
expect(text).toContain("x.liviu@gmail.com");
|
||||
|
||||
// Sub-items
|
||||
expect(text).toContain("History");
|
||||
expect(text).toContain("Starred");
|
||||
expect(text).toContain("Introduction");
|
||||
expect(text).toContain("Get Started");
|
||||
});
|
||||
|
||||
it("does not render icon if item.icon is missing", () => {
|
||||
const wrapper = mount(SidebarLayout, {
|
||||
props: {
|
||||
navItems: [
|
||||
{
|
||||
title: "No Icon Item",
|
||||
url: "#",
|
||||
items: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.text()).toContain("No Icon Item");
|
||||
expect(wrapper.find('[data-testid="sidebar-icon"]').exists()).toBe(false);
|
||||
});
|
||||
|
||||
it("renders correctly in mobile view", () => {
|
||||
useSidebarMock.mockReturnValue({
|
||||
isMobile: ref(true),
|
||||
state: ref("expanded"),
|
||||
openMobile: ref(true),
|
||||
setOpenMobile: vi.fn(),
|
||||
});
|
||||
|
||||
const wrapper = mount(SidebarLayout);
|
||||
|
||||
// When isMobile is true, it renders a Sheet.
|
||||
// Since we mocked Sheet components as simple divs with slots, the content should still be present.
|
||||
// However, the structure is different.
|
||||
// We can verify that the content is still rendered (passed through the slot).
|
||||
const text = wrapper.text();
|
||||
expect(text).toContain("Glowing Fiesta");
|
||||
expect(text).toContain("Liviu");
|
||||
|
||||
// Check specific specific mock interaction if needed, or just that it doesn't crash
|
||||
// and renders the menu items.
|
||||
expect(text).toContain("Playground");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue