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(); }); });