// The Lucia project. // Copyright 2026-2026 DSP, inc. All rights reserved. // Authors: // imacat.yang@dsp.im (imacat), 2026/03/06 import { describe, it, expect, beforeEach, vi } from "vitest"; import { setActivePinia, createPinia } from "pinia"; // Mock all heavy imports that MainContainer.vue pulls in vi.mock("@/stores/loading", () => ({ useLoadingStore: () => ({ isLoading: false }), })); vi.mock("@/stores/allMapData", () => ({ useAllMapDataStore: () => ({}), })); vi.mock("@/stores/conformance", () => ({ useConformanceStore: () => ({}), })); vi.mock("@/stores/pageAdmin", () => ({ usePageAdminStore: () => ({}), })); vi.mock("@/module/alertModal.js", () => ({ leaveFilter: vi.fn(), leaveConformance: vi.fn(), })); vi.mock("@/module/apiError.js", () => ({ default: vi.fn(), })); vi.mock("@/router/index.ts", () => ({ default: { push: vi.fn(), currentRoute: { value: { path: "/" } } }, })); vi.mock("@/module/cytoscapeMap.js", () => ({})); import { useLoginStore } from "@/stores/login"; import * as cookieUtil from "@/utils/cookieUtil.js"; // Import the component definition to access beforeRouteEnter import MainContainer from "@/views/MainContainer.vue"; describe("MainContainer beforeRouteEnter", () => { let loginStore; let next; beforeEach(() => { setActivePinia(createPinia()); loginStore = useLoginStore(); loginStore.$router = { push: vi.fn() }; next = vi.fn(); vi.clearAllMocks(); // Clear cookies document.cookie.split(";").forEach((c) => { const name = c.split("=")[0].trim(); if (name) { document.cookie = name + "=; Max-Age=-99999999; path=/"; } }); }); const callGuard = () => { const guard = MainContainer.beforeRouteEnter; return guard({}, {}, next); }; it("calls next() after successful refreshToken", async () => { // Not logged in, but has refresh token document.cookie = "luciaRefreshToken=some-token"; vi.spyOn(loginStore, "refreshToken").mockResolvedValue(); await callGuard(); expect(loginStore.refreshToken).toHaveBeenCalled(); expect(next).toHaveBeenCalled(); }); it("redirects to login when refreshToken fails", async () => { // Not logged in, has refresh token, but refresh fails document.cookie = "luciaRefreshToken=some-token"; vi.spyOn(loginStore, "refreshToken").mockRejectedValue(new Error("401")); await callGuard(); expect(next).toHaveBeenCalledWith( expect.objectContaining({ path: "/login" }), ); }); it("calls next() when logged-in marker and access token both exist", async () => { document.cookie = "isLuciaLoggedIn=true"; document.cookie = "luciaToken=token"; await callGuard(); expect(next).toHaveBeenCalled(); }); it("redirects to login when logged-in marker exists without access token", async () => { document.cookie = "isLuciaLoggedIn=true"; await callGuard(); expect(next).toHaveBeenCalledWith( expect.objectContaining({ path: "/login" }), ); }); it("stores a relative return-to path when redirecting to login", async () => { window.history.replaceState( {}, "", "/discover/log/1/map?view=summary#node-2", ); await callGuard(); const redirectArg = next.mock.calls[0][0]; const returnTo = redirectArg.query["return-to"]; expect(atob(returnTo)).toBe("/discover/log/1/map?view=summary#node-2"); }); });