import { describe, it, expect, vi, beforeEach } from "vitest";
import { mount } from "@vue/test-utils";
import { setActivePinia, createPinia } from "pinia";
import { useFavoritesStore } from "../../../../stores/favorites";
import AreaTreeNode from "../AreaTreeNode.vue";
const pushMock = vi.fn();
vi.mock("vue-router", () => ({
useRouter: () => ({ push: pushMock }),
}));
describe("AreaTreeNode", () => {
beforeEach(() => {
setActivePinia(createPinia());
pushMock.mockClear();
});
function makeArea(overrides = {}) {
return {
id: 1,
display_name: "Kitchen",
type: "room",
alias: "kitchen",
parent_id: 0,
children: [],
...overrides,
};
}
it("renders area info", () => {
const wrapper = mount(AreaTreeNode, {
props: { area: makeArea() },
});
expect(wrapper.text()).toContain("Kitchen");
expect(wrapper.text()).toContain("room");
expect(wrapper.text()).toContain("kitchen");
});
it("renders children when expanded", async () => {
const area = makeArea({
children: [
{ id: 2, display_name: "Pantry", type: "room", alias: "pantry", parent_id: 1, children: [] },
],
});
const wrapper = mount(AreaTreeNode, {
props: { area },
});
expect(wrapper.text()).not.toContain("Pantry");
await wrapper.find(".tree-toggle").trigger("click");
expect(wrapper.text()).toContain("Pantry");
});
it("navigates to area detail on card click", () => {
const wrapper = mount(AreaTreeNode, {
props: { area: makeArea() },
});
wrapper.find(".area-tree-card").trigger("click");
expect(pushMock).toHaveBeenCalledWith({
name: "area-detail",
params: { id: "1" },
});
});
it("does not navigate when clicking toggle", () => {
const wrapper = mount(AreaTreeNode, {
props: { area: makeArea({ children: [{ id: 2, display_name: "Child", type: "room", alias: "child", parent_id: 1, children: [] }] }) },
});
wrapper.find(".tree-toggle").trigger("click");
expect(pushMock).not.toHaveBeenCalled();
});
it("disables toggle button for leaf nodes", () => {
const wrapper = mount(AreaTreeNode, {
props: { area: makeArea() },
});
const toggle = wrapper.find(".tree-toggle");
expect(toggle.attributes("disabled")).toBeDefined();
expect(toggle.text()).toBe("ยท");
});
it("shows cycle message when area is its own ancestor", () => {
const wrapper = mount(AreaTreeNode, {
props: { area: makeArea({ id: 1 }), ancestors: ["1"] },
});
expect(wrapper.text()).toContain("Cycle skipped");
});
it("toggles favorite via store", () => {
const store = useFavoritesStore();
const wrapper = mount(AreaTreeNode, {
props: { area: makeArea() },
});
expect(store.has(1)).toBe(false);
wrapper.findAll("button").find((btn) => btn.text().includes("Star"))?.trigger("click");
expect(store.has(1)).toBe(true);
});
});