/**
 * 用户实体、DTO和服务的完整测试套件
 * 
 * 功能描述：
 * - 测试Users实体的结构和装饰器配置
 * - 测试CreateUserDto的数据验证规则和边界条件
 * - 测试UsersService的所有CRUD操作和业务逻辑
 * - 验证数据类型、约束条件和异常处理
 * - 确保服务层与数据库交互的正确性
 * 
 * 测试覆盖范围：
 * - 实体字段映射和类型验证
 * - DTO数据验证和错误处理
 * - 服务方法的正常流程和异常流程
 * - 数据库操作的模拟和验证
 * - 业务规则和约束条件检查
 * 
 * 测试策略：
 * - 单元测试：独立测试每个方法的功能
 * - 集成测试：测试DTO到Entity的完整流程
 * - 异常测试：验证各种错误情况的处理
 * - 边界测试：测试数据验证的边界条件
 * 
 * 依赖模块：
 * - Jest: 测试框架和断言库
 * - NestJS Testing: 提供测试模块和依赖注入
 * - class-validator: DTO验证测试
 * - TypeORM: 数据库操作模拟
 * 
 * @author moyin
 * @version 1.0.0
 * @since 2025-12-17
 * 
 * @lastModified 2025-01-07 by moyin
 * @lastChange 添加完整的测试注释体系，增强测试覆盖率和方法测试
 */

import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { ConflictException, NotFoundException, BadRequestException } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToClass } from 'class-transformer';

import { Users } from './users.entity';
import { CreateUserDto } from './users.dto';
import { UsersService } from './users.service';

