Files
platforms/backend/api/internal/repair/gas_account_test.go
2026-08-17 22:34:02 +08:00

85 lines
3.6 KiB
Go

package repair
import (
"regexp"
"testing"
"time"
"github.com/DATA-DOG/go-sqlmock"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
func repairTestDatabase(t *testing.T) (*gorm.DB, sqlmock.Sqlmock) {
t.Helper()
sqlDatabase, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("创建 SQL Mock 失败:%v", err)
}
t.Cleanup(func() { _ = sqlDatabase.Close() })
database, err := gorm.Open(postgres.New(postgres.Config{Conn: sqlDatabase}), &gorm.Config{})
if err != nil {
t.Fatalf("创建 GORM 数据库失败:%v", err)
}
return database, mock
}
func TestRepairLegacyGasAccountWritesUpdateAndAuditInOneTransaction(t *testing.T) {
database, mock := repairTestDatabase(t)
now := time.Now()
mock.ExpectBegin()
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "gas_account" WHERE role_code = $1 AND "gas_account"."deleted_at" IS NULL LIMIT $2`)).
WithArgs(legacyGasAccountRole, 2).
WillReturnRows(sqlmock.NewRows([]string{"id", "identity", "username", "display_name", "role_code", "status", "created_at", "updated_at"}).
AddRow(9, "gas-account-identity", "xuehai", "", legacyGasAccountRole, 1, now, now))
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "platform_account" WHERE (username = $1 AND status = $2) AND "platform_account"."deleted_at" IS NULL ORDER BY "platform_account"."id" LIMIT $3`)).
WithArgs("root", 1, 1).
WillReturnRows(sqlmock.NewRows([]string{"id", "identity", "username", "platform_role_code", "status", "created_at", "updated_at"}).
AddRow(1, "root-account-identity", "root", "root", 1, now, now))
mock.ExpectExec(regexp.QuoteMeta(`UPDATE "gas_account" SET "display_name"=$1,"role_code"=$2,"updated_at"=$3 WHERE (identity = $4 AND role_code = $5) AND "gas_account"."deleted_at" IS NULL`)).
WithArgs("薛海", gasAdminRole, sqlmock.AnyArg(), "gas-account-identity", legacyGasAccountRole).
WillReturnResult(sqlmock.NewResult(0, 1))
mock.ExpectQuery(`INSERT INTO "audit_operation_log"`).
WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(1))
mock.ExpectCommit()
result, err := RepairLegacyGasAccount(database, "root", " 薛海 ")
if err != nil {
t.Fatalf("修复失败:%v", err)
}
if result.AccountIdentity != "gas-account-identity" || result.OldRoleCode != "010" || result.NewRoleCode != "admin" {
t.Fatalf("修复结果不正确:%#v", result)
}
if result.OldDisplayName != "" || result.NewDisplayName != "薛海" || result.Operator != "root" || result.RepairedAt == nil {
t.Fatalf("修复审计摘要不完整:%#v", result)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Fatalf("数据库事务与审计写入不符合预期:%v", err)
}
}
func TestRepairLegacyGasAccountRefusesAmbiguousTarget(t *testing.T) {
database, mock := repairTestDatabase(t)
now := time.Now()
mock.ExpectBegin()
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "gas_account" WHERE role_code = $1 AND "gas_account"."deleted_at" IS NULL LIMIT $2`)).
WithArgs(legacyGasAccountRole, 2).
WillReturnRows(sqlmock.NewRows([]string{"id", "identity", "role_code", "created_at", "updated_at"}).
AddRow(1, "first", legacyGasAccountRole, now, now).
AddRow(2, "second", legacyGasAccountRole, now, now))
mock.ExpectRollback()
if _, err := RepairLegacyGasAccount(database, "root", "薛海"); err == nil {
t.Fatal("存在多个 010 账号时必须拒绝修复")
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Fatalf("歧义目标不应产生写操作:%v", err)
}
}
func TestInspectLegacyGasAccountRejectsMissingArguments(t *testing.T) {
if _, err := InspectLegacyGasAccount(nil, "root", "薛海"); err == nil {
t.Fatal("缺少数据库时必须拒绝预检")
}
}