169 lines
4.2 KiB
Go
169 lines
4.2 KiB
Go
package user
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/alicebob/miniredis/v2"
|
|
"github.com/perfect-panel/server/internal/config"
|
|
"github.com/perfect-panel/server/internal/model/order"
|
|
"github.com/perfect-panel/server/internal/model/subscribe"
|
|
"github.com/perfect-panel/server/internal/model/user"
|
|
"github.com/perfect-panel/server/internal/svc"
|
|
"github.com/perfect-panel/server/internal/types"
|
|
"github.com/perfect-panel/server/pkg/constant"
|
|
"github.com/redis/go-redis/v9"
|
|
"github.com/stretchr/testify/assert"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// setupTestSvcCtx 初始化测试上下文
|
|
func setupTestSvcCtx(t *testing.T) (*svc.ServiceContext, *gorm.DB) {
|
|
// 1. Setup Miniredis
|
|
mr, err := miniredis.Run()
|
|
assert.NoError(t, err)
|
|
|
|
rdb := redis.NewClient(&redis.Options{
|
|
Addr: mr.Addr(),
|
|
})
|
|
|
|
// 2. Setup GORM with SQLite
|
|
dbName := fmt.Sprintf("test_sales_%d.db", time.Now().UnixNano())
|
|
db, err := gorm.Open(sqlite.Open(dbName), &gorm.Config{})
|
|
assert.NoError(t, err)
|
|
|
|
t.Cleanup(func() {
|
|
os.Remove(dbName)
|
|
mr.Close()
|
|
})
|
|
|
|
// Migrate tables
|
|
_ = db.Migrator().CreateTable(&user.User{})
|
|
_ = db.Migrator().CreateTable(&subscribe.Subscribe{}) // Plan definition
|
|
_ = db.Migrator().CreateTable(&order.Order{})
|
|
|
|
// 3. Create ServiceContext
|
|
svcCtx := &svc.ServiceContext{
|
|
Redis: rdb,
|
|
DB: db,
|
|
Config: config.Config{},
|
|
UserModel: user.NewModel(db, rdb),
|
|
}
|
|
|
|
return svcCtx, db
|
|
}
|
|
|
|
func TestGetInviteSales_TimeFilter(t *testing.T) {
|
|
svcCtx, db := setupTestSvcCtx(t)
|
|
|
|
// 1. Prepare Data
|
|
// Referrer User (Current User)
|
|
referrer := &user.User{
|
|
Id: 100,
|
|
// Email removed (not in struct)
|
|
ReferCode: "REF100",
|
|
}
|
|
db.Create(referrer)
|
|
|
|
// Invited User
|
|
invitedUser := &user.User{
|
|
Id: 200,
|
|
// Email removed
|
|
RefererId: referrer.Id, // Linked to referrer
|
|
}
|
|
db.Create(invitedUser)
|
|
|
|
// Subscribe (Plan)
|
|
sub := &subscribe.Subscribe{
|
|
Id: 1,
|
|
Name: "Standard Plan",
|
|
}
|
|
db.Create(sub)
|
|
|
|
// Orders
|
|
// Order 1: Inside Range (2023-10-15)
|
|
timeIn := time.Date(2023, 10, 15, 12, 0, 0, 0, time.UTC)
|
|
db.Create(&order.Order{
|
|
UserId: invitedUser.Id,
|
|
OrderNo: "ORD001",
|
|
Status: 5, // Finished
|
|
Amount: 1000,
|
|
Quantity: 30,
|
|
SubscribeId: sub.Id,
|
|
UpdatedAt: timeIn,
|
|
})
|
|
|
|
// Order 2: Before Range (2023-09-15)
|
|
timeBefore := time.Date(2023, 9, 15, 12, 0, 0, 0, time.UTC)
|
|
db.Create(&order.Order{
|
|
UserId: invitedUser.Id,
|
|
OrderNo: "ORD002",
|
|
Status: 5, // Finished
|
|
Amount: 1000,
|
|
Quantity: 30,
|
|
SubscribeId: sub.Id,
|
|
UpdatedAt: timeBefore,
|
|
})
|
|
|
|
// Order 3: After Range (2023-11-15)
|
|
timeAfter := time.Date(2023, 11, 15, 12, 0, 0, 0, time.UTC)
|
|
db.Create(&order.Order{
|
|
UserId: invitedUser.Id,
|
|
OrderNo: "ORD003",
|
|
Status: 5, // Finished
|
|
Amount: 1000,
|
|
Quantity: 30,
|
|
SubscribeId: sub.Id,
|
|
UpdatedAt: timeAfter,
|
|
})
|
|
|
|
// Order 4: Wrong Status (2023-10-16) - Should be ignored
|
|
db.Create(&order.Order{
|
|
UserId: invitedUser.Id,
|
|
OrderNo: "ORD004",
|
|
Status: 1, // Pending
|
|
Amount: 1000,
|
|
Quantity: 30,
|
|
SubscribeId: sub.Id,
|
|
UpdatedAt: timeIn.Add(24 * time.Hour),
|
|
})
|
|
|
|
// 2. Execute Logic
|
|
// Context with current user
|
|
ctx := context.WithValue(context.Background(), constant.CtxKeyUser, referrer)
|
|
l := NewGetInviteSalesLogic(ctx, svcCtx)
|
|
|
|
// Filter for October 2023
|
|
startTime := time.Date(2023, 10, 1, 0, 0, 0, 0, time.UTC).Unix()
|
|
endTime := time.Date(2023, 10, 31, 23, 59, 59, 0, time.UTC).Unix()
|
|
|
|
req := &types.GetInviteSalesRequest{
|
|
Page: 1,
|
|
Size: 10,
|
|
StartTime: startTime, // 2023-10-01
|
|
EndTime: endTime, // 2023-10-31
|
|
}
|
|
|
|
resp, err := l.GetInviteSales(req)
|
|
assert.NoError(t, err)
|
|
|
|
// 3. Verify Results
|
|
// Should match exactly 1 order (ORD001)
|
|
assert.Equal(t, int64(1), resp.Total, "Should return exactly 1 order matching time range and status")
|
|
if assert.NotEmpty(t, resp.List) {
|
|
assert.Equal(t, 1, len(resp.List))
|
|
// Log result for debug
|
|
t.Logf("Found Sale: Amount=%.2f, Time=%d", resp.List[0].Amount, resp.List[0].UpdatedAt)
|
|
|
|
// Verify timestamp is roughly correct (millisecond precision in logic)
|
|
expectedMs := timeIn.Unix() * 1000
|
|
assert.Equal(t, expectedMs, resp.List[0].UpdatedAt)
|
|
} else {
|
|
t.Error("Returned list is empty")
|
|
}
|
|
}
|