import { mount } from "@vue/test-utils";
import { describe, it, expect, vi } from "vitest";
import SidebarLink from "@/components/SidebarLink.vue";
describe("SidebarLink.vue", () => {
const defaultProps = {
to: { name: "test-route" },
isCollapsed: false,
};
const RouterLinkStub = {
template: '',
props: ["to", "custom", "navigate", "isActive"],
};
it("renders icon and text slots", () => {
const wrapper = mount(SidebarLink, {
props: defaultProps,
slots: {
icon: 'icon',
text: 'Link Text',
},
global: {
stubs: {
RouterLink: RouterLinkStub,
},
},
});
expect(wrapper.find(".icon").exists()).toBe(true);
expect(wrapper.find(".text").exists()).toBe(true);
expect(wrapper.text()).toContain("Link Text");
});
it("applies collapsed class when isCollapsed is true", () => {
const wrapper = mount(SidebarLink, {
props: { ...defaultProps, isCollapsed: true },
slots: {
icon: 'icon',
text: 'Link Text',
},
global: {
stubs: {
RouterLink: RouterLinkStub,
},
},
});
// v-if="!isCollapsed" means the span with the text won't exist
expect(wrapper.find(".text").exists()).toBe(false);
});
it("emits click event and calls navigate when clicked", async () => {
const navigate = vi.fn();
const wrapper = mount(SidebarLink, {
props: defaultProps,
global: {
stubs: {
RouterLink: {
template: '',
props: ["to", "custom"],
setup() {
return { navigate };
},
},
},
},
});
await wrapper.find("a").trigger("click");
expect(wrapper.emitted("click")).toBeTruthy();
expect(navigate).toHaveBeenCalled();
});
it("applies active classes when isActive is true", () => {
const wrapper = mount(SidebarLink, {
props: defaultProps,
global: {
stubs: {
RouterLink: {
template: '',
props: ["to", "custom"],
},
},
},
});
// Based on SidebarLink.vue line 8: bg-blue-100 text-blue-800 ...
expect(wrapper.find("a").classes()).toContain("bg-blue-100");
});
});