describe('Users Entity, DTO and Service Tests', () => {
  let service: UsersService;
  let module: TestingModule;

  /**
   * 模拟的TypeORM Repository方法
   * 
   * 功能：模拟数据库操作，避免真实数据库依赖
   * 包含的方法：
   * - save: 保存实体到数据库
   * - find: 查询多个实体
   * - findOne: 查询单个实体
   * - delete: 删除实体
   * - softRemove: 软删除实体
   * - count: 统计实体数量
   * - createQueryBuilder: 创建查询构建器
   */
  const mockRepository = {
    save: jest.fn(),
    find: jest.fn(),
    findOne: jest.fn(),
    delete: jest.fn(),
    softRemove: jest.fn(),
    count: jest.fn(),
    createQueryBuilder: jest.fn(),
  };

  /**
   * 测试用的模拟用户数据
   * 
   * 包含所有Users实体的字段：
   * - 基础信息：id, username, nickname
   * - 联系方式：email, phone
   * - 认证信息：password_hash, github_id
   * - 状态信息：role, status, email_verified
   * - 时间戳：created_at, updated_at
   * - 扩展信息：avatar_url
   */
  const mockUser: Users = {
    id: BigInt(1),
    username: 'testuser',
    email: 'test@example.com',
    email_verified: false,
    phone: '+8613800138000',
    password_hash: 'hashed_password',
    nickname: '测试用户',
    github_id: 'github_123',
    avatar_url: 'https://example.com/avatar.jpg',
    role: 1,
    status: 'active' as any, // UserStatus.ACTIVE
    created_at: new Date(),
    updated_at: new Date(),
  };

  /**
   * 测试用的创建用户DTO数据
   * 
   * 包含创建用户所需的基本字段：
   * - 必填字段：username, nickname
   * - 可选字段：email, phone, password_hash, github_id, avatar_url, role
   * 
   * 用于测试：
   * - 数据验证规则
   * - 用户创建流程
   * - DTO到Entity的转换
   */
  const createUserDto: CreateUserDto = {
    username: 'testuser',
    email: 'test@example.com',
    phone: '+8613800138000',
    password_hash: 'hashed_password',
    nickname: '测试用户',
    github_id: 'github_123',
    avatar_url: 'https://example.com/avatar.jpg',
    role: 1
  };

  /**
   * 测试前置设置
   * 
   * 功能：
   * - 创建测试模块和依赖注入容器
   * - 配置UsersService和模拟的Repository
   * - 初始化测试环境
   * - 清理之前测试的Mock状态
   * 
   * 执行时机：每个测试用例执行前
   */
  beforeEach(async () => {
    module = await Test.createTestingModule({
      providers: [
        UsersService,
        {
          provide: getRepositoryToken(Users),
          useValue: mockRepository,
        },
      ],
    }).compile();

    service = module.get<UsersService>(UsersService);

    // 清理所有mock状态，确保测试独立性
    jest.clearAllMocks();
  });

  /**
   * 测试后置清理
   * 
   * 功能：
   * - 关闭测试模块
   * - 释放资源和内存
   * - 防止测试间的状态污染
   * 
   * 执行时机：每个测试用例执行后
   */
  afterEach(async () => {
    await module.close();
  });

  /**
   * Users实体测试组
   * 
   * 测试目标：
   * - 验证Users实体类的基本功能
   * - 测试实体字段的设置和获取
   * - 确保实体结构符合设计要求
   * 
   * 测试内容：
   * - 实体实例化和属性赋值
   * - 字段类型和数据完整性
   * - TypeORM装饰器的正确配置
   */
  describe('Users Entity Tests', () => {
    /**
     * 测试用户实体的基本创建和属性设置
     * 
     * 验证点：
     * - 实体可以正常实例化
     * - 所有字段可以正确赋值
     * - 字段值可以正确读取
     */
    it('应该正确创建用户实体实例', () => {
      const user = new Users();
      user.username = 'testuser';
      user.email = 'test@example.com';
      user.phone = '+8613800138000';
      user.password_hash = 'hashed_password';
      user.nickname = '测试用户';
      user.github_id = 'github_123';
      user.avatar_url = 'https://example.com/avatar.jpg';
      user.role = 1;
      user.created_at = new Date();
      user.updated_at = new Date();

      expect(user.username).toBe('testuser');
      expect(user.email).toBe('test@example.com');
      expect(user.nickname).toBe('测试用户');
      expect(user.role).toBe(1);
    });

    it('应该能够设置和获取所有属性', () => {
      const user = new Users();
      
      // 验证可以设置和获取所有属性
      user.username = 'testuser';
      user.email = 'test@example.com';
      user.phone = '+8613800138000';
      user.password_hash = 'hashed_password';
      user.nickname = '测试用户';
      user.github_id = 'github_123';
      user.avatar_url = 'https://example.com/avatar.jpg';
      user.role = 1;
      user.created_at = new Date();
      user.updated_at = new Date();

      expect(user.username).toBe('testuser');
      expect(user.email).toBe('test@example.com');
      expect(user.phone).toBe('+8613800138000');
      expect(user.password_hash).toBe('hashed_password');
      expect(user.nickname).toBe('测试用户');
      expect(user.github_id).toBe('github_123');
      expect(user.avatar_url).toBe('https://example.com/avatar.jpg');
      expect(user.role).toBe(1);
      expect(user.created_at).toBeInstanceOf(Date);
      expect(user.updated_at).toBeInstanceOf(Date);
    });
  });

  /**
   * CreateUserDto数据验证测试组
   * 
   * 测试目标：
   * - 验证DTO的数据验证规则
   * - 测试各种输入数据的验证结果
   * - 确保数据完整性和业务规则
   * 
   * 测试内容：
   * - 有效数据的验证通过
   * - 无效数据的验证失败
   * - 必填字段的验证
   * - 格式验证（邮箱、手机号等）
   * - 长度限制验证
   * - 数值范围验证
   */
  describe('CreateUserDto Validation Tests', () => {
    /**
     * 测试有效数据的验证
     * 
     * 验证点：
     * - 包含所有必填字段的数据应该通过验证
     * - 可选字段的数据格式正确
     * - 验证错误数组应该为空
     */
    it('应该通过有效数据的验证', async () => {
      const validData = {
        username: 'testuser',
        email: 'test@example.com',
        phone: '+8613800138000',
        password_hash: 'hashed_password',
        nickname: '测试用户',
        github_id: 'github_123',
        avatar_url: 'https://example.com/avatar.jpg',
        role: 1
      };

      const dto = plainToClass(CreateUserDto, validData);
      const errors = await validate(dto);

      expect(errors).toHaveLength(0);
    });

    /**
     * 测试缺少必填字段时的验证失败
     * 
     * 验证点：
     * - 缺少username和nickname时验证应该失败
     * - 验证错误数组包含对应的字段错误
     * - 错误信息准确指向缺失的字段
     */
    it('应该拒绝缺少必填字段的数据', async () => {
      const invalidData = {
        email: 'test@example.com'
        // 缺少 username 和 nickname
      };

      const dto = plainToClass(CreateUserDto, invalidData);
      const errors = await validate(dto);

      expect(errors.length).toBeGreaterThan(0);
      
      const usernameError = errors.find(error => error.property === 'username');
      const nicknameError = errors.find(error => error.property === 'nickname');
      
      expect(usernameError).toBeDefined();
      expect(nicknameError).toBeDefined();
    });

    /**
     * 测试邮箱格式验证
     * 
     * 验证点：
     * - 无效的邮箱格式应该被拒绝
     * - 验证错误指向email字段
     * - 错误信息提示格式不正确
     */
    it('应该拒绝无效的邮箱格式', async () => {
      const invalidData = {
        username: 'testuser',
        nickname: '测试用户',
        email: 'invalid-email'
      };

      const dto = plainToClass(CreateUserDto, invalidData);
      const errors = await validate(dto);

      const emailError = errors.find(error => error.property === 'email');
      expect(emailError).toBeDefined();
    });

    it('应该拒绝超长的用户名', async () => {
      const invalidData = {
        username: 'a'.repeat(51), // 超过50字符
        nickname: '测试用户'
      };

      const dto = plainToClass(CreateUserDto, invalidData);
      const errors = await validate(dto);

      const usernameError = errors.find(error => error.property === 'username');
      expect(usernameError).toBeDefined();
    });

    it('应该拒绝无效的角色值', async () => {
      const invalidData = {
        username: 'testuser',
        nickname: '测试用户',
        role: 10 // 超出1-9范围
      };

      const dto = plainToClass(CreateUserDto, invalidData);
      const errors = await validate(dto);

      const roleError = errors.find(error => error.property === 'role');
      expect(roleError).toBeDefined();
    });
  });

  /**
   * UsersService CRUD操作测试组
   * 
   * 测试目标：
   * - 验证所有CRUD操作的正确性
   * - 测试业务逻辑和数据处理
   * - 确保异常情况的正确处理
   * 
   * 测试内容：
   * - 创建操作：create, createWithDuplicateCheck, createBatch
   * - 查询操作：findAll, findOne, findByUsername, findByEmail, findByGithubId, findByRole, search
   * - 更新操作：update
   * - 删除操作：remove, softRemove
   * - 工具方法：count, exists
   * 
   * 测试策略：
   * - 正常流程测试：验证方法的基本功能
   * - 异常流程测试：验证错误处理和异常抛出
   * - 边界条件测试：验证参数边界和特殊情况
   */
  describe('UsersService CRUD Tests', () => {

    /**
     * create()方法测试组
     * 
     * 测试目标：
     * - 验证基础用户创建功能
     * - 测试数据验证和异常处理
     * - 确保数据库操作的正确性
     */
    describe('create()', () => {
      /**
       * 测试成功创建用户的正常流程
       * 
       * 验证点：
       * - Repository.save方法被正确调用
       * - 返回值与期望的用户数据一致
       * - 数据验证通过
       */
      it('应该成功创建新用户', async () => {
        mockRepository.save.mockResolvedValue(mockUser);

        const result = await service.create(createUserDto);

        expect(mockRepository.save).toHaveBeenCalled();
        expect(result).toEqual(mockUser);
      });

      it('应该在数据验证失败时抛出BadRequestException', async () => {
        const invalidDto = { username: '', nickname: '' }; // 无效数据

        await expect(service.create(invalidDto as CreateUserDto)).rejects.toThrow(BadRequestException);
      });

      it('应该在系统异常时抛出BadRequestException', async () => {
        mockRepository.save.mockRejectedValue(new Error('Database error'));

        await expect(service.create(createUserDto)).rejects.toThrow(BadRequestException);
      });
    });

    describe('findAll()', () => {
      it('应该返回用户列表', async () => {
        const mockUsers = [mockUser];
        mockRepository.find.mockResolvedValue(mockUsers);

        const result = await service.findAll();

        expect(mockRepository.find).toHaveBeenCalledWith({
          where: {},
          take: 100,
          skip: 0,
          order: { created_at: 'DESC' }
        });
        expect(result).toEqual(mockUsers);
      });

      it('应该支持分页参数', async () => {
        mockRepository.find.mockResolvedValue([]);

        await service.findAll(50, 10);

        expect(mockRepository.find).toHaveBeenCalledWith({
          where: {},
          take: 50,
          skip: 10,
          order: { created_at: 'DESC' }
        });
      });

      it('应该支持包含已删除用户的查询', async () => {
        const mockUsers = [mockUser];
        mockRepository.find.mockResolvedValue(mockUsers);

        const result = await service.findAll(100, 0, true);

        expect(mockRepository.find).toHaveBeenCalledWith({
          where: {},
          take: 100,
          skip: 0,
          order: { created_at: 'DESC' }
        });
        expect(result).toEqual(mockUsers);
      });
    });

    describe('findOne()', () => {
      it('应该根据ID返回用户', async () => {
        mockRepository.findOne.mockResolvedValue(mockUser);

        const result = await service.findOne(BigInt(1));

        expect(mockRepository.findOne).toHaveBeenCalledWith({
          where: { id: BigInt(1) }
        });
        expect(result).toEqual(mockUser);
      });

      it('应该在用户不存在时抛出NotFoundException', async () => {
        mockRepository.findOne.mockResolvedValue(null);

        await expect(service.findOne(BigInt(999))).rejects.toThrow(NotFoundException);
      });

      it('应该支持包含已删除用户的查询', async () => {
        mockRepository.findOne.mockResolvedValue(mockUser);

        const result = await service.findOne(BigInt(1), true);

        expect(mockRepository.findOne).toHaveBeenCalledWith({
          where: { id: BigInt(1) }
        });
        expect(result).toEqual(mockUser);
      });
    });

    describe('findByUsername()', () => {
      it('应该根据用户名返回用户', async () => {
        mockRepository.findOne.mockResolvedValue(mockUser);

        const result = await service.findByUsername('testuser');

        expect(mockRepository.findOne).toHaveBeenCalledWith({
          where: { username: 'testuser' }
        });
        expect(result).toEqual(mockUser);
      });

      it('应该在用户不存在时返回null', async () => {
        mockRepository.findOne.mockResolvedValue(null);

        const result = await service.findByUsername('nonexistent');

        expect(result).toBeNull();
      });

      it('应该支持包含已删除用户的查询', async () => {
        mockRepository.findOne.mockResolvedValue(mockUser);

        const result = await service.findByUsername('testuser', true);

        expect(mockRepository.findOne).toHaveBeenCalledWith({
          where: { username: 'testuser' }
        });
        expect(result).toEqual(mockUser);
      });
    });

    describe('findByGithubId()', () => {
      it('应该根据GitHub ID返回用户', async () => {
        mockRepository.findOne.mockResolvedValue(mockUser);

        const result = await service.findByGithubId('github_123');

        expect(mockRepository.findOne).toHaveBeenCalledWith({
          where: { github_id: 'github_123' }
        });
        expect(result).toEqual(mockUser);
      });

      it('应该在GitHub ID不存在时返回null', async () => {
        mockRepository.findOne.mockResolvedValue(null);

        const result = await service.findByGithubId('nonexistent');

        expect(result).toBeNull();
      });

      it('应该支持包含已删除用户的查询', async () => {
        mockRepository.findOne.mockResolvedValue(mockUser);

        const result = await service.findByGithubId('github_123', true);

        expect(mockRepository.findOne).toHaveBeenCalledWith({
          where: { github_id: 'github_123' }
        });
        expect(result).toEqual(mockUser);
      });
    });

    describe('createWithDuplicateCheck()', () => {
      it('应该成功创建用户（带重复检查）', async () => {
        // 模拟所有唯一性检查都通过
        mockRepository.findOne.mockResolvedValue(null);
        mockRepository.save.mockResolvedValue(mockUser);

        const result = await service.createWithDuplicateCheck(createUserDto);

        expect(mockRepository.findOne).toHaveBeenCalledTimes(4); // 检查用户名、邮箱、手机号、GitHub ID
        expect(mockRepository.save).toHaveBeenCalled();
        expect(result).toEqual(mockUser);
      });

      it('应该在用户名重复时抛出ConflictException', async () => {
        mockRepository.findOne.mockResolvedValue(mockUser); // 模拟用户名已存在

        await expect(service.createWithDuplicateCheck(createUserDto)).rejects.toThrow(ConflictException);
        expect(mockRepository.save).not.toHaveBeenCalled();
      });

      it('应该在邮箱重复时抛出ConflictException', async () => {
        mockRepository.findOne
          .mockResolvedValueOnce(null) // 用户名检查通过
          .mockResolvedValueOnce(mockUser); // 邮箱已存在

        await expect(service.createWithDuplicateCheck(createUserDto)).rejects.toThrow(ConflictException);
      });

      it('应该在手机号重复时抛出ConflictException', async () => {
        mockRepository.findOne
          .mockResolvedValueOnce(null) // 用户名检查通过
          .mockResolvedValueOnce(null) // 邮箱检查通过
          .mockResolvedValueOnce(mockUser); // 手机号已存在

        await expect(service.createWithDuplicateCheck(createUserDto)).rejects.toThrow(ConflictException);
      });

      it('应该在GitHub ID重复时抛出ConflictException', async () => {
        mockRepository.findOne
          .mockResolvedValueOnce(null) // 用户名检查通过
          .mockResolvedValueOnce(null) // 邮箱检查通过
          .mockResolvedValueOnce(null) // 手机号检查通过
          .mockResolvedValueOnce(mockUser); // GitHub ID已存在

        await expect(service.createWithDuplicateCheck(createUserDto)).rejects.toThrow(ConflictException);
      });
    });

    describe('softRemove()', () => {
      it('应该成功软删除用户', async () => {
        mockRepository.findOne.mockResolvedValue(mockUser);

        const result = await service.softRemove(BigInt(1));

        expect(mockRepository.findOne).toHaveBeenCalledWith({
          where: { id: BigInt(1) }
        });
        expect(result).toEqual(mockUser);
      });

      it('应该在软删除不存在的用户时抛出NotFoundException', async () => {
        mockRepository.findOne.mockResolvedValue(null);

        await expect(service.softRemove(BigInt(999))).rejects.toThrow(NotFoundException);
      });
    });

    describe('createBatch()', () => {
      it('应该成功批量创建用户', async () => {
        const batchDto = [
          { ...createUserDto, username: 'user1', nickname: '用户1' },
          { ...createUserDto, username: 'user2', nickname: '用户2' }
        ];
        
        const batchUsers = [
          { ...mockUser, username: 'user1', nickname: '用户1' },
          { ...mockUser, username: 'user2', nickname: '用户2' }
        ];

        mockRepository.save.mockResolvedValueOnce(batchUsers[0]).mockResolvedValueOnce(batchUsers[1]);

        const result = await service.createBatch(batchDto);

        expect(mockRepository.save).toHaveBeenCalledTimes(2);
        expect(result).toHaveLength(2);
        expect(result[0].username).toBe('user1');
        expect(result[1].username).toBe('user2');
      });

      it('应该在批量创建中某个用户失败时抛出异常', async () => {
        const batchDto = [
          { ...createUserDto, username: 'user1' },
          { username: '', nickname: '' } // 无效数据
        ];

        await expect(service.createBatch(batchDto)).rejects.toThrow(BadRequestException);
      });
    });

    describe('update()', () => {
      it('应该成功更新用户信息', async () => {
        const updatedUser = { ...mockUser, nickname: '更新后的昵称' };
        
        mockRepository.findOne
          .mockResolvedValueOnce(mockUser) // findOne in update method
          .mockResolvedValueOnce(mockUser) // findOne in checkUpdateUniqueness
          .mockResolvedValueOnce(null); // 检查昵称是否重复
        mockRepository.save.mockResolvedValue(updatedUser);

        const result = await service.update(BigInt(1), { nickname: '更新后的昵称' });

        expect(mockRepository.save).toHaveBeenCalled();
        expect(result.nickname).toBe('更新后的昵称');
      });

      it('应该在更新不存在的用户时抛出NotFoundException', async () => {
        mockRepository.findOne.mockResolvedValue(null);

        await expect(service.update(BigInt(999), { nickname: '新昵称' })).rejects.toThrow(NotFoundException);
      });

      it('应该在更新数据冲突时抛出ConflictException', async () => {
        const conflictUser = { ...mockUser, username: 'conflictuser' };
        
        mockRepository.findOne
          .mockResolvedValueOnce(mockUser) // findOne in update method
          .mockResolvedValueOnce(mockUser) // findOne in checkUpdateUniqueness
          .mockResolvedValueOnce(conflictUser); // 发现用户名冲突

        await expect(service.update(BigInt(1), { username: 'conflictuser' })).rejects.toThrow(ConflictException);
      });
    });

    describe('remove()', () => {
      it('应该成功删除用户', async () => {
        mockRepository.findOne.mockResolvedValue(mockUser);
        mockRepository.delete.mockResolvedValue({ affected: 1 });

        const result = await service.remove(BigInt(1));

        expect(mockRepository.delete).toHaveBeenCalledWith({ id: BigInt(1) });
        expect(result.affected).toBe(1);
        expect(result.message).toContain('成功删除');
      });

      it('应该在删除不存在的用户时抛出NotFoundException', async () => {
        mockRepository.findOne.mockResolvedValue(null);

        await expect(service.remove(BigInt(999))).rejects.toThrow(NotFoundException);
      });
    });

    describe('count()', () => {
      it('应该返回用户总数', async () => {
        mockRepository.count.mockResolvedValue(10);

        const result = await service.count();

        expect(mockRepository.count).toHaveBeenCalled();
        expect(result).toBe(10);
      });
    });

    describe('exists()', () => {
      it('应该在用户存在时返回true', async () => {
        mockRepository.count.mockResolvedValue(1);

        const result = await service.exists(BigInt(1));

        expect(result).toBe(true);
      });

      it('应该在用户不存在时返回false', async () => {
        mockRepository.count.mockResolvedValue(0);

        const result = await service.exists(BigInt(999));

        expect(result).toBe(false);
      });
    });

    describe('search()', () => {
      it('应该根据关键词搜索用户', async () => {
        const mockQueryBuilder = {
          where: jest.fn().mockReturnThis(),
          orderBy: jest.fn().mockReturnThis(),
          limit: jest.fn().mockReturnThis(),
          getMany: jest.fn().mockResolvedValue([mockUser]),
        };

        mockRepository.createQueryBuilder.mockReturnValue(mockQueryBuilder);

        const result = await service.search('test');

        expect(mockRepository.createQueryBuilder).toHaveBeenCalledWith('user');
        expect(mockQueryBuilder.where).toHaveBeenCalledWith(
          'user.username LIKE :keyword OR user.nickname LIKE :keyword',
          { keyword: '%test%' }
        );
        expect(result).toEqual([mockUser]);
      });

      it('应该支持包含已删除用户的搜索', async () => {
        const mockQueryBuilder = {
          where: jest.fn().mockReturnThis(),
          orderBy: jest.fn().mockReturnThis(),
          limit: jest.fn().mockReturnThis(),
          getMany: jest.fn().mockResolvedValue([mockUser]),
        };

        mockRepository.createQueryBuilder.mockReturnValue(mockQueryBuilder);

        const result = await service.search('test', 20, true);

        expect(mockQueryBuilder.where).toHaveBeenCalledWith(
          'user.username LIKE :keyword OR user.nickname LIKE :keyword',
          { keyword: '%test%' }
        );
        expect(result).toEqual([mockUser]);
      });
    });

    describe('findByRole()', () => {
      it('应该根据角色查询用户', async () => {
        mockRepository.find.mockResolvedValue([mockUser]);

        const result = await service.findByRole(1);

        expect(mockRepository.find).toHaveBeenCalledWith({
          where: { role: 1 },
          order: { created_at: 'DESC' }
        });
        expect(result).toEqual([mockUser]);
      });

      it('应该支持包含已删除用户的查询', async () => {
        mockRepository.find.mockResolvedValue([mockUser]);

        const result = await service.findByRole(1, true);

        expect(mockRepository.find).toHaveBeenCalledWith({
          where: { role: 1 },
          order: { created_at: 'DESC' }
        });
        expect(result).toEqual([mockUser]);
      });
    });
  });

  /**
   * 集成测试组
   * 
   * 测试目标：
   * - 验证DTO到Entity的完整数据流
   * - 测试组件间的协作和集成
   * - 确保端到端流程的正确性
   * 
   * 测试内容：
   * - DTO验证 → 实体创建 → 数据库保存的完整流程
   * - 可选字段的默认值处理
   * - 数据转换和映射的正确性
   */
  describe('Integration Tests', () => {
    /**
     * 测试从DTO到Entity的完整数据流
     * 
     * 验证点：
     * - DTO验证成功
     * - 数据正确转换为Entity
     * - 服务方法正确处理数据
     * - 返回结果符合预期
     */
    it('应该完成从DTO到Entity的完整流程', async () => {
      // 1. 验证DTO
      const dto = plainToClass(CreateUserDto, createUserDto);
      const validationErrors = await validate(dto);
      expect(validationErrors).toHaveLength(0);

      // 2. 创建匹配的mock用户数据
      const expectedUser = { 
        ...mockUser, 
        username: dto.username,
        nickname: dto.nickname,
        email: dto.email 
      };
      
      // 3. 模拟服务创建用户
      mockRepository.findOne.mockResolvedValue(null);
      mockRepository.save.mockResolvedValue(expectedUser);

      const result = await service.create(dto);

      // 4. 验证结果
      expect(result).toBeDefined();
      expect(result.username).toBe(dto.username);
      expect(result.nickname).toBe(dto.nickname);
    });

    it('应该正确处理可选字段', async () => {
      const minimalDto: CreateUserDto = {
        username: 'minimaluser',
        nickname: '最小用户'
      };

      const dto = plainToClass(CreateUserDto, minimalDto);
      const validationErrors = await validate(dto);
      expect(validationErrors).toHaveLength(0);

      // 验证可选字段的默认值处理
      expect(dto.role).toBe(1); // 默认角色
      expect(dto.email).toBeUndefined();
      expect(dto.phone).toBeUndefined();
    });
  });

  /**
   * 错误处理测试组
   * 
   * 测试目标：
   * - 验证各种异常情况的处理
   * - 测试错误恢复和降级机制
   * - 确保系统的健壮性和稳定性
   * 
   * 测试内容：
   * - 数据库连接错误处理
   * - 并发操作冲突处理
   * - 系统异常的统一处理
   * - 搜索异常的降级处理
   * - 各种操作失败的异常抛出
   * 
   * 异常处理策略：
   * - 业务异常：直接抛出对应的HTTP异常
   * - 系统异常：转换为BadRequestException
   * - 搜索异常：返回空结果而不抛出异常
   */
  describe('Error Handling Tests', () => {
    /**
     * 测试数据库连接错误的处理
     * 
     * 验证点：
     * - 数据库操作失败时抛出正确的异常
     * - 异常类型为BadRequestException
     * - 错误信息被正确记录
     */
    it('应该正确处理数据库连接错误', async () => {
      mockRepository.save.mockRejectedValue(new Error('Database connection failed'));

      await expect(service.create(createUserDto)).rejects.toThrow(BadRequestException);
    });

    it('应该正确处理并发创建冲突', async () => {
      // 模拟并发情况：检查时不存在，保存时出现唯一约束错误
      mockRepository.save.mockRejectedValue(new Error('Duplicate entry'));

      await expect(service.create(createUserDto)).rejects.toThrow(BadRequestException);
    });

    it('应该正确处理搜索异常', async () => {
      const mockQueryBuilder = {
        where: jest.fn().mockReturnThis(),
        orderBy: jest.fn().mockReturnThis(),
        limit: jest.fn().mockReturnThis(),
        getMany: jest.fn().mockRejectedValue(new Error('Search failed')),
      };

      mockRepository.createQueryBuilder.mockReturnValue(mockQueryBuilder);

      const result = await service.search('test');

      // 搜索失败时应该返回空数组，不抛出异常
      expect(result).toEqual([]);
    });

    it('应该正确处理更新时的系统异常', async () => {
      mockRepository.findOne.mockResolvedValue(mockUser);
      mockRepository.save.mockRejectedValue(new Error('Update failed'));

      await expect(service.update(BigInt(1), { nickname: '新昵称' })).rejects.toThrow(BadRequestException);
    });

    it('应该正确处理删除时的系统异常', async () => {
      mockRepository.findOne.mockResolvedValue(mockUser);
      mockRepository.delete.mockRejectedValue(new Error('Delete failed'));

      await expect(service.remove(BigInt(1))).rejects.toThrow(BadRequestException);
    });
  });
});