// Package mysqltest provides real room-service MySQL repositories for tests. package mysqltest import ( "context" "database/sql" "testing" "google.golang.org/protobuf/proto" roomeventsv1 "hyapp/api/proto/events/room/v1" "hyapp/internal/testutil/mysqlschema" "hyapp/services/room-service/internal/room/outbox" mysqlstorage "hyapp/services/room-service/internal/storage/mysql" ) // Repository wraps the production room MySQL repository with test-only read helpers. type Repository struct { *mysqlstorage.Repository t testing.TB schema *mysqlschema.Schema } // NewRepository creates an isolated room schema and opens the production repository. func NewRepository(t testing.TB) *Repository { t.Helper() schema := mysqlschema.New(t, mysqlschema.Config{ EnvVar: "ROOM_SERVICE_MYSQL_TEST_DSN", InitDBPath: initDBPath(t), DatabasePrefix: "hyapp_room_test", }) repository, err := mysqlstorage.Open(context.Background(), schema.DSN, 4, 4) if err != nil { t.Fatalf("open room mysql repository failed: %v", err) } wrapped := &Repository{Repository: repository, t: t, schema: schema} t.Cleanup(wrapped.Close) return wrapped } // Close shuts down the repository; mysqlschema owns schema cleanup. func (r *Repository) Close() { r.t.Helper() if r.Repository != nil { _ = r.Repository.Close() } } // OutboxRecord reads one outbox row, including published rows that normal scans skip. func (r *Repository) OutboxRecord(eventID string) (outbox.Record, bool) { r.t.Helper() row := r.schema.DB.QueryRowContext(context.Background(), ` SELECT event_id, event_type, room_id, status, envelope, created_at, retry_count, COALESCE(last_error, '') FROM room_outbox WHERE event_id = ? `, eventID) var envelopeBytes []byte var record outbox.Record if err := row.Scan(&record.EventID, &record.EventType, &record.RoomID, &record.Status, &envelopeBytes, &record.CreatedAt, &record.RetryCount, &record.LastError); err != nil { if err == sql.ErrNoRows { return outbox.Record{}, false } r.t.Fatalf("query room outbox record failed: %v", err) } var envelope roomeventsv1.EventEnvelope if err := proto.Unmarshal(envelopeBytes, &envelope); err != nil { r.t.Fatalf("decode room outbox envelope failed: %v", err) } record.Envelope = &envelope return record, true } func initDBPath(t testing.TB) string { t.Helper() return mysqlschema.InitDBPath(t, mysqlschema.CallerFile(t, 1), "..", "..", "..", "deploy", "mysql", "initdb", "001_room_service.sql", ) }