import { describe, expect, it, vi } from "vitest";
import type { Did } from "@atcute/lexicons/syntax";
import { createBobbinClient } from "#lib/api/client.ts";
import { NO_ACCESS, resolveRepoAccess } from "#lib/api/access.ts";
import type { Fetch } from "#lib/fetch.ts";
const owner = "did:plc:owner" as Did;
const repoDid = "did:plc:repo" as Did;
const bobbin = (items: { subject: string }[]) => {
const fetch = vi.fn<Fetch>(
async () =>
new Response(JSON.stringify({ items }), {
status: 200,
headers: { "content-type": "application/json" }
})
);
return { ctx: createBobbinClient({ serviceUrl: "https://bobbin.test", fetch }), fetch };
};
describe("resolveRepoAccess", () => {
it("gives the owner everything without asking the knot", async () => {
const { ctx, fetch } = bobbin([]);
await expect(resolveRepoAccess(ctx, { ownerDid: owner, repoDid }, owner)).resolves.toEqual({
role: "owner",
canPush: true,
canAdminister: true
});
expect(fetch).not.toHaveBeenCalled();
});
it("gives an accepted collaborator push but not administration", async () => {
const { ctx } = bobbin([{ subject: "did:plc:friend" }]);
await expect(
resolveRepoAccess(ctx, { ownerDid: owner, repoDid }, "did:plc:friend")
).resolves.toEqual({ role: "collaborator", canPush: true, canAdminister: false });
});
it("gives a stranger nothing", async () => {
const { ctx } = bobbin([{ subject: "did:plc:friend" }]);
await expect(
resolveRepoAccess(ctx, { ownerDid: owner, repoDid }, "did:plc:stranger")
).resolves.toEqual(NO_ACCESS);
});
it("gives a signed-out viewer nothing", async () => {
const { ctx, fetch } = bobbin([]);
await expect(
resolveRepoAccess(ctx, { ownerDid: owner, repoDid }, undefined)
).resolves.toEqual(NO_ACCESS);
expect(fetch).not.toHaveBeenCalled();
});
it("has no collaborators to check on a repo without a DID", async () => {
const { ctx, fetch } = bobbin([{ subject: "did:plc:friend" }]);
await expect(
resolveRepoAccess(ctx, { ownerDid: owner }, "did:plc:friend")
).resolves.toEqual(NO_ACCESS);
expect(fetch).not.toHaveBeenCalled();
});
});