bindbox-game/internal/api/user/sync_douyin_orders_app_test.go
2026-04-20 15:53:31 +08:00

192 lines
5.3 KiB
Go

package app
import (
"bytes"
"context"
"encoding/json"
"errors"
"net/http"
"net/http/httptest"
"testing"
"time"
"bindbox-game/internal/pkg/core"
"bindbox-game/internal/pkg/logger"
"bindbox-game/internal/proposal"
"bindbox-game/internal/repository/mysql"
"bindbox-game/internal/repository/mysql/model"
douyinsvc "bindbox-game/internal/service/douyin"
)
type fakeDouyinService struct {
syncUserOrdersFn func(ctx context.Context, localUserID int64) (*douyinsvc.SyncResult, error)
}
func (f *fakeDouyinService) FetchAndSyncOrders(ctx context.Context, opts *douyinsvc.FetchOptions) (*douyinsvc.SyncResult, error) {
return nil, nil
}
func (f *fakeDouyinService) SyncUserOrders(ctx context.Context, localUserID int64) (*douyinsvc.SyncResult, error) {
if f.syncUserOrdersFn == nil {
return nil, nil
}
return f.syncUserOrdersFn(ctx, localUserID)
}
func (f *fakeDouyinService) SyncAllOrders(ctx context.Context, duration time.Duration, useProxy bool) (*douyinsvc.SyncResult, error) {
return nil, nil
}
func (f *fakeDouyinService) ListOrders(ctx context.Context, page, pageSize int, filter *douyinsvc.ListOrdersFilter) ([]*model.DouyinOrders, int64, error) {
return nil, 0, nil
}
func (f *fakeDouyinService) GetConfig(ctx context.Context) (*douyinsvc.DouyinConfig, error) {
return nil, nil
}
func (f *fakeDouyinService) SaveConfig(ctx context.Context, cookie, proxy string, intervalMinutes int) error {
return nil
}
func (f *fakeDouyinService) SyncOrder(ctx context.Context, item *douyinsvc.DouyinOrderItem, suggestUserID int64, productID string) (bool, bool) {
return false, false
}
func (f *fakeDouyinService) GrantMinesweeperQualifications(ctx context.Context) error {
return nil
}
func (f *fakeDouyinService) GrantLivestreamPrizes(ctx context.Context) error {
return nil
}
func (f *fakeDouyinService) SyncRefundStatus(ctx context.Context) error {
return nil
}
func (f *fakeDouyinService) GrantOrderReward(ctx context.Context, shopOrderID string) (*douyinsvc.GrantOrderRewardResult, error) {
return nil, nil
}
func TestSyncMyDouyinOrders_AppSuccess(t *testing.T) {
repo, err := mysql.NewSQLiteRepoForTest()
if err != nil {
t.Fatal(err)
}
if err := repo.GetDbW().Exec(`CREATE TABLE users (
id INTEGER PRIMARY KEY,
nickname TEXT,
douyin_user_id TEXT,
deleted_at DATETIME
)`).Error; err != nil {
t.Fatal(err)
}
if err := repo.GetDbW().Exec(`INSERT INTO users (id, nickname, douyin_user_id) VALUES (1, 'tester', 'dy_user_001')`).Error; err != nil {
t.Fatal(err)
}
lg, err := logger.NewCustomLogger(logger.WithOutputInConsole())
if err != nil {
t.Fatal(err)
}
mux, err := core.New(lg)
if err != nil {
t.Fatal(err)
}
h := New(lg, repo, nil)
h.douyin = &fakeDouyinService{
syncUserOrdersFn: func(ctx context.Context, localUserID int64) (*douyinsvc.SyncResult, error) {
if localUserID != 1 {
t.Fatalf("unexpected localUserID: %d", localUserID)
}
return &douyinsvc.SyncResult{
TotalFetched: 4,
NewOrders: 2,
MatchedUsers: 3,
ElapsedMS: 123,
}, nil
},
}
dummyAuth := func(ctx core.Context) (proposal.SessionUserInfo, core.BusinessError) {
return proposal.SessionUserInfo{Id: 1}, nil
}
app := mux.Group("/api/app", core.WrapAuthHandler(dummyAuth))
app.POST("/users/douyin/orders/sync", h.SyncMyDouyinOrders())
rr := httptest.NewRecorder()
req, _ := http.NewRequest("POST", "/api/app/users/douyin/orders/sync", bytes.NewBufferString(""))
mux.ServeHTTP(rr, req)
if rr.Code != http.StatusOK {
t.Fatalf("code=%d body=%s", rr.Code, rr.Body.String())
}
var rsp syncMyDouyinOrdersResponse
if err := json.Unmarshal(rr.Body.Bytes(), &rsp); err != nil {
t.Fatal(err)
}
if rsp.DouyinUserID != "dy_user_001" {
t.Fatalf("unexpected douyin_user_id: %s", rsp.DouyinUserID)
}
if rsp.TotalFetched != 4 || rsp.NewOrders != 2 || rsp.MatchedUsers != 3 || rsp.ElapsedMS != 123 {
t.Fatalf("unexpected response: %+v", rsp)
}
}
func TestSyncMyDouyinOrders_AppError(t *testing.T) {
repo, err := mysql.NewSQLiteRepoForTest()
if err != nil {
t.Fatal(err)
}
if err := repo.GetDbW().Exec(`CREATE TABLE users (
id INTEGER PRIMARY KEY,
nickname TEXT,
douyin_user_id TEXT,
deleted_at DATETIME
)`).Error; err != nil {
t.Fatal(err)
}
if err := repo.GetDbW().Exec(`INSERT INTO users (id, nickname, douyin_user_id) VALUES (1, 'tester', '')`).Error; err != nil {
t.Fatal(err)
}
lg, err := logger.NewCustomLogger(logger.WithOutputInConsole())
if err != nil {
t.Fatal(err)
}
mux, err := core.New(lg)
if err != nil {
t.Fatal(err)
}
h := New(lg, repo, nil)
h.douyin = &fakeDouyinService{
syncUserOrdersFn: func(ctx context.Context, localUserID int64) (*douyinsvc.SyncResult, error) {
return nil, errors.New("当前用户未绑定抖音号")
},
}
dummyAuth := func(ctx core.Context) (proposal.SessionUserInfo, core.BusinessError) {
return proposal.SessionUserInfo{Id: 1}, nil
}
app := mux.Group("/api/app", core.WrapAuthHandler(dummyAuth))
app.POST("/users/douyin/orders/sync", h.SyncMyDouyinOrders())
rr := httptest.NewRecorder()
req, _ := http.NewRequest("POST", "/api/app/users/douyin/orders/sync", bytes.NewBufferString(""))
mux.ServeHTTP(rr, req)
if rr.Code != http.StatusBadRequest {
t.Fatalf("code=%d body=%s", rr.Code, rr.Body.String())
}
if !bytes.Contains(rr.Body.Bytes(), []byte("当前用户未绑定抖音号")) {
t.Fatalf("unexpected body=%s", rr.Body.String())
}
}