Files
anonymous_github/test/database-storage.test.js
T

180 lines
5.7 KiB
JavaScript

const { expect } = require("chai");
const { join } = require("path");
/**
* Tests for database input validation guards and Storage.repoPath(),
* plus the extractZip decodeString path-stripping logic.
*
* The database functions (getRepository, getPullRequest) validate their
* input before querying MongoDB. We replicate those guards here.
* Storage.repoPath() is a pure function we can test directly.
*/
// ---------------------------------------------------------------------------
// Replicated database input validation
// ---------------------------------------------------------------------------
function validateRepoId(repoId) {
if (!repoId || repoId == "undefined") {
throw new Error("repo_not_found");
}
}
function validatePullRequestId(pullRequestId) {
if (!pullRequestId || pullRequestId == "undefined") {
throw new Error("pull_request_not_found");
}
}
// ---------------------------------------------------------------------------
// Replicated Storage.repoPath() from src/core/storage/Storage.ts
// ---------------------------------------------------------------------------
function repoPath(repoId) {
return join(repoId, "original") + "/";
}
// ---------------------------------------------------------------------------
// Replicated extractZip decodeString from FileSystem.ts
// ---------------------------------------------------------------------------
function decodeZipEntryName(name) {
const newName = name.substr(name.indexOf("/") + 1);
if (newName == "") {
return "___IGNORE___";
}
return newName;
}
// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------
describe("Database input validation", function () {
describe("getRepository guard", function () {
it("rejects null repoId", function () {
expect(() => validateRepoId(null)).to.throw("repo_not_found");
});
it("rejects undefined repoId", function () {
expect(() => validateRepoId(undefined)).to.throw("repo_not_found");
});
it('rejects the string "undefined"', function () {
expect(() => validateRepoId("undefined")).to.throw("repo_not_found");
});
it("rejects empty string", function () {
expect(() => validateRepoId("")).to.throw("repo_not_found");
});
it("accepts a valid repoId string", function () {
expect(() => validateRepoId("my-repo-123")).to.not.throw();
});
it("accepts a numeric-looking repoId", function () {
expect(() => validateRepoId("12345")).to.not.throw();
});
});
describe("getPullRequest guard", function () {
it("rejects null pullRequestId", function () {
expect(() => validatePullRequestId(null)).to.throw(
"pull_request_not_found"
);
});
it("rejects undefined pullRequestId", function () {
expect(() => validatePullRequestId(undefined)).to.throw(
"pull_request_not_found"
);
});
it('rejects the string "undefined"', function () {
expect(() => validatePullRequestId("undefined")).to.throw(
"pull_request_not_found"
);
});
it("rejects empty string", function () {
expect(() => validatePullRequestId("")).to.throw(
"pull_request_not_found"
);
});
it("accepts a valid pullRequestId string", function () {
expect(() => validatePullRequestId("my-pr-42")).to.not.throw();
});
});
});
describe("Storage.repoPath()", function () {
it("returns {repoId}/original/ for a simple repoId", function () {
expect(repoPath("abc123")).to.equal("abc123/original/");
});
it("joins with path separator", function () {
const result = repoPath("my-repo");
expect(result).to.equal("my-repo/original/");
});
it("handles repoId with hyphens", function () {
expect(repoPath("my-anon-repo")).to.equal("my-anon-repo/original/");
});
it("handles repoId with underscores", function () {
expect(repoPath("repo_123")).to.equal("repo_123/original/");
});
it("always ends with a forward slash", function () {
expect(repoPath("test").endsWith("/")).to.be.true;
});
it("always includes 'original' subdirectory", function () {
expect(repoPath("any-repo")).to.include("/original");
});
});
describe("extractZip decodeString (path stripping)", function () {
it("strips the root folder prefix from zip entries", function () {
// GitHub zip archives have a root folder like "owner-repo-commitsha/"
expect(decodeZipEntryName("owner-repo-abc123/src/file.ts")).to.equal(
"src/file.ts"
);
});
it("strips only the first path component", function () {
expect(decodeZipEntryName("root/a/b/c.txt")).to.equal("a/b/c.txt");
});
it('returns ___IGNORE___ for root directory entry (trailing /)', function () {
// Root folder entry is like "owner-repo-abc123/"
// After substr(indexOf("/")+1), the result is ""
expect(decodeZipEntryName("owner-repo-abc123/")).to.equal("___IGNORE___");
});
it("handles files directly under root", function () {
expect(decodeZipEntryName("root/README.md")).to.equal("README.md");
});
it("handles deeply nested paths", function () {
expect(decodeZipEntryName("root/a/b/c/d/e/f.txt")).to.equal(
"a/b/c/d/e/f.txt"
);
});
it("handles entry with no slash (file at root level)", function () {
// If there's no "/", indexOf returns -1, substr(0) returns the whole string
expect(decodeZipEntryName("justfile.txt")).to.equal("justfile.txt");
});
it("handles entry that is just a slash", function () {
expect(decodeZipEntryName("/")).to.equal("___IGNORE___");
});
it("preserves the rest of the path structure", function () {
const result = decodeZipEntryName("prefix/src/components/App.tsx");
expect(result).to.equal("src/components/App.tsx");
});
});