// S3 设置弹窗(docs/30):字段回填、编辑后保存的载荷、自动上传开关。 import { describe, it, expect, vi } from 'vitest' import { createRoot } from 'react-dom/client' import { act } from 'react-dom/test-utils' import { S3SettingsModal } from '../src/components/S3SettingsModal' import { DEFAULT_S3_SETTINGS } from '../src/services/s3' function setInput(input: HTMLInputElement, value: string) { const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value')?.set setter?.call(input, value) input.dispatchEvent(new Event('input', { bubbles: true })) } describe('S3SettingsModal', () => { it('填写桶/区域/密钥与自动上传开关后,保存回传完整设置', async () => { const container = document.createElement('div') document.body.appendChild(container) const root = createRoot(container) const onSave = vi.fn() await act(async () => { root.render( undefined} />) }) const inputs = [...container.querySelectorAll('input')] const byPlaceholder = (ph: string) => inputs.find((i) => i.placeholder === ph) as HTMLInputElement await act(async () => { setInput(byPlaceholder('us-east-1'), 'ap-northeast-1') setInput(byPlaceholder('my-images'), 'my-images') setInput(byPlaceholder('notes/'), 'blog/') }) const textInputs = inputs.filter((i) => i.type === 'text' || i.type === 'password') // Access Key / Secret Key 是无 placeholder 的两个输入(第 4、5 个字段) await act(async () => { setInput(textInputs[3], 'AKID') setInput(textInputs[4], 'SECRET') }) const checkbox = inputs.find((i) => i.type === 'checkbox') as HTMLInputElement await act(async () => { checkbox.click() }) const saveBtn = [...container.querySelectorAll('button')].find((b) => b.textContent === '保存') as HTMLButtonElement await act(async () => { saveBtn.dispatchEvent(new MouseEvent('click', { bubbles: true })) }) expect(onSave).toHaveBeenCalledTimes(1) const saved = onSave.mock.calls[0][0] expect(saved).toMatchObject({ region: 'ap-northeast-1', bucket: 'my-images', accessKey: 'AKID', secretKey: 'SECRET', prefix: 'blog/', autoUpload: true, }) await act(async () => { root.unmount() }) container.remove() }) })