Files
quyun-v2/backend/app/services/order_test.go

171 lines
4.9 KiB
Go

package services
import (
"database/sql"
"testing"
"quyun/v2/app/commands/testx"
order_dto "quyun/v2/app/http/v1/dto"
"quyun/v2/database"
"quyun/v2/database/models"
"quyun/v2/pkg/consts"
. "github.com/smartystreets/goconvey/convey"
"github.com/stretchr/testify/suite"
"go.ipao.vip/atom/contracts"
"go.uber.org/dig"
)
type OrderTestSuiteInjectParams struct {
dig.In
DB *sql.DB
Initials []contracts.Initial `group:"initials"`
}
type OrderTestSuite struct {
suite.Suite
OrderTestSuiteInjectParams
}
func Test_Order(t *testing.T) {
providers := testx.Default().With(Provide)
testx.Serve(providers, t, func(p OrderTestSuiteInjectParams) {
suite.Run(t, &OrderTestSuite{OrderTestSuiteInjectParams: p})
})
}
func (s *OrderTestSuite) Test_PurchaseFlow() {
Convey("Purchase Flow", s.T(), func() {
ctx := s.T().Context()
tenantID := int64(0)
database.Truncate(
ctx,
s.DB,
models.TableNameOrder,
models.TableNameOrderItem,
models.TableNameUser,
models.TableNameContent,
models.TableNameContentPrice,
models.TableNameTenant,
models.TableNameContentAccess,
models.TableNameTenantLedger,
models.TableNameMediaAsset,
models.TableNameContentAsset,
)
// Setup
creator := &models.User{Username: "creator2", Phone: "13800000002"}
models.UserQuery.WithContext(ctx).Create(creator)
tenant := &models.Tenant{UserID: creator.ID, Name: "Best Shop", Status: consts.TenantStatusVerified}
models.TenantQuery.WithContext(ctx).Create(tenant)
content := &models.Content{
TenantID: tenant.ID,
UserID: creator.ID,
Title: "Amazing Song",
Status: consts.ContentStatusPublished,
}
models.ContentQuery.WithContext(ctx).Create(content)
price := &models.ContentPrice{
TenantID: tenant.ID,
ContentID: content.ID,
PriceAmount: 500,
Currency: consts.CurrencyCNY,
}
models.ContentPriceQuery.WithContext(ctx).Create(price)
// Asset (Cover)
asset := &models.MediaAsset{
TenantID: tenant.ID,
UserID: creator.ID,
Type: consts.MediaAssetTypeImage,
ObjectKey: "cover.jpg",
}
models.MediaAssetQuery.WithContext(ctx).Create(asset)
models.ContentAssetQuery.WithContext(ctx).
Create(&models.ContentAsset{ContentID: content.ID, AssetID: asset.ID, Role: consts.ContentAssetRoleCover})
// Buyer
buyer := &models.User{Username: "buyer2", Phone: "13900000002", Balance: 1000}
models.UserQuery.WithContext(ctx).Create(buyer)
// buyerCtx := context.WithValue(ctx, consts.CtxKeyUser, buyer.ID)
Convey("should get full order details", func() {
// Create & Pay
createRes, _ := Order.Create(
ctx,
tenantID,
buyer.ID,
&order_dto.OrderCreateForm{ContentID: content.ID},
)
res, err := Order.Pay(ctx, tenantID, buyer.ID, createRes.OrderID, &order_dto.OrderPayForm{Method: "balance"})
So(err, ShouldBeNil)
So(res.Status, ShouldEqual, string(consts.OrderStatusPaid))
// Get Detail
detail, err := Order.GetUserOrder(ctx, tenantID, buyer.ID, createRes.OrderID)
So(err, ShouldBeNil)
So(detail.TenantName, ShouldEqual, "Best Shop")
So(len(detail.Items), ShouldEqual, 1)
So(detail.Items[0].Title, ShouldEqual, "Amazing Song")
So(detail.Items[0].Cover, ShouldContainSubstring, "cover.jpg")
So(detail.Amount, ShouldEqual, 5.00)
})
})
}
func (s *OrderTestSuite) Test_PlatformCommission() {
Convey("Platform Commission", s.T(), func() {
ctx := s.T().Context()
tenantID := int64(0)
database.Truncate(
ctx,
s.DB,
models.TableNameUser,
models.TableNameOrder,
models.TableNameOrderItem,
models.TableNameTenant,
models.TableNameTenantLedger,
models.TableNameContentAccess,
)
// Creator
creator := &models.User{Username: "creator_c", Balance: 0}
models.UserQuery.WithContext(ctx).Create(creator)
// Tenant
t := &models.Tenant{UserID: creator.ID, Name: "Shop C", Status: consts.TenantStatusVerified}
models.TenantQuery.WithContext(ctx).Create(t)
tenantID = t.ID
// Buyer
buyer := &models.User{Username: "buyer_c", Balance: 2000}
models.UserQuery.WithContext(ctx).Create(buyer)
// buyerCtx := context.WithValue(ctx, consts.CtxKeyUser, buyer.ID)
// Order (10.00 CNY = 1000)
o := &models.Order{
TenantID: t.ID,
UserID: buyer.ID,
AmountPaid: 1000,
Status: consts.OrderStatusCreated,
}
models.OrderQuery.WithContext(ctx).Create(o)
models.OrderItemQuery.WithContext(ctx).Create(&models.OrderItem{OrderID: o.ID, ContentID: 999}) // Fake content
Convey("should deduct 10% fee", func() {
payForm := &order_dto.OrderPayForm{Method: "balance"}
_, err := Order.Pay(ctx, tenantID, buyer.ID, o.ID, payForm)
So(err, ShouldBeNil)
// Verify Creator Balance (1000 - 10% = 900)
cReload, _ := models.UserQuery.WithContext(ctx).Where(models.UserQuery.ID.Eq(creator.ID)).First()
So(cReload.Balance, ShouldEqual, 900)
// Verify Ledger
l, _ := models.TenantLedgerQuery.WithContext(ctx).Where(models.TenantLedgerQuery.OrderID.Eq(o.ID)).First()
So(l.Amount, ShouldEqual, 900)
})
})
}