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