~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/atlibs-knotless

0
0
main
82 lines · 4.0 KB Raw History
// node --test web/knotless/knotless-cubit.test.mjs  (after `cargo wasm`)
// The cubit with the real knotless module, runModule, policyCall and the Node wasm runner; only OAuth
// and the user's PDS are stubbed.
import assert from "node:assert/strict";
import { mkdtemp, readFile } from "node:fs/promises";
import { registerHooks } from "node:module";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { test } from "node:test";

// The page resolves atlibs/ through its import map; Node gets the same mapping here.
registerHooks({
	resolve(specifier, context, next) {
		const lib = specifier.startsWith("atlibs/") && new URL(`./atlibs/${specifier.slice("atlibs/".length)}`, import.meta.url).href;
		return next(lib || specifier, context);
	},
});
const { KnotlessCubit, POLICY } = await import("./knotless-cubit.js");
const { localModule } = await import("./atlibs/run-module/index.js");
const { createNodeContext, fileFetch } = await import("./atlibs/server/index.js");

const did = "did:plc:lpfuqerea3deuoyrn7ojser4";
const modules = new URL("./modules/", import.meta.url);

// A signed-in OAuth session over an in-memory PDS: fetchHandler is what sessionXrpc calls through.
function session(records, writes) {
	return {
		did,
		async fetchHandler(path, init) {
			const [nsid, query] = path.slice("/xrpc/".length).split("?");
			const params = Object.fromEntries(new URLSearchParams(query));
			const body = init?.body && JSON.parse(init.body);
			if (nsid === "com.atproto.repo.getRecord") {
				const value = records[`${params.collection}/${params.rkey}`];
				return value ? Response.json({ value }) : Response.json({ error: "RecordNotFound", message: "Could not locate record" }, { status: 400 });
			}
			if (nsid === "com.atproto.repo.createRecord") {
				writes.push(body);
				records[`${body.collection}/${body.rkey}`] = body.record;
				return Response.json({ uri: `at://${did}/${body.collection}/${body.rkey}`, cid: "bafy" });
			}
			if (nsid === "com.atproto.repo.applyWrites") {
				writes.push(body);
				for (const w of body.writes) records[`${w.collection}/${w.rkey}`] = w.value;
				return Response.json({});
			}
			return Response.json({ error: "InvalidRequest" }, { status: 400 });
		},
	};
}

test("the page's policy is records/knotless.json's scope", async () => {
	const record = JSON.parse(await readFile(new URL("../../records/knotless.json", import.meta.url)));
	assert.equal(POLICY.sessions.knotless.scope, record.clientMetadata.scope);
	const spec = JSON.parse(await readFile(new URL("knotless.json", modules)));
	assert.equal(spec.session, "knotless");
});

test("create a repository, then commit to it, as the signed-in user", async () => {
	const records = {};
	const writes = [];
	const ctx = createNodeContext({ id: "knotless-test", stateDir: await mkdtemp(join(tmpdir(), "knotless-")) });
	const client = Promise.resolve({ init: async () => ({ session: session(records, writes) }), signIn: async () => {}, revoke: async () => {} });
	const knotless = localModule(new URL("knotless.wasm", modules), new URL("knotless.json", modules), fileFetch);
	const cubit = new KnotlessCubit({ ctx, client, knotless });
	await cubit.init();
	assert.equal(cubit.state.did, did);

	await cubit.createRepo({ name: "demo", description: "", defaultBranch: "" });
	assert.equal(cubit.state.run.status, "done", cubit.state.run.error);
	assert.equal(cubit.state.run.result.url, `knotless://${did}/demo`);
	assert.equal(records["dev.knotless.repo/demo"].defaultBranch, "main");

	await cubit.commit({ name: "demo", branch: "main", parent: "", message: "first", author: "", changes: '[{"path": "README.md", "content": "# hello\\n"}]' });
	assert.equal(cubit.state.run.status, "done", cubit.state.run.error);
	assert.equal(cubit.state.run.result.changed, true);
	assert.deepEqual(writes.at(-1).writes.map((w) => w.collection), ["dev.knotless.pack", "dev.knotless.ref"]);

	await cubit.commit({ name: "demo", branch: "main", message: "bad", changes: "[]" });
	assert.equal(cubit.state.run.status, "error");
	assert.match(cubit.state.run.error, /empty/);
});