feat: add Husky hooks and fix provider tutorial UI/logic
- Add Husky pre-commit and pre-push hooks for linting, type checking, and build validation - Fix visual hierarchy bug in the provider onboarding tutorial - Remove feedback modal - Move MinIO bucket creation logic to before app startup - Wire MiniMax audio through voice generation pipeline - Fix scene insertion issues - Fix portal tutorial modal and harden panel variant task flow
This commit is contained in:
97
tests/unit/storage/bootstrap.test.ts
Normal file
97
tests/unit/storage/bootstrap.test.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { ensureStorageReady } from '@/lib/storage/bootstrap'
|
||||
|
||||
type MockCommand = {
|
||||
readonly type: 'HeadBucketCommand' | 'CreateBucketCommand'
|
||||
readonly input: Record<string, unknown>
|
||||
}
|
||||
|
||||
const {
|
||||
sendMock,
|
||||
s3ClientMock,
|
||||
headBucketCommandMock,
|
||||
createBucketCommandMock,
|
||||
} = vi.hoisted(() => ({
|
||||
sendMock: vi.fn<(command: MockCommand) => Promise<unknown>>(),
|
||||
s3ClientMock: vi.fn(() => ({ send: undefined as unknown })),
|
||||
headBucketCommandMock: vi.fn((input: Record<string, unknown>): MockCommand => ({
|
||||
type: 'HeadBucketCommand',
|
||||
input,
|
||||
})),
|
||||
createBucketCommandMock: vi.fn((input: Record<string, unknown>): MockCommand => ({
|
||||
type: 'CreateBucketCommand',
|
||||
input,
|
||||
})),
|
||||
}))
|
||||
|
||||
s3ClientMock.mockImplementation(() => ({ send: sendMock }))
|
||||
|
||||
vi.mock('@aws-sdk/client-s3', () => ({
|
||||
S3Client: s3ClientMock,
|
||||
HeadBucketCommand: headBucketCommandMock,
|
||||
CreateBucketCommand: createBucketCommandMock,
|
||||
}))
|
||||
|
||||
describe('storage bootstrap', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
process.env.MINIO_ENDPOINT = 'http://127.0.0.1:9000'
|
||||
process.env.MINIO_REGION = 'us-east-1'
|
||||
process.env.MINIO_BUCKET = 'waoowaoo'
|
||||
process.env.MINIO_ACCESS_KEY = 'minioadmin'
|
||||
process.env.MINIO_SECRET_KEY = 'minioadmin'
|
||||
process.env.MINIO_FORCE_PATH_STYLE = 'true'
|
||||
})
|
||||
|
||||
it('skips startup storage initialization when STORAGE_TYPE=local', async () => {
|
||||
await expect(ensureStorageReady({ storageType: 'local' })).resolves.toBe('skipped')
|
||||
expect(s3ClientMock).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('verifies the MinIO bucket during startup when it already exists', async () => {
|
||||
sendMock.mockResolvedValueOnce({})
|
||||
|
||||
await expect(ensureStorageReady({ storageType: 'minio' })).resolves.toBe('existing')
|
||||
|
||||
expect(s3ClientMock).toHaveBeenCalledWith({
|
||||
endpoint: 'http://127.0.0.1:9000',
|
||||
region: 'us-east-1',
|
||||
forcePathStyle: true,
|
||||
credentials: {
|
||||
accessKeyId: 'minioadmin',
|
||||
secretAccessKey: 'minioadmin',
|
||||
},
|
||||
})
|
||||
expect(headBucketCommandMock).toHaveBeenCalledWith({ Bucket: 'waoowaoo' })
|
||||
expect(createBucketCommandMock).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('creates the MinIO bucket during startup when HeadBucket reports it missing', async () => {
|
||||
sendMock
|
||||
.mockRejectedValueOnce(Object.assign(new Error('missing bucket'), {
|
||||
name: 'NotFound',
|
||||
$metadata: { httpStatusCode: 404 },
|
||||
}))
|
||||
.mockResolvedValueOnce({})
|
||||
|
||||
await expect(ensureStorageReady({ storageType: 'minio' })).resolves.toBe('created')
|
||||
|
||||
expect(headBucketCommandMock).toHaveBeenCalledWith({ Bucket: 'waoowaoo' })
|
||||
expect(createBucketCommandMock).toHaveBeenCalledWith({ Bucket: 'waoowaoo' })
|
||||
expect(sendMock).toHaveBeenNthCalledWith(2, {
|
||||
type: 'CreateBucketCommand',
|
||||
input: { Bucket: 'waoowaoo' },
|
||||
})
|
||||
})
|
||||
|
||||
it('fails fast when MinIO returns a non-bucket-missing error at startup', async () => {
|
||||
const startupError = Object.assign(new Error('MinIO unavailable'), {
|
||||
name: 'TimeoutError',
|
||||
$metadata: { httpStatusCode: 503 },
|
||||
})
|
||||
sendMock.mockRejectedValueOnce(startupError)
|
||||
|
||||
await expect(ensureStorageReady({ storageType: 'minio' })).rejects.toBe(startupError)
|
||||
expect(createBucketCommandMock).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user