70 lines
3.0 KiB
Go
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)
|
|
}
|
|
}
|