//go:build integration package mysql import ( "context" "database/sql" "os" "path/filepath" "strings" "testing" "time" _ "github.com/go-sql-driver/mysql" "github.com/testcontainers/testcontainers-go" tcmysql "github.com/testcontainers/testcontainers-go/modules/mysql" "github.com/testcontainers/testcontainers-go/wait" ) func TestTaskRepositoryReportsWithMySQL(t *testing.T) { ctx := context.Background() dsn := testDSN(ctx, t) db, err := sql.Open("mysql", dsn) if err != nil { t.Fatal(err) } defer db.Close() migrate(ctx, t, db) repo := NewTaskRepository(db) if _, err := repo.TeamSummary(context.Background()); err != nil { t.Fatalf("team summary query failed: %v", err) } if _, err := repo.TopCreators(context.Background()); err != nil { t.Fatalf("top creators query failed: %v", err) } if _, err := repo.InvalidAssignees(context.Background()); err != nil { t.Fatalf("invalid assignees query failed: %v", err) } } func testDSN(ctx context.Context, t *testing.T) string { t.Helper() if dsn := os.Getenv("TEST_MYSQL_DSN"); dsn != "" { return dsn } container, err := tcmysql.Run(ctx, "mysql:8.4", tcmysql.WithDatabase("task_service_test"), tcmysql.WithUsername("app"), tcmysql.WithPassword("app"), testcontainers.WithWaitStrategy(wait.ForListeningPort("3306/tcp").WithStartupTimeout(2*time.Minute)), ) if err != nil { t.Fatalf("start mysql container: %v", err) } t.Cleanup(func() { _ = testcontainers.TerminateContainer(container) }) dsn, err := container.ConnectionString(ctx, "parseTime=true", "multiStatements=true") if err != nil { t.Fatalf("mysql dsn: %v", err) } return dsn } func migrate(ctx context.Context, t *testing.T, db *sql.DB) { t.Helper() data, err := os.ReadFile(filepath.Join("..", "..", "..", "migrations", "001_init.sql")) if err != nil { t.Fatal(err) } for _, stmt := range strings.Split(string(data), ";") { stmt = strings.TrimSpace(stmt) if stmt == "" { continue } if _, err := db.ExecContext(ctx, stmt); err != nil { t.Fatalf("migration failed: %v\nsql: %s", err, stmt) } } }