Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol.
wisp.place
1import { describe, test, expect, beforeAll, afterAll } from 'bun:test'
2import {
3 claimCustomDomain,
4 getCustomDomainInfo,
5 deleteCustomDomain,
6 updateCustomDomainVerification,
7 db
8} from './db'
9
10describe('custom domain claiming', () => {
11 const testDid1 = 'did:plc:testuser1'
12 const testDid2 = 'did:plc:testuser2'
13 const testDomain = 'example-test-domain.com'
14 const hash1 = 'testhash12345678'
15 const hash2 = 'testhash87654321'
16 const hash3 = 'testhash11111111'
17
18 beforeAll(async () => {
19 // Clean up any existing test data
20 try {
21 await db`DELETE FROM custom_domains WHERE domain = ${testDomain}`
22 } catch (err) {
23 // Ignore errors if table doesn't exist or other issues
24 }
25 })
26
27 afterAll(async () => {
28 // Clean up test data
29 try {
30 await db`DELETE FROM custom_domains WHERE domain = ${testDomain}`
31 } catch (err) {
32 // Ignore cleanup errors
33 }
34 })
35
36 test('should allow first user to claim a domain', async () => {
37 const result = await claimCustomDomain(testDid1, testDomain, hash1)
38 expect(result.success).toBe(true)
39 expect(result.hash).toBe(hash1)
40
41 const domainInfo = await getCustomDomainInfo(testDomain)
42 expect(domainInfo).toBeTruthy()
43 expect(domainInfo!.domain).toBe(testDomain)
44 expect(domainInfo!.did).toBe(testDid1)
45 expect(domainInfo!.verified).toBe(false)
46 expect(domainInfo!.id).toBe(hash1)
47 })
48
49 test('should allow second user to claim an unverified domain', async () => {
50 const result = await claimCustomDomain(testDid2, testDomain, hash2)
51 expect(result.success).toBe(true)
52 expect(result.hash).toBe(hash2)
53
54 const domainInfo = await getCustomDomainInfo(testDomain)
55 expect(domainInfo).toBeTruthy()
56 expect(domainInfo!.domain).toBe(testDomain)
57 expect(domainInfo!.did).toBe(testDid2) // Should have changed
58 expect(domainInfo!.verified).toBe(false)
59 expect(domainInfo!.id).toBe(hash2) // Should have changed
60 })
61
62 test('should prevent claiming a verified domain', async () => {
63 // First verify the domain for testDid2
64 await updateCustomDomainVerification(hash2, true)
65
66 // Now try to claim it with testDid1 - should fail
67 try {
68 await claimCustomDomain(testDid1, testDomain, hash3)
69 expect.fail('Should have thrown an error when trying to claim a verified domain')
70 } catch (err) {
71 expect(err.message).toBe('conflict')
72 }
73
74 // Verify the domain is still owned by testDid2 and verified
75 const domainInfo = await getCustomDomainInfo(testDomain)
76 expect(domainInfo).toBeTruthy()
77 expect(domainInfo!.did).toBe(testDid2)
78 expect(domainInfo!.verified).toBe(true)
79 expect(domainInfo!.id).toBe(hash2)
80 })
81
82 test('should allow claiming after unverification', async () => {
83 // Unverify the domain
84 await updateCustomDomainVerification(hash2, false)
85
86 // Now should be claimable again
87 const result = await claimCustomDomain(testDid1, testDomain, hash3)
88 expect(result.success).toBe(true)
89 expect(result.hash).toBe(hash3)
90
91 const domainInfo = await getCustomDomainInfo(testDomain)
92 expect(domainInfo).toBeTruthy()
93 expect(domainInfo!.did).toBe(testDid1) // Should have changed back
94 expect(domainInfo!.verified).toBe(false)
95 expect(domainInfo!.id).toBe(hash3)
96 })
97
98 test('should handle concurrent claims gracefully', async () => {
99 // Both users try to claim at the same time - one should win
100 const promise1 = claimCustomDomain(testDid1, testDomain, hash1)
101 const promise2 = claimCustomDomain(testDid2, testDomain, hash2)
102
103 const [result1, result2] = await Promise.allSettled([promise1, promise2])
104
105 // At least one should succeed
106 const successCount = [result1, result2].filter(r => r.status === 'fulfilled').length
107 expect(successCount).toBeGreaterThan(0)
108 expect(successCount).toBeLessThanOrEqual(2)
109
110 // Final state should be consistent
111 const domainInfo = await getCustomDomainInfo(testDomain)
112 expect(domainInfo).toBeTruthy()
113 expect(domainInfo!.verified).toBe(false)
114 expect([hash1, hash2]).toContain(domainInfo!.id)
115 })
116})