2026-06-12 19:40:21 +08:00

121 lines
4.5 KiB
Go

package mysql
import (
"context"
"testing"
mysqldriver "github.com/go-sql-driver/mysql"
"hyapp/internal/testutil/mysqlschema"
"hyapp/pkg/appcode"
"hyapp/pkg/xerr"
robotdomain "hyapp/services/robot-service/internal/domain/robot"
)
func TestMigrateLegacyGameRobotsCopiesOnceIntoRobotDatabase(t *testing.T) {
caller := mysqlschema.CallerFile(t, 1)
legacy := mysqlschema.New(t, mysqlschema.Config{
InitDBPath: mysqlschema.InitDBPath(t, caller, "../../../../game-service/deploy/mysql/initdb/001_game_service.sql"),
DatabasePrefix: "hy_game_legacy_test",
})
robot := mysqlschema.New(t, mysqlschema.Config{
InitDBPath: mysqlschema.InitDBPath(t, caller, "../../../deploy/mysql/initdb/001_robot_service.sql"),
DatabasePrefix: "hy_robot_test",
})
legacyDSN, err := mysqldriver.ParseDSN(legacy.DSN)
if err != nil {
t.Fatalf("parse legacy dsn failed: %v", err)
}
ctx := appcode.WithContext(context.Background(), "lalu")
nowMS := int64(1781200000000)
if _, err := legacy.DB.ExecContext(ctx,
`INSERT INTO game_self_game_robots (
app_code, game_id, user_id, status, created_by_admin_id, created_at_ms, updated_at_ms, last_used_at_ms, used_count
) VALUES
(?, 'dice', ?, 'disabled', 7, ?, ?, 11, 1),
(?, 'rock', ?, 'active', 7, ?, ?, 22, 2),
(?, 'dice', ?, 'disabled', 8, ?, ?, 33, 3)`,
"lalu", int64(101), nowMS, nowMS+1,
"lalu", int64(101), nowMS+2, nowMS+3,
"lalu", int64(202), nowMS+4, nowMS+5,
); err != nil {
t.Fatalf("seed legacy robots failed: %v", err)
}
repo, err := Open(ctx, robot.DSN)
if err != nil {
t.Fatalf("open robot repo failed: %v", err)
}
t.Cleanup(func() { _ = repo.Close() })
result, err := repo.MigrateLegacyGameRobots(ctx, legacyDSN.DBName)
if err != nil {
t.Fatalf("migrate legacy robots failed: %v", err)
}
if !result.Applied || !result.SourceFound || result.MigratedRows != 2 {
t.Fatalf("migration result mismatch: %+v", result)
}
items, _, err := repo.ListGameRobots(ctx, "lalu", "rock", "", 20, "")
if err != nil {
t.Fatalf("list migrated robots failed: %v", err)
}
if len(items) != 2 {
t.Fatalf("migrated robots length = %d, want 2: %+v", len(items), items)
}
if items[0].UserID != 101 || items[0].Status != robotdomain.StatusActive || items[0].UsedCount != 2 || items[0].LastUsedAtMS != 22 {
t.Fatalf("active aggregated robot mismatch: %+v", items[0])
}
if items[1].UserID != 202 || items[1].Status != robotdomain.StatusDisabled || items[1].UsedCount != 3 || items[1].LastUsedAtMS != 33 {
t.Fatalf("disabled migrated robot mismatch: %+v", items[1])
}
if _, err := legacy.DB.ExecContext(ctx,
`INSERT INTO game_self_game_robots (
app_code, game_id, user_id, status, created_by_admin_id, created_at_ms, updated_at_ms, last_used_at_ms, used_count
) VALUES (?, 'dice', ?, 'active', 9, ?, ?, 44, 4)`,
"lalu", int64(303), nowMS+6, nowMS+7,
); err != nil {
t.Fatalf("seed post-migration legacy robot failed: %v", err)
}
result, err = repo.MigrateLegacyGameRobots(ctx, legacyDSN.DBName)
if err != nil {
t.Fatalf("rerun legacy migration failed: %v", err)
}
if result.Applied {
t.Fatalf("migration must be one-shot after marker, got %+v", result)
}
items, _, err = repo.ListGameRobots(ctx, "lalu", "dice", "", 20, "")
if err != nil {
t.Fatalf("list after migration rerun failed: %v", err)
}
if len(items) != 2 {
t.Fatalf("rerun must not import new legacy rows, got %+v", items)
}
}
func TestPickGameRobotUsesRobotTableAndExcludesParticipants(t *testing.T) {
caller := mysqlschema.CallerFile(t, 1)
schema := mysqlschema.New(t, mysqlschema.Config{
InitDBPath: mysqlschema.InitDBPath(t, caller, "../../../deploy/mysql/initdb/001_robot_service.sql"),
DatabasePrefix: "hy_robot_test",
})
ctx := appcode.WithContext(context.Background(), "lalu")
repo, err := Open(ctx, schema.DSN)
if err != nil {
t.Fatalf("open robot repo failed: %v", err)
}
t.Cleanup(func() { _ = repo.Close() })
if _, err := repo.RegisterGameRobots(ctx, "lalu", "dice", []int64{101, 202}, 7, 1781200000000); err != nil {
t.Fatalf("register game robots failed: %v", err)
}
if _, err := repo.PickGameRobot(ctx, "lalu", "dice", []int64{101, 202}, 1781200000100); !xerr.IsCode(err, xerr.NotFound) {
t.Fatalf("all excluded robots should return NotFound, got %v", err)
}
robot, err := repo.PickGameRobot(ctx, "lalu", "rock", []int64{101}, 1781200000200)
if err != nil {
t.Fatalf("pick available robot failed: %v", err)
}
if robot.UserID != 202 || robot.GameID != "rock" || robot.LastUsedAtMS != 1781200000200 || robot.UsedCount != 1 {
t.Fatalf("picked robot mismatch: %+v", robot)
}
}