const { paginate } = require('../utils/pagination') describe('paginate', () => { // 模拟 queryFn const createMockQueryFn = (totalCount, dataRows) => { return jest.fn((sql, params) => { if (sql.includes('COUNT(*)')) { return Promise.resolve([{ total: totalCount }]) } return Promise.resolve(dataRows) }) } it('应返回正确的分页结构', async () => { const mockFn = createMockQueryFn(50, [{ id: 1 }]) const result = await paginate(mockFn, 'SELECT * FROM users', [], 1, 10) expect(result).toHaveProperty('data') expect(result).toHaveProperty('total', 50) expect(result).toHaveProperty('page', 1) expect(result).toHaveProperty('pageSize', 10) expect(result).toHaveProperty('totalPages', 5) }) it('应计算正确的 totalPages', async () => { // 50 条数据,每页 20 条 → 3 页 const mockFn = createMockQueryFn(50, []) const result = await paginate(mockFn, 'SELECT * FROM t', [], 1, 20) expect(result.totalPages).toBe(3) }) it('应在无数据时 totalPages 为 0', async () => { const mockFn = createMockQueryFn(0, []) const result = await paginate(mockFn, 'SELECT * FROM t', [], 1, 20) expect(result.totalPages).toBe(0) expect(result.total).toBe(0) }) it('应将 page 限制为最小值 1', async () => { const mockFn = createMockQueryFn(10, []) const result = await paginate(mockFn, 'SELECT * FROM t', [], -5, 10) expect(result.page).toBe(1) }) it('应将 page 设为 1 当输入无法解析时', async () => { const mockFn = createMockQueryFn(10, []) const result = await paginate(mockFn, 'SELECT * FROM t', [], 'abc', 10) expect(result.page).toBe(1) }) it('应将 pageSize 限制在 1-100 之间', async () => { // pageSize=0 时 parseInt(0)||20 = 20(0 是 falsy),所以回退到默认值 const mockFn1 = createMockQueryFn(10, []) const result1 = await paginate(mockFn1, 'SELECT * FROM t', [], 1, -5) expect(result1.pageSize).toBe(1) const mockFn2 = createMockQueryFn(10, []) const result2 = await paginate(mockFn2, 'SELECT * FROM t', [], 1, 200) expect(result2.pageSize).toBe(100) }) it('应使用默认 page=1 和 pageSize=20', async () => { const mockFn = createMockQueryFn(100, []) const result = await paginate(mockFn, 'SELECT * FROM t', []) expect(result.page).toBe(1) expect(result.pageSize).toBe(20) }) it('应传递正确的 SQL 和参数给 queryFn', async () => { const mockFn = createMockQueryFn(10, []) await paginate(mockFn, 'SELECT * FROM users WHERE status = ?', ['active'], 2, 10) // 第一次调用:count 查询 expect(mockFn).toHaveBeenNthCalledWith( 1, 'SELECT COUNT(*) as total FROM (SELECT * FROM users WHERE status = ?) AS _paged', ['active'] ) // 第二次调用:数据查询 expect(mockFn).toHaveBeenNthCalledWith( 2, 'SELECT * FROM users WHERE status = ? LIMIT 10 OFFSET 10', ['active'] ) }) it('应计算正确的 offset', async () => { const mockFn = createMockQueryFn(100, []) await paginate(mockFn, 'SELECT * FROM t', [], 3, 15) // page=3, pageSize=15 → offset = (3-1)*15 = 30 expect(mockFn).toHaveBeenNthCalledWith( 2, 'SELECT * FROM t LIMIT 15 OFFSET 30', [] ) }) it('应返回 queryFn 返回的数据', async () => { const rows = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }] const mockFn = createMockQueryFn(2, rows) const result = await paginate(mockFn, 'SELECT * FROM t', [], 1, 10) expect(result.data).toEqual(rows) }) it('应处理字符串形式的 page 和 pageSize', async () => { const mockFn = createMockQueryFn(50, []) const result = await paginate(mockFn, 'SELECT * FROM t', [], '2', '25') expect(result.page).toBe(2) expect(result.pageSize).toBe(25) }) })