import assert from "node:assert/strict" import test from "node:test" import { createHash } from "node:crypto" import { readFileSync } from "node:fs" import { createRequire } from "node:module" import path from "node:path" import vm from "node:vm" import ts from "typescript" import Fastify from "fastify" import { getTableColumns, getTableName } from "drizzle-orm" import { PgDialect } from "drizzle-orm/pg-core" // Load the real route with only file storage replaced; tests never contact S3 or a live database. const routePath = path.resolve(__dirname, "../src/routes/instanceAgentGateway.ts") const routeRequire = createRequire(routePath) const compiled = ts.transpileModule(readFileSync(routePath, "utf8"), { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022, esModuleInterop: true }, }).outputText const fixture = async (status = "running") => { const token = "test-agent-token" const agent = { id: "agent", tokenHash: createHash("sha256").update(token).digest("hex"), active: true } const job: any = { id: "job", agentId: "agent", tenantId: 7, requestedBy: "user", requestedFilename: "scan.png", target: { folder: "folder" }, status } const saved: any[] = [] const rows: Record = { instance_agents: [agent], instance_agent_scan_jobs: [job] } const dialect = new PgDialect() const matching = (table: any, condition: any) => { const query = dialect.sqlToQuery(condition) const columns = getTableColumns(table) as Record const clauses = [...query.sql.matchAll(/"\w+"\."(\w+)" (?:= \$(\d+)|in \(([^)]+)\))/g)] assert.ok(clauses.length, query.sql) return rows[getTableName(table)].filter(row => clauses.every(match => { const key = Object.keys(columns).find(key => columns[key].name === match[1])! if (match[2]) return row[key] === query.params[Number(match[2]) - 1] return [...match[3].matchAll(/\$(\d+)/g)].some(parameter => row[key] === query.params[Number(parameter[1]) - 1]) })) } const db = { select: () => ({ from: (table: any) => ({ where: (where: any) => ({ limit: async () => matching(table, where) }) }) }), update: (table: any) => ({ set: (data: any) => ({ where: (where: any) => ({ returning: async () => matching(table, where).map(row => Object.assign(row, data)) }) }) }), } const exports: any = {} vm.runInNewContext(compiled, { exports, require: (name: string) => name === "../utils/files" ? { saveFile: async (...args: any[]) => { saved.push(args); return { id: "saved-file" } } } : routeRequire(name), }) const app = Fastify() app.decorate("db", db) await app.register(exports.default) return { app, job, saved, headers: { "x-agent-token": token } } } test("late failure status cannot overwrite an already completed scan", async (t) => { const f = await fixture("completed") t.after(() => f.app.close()) const response = await f.app.inject({ method: "POST", url: "/scan-jobs/job/status", headers: f.headers, payload: { status: "failed", message: "upload timeout" } }) assert.equal(response.statusCode, 409) assert.equal(f.job.status, "completed") }) test("running jobs accept progress and scanner failures", async (t) => { const f = await fixture() t.after(() => f.app.close()) for (const status of ["running", "failed"]) { const response = await f.app.inject({ method: "POST", url: "/scan-jobs/job/status", headers: f.headers, payload: { status, message: "4 Seiten" } }) assert.equal(response.statusCode, 200) assert.equal(f.job.status, status) } }) test("upload preserves the actual PDF filename, tenant and target folder", async (t) => { const f = await fixture() t.after(() => f.app.close()) const boundary = "fedeo-test-boundary" const response = await f.app.inject({ method: "POST", url: "/scan-jobs/job/upload", headers: { ...f.headers, "content-type": `multipart/form-data; boundary=${boundary}` }, payload: `--${boundary}\r\nContent-Disposition: form-data; name="file"; filename="scan.pdf"\r\nContent-Type: application/pdf\r\n\r\n%PDF-test\r\n--${boundary}--\r\n`, }) assert.equal(response.statusCode, 200, response.body) assert.equal(f.saved[0][1], 7) assert.equal(f.saved[0][3].filename, "scan.pdf") assert.equal(f.saved[0][3].contentType, "application/pdf") assert.equal(f.saved[0][4], "folder") assert.equal(f.job.status, "completed") assert.equal(f.job.fileId, "saved-file") })