import { describe, it, expect } from "vitest"; import { parseAtUri } from "../at-uri.js"; describe("parseAtUri", () => { describe("valid URIs", () => { it("parses a standard post URI", () => { const result = parseAtUri( "at://did:plc:abc123/space.atbb.post/3lbk7xxx" ); expect(result).toEqual({ did: "did:plc:abc123", collection: "space.atbb.post", rkey: "3lbk7xxx", }); }); it("parses a forum URI with 'self' rkey", () => { const result = parseAtUri( "at://did:plc:forum/space.atbb.forum.forum/self" ); expect(result).toEqual({ did: "did:plc:forum", collection: "space.atbb.forum.forum", rkey: "self", }); }); it("parses a category URI", () => { const result = parseAtUri( "at://did:plc:forum/space.atbb.forum.category/cat1" ); expect(result).toEqual({ did: "did:plc:forum", collection: "space.atbb.forum.category", rkey: "cat1", }); }); it("parses a membership URI", () => { const result = parseAtUri( "at://did:plc:user123/space.atbb.membership/mem1" ); expect(result).toEqual({ did: "did:plc:user123", collection: "space.atbb.membership", rkey: "mem1", }); }); it("parses a did:web DID", () => { const result = parseAtUri( "at://did:web:example.com/space.atbb.post/abc" ); expect(result).toEqual({ did: "did:web:example.com", collection: "space.atbb.post", rkey: "abc", }); }); it("parses a Bluesky post URI", () => { const result = parseAtUri( "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3lbk7abc" ); expect(result).toEqual({ did: "did:plc:z72i7hdynmk6r22z27h6tvur", collection: "app.bsky.feed.post", rkey: "3lbk7abc", }); }); it("handles rkey with special characters", () => { const result = parseAtUri( "at://did:plc:abc/space.atbb.post/rkey-with.dots_and-dashes" ); expect(result).toEqual({ did: "did:plc:abc", collection: "space.atbb.post", rkey: "rkey-with.dots_and-dashes", }); }); }); describe("invalid URIs", () => { it("returns null for empty string", () => { expect(parseAtUri("")).toBeNull(); }); it("returns null for a plain string", () => { expect(parseAtUri("not-a-uri")).toBeNull(); }); it("returns null for an HTTP URL", () => { expect(parseAtUri("https://example.com/path")).toBeNull(); }); it("returns null for a URI missing the rkey", () => { expect( parseAtUri("at://did:plc:abc/space.atbb.post") ).toBeNull(); }); it("returns null for a URI missing collection and rkey", () => { expect(parseAtUri("at://did:plc:abc")).toBeNull(); }); it("returns null for a URI with only the scheme", () => { expect(parseAtUri("at://")).toBeNull(); }); it("returns null for a URI with wrong scheme", () => { expect( parseAtUri("http://did:plc:abc/space.atbb.post/rkey") ).toBeNull(); }); }); describe("edge cases", () => { it("returns all three components as strings", () => { const result = parseAtUri( "at://did:plc:test/space.atbb.post/abc123" ); expect(result).not.toBeNull(); expect(typeof result!.did).toBe("string"); expect(typeof result!.collection).toBe("string"); expect(typeof result!.rkey).toBe("string"); }); it("does not match URIs with trailing slash", () => { // The regex uses (.+)$ for rkey, so trailing slash is included in rkey const result = parseAtUri( "at://did:plc:abc/space.atbb.post/rkey/" ); // rkey would be "rkey/" which includes the trailing slash expect(result).toEqual({ did: "did:plc:abc", collection: "space.atbb.post", rkey: "rkey/", }); }); it("does not match a URI with empty path segments", () => { expect(parseAtUri("at:////")).toBeNull(); }); it("handles numeric rkey (TID format)", () => { const result = parseAtUri( "at://did:plc:abc/space.atbb.post/3lbk7xyzhij2q" ); expect(result).toEqual({ did: "did:plc:abc", collection: "space.atbb.post", rkey: "3lbk7xyzhij2q", }); }); }); });