Barazo AppView backend
barazo.forum
1/**
2 * Integration test: PLC DID creation with handle + serviceEndpoint
3 * against the real plc.directory.
4 *
5 * HUMAN CHECKPOINT REQUIRED:
6 * This test creates a real DID on plc.directory. It should only be run
7 * manually during checkpoint validation, not in CI.
8 *
9 * To run: LIVE_PLC_TEST=1 pnpm vitest run tests/integration/plc-did-live.test.ts
10 *
11 * What to verify manually after running:
12 * 1. The test outputs a DID -- look it up at https://plc.directory/{did}
13 * 2. Verify the DID document contains:
14 * - alsoKnownAs: ["at://test-{timestamp}.barazo.forum"]
15 * - services.atproto_pds.endpoint: "https://test-{timestamp}.barazo.forum"
16 * - verificationMethods.atproto: a did:key
17 * - rotationKeys: [a did:key]
18 * 3. Verify the DID was accepted (HTTP 200 from plc.directory, not rejected)
19 *
20 * Note: Each run creates a new permanent DID on plc.directory. The keys are
21 * logged so the DID could be updated later if needed.
22 */
23
24import { describe, it, expect } from 'vitest'
25import { createPlcDidService } from '../../src/services/plc-did.js'
26import type { Logger } from '../../src/lib/logger.js'
27
28const SHOULD_RUN = process.env.LIVE_PLC_TEST === '1'
29
30function createTestLogger(): Logger {
31 return {
32 info: (...args: unknown[]) => {
33 process.stdout.write(`[INFO] ${args.join(' ')}\n`)
34 },
35 error: (...args: unknown[]) => {
36 process.stderr.write(`[ERROR] ${args.join(' ')}\n`)
37 },
38 warn: (...args: unknown[]) => {
39 process.stderr.write(`[WARN] ${args.join(' ')}\n`)
40 },
41 debug: () => {
42 /* empty */
43 },
44 fatal: (...args: unknown[]) => {
45 process.stderr.write(`[FATAL] ${args.join(' ')}\n`)
46 },
47 trace: () => {
48 /* empty */
49 },
50 child: () => createTestLogger(),
51 silent: () => {
52 /* empty */
53 },
54 level: 'info',
55 } as unknown as Logger
56}
57
58describe.skipIf(!SHOULD_RUN)('PLC DID live integration (handle + serviceEndpoint)', () => {
59 it('creates a DID on plc.directory with handle and serviceEndpoint', async () => {
60 const logger = createTestLogger()
61 const service = createPlcDidService(logger)
62
63 // Use a unique timestamp-based handle to avoid collisions
64 const timestamp = Date.now()
65 const handle = `test-${String(timestamp)}.barazo.forum`
66 const serviceEndpoint = `https://test-${String(timestamp)}.barazo.forum`
67
68 process.stdout.write('\n=== PLC DID Live Test ===\n')
69 process.stdout.write(`Handle: ${handle}\n`)
70 process.stdout.write(`Service Endpoint: ${serviceEndpoint}\n`)
71
72 const result = await service.generateDid({
73 handle,
74 serviceEndpoint,
75 })
76
77 // Verify the result structure
78 expect(result.did).toMatch(/^did:plc:[a-z2-7]{24}$/)
79 expect(result.signingKey).toMatch(/^[0-9a-f]{64}$/)
80 expect(result.rotationKey).toMatch(/^[0-9a-f]{64}$/)
81
82 process.stdout.write(`\nGenerated DID: ${result.did}\n`)
83 process.stdout.write(`Signing Key (hex): ${result.signingKey}\n`)
84 process.stdout.write(`Rotation Key (hex): ${result.rotationKey}\n`)
85 process.stdout.write(`\nVerify at: https://plc.directory/${result.did}\n`)
86 process.stdout.write('=== End PLC DID Live Test ===\n\n')
87
88 // Verify the DID is resolvable from plc.directory
89 const verifyResponse = await fetch(`https://plc.directory/${result.did}`)
90 expect(verifyResponse.status).toBe(200)
91
92 const didDoc = (await verifyResponse.json()) as Record<string, unknown>
93 expect(didDoc.id).toBe(result.did)
94
95 // Verify alsoKnownAs contains our handle
96 const alsoKnownAs = didDoc.alsoKnownAs as string[]
97 expect(alsoKnownAs).toContain(`at://${handle}`)
98
99 // Verify service endpoint
100 const services = didDoc.service as Array<{
101 id: string
102 type: string
103 serviceEndpoint: string
104 }>
105 const pdsService = services.find((s) => s.type === 'AtprotoPersonalDataServer')
106 expect(pdsService).toBeDefined()
107 expect(pdsService?.serviceEndpoint).toBe(serviceEndpoint)
108 }, 30_000) // 30s timeout for network call
109})
110
111/**
112 * Setup wizard integration: verify the initialize endpoint passes
113 * handle + serviceEndpoint through to PLC DID generation.
114 *
115 * This is tested with mocked PLC in the unit tests (setup.test.ts).
116 * The live PLC test above verifies the actual plc.directory interaction.
117 *
118 * MANUAL VERIFICATION CHECKLIST:
119 * [ ] Run: LIVE_PLC_TEST=1 pnpm vitest run tests/integration/plc-did-live.test.ts
120 * [ ] Test passes (DID created successfully)
121 * [ ] Visit https://plc.directory/{did} and verify the DID document
122 * [ ] alsoKnownAs contains the test handle
123 * [ ] Service endpoint is set correctly
124 * [ ] Verification method (atproto) is a valid did:key
125 * [ ] Rotation key is present
126 */