CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /**
* Smoke tests for the new AI-PR-description endpoint:
* POST /:owner/:repo/ai/pr-description
*
* The route requires write access, so unauthenticated callers should
* never see a 200/JSON body. Authenticated paths require a live DB +
* git checkout, so we focus on the auth-guard contract.
*/
import { describe, it, expect } from "bun:test";
import app from "../app";
describe("POST /:owner/:repo/ai/pr-description — auth guard", () => {
it("redirects to /login when unauthenticated (no bearer)", async () => {
const res = await app.request(
"/alice/demo/ai/pr-description",
{
method: "POST",
headers: { "content-type": "application/x-www-form-urlencoded" },
body: "title=Test&base=main&head=feature",
redirect: "manual",
}
);
// Either a 302 to /login (cookie flow), or a 4xx/5xx if requireAuth
// / requireRepoAccess fail-closed earlier. The one thing we MUST NOT
// see is a 200 with a leaked body.
expect([301, 302, 303, 307, 401, 403, 404, 503]).toContain(res.status);
if (res.status === 302 || res.status === 303 || res.status === 307) {
const loc = res.headers.get("location") || "";
expect(loc).toContain("/login");
}
});
it("rejects bogus bearer tokens with 401", async () => {
const res = await app.request(
"/alice/demo/ai/pr-description",
{
method: "POST",
headers: {
"content-type": "application/x-www-form-urlencoded",
authorization: "Bearer glct_definitely-not-valid",
},
body: "title=Test&base=main&head=feature",
}
);
expect([401, 403, 404, 503]).toContain(res.status);
});
});
|