diff --git a/src/worker.js b/src/worker.js index 6f56b3a..499d28b 100644 --- a/src/worker.js +++ b/src/worker.js @@ -33,7 +33,7 @@ async function processJob(pool, config, job) { } const startedAt = Date.now(); - await withTimeout(entry.convert(inputFilePath, outputFilePath), JOB_TIMEOUT_MS); + await withTimeout(entry.convert(inputFilePath, outputFilePath, { quality: job.quality }), JOB_TIMEOUT_MS); const conversionDurationSeconds = (Date.now() - startedAt) / 1000; const { size: outputSizeBytes } = await fs.stat(outputFilePath); diff --git a/test/worker.test.js b/test/worker.test.js index fdfa591..d5fedf6 100644 --- a/test/worker.test.js +++ b/test/worker.test.js @@ -2,6 +2,7 @@ import { describe, it, expect, beforeAll, afterAll, beforeEach } from 'vitest'; import fs from 'node:fs/promises'; import path from 'node:path'; import os from 'node:os'; +import sharp from 'sharp'; import { getPool, closePool } from '../src/db.js'; import { loadConfig } from '../src/config.js'; import { ensureStorageDirs, uploadPath, outputPath } from '../src/storage.js'; @@ -66,6 +67,58 @@ describe('processPendingJobs', () => { expect(stat.size).toBeGreaterThan(0); }); + it('passes the job quality through to the converter, shrinking output for a low quality value', async () => { + const lowUuid = 'eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee'; + const defaultUuid = 'ffffffff-ffff-4fff-8fff-ffffffffffff'; + + const noisyBuffer = await sharp({ + create: { + width: 256, + height: 256, + channels: 3, + noise: { type: 'gaussian', mean: 128, sigma: 40 }, + }, + }) + .png() + .toBuffer(); + + for (const uuid of [lowUuid, defaultUuid]) { + await fs.writeFile(uploadPath(config, uuid, 'png'), noisyBuffer); + } + + await createJob(pool, { + uuid: lowUuid, + family: 'image', + sourceFormat: 'png', + targetFormat: 'jpg', + originalFilename: 'noisy.png', + inputPath: `${lowUuid}.png`, + inputMimeType: 'image/png', + inputSizeBytes: noisyBuffer.length, + expiresAt: new Date(Date.now() + 3600 * 1000), + quality: 5, + }); + await createJob(pool, { + uuid: defaultUuid, + family: 'image', + sourceFormat: 'png', + targetFormat: 'jpg', + originalFilename: 'noisy.png', + inputPath: `${defaultUuid}.png`, + inputMimeType: 'image/png', + inputSizeBytes: noisyBuffer.length, + expiresAt: new Date(Date.now() + 3600 * 1000), + }); + + await processPendingJobs(pool, { ...config, workerConcurrency: 2 }); + + const lowJob = await getJobByUuid(pool, lowUuid); + const defaultJob = await getJobByUuid(pool, defaultUuid); + expect(lowJob.status).toBe('done'); + expect(defaultJob.status).toBe('done'); + expect(lowJob.outputSizeBytes).toBeLessThan(defaultJob.outputSizeBytes); + }); + it('marks a job failed with a safe message and a detailed log when the converter throws', async () => { const uuid = 'aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa'; await createJob(pool, {