A community based topic aggregation platform built on atproto
1package integration 2 3import ( 4 "Coves/internal/core/users" 5 "Coves/internal/db/postgres" 6 "bytes" 7 "database/sql" 8 "encoding/json" 9 "fmt" 10 "net/http" 11 "net/http/httptest" 12 "os" 13 "testing" 14 15 "github.com/go-chi/chi/v5" 16 _ "github.com/lib/pq" 17 "github.com/pressly/goose/v3" 18 19 "Coves/internal/api/routes" 20) 21 22func setupTestDB(t *testing.T) *sql.DB { 23 // Build connection string from environment variables (set by .env.dev) 24 // These are loaded by the Makefile when running tests 25 testUser := os.Getenv("POSTGRES_TEST_USER") 26 testPassword := os.Getenv("POSTGRES_TEST_PASSWORD") 27 testPort := os.Getenv("POSTGRES_TEST_PORT") 28 testDB := os.Getenv("POSTGRES_TEST_DB") 29 30 // Fallback to defaults if not set 31 if testUser == "" { 32 testUser = "test_user" 33 } 34 if testPassword == "" { 35 testPassword = "test_password" 36 } 37 if testPort == "" { 38 testPort = "5434" 39 } 40 if testDB == "" { 41 testDB = "coves_test" 42 } 43 44 dbURL := fmt.Sprintf("postgres://%s:%s@localhost:%s/%s?sslmode=disable", 45 testUser, testPassword, testPort, testDB) 46 47 db, err := sql.Open("postgres", dbURL) 48 if err != nil { 49 t.Fatalf("Failed to connect to test database: %v", err) 50 } 51 52 if err := db.Ping(); err != nil { 53 t.Fatalf("Failed to ping test database: %v", err) 54 } 55 56 if err := goose.SetDialect("postgres"); err != nil { 57 t.Fatalf("Failed to set goose dialect: %v", err) 58 } 59 60 if err := goose.Up(db, "../../internal/db/migrations"); err != nil { 61 t.Fatalf("Failed to run migrations: %v", err) 62 } 63 64 // Clean up any existing test data 65 _, err = db.Exec("DELETE FROM users WHERE email LIKE '%@example.com'") 66 if err != nil { 67 t.Logf("Warning: Failed to clean up test data: %v", err) 68 } 69 70 return db 71} 72 73func TestCreateUser(t *testing.T) { 74 db := setupTestDB(t) 75 defer db.Close() 76 77 // Wire up dependencies according to architecture 78 userRepo := postgres.NewUserRepository(db) 79 userService := users.NewUserService(userRepo) 80 81 r := chi.NewRouter() 82 r.Mount("/api/users", routes.UserRoutes(userService)) 83 84 user := users.CreateUserRequest{ 85 Email: "test@example.com", 86 Username: "testuser", 87 } 88 89 body, _ := json.Marshal(user) 90 req := httptest.NewRequest("POST", "/api/users", bytes.NewBuffer(body)) 91 req.Header.Set("Content-Type", "application/json") 92 93 w := httptest.NewRecorder() 94 r.ServeHTTP(w, req) 95 96 if w.Code != http.StatusCreated { 97 t.Errorf("Expected status %d, got %d. Response: %s", http.StatusCreated, w.Code, w.Body.String()) 98 return 99 } 100 101 var createdUser users.User 102 if err := json.NewDecoder(w.Body).Decode(&createdUser); err != nil { 103 t.Fatalf("Failed to decode response: %v", err) 104 } 105 106 if createdUser.Email != user.Email { 107 t.Errorf("Expected email %s, got %s", user.Email, createdUser.Email) 108 } 109 110 if createdUser.Username != user.Username { 111 t.Errorf("Expected username %s, got %s", user.Username, createdUser.Username) 112 } 113} 114