WIP! A BB-style forum, on the ATmosphere! We're still working... we'll be back soon when we have something to show off!
node typescript hono htmx atproto
at root/atb-56-theme-caching-layer 167 lines 4.5 kB view raw
1import { describe, it, expect } from "vitest"; 2import { parseAtUri } from "../at-uri.js"; 3 4describe("parseAtUri", () => { 5 describe("valid URIs", () => { 6 it("parses a standard post URI", () => { 7 const result = parseAtUri( 8 "at://did:plc:abc123/space.atbb.post/3lbk7xxx" 9 ); 10 11 expect(result).toEqual({ 12 did: "did:plc:abc123", 13 collection: "space.atbb.post", 14 rkey: "3lbk7xxx", 15 }); 16 }); 17 18 it("parses a forum URI with 'self' rkey", () => { 19 const result = parseAtUri( 20 "at://did:plc:forum/space.atbb.forum.forum/self" 21 ); 22 23 expect(result).toEqual({ 24 did: "did:plc:forum", 25 collection: "space.atbb.forum.forum", 26 rkey: "self", 27 }); 28 }); 29 30 it("parses a category URI", () => { 31 const result = parseAtUri( 32 "at://did:plc:forum/space.atbb.forum.category/cat1" 33 ); 34 35 expect(result).toEqual({ 36 did: "did:plc:forum", 37 collection: "space.atbb.forum.category", 38 rkey: "cat1", 39 }); 40 }); 41 42 it("parses a membership URI", () => { 43 const result = parseAtUri( 44 "at://did:plc:user123/space.atbb.membership/mem1" 45 ); 46 47 expect(result).toEqual({ 48 did: "did:plc:user123", 49 collection: "space.atbb.membership", 50 rkey: "mem1", 51 }); 52 }); 53 54 it("parses a did:web DID", () => { 55 const result = parseAtUri( 56 "at://did:web:example.com/space.atbb.post/abc" 57 ); 58 59 expect(result).toEqual({ 60 did: "did:web:example.com", 61 collection: "space.atbb.post", 62 rkey: "abc", 63 }); 64 }); 65 66 it("parses a Bluesky post URI", () => { 67 const result = parseAtUri( 68 "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3lbk7abc" 69 ); 70 71 expect(result).toEqual({ 72 did: "did:plc:z72i7hdynmk6r22z27h6tvur", 73 collection: "app.bsky.feed.post", 74 rkey: "3lbk7abc", 75 }); 76 }); 77 78 it("handles rkey with special characters", () => { 79 const result = parseAtUri( 80 "at://did:plc:abc/space.atbb.post/rkey-with.dots_and-dashes" 81 ); 82 83 expect(result).toEqual({ 84 did: "did:plc:abc", 85 collection: "space.atbb.post", 86 rkey: "rkey-with.dots_and-dashes", 87 }); 88 }); 89 }); 90 91 describe("invalid URIs", () => { 92 it("returns null for empty string", () => { 93 expect(parseAtUri("")).toBeNull(); 94 }); 95 96 it("returns null for a plain string", () => { 97 expect(parseAtUri("not-a-uri")).toBeNull(); 98 }); 99 100 it("returns null for an HTTP URL", () => { 101 expect(parseAtUri("https://example.com/path")).toBeNull(); 102 }); 103 104 it("returns null for a URI missing the rkey", () => { 105 expect( 106 parseAtUri("at://did:plc:abc/space.atbb.post") 107 ).toBeNull(); 108 }); 109 110 it("returns null for a URI missing collection and rkey", () => { 111 expect(parseAtUri("at://did:plc:abc")).toBeNull(); 112 }); 113 114 it("returns null for a URI with only the scheme", () => { 115 expect(parseAtUri("at://")).toBeNull(); 116 }); 117 118 it("returns null for a URI with wrong scheme", () => { 119 expect( 120 parseAtUri("http://did:plc:abc/space.atbb.post/rkey") 121 ).toBeNull(); 122 }); 123 }); 124 125 describe("edge cases", () => { 126 it("returns all three components as strings", () => { 127 const result = parseAtUri( 128 "at://did:plc:test/space.atbb.post/abc123" 129 ); 130 131 expect(result).not.toBeNull(); 132 expect(typeof result!.did).toBe("string"); 133 expect(typeof result!.collection).toBe("string"); 134 expect(typeof result!.rkey).toBe("string"); 135 }); 136 137 it("does not match URIs with trailing slash", () => { 138 // The regex uses (.+)$ for rkey, so trailing slash is included in rkey 139 const result = parseAtUri( 140 "at://did:plc:abc/space.atbb.post/rkey/" 141 ); 142 143 // rkey would be "rkey/" which includes the trailing slash 144 expect(result).toEqual({ 145 did: "did:plc:abc", 146 collection: "space.atbb.post", 147 rkey: "rkey/", 148 }); 149 }); 150 151 it("does not match a URI with empty path segments", () => { 152 expect(parseAtUri("at:////")).toBeNull(); 153 }); 154 155 it("handles numeric rkey (TID format)", () => { 156 const result = parseAtUri( 157 "at://did:plc:abc/space.atbb.post/3lbk7xyzhij2q" 158 ); 159 160 expect(result).toEqual({ 161 did: "did:plc:abc", 162 collection: "space.atbb.post", 163 rkey: "3lbk7xyzhij2q", 164 }); 165 }); 166 }); 167});