feat!: le paquet crée un index et lui ajoute une référence, rien de plus
This commit is contained in:
+48
-40
@@ -1,62 +1,70 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { expect, mock, 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 * as published from "../src/index";
|
||||
import { ENTRY_VALUE, INDEX_FIELD, indexing } from "../src/index";
|
||||
import { indexingOn } from "../src/indexing";
|
||||
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 () => {
|
||||
test("the published surface carries both acts, end to end", async () => {
|
||||
const network = new FakeNextGraph();
|
||||
const ownerPort: NextGraphPort = network.portFor("alice");
|
||||
const strangerPort: NextGraphPort = network.portFor("bob");
|
||||
const ownerPort = network.portFor("alice");
|
||||
const strangerPort = network.portFor("bob");
|
||||
|
||||
const owner = await indexing(ownerPort);
|
||||
const stranger = await indexing(strangerPort);
|
||||
// `indexingOn` is what `indexing(sessionId)` calls once it has built the port for
|
||||
// you: the two acts below are the published ones, reached here over an in-memory
|
||||
// NextGraph. `adapter.test.ts` drives these same acts through the real adapter.
|
||||
const owner = indexingOn(ownerPort);
|
||||
const stranger = indexingOn(strangerPort);
|
||||
|
||||
const index = await owner.createIndex(PUBLISHED_AT);
|
||||
const index = await owner.create(PUBLISHED_AT);
|
||||
const article = await publishObject(strangerPort, PUBLISHED_AT, "2026-07-08");
|
||||
await stranger.refer(index, article);
|
||||
await stranger.add(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" }]);
|
||||
// What the two acts leave behind, and the whole of it: a document declaring its
|
||||
// field, and a bare reference waiting in its inbox. Making an entry of that
|
||||
// reference is the business of the layer below, and there is nothing on this
|
||||
// surface that does it or asks for it.
|
||||
expect(network.contentsOf(index)).toEqual([
|
||||
{ subject: index, predicate: INDEX_FIELD, values: [PUBLISHED_AT] },
|
||||
]);
|
||||
expect(network.depositsIn(index)?.map((deposit) => deposit.payload)).toEqual([article]);
|
||||
});
|
||||
|
||||
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 offers TWO acts, and neither reads nor processes anything", () => {
|
||||
const handle = indexingOn(new FakeNextGraph().portFor("alice"));
|
||||
// Read off the handle rather than from a list: an application gets these two acts
|
||||
// and nothing else. Reading an index is not one of them, and neither is anything
|
||||
// that would make its deposits into entries.
|
||||
expect(Object.keys(handle).sort()).toEqual(["add", "create"]);
|
||||
});
|
||||
|
||||
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();
|
||||
test("the package publishes ONE function and the two IRIs, and nothing else", () => {
|
||||
// Read off the module rather than from a list of names to remember: publishing a
|
||||
// helper again — a port builder, a deposit decoder, a read — fails here first.
|
||||
expect(Object.keys(published).sort()).toEqual(["ENTRY_VALUE", "INDEX_FIELD", "indexing"]);
|
||||
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([]);
|
||||
test("indexing takes a session id and reaches nothing at all", () => {
|
||||
// The REAL polyfill, unconfigured — which would fail every call that needs a
|
||||
// broker. Building the handle does not make one, so this passes without any
|
||||
// arrangement, and there is nothing on the log stream to report. It also proves
|
||||
// the entry point builds its own port: an application hands over the session id
|
||||
// `init(…)` gave it, and never sees a port at all.
|
||||
const reported = mock((..._args: unknown[]) => {});
|
||||
const original = console.error;
|
||||
console.error = reported;
|
||||
try {
|
||||
const handle = indexing("session-under-test");
|
||||
expect(Object.keys(handle).sort()).toEqual(["add", "create"]);
|
||||
} finally {
|
||||
console.error = original;
|
||||
}
|
||||
expect(reported).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user