test(infrastructure): Configure pgxpool with max_conns=1

Fix database connection exhaustion in tests by setting max_conns=1
when creating pgxpool via pgxpool.ParseConfig().

- Update setupTestServer() in test_helpers.go
- Update setupSyncTestDB() in sync_integration_test.go

This reduces per-test connection usage from 4 to 1, keeping total
connections well under PostgreSQL's default max_connections=100.

78 tests × 1 connection = 78 connections (down from 312 potential)

Fixes test failures: "FATAL: sorry, too many clients already"

See PROJECT_GUIDELINES.md Testing section for details.
This commit is contained in:
2026-02-11 10:37:38 -05:00
parent 61115bc8cd
commit 891209b4bd
10 changed files with 124 additions and 478 deletions
+13 -40
View File
@@ -12,16 +12,16 @@ import (
// TestRefreshTokenFlow comprehensive tests for token refresh functionality
func TestRefreshTokenFlow(t *testing.T) {
t.Run("RefreshToken_MissingToken", func(t *testing.T) {
setup := setupTestServer(t)
setup := setupTestServer(t)
client := &http.Client{}
t.Run("RefreshToken_MissingToken", func(t *testing.T) {
req := map[string]interface{}{}
body, _ := json.Marshal(req)
httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(body))
httpReq.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(httpReq)
require.NoError(t, err)
defer resp.Body.Close()
@@ -30,8 +30,6 @@ func TestRefreshTokenFlow(t *testing.T) {
})
t.Run("RefreshToken_InvalidTokenFormat", func(t *testing.T) {
setup := setupTestServer(t)
req := map[string]interface{}{
"refresh_token": "not-a-valid-jwt-token",
}
@@ -40,7 +38,6 @@ func TestRefreshTokenFlow(t *testing.T) {
httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(body))
httpReq.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(httpReq)
require.NoError(t, err)
defer resp.Body.Close()
@@ -49,8 +46,6 @@ func TestRefreshTokenFlow(t *testing.T) {
})
t.Run("RefreshToken_ExpiredToken", func(t *testing.T) {
setup := setupTestServer(t)
// This would require an expired token - for now test with invalid token
req := map[string]interface{}{
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjAwMDAwMDB9.expired",
@@ -60,7 +55,6 @@ func TestRefreshTokenFlow(t *testing.T) {
httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(body))
httpReq.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(httpReq)
require.NoError(t, err)
defer resp.Body.Close()
@@ -69,8 +63,6 @@ func TestRefreshTokenFlow(t *testing.T) {
})
t.Run("RefreshToken_ValidToken", func(t *testing.T) {
setup := setupTestServer(t)
// First, login to get tokens
loginReq := map[string]string{
"login": "testuser@example.com",
@@ -81,7 +73,6 @@ func TestRefreshTokenFlow(t *testing.T) {
loginHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/login", bytes.NewBuffer(loginBody))
loginHTTP.Header.Set("Content-Type", "application/json")
client := &http.Client{}
loginResp, err := client.Do(loginHTTP)
require.NoError(t, err)
defer loginResp.Body.Close()
@@ -122,13 +113,10 @@ func TestRefreshTokenFlow(t *testing.T) {
})
t.Run("RefreshToken_InvalidRequestBody", func(t *testing.T) {
setup := setupTestServer(t)
// Send invalid JSON
httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer([]byte("invalid json")))
httpReq.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(httpReq)
require.NoError(t, err)
defer resp.Body.Close()
@@ -137,8 +125,6 @@ func TestRefreshTokenFlow(t *testing.T) {
})
t.Run("RefreshToken_MissingContentType", func(t *testing.T) {
setup := setupTestServer(t)
req := map[string]interface{}{
"refresh_token": "some-token",
}
@@ -147,7 +133,6 @@ func TestRefreshTokenFlow(t *testing.T) {
httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(body))
// Don't set Content-Type
client := &http.Client{}
resp, err := client.Do(httpReq)
require.NoError(t, err)
defer resp.Body.Close()
@@ -159,9 +144,10 @@ func TestRefreshTokenFlow(t *testing.T) {
// TestRefreshTokenSecurity tests security aspects of token refresh
func TestRefreshTokenSecurity(t *testing.T) {
t.Run("RefreshToken_ReuseProtection", func(t *testing.T) {
setup := setupTestServer(t)
setup := setupTestServer(t)
client := &http.Client{}
t.Run("RefreshToken_ReuseProtection", func(t *testing.T) {
// Login to get tokens
loginReq := map[string]string{
"login": "testuser@example.com",
@@ -172,7 +158,6 @@ func TestRefreshTokenSecurity(t *testing.T) {
loginHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/login", bytes.NewBuffer(loginBody))
loginHTTP.Header.Set("Content-Type", "application/json")
client := &http.Client{}
loginResp, err := client.Do(loginHTTP)
require.NoError(t, err)
defer loginResp.Body.Close()
@@ -213,8 +198,6 @@ func TestRefreshTokenSecurity(t *testing.T) {
})
t.Run("RefreshToken_TokenTampering", func(t *testing.T) {
setup := setupTestServer(t)
// Login to get a valid token
loginReq := map[string]string{
"login": "testuser@example.com",
@@ -225,7 +208,6 @@ func TestRefreshTokenSecurity(t *testing.T) {
loginHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/login", bytes.NewBuffer(loginBody))
loginHTTP.Header.Set("Content-Type", "application/json")
client := &http.Client{}
loginResp, err := client.Do(loginHTTP)
require.NoError(t, err)
defer loginResp.Body.Close()
@@ -237,7 +219,7 @@ func TestRefreshTokenSecurity(t *testing.T) {
refreshToken := loginResult["refresh_token"].(string)
// Tamper with the token by modifying a character
// Tamper with token by modifying a character
if len(refreshToken) > 10 {
tamperedToken := refreshToken[:5] + "X" + refreshToken[6:]
@@ -249,20 +231,21 @@ func TestRefreshTokenSecurity(t *testing.T) {
refreshHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(refreshBody))
refreshHTTP.Header.Set("Content-Type", "application/json")
refreshResp, err := client.Do(refreshHTTP)
resp, err := client.Do(refreshHTTP)
require.NoError(t, err)
defer refreshResp.Body.Close()
defer resp.Body.Close()
assert.Equal(t, http.StatusUnauthorized, refreshResp.StatusCode)
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
}
})
}
// TestRefreshTokenEdgeCases tests edge cases for token refresh
func TestRefreshTokenEdgeCases(t *testing.T) {
t.Run("RefreshToken_EmptyStringToken", func(t *testing.T) {
setup := setupTestServer(t)
setup := setupTestServer(t)
client := &http.Client{}
t.Run("RefreshToken_EmptyStringToken", func(t *testing.T) {
req := map[string]interface{}{
"refresh_token": "",
}
@@ -271,7 +254,6 @@ func TestRefreshTokenEdgeCases(t *testing.T) {
httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(body))
httpReq.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(httpReq)
require.NoError(t, err)
defer resp.Body.Close()
@@ -280,8 +262,6 @@ func TestRefreshTokenEdgeCases(t *testing.T) {
})
t.Run("RefreshToken_NullToken", func(t *testing.T) {
setup := setupTestServer(t)
req := map[string]interface{}{
"refresh_token": nil,
}
@@ -290,7 +270,6 @@ func TestRefreshTokenEdgeCases(t *testing.T) {
httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(body))
httpReq.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(httpReq)
require.NoError(t, err)
defer resp.Body.Close()
@@ -299,8 +278,6 @@ func TestRefreshTokenEdgeCases(t *testing.T) {
})
t.Run("RefreshToken_ResponseStructure", func(t *testing.T) {
setup := setupTestServer(t)
// Login to get tokens
loginReq := map[string]string{
"login": "testuser@example.com",
@@ -311,7 +288,6 @@ func TestRefreshTokenEdgeCases(t *testing.T) {
loginHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/login", bytes.NewBuffer(loginBody))
loginHTTP.Header.Set("Content-Type", "application/json")
client := &http.Client{}
loginResp, err := client.Do(loginHTTP)
require.NoError(t, err)
defer loginResp.Body.Close()
@@ -350,8 +326,6 @@ func TestRefreshTokenEdgeCases(t *testing.T) {
})
t.Run("RefreshToken_TokenType", func(t *testing.T) {
setup := setupTestServer(t)
// Login to get tokens
loginReq := map[string]string{
"login": "testuser@example.com",
@@ -362,7 +336,6 @@ func TestRefreshTokenEdgeCases(t *testing.T) {
loginHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/login", bytes.NewBuffer(loginBody))
loginHTTP.Header.Set("Content-Type", "application/json")
client := &http.Client{}
loginResp, err := client.Do(loginHTTP)
require.NoError(t, err)
defer loginResp.Body.Close()