2026-07-15 09:43:33 +08:00

93 lines
3.3 KiB
Go

package activitytemplate
import (
"context"
"net/http"
"net/http/httptest"
"strings"
"testing"
"hyapp-admin-server/internal/integration/activityclient"
"hyapp-admin-server/internal/middleware"
activityv1 "hyapp.local/api/proto/activity/v1"
"github.com/gin-gonic/gin"
)
type validatePermissionClient struct {
activityclient.Client
}
func (validatePermissionClient) ValidateActivityTemplate(context.Context, *activityv1.ValidateActivityTemplateRequest) (*activityv1.ValidateActivityTemplateResponse, error) {
return &activityv1.ValidateActivityTemplateResponse{Valid: true}, nil
}
func TestRegisterRoutesExposesActivityTemplateContract(t *testing.T) {
gin.SetMode(gin.TestMode)
engine := gin.New()
RegisterRoutes(engine.Group("/api/v1"), &Handler{})
actual := make(map[string]struct{})
for _, route := range engine.Routes() {
actual[route.Method+" "+route.Path] = struct{}{}
}
expected := []string{
"GET /api/v1/admin/activities/templates",
"POST /api/v1/admin/activities/templates",
"POST /api/v1/admin/activities/templates/validate",
"GET /api/v1/admin/activities/templates/:template_id",
"PUT /api/v1/admin/activities/templates/:template_id",
"PATCH /api/v1/admin/activities/templates/:template_id/status",
"DELETE /api/v1/admin/activities/templates/:template_id",
"GET /api/v1/admin/activities/templates/:template_id/versions",
"POST /api/v1/admin/activities/templates/:template_id/clone",
"GET /api/v1/admin/activities/templates/:template_id/leaderboard",
"GET /api/v1/admin/activities/templates/:template_id/data",
"GET /api/v1/admin/activities/templates/:template_id/data/export",
"GET /api/v1/admin/activities/templates/:template_id/rewards",
"POST /api/v1/admin/activities/templates/:template_id/rewards/:reward_job_id/retry",
"GET /api/v1/admin/activities/templates/:template_id/task-claims",
"POST /api/v1/admin/activities/templates/:template_id/task-claims/:claim_id/retry",
}
for _, route := range expected {
if _, ok := actual[route]; !ok {
t.Errorf("missing route %s; actual=%v", route, actual)
}
}
}
func TestValidateRouteAcceptsCreateUpdateOrPublishPermission(t *testing.T) {
gin.SetMode(gin.TestMode)
tests := []struct {
permission string
wantStatus int
}{
{permission: "activity-template:create", wantStatus: http.StatusOK},
{permission: "activity-template:update", wantStatus: http.StatusOK},
{permission: "activity-template:publish", wantStatus: http.StatusOK},
{permission: "activity-template:view", wantStatus: http.StatusForbidden},
}
for _, tt := range tests {
t.Run(tt.permission, func(t *testing.T) {
engine := gin.New()
engine.Use(func(c *gin.Context) {
c.Set(middleware.ContextPermissions, []string{tt.permission})
c.Next()
})
RegisterRoutes(engine.Group("/api/v1"), New(validatePermissionClient{}, nil))
recorder := httptest.NewRecorder()
request := httptest.NewRequest(http.MethodPost, "/api/v1/admin/activities/templates/validate", strings.NewReader(`{
"template":{"template_code":"gift_challenge_2026","name":"Gift Challenge"},
"for_publish":false
}`))
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())
}
})
}
}