//go:build integration // Package testutil provides shared helpers for integration tests, which run // against the compose Mongo (published on 127.0.0.1 by // docker-compose.test.yml) using a per-run database name that is dropped on // cleanup. package testutil import ( "context" "os" "strings" "testing" "time" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" "go.mongodb.org/mongo-driver/v2/mongo/readpref" "bountyboard/internal/ulid" ) // MongoDB connects to the test Mongo (MONGO_TEST_URI, default localhost) and // returns a database with a unique per-run name, dropped automatically. func MongoDB(t *testing.T) *mongo.Database { t.Helper() uri := os.Getenv("MONGO_TEST_URI") if uri == "" { uri = "mongodb://127.0.0.1:27017" } client, err := mongo.Connect(options.Client(). ApplyURI(uri). SetServerSelectionTimeout(5 * time.Second)) if err != nil { t.Fatalf("mongo connect: %v", err) } ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() if err := client.Ping(ctx, readpref.Primary()); err != nil { t.Fatalf("mongo at %s not reachable (start it with: docker compose -f docker-compose.yml -f docker-compose.test.yml up -d mongo): %v", uri, err) } db := client.Database("bountyboard_test_" + strings.ToLower(ulid.New())) t.Cleanup(func() { ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() if err := db.Drop(ctx); err != nil { t.Errorf("drop test db: %v", err) } _ = client.Disconnect(ctx) }) return db }