登录页UI及长时间未操作锁定逻辑优化
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { createPinia, setActivePinia } from "pinia";
|
||||
|
||||
vi.mock("../router", () => ({
|
||||
default: {
|
||||
replace: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock("../api/authClient", () => ({
|
||||
extendToken: vi.fn(),
|
||||
unlockSession: vi.fn(),
|
||||
}));
|
||||
|
||||
describe("session manager idle recovery", () => {
|
||||
beforeEach(() => {
|
||||
vi.resetModules();
|
||||
vi.useFakeTimers();
|
||||
setActivePinia(createPinia());
|
||||
const storage = (() => {
|
||||
const data = new Map<string, string>();
|
||||
return {
|
||||
getItem: (key: string) => data.get(key) ?? null,
|
||||
setItem: (key: string, value: string) => {
|
||||
data.set(key, String(value));
|
||||
},
|
||||
removeItem: (key: string) => {
|
||||
data.delete(key);
|
||||
},
|
||||
clear: () => {
|
||||
data.clear();
|
||||
},
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(window, "localStorage", {
|
||||
value: storage,
|
||||
configurable: true,
|
||||
});
|
||||
Object.defineProperty(window, "sessionStorage", {
|
||||
value: storage,
|
||||
configurable: true,
|
||||
});
|
||||
Object.defineProperty(window, "BroadcastChannel", {
|
||||
value: class {
|
||||
onmessage: ((event: MessageEvent) => void) | null = null;
|
||||
postMessage() {}
|
||||
close() {}
|
||||
},
|
||||
configurable: true,
|
||||
});
|
||||
});
|
||||
|
||||
it("locks instead of refreshing activity after long inactivity when user activity resumes", async () => {
|
||||
vi.setSystemTime(new Date("2026-03-10T01:00:00.000Z"));
|
||||
const { useSessionStore } = await import("../store/session");
|
||||
const { IDLE_TIMEOUT_MINUTES, AUTO_LOGOUT_TIMEOUT_HOURS, markUserActive } = await import("./sessionManager");
|
||||
const session = useSessionStore();
|
||||
const oldTs = Date.now() - (IDLE_TIMEOUT_MINUTES * 60 * 1000 + 1_000);
|
||||
|
||||
session.recordUserActivity(oldTs);
|
||||
session.recordNetworkActivity(oldTs);
|
||||
|
||||
markUserActive(Date.now());
|
||||
|
||||
expect(session.locked).toBe(true);
|
||||
expect(session.lockReason).toBe("idle");
|
||||
expect(session.lockAutoLogoutDeadlineAt).toBe(oldTs + AUTO_LOGOUT_TIMEOUT_HOURS * 60 * 60 * 1000);
|
||||
});
|
||||
|
||||
it("locks instead of refreshing activity after long inactivity when network activity resumes", async () => {
|
||||
vi.setSystemTime(new Date("2026-03-10T01:00:00.000Z"));
|
||||
const { useSessionStore } = await import("../store/session");
|
||||
const { IDLE_TIMEOUT_MINUTES, AUTO_LOGOUT_TIMEOUT_HOURS, markNetworkActive } = await import("./sessionManager");
|
||||
const session = useSessionStore();
|
||||
const oldTs = Date.now() - (IDLE_TIMEOUT_MINUTES * 60 * 1000 + 1_000);
|
||||
|
||||
session.recordUserActivity(oldTs);
|
||||
session.recordNetworkActivity(oldTs);
|
||||
|
||||
markNetworkActive(Date.now());
|
||||
|
||||
expect(session.locked).toBe(true);
|
||||
expect(session.lockReason).toBe("idle");
|
||||
expect(session.lockAutoLogoutDeadlineAt).toBe(oldTs + AUTO_LOGOUT_TIMEOUT_HOURS * 60 * 60 * 1000);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user