Revise user data cleanup logic to ensure proper cascading deletion of user-related database rows and S3 objects, including shared document and preview artifacts. Introduce explicit checks for last ownership before removing shared resources. Add TTS segment cache and audio cleanup to document and user deletion flows. Expand user data export to include TTS segment entries and audio, job events, document settings, and linked auth sessions. Update schema with ON DELETE CASCADE for userTtsChars and userJobEvents. Add new migration scripts and comprehensive unit tests for cleanup and export scenarios.
45 lines
1.3 KiB
TypeScript
45 lines
1.3 KiB
TypeScript
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
|
|
const mocks = vi.hoisted(() => ({
|
|
send: vi.fn(),
|
|
}));
|
|
|
|
vi.mock('@/lib/server/storage/s3', () => ({
|
|
getS3Config: () => ({ bucket: 'test-bucket' }),
|
|
getS3Client: () => ({ send: mocks.send }),
|
|
getS3ProxyClient: () => ({ send: mocks.send }),
|
|
}));
|
|
|
|
import { deleteTtsSegmentPrefix } from '../../src/lib/server/tts/segments-blobstore';
|
|
|
|
describe('TTS segment blob cleanup', () => {
|
|
beforeEach(() => {
|
|
mocks.send.mockReset();
|
|
});
|
|
|
|
test('counts successful quiet deletes by requested object count', async () => {
|
|
mocks.send
|
|
.mockResolvedValueOnce({
|
|
Contents: [{ Key: 'prefix/a.mp3' }, { Key: 'prefix/b.mp3' }],
|
|
IsTruncated: false,
|
|
})
|
|
.mockResolvedValueOnce({});
|
|
|
|
await expect(deleteTtsSegmentPrefix('prefix/')).resolves.toBe(2);
|
|
});
|
|
|
|
test('fails cleanup when storage reports per-object deletion errors', async () => {
|
|
mocks.send
|
|
.mockResolvedValueOnce({
|
|
Contents: [{ Key: 'prefix/a.mp3' }],
|
|
IsTruncated: false,
|
|
})
|
|
.mockResolvedValueOnce({
|
|
Errors: [{ Key: 'prefix/a.mp3', Code: 'AccessDenied' }],
|
|
});
|
|
|
|
await expect(deleteTtsSegmentPrefix('prefix/')).rejects.toThrow(
|
|
'Failed deleting 1 TTS segment audio objects',
|
|
);
|
|
});
|
|
});
|