const { expect } = require("chai"); /** * Tests for route utility functions. * * We replicate the handleError status-code logic and escapeHtml utility * here so we can test them without starting the Express server or * connecting to a database. */ // --------------------------------------------------------------------------- // Replicated handleError status derivation logic // (mirrors src/server/routes/route-utils.ts) // --------------------------------------------------------------------------- function deriveHttpStatus(error) { let message = error; if (error instanceof Error) { message = error.message; } else if (typeof error !== "string") { message = String(error); } let status = 500; if (error.httpStatus) { status = error.httpStatus; } else if (error.$metadata?.httpStatusCode) { status = error.$metadata.httpStatusCode; } else if ( message && (message.indexOf("not_found") > -1 || message.indexOf("(Not Found)") > -1) ) { status = 404; } else if (message && message.indexOf("not_connected") > -1) { status = 401; } return status; } // --------------------------------------------------------------------------- // Replicated escapeHtml from webview.ts // --------------------------------------------------------------------------- function escapeHtml(str) { return str .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } // --------------------------------------------------------------------------- // Tests // --------------------------------------------------------------------------- describe("deriveHttpStatus", function () { it("returns 500 for a generic error", function () { const status = deriveHttpStatus(new Error("something broke")); expect(status).to.equal(500); }); it("uses httpStatus when present on the error", function () { const err = new Error("bad request"); err.httpStatus = 400; expect(deriveHttpStatus(err)).to.equal(400); }); it("uses $metadata.httpStatusCode for AWS-style errors", function () { const err = { $metadata: { httpStatusCode: 403 }, message: "forbidden" }; expect(deriveHttpStatus(err)).to.equal(403); }); it("returns 404 when message contains not_found", function () { expect(deriveHttpStatus(new Error("repo_not_found"))).to.equal(404); }); it("returns 404 when message contains (Not Found)", function () { expect(deriveHttpStatus(new Error("GitHub (Not Found)"))).to.equal(404); }); it("returns 401 when message contains not_connected", function () { expect(deriveHttpStatus(new Error("not_connected"))).to.equal(401); }); it("prefers httpStatus over message-based detection", function () { const err = new Error("not_found"); err.httpStatus = 503; expect(deriveHttpStatus(err)).to.equal(503); }); it("handles plain string error", function () { expect(deriveHttpStatus("repo_not_found")).to.equal(404); }); it("handles string error for not_connected", function () { expect(deriveHttpStatus("not_connected")).to.equal(401); }); it("returns status from httpStatus on a plain object", function () { expect(deriveHttpStatus({ httpStatus: 429 })).to.equal(429); }); it("returns 500 for a plain object without httpStatus", function () { expect(deriveHttpStatus({})).to.equal(500); }); }); describe("escapeHtml", function () { it("escapes ampersands", function () { expect(escapeHtml("a&b")).to.equal("a&b"); }); it("escapes less-than signs", function () { expect(escapeHtml("'; const escaped = escapeHtml(maliciousName); expect(escaped).to.not.include("