mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-04-21 21:06:01 +02:00
Fix 9 bugs and add 103 tests for core anonymization, config, and routing (#669)
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
const { expect } = require("chai");
|
||||
|
||||
/**
|
||||
* Tests for AnonymousError.toString() formatting logic.
|
||||
*
|
||||
* The toString() method has branching logic based on the type of the
|
||||
* `value` property (Repository, AnonymizedFile, GitHubRepository, User,
|
||||
* GitHubBase, or plain object). We simulate these types to test each
|
||||
* branch without importing the actual classes.
|
||||
*/
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Simulated AnonymousError
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class AnonymousError extends Error {
|
||||
constructor(message, opt) {
|
||||
super(message);
|
||||
this.value = opt?.object;
|
||||
this.httpStatus = opt?.httpStatus;
|
||||
this.cause = opt?.cause;
|
||||
}
|
||||
|
||||
toString() {
|
||||
let out = "";
|
||||
let detail = this.value ? JSON.stringify(this.value) : null;
|
||||
|
||||
// Simulate the instanceof checks with duck typing
|
||||
if (this.value && this.value.__type === "Repository") {
|
||||
detail = this.value.repoId;
|
||||
} else if (this.value && this.value.__type === "AnonymizedFile") {
|
||||
detail = `/r/${this.value.repository.repoId}/${this.value.anonymizedPath}`;
|
||||
} else if (this.value && this.value.__type === "GitHubRepository") {
|
||||
detail = `${this.value.fullName}`;
|
||||
} else if (this.value && this.value.__type === "User") {
|
||||
detail = `${this.value.username}`;
|
||||
} else if (this.value && this.value.__type === "GitHubBase") {
|
||||
detail = `GHDownload ${this.value.data.repoId}`;
|
||||
}
|
||||
|
||||
out += this.message;
|
||||
if (detail) {
|
||||
out += `: ${detail}`;
|
||||
}
|
||||
if (this.cause) {
|
||||
out += `\n\tCause by ${this.cause}\n${this.cause.stack}`;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Tests
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe("AnonymousError.toString()", function () {
|
||||
describe("message formatting", function () {
|
||||
it("outputs the error message", function () {
|
||||
const err = new AnonymousError("repo_not_found");
|
||||
expect(err.toString()).to.equal("repo_not_found");
|
||||
});
|
||||
|
||||
it("outputs message with httpStatus on the object", function () {
|
||||
const err = new AnonymousError("repo_not_found", { httpStatus: 404 });
|
||||
expect(err.httpStatus).to.equal(404);
|
||||
expect(err.toString()).to.equal("repo_not_found");
|
||||
});
|
||||
});
|
||||
|
||||
describe("detail from value types", function () {
|
||||
it("formats Repository value as repoId", function () {
|
||||
const err = new AnonymousError("error", {
|
||||
object: { __type: "Repository", repoId: "my-anon-repo" },
|
||||
});
|
||||
expect(err.toString()).to.equal("error: my-anon-repo");
|
||||
});
|
||||
|
||||
it("formats AnonymizedFile value as /r/{repoId}/{path}", function () {
|
||||
const err = new AnonymousError("file_not_found", {
|
||||
object: {
|
||||
__type: "AnonymizedFile",
|
||||
repository: { repoId: "abc123" },
|
||||
anonymizedPath: "src/XXXX-1/file.ts",
|
||||
},
|
||||
});
|
||||
expect(err.toString()).to.equal(
|
||||
"file_not_found: /r/abc123/src/XXXX-1/file.ts"
|
||||
);
|
||||
});
|
||||
|
||||
it("formats GitHubRepository value as fullName", function () {
|
||||
const err = new AnonymousError("error", {
|
||||
object: { __type: "GitHubRepository", fullName: "owner/repo" },
|
||||
});
|
||||
expect(err.toString()).to.equal("error: owner/repo");
|
||||
});
|
||||
|
||||
it("formats User value as username", function () {
|
||||
const err = new AnonymousError("error", {
|
||||
object: { __type: "User", username: "jdoe" },
|
||||
});
|
||||
expect(err.toString()).to.equal("error: jdoe");
|
||||
});
|
||||
|
||||
it("formats GitHubBase value as GHDownload {repoId}", function () {
|
||||
const err = new AnonymousError("error", {
|
||||
object: {
|
||||
__type: "GitHubBase",
|
||||
data: { repoId: "download-123" },
|
||||
},
|
||||
});
|
||||
expect(err.toString()).to.equal("error: GHDownload download-123");
|
||||
});
|
||||
|
||||
it("formats plain object as JSON.stringify", function () {
|
||||
const err = new AnonymousError("error", {
|
||||
object: { key: "value" },
|
||||
});
|
||||
expect(err.toString()).to.equal('error: {"key":"value"}');
|
||||
});
|
||||
|
||||
it("formats string value as JSON string", function () {
|
||||
const err = new AnonymousError("error", {
|
||||
object: "some-id",
|
||||
});
|
||||
expect(err.toString()).to.equal('error: "some-id"');
|
||||
});
|
||||
|
||||
it("formats number value", function () {
|
||||
const err = new AnonymousError("error", {
|
||||
object: 42,
|
||||
});
|
||||
expect(err.toString()).to.equal("error: 42");
|
||||
});
|
||||
});
|
||||
|
||||
describe("null/undefined value", function () {
|
||||
it("outputs only message when value is null", function () {
|
||||
const err = new AnonymousError("error", { object: null });
|
||||
expect(err.toString()).to.equal("error");
|
||||
});
|
||||
|
||||
it("outputs only message when value is undefined", function () {
|
||||
const err = new AnonymousError("error", { object: undefined });
|
||||
expect(err.toString()).to.equal("error");
|
||||
});
|
||||
|
||||
it("outputs only message when no opt is passed", function () {
|
||||
const err = new AnonymousError("error");
|
||||
expect(err.toString()).to.equal("error");
|
||||
});
|
||||
});
|
||||
|
||||
describe("cause formatting", function () {
|
||||
it("includes cause message and stack when cause is present", function () {
|
||||
const cause = new Error("original error");
|
||||
const err = new AnonymousError("wrapper", { cause });
|
||||
const str = err.toString();
|
||||
expect(str).to.include("wrapper");
|
||||
expect(str).to.include("Cause by");
|
||||
expect(str).to.include("original error");
|
||||
});
|
||||
|
||||
it("omits cause section when no cause", function () {
|
||||
const err = new AnonymousError("error", { object: "test" });
|
||||
expect(err.toString()).to.not.include("Cause by");
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user