A community based topic aggregation platform built on atproto
1package integration 2 3import ( 4 "Coves/internal/core/users" 5 "bytes" 6 "context" 7 "database/sql" 8 "encoding/json" 9 "fmt" 10 "io" 11 "net/http" 12 "strings" 13 "testing" 14) 15 16// createTestUser creates a test user in the database for use in integration tests 17// Returns the created user or fails the test 18func createTestUser(t *testing.T, db *sql.DB, handle, did string) *users.User { 19 t.Helper() 20 21 ctx := context.Background() 22 23 // Create user directly in DB for speed 24 query := ` 25 INSERT INTO users (did, handle, pds_url, created_at, updated_at) 26 VALUES ($1, $2, $3, NOW(), NOW()) 27 RETURNING did, handle, pds_url, created_at, updated_at 28 ` 29 30 user := &users.User{} 31 err := db.QueryRowContext(ctx, query, did, handle, "http://localhost:3001").Scan( 32 &user.DID, 33 &user.Handle, 34 &user.PDSURL, 35 &user.CreatedAt, 36 &user.UpdatedAt, 37 ) 38 if err != nil { 39 t.Fatalf("Failed to create test user: %v", err) 40 } 41 42 return user 43} 44 45// contains checks if string s contains substring substr 46// Helper for error message assertions 47func contains(s, substr string) bool { 48 return strings.Contains(s, substr) 49} 50 51// authenticateWithPDS authenticates with PDS to get access token and DID 52// Used for setting up test environments that need PDS credentials 53func authenticateWithPDS(pdsURL, handle, password string) (string, string, error) { 54 // Call com.atproto.server.createSession 55 sessionReq := map[string]string{ 56 "identifier": handle, 57 "password": password, 58 } 59 60 reqBody, marshalErr := json.Marshal(sessionReq) 61 if marshalErr != nil { 62 return "", "", fmt.Errorf("failed to marshal session request: %w", marshalErr) 63 } 64 resp, err := http.Post( 65 pdsURL+"/xrpc/com.atproto.server.createSession", 66 "application/json", 67 bytes.NewBuffer(reqBody), 68 ) 69 if err != nil { 70 return "", "", fmt.Errorf("failed to create session: %w", err) 71 } 72 defer func() { _ = resp.Body.Close() }() 73 74 if resp.StatusCode != http.StatusOK { 75 body, readErr := io.ReadAll(resp.Body) 76 if readErr != nil { 77 return "", "", fmt.Errorf("PDS auth failed (status %d, failed to read body: %w)", resp.StatusCode, readErr) 78 } 79 return "", "", fmt.Errorf("PDS auth failed (status %d): %s", resp.StatusCode, string(body)) 80 } 81 82 var sessionResp struct { 83 AccessJwt string `json:"accessJwt"` 84 DID string `json:"did"` 85 } 86 87 if err := json.NewDecoder(resp.Body).Decode(&sessionResp); err != nil { 88 return "", "", fmt.Errorf("failed to decode session response: %w", err) 89 } 90 91 return sessionResp.AccessJwt, sessionResp.DID, nil 92}