Files
2026-09-15 00:53:04 +08:00

70 lines
3.0 KiB
Go

package service
import (
"context"
"errors"
"testing"
"git.lzcwy.cn/zhengchiliu/zt-closet-backend/global"
"git.lzcwy.cn/zhengchiliu/zt-closet-backend/internal/mysqlmodel"
"git.lzcwy.cn/zhengchiliu/zt-closet-backend/pkg/errcode"
"github.com/DATA-DOG/go-sqlmock"
"go.opentelemetry.io/otel/trace/noop"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
func setupOrderQuotaTest(t *testing.T) sqlmock.Sqlmock {
t.Helper()
conn, mock, err := sqlmock.New()
if err != nil {
t.Fatal(err)
}
db, err := gorm.Open(mysql.New(mysql.Config{Conn: conn, SkipInitializeWithVersion: true}), &gorm.Config{Logger: logger.Default.LogMode(logger.Silent)})
if err != nil {
t.Fatal(err)
}
oldDB, oldTracer := global.MysqlEngine, global.Tracer
global.MysqlEngine, global.Tracer = db, noop.NewTracerProvider().Tracer("order-test")
t.Cleanup(func() { global.MysqlEngine, global.Tracer = oldDB, oldTracer; conn.Close() })
return mock
}
func TestOrderQuotaGoodsReadFailureDoesNotGrant(t *testing.T) {
mock := setupOrderQuotaTest(t)
mock.ExpectQuery("SELECT .* FROM `orders`").WillReturnRows(sqlmock.NewRows([]string{"order_no", "goods_type", "quota_valid_days"}).AddRow("RENEW", 0, 0))
mock.ExpectQuery("SELECT .* FROM `goods`").WillReturnError(errors.New("database unavailable"))
err := NewOrderService().grantQuotaGrant(context.Background(), &mysqlmodel.BenefitGrantTask{UserID: 7, GoodsID: 9, OrderNo: "RENEW", Amount: 100}, QuotaTypeCos)
if err != errcode.DatabaseError {
t.Fatalf("got %v, want DatabaseError", err)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Fatal(err)
}
}
func TestOrderRenewalAndCompensationSkipQuota(t *testing.T) {
mock := setupOrderQuotaTest(t)
svc := NewOrderService()
// 首购凭证已存在:新续费订单和该订单补偿执行均不得插入额度或流水。
for i := 0; i < 2; i++ {
mock.ExpectQuery("SELECT .* FROM `orders`").WillReturnRows(sqlmock.NewRows([]string{"order_no", "goods_type", "quota_valid_days"}).AddRow("RENEW", GoodsTypeMember, 30))
mock.ExpectQuery("SELECT .* FROM `users`").WillReturnRows(sqlmock.NewRows([]string{"id", "vip_expire"}).AddRow(7, nowUnix()+86400))
mock.ExpectQuery("SELECT .* FROM `quota_grants`").WillReturnRows(sqlmock.NewRows([]string{"id", "source", "amount", "used", "expire_time"}).AddRow(1, QuotaGrantSourceMember, 100, 40, 0))
mock.ExpectQuery("SELECT .* FROM `user_quotas`").WillReturnRows(sqlmock.NewRows([]string{"used"}).AddRow(0))
mock.ExpectBegin()
mock.ExpectQuery("SELECT .* FROM `users` .*FOR UPDATE").WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(7))
mock.ExpectQuery("SELECT quota_grants.* .*FOR UPDATE").WithArgs(7, 9, QuotaTypeCos, QuotaGrantSourceMember, 1).
WillReturnRows(sqlmock.NewRows([]string{"id", "amount", "used", "ref_id"}).AddRow(1, 100, 40, "FIRST"))
mock.ExpectCommit()
err := svc.doGrantBenefit(context.Background(), &mysqlmodel.BenefitGrantTask{UserID: 7, GoodsID: 9, OrderNo: "RENEW", Amount: 100, BenefitType: BenefitTypeCos})
if err != nil {
t.Fatal(err)
}
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Fatal(err)
}
}