fix(media): stream large files and honour size settings (#3387)

This commit is contained in:
Hampus authored and GitHub committed 2026-10-11 13:28:24 +02:00
1 parent 6acd7f3d22
commit 45b78a13c2
97 files changed
+2547 -409

No files matched your search

@@ -2,8 +2,10 @@
import {AttachmentDecayRepository} from '@app/api/attachment/AttachmentDecayRepository';
import {createAttachmentID, createChannelID, createMessageID} from '@app/api/BrandedTypes';
import {getConfig} from '@app/api/Config';
import type {IAssetDeletionQueue, QueuedAssetDeletion} from '@app/api/infrastructure/IAssetDeletionQueue';
import type {InstanceConfigRepository} from '@app/api/instance/InstanceConfigRepository';
import {MockKVProvider} from '@app/api/test/mocks/MockKVProvider';
import {getExpiryBucket} from '@app/api/utils/AttachmentDecay';
import {processExpiredAttachments} from '@app/api/worker/tasks/ExpireAttachments';
import {clearWorkerDependencies, setWorkerDependenciesForTest} from '@app/api/worker/WorkerContext';
@@ -28,9 +30,10 @@ function createQueue(): {queue: IAssetDeletionQueue; queued: Array<QueuedAssetDe
return {queue, queued};
}
function installDependencies(queue: IAssetDeletionQueue): void {
function installDependencies(queue: IAssetDeletionQueue, kvClient = new MockKVProvider()): void {
setWorkerDependenciesForTest({
assetDeletionQueue: queue,
kvClient,
instanceConfigRepository: {
async getEffectiveAttachmentDecayConfig() {
return {enabled: true};
@@ -57,10 +60,29 @@ async function writeDecayRecord(repository: AttachmentDecayRepository, expiresAt
}
describe('processExpiredAttachments', () => {
const originalSelfHosted = getConfig().instance.selfHosted;
afterEach(() => {
getConfig().instance.selfHosted = originalSelfHosted;
clearWorkerDependencies();
});
it.each([
[true, []],
[false, [`attachments/${CHANNEL_ID}/${ATTACHMENT_ID}/${FILENAME}`]],
])('pauses deletion during a reconcile run only when self-hosted (%s)', async (selfHosted, expectedKeys) => {
getConfig().instance.selfHosted = selfHosted;
const repository = new AttachmentDecayRepository();
const {queue, queued} = createQueue();
const kvClient = new MockKVProvider();
await kvClient.setex('attachment_decay:reconcile_run', 60, 'run');
installDependencies(queue, kvClient);
await writeDecayRecord(repository, FIRST_EXPIRY);
await processExpiredAttachments(new Date(FIRST_EXPIRY.getTime() + ms('1 day')));
expect(queued.map((item) => item.s3Key)).toEqual(expectedKeys);
});
it('keeps the decay record when it clears a superseded expiry row', async () => {
const repository = new AttachmentDecayRepository();
const {queue} = createQueue();