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

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
135 lines · 4.3 KB Raw History
import { describe, expect, it } from 'vitest';
import { diffRefs, refsToState, removedRefs } from '../src/refs.js';
import {
  checkRequestKey,
  latestCheckKey,
  parseSpec,
  repoKey,
} from '../src/spec.js';

describe('diffRefs', () => {
  it('reports a new ref with no previous object id', () => {
    expect(diffRefs({}, [{ name: 'refs/heads/main', sha: 'aa' }])).toEqual([
      { name: 'refs/heads/main', sha: 'aa', previousSha: null },
    ]);
  });

  it('reports a ref that moved', () => {
    const previous = { 'refs/heads/main': 'aa' };
    expect(
      diffRefs(previous, [{ name: 'refs/heads/main', sha: 'bb' }]),
    ).toEqual([{ name: 'refs/heads/main', sha: 'bb', previousSha: 'aa' }]);
  });

  it('reports nothing when every ref is where it was', () => {
    const refs = [
      { name: 'refs/heads/main', sha: 'aa' },
      { name: 'refs/heads/topic', sha: 'bb' },
    ];
    expect(diffRefs(refsToState(refs), refs)).toEqual([]);
  });

  it('ignores a ref that disappeared', () => {
    const previous = { 'refs/heads/main': 'aa', 'refs/heads/gone': 'bb' };
    expect(
      diffRefs(previous, [{ name: 'refs/heads/main', sha: 'aa' }]),
    ).toEqual([]);
  });
});

describe('parseSpec', () => {
  it('splits a handle from a repository name', () => {
    expect(parseSpec('alice.example.com/my-project')).toEqual({
      authority: 'alice.example.com',
      repoName: 'my-project',
    });
  });

  it('keeps a DID whole', () => {
    expect(parseSpec('did:plc:abc123/my-project')).toEqual({
      authority: 'did:plc:abc123',
      repoName: 'my-project',
    });
  });

  it('rejects a spec with no repository name', () => {
    expect(() => parseSpec('alice.example.com')).toThrow(/expected/);
    expect(() => parseSpec('alice.example.com/')).toThrow(/expected/);
    expect(() => parseSpec('/my-project')).toThrow(/expected/);
  });
});

describe('repoKey', () => {
  it('keys a repository by DID and name', () => {
    expect(repoKey('did:plc:abc', 'proj')).toBe('did:plc:abc/proj');
  });
});

describe('removedRefs', () => {
  it('names the refs the last look saw that are not there now', () => {
    expect(
      removedRefs({ 'refs/heads/main': 'a', 'refs/heads/fix': 'b' }, [
        { name: 'refs/heads/main', sha: 'a' },
      ]),
    ).toEqual(['refs/heads/fix']);
  });

  it('names none where every ref is still held', () => {
    expect(
      removedRefs({ 'refs/heads/main': 'a' }, [
        { name: 'refs/heads/main', sha: 'c' },
      ]),
    ).toEqual([]);
  });
});

describe('latestCheckKey', () => {
  // The account page derives the same key in @pdsjs/core to find a check. If
  // these disagree, a published check never resolves, so both assert this.
  it('keeps the colons a DID and a record key both allow', () => {
    expect(latestCheckKey('did:plc:abc', 'proj', 'refs/heads/main')).toBe(
      'did:plc:abc:proj:refs_heads_main',
    );
  });

  it('replaces every character a record key forbids', () => {
    expect(latestCheckKey('did:plc:abc', 'proj', 'refs/heads/a b/c')).toBe(
      'did:plc:abc:proj:refs_heads_a_b_c',
    );
  });

  it('separates two refs of one repository', () => {
    const main = latestCheckKey('did:plc:abc', 'proj', 'refs/heads/main');
    const topic = latestCheckKey('did:plc:abc', 'proj', 'refs/heads/topic');
    expect(main).not.toBe(topic);
  });

  it('separates same-named repositories owned by different accounts', () => {
    const mine = latestCheckKey('did:plc:abc', 'proj', 'refs/heads/main');
    const yours = latestCheckKey('did:plc:xyz', 'proj', 'refs/heads/main');
    expect(mine).not.toBe(yours);
  });
});

describe('checkRequestKey', () => {
  // The account page derives the same key in @pdsjs/core to write a request.
  // If these disagree, asking twice leaves two records and the daemon runs
  // twice, so both assert this.
  it('names the repository and the ref, and nothing else', () => {
    expect(checkRequestKey('proj', 'refs/heads/main')).toBe(
      'proj:refs_heads_main',
    );
  });

  it('replaces every character a record key forbids', () => {
    expect(checkRequestKey('proj', 'refs/heads/a b/c')).toBe(
      'proj:refs_heads_a_b_c',
    );
  });

  it('separates two refs of one repository', () => {
    expect(checkRequestKey('proj', 'refs/heads/main')).not.toBe(
      checkRequestKey('proj', 'refs/heads/topic'),
    );
  });
});