testRegistryCreditsAreMergeEntries

tcmts.registry.test.testRegistryCreditsAreMergeEntries · #2264y3pn · function

A codebase's credits are its merge entries' Contributed-by: lines: one in an entry that isn't a merge credits no one. Read again at a later head, only the entries since are read (and none twice); at a head whose history doesn't hold the one before (pushed over), they're read again whole, in place of what was kept. Whoever's credited is someone the registry knows.

import { onBranch } from "#codebase/tcmts/cli/contributions";
import { save } from "#codebase/tcmts/cli/main";
import { mergeBranch } from "#codebase/tcmts/cli/merge";
import { publicRemote } from "#codebase/tcmts/cli/sync";
import { startFakeAtproto } from "#codebase/tcmts/cli/test/e2e/examples";
import { tempDir, withChildren } from "#codebase/tcmts/cli/test/e2e/harness";
import { credits, people, readCredits } from "#codebase/tcmts/registry";
import { codebaseHolding, served, withEnv } from "#codebase/tcmts/registry/test";
import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";

export const testRegistryCreditsAreMergeEntries = () =>
  withChildren(async (keep) => {
    const maya = {
      did: "did:plc:maya0000000000000000000",
      handle: "maya.test",
      password: "m-pass",
    };
    const net = await startFakeAtproto(keep, [maya]);
    const notes = codebaseHolding(
      "credited notes",
      `// tcm: namespace notes\nexport const title = "Notes";\n`,
      "notes",
    );
    const file = path.join(notes.dir, "scratch.ts");
    const credit = `Contributed-by: @maya.test ${maya.did}`;
    // (a change on a branch of maya's, merged as the server merges a contribution: an entry of its own, crediting her)
    const contribute = (branch: string, code: string, title: string) => {
      notes.cb.store.createBranch(branch);
      onBranch(notes.cb, branch, () => {
        notes.cb.store.endBatch();
        fs.writeFileSync(file, code);
        save(notes.cb, file, "add");
      });
      notes.cb.store.endBatch();
      notes.cb.store.message = `${title}\n\n${credit}`;
      try {
        mergeBranch(notes.cb, branch, `merge: ${title}`, true);
      } finally {
        notes.cb.store.message = undefined;
      }
    };
    contribute("@maya.test/a", `// tcm: namespace notes\nexport const a = 1;\n`, "Adds a");
    // (an entry of main's own saying it, not a merge: no one's credited)
    notes.cb.store.endBatch();
    notes.cb.store.message = `Not a merge\n\n${credit}`;
    fs.writeFileSync(file, `// tcm: namespace notes\nexport const b = 2;\n`);
    save(notes.cb, file, "add");
    notes.cb.store.message = undefined;
    const url = await served(keep, notes.cb);
    const uri = `at://did:plc:alice/codes.tcm.codebase/notes`;
    await withEnv(
      {
        ATPROTO_DIRECTORY: net.url,
        ATPROTO_ALLOW_LOCAL: "1",
        TCM_REGISTRY_CODEBASE: tempDir("registry credits"),
      },
      async () => {
        const kept = async () =>
          (await credits.find({ codebase: uri })).map((x) => x.value.title).sort();
        const remote = await publicRemote(url, "notes");
        const first = notes.cb.store.head();
        await readCredits(uri, remote, first, undefined);
        assert.deepEqual(await kept(), ["Adds a"]);
        assert.equal(await credits.findOne({ key: `${uri} ${first}` }), undefined, "not a merge");
        assert.equal((await people.findOne({ did: maya.did }))?.value.handle, "maya.test");

        // a later head: what's since, and nothing twice
        contribute("@maya.test/c", `// tcm: namespace notes\nexport const c = 3;\n`, "Adds c");
        await readCredits(uri, remote, notes.cb.store.head(), first);
        assert.deepEqual(await kept(), ["Adds a", "Adds c"]);
        await readCredits(uri, remote, notes.cb.store.head(), first);
        assert.deepEqual(await kept(), ["Adds a", "Adds c"]);

        // a head whose history doesn't hold the last one read: read again whole
        await readCredits(uri, remote, first, notes.cb.store.head());
        assert.deepEqual(await kept(), ["Adds a"]);
      },
    );
  })

uses