diff --git a/CLAUDE.md b/CLAUDE.md index ed48e73..9496d90 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -44,3 +44,15 @@ Fall back to Grep/Glob/Read **only** when the graph doesn't cover what you need. 2. Use `detect_changes` for code review. 3. Use `get_affected_flows` to understand impact. 4. Use `query_graph` pattern="tests_for" to check coverage. + +## Local environment / running tests + +- `.env` holds **production** credentials (o2switch host, real DB name/password). Never load it for local runs or tests. +- `.env.local` holds the local dev DB credentials (`DB_HOST=127.0.0.1`, `DB_USER=convert_user`, `DB_NAME=file_converter`, `DB_PASSWORD=change_me`). This is what local testing should use. +- `src/config.js` uses `dotenv/config`, which only loads `.env` and does not override variables already present in `process.env`. There's no vitest/dotenv wiring that picks up `.env.local` automatically. +- To run tests locally without touching prod config, pass the `.env.local` values as inline env vars so they take precedence before `dotenv/config` runs, e.g.: + ``` + DB_HOST=127.0.0.1 DB_USER=convert_user DB_PASSWORD=change_me DB_NAME=file_converter STORAGE_DIR=./storage PORT=3000 npx vitest run + ``` +- A local MariaDB is expected to already be running on `127.0.0.1:3306` with the `file_converter` DB and `convert_user` credentials seeded. +- Known pre-existing failures unrelated to any fix: `test/cleanup.test.js` ("deletes an expired pending job...") and `test/jobs/jobRepository.test.js` ("finds expired jobs and allows deleting them") — both fail on `main` independent of other changes (looks like a clock/timezone mismatch around `expiresAt` comparisons, not yet root-caused). Don't assume a change caused these; verify against `main` first if they show up again. diff --git a/frontend/index.html b/frontend/index.html index f94d687..deea0dd 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -9,5 +9,14 @@
+ diff --git a/src/app.js b/src/app.js index bc2794e..3f5ac7a 100644 --- a/src/app.js +++ b/src/app.js @@ -147,8 +147,9 @@ export function createApp(config, pool) { } const filePath = outputPath(config, job.id, job.targetFormat); + const downloadFilename = `${path.parse(job.originalFilename).name}.${job.targetFormat}`; res.set('Content-Type', job.outputMimeType); - res.set('Content-Disposition', contentDispositionHeader(job.originalFilename)); + res.set('Content-Disposition', contentDispositionHeader(downloadFilename)); fs.createReadStream(filePath).pipe(res); }); diff --git a/test/api/endToEnd.test.js b/test/api/endToEnd.test.js index 6d72f77..a9b8e4f 100644 --- a/test/api/endToEnd.test.js +++ b/test/api/endToEnd.test.js @@ -57,7 +57,7 @@ describe('end-to-end: image family', () => { const downloadResponse = await request(app).get(`/api/jobs/${id}/download`); expect(downloadResponse.status).toBe(200); expect(downloadResponse.headers['content-type']).toBe('image/webp'); - expect(downloadResponse.headers['content-disposition']).toContain('photo.png'); + expect(downloadResponse.headers['content-disposition']).toContain('photo.webp'); }, 20000); }); @@ -82,7 +82,7 @@ describe('end-to-end: document family', () => { const downloadResponse = await request(app).get(`/api/jobs/${id}/download`); expect(downloadResponse.status).toBe(200); expect(downloadResponse.headers['content-type']).toBe('application/pdf'); - expect(downloadResponse.headers['content-disposition']).toContain('report.docx'); + expect(downloadResponse.headers['content-disposition']).toContain('report.pdf'); await fs.unlink(docxPath); }, 20000); diff --git a/test/api/jobStatus.test.js b/test/api/jobStatus.test.js index 344a549..78fad6e 100644 --- a/test/api/jobStatus.test.js +++ b/test/api/jobStatus.test.js @@ -73,7 +73,7 @@ describe('GET /api/jobs/:id/download', () => { expect(response.status).toBe(200); expect(response.headers['content-type']).toBe('image/webp'); - expect(response.headers['content-disposition']).toContain('holiday photo.png'); + expect(response.headers['content-disposition']).toContain('holiday photo.webp'); expect(response.body ?? response.text).toBeDefined(); });