| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
- import { DataSource } from 'typeorm';
- import { MiniAuthService } from '../../src/services';
- import { UserEntity } from '@d8d/user-module';
- // Mock 依赖
- vi.mock('@d8d/shared-utils', async (importOriginal) => {
- const actual = await importOriginal() as any;
- return {
- ...actual,
- JWTUtil: {
- generateToken: vi.fn().mockReturnValue('mock-jwt-token')
- },
- redisUtil: {
- setSessionKey: vi.fn().mockResolvedValue(undefined),
- getSessionKey: vi.fn().mockResolvedValue('mock-session-key')
- }
- };
- });
- vi.mock('@d8d/file-module', () => ({
- FileService: vi.fn().mockImplementation(() => ({
- downloadAndSaveFromUrl: vi.fn().mockResolvedValue({ file: { id: 1 } })
- }))
- }));
- describe('MiniAuthService', () => {
- let miniAuthService: MiniAuthService;
- let mockDataSource: DataSource;
- let mockUserRepository: any;
- beforeEach(() => {
- // Mock DataSource
- mockUserRepository = {
- findOne: vi.fn(),
- create: vi.fn(),
- save: vi.fn()
- };
- mockDataSource = {
- getRepository: vi.fn().mockReturnValue(mockUserRepository)
- } as any;
- miniAuthService = new MiniAuthService(mockDataSource);
- });
- afterEach(() => {
- vi.clearAllMocks();
- });
- describe('decryptPhoneNumber', () => {
- it('应该成功解密有效的手机号数据', async () => {
- // 模拟有效的加密数据、IV和sessionKey
- const encryptedData = 'valid_encrypted_data';
- const iv = 'valid_iv';
- const sessionKey = 'valid_session_key';
- // 这里我们模拟一个成功的解密过程
- // 在实际测试中,可能需要更复杂的模拟
- const result = await miniAuthService.decryptPhoneNumber(encryptedData, iv, sessionKey);
- // 由于我们无法真正模拟 crypto 模块,这里主要测试方法调用
- expect(result).toBeDefined();
- });
- it('应该拒绝空的加密数据', async () => {
- const encryptedData = '';
- const iv = 'valid_iv';
- const sessionKey = 'valid_session_key';
- await expect(miniAuthService.decryptPhoneNumber(encryptedData, iv, sessionKey))
- .rejects.toMatchObject({ code: 400, message: '加密数据或初始向量不能为空' });
- });
- it('应该拒绝空的初始向量', async () => {
- const encryptedData = 'valid_encrypted_data';
- const iv = '';
- const sessionKey = 'valid_session_key';
- await expect(miniAuthService.decryptPhoneNumber(encryptedData, iv, sessionKey))
- .rejects.toMatchObject({ code: 400, message: '加密数据或初始向量不能为空' });
- });
- it('应该拒绝空的sessionKey', async () => {
- const encryptedData = 'valid_encrypted_data';
- const iv = 'valid_iv';
- const sessionKey = '';
- await expect(miniAuthService.decryptPhoneNumber(encryptedData, iv, sessionKey))
- .rejects.toMatchObject({ code: 400, message: '加密数据或初始向量不能为空' });
- });
- it('应该处理解密失败的情况', async () => {
- // 模拟无效的加密数据
- const encryptedData = 'invalid_encrypted_data';
- const iv = 'invalid_iv';
- const sessionKey = 'invalid_session_key';
- // 由于我们无法真正模拟 crypto 模块,这里主要测试错误处理
- await expect(miniAuthService.decryptPhoneNumber(encryptedData, iv, sessionKey))
- .rejects.toMatchObject({ code: 400 });
- });
- });
- describe('miniLogin', () => {
- it('应该成功处理小程序登录', async () => {
- // Mock 微信API响应
- const mockOpenidInfo = {
- openid: 'test_openid',
- session_key: 'test_session_key'
- };
- // Mock 用户数据
- const mockUser = {
- id: 1,
- username: 'wx_user',
- openid: 'test_openid'
- } as UserEntity;
- // Mock 方法
- vi.spyOn(miniAuthService as any, 'getOpenIdByCode').mockResolvedValue(mockOpenidInfo);
- mockUserRepository.findOne.mockResolvedValue(mockUser);
- const result = await miniAuthService.miniLogin('test_code');
- expect(result).toHaveProperty('token');
- expect(result).toHaveProperty('user');
- expect(result).toHaveProperty('isNewUser');
- expect(result.token).toBe('mock-jwt-token');
- expect(result.user).toEqual(mockUser);
- expect(result.isNewUser).toBe(false);
- });
- it('应该为新用户创建账户', async () => {
- // Mock 微信API响应
- const mockOpenidInfo = {
- openid: 'new_user_openid',
- session_key: 'test_session_key'
- };
- // Mock 新用户数据
- const mockNewUser = {
- id: 2,
- username: 'wx_new_user',
- openid: 'new_user_openid'
- } as UserEntity;
- // Mock 方法
- vi.spyOn(miniAuthService as any, 'getOpenIdByCode').mockResolvedValue(mockOpenidInfo);
- vi.spyOn(miniAuthService as any, 'createMiniUser').mockResolvedValue(mockNewUser);
- mockUserRepository.findOne.mockResolvedValue(null);
- const result = await miniAuthService.miniLogin('test_code');
- expect(result.isNewUser).toBe(true);
- expect(result.user).toEqual(mockNewUser);
- });
- });
- describe('updateUserProfile', () => {
- it('应该成功更新用户资料', async () => {
- const mockUser = {
- id: 1,
- nickname: 'old_nickname',
- avatarFileId: null
- } as UserEntity;
- mockUserRepository.findOne.mockResolvedValue(mockUser);
- mockUserRepository.save.mockResolvedValue({ ...mockUser, nickname: 'new_nickname' });
- const result = await miniAuthService.updateUserProfile(1, {
- nickname: 'new_nickname'
- });
- expect(result.nickname).toBe('new_nickname');
- expect(mockUserRepository.save).toHaveBeenCalled();
- });
- it('应该处理用户不存在的情况', async () => {
- mockUserRepository.findOne.mockResolvedValue(null);
- await expect(miniAuthService.updateUserProfile(999, { nickname: 'test' }))
- .rejects.toThrow('用户不存在');
- });
- });
- });
|