gongxiangp2/lib/__tests__/system-logs-route.test.ts

68 lines
2.2 KiB
TypeScript
Raw Permalink 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.

/** @jest-environment node */
import { execFile } from 'child_process'
import { NextRequest } from 'next/server'
import { getServerSession } from 'next-auth'
import { GET } from '@/app/api/admin/system-logs/route'
jest.mock('next-auth', () => ({
getServerSession: jest.fn(),
}))
jest.mock('@/lib/auth', () => ({ authOptions: {} }))
jest.mock('@/lib/department-permission', () => ({
isSuperAdmin: jest.fn().mockResolvedValue(false),
hasSystemAdminPermission: jest.fn((role: string, isSuperAdmin: boolean) =>
isSuperAdmin || role === 'ADMIN' || role === 'SYSTEM_ADMIN'),
}))
jest.mock('child_process', () => ({
execFile: jest.fn(),
}))
describe('admin system-logs route', () => {
beforeEach(() => {
jest.clearAllMocks()
;(getServerSession as jest.Mock).mockResolvedValue({
user: { id: 'admin-1', role: 'ADMIN' },
})
;(execFile as unknown as jest.Mock).mockImplementation(
(_file: string, _args: string[], _options: unknown, callback: Function) =>
callback(null, 'INFO ready\nERROR failed\n', ''),
)
})
test('关键词和行数不得进入 shell,并在进程输出后过滤', async () => {
const keyword = '"; touch /tmp/pwn; #'
const request = new NextRequest(
`http://localhost/api/admin/system-logs?lines=999999&keyword=${encodeURIComponent(keyword)}`,
)
const response = await GET(request)
const body = await response.json()
expect(response.status).toBe(200)
expect(execFile).toHaveBeenCalledWith(
'docker',
['logs', '--tail', '5000', 'youyidian-3d-material'],
expect.objectContaining({ encoding: 'utf8' }),
expect.any(Function),
)
expect((execFile as unknown as jest.Mock).mock.calls[0][2]).not.toHaveProperty('shell')
expect(JSON.stringify((execFile as unknown as jest.Mock).mock.calls[0].slice(0, 3))).not.toContain(keyword)
expect(body.logs).toBe('')
})
test('普通用户不得调用 docker', async () => {
;(getServerSession as jest.Mock).mockResolvedValue({
user: { id: 'user-1', role: 'USER' },
})
const response = await GET(new NextRequest('http://localhost/api/admin/system-logs'))
expect(response.status).toBe(403)
expect(execFile).not.toHaveBeenCalled()
})
})