115 lines
3.7 KiB
Go
115 lines
3.7 KiB
Go
// Package mysqltest provides real room-service MySQL repositories for tests.
|
|
package mysqltest
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"testing"
|
|
|
|
"google.golang.org/protobuf/proto"
|
|
roomeventsv1 "hyapp.local/api/proto/events/room/v1"
|
|
"hyapp/internal/testutil/mysqlschema"
|
|
"hyapp/pkg/appcode"
|
|
"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()
|
|
}
|
|
}
|
|
|
|
// SetRoomStatus simulates an external admin status update against room-service tables.
|
|
func (r *Repository) SetRoomStatus(roomID string, status string) {
|
|
r.t.Helper()
|
|
|
|
ctx := context.Background()
|
|
if _, err := r.schema.DB.ExecContext(ctx, `UPDATE rooms SET status = ? WHERE app_code = ? AND room_id = ?`, status, appcode.Default, roomID); err != nil {
|
|
r.t.Fatalf("update room status failed: %v", err)
|
|
}
|
|
if _, err := r.schema.DB.ExecContext(ctx, `UPDATE room_list_entries SET status = ? WHERE app_code = ? AND room_id = ?`, status, appcode.Default, roomID); err != nil {
|
|
r.t.Fatalf("update room list status failed: %v", err)
|
|
}
|
|
}
|
|
|
|
// DeleteRoomListEntry removes the discovery projection while keeping rooms metadata.
|
|
func (r *Repository) DeleteRoomListEntry(roomID string) {
|
|
r.t.Helper()
|
|
|
|
if _, err := r.schema.DB.ExecContext(context.Background(), `DELETE FROM room_list_entries WHERE app_code = ? AND room_id = ?`, appcode.Default, roomID); err != nil {
|
|
r.t.Fatalf("delete room list entry failed: %v", err)
|
|
}
|
|
}
|
|
|
|
// OutboxRecord reads one outbox row, including delivered 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 app_code, event_id, event_type, room_id, status, worker_id, lock_until_ms, envelope, created_at_ms, retry_count, COALESCE(last_error, '')
|
|
FROM room_outbox
|
|
WHERE app_code = ? AND event_id = ?
|
|
`, appcode.Default, eventID)
|
|
|
|
var envelopeBytes []byte
|
|
var record outbox.Record
|
|
var lockUntil sql.Null[int64]
|
|
if err := row.Scan(&record.AppCode, &record.EventID, &record.EventType, &record.RoomID, &record.Status, &record.WorkerID, &lockUntil, &envelopeBytes, &record.CreatedAtMS, &record.RetryCount, &record.LastError); err != nil {
|
|
if err == sql.ErrNoRows {
|
|
return outbox.Record{}, false
|
|
}
|
|
r.t.Fatalf("query room outbox record failed: %v", err)
|
|
}
|
|
if lockUntil.Valid {
|
|
record.LockUntilMS = lockUntil.V
|
|
}
|
|
|
|
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",
|
|
)
|
|
}
|