164 lines
4.8 KiB
Go
164 lines
4.8 KiB
Go
package services
|
|
|
|
import (
|
|
"database/sql"
|
|
"testing"
|
|
|
|
"quyun/v2/app/commands/testx"
|
|
super_dto "quyun/v2/app/http/super/v1/dto"
|
|
"quyun/v2/app/requests"
|
|
"quyun/v2/database"
|
|
"quyun/v2/database/models"
|
|
"quyun/v2/pkg/consts"
|
|
|
|
"github.com/samber/lo"
|
|
. "github.com/smartystreets/goconvey/convey"
|
|
"github.com/stretchr/testify/suite"
|
|
"go.ipao.vip/atom/contracts"
|
|
"go.uber.org/dig"
|
|
)
|
|
|
|
type SuperTestSuiteInjectParams struct {
|
|
dig.In
|
|
|
|
DB *sql.DB
|
|
Initials []contracts.Initial `group:"initials"`
|
|
}
|
|
|
|
type SuperTestSuite struct {
|
|
suite.Suite
|
|
SuperTestSuiteInjectParams
|
|
}
|
|
|
|
func Test_Super(t *testing.T) {
|
|
providers := testx.Default().With(Provide)
|
|
|
|
testx.Serve(providers, t, func(p SuperTestSuiteInjectParams) {
|
|
suite.Run(t, &SuperTestSuite{SuperTestSuiteInjectParams: p})
|
|
})
|
|
}
|
|
|
|
func (s *SuperTestSuite) Test_ListUsers() {
|
|
Convey("ListUsers", s.T(), func() {
|
|
ctx := s.T().Context()
|
|
database.Truncate(ctx, s.DB, models.TableNameUser)
|
|
|
|
u1 := &models.User{Username: "user1", Nickname: "Alice"}
|
|
u2 := &models.User{Username: "user2", Nickname: "Bob"}
|
|
models.UserQuery.WithContext(ctx).Create(u1, u2)
|
|
|
|
Convey("should list users", func() {
|
|
filter := &super_dto.UserListFilter{
|
|
Pagination: requests.Pagination{Page: 1, Limit: 10},
|
|
}
|
|
res, err := Super.ListUsers(ctx, filter)
|
|
So(err, ShouldBeNil)
|
|
So(res.Total, ShouldEqual, 2)
|
|
|
|
items := res.Items.([]super_dto.UserItem)
|
|
So(items[0].Username, ShouldEqual, "user2") // Desc order
|
|
})
|
|
|
|
Convey("should filter users", func() {
|
|
filter := &super_dto.UserListFilter{
|
|
Pagination: requests.Pagination{Page: 1, Limit: 10},
|
|
Username: lo.ToPtr("Alice"),
|
|
}
|
|
res, err := Super.ListUsers(ctx, filter)
|
|
So(err, ShouldBeNil)
|
|
So(res.Total, ShouldEqual, 1)
|
|
items := res.Items.([]super_dto.UserItem)
|
|
So(items[0].Username, ShouldEqual, "user1")
|
|
})
|
|
})
|
|
}
|
|
|
|
func (s *SuperTestSuite) Test_CreateTenant() {
|
|
Convey("CreateTenant", s.T(), func() {
|
|
ctx := s.T().Context()
|
|
database.Truncate(ctx, s.DB, models.TableNameUser, models.TableNameTenant)
|
|
|
|
u := &models.User{Username: "admin1"}
|
|
models.UserQuery.WithContext(ctx).Create(u)
|
|
|
|
Convey("should create tenant", func() {
|
|
form := &super_dto.TenantCreateForm{
|
|
Name: "Super Tenant",
|
|
Code: "st1",
|
|
AdminUserID: u.ID,
|
|
}
|
|
err := Super.CreateTenant(ctx, form)
|
|
So(err, ShouldBeNil)
|
|
|
|
t, _ := models.TenantQuery.WithContext(ctx).Where(models.TenantQuery.Code.Eq("st1")).First()
|
|
So(t, ShouldNotBeNil)
|
|
So(t.Name, ShouldEqual, "Super Tenant")
|
|
So(t.UserID, ShouldEqual, u.ID)
|
|
So(t.Status, ShouldEqual, consts.TenantStatusVerified)
|
|
})
|
|
})
|
|
}
|
|
|
|
func (s *SuperTestSuite) Test_WithdrawalApproval() {
|
|
Convey("Withdrawal Approval", s.T(), func() {
|
|
ctx := s.T().Context()
|
|
database.Truncate(ctx, s.DB, models.TableNameOrder, models.TableNameUser, models.TableNameTenantLedger)
|
|
|
|
u := &models.User{Username: "user_w", Balance: 1000} // Initial 10.00
|
|
models.UserQuery.WithContext(ctx).Create(u)
|
|
|
|
// Create Withdrawal Order (Pending)
|
|
o1 := &models.Order{
|
|
UserID: u.ID,
|
|
Type: consts.OrderTypeWithdrawal,
|
|
Status: consts.OrderStatusCreated,
|
|
AmountPaid: 500,
|
|
}
|
|
models.OrderQuery.WithContext(ctx).Create(o1)
|
|
|
|
Convey("should list withdrawals", func() {
|
|
filter := &super_dto.SuperOrderListFilter{Pagination: requests.Pagination{Page: 1, Limit: 10}}
|
|
res, err := Super.ListWithdrawals(ctx, filter)
|
|
So(err, ShouldBeNil)
|
|
So(res.Total, ShouldEqual, 1)
|
|
})
|
|
|
|
Convey("should approve withdrawal", func() {
|
|
err := Super.ApproveWithdrawal(ctx, o1.ID)
|
|
So(err, ShouldBeNil)
|
|
|
|
oReload, _ := models.OrderQuery.WithContext(ctx).Where(models.OrderQuery.ID.Eq(o1.ID)).First()
|
|
So(oReload.Status, ShouldEqual, consts.OrderStatusPaid)
|
|
})
|
|
|
|
Convey("should reject withdrawal and refund", func() {
|
|
// Another order
|
|
o2 := &models.Order{
|
|
UserID: u.ID,
|
|
Type: consts.OrderTypeWithdrawal,
|
|
Status: consts.OrderStatusCreated,
|
|
AmountPaid: 200,
|
|
}
|
|
models.OrderQuery.WithContext(ctx).Create(o2)
|
|
|
|
// Assuming user balance was deducted when o2 was created (logic in creator service)
|
|
// But here we set balance manually to 1000. Let's assume it was 1200 before.
|
|
// Current balance 1000. Refund 200 -> Expect 1200.
|
|
|
|
err := Super.RejectWithdrawal(ctx, o2.ID, "Invalid account")
|
|
So(err, ShouldBeNil)
|
|
|
|
oReload, _ := models.OrderQuery.WithContext(ctx).Where(models.OrderQuery.ID.Eq(o2.ID)).First()
|
|
So(oReload.Status, ShouldEqual, consts.OrderStatusFailed)
|
|
|
|
uReload, _ := models.UserQuery.WithContext(ctx).Where(models.UserQuery.ID.Eq(u.ID)).First()
|
|
So(uReload.Balance, ShouldEqual, 1200)
|
|
|
|
// Check Ledger
|
|
l, _ := models.TenantLedgerQuery.WithContext(ctx).Where(models.TenantLedgerQuery.OrderID.Eq(o2.ID)).First()
|
|
So(l, ShouldNotBeNil)
|
|
So(l.Type, ShouldEqual, consts.TenantLedgerTypeAdjustment)
|
|
})
|
|
})
|
|
}
|