170 lines
4.6 KiB
Go
170 lines
4.6 KiB
Go
package ordertimeout
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"hfb_sys/backend/internal/model"
|
|
"hfb_sys/backend/internal/modules/chat"
|
|
|
|
"go.uber.org/zap"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/logger"
|
|
)
|
|
|
|
func setupOrderTimeoutTestDB(t *testing.T) *gorm.DB {
|
|
t.Helper()
|
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{
|
|
Logger: logger.Default.LogMode(logger.Silent),
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("无法创建测试数据库: %v", err)
|
|
}
|
|
if err := db.AutoMigrate(
|
|
&model.RentalOrder{},
|
|
&model.ChatConversation{},
|
|
&model.ChatParticipant{},
|
|
&model.ChatMessage{},
|
|
&model.SystemConfig{},
|
|
&model.AuditLog{},
|
|
); err != nil {
|
|
t.Fatalf("数据库迁移失败: %v", err)
|
|
}
|
|
return db
|
|
}
|
|
|
|
func TestHandleEndedOrderRenterRetention(t *testing.T) {
|
|
db := setupOrderTimeoutTestDB(t)
|
|
job := New(db, nil, zap.NewNop())
|
|
now := time.Date(2026, 6, 18, 12, 0, 0, 0, time.UTC)
|
|
|
|
oldSettledAt := now.AddDate(0, 0, -6)
|
|
recentSettledAt := now.AddDate(0, 0, -2)
|
|
oldOrder := model.RentalOrder{
|
|
OrderNo: "ORDER-OLD",
|
|
ListingID: 101,
|
|
AccountID: 201,
|
|
OwnerID: 301,
|
|
RenterID: 401,
|
|
Status: "completed",
|
|
SettledAt: &oldSettledAt,
|
|
}
|
|
recentOrder := model.RentalOrder{
|
|
OrderNo: "ORDER-RECENT",
|
|
ListingID: 102,
|
|
AccountID: 202,
|
|
OwnerID: 302,
|
|
RenterID: 402,
|
|
Status: "completed",
|
|
SettledAt: &recentSettledAt,
|
|
}
|
|
if err := db.Create(&oldOrder).Error; err != nil {
|
|
t.Fatalf("创建旧订单失败: %v", err)
|
|
}
|
|
if err := db.Create(&recentOrder).Error; err != nil {
|
|
t.Fatalf("创建新订单失败: %v", err)
|
|
}
|
|
|
|
oldConv := model.ChatConversation{
|
|
ListingID: &oldOrder.ListingID,
|
|
Type: chat.ConversationTypeListingGroup,
|
|
Title: "旧发布群",
|
|
Status: "active",
|
|
}
|
|
recentConv := model.ChatConversation{
|
|
ListingID: &recentOrder.ListingID,
|
|
Type: chat.ConversationTypeListingGroup,
|
|
Title: "新发布群",
|
|
Status: "active",
|
|
}
|
|
if err := db.Create(&oldConv).Error; err != nil {
|
|
t.Fatalf("创建旧会话失败: %v", err)
|
|
}
|
|
if err := db.Create(&recentConv).Error; err != nil {
|
|
t.Fatalf("创建新会话失败: %v", err)
|
|
}
|
|
participants := []model.ChatParticipant{
|
|
{ConversationID: oldConv.ID, ParticipantType: "user", ParticipantID: oldOrder.RenterID, Role: "renter", JoinedAt: oldSettledAt},
|
|
{ConversationID: recentConv.ID, ParticipantType: "user", ParticipantID: recentOrder.RenterID, Role: "renter", JoinedAt: recentSettledAt},
|
|
}
|
|
if err := db.Create(&participants).Error; err != nil {
|
|
t.Fatalf("创建成员失败: %v", err)
|
|
}
|
|
|
|
count, err := job.handleEndedOrderRenterRetention(t.Context(), now, thresholds{
|
|
RenterRetentionDaysAfterOrderEnd: 5,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("清退任务失败: %v", err)
|
|
}
|
|
if count != 1 {
|
|
t.Fatalf("清退数量 = %d, want 1", count)
|
|
}
|
|
|
|
var oldCount int64
|
|
if err := db.Model(&model.ChatParticipant{}).
|
|
Where("conversation_id = ? AND participant_id = ? AND role = ?", oldConv.ID, oldOrder.RenterID, "renter").
|
|
Count(&oldCount).Error; err != nil {
|
|
t.Fatalf("统计旧租客失败: %v", err)
|
|
}
|
|
if oldCount != 0 {
|
|
t.Fatalf("旧租客成员数 = %d, want 0", oldCount)
|
|
}
|
|
|
|
var recentCount int64
|
|
if err := db.Model(&model.ChatParticipant{}).
|
|
Where("conversation_id = ? AND participant_id = ? AND role = ?", recentConv.ID, recentOrder.RenterID, "renter").
|
|
Count(&recentCount).Error; err != nil {
|
|
t.Fatalf("统计新租客失败: %v", err)
|
|
}
|
|
if recentCount != 1 {
|
|
t.Fatalf("新租客成员数 = %d, want 1", recentCount)
|
|
}
|
|
|
|
var auditCount int64
|
|
if err := db.Model(&model.AuditLog{}).
|
|
Where("action = ?", "chat.renter_retention.remove").
|
|
Count(&auditCount).Error; err != nil {
|
|
t.Fatalf("统计清退审计失败: %v", err)
|
|
}
|
|
if auditCount != 1 {
|
|
t.Fatalf("清退审计数 = %d, want 1", auditCount)
|
|
}
|
|
|
|
count, err = job.handleEndedOrderRenterRetention(t.Context(), now, thresholds{
|
|
RenterRetentionDaysAfterOrderEnd: 5,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("重复清退任务失败: %v", err)
|
|
}
|
|
if count != 0 {
|
|
t.Fatalf("重复清退数量 = %d, want 0", count)
|
|
}
|
|
|
|
if err := db.Model(&model.AuditLog{}).
|
|
Where("action = ?", "chat.renter_retention.remove").
|
|
Count(&auditCount).Error; err != nil {
|
|
t.Fatalf("重复统计清退审计失败: %v", err)
|
|
}
|
|
if auditCount != 1 {
|
|
t.Fatalf("重复清退审计数 = %d, want 1", auditCount)
|
|
}
|
|
}
|
|
|
|
func TestClampRenterRetentionDays(t *testing.T) {
|
|
tests := []struct {
|
|
value int
|
|
want int
|
|
}{
|
|
{value: 1, want: 3},
|
|
{value: 5, want: 5},
|
|
{value: 9, want: 7},
|
|
}
|
|
for _, tt := range tests {
|
|
if got := clampRenterRetentionDays(tt.value); got != tt.want {
|
|
t.Fatalf("clampRenterRetentionDays(%d) = %d, want %d", tt.value, got, tt.want)
|
|
}
|
|
}
|
|
}
|