feat(quality-owner): 增加优质号主自助取消与权益校验
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package qualityowner
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"hfb_sys/backend/internal/database"
|
||||
@@ -112,3 +113,97 @@ func TestAdminCanGrantQualityOwnerWithoutWalletDeposit(t *testing.T) {
|
||||
t.Fatalf("后台手动开通不应产生钱包流水,实际 %d 条", ledgerCount)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelQualityOwnerRequiresNoActivePremiumListings(t *testing.T) {
|
||||
db := database.NewTestDB()
|
||||
user := model.User{
|
||||
Phone: "13900009303",
|
||||
RealnameStatus: "verified",
|
||||
Status: "active",
|
||||
}
|
||||
if err := db.Create(&user).Error; err != nil {
|
||||
t.Fatalf("创建用户失败: %v", err)
|
||||
}
|
||||
account := model.WalletAccount{
|
||||
UserID: user.ID,
|
||||
AvailableBalanceCent: 30_000,
|
||||
Status: "active",
|
||||
}
|
||||
if err := db.Create(&account).Error; err != nil {
|
||||
t.Fatalf("创建钱包失败: %v", err)
|
||||
}
|
||||
repo := NewRepository(db)
|
||||
if _, err := repo.Activate(t.Context(), user.ID); err != nil {
|
||||
t.Fatalf("开通优质号主失败: %v", err)
|
||||
}
|
||||
premiumListing := model.RentalListing{
|
||||
ListingNo: "QO-CANCEL-ACTIVE",
|
||||
AccountID: 1,
|
||||
OwnerID: user.ID,
|
||||
Status: "published",
|
||||
ReviewStatus: "approved",
|
||||
IsPremium: true,
|
||||
}
|
||||
if err := db.Create(&premiumListing).Error; err != nil {
|
||||
t.Fatalf("创建极品专区商品失败: %v", err)
|
||||
}
|
||||
|
||||
status, err := repo.Status(t.Context(), user.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("读取优质号主状态失败: %v", err)
|
||||
}
|
||||
if status.ActivePremiumListings != 1 || status.CanCancel {
|
||||
t.Fatalf("进行中极品商品统计不正确: %+v", status)
|
||||
}
|
||||
if _, err := repo.Cancel(t.Context(), user.ID, AuditMeta{}); !errors.Is(err, ErrActivePremiumListings) {
|
||||
t.Fatalf("用户取消 error = %v, want ErrActivePremiumListings", err)
|
||||
}
|
||||
if _, err := repo.AdminSet(t.Context(), 99, user.ID, AdminSetRequest{
|
||||
Enabled: false,
|
||||
Reason: "后台尝试取消",
|
||||
}, AuditMeta{}); !errors.Is(err, ErrActivePremiumListings) {
|
||||
t.Fatalf("后台取消 error = %v, want ErrActivePremiumListings", err)
|
||||
}
|
||||
|
||||
if err := db.Model(&premiumListing).Updates(map[string]any{
|
||||
"status": "offline",
|
||||
"review_status": "none",
|
||||
}).Error; err != nil {
|
||||
t.Fatalf("下架极品商品失败: %v", err)
|
||||
}
|
||||
draftListing := model.RentalListing{
|
||||
ListingNo: "QO-CANCEL-DRAFT",
|
||||
AccountID: 2,
|
||||
OwnerID: user.ID,
|
||||
Status: "draft",
|
||||
ReviewStatus: "none",
|
||||
IsPremium: true,
|
||||
}
|
||||
if err := db.Create(&draftListing).Error; err != nil {
|
||||
t.Fatalf("创建极品专区草稿失败: %v", err)
|
||||
}
|
||||
|
||||
status, err = repo.Cancel(t.Context(), user.ID, AuditMeta{RequestID: "quality-owner-self-cancel"})
|
||||
if err != nil {
|
||||
t.Fatalf("自动取消优质号主失败: %v", err)
|
||||
}
|
||||
if status.Active || status.DepositAmountCent != 0 || status.AvailableBalanceCent != 30_000 {
|
||||
t.Fatalf("取消后的状态不正确: %+v", status)
|
||||
}
|
||||
var gotDraft model.RentalListing
|
||||
if err := db.First(&gotDraft, draftListing.ID).Error; err != nil {
|
||||
t.Fatalf("读取草稿失败: %v", err)
|
||||
}
|
||||
if gotDraft.Status != "offline" {
|
||||
t.Fatalf("取消后草稿状态 = %s, want offline", gotDraft.Status)
|
||||
}
|
||||
var auditCount int64
|
||||
if err := db.Model(&model.AuditLog{}).
|
||||
Where("action = ? AND biz_id = ?", "quality_owner.cancel", user.ID).
|
||||
Count(&auditCount).Error; err != nil {
|
||||
t.Fatalf("统计自动取消审计日志失败: %v", err)
|
||||
}
|
||||
if auditCount != 1 {
|
||||
t.Fatalf("自动取消审计日志条数 = %d, want 1", auditCount)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user