Skip to content

Commit

Permalink
Added tests for the probational endpoints.
Browse files Browse the repository at this point in the history
  • Loading branch information
LTLA committed Dec 1, 2023
1 parent d0a3566 commit 15b154f
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 4 deletions.
11 changes: 7 additions & 4 deletions src/probation.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import * as utils from "./utils.js";
import * as auth from "./auth.js";
import * as s3 from "./s3.js";
import * as pkeys from "./internal.js";
import * as lock from "./lock.js";

export async function approveProbationHandler(request, nonblockers) {
let project = decodeURIComponent(request.params.project);
Expand All @@ -20,7 +23,7 @@ export async function approveProbationHandler(request, nonblockers) {
throw new utils.HttpError("probational version does not exist", 400);
}

let info = JSON.parse(raw_info);
let info = await raw_info.json();
if (!("on_probation" in info) || !info.on_probation) {
throw new utils.HttpError("cannot approve probation for non-probational version", 400);
}
Expand All @@ -43,7 +46,7 @@ export async function rejectProbationHandler(request, nonblockers) {
let version = decodeURIComponent(request.params.version);

let token = auth.extractBearerToken(request);
let { status, user } = await auth.checkProjectUploadPermissions(project, asset, version, token, nonblockers);
let { can_manage, is_trusted, user } = await auth.checkProjectUploadPermissions(project, asset, version, token, nonblockers);

let bound_bucket = s3.getR2Binding();
let session_key = crypto.randomUUID();
Expand All @@ -56,12 +59,12 @@ export async function rejectProbationHandler(request, nonblockers) {
throw new utils.HttpError("probational version does not exist", 400);
}

let info = JSON.parse(raw_info);
let info = await raw_info.json();
if (!("on_probation" in info) || !info.on_probation) {
throw new utils.HttpError("cannot reject probation for non-probational version", 400);
}

if (status !== "owner" && user.login !== info.upload_user_id) {
if (!can_manage && user.login !== info.upload_user_id) {
throw new utils.HttpError("cannot reject probation for different user", 400);
}

Expand Down
77 changes: 77 additions & 0 deletions tests/probation.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import * as f_ from "../src/index.js";
import * as prob from "../src/probation.js";
import * as auth from "../src/auth.js";
import * as s3 from "../src/s3.js";
import * as gh from "../src/github.js";
import * as setup from "./setup.js";

beforeAll(async () => {
let rigging = gh.enableTestRigging();
setup.mockGitHubIdentities(rigging);
})

afterAll(() => {
gh.enableTestRigging(false);
})

test("probation approval works as expected", async () => {
await setup.mockProject();
let sumpath = "test/blob/v1/..summary";
let existing = await (await BOUND_BUCKET.get(sumpath)).json();
existing.on_probation = true;
await BOUND_BUCKET.put(sumpath, JSON.stringify(existing), setup.jsonmeta);

let req = new Request("http://localhost", { method: "DELETE" });
req.params = { project: "test", asset: "blob", version: "v1" };
req.query = {};

// Doesn't work without sufficient permissions.
req.headers.set("Authorization", "Bearer " + setup.mockTokenUser);
await setup.expectError(prob.approveProbationHandler(req, []), "not an owner");

// Success!
req.headers.set("Authorization", "Bearer " + setup.mockTokenOwner);
await prob.approveProbationHandler(req, []);
let refreshed = await (await BOUND_BUCKET.get(sumpath)).json();
expect("on_probation" in refreshed).toBe(false);

// Repeated attempt fails.
await setup.expectError(prob.approveProbationHandler(req, []), "non-probational");

// Fails if it can't find anything.
req.params = { project: "test", asset: "blob", version: "v2" };
await setup.expectError(prob.approveProbationHandler(req, []), "does not exist");
})

test("probation rejection works as expected", async () => {
await setup.mockProject();

let req = new Request("http://localhost", { method: "DELETE" });
req.params = { project: "test", asset: "blob", version: "v1" };
req.query = {};
req.headers.set("Authorization", "Bearer " + setup.mockTokenOwner);
await setup.expectError(prob.rejectProbationHandler(req, []), "non-probational");

// Setting the probational flag.
let sumpath = "test/blob/v1/..summary";
let existing = await (await BOUND_BUCKET.get(sumpath)).json();
existing.on_probation = true;
await BOUND_BUCKET.put(sumpath, JSON.stringify(existing), setup.jsonmeta);

// Doesn't work without sufficient permissions.
req.headers.set("Authorization", "Bearer " + setup.mockTokenUser);
await setup.expectError(prob.rejectProbationHandler(req, []), "not authorized to upload");

await BOUND_BUCKET.put("test/..permissions", '{ "owners": [ "ProjectOwner" ], "uploaders": [ { "id": "RandomDude" } ] }');
await auth.flushCachedPermissions("test", []);
await setup.expectError(prob.rejectProbationHandler(req, []), "different user");

// Success!
req.headers.set("Authorization", "Bearer " + setup.mockTokenOwner);
await prob.rejectProbationHandler(req, []);
expect(await BOUND_BUCKET.head(sumpath)).toBeNull()

// Fails if it can't find anything.
req.params = { project: "test", asset: "blob", version: "v2" };
await setup.expectError(prob.rejectProbationHandler(req, []), "does not exist");
})

0 comments on commit 15b154f

Please sign in to comment.