Files
first-electron-app/tests/unit/auth.test.ts
Misaka_Company cae0b845ac first commit
2026-02-28 14:11:35 +08:00

100 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { AuthService } from '../../src/main/services/authService';
import { chromium } from 'playwright-core';
import { ENV } from '../../src/main/config/env'; // <-- 引入 ENV 对象
// 深度 Mock playwright-core显式声明返回 any 绕过 TS 严格模式检查
vi.mock('playwright-core', (): any => {
const mockFrame = {
locator: vi.fn().mockReturnThis(),
getByText: vi.fn().mockReturnThis(),
waitFor: vi.fn().mockResolvedValue(true),
click: vi.fn().mockResolvedValue(true),
};
const mockFrameElement = {
contentFrame: vi.fn().mockResolvedValue(mockFrame),
};
const mockPage = {
goto: vi.fn().mockResolvedValue(true),
locator: vi.fn().mockReturnThis(),
first: vi.fn().mockReturnThis(),
nth: vi.fn().mockReturnThis(),
fill: vi.fn().mockResolvedValue(true),
click: vi.fn().mockResolvedValue(true),
waitForSelector: vi.fn().mockResolvedValue(mockFrameElement),
waitFor: vi.fn().mockResolvedValue(true),
waitForURL: vi.fn().mockResolvedValue(true),
};
const mockContext = {
newPage: vi.fn().mockResolvedValue(mockPage),
};
const mockBrowser = {
newContext: vi.fn().mockResolvedValue(mockContext),
close: vi.fn().mockResolvedValue(true),
};
return {
chromium: {
launch: vi.fn().mockResolvedValue(mockBrowser),
},
};
});
describe('AuthService', () => {
let authService: AuthService;
beforeEach(() => {
authService = new AuthService();
vi.clearAllMocks();
// 强制设置测试环境变量
process.env.NODE_ENV = 'production';
});
it('应该抛出错误,如果未提供且环境变量中也没有用户名或密码', async () => {
// 临时清空 ENV 对象中缓存的配置
const originalUsername = ENV.ERP_USERNAME;
const originalPassword = ENV.ERP_PASSWORD;
ENV.ERP_USERNAME = '';
ENV.ERP_PASSWORD = '';
// 此时 ENV 为空options 也为空,必定会触发报错
await expect(authService.login({ username: '', password: '' }))
.rejects
.toThrow('登录失败: 必须提供用户名和密码,或在 .env 中配置');
// 恢复全局配置,以免影响后面的测试用例
ENV.ERP_USERNAME = originalUsername;
ENV.ERP_PASSWORD = originalPassword;
});
it('应该能读取环境变量并成功执行登录流程', async () => {
// 这里的 login 不传参数,将自动从 ENV 对象(也就是你的 .env 文件)中读取账号密码
const result = await authService.login({
headless: true, // 强制测试静默模式
});
expect(chromium.launch).toHaveBeenCalled();
expect(result).toHaveProperty('browser');
expect(result).toHaveProperty('page');
expect(result).toHaveProperty('mainFrame');
});
it('登出操作应该按顺序点击头像和退出按钮', async () => {
// 拿到 Mock 的 frame 对象
const mockBrowser = await chromium.launch();
const mockContext = await mockBrowser.newContext();
const mockPage = await mockContext.newPage();
const mockFrameEl = await mockPage.waitForSelector('#forwardFrame');
const mockFrame = await mockFrameEl.contentFrame();
await authService.logout(mockFrame!, mockPage);
// 验证对应的选择器是否被正确调用
expect(mockFrame!.locator).toHaveBeenCalledWith('.diwork-avatar-default');
expect(mockFrame!.getByText).toHaveBeenCalledWith('退出登录');
});
});