Barazo AppView backend barazo.forum
at main 126 lines 4.7 kB view raw
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 */