A community based topic aggregation platform built on atproto

feat(testing): add make test-all for comprehensive pre-merge testing

- Add test-all target that runs all tests with live infrastructure
- Check dev stack, AppView, and test database before running tests
- Add LOG_ENABLED=false support to silence app logs during tests
- Add TestMain to integration, e2e, unit, and tests packages
- Fail fast on first test failure for quick feedback

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+102 -1
+2
CLAUDE.md
··· 56 56 - [ ]  **Does the Lexicon make sense?** (Would it work for other forums?) 57 57 - [ ]  **AppView only indexes**: We don't write to CAR files, only read from firehose 58 58 59 + Always prefer error codes over dataintegrity boolean markers 60 + 59 61 ## Security-First Building 60 62 61 63 ### Every Feature MUST:
+47 -1
Makefile
··· 1 - .PHONY: help dev-up dev-down dev-logs dev-status dev-reset test e2e-test clean verify-stack create-test-account mobile-full-setup 1 + .PHONY: help dev-up dev-down dev-logs dev-status dev-reset test test-all e2e-test clean verify-stack create-test-account mobile-full-setup 2 2 3 3 # Default target - show help 4 4 .DEFAULT_GOAL := help ··· 8 8 RESET := \033[0m 9 9 GREEN := \033[32m 10 10 YELLOW := \033[33m 11 + RED := \033[31m 11 12 12 13 # Load test database configuration from .env.dev 13 14 include .env.dev ··· 155 156 test-db-stop: ## Stop test database 156 157 @docker-compose -f docker-compose.dev.yml --env-file .env.dev --profile test stop postgres-test 157 158 @echo "$(GREEN)✓ Test database stopped$(RESET)" 159 + 160 + test-all: ## Run ALL tests with live infrastructure (required before merge) 161 + @echo "" 162 + @echo "$(CYAN)═══════════════════════════════════════════════════════════════$(RESET)" 163 + @echo "$(CYAN) FULL TEST SUITE - All tests with live infrastructure $(RESET)" 164 + @echo "$(CYAN)═══════════════════════════════════════════════════════════════$(RESET)" 165 + @echo "" 166 + @echo "$(YELLOW)▶ Checking infrastructure...$(RESET)" 167 + @echo "" 168 + @# Check dev stack is running 169 + @echo " Checking dev stack (PDS, Jetstream, PLC)..." 170 + @docker-compose -f docker-compose.dev.yml --env-file .env.dev ps 2>/dev/null | grep -q "Up" || \ 171 + (echo "$(RED) ✗ Dev stack not running. Run 'make dev-up' first.$(RESET)" && exit 1) 172 + @echo " $(GREEN)✓ Dev stack is running$(RESET)" 173 + @# Check AppView is running 174 + @echo " Checking AppView (port 8081)..." 175 + @curl -sf http://127.0.0.1:8081/xrpc/_health >/dev/null 2>&1 || \ 176 + curl -sf http://127.0.0.1:8081/ >/dev/null 2>&1 || \ 177 + (echo "$(RED) ✗ AppView not running. Run 'make run' in another terminal.$(RESET)" && exit 1) 178 + @echo " $(GREEN)✓ AppView is running$(RESET)" 179 + @# Check test database 180 + @echo " Checking test database (port 5434)..." 181 + @docker-compose -f docker-compose.dev.yml --env-file .env.dev ps postgres-test 2>/dev/null | grep -q "Up" || \ 182 + (echo "$(YELLOW) ⚠ Test database not running, starting it...$(RESET)" && \ 183 + docker-compose -f docker-compose.dev.yml --env-file .env.dev --profile test up -d postgres-test && \ 184 + sleep 3 && \ 185 + goose -dir internal/db/migrations postgres "postgresql://$(POSTGRES_TEST_USER):$(POSTGRES_TEST_PASSWORD)@localhost:$(POSTGRES_TEST_PORT)/$(POSTGRES_TEST_DB)?sslmode=disable" up) 186 + @echo " $(GREEN)✓ Test database is running$(RESET)" 187 + @echo "" 188 + @echo "$(GREEN)▶ [1/3] Unit & Package Tests (./cmd/... ./internal/...)$(RESET)" 189 + @echo "$(CYAN)───────────────────────────────────────────────────────────────$(RESET)" 190 + @LOG_ENABLED=false go test ./cmd/... ./internal/... -timeout 120s 191 + @echo "" 192 + @echo "$(GREEN)▶ [2/3] Integration Tests (./tests/integration/...)$(RESET)" 193 + @echo "$(CYAN)───────────────────────────────────────────────────────────────$(RESET)" 194 + @LOG_ENABLED=false go test ./tests/integration/... -timeout 180s 195 + @echo "" 196 + @echo "$(GREEN)▶ [3/3] E2E Tests (./tests/e2e/...)$(RESET)" 197 + @echo "$(CYAN)───────────────────────────────────────────────────────────────$(RESET)" 198 + @LOG_ENABLED=false go test ./tests/e2e/... -timeout 180s 199 + @echo "" 200 + @echo "$(GREEN)═══════════════════════════════════════════════════════════════$(RESET)" 201 + @echo "$(GREEN) ✓ ALL TESTS PASSED - Safe to merge $(RESET)" 202 + @echo "$(GREEN)═══════════════════════════════════════════════════════════════$(RESET)" 203 + @echo "" 158 204 159 205 ##@ Code Quality 160 206
+13
tests/e2e/user_signup_test.go
··· 10 10 "database/sql" 11 11 "encoding/json" 12 12 "fmt" 13 + "io" 14 + "log" 13 15 "net/http" 14 16 "os" 15 17 "testing" ··· 18 20 _ "github.com/lib/pq" 19 21 "github.com/pressly/goose/v3" 20 22 ) 23 + 24 + // TestMain controls test setup for the e2e package. 25 + // Set LOG_ENABLED=false to suppress application log output during tests. 26 + func TestMain(m *testing.M) { 27 + // Silence logs when LOG_ENABLED=false (used by make test-all) 28 + if os.Getenv("LOG_ENABLED") == "false" { 29 + log.SetOutput(io.Discard) 30 + } 31 + 32 + os.Exit(m.Run()) 33 + } 21 34 22 35 // TestE2E_UserSignup tests the full user signup flow: 23 36 // Third-party client → social.coves.actor.signup XRPC → PDS account creation → Jetstream → AppView indexing
+13
tests/integration/user_test.go
··· 9 9 "database/sql" 10 10 "encoding/json" 11 11 "fmt" 12 + "io" 13 + "log" 12 14 "net/http" 13 15 "net/http/httptest" 14 16 "os" ··· 19 21 _ "github.com/lib/pq" 20 22 "github.com/pressly/goose/v3" 21 23 ) 24 + 25 + // TestMain controls test setup for the integration package. 26 + // Set LOG_ENABLED=false to suppress application log output during tests. 27 + func TestMain(m *testing.M) { 28 + // Silence logs when LOG_ENABLED=false (used by make test-all) 29 + if os.Getenv("LOG_ENABLED") == "false" { 30 + log.SetOutput(io.Discard) 31 + } 32 + 33 + os.Exit(m.Run()) 34 + } 22 35 23 36 func setupTestDB(t *testing.T) *sql.DB { 24 37 // Build connection string from environment variables (set by .env.dev)
+13
tests/lexicon_validation_test.go
··· 1 1 package tests 2 2 3 3 import ( 4 + "io" 5 + "log" 4 6 "os" 5 7 "path/filepath" 6 8 "strings" ··· 8 10 9 11 lexicon "github.com/bluesky-social/indigo/atproto/lexicon" 10 12 ) 13 + 14 + // TestMain controls test setup for the tests package. 15 + // Set LOG_ENABLED=false to suppress application log output during tests. 16 + func TestMain(m *testing.M) { 17 + // Silence logs when LOG_ENABLED=false (used by make test-all) 18 + if os.Getenv("LOG_ENABLED") == "false" { 19 + log.SetOutput(io.Discard) 20 + } 21 + 22 + os.Exit(m.Run()) 23 + } 11 24 12 25 func TestLexiconSchemaValidation(t *testing.T) { 13 26 // Create a new catalog
+14
tests/unit/community_service_test.go
··· 4 4 "Coves/internal/core/communities" 5 5 "context" 6 6 "fmt" 7 + "io" 8 + "log" 7 9 "net/http" 8 10 "net/http/httptest" 11 + "os" 9 12 "strings" 10 13 "sync/atomic" 11 14 "testing" 12 15 "time" 13 16 ) 17 + 18 + // TestMain controls test setup for the unit package. 19 + // Set LOG_ENABLED=false to suppress application log output during tests. 20 + func TestMain(m *testing.M) { 21 + // Silence logs when LOG_ENABLED=false (used by make test-all) 22 + if os.Getenv("LOG_ENABLED") == "false" { 23 + log.SetOutput(io.Discard) 24 + } 25 + 26 + os.Exit(m.Run()) 27 + } 14 28 15 29 // mockCommunityRepo is a minimal mock for testing service layer 16 30 type mockCommunityRepo struct {