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

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
113 lines · 3.3 KB Raw History
import { describe, expect, it } from 'vitest';
import { formatSpaceUri, isSpaceUri, parseSpaceUri } from '../src/uri.js';

const SPACE = 'at://did:plc:aaaa/space/com.atmoboards.forum/general';
const FULL = `${SPACE}/did:plc:bbbb/com.atmoboards.thread/3kabc`;

describe('space URIs', () => {
  it('formats a bare space URI', () => {
    expect(
      formatSpaceUri({
        spaceDid: 'did:plc:aaaa',
        spaceType: 'com.atmoboards.forum',
        skey: 'general',
      }),
    ).toBe(SPACE);
  });

  it('formats a full record URI', () => {
    expect(
      formatSpaceUri({
        spaceDid: 'did:plc:aaaa',
        spaceType: 'com.atmoboards.forum',
        skey: 'general',
        authorDid: 'did:plc:bbbb',
        collection: 'com.atmoboards.thread',
        rkey: '3kabc',
      }),
    ).toBe(FULL);
  });

  it('parses a bare space URI', () => {
    expect(parseSpaceUri(SPACE)).toEqual({
      spaceDid: 'did:plc:aaaa',
      spaceType: 'com.atmoboards.forum',
      skey: 'general',
      authorDid: null,
      collection: null,
      rkey: null,
    });
  });

  it('parses a full record URI', () => {
    expect(parseSpaceUri(FULL)).toEqual({
      spaceDid: 'did:plc:aaaa',
      spaceType: 'com.atmoboards.forum',
      skey: 'general',
      authorDid: 'did:plc:bbbb',
      collection: 'com.atmoboards.thread',
      rkey: '3kabc',
    });
  });

  it('round-trips', () => {
    expect(formatSpaceUri(parseSpaceUri(FULL))).toBe(FULL);
    expect(formatSpaceUri(parseSpaceUri(SPACE))).toBe(SPACE);
  });

  it('recognises space URIs by the marker segment', () => {
    expect(isSpaceUri(SPACE)).toBe(true);
    expect(isSpaceUri(FULL)).toBe(true);
    // Public repo URI: the first path segment is a collection NSID, which
    // always contains dots. The space marker never does.
    expect(isSpaceUri('at://did:plc:aaaa/app.bsky.feed.post/3kabc')).toBe(
      false,
    );
    expect(isSpaceUri('at://did:plc:aaaa')).toBe(false);
  });

  it('rejects malformed space URIs', () => {
    expect(() =>
      parseSpaceUri('at://did:plc:aaaa/app.bsky.feed.post/3k'),
    ).toThrow();
    // missing skey
    expect(() =>
      parseSpaceUri('at://did:plc:aaaa/space/com.example.t'),
    ).toThrow();
    // author present but collection/rkey truncated
    expect(() =>
      parseSpaceUri(`${SPACE}/did:plc:bbbb/com.example.c`),
    ).toThrow();
    // non-DID authority
    expect(() =>
      parseSpaceUri('at://alice.test/space/com.example.t/k'),
    ).toThrow();
  });

  it('rejects a space type that is not an NSID', () => {
    expect(() => parseSpaceUri('at://did:plc:aaaa/space/nodots/k')).toThrow();
  });

  it('rejects formatting with only some of authorDid/collection/rkey set', () => {
    // authorDid alone would produce a 5-segment URI, which parseSpaceUri rejects.
    expect(() =>
      formatSpaceUri({
        spaceDid: 'did:plc:aaaa',
        spaceType: 'com.atmoboards.forum',
        skey: 'general',
        authorDid: 'did:plc:bbbb',
      }),
    ).toThrow();
    // collection + rkey without authorDid would produce a 6-segment URI, also
    // unparseable.
    expect(() =>
      formatSpaceUri({
        spaceDid: 'did:plc:aaaa',
        spaceType: 'com.atmoboards.forum',
        skey: 'general',
        collection: 'com.atmoboards.thread',
        rkey: '3kabc',
      }),
    ).toThrow();
  });
});