88 lines
3.3 KiB
Go

package opscenter
import (
"context"
"net/http"
"net/http/httptest"
"strings"
"testing"
"hyapp-admin-server/internal/integration/luckygiftadmin"
"hyapp-admin-server/internal/middleware"
luckygiftmodule "hyapp-admin-server/internal/modules/luckygift"
luckygiftv1 "hyapp.local/api/proto/luckygift/v1"
"github.com/gin-gonic/gin"
)
type poolPermissionClient struct {
luckygiftadmin.Client
}
func (poolPermissionClient) AdjustLuckyGiftPoolBalance(_ context.Context, req *luckygiftv1.AdjustLuckyGiftPoolBalanceRequest) (*luckygiftv1.AdjustLuckyGiftPoolBalanceResponse, error) {
return &luckygiftv1.AdjustLuckyGiftPoolBalanceResponse{
Adjustment: &luckygiftv1.LuckyGiftPoolAdjustment{
AdjustmentId: req.GetAdjustmentId(), AppCode: req.GetMeta().GetAppCode(), PoolId: req.GetPoolId(),
StrategyVersion: req.GetStrategyVersion(), Direction: req.GetDirection(), AmountCoins: req.GetAmountCoins(),
},
Pool: &luckygiftv1.LuckyGiftPoolBalance{
AppCode: req.GetMeta().GetAppCode(), PoolId: req.GetPoolId(), StrategyVersion: req.GetStrategyVersion(), Materialized: true,
},
}, nil
}
func TestRegisterRoutesExposesStrategyPoolAdjustmentEndpoints(t *testing.T) {
gin.SetMode(gin.TestMode)
engine := gin.New()
RegisterRoutes(engine.Group("/api/v1"), New(nil, luckygiftmodule.New(poolPermissionClient{}, 0, nil)))
routes := make(map[string]struct{})
for _, route := range engine.Routes() {
routes[route.Method+" "+route.Path] = struct{}{}
}
for _, expected := range []string{
"POST /api/v1/admin/ops-center/lucky-gifts/pools/credit",
"POST /api/v1/admin/ops-center/lucky-gifts/pools/debit",
} {
if _, ok := routes[expected]; !ok {
t.Fatalf("missing route %s; actual=%v", expected, routes)
}
}
}
func TestPoolAdjustmentRoutesRequireDirectionSpecificPermission(t *testing.T) {
gin.SetMode(gin.TestMode)
tests := []struct {
name string
path string
permission string
wantStatus int
}{
{name: "credit allowed", path: "credit", permission: "lucky-gift:pool-credit", wantStatus: http.StatusOK},
{name: "credit rejects debit permission", path: "credit", permission: "lucky-gift:pool-debit", wantStatus: http.StatusForbidden},
{name: "debit allowed", path: "debit", permission: "lucky-gift:pool-debit", wantStatus: http.StatusOK},
{name: "debit rejects view permission", path: "debit", permission: "lucky-gift:view", wantStatus: http.StatusForbidden},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
engine := gin.New()
engine.Use(func(c *gin.Context) {
c.Set(middleware.ContextPermissions, []string{tt.permission})
c.Set(middleware.ContextUserID, uint(7))
c.Next()
})
RegisterRoutes(engine.Group("/api/v1"), New(nil, luckygiftmodule.New(poolPermissionClient{}, 0, nil)))
recorder := httptest.NewRecorder()
request := httptest.NewRequest(
http.MethodPost,
"/api/v1/admin/ops-center/lucky-gifts/pools/"+tt.path+"?app_code=aslan&pool_id=lucky&strategy_version=dynamic_v3",
strings.NewReader(`{"adjustment_id":"route-adjustment","amount_coins":1,"reason":"permission test"}`),
)
request.Header.Set("Content-Type", "application/json")
engine.ServeHTTP(recorder, request)
if recorder.Code != tt.wantStatus {
t.Fatalf("status=%d want=%d body=%s", recorder.Code, tt.wantStatus, recorder.Body.String())
}
})
}
}