gongxiangp2/app/admin/settings/page.test.tsx
2026-07-31 09:41:40 +08:00

99 lines
3.0 KiB
TypeScript

import { fireEvent, render, screen, waitFor } from '@testing-library/react'
import { useSession } from 'next-auth/react'
import SystemSettings from '@/app/admin/settings/page'
jest.mock('next-auth/react', () => ({
useSession: jest.fn(),
}))
jest.mock('next/navigation', () => ({
useRouter: () => ({
push: jest.fn(),
refresh: jest.fn(),
}),
}))
jest.mock('@/components/Header', () => ({
__esModule: true,
default: () => <div data-testid="header" />,
}))
jest.mock('@/hooks/useToast', () => ({
useToast: () => ({
toast: null,
showToast: jest.fn(),
}),
}))
jest.mock('@/components/ToastBubble', () => ({
__esModule: true,
default: () => null,
}))
describe('系统设置页凭据脱敏', () => {
beforeEach(() => {
jest.clearAllMocks()
;(useSession as jest.Mock).mockReturnValue({
data: {
user: { id: 'admin-1', role: 'ADMIN' },
},
status: 'authenticated',
})
global.fetch = jest.fn().mockResolvedValue({
ok: true,
json: async () => ({
headerBgColor: '#1f2937',
siteName: '由壹点3D素材',
headerLogoUrl: '',
loginLogoUrl: '',
s3Endpoint: 'https://storage.example.com',
s3Bucket: 'materials',
s3Region: 'us-east-1',
s3PublicUrl: 'https://cdn.example.com/materials',
s3CredentialsConfigured: true,
// 即使旧服务误返回这些字段,页面也不得回填或展示。
s3AccessKey: 'should-never-render-access-key',
s3SecretKey: 'should-never-render-secret-key',
maintenanceEnabled: false,
maintenanceMessage: null,
maintenanceStartTime: null,
maintenanceEndTime: null,
}),
}) as jest.Mock
})
test('只显示 configured 状态,凭据输入框始终为空', async () => {
render(<SystemSettings />)
await waitFor(() => {
expect(screen.getByText('已配置')).toBeInTheDocument()
})
expect(screen.getByLabelText('新 Access Key')).toHaveValue('')
expect(screen.getByLabelText('新 Secret Key')).toHaveValue('')
expect(screen.queryByDisplayValue('should-never-render-access-key')).not.toBeInTheDocument()
expect(screen.queryByDisplayValue('should-never-render-secret-key')).not.toBeInTheDocument()
expect(screen.queryByText('should-never-render-access-key')).not.toBeInTheDocument()
expect(screen.queryByText('should-never-render-secret-key')).not.toBeInTheDocument()
})
test('未填写新凭据时,保存请求不会覆盖现有凭据', async () => {
render(<SystemSettings />)
await waitFor(() => {
expect(screen.getByText('已配置')).toBeInTheDocument()
})
fireEvent.click(screen.getByRole('button', { name: '保存设置' }))
await waitFor(() => {
expect(global.fetch).toHaveBeenCalledTimes(2)
})
const [, requestInit] = (global.fetch as jest.Mock).mock.calls[1]
const payload = JSON.parse(requestInit.body)
expect(payload).not.toHaveProperty('s3AccessKey')
expect(payload).not.toHaveProperty('s3SecretKey')
})
})