// The Lucia project. // Copyright 2026-2026 DSP, inc. All rights reserved. // Authors: // imacat.yang@dsp.im (imacat), 2026/03/05 import { describe, it, expect, beforeEach, vi } from "vitest"; import { mount } from "@vue/test-utils"; import { setActivePinia, createPinia } from "pinia"; vi.mock("@/module/apiError.js", () => ({ default: vi.fn(), })); const mockRoute = vi.hoisted(() => ({ query: {}, })); vi.mock("vue-router", () => ({ useRoute: () => mockRoute, })); import Login from "@/views/Login/LoginPage.vue"; import { useLoginStore } from "@/stores/login"; describe("Login", () => { let pinia; beforeEach(() => { pinia = createPinia(); setActivePinia(pinia); mockRoute.query = {}; }); const mountLogin = (options = {}) => { if (options.route?.query) { Object.assign(mockRoute.query, options.route.query); } return mount(Login, { global: { plugins: [pinia], }, }); }; it("renders login form", () => { const wrapper = mountLogin(); expect(wrapper.find("h2").text()).toBe("LOGIN"); expect(wrapper.find("#account").exists()).toBe(true); expect(wrapper.find("#password").exists()).toBe(true); }); it("has disabled login button when fields are empty", () => { const wrapper = mountLogin(); const btn = wrapper.find("#login_btn_main_btn"); expect(btn.attributes("disabled")).toBeDefined(); }); it("enables login button when both fields have values", async () => { const wrapper = mountLogin(); const store = useLoginStore(); store.auth.username = "user"; store.auth.password = "pass"; await wrapper.vm.$nextTick(); const btn = wrapper.find("#login_btn_main_btn"); expect(btn.attributes("disabled")).toBeUndefined(); }); it("shows error message when isInvalid", async () => { const wrapper = mountLogin(); const store = useLoginStore(); store.isInvalid = true; await wrapper.vm.$nextTick(); expect(wrapper.text()).toContain("Incorrect account or password"); }); it("toggles password visibility", async () => { const wrapper = mountLogin(); const store = useLoginStore(); store.auth.password = "secret"; await wrapper.vm.$nextTick(); const pwdInput = wrapper.find("#password"); expect(pwdInput.attributes("type")).toBe("password"); // Click the eye icon to toggle const eyeToggle = wrapper.find( 'label[for="passwordt"] span.cursor-pointer', ); if (eyeToggle.exists()) { await eyeToggle.trigger("click"); await wrapper.vm.$nextTick(); expect(pwdInput.attributes("type")).toBe("text"); } }); it("stores return-to URL from route query", () => { const wrapper = mountLogin({ route: { query: { "return-to": "encodedUrl" } }, }); const store = useLoginStore(); expect(store.rememberedReturnToUrl).toBe("encodedUrl"); }); });