feat: 更新服务方法,显式接受用户ID参数,简化上下文调用
This commit is contained in:
@@ -126,7 +126,7 @@ func (s *ContentTestSuite) Test_Get() {
|
|||||||
ctx = context.WithValue(ctx, consts.CtxKeyUser, author.ID)
|
ctx = context.WithValue(ctx, consts.CtxKeyUser, author.ID)
|
||||||
|
|
||||||
Convey("should get detail with assets", func() {
|
Convey("should get detail with assets", func() {
|
||||||
detail, err := Content.Get(ctx, cast.ToString(content.ID))
|
detail, err := Content.Get(ctx, author.ID, cast.ToString(content.ID))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(detail.Title, ShouldEqual, "Detail Content")
|
So(detail.Title, ShouldEqual, "Detail Content")
|
||||||
So(detail.AuthorName, ShouldEqual, "Author1")
|
So(detail.AuthorName, ShouldEqual, "Author1")
|
||||||
@@ -154,7 +154,7 @@ func (s *ContentTestSuite) Test_CreateComment() {
|
|||||||
form := &content_dto.CommentCreateForm{
|
form := &content_dto.CommentCreateForm{
|
||||||
Content: "Nice!",
|
Content: "Nice!",
|
||||||
}
|
}
|
||||||
err := Content.CreateComment(ctx, cast.ToString(c.ID), form)
|
err := Content.CreateComment(ctx, u.ID, cast.ToString(c.ID), form)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
count, _ := models.CommentQuery.WithContext(ctx).Where(models.CommentQuery.ContentID.Eq(c.ID)).Count()
|
count, _ := models.CommentQuery.WithContext(ctx).Where(models.CommentQuery.ContentID.Eq(c.ID)).Count()
|
||||||
@@ -193,7 +193,7 @@ func (s *ContentTestSuite) Test_Library() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Convey("should get library content with details", func() {
|
Convey("should get library content with details", func() {
|
||||||
list, err := Content.GetLibrary(ctx)
|
list, err := Content.GetLibrary(ctx, u.ID)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(len(list), ShouldEqual, 1)
|
So(len(list), ShouldEqual, 1)
|
||||||
So(list[0].Title, ShouldEqual, "Paid Content")
|
So(list[0].Title, ShouldEqual, "Paid Content")
|
||||||
@@ -219,7 +219,7 @@ func (s *ContentTestSuite) Test_Interact() {
|
|||||||
|
|
||||||
Convey("Like flow", func() {
|
Convey("Like flow", func() {
|
||||||
// Add Like
|
// Add Like
|
||||||
err := Content.AddLike(ctx, cast.ToString(c.ID))
|
err := Content.AddLike(ctx, u.ID, cast.ToString(c.ID))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
// Verify count
|
// Verify count
|
||||||
@@ -227,13 +227,13 @@ func (s *ContentTestSuite) Test_Interact() {
|
|||||||
So(cReload.Likes, ShouldEqual, 1)
|
So(cReload.Likes, ShouldEqual, 1)
|
||||||
|
|
||||||
// Get Likes
|
// Get Likes
|
||||||
likes, err := Content.GetLikes(ctx)
|
likes, err := Content.GetLikes(ctx, u.ID)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(len(likes), ShouldEqual, 1)
|
So(len(likes), ShouldEqual, 1)
|
||||||
So(likes[0].ID, ShouldEqual, cast.ToString(c.ID))
|
So(likes[0].ID, ShouldEqual, cast.ToString(c.ID))
|
||||||
|
|
||||||
// Remove Like
|
// Remove Like
|
||||||
err = Content.RemoveLike(ctx, cast.ToString(c.ID))
|
err = Content.RemoveLike(ctx, u.ID, cast.ToString(c.ID))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
// Verify count
|
// Verify count
|
||||||
@@ -243,21 +243,21 @@ func (s *ContentTestSuite) Test_Interact() {
|
|||||||
|
|
||||||
Convey("Favorite flow", func() {
|
Convey("Favorite flow", func() {
|
||||||
// Add Favorite
|
// Add Favorite
|
||||||
err := Content.AddFavorite(ctx, cast.ToString(c.ID))
|
err := Content.AddFavorite(ctx, u.ID, cast.ToString(c.ID))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
// Get Favorites
|
// Get Favorites
|
||||||
favs, err := Content.GetFavorites(ctx)
|
favs, err := Content.GetFavorites(ctx, u.ID)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(len(favs), ShouldEqual, 1)
|
So(len(favs), ShouldEqual, 1)
|
||||||
So(favs[0].ID, ShouldEqual, cast.ToString(c.ID))
|
So(favs[0].ID, ShouldEqual, cast.ToString(c.ID))
|
||||||
|
|
||||||
// Remove Favorite
|
// Remove Favorite
|
||||||
err = Content.RemoveFavorite(ctx, cast.ToString(c.ID))
|
err = Content.RemoveFavorite(ctx, u.ID, cast.ToString(c.ID))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
// Get Favorites
|
// Get Favorites
|
||||||
favs, err = Content.GetFavorites(ctx)
|
favs, err = Content.GetFavorites(ctx, u.ID)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(len(favs), ShouldEqual, 0)
|
So(len(favs), ShouldEqual, 0)
|
||||||
})
|
})
|
||||||
@@ -325,7 +325,7 @@ func (s *ContentTestSuite) Test_PreviewLogic() {
|
|||||||
models.UserQuery.WithContext(ctx).Create(guest)
|
models.UserQuery.WithContext(ctx).Create(guest)
|
||||||
guestCtx := context.WithValue(ctx, consts.CtxKeyUser, guest.ID)
|
guestCtx := context.WithValue(ctx, consts.CtxKeyUser, guest.ID)
|
||||||
|
|
||||||
detail, err := Content.Get(guestCtx, cast.ToString(c.ID))
|
detail, err := Content.Get(guestCtx, 0, cast.ToString(c.ID))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(len(detail.MediaUrls), ShouldEqual, 1)
|
So(len(detail.MediaUrls), ShouldEqual, 1)
|
||||||
So(detail.MediaUrls[0].URL, ShouldEndWith, "preview.mp4")
|
So(detail.MediaUrls[0].URL, ShouldEndWith, "preview.mp4")
|
||||||
@@ -334,7 +334,7 @@ func (s *ContentTestSuite) Test_PreviewLogic() {
|
|||||||
|
|
||||||
Convey("owner should see all", func() {
|
Convey("owner should see all", func() {
|
||||||
ownerCtx := context.WithValue(ctx, consts.CtxKeyUser, author.ID)
|
ownerCtx := context.WithValue(ctx, consts.CtxKeyUser, author.ID)
|
||||||
detail, err := Content.Get(ownerCtx, cast.ToString(c.ID))
|
detail, err := Content.Get(ownerCtx, author.ID, cast.ToString(c.ID))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(len(detail.MediaUrls), ShouldEqual, 2)
|
So(len(detail.MediaUrls), ShouldEqual, 2)
|
||||||
So(detail.IsPurchased, ShouldBeTrue)
|
So(detail.IsPurchased, ShouldBeTrue)
|
||||||
@@ -349,7 +349,7 @@ func (s *ContentTestSuite) Test_PreviewLogic() {
|
|||||||
UserID: buyer.ID, ContentID: c.ID, Status: consts.ContentAccessStatusActive,
|
UserID: buyer.ID, ContentID: c.ID, Status: consts.ContentAccessStatusActive,
|
||||||
})
|
})
|
||||||
|
|
||||||
detail, err := Content.Get(buyerCtx, cast.ToString(c.ID))
|
detail, err := Content.Get(buyerCtx, buyer.ID, cast.ToString(c.ID))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(len(detail.MediaUrls), ShouldEqual, 2)
|
So(len(detail.MediaUrls), ShouldEqual, 2)
|
||||||
So(detail.IsPurchased, ShouldBeTrue)
|
So(detail.IsPurchased, ShouldBeTrue)
|
||||||
@@ -369,7 +369,7 @@ func (s *ContentTestSuite) Test_ViewCounting() {
|
|||||||
models.ContentQuery.WithContext(ctx).Create(c)
|
models.ContentQuery.WithContext(ctx).Create(c)
|
||||||
|
|
||||||
Convey("should increment views", func() {
|
Convey("should increment views", func() {
|
||||||
_, err := Content.Get(ctx, cast.ToString(c.ID))
|
_, err := Content.Get(ctx, 0, cast.ToString(c.ID))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
cReload, _ := models.ContentQuery.WithContext(ctx).Where(models.ContentQuery.ID.Eq(c.ID)).First()
|
cReload, _ := models.ContentQuery.WithContext(ctx).Where(models.ContentQuery.ID.Eq(c.ID)).First()
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"quyun/v2/app/errorx"
|
"quyun/v2/app/errorx"
|
||||||
coupon_dto "quyun/v2/app/http/v1/dto"
|
coupon_dto "quyun/v2/app/http/v1/dto"
|
||||||
"quyun/v2/database/models"
|
"quyun/v2/database/models"
|
||||||
"quyun/v2/pkg/consts"
|
|
||||||
|
|
||||||
"github.com/spf13/cast"
|
"github.com/spf13/cast"
|
||||||
)
|
)
|
||||||
@@ -15,7 +14,11 @@ import (
|
|||||||
// @provider
|
// @provider
|
||||||
type coupon struct{}
|
type coupon struct{}
|
||||||
|
|
||||||
func (s *coupon) ListUserCoupons(ctx context.Context, userID int64, status string) ([]coupon_dto.UserCouponItem, error) {
|
func (s *coupon) ListUserCoupons(
|
||||||
|
ctx context.Context,
|
||||||
|
userID int64,
|
||||||
|
status string,
|
||||||
|
) ([]coupon_dto.UserCouponItem, error) {
|
||||||
if userID == 0 {
|
if userID == 0 {
|
||||||
return nil, errorx.ErrUnauthorized
|
return nil, errorx.ErrUnauthorized
|
||||||
}
|
}
|
||||||
@@ -111,7 +114,9 @@ func (s *coupon) Validate(ctx context.Context, userID, userCouponID, amount int6
|
|||||||
func (s *coupon) MarkUsed(ctx context.Context, tx *models.Query, userCouponID, orderID int64) error {
|
func (s *coupon) MarkUsed(ctx context.Context, tx *models.Query, userCouponID, orderID int64) error {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
// Update User Coupon
|
// Update User Coupon
|
||||||
info, err := tx.UserCoupon.WithContext(ctx).Where(tx.UserCoupon.ID.Eq(userCouponID), tx.UserCoupon.Status.Eq("unused")).Updates(&models.UserCoupon{
|
info, err := tx.UserCoupon.WithContext(ctx).
|
||||||
|
Where(tx.UserCoupon.ID.Eq(userCouponID), tx.UserCoupon.Status.Eq("unused")).
|
||||||
|
Updates(&models.UserCoupon{
|
||||||
Status: "used",
|
Status: "used",
|
||||||
OrderID: orderID,
|
OrderID: orderID,
|
||||||
UsedAt: now,
|
UsedAt: now,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -42,7 +41,16 @@ func Test_Coupon(t *testing.T) {
|
|||||||
func (s *CouponTestSuite) Test_CouponFlow() {
|
func (s *CouponTestSuite) Test_CouponFlow() {
|
||||||
Convey("Coupon Flow", s.T(), func() {
|
Convey("Coupon Flow", s.T(), func() {
|
||||||
ctx := s.T().Context()
|
ctx := s.T().Context()
|
||||||
database.Truncate(ctx, s.DB, models.TableNameCoupon, models.TableNameUserCoupon, models.TableNameOrder, models.TableNameUser, models.TableNameContent, models.TableNameContentPrice)
|
database.Truncate(
|
||||||
|
ctx,
|
||||||
|
s.DB,
|
||||||
|
models.TableNameCoupon,
|
||||||
|
models.TableNameUserCoupon,
|
||||||
|
models.TableNameOrder,
|
||||||
|
models.TableNameUser,
|
||||||
|
models.TableNameContent,
|
||||||
|
models.TableNameContentPrice,
|
||||||
|
)
|
||||||
|
|
||||||
user := &models.User{Username: "coupon_user", Phone: "13800000001"}
|
user := &models.User{Username: "coupon_user", Phone: "13800000001"}
|
||||||
models.UserQuery.WithContext(ctx).Create(user)
|
models.UserQuery.WithContext(ctx).Create(user)
|
||||||
@@ -90,8 +98,7 @@ func (s *CouponTestSuite) Test_CouponFlow() {
|
|||||||
UserCouponID: cast.ToString(uc.ID),
|
UserCouponID: cast.ToString(uc.ID),
|
||||||
}
|
}
|
||||||
// Simulate Auth context for Order service
|
// Simulate Auth context for Order service
|
||||||
authCtx := context.WithValue(ctx, consts.CtxKeyUser, user.ID)
|
res, err := Order.Create(ctx, user.ID, form)
|
||||||
res, err := Order.Create(authCtx, form)
|
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
// Verify Order
|
// Verify Order
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ func (s *CreatorTestSuite) Test_Apply() {
|
|||||||
form := &creator_dto.ApplyForm{
|
form := &creator_dto.ApplyForm{
|
||||||
Name: "My Channel",
|
Name: "My Channel",
|
||||||
}
|
}
|
||||||
err := Creator.Apply(ctx, form)
|
err := Creator.Apply(ctx, u.ID, form)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
t, _ := models.TenantQuery.WithContext(ctx).Where(models.TenantQuery.UserID.Eq(u.ID)).First()
|
t, _ := models.TenantQuery.WithContext(ctx).Where(models.TenantQuery.UserID.Eq(u.ID)).First()
|
||||||
@@ -73,7 +73,15 @@ func (s *CreatorTestSuite) Test_Apply() {
|
|||||||
func (s *CreatorTestSuite) Test_CreateContent() {
|
func (s *CreatorTestSuite) Test_CreateContent() {
|
||||||
Convey("CreateContent", s.T(), func() {
|
Convey("CreateContent", s.T(), func() {
|
||||||
ctx := s.T().Context()
|
ctx := s.T().Context()
|
||||||
database.Truncate(ctx, s.DB, models.TableNameTenant, models.TableNameContent, models.TableNameContentAsset, models.TableNameContentPrice, models.TableNameUser)
|
database.Truncate(
|
||||||
|
ctx,
|
||||||
|
s.DB,
|
||||||
|
models.TableNameTenant,
|
||||||
|
models.TableNameContent,
|
||||||
|
models.TableNameContentAsset,
|
||||||
|
models.TableNameContentPrice,
|
||||||
|
models.TableNameUser,
|
||||||
|
)
|
||||||
|
|
||||||
u := &models.User{Username: "creator2", Phone: "13700000002"}
|
u := &models.User{Username: "creator2", Phone: "13700000002"}
|
||||||
models.UserQuery.WithContext(ctx).Create(u)
|
models.UserQuery.WithContext(ctx).Create(u)
|
||||||
@@ -90,7 +98,7 @@ func (s *CreatorTestSuite) Test_CreateContent() {
|
|||||||
Price: 9.99,
|
Price: 9.99,
|
||||||
// MediaIDs: ... need media asset
|
// MediaIDs: ... need media asset
|
||||||
}
|
}
|
||||||
err := Creator.CreateContent(ctx, form)
|
err := Creator.CreateContent(ctx, u.ID, form)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
c, _ := models.ContentQuery.WithContext(ctx).Where(models.ContentQuery.Title.Eq("New Song")).First()
|
c, _ := models.ContentQuery.WithContext(ctx).Where(models.ContentQuery.Title.Eq("New Song")).First()
|
||||||
@@ -109,7 +117,15 @@ func (s *CreatorTestSuite) Test_CreateContent() {
|
|||||||
func (s *CreatorTestSuite) Test_UpdateContent() {
|
func (s *CreatorTestSuite) Test_UpdateContent() {
|
||||||
Convey("UpdateContent", s.T(), func() {
|
Convey("UpdateContent", s.T(), func() {
|
||||||
ctx := s.T().Context()
|
ctx := s.T().Context()
|
||||||
database.Truncate(ctx, s.DB, models.TableNameTenant, models.TableNameContent, models.TableNameContentAsset, models.TableNameContentPrice, models.TableNameUser)
|
database.Truncate(
|
||||||
|
ctx,
|
||||||
|
s.DB,
|
||||||
|
models.TableNameTenant,
|
||||||
|
models.TableNameContent,
|
||||||
|
models.TableNameContentAsset,
|
||||||
|
models.TableNameContentPrice,
|
||||||
|
models.TableNameUser,
|
||||||
|
)
|
||||||
|
|
||||||
u := &models.User{Username: "creator3", Phone: "13700000003"}
|
u := &models.User{Username: "creator3", Phone: "13700000003"}
|
||||||
models.UserQuery.WithContext(ctx).Create(u)
|
models.UserQuery.WithContext(ctx).Create(u)
|
||||||
@@ -120,7 +136,8 @@ func (s *CreatorTestSuite) Test_UpdateContent() {
|
|||||||
|
|
||||||
c := &models.Content{TenantID: t.ID, UserID: u.ID, Title: "Old Title", Genre: "audio"}
|
c := &models.Content{TenantID: t.ID, UserID: u.ID, Title: "Old Title", Genre: "audio"}
|
||||||
models.ContentQuery.WithContext(ctx).Create(c)
|
models.ContentQuery.WithContext(ctx).Create(c)
|
||||||
models.ContentPriceQuery.WithContext(ctx).Create(&models.ContentPrice{TenantID: t.ID, UserID: u.ID, ContentID: c.ID, PriceAmount: 100})
|
models.ContentPriceQuery.WithContext(ctx).
|
||||||
|
Create(&models.ContentPrice{TenantID: t.ID, UserID: u.ID, ContentID: c.ID, PriceAmount: 100})
|
||||||
|
|
||||||
Convey("should update content", func() {
|
Convey("should update content", func() {
|
||||||
form := &creator_dto.ContentUpdateForm{
|
form := &creator_dto.ContentUpdateForm{
|
||||||
@@ -128,7 +145,7 @@ func (s *CreatorTestSuite) Test_UpdateContent() {
|
|||||||
Genre: "video",
|
Genre: "video",
|
||||||
Price: 20.00,
|
Price: 20.00,
|
||||||
}
|
}
|
||||||
err := Creator.UpdateContent(ctx, cast.ToString(c.ID), form)
|
err := Creator.UpdateContent(ctx, u.ID, cast.ToString(c.ID), form)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
@@ -145,7 +162,15 @@ func (s *CreatorTestSuite) Test_UpdateContent() {
|
|||||||
func (s *CreatorTestSuite) Test_Dashboard() {
|
func (s *CreatorTestSuite) Test_Dashboard() {
|
||||||
Convey("Dashboard", s.T(), func() {
|
Convey("Dashboard", s.T(), func() {
|
||||||
ctx := s.T().Context()
|
ctx := s.T().Context()
|
||||||
database.Truncate(ctx, s.DB, models.TableNameTenant, models.TableNameTenantUser, models.TableNameTenantLedger, models.TableNameUser, models.TableNameOrder)
|
database.Truncate(
|
||||||
|
ctx,
|
||||||
|
s.DB,
|
||||||
|
models.TableNameTenant,
|
||||||
|
models.TableNameTenantUser,
|
||||||
|
models.TableNameTenantLedger,
|
||||||
|
models.TableNameUser,
|
||||||
|
models.TableNameOrder,
|
||||||
|
)
|
||||||
|
|
||||||
u := &models.User{Username: "creator4", Phone: "13700000004"}
|
u := &models.User{Username: "creator4", Phone: "13700000004"}
|
||||||
models.UserQuery.WithContext(ctx).Create(u)
|
models.UserQuery.WithContext(ctx).Create(u)
|
||||||
@@ -165,11 +190,15 @@ func (s *CreatorTestSuite) Test_Dashboard() {
|
|||||||
models.TenantLedgerQuery.WithContext(ctx).Create(
|
models.TenantLedgerQuery.WithContext(ctx).Create(
|
||||||
&models.TenantLedger{TenantID: t.ID, Type: consts.TenantLedgerTypeDebitPurchase, Amount: 1000}, // 10.00
|
&models.TenantLedger{TenantID: t.ID, Type: consts.TenantLedgerTypeDebitPurchase, Amount: 1000}, // 10.00
|
||||||
&models.TenantLedger{TenantID: t.ID, Type: consts.TenantLedgerTypeDebitPurchase, Amount: 2000}, // 20.00
|
&models.TenantLedger{TenantID: t.ID, Type: consts.TenantLedgerTypeDebitPurchase, Amount: 2000}, // 20.00
|
||||||
&models.TenantLedger{TenantID: t.ID, Type: consts.TenantLedgerTypeCreditRefund, Amount: 500}, // -5.00 (Refund, currently Dashboard sums DebitPurchase only, ideally should subtract refunds, but let's stick to implementation)
|
&models.TenantLedger{
|
||||||
|
TenantID: t.ID,
|
||||||
|
Type: consts.TenantLedgerTypeCreditRefund,
|
||||||
|
Amount: 500,
|
||||||
|
}, // -5.00 (Refund, currently Dashboard sums DebitPurchase only, ideally should subtract refunds, but let's stick to implementation)
|
||||||
)
|
)
|
||||||
|
|
||||||
Convey("should get stats", func() {
|
Convey("should get stats", func() {
|
||||||
stats, err := Creator.Dashboard(ctx)
|
stats, err := Creator.Dashboard(ctx, u.ID)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(stats.TotalFollowers.Value, ShouldEqual, 2)
|
So(stats.TotalFollowers.Value, ShouldEqual, 2)
|
||||||
// Implementation sums 'debit_purchase' only based on my code
|
// Implementation sums 'debit_purchase' only based on my code
|
||||||
@@ -198,21 +227,21 @@ func (s *CreatorTestSuite) Test_PayoutAccount() {
|
|||||||
Account: "user@example.com",
|
Account: "user@example.com",
|
||||||
Realname: "John Doe",
|
Realname: "John Doe",
|
||||||
}
|
}
|
||||||
err := Creator.AddPayoutAccount(ctx, form)
|
err := Creator.AddPayoutAccount(ctx, u.ID, form)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
// List
|
// List
|
||||||
list, err := Creator.ListPayoutAccounts(ctx)
|
list, err := Creator.ListPayoutAccounts(ctx, u.ID)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(len(list), ShouldEqual, 1)
|
So(len(list), ShouldEqual, 1)
|
||||||
So(list[0].Account, ShouldEqual, "user@example.com")
|
So(list[0].Account, ShouldEqual, "user@example.com")
|
||||||
|
|
||||||
// Remove
|
// Remove
|
||||||
err = Creator.RemovePayoutAccount(ctx, list[0].ID)
|
err = Creator.RemovePayoutAccount(ctx, u.ID, list[0].ID)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
// Verify Empty
|
// Verify Empty
|
||||||
list, err = Creator.ListPayoutAccounts(ctx)
|
list, err = Creator.ListPayoutAccounts(ctx, u.ID)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(len(list), ShouldEqual, 0)
|
So(len(list), ShouldEqual, 0)
|
||||||
})
|
})
|
||||||
@@ -222,7 +251,15 @@ func (s *CreatorTestSuite) Test_PayoutAccount() {
|
|||||||
func (s *CreatorTestSuite) Test_Withdraw() {
|
func (s *CreatorTestSuite) Test_Withdraw() {
|
||||||
Convey("Withdraw", s.T(), func() {
|
Convey("Withdraw", s.T(), func() {
|
||||||
ctx := s.T().Context()
|
ctx := s.T().Context()
|
||||||
database.Truncate(ctx, s.DB, models.TableNameTenant, models.TableNamePayoutAccount, models.TableNameUser, models.TableNameOrder, models.TableNameTenantLedger)
|
database.Truncate(
|
||||||
|
ctx,
|
||||||
|
s.DB,
|
||||||
|
models.TableNameTenant,
|
||||||
|
models.TableNamePayoutAccount,
|
||||||
|
models.TableNameUser,
|
||||||
|
models.TableNameOrder,
|
||||||
|
models.TableNameTenantLedger,
|
||||||
|
)
|
||||||
|
|
||||||
u := &models.User{Username: "creator6", Phone: "13700000006", Balance: 5000} // 50.00
|
u := &models.User{Username: "creator6", Phone: "13700000006", Balance: 5000} // 50.00
|
||||||
models.UserQuery.WithContext(ctx).Create(u)
|
models.UserQuery.WithContext(ctx).Create(u)
|
||||||
@@ -231,7 +268,14 @@ func (s *CreatorTestSuite) Test_Withdraw() {
|
|||||||
t := &models.Tenant{UserID: u.ID, Name: "Channel 6", Code: "127", Status: consts.TenantStatusVerified}
|
t := &models.Tenant{UserID: u.ID, Name: "Channel 6", Code: "127", Status: consts.TenantStatusVerified}
|
||||||
models.TenantQuery.WithContext(ctx).Create(t)
|
models.TenantQuery.WithContext(ctx).Create(t)
|
||||||
|
|
||||||
pa := &models.PayoutAccount{TenantID: t.ID, UserID: u.ID, Type: "bank", Name: "Bank", Account: "123", Realname: "Creator"}
|
pa := &models.PayoutAccount{
|
||||||
|
TenantID: t.ID,
|
||||||
|
UserID: u.ID,
|
||||||
|
Type: "bank",
|
||||||
|
Name: "Bank",
|
||||||
|
Account: "123",
|
||||||
|
Realname: "Creator",
|
||||||
|
}
|
||||||
models.PayoutAccountQuery.WithContext(ctx).Create(pa)
|
models.PayoutAccountQuery.WithContext(ctx).Create(pa)
|
||||||
|
|
||||||
Convey("should withdraw successfully", func() {
|
Convey("should withdraw successfully", func() {
|
||||||
@@ -239,7 +283,7 @@ func (s *CreatorTestSuite) Test_Withdraw() {
|
|||||||
Amount: 20.00,
|
Amount: 20.00,
|
||||||
AccountID: cast.ToString(pa.ID),
|
AccountID: cast.ToString(pa.ID),
|
||||||
}
|
}
|
||||||
err := Creator.Withdraw(ctx, form)
|
err := Creator.Withdraw(ctx, u.ID, form)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
// Verify Balance Deducted
|
// Verify Balance Deducted
|
||||||
@@ -247,7 +291,9 @@ func (s *CreatorTestSuite) Test_Withdraw() {
|
|||||||
So(uReload.Balance, ShouldEqual, 3000)
|
So(uReload.Balance, ShouldEqual, 3000)
|
||||||
|
|
||||||
// Verify Order Created
|
// Verify Order Created
|
||||||
o, _ := models.OrderQuery.WithContext(ctx).Where(models.OrderQuery.TenantID.Eq(t.ID), models.OrderQuery.Type.Eq(consts.OrderTypeWithdrawal)).First()
|
o, _ := models.OrderQuery.WithContext(ctx).
|
||||||
|
Where(models.OrderQuery.TenantID.Eq(t.ID), models.OrderQuery.Type.Eq(consts.OrderTypeWithdrawal)).
|
||||||
|
First()
|
||||||
So(o, ShouldNotBeNil)
|
So(o, ShouldNotBeNil)
|
||||||
So(o.AmountPaid, ShouldEqual, 2000)
|
So(o.AmountPaid, ShouldEqual, 2000)
|
||||||
|
|
||||||
@@ -262,7 +308,7 @@ func (s *CreatorTestSuite) Test_Withdraw() {
|
|||||||
Amount: 100.00,
|
Amount: 100.00,
|
||||||
AccountID: cast.ToString(pa.ID),
|
AccountID: cast.ToString(pa.ID),
|
||||||
}
|
}
|
||||||
err := Creator.Withdraw(ctx, form)
|
err := Creator.Withdraw(ctx, u.ID, form)
|
||||||
So(err, ShouldNotBeNil)
|
So(err, ShouldNotBeNil)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -279,7 +325,7 @@ func (s *CreatorTestSuite) Test_Refund() {
|
|||||||
// Creator
|
// Creator
|
||||||
creator := &models.User{Username: "creator7", Phone: "13700000007", Balance: 5000} // Has funds
|
creator := &models.User{Username: "creator7", Phone: "13700000007", Balance: 5000} // Has funds
|
||||||
models.UserQuery.WithContext(ctx).Create(creator)
|
models.UserQuery.WithContext(ctx).Create(creator)
|
||||||
creatorCtx := context.WithValue(ctx, consts.CtxKeyUser, creator.ID)
|
// creatorCtx := context.WithValue(ctx, consts.CtxKeyUser, creator.ID)
|
||||||
|
|
||||||
// Tenant
|
// Tenant
|
||||||
t := &models.Tenant{UserID: creator.ID, Name: "Channel 7", Code: "128", Status: consts.TenantStatusVerified}
|
t := &models.Tenant{UserID: creator.ID, Name: "Channel 7", Code: "128", Status: consts.TenantStatusVerified}
|
||||||
@@ -298,11 +344,12 @@ func (s *CreatorTestSuite) Test_Refund() {
|
|||||||
}
|
}
|
||||||
models.OrderQuery.WithContext(ctx).Create(o)
|
models.OrderQuery.WithContext(ctx).Create(o)
|
||||||
models.OrderItemQuery.WithContext(ctx).Create(&models.OrderItem{OrderID: o.ID, ContentID: 100}) // Fake content
|
models.OrderItemQuery.WithContext(ctx).Create(&models.OrderItem{OrderID: o.ID, ContentID: 100}) // Fake content
|
||||||
models.ContentAccessQuery.WithContext(ctx).Create(&models.ContentAccess{UserID: buyer.ID, ContentID: 100, Status: consts.ContentAccessStatusActive})
|
models.ContentAccessQuery.WithContext(ctx).
|
||||||
|
Create(&models.ContentAccess{UserID: buyer.ID, ContentID: 100, Status: consts.ContentAccessStatusActive})
|
||||||
|
|
||||||
Convey("should accept refund", func() {
|
Convey("should accept refund", func() {
|
||||||
form := &creator_dto.RefundForm{Action: "accept", Reason: "Defective"}
|
form := &creator_dto.RefundForm{Action: "accept", Reason: "Defective"}
|
||||||
err := Creator.ProcessRefund(creatorCtx, cast.ToString(o.ID), form)
|
err := Creator.ProcessRefund(ctx, creator.ID, cast.ToString(o.ID), form)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
// Verify Order
|
// Verify Order
|
||||||
@@ -317,7 +364,9 @@ func (s *CreatorTestSuite) Test_Refund() {
|
|||||||
So(bReload.Balance, ShouldEqual, 1000) // 0 + 1000
|
So(bReload.Balance, ShouldEqual, 1000) // 0 + 1000
|
||||||
|
|
||||||
// Verify Access
|
// Verify Access
|
||||||
acc, _ := models.ContentAccessQuery.WithContext(ctx).Where(models.ContentAccessQuery.UserID.Eq(buyer.ID)).First()
|
acc, _ := models.ContentAccessQuery.WithContext(ctx).
|
||||||
|
Where(models.ContentAccessQuery.UserID.Eq(buyer.ID)).
|
||||||
|
First()
|
||||||
So(acc.Status, ShouldEqual, consts.ContentAccessStatusRevoked)
|
So(acc.Status, ShouldEqual, consts.ContentAccessStatusRevoked)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import (
|
|||||||
"quyun/v2/app/jobs/args"
|
"quyun/v2/app/jobs/args"
|
||||||
"quyun/v2/app/requests"
|
"quyun/v2/app/requests"
|
||||||
"quyun/v2/database/models"
|
"quyun/v2/database/models"
|
||||||
"quyun/v2/pkg/consts"
|
|
||||||
"quyun/v2/providers/job"
|
"quyun/v2/providers/job"
|
||||||
|
|
||||||
"github.com/spf13/cast"
|
"github.com/spf13/cast"
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func (s *NotificationTestSuite) Test_CRUD() {
|
|||||||
err := Notification.Send(ctx, uID, "system", "Welcome", "Hello World")
|
err := Notification.Send(ctx, uID, "system", "Welcome", "Hello World")
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
list, err := Notification.List(ctx, 1, "")
|
list, err := Notification.List(ctx, uID, 1, "")
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(list.Total, ShouldEqual, 1)
|
So(list.Total, ShouldEqual, 1)
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ func (s *NotificationTestSuite) Test_CRUD() {
|
|||||||
// Mark Read
|
// Mark Read
|
||||||
// Need ID
|
// Need ID
|
||||||
n, _ := models.NotificationQuery.WithContext(ctx).Where(models.NotificationQuery.UserID.Eq(uID)).First()
|
n, _ := models.NotificationQuery.WithContext(ctx).Where(models.NotificationQuery.UserID.Eq(uID)).First()
|
||||||
err = Notification.MarkRead(ctx, cast.ToString(n.ID))
|
err = Notification.MarkRead(ctx, uID, cast.ToString(n.ID))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
nReload, _ := models.NotificationQuery.WithContext(ctx).Where(models.NotificationQuery.ID.Eq(n.ID)).First()
|
nReload, _ := models.NotificationQuery.WithContext(ctx).Where(models.NotificationQuery.ID.Eq(n.ID)).First()
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -52,25 +51,40 @@ func (s *OrderTestSuite) Test_PurchaseFlow() {
|
|||||||
creator := &models.User{Username: "creator", Phone: "13800000001"}
|
creator := &models.User{Username: "creator", Phone: "13800000001"}
|
||||||
models.UserQuery.WithContext(ctx).Create(creator)
|
models.UserQuery.WithContext(ctx).Create(creator)
|
||||||
// Tenant
|
// Tenant
|
||||||
tenant := &models.Tenant{UserID: creator.ID, Name: "Music Shop", Code: "shop1", Status: consts.TenantStatusVerified}
|
tenant := &models.Tenant{
|
||||||
|
UserID: creator.ID,
|
||||||
|
Name: "Music Shop",
|
||||||
|
Code: "shop1",
|
||||||
|
Status: consts.TenantStatusVerified,
|
||||||
|
}
|
||||||
models.TenantQuery.WithContext(ctx).Create(tenant)
|
models.TenantQuery.WithContext(ctx).Create(tenant)
|
||||||
// Content
|
// Content
|
||||||
content := &models.Content{TenantID: tenant.ID, UserID: creator.ID, Title: "Song A", Status: consts.ContentStatusPublished}
|
content := &models.Content{
|
||||||
|
TenantID: tenant.ID,
|
||||||
|
UserID: creator.ID,
|
||||||
|
Title: "Song A",
|
||||||
|
Status: consts.ContentStatusPublished,
|
||||||
|
}
|
||||||
models.ContentQuery.WithContext(ctx).Create(content)
|
models.ContentQuery.WithContext(ctx).Create(content)
|
||||||
// Price (10.00 CNY = 1000 cents)
|
// Price (10.00 CNY = 1000 cents)
|
||||||
price := &models.ContentPrice{TenantID: tenant.ID, ContentID: content.ID, PriceAmount: 1000, Currency: consts.CurrencyCNY}
|
price := &models.ContentPrice{
|
||||||
|
TenantID: tenant.ID,
|
||||||
|
ContentID: content.ID,
|
||||||
|
PriceAmount: 1000,
|
||||||
|
Currency: consts.CurrencyCNY,
|
||||||
|
}
|
||||||
models.ContentPriceQuery.WithContext(ctx).Create(price)
|
models.ContentPriceQuery.WithContext(ctx).Create(price)
|
||||||
|
|
||||||
// Buyer
|
// Buyer
|
||||||
buyer := &models.User{Username: "buyer", Phone: "13900000001", Balance: 2000} // Has 20.00
|
buyer := &models.User{Username: "buyer", Phone: "13900000001", Balance: 2000} // Has 20.00
|
||||||
models.UserQuery.WithContext(ctx).Create(buyer)
|
models.UserQuery.WithContext(ctx).Create(buyer)
|
||||||
|
|
||||||
buyerCtx := context.WithValue(ctx, consts.CtxKeyUser, buyer.ID)
|
// buyerCtx := context.WithValue(ctx, consts.CtxKeyUser, buyer.ID)
|
||||||
|
|
||||||
Convey("should create and pay order successfully", func() {
|
Convey("should create and pay order successfully", func() {
|
||||||
// Step 1: Create Order
|
// Step 1: Create Order
|
||||||
form := &order_dto.OrderCreateForm{ContentID: cast.ToString(content.ID)}
|
form := &order_dto.OrderCreateForm{ContentID: cast.ToString(content.ID)}
|
||||||
createRes, err := Order.Create(buyerCtx, form)
|
createRes, err := Order.Create(ctx, buyer.ID, form)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(createRes.OrderID, ShouldNotBeEmpty)
|
So(createRes.OrderID, ShouldNotBeEmpty)
|
||||||
|
|
||||||
@@ -82,7 +96,7 @@ func (s *OrderTestSuite) Test_PurchaseFlow() {
|
|||||||
|
|
||||||
// Step 2: Pay Order
|
// Step 2: Pay Order
|
||||||
payForm := &order_dto.OrderPayForm{Method: "balance"}
|
payForm := &order_dto.OrderPayForm{Method: "balance"}
|
||||||
_, err = Order.Pay(buyerCtx, createRes.OrderID, payForm)
|
_, err = Order.Pay(ctx, buyer.ID, createRes.OrderID, payForm)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
// Verify Order Paid
|
// Verify Order Paid
|
||||||
@@ -95,7 +109,9 @@ func (s *OrderTestSuite) Test_PurchaseFlow() {
|
|||||||
So(b.Balance, ShouldEqual, 1000) // 2000 - 1000
|
So(b.Balance, ShouldEqual, 1000) // 2000 - 1000
|
||||||
|
|
||||||
// Verify Access Granted
|
// Verify Access Granted
|
||||||
access, _ := models.ContentAccessQuery.WithContext(ctx).Where(models.ContentAccessQuery.UserID.Eq(buyer.ID), models.ContentAccessQuery.ContentID.Eq(content.ID)).First()
|
access, _ := models.ContentAccessQuery.WithContext(ctx).
|
||||||
|
Where(models.ContentAccessQuery.UserID.Eq(buyer.ID), models.ContentAccessQuery.ContentID.Eq(content.ID)).
|
||||||
|
First()
|
||||||
So(access, ShouldNotBeNil)
|
So(access, ShouldNotBeNil)
|
||||||
So(access.Status, ShouldEqual, consts.ContentAccessStatusActive)
|
So(access.Status, ShouldEqual, consts.ContentAccessStatusActive)
|
||||||
|
|
||||||
@@ -110,14 +126,16 @@ func (s *OrderTestSuite) Test_PurchaseFlow() {
|
|||||||
|
|
||||||
Convey("should fail pay if insufficient balance", func() {
|
Convey("should fail pay if insufficient balance", func() {
|
||||||
// Set balance to 5.00
|
// Set balance to 5.00
|
||||||
models.UserQuery.WithContext(ctx).Where(models.UserQuery.ID.Eq(buyer.ID)).Update(models.UserQuery.Balance, 500)
|
models.UserQuery.WithContext(ctx).
|
||||||
|
Where(models.UserQuery.ID.Eq(buyer.ID)).
|
||||||
|
Update(models.UserQuery.Balance, 500)
|
||||||
|
|
||||||
form := &order_dto.OrderCreateForm{ContentID: cast.ToString(content.ID)}
|
form := &order_dto.OrderCreateForm{ContentID: cast.ToString(content.ID)}
|
||||||
createRes, err := Order.Create(buyerCtx, form)
|
createRes, err := Order.Create(ctx, buyer.ID, form)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
payForm := &order_dto.OrderPayForm{Method: "balance"}
|
payForm := &order_dto.OrderPayForm{Method: "balance"}
|
||||||
_, err = Order.Pay(buyerCtx, createRes.OrderID, payForm)
|
_, err = Order.Pay(ctx, buyer.ID, createRes.OrderID, payForm)
|
||||||
So(err, ShouldNotBeNil)
|
So(err, ShouldNotBeNil)
|
||||||
// Error should be QuotaExceeded or similar
|
// Error should be QuotaExceeded or similar
|
||||||
})
|
})
|
||||||
@@ -127,10 +145,19 @@ func (s *OrderTestSuite) Test_PurchaseFlow() {
|
|||||||
func (s *OrderTestSuite) Test_OrderDetails() {
|
func (s *OrderTestSuite) Test_OrderDetails() {
|
||||||
Convey("Order Details", s.T(), func() {
|
Convey("Order Details", s.T(), func() {
|
||||||
ctx := s.T().Context()
|
ctx := s.T().Context()
|
||||||
database.Truncate(ctx, s.DB,
|
database.Truncate(
|
||||||
models.TableNameOrder, models.TableNameOrderItem, models.TableNameUser,
|
ctx,
|
||||||
models.TableNameContent, models.TableNameContentPrice, models.TableNameTenant,
|
s.DB,
|
||||||
models.TableNameContentAccess, models.TableNameTenantLedger, models.TableNameMediaAsset, models.TableNameContentAsset,
|
models.TableNameOrder,
|
||||||
|
models.TableNameOrderItem,
|
||||||
|
models.TableNameUser,
|
||||||
|
models.TableNameContent,
|
||||||
|
models.TableNameContentPrice,
|
||||||
|
models.TableNameTenant,
|
||||||
|
models.TableNameContentAccess,
|
||||||
|
models.TableNameTenantLedger,
|
||||||
|
models.TableNameMediaAsset,
|
||||||
|
models.TableNameContentAsset,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
@@ -138,28 +165,48 @@ func (s *OrderTestSuite) Test_OrderDetails() {
|
|||||||
models.UserQuery.WithContext(ctx).Create(creator)
|
models.UserQuery.WithContext(ctx).Create(creator)
|
||||||
tenant := &models.Tenant{UserID: creator.ID, Name: "Best Shop", Status: consts.TenantStatusVerified}
|
tenant := &models.Tenant{UserID: creator.ID, Name: "Best Shop", Status: consts.TenantStatusVerified}
|
||||||
models.TenantQuery.WithContext(ctx).Create(tenant)
|
models.TenantQuery.WithContext(ctx).Create(tenant)
|
||||||
content := &models.Content{TenantID: tenant.ID, UserID: creator.ID, Title: "Amazing Song", Status: consts.ContentStatusPublished}
|
content := &models.Content{
|
||||||
|
TenantID: tenant.ID,
|
||||||
|
UserID: creator.ID,
|
||||||
|
Title: "Amazing Song",
|
||||||
|
Status: consts.ContentStatusPublished,
|
||||||
|
}
|
||||||
models.ContentQuery.WithContext(ctx).Create(content)
|
models.ContentQuery.WithContext(ctx).Create(content)
|
||||||
price := &models.ContentPrice{TenantID: tenant.ID, ContentID: content.ID, PriceAmount: 500, Currency: consts.CurrencyCNY}
|
price := &models.ContentPrice{
|
||||||
|
TenantID: tenant.ID,
|
||||||
|
ContentID: content.ID,
|
||||||
|
PriceAmount: 500,
|
||||||
|
Currency: consts.CurrencyCNY,
|
||||||
|
}
|
||||||
models.ContentPriceQuery.WithContext(ctx).Create(price)
|
models.ContentPriceQuery.WithContext(ctx).Create(price)
|
||||||
|
|
||||||
// Asset (Cover)
|
// Asset (Cover)
|
||||||
asset := &models.MediaAsset{TenantID: tenant.ID, UserID: creator.ID, Type: consts.MediaAssetTypeImage, ObjectKey: "cover.jpg"}
|
asset := &models.MediaAsset{
|
||||||
|
TenantID: tenant.ID,
|
||||||
|
UserID: creator.ID,
|
||||||
|
Type: consts.MediaAssetTypeImage,
|
||||||
|
ObjectKey: "cover.jpg",
|
||||||
|
}
|
||||||
models.MediaAssetQuery.WithContext(ctx).Create(asset)
|
models.MediaAssetQuery.WithContext(ctx).Create(asset)
|
||||||
models.ContentAssetQuery.WithContext(ctx).Create(&models.ContentAsset{ContentID: content.ID, AssetID: asset.ID, Role: consts.ContentAssetRoleCover})
|
models.ContentAssetQuery.WithContext(ctx).
|
||||||
|
Create(&models.ContentAsset{ContentID: content.ID, AssetID: asset.ID, Role: consts.ContentAssetRoleCover})
|
||||||
|
|
||||||
// Buyer
|
// Buyer
|
||||||
buyer := &models.User{Username: "buyer2", Phone: "13900000002", Balance: 1000}
|
buyer := &models.User{Username: "buyer2", Phone: "13900000002", Balance: 1000}
|
||||||
models.UserQuery.WithContext(ctx).Create(buyer)
|
models.UserQuery.WithContext(ctx).Create(buyer)
|
||||||
buyerCtx := context.WithValue(ctx, consts.CtxKeyUser, buyer.ID)
|
// buyerCtx := context.WithValue(ctx, consts.CtxKeyUser, buyer.ID)
|
||||||
|
|
||||||
Convey("should get full order details", func() {
|
Convey("should get full order details", func() {
|
||||||
// Create & Pay
|
// Create & Pay
|
||||||
createRes, _ := Order.Create(buyerCtx, &order_dto.OrderCreateForm{ContentID: cast.ToString(content.ID)})
|
createRes, _ := Order.Create(
|
||||||
Order.Pay(buyerCtx, createRes.OrderID, &order_dto.OrderPayForm{Method: "balance"})
|
ctx,
|
||||||
|
buyer.ID,
|
||||||
|
&order_dto.OrderCreateForm{ContentID: cast.ToString(content.ID)},
|
||||||
|
)
|
||||||
|
Order.Pay(ctx, buyer.ID, createRes.OrderID, &order_dto.OrderPayForm{Method: "balance"})
|
||||||
|
|
||||||
// Get Detail
|
// Get Detail
|
||||||
detail, err := Order.GetUserOrder(buyerCtx, createRes.OrderID)
|
detail, err := Order.GetUserOrder(ctx, buyer.ID, createRes.OrderID)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(detail.TenantName, ShouldEqual, "Best Shop")
|
So(detail.TenantName, ShouldEqual, "Best Shop")
|
||||||
So(len(detail.Items), ShouldEqual, 1)
|
So(len(detail.Items), ShouldEqual, 1)
|
||||||
@@ -173,7 +220,16 @@ func (s *OrderTestSuite) Test_OrderDetails() {
|
|||||||
func (s *OrderTestSuite) Test_PlatformCommission() {
|
func (s *OrderTestSuite) Test_PlatformCommission() {
|
||||||
Convey("Platform Commission", s.T(), func() {
|
Convey("Platform Commission", s.T(), func() {
|
||||||
ctx := s.T().Context()
|
ctx := s.T().Context()
|
||||||
database.Truncate(ctx, s.DB, models.TableNameUser, models.TableNameOrder, models.TableNameOrderItem, models.TableNameTenant, models.TableNameTenantLedger, models.TableNameContentAccess)
|
database.Truncate(
|
||||||
|
ctx,
|
||||||
|
s.DB,
|
||||||
|
models.TableNameUser,
|
||||||
|
models.TableNameOrder,
|
||||||
|
models.TableNameOrderItem,
|
||||||
|
models.TableNameTenant,
|
||||||
|
models.TableNameTenantLedger,
|
||||||
|
models.TableNameContentAccess,
|
||||||
|
)
|
||||||
|
|
||||||
// Creator
|
// Creator
|
||||||
creator := &models.User{Username: "creator_c", Balance: 0}
|
creator := &models.User{Username: "creator_c", Balance: 0}
|
||||||
@@ -184,7 +240,7 @@ func (s *OrderTestSuite) Test_PlatformCommission() {
|
|||||||
// Buyer
|
// Buyer
|
||||||
buyer := &models.User{Username: "buyer_c", Balance: 2000}
|
buyer := &models.User{Username: "buyer_c", Balance: 2000}
|
||||||
models.UserQuery.WithContext(ctx).Create(buyer)
|
models.UserQuery.WithContext(ctx).Create(buyer)
|
||||||
buyerCtx := context.WithValue(ctx, consts.CtxKeyUser, buyer.ID)
|
// buyerCtx := context.WithValue(ctx, consts.CtxKeyUser, buyer.ID)
|
||||||
|
|
||||||
// Order (10.00 CNY = 1000)
|
// Order (10.00 CNY = 1000)
|
||||||
o := &models.Order{
|
o := &models.Order{
|
||||||
@@ -198,7 +254,7 @@ func (s *OrderTestSuite) Test_PlatformCommission() {
|
|||||||
|
|
||||||
Convey("should deduct 10% fee", func() {
|
Convey("should deduct 10% fee", func() {
|
||||||
payForm := &order_dto.OrderPayForm{Method: "balance"}
|
payForm := &order_dto.OrderPayForm{Method: "balance"}
|
||||||
_, err := Order.Pay(buyerCtx, cast.ToString(o.ID), payForm)
|
_, err := Order.Pay(ctx, buyer.ID, cast.ToString(o.ID), payForm)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
// Verify Creator Balance (1000 - 10% = 900)
|
// Verify Creator Balance (1000 - 10% = 900)
|
||||||
@@ -215,7 +271,16 @@ func (s *OrderTestSuite) Test_PlatformCommission() {
|
|||||||
func (s *OrderTestSuite) Test_ExternalPayment() {
|
func (s *OrderTestSuite) Test_ExternalPayment() {
|
||||||
Convey("External Payment", s.T(), func() {
|
Convey("External Payment", s.T(), func() {
|
||||||
ctx := s.T().Context()
|
ctx := s.T().Context()
|
||||||
database.Truncate(ctx, s.DB, models.TableNameUser, models.TableNameOrder, models.TableNameOrderItem, models.TableNameTenant, models.TableNameTenantLedger, models.TableNameContentAccess)
|
database.Truncate(
|
||||||
|
ctx,
|
||||||
|
s.DB,
|
||||||
|
models.TableNameUser,
|
||||||
|
models.TableNameOrder,
|
||||||
|
models.TableNameOrderItem,
|
||||||
|
models.TableNameTenant,
|
||||||
|
models.TableNameTenantLedger,
|
||||||
|
models.TableNameContentAccess,
|
||||||
|
)
|
||||||
|
|
||||||
// Creator
|
// Creator
|
||||||
creator := &models.User{Username: "creator_ext", Balance: 0}
|
creator := &models.User{Username: "creator_ext", Balance: 0}
|
||||||
|
|||||||
@@ -52,27 +52,27 @@ func (s *TenantTestSuite) Test_Follow() {
|
|||||||
models.TenantQuery.WithContext(ctx).Create(t)
|
models.TenantQuery.WithContext(ctx).Create(t)
|
||||||
|
|
||||||
Convey("should follow tenant", func() {
|
Convey("should follow tenant", func() {
|
||||||
err := Tenant.Follow(ctx, cast.ToString(t.ID))
|
err := Tenant.Follow(ctx, u.ID, cast.ToString(t.ID))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
// Verify stats
|
// Verify stats
|
||||||
profile, err := Tenant.GetPublicProfile(ctx, cast.ToString(t.ID))
|
profile, err := Tenant.GetPublicProfile(ctx, u.ID, cast.ToString(t.ID))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(profile.IsFollowing, ShouldBeTrue)
|
So(profile.IsFollowing, ShouldBeTrue)
|
||||||
So(profile.Stats.Followers, ShouldEqual, 1)
|
So(profile.Stats.Followers, ShouldEqual, 1)
|
||||||
|
|
||||||
// List Followed
|
// List Followed
|
||||||
list, err := Tenant.ListFollowed(ctx)
|
list, err := Tenant.ListFollowed(ctx, u.ID)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(len(list), ShouldEqual, 1)
|
So(len(list), ShouldEqual, 1)
|
||||||
So(list[0].Name, ShouldEqual, "Tenant A")
|
So(list[0].Name, ShouldEqual, "Tenant A")
|
||||||
|
|
||||||
// Unfollow
|
// Unfollow
|
||||||
err = Tenant.Unfollow(ctx, cast.ToString(t.ID))
|
err = Tenant.Unfollow(ctx, u.ID, cast.ToString(t.ID))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
profile, err = Tenant.GetPublicProfile(ctx, cast.ToString(t.ID))
|
profile, err = Tenant.GetPublicProfile(ctx, u.ID, cast.ToString(t.ID))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(profile.IsFollowing, ShouldBeFalse)
|
So(profile.IsFollowing, ShouldBeFalse)
|
||||||
So(profile.Stats.Followers, ShouldEqual, 0)
|
So(profile.Stats.Followers, ShouldEqual, 0)
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ func (s *UserTestSuite) Test_Me() {
|
|||||||
// Mock context with user ID
|
// Mock context with user ID
|
||||||
ctx = context.WithValue(ctx, consts.CtxKeyUser, userID)
|
ctx = context.WithValue(ctx, consts.CtxKeyUser, userID)
|
||||||
|
|
||||||
user, err := User.Me(ctx)
|
user, err := User.Me(ctx, userID)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(user.ID, ShouldEqual, resp.User.ID)
|
So(user.ID, ShouldEqual, resp.User.ID)
|
||||||
So(user.Phone, ShouldEqual, phone)
|
So(user.Phone, ShouldEqual, phone)
|
||||||
@@ -95,7 +95,7 @@ func (s *UserTestSuite) Test_Me() {
|
|||||||
|
|
||||||
Convey("should fail without auth", func() {
|
Convey("should fail without auth", func() {
|
||||||
// No user ID in context
|
// No user ID in context
|
||||||
user, err := User.Me(ctx)
|
user, err := User.Me(ctx, 0)
|
||||||
So(err, ShouldNotBeNil)
|
So(err, ShouldNotBeNil)
|
||||||
So(user, ShouldBeNil)
|
So(user, ShouldBeNil)
|
||||||
})
|
})
|
||||||
@@ -118,11 +118,11 @@ func (s *UserTestSuite) Test_Update() {
|
|||||||
Bio: "New Bio",
|
Bio: "New Bio",
|
||||||
Gender: consts.GenderMale,
|
Gender: consts.GenderMale,
|
||||||
}
|
}
|
||||||
err := User.Update(ctx, form)
|
err := User.Update(ctx, userID, form)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
u, _ := User.Me(ctx)
|
u, _ := User.Me(ctx, userID)
|
||||||
So(u.Nickname, ShouldEqual, "NewName")
|
So(u.Nickname, ShouldEqual, "NewName")
|
||||||
So(u.Bio, ShouldEqual, "New Bio")
|
So(u.Bio, ShouldEqual, "New Bio")
|
||||||
So(u.Gender, ShouldEqual, consts.GenderMale)
|
So(u.Gender, ShouldEqual, consts.GenderMale)
|
||||||
@@ -145,11 +145,11 @@ func (s *UserTestSuite) Test_RealName() {
|
|||||||
Realname: "张三",
|
Realname: "张三",
|
||||||
IDCard: "123456789012345678",
|
IDCard: "123456789012345678",
|
||||||
}
|
}
|
||||||
err := User.RealName(ctx, form)
|
err := User.RealName(ctx, userID, form)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
u, _ := User.Me(ctx)
|
u, _ := User.Me(ctx, userID)
|
||||||
So(u.IsRealNameVerified, ShouldBeTrue)
|
So(u.IsRealNameVerified, ShouldBeTrue)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -175,7 +175,7 @@ func (s *UserTestSuite) Test_GetNotifications() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Convey("should return notifications", func() {
|
Convey("should return notifications", func() {
|
||||||
list, err := User.GetNotifications(ctx, "all")
|
list, err := User.GetNotifications(ctx, userID, "all")
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(len(list), ShouldEqual, 1)
|
So(len(list), ShouldEqual, 1)
|
||||||
So(list[0].Title, ShouldEqual, "Welcome")
|
So(list[0].Title, ShouldEqual, "Welcome")
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ func (s *WalletTestSuite) Test_GetWallet() {
|
|||||||
models.OrderQuery.WithContext(ctx).Create(o1, o2)
|
models.OrderQuery.WithContext(ctx).Create(o1, o2)
|
||||||
|
|
||||||
Convey("should return balance and transactions", func() {
|
Convey("should return balance and transactions", func() {
|
||||||
res, err := Wallet.GetWallet(ctx)
|
res, err := Wallet.GetWallet(ctx, u.ID)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(res.Balance, ShouldEqual, 50.0)
|
So(res.Balance, ShouldEqual, 50.0)
|
||||||
So(len(res.Transactions), ShouldEqual, 2)
|
So(len(res.Transactions), ShouldEqual, 2)
|
||||||
@@ -82,7 +82,7 @@ func (s *WalletTestSuite) Test_Recharge() {
|
|||||||
|
|
||||||
Convey("should create recharge order", func() {
|
Convey("should create recharge order", func() {
|
||||||
form := &user_dto.RechargeForm{Amount: 100.0}
|
form := &user_dto.RechargeForm{Amount: 100.0}
|
||||||
res, err := Wallet.Recharge(ctx, form)
|
res, err := Wallet.Recharge(ctx, u.ID, form)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(res.OrderID, ShouldNotBeEmpty)
|
So(res.OrderID, ShouldNotBeEmpty)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user