Files
ng-helpers/test/public-surface.test.ts
T

63 lines
2.8 KiB
TypeScript

import { expect, test } from "bun:test";
// Deliberately the PACKAGE ENTRY POINT, not the modules behind it: this is the
// surface an application gets, and it must be usable on its own. It pulls in
// `polyfill-adapter.ts`, so this also proves the real `@ng-eventually/polyfill`
// still loads and still exports everything this package compiles against.
import {
indexing,
decodeReference,
polyfillPort,
ENTRY_VALUE,
INDEX_FIELD,
type IndexEntry,
type NextGraphPort,
} from "../src/index";
import { FakeNextGraph, publishObject } from "./fake-nextgraph";
const PUBLISHED_AT = "http://schema.org/datePublished";
test("the published surface carries the whole loop, end to end", async () => {
const network = new FakeNextGraph();
const ownerPort: NextGraphPort = network.portFor("alice");
const strangerPort: NextGraphPort = network.portFor("bob");
const owner = await indexing(ownerPort);
const stranger = await indexing(strangerPort);
const index = await owner.createIndex(PUBLISHED_AT);
const article = await publishObject(strangerPort, PUBLISHED_AT, "2026-07-08");
await stranger.refer(index, article);
// NOBODY CURATES — there is nothing on this surface to call. Alice is connected,
// so her session is told a deposit landed and processes that inbox itself.
await network.deliverNotifications();
const entries: IndexEntry[] = await owner.read(index);
expect(entries).toEqual([{ object: article, value: "2026-07-08" }]);
});
test("the published surface offers no way to run, aim or schedule curation", async () => {
const handle = await indexing(new FakeNextGraph().portFor("alice"));
// Read off the handle rather than from a list: an application gets these three
// acts and nothing else, and curation is not one of them.
expect(Object.keys(handle).sort()).toEqual(["createIndex", "read", "refer"]);
});
test("the published surface exposes the deposit decoder and the two IRIs it writes", () => {
expect(decodeReference("did:ng:o:doc-1")).toBe("did:ng:o:doc-1");
expect(decodeReference({ object: "did:ng:o:doc-1" })).toBeNull();
expect(INDEX_FIELD).toBe("urn:ng-helpers:index:field");
expect(ENTRY_VALUE).toBe("urn:ng-helpers:index:value");
});
test("polyfillPort is published and builds a port without a live session", () => {
// Constructing it must not touch the broker — an application wires it at
// startup, and only the calls on it talk to anything.
const port: NextGraphPort = polyfillPort({ sessionId: "session-under-test" });
expect(typeof port.resolveObject).toBe("function");
expect(typeof port.addLiteralProperty).toBe("function");
// The port has NO operation that could take an entry out of an index.
const removing = Object.keys(port).filter((name) => /delete|remove|clear|drop/i.test(name));
expect(removing).toEqual([]);
});