auth.test.ts
4.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import { describe, it, expect, vi, beforeEach } from "vitest";
import { useAuthStore } from "@/stores/auth";
// mock API 模块,不发真实请求
vi.mock("@/api/user", () => ({
apiLogin: vi.fn(),
apiRegister: vi.fn(),
apiForgotPassword: vi.fn(),
apiResetPassword: vi.fn(),
apiResendActivation: vi.fn(),
apiProfile: vi.fn(),
apiVerify: vi.fn(),
apiRefreshToken: vi.fn(),
apiLogout: vi.fn(),
}));
vi.mock("@/utils/request.ts", () => ({
service: { defaults: { headers: { common: {} } } },
}));
vi.mock("@/utils/newbieTask", () => ({
triggerNewbieTask: vi.fn(),
}));
import * as userApi from "@/api/user";
const mockApiLogin = vi.mocked(userApi.apiLogin);
const mockApiLogout = vi.mocked(userApi.apiLogout);
const mockApiRefreshToken = vi.mocked(userApi.apiRefreshToken);
beforeEach(() => {
vi.clearAllMocks();
});
describe("useAuthStore - login", () => {
it("格式1(标准格式):正确解析 token 并写入 localStorage", async () => {
mockApiLogin.mockResolvedValue({
data: { token: "abc123", refreshToken: "refresh456" },
} as any);
const store = useAuthStore();
const result = await store.login({ email: "a@b.com", password: "123" });
expect(result.success).toBe(true);
expect(store.token).toBe("abc123");
expect(localStorage.getItem("auth_token")).toBe("abc123");
expect(store.isAuthenticated).toBe(true);
});
it("格式3(嵌套格式):正确解析 token", async () => {
mockApiLogin.mockResolvedValue({
data: { data: { token: "nested123" } },
} as any);
const store = useAuthStore();
const result = await store.login({ email: "a@b.com", password: "123" });
expect(result.success).toBe(true);
expect(store.token).toBe("nested123");
});
it("登录失败:error 有值,loading 恢复 false,isAuthenticated 为 false", async () => {
mockApiLogin.mockRejectedValue({
response: { data: { message: "密码错误" } },
});
const store = useAuthStore();
const result = await store.login({ email: "a@b.com", password: "wrong" });
expect(result.success).toBe(false);
expect(store.error).toBe("密码错误");
expect(store.loading).toBe(false);
expect(store.isAuthenticated).toBe(false);
});
it("登录过程中 loading 为 true,完成后恢复 false", async () => {
let resolveLogin!: (v: any) => void;
mockApiLogin.mockReturnValue(
new Promise((res) => {
resolveLogin = res;
}),
);
const store = useAuthStore();
const loginPromise = store.login({ email: "a@b.com", password: "123" });
expect(store.loading).toBe(true);
resolveLogin({ data: { token: "abc" } });
await loginPromise;
expect(store.loading).toBe(false);
});
});
describe("useAuthStore - logout", () => {
it("logout 后 token、localStorage、user 全部清空", async () => {
mockApiLogin.mockResolvedValue({
data: { token: "abc123", refreshToken: "refresh456" },
} as any);
mockApiLogout.mockResolvedValue({} as any);
const store = useAuthStore();
await store.login({ email: "a@b.com", password: "123" });
store.logout();
expect(store.token).toBe("");
expect(store.isAuthenticated).toBe(false);
expect(store.user).toBeNull();
expect(localStorage.getItem("auth_token")).toBeNull();
});
it("logout 后再初始化 store,LOGOUT_FLAG 阻止读取残留 token", () => {
localStorage.setItem("auth_token", "stale-token");
localStorage.setItem("user_logged_out", "true");
const store = useAuthStore();
expect(store.token).toBe("");
expect(store.isAuthenticated).toBe(false);
});
});
describe("useAuthStore - isAuthenticated", () => {
it("有 token 时为 true", async () => {
mockApiLogin.mockResolvedValue({ data: { token: "abc" } } as any);
const store = useAuthStore();
await store.login({ email: "a@b.com", password: "123" });
expect(store.isAuthenticated).toBe(true);
});
it("无 token 时为 false", () => {
const store = useAuthStore();
expect(store.isAuthenticated).toBe(false);
});
});
describe("useAuthStore - refreshAccessToken", () => {
it("无 refreshToken 时直接返回失败", async () => {
const store = useAuthStore();
const result = await store.refreshAccessToken();
expect(result.success).toBe(false);
expect(result.message).toBe("No refresh token");
});
it("刷新成功后更新 token", async () => {
mockApiRefreshToken.mockResolvedValue({
data: { token: "new-token", refreshToken: "new-refresh" },
} as any);
const store = useAuthStore();
store.refreshToken = "old-refresh" as any;
const result = await store.refreshAccessToken();
expect(result.success).toBe(true);
expect(store.token).toBe("new-token");
expect(localStorage.getItem("auth_token")).toBe("new-token");
});
});