// REQ-USR-003: listUsers API 封装单测(GET /api/usr/users + 中文键归一 D-PLAN-2) import { describe, it, expect, vi, beforeEach } from 'vitest'; // 桩掉底层 axios 实例(request.ts 的 default 导出),沿用 usrApi.test.ts 模式 vi.mock('../../src/api/request', () => { return { default: { post: vi.fn(), get: vi.fn(), }, }; }); import request from '../../src/api/request'; import { listUsers } from '../../src/api/usrApi'; const mockedRequest = request as unknown as { post: ReturnType; get: ReturnType; }; function pageBody(records: unknown[], total = 1, pageNum = 1, pageSize = 10) { return { records, total, pageNum, pageSize }; } describe('usrApi.listUsers', () => { beforeEach(() => { vi.clearAllMocks(); }); it('listUsers gets /usr/users with query params', async () => { mockedRequest.get.mockResolvedValue(pageBody([], 0, 2, 20)); await listUsers({ queryField: '用户名', matchType: '包含', queryValue: '李', pageNum: 2, pageSize: 20, }); expect(mockedRequest.get).toHaveBeenCalledTimes(1); const [url, config] = mockedRequest.get.mock.calls[0]; expect(url).toBe('/usr/users'); expect(config.params).toMatchObject({ queryField: '用户名', matchType: '包含', queryValue: '李', pageNum: 2, pageSize: 20, }); }); it('listUsers omits empty queryValue', async () => { mockedRequest.get.mockResolvedValue(pageBody([], 0, 1, 10)); await listUsers({ queryField: '用户名', matchType: '包含', queryValue: '', pageNum: 1, pageSize: 10, }); const [, config] = mockedRequest.get.mock.calls[0]; expect(config.params).not.toHaveProperty('queryValue'); }); it('listUsers normalizes chinese keys 员工名/部门 to employeeName/departmentName', async () => { mockedRequest.get.mockResolvedValue( pageBody( [ { id: 1, sUserName: 'a', 员工名: '张三', 部门: '技术', sUserNo: 'a', sUserType: '超级管理员', sLanguage: '中文', iIsVoid: 0, tLastLoginDate: null, sCreator: 'x', tCreateDate: 't', }, ], 1, 2, 20, ), ); const ret = await listUsers({ pageNum: 2, pageSize: 20 }); expect(ret.records[0].employeeName).toBe('张三'); expect(ret.records[0].departmentName).toBe('技术'); expect(ret.total).toBe(1); expect(ret.pageNum).toBe(2); expect(ret.pageSize).toBe(20); }); });