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

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
92 lines · 2.8 KB Raw History
// What a merge commit says it is. It writes git's own subject, because
// a merge is a record of taking a change rather than the change itself.

import { describe, expect, it } from 'vitest';
import { createGitMerger, mergeSubject } from '../src/merger.js';

/**
 * A merger whose ports answer just enough to reach the guards.
 * @param {Record<string, Object>} records - repository records by rkey
 * @param {string[]} seen - the DIDs it resolved, so a test can say it did not
 */
function mergerSeeing(records, seen) {
  return createGitMerger({
    readRecord: async (
      /** @type {string} */ _did,
      /** @type {string} */ _collection,
      /** @type {string} */ rkey,
    ) => records[rkey] ?? null,
    writeRecord: async () => {},
    readBlob: async () => null,
    writeBlob: async () => ({
      ref: { $link: 'bafypart' },
      mimeType: 'application/x-git-bundle',
      size: 0,
    }),
    linkBlob: async () => {},
    chunkSize: 1024,
    locate: async (/** @type {string} */ did) => {
      seen.push(did);
      return { did, service: 'http://elsewhere.invalid' };
    },
    handle: async () => 'alice.localhost',
  });
}

describe('mergeSubject', () => {
  it("is git's own subject, naming where the branch came from", () => {
    expect(mergeSubject('refs/heads/agent/farewell', 'bob.localhost')).toBe(
      "Merge branch 'agent/farewell' of bob.localhost",
    );
  });

  it('names the branch alone where the account is not known', () => {
    expect(mergeSubject('refs/heads/fix', '')).toBe("Merge branch 'fix'");
    expect(mergeSubject('refs/heads/fix')).toBe("Merge branch 'fix'");
  });
});

describe('createGitMerger', () => {
  const records = {
    demo: {
      $type: 'dev.pdsjs.git.repo',
      name: 'demo',
      refs: [],
      bundles: [],
      createdAt: '2026-08-24T00:00:00Z',
    },
  };

  it('reads the repository before it reaches across the network', async () => {
    /** @type {string[]} */
    const seen = [];
    const merger = mergerSeeing(records, seen);
    await expect(
      merger.merge({
        did: 'did:plc:alice',
        rkey: 'demo',
        name: 'demo',
        from: 'did:plc:bob',
        ref: 'refs/heads/fix',
        mode: 'merge',
      }),
    ).rejects.toThrow(/is not a branch here/);
    // A repository with no main is refused before the other account is
    // resolved, so a merge that cannot work costs no request.
    expect(seen).toEqual([]);
  });

  it('refuses a repository this account does not hold', async () => {
    const merger = mergerSeeing({}, []);
    await expect(
      merger.merge({
        did: 'did:plc:alice',
        rkey: 'gone',
        name: 'gone',
        from: 'did:plc:bob',
        ref: 'refs/heads/fix',
        mode: 'merge',
      }),
    ).rejects.toThrow(/no such repository/);
  });
});