package mysqldao import ( "context" "testing" "git.lzcwy.cn/zhengchiliu/zt-closet-backend/internal/mysqlmodel" "github.com/DATA-DOG/go-sqlmock" ) func TestUserDailyUsageConsumeIsAtomic(t *testing.T) { for _, tc := range []struct { name string rows int64 want bool }{ {name: "within_limit", rows: 1, want: true}, {name: "over_limit", rows: 0, want: false}, } { t.Run(tc.name, func(t *testing.T) { base, mock := newQuotaTestDAO(t) dao := &UserDailyUsageDao{db: base.db} mock.ExpectBegin() mock.ExpectExec("INSERT INTO `user_daily_usages`").WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectExec("UPDATE `user_daily_usages` SET `ai_recommend_count`=ai_recommend_count \\+ \\? WHERE"). WithArgs(int64(1), int64(7), int64(20260915), int64(1), int64(3), int64(0)). WillReturnResult(sqlmock.NewResult(0, tc.rows)) mock.ExpectCommit() got, err := dao.UserDailyUsageConsume(context.Background(), 7, 20260915, 2, 1, 3) if err != nil || got != tc.want { t.Fatalf("consumed=%v err=%v, want %v", got, err, tc.want) } if err := mock.ExpectationsWereMet(); err != nil { t.Fatal(err) } }) } } func TestVIPGrantUsesOrderWideIdempotency(t *testing.T) { base, mock := newQuotaTestDAO(t) dao := &UserDao{db: base.db} mock.ExpectBegin() mock.ExpectQuery("SELECT .* FROM `users` .*FOR UPDATE"). WillReturnRows(sqlmock.NewRows([]string{"id", "vip_type", "vip_expire"}).AddRow(7, 2, 2000)) mock.ExpectQuery("SELECT count\\(\\*\\) FROM `vip_flow_logs`"). WithArgs("ORDER-1", int8(1), int8(2), int64(0)). WillReturnRows(sqlmock.NewRows([]string{"count(*)"}).AddRow(1)) mock.ExpectCommit() flow := &mysqlmodel.VIPFlowLog{OrderNo: "ORDER-1", ChangeType: 2} if err := dao.VIPGrantIdempotent(context.Background(), 7, 1000, 30, 2, flow); err != nil { t.Fatal(err) } if err := mock.ExpectationsWereMet(); err != nil { t.Fatal(err) } } func TestRefundSettlementCreatesRevokeTaskAtomically(t *testing.T) { base, mock := newQuotaTestDAO(t) dao := &BenefitRevokeTaskDao{db: base.db} mock.ExpectBegin() mock.ExpectQuery("SELECT .* FROM `orders` .*FOR UPDATE"). WillReturnRows(sqlmock.NewRows([]string{"id", "order_no", "user_id", "order_status"}).AddRow(8, "ORDER-1", 7, 2)) mock.ExpectExec("UPDATE `orders` SET").WillReturnResult(sqlmock.NewResult(0, 1)) mock.ExpectExec("UPDATE `benefit_grant_tasks` SET").WillReturnResult(sqlmock.NewResult(0, 2)) mock.ExpectExec("INSERT INTO `benefit_revoke_tasks`").WillReturnResult(sqlmock.NewResult(3, 1)) mock.ExpectCommit() settled, err := dao.RefundSettleWithRevokeTask(context.Background(), "ORDER-1", 990, 1234) if err != nil || !settled { t.Fatalf("settled=%v err=%v", settled, err) } if err := mock.ExpectationsWereMet(); err != nil { t.Fatal(err) } }