membership_plans 表、admin 套餐页、Grant/CreateOrder 读表; Loop continuous 自动 Approve/Closed。Next:ECR-015 RedemptionCode。 Co-authored-by: Cursor <cursoragent@cursor.com>
98 lines
2.6 KiB
Go
98 lines
2.6 KiB
Go
package integration_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestMembershipPlans(t *testing.T) {
|
|
r, _ := setupAPIPool(t)
|
|
tok := adminLogin(t, r, "admin", "change-me")
|
|
|
|
_, code := doAdminJSON(t, r, http.MethodGet, "/api/v1/admin/membership-plans", nil, "")
|
|
if code != http.StatusUnauthorized {
|
|
t.Fatalf("expected 401, got %d", code)
|
|
}
|
|
|
|
start := time.Now()
|
|
env, code := doAdminJSON(t, r, http.MethodGet, "/api/v1/admin/membership-plans", nil, tok)
|
|
if code != 200 || time.Since(start) > 500*time.Millisecond {
|
|
t.Fatalf("list plans http=%d dur=%v msg=%s", code, time.Since(start), env.Message)
|
|
}
|
|
var list struct {
|
|
Items []struct {
|
|
Code string `json:"code"`
|
|
DurationDays int `json:"duration_days"`
|
|
AmountCents int `json:"amount_cents"`
|
|
} `json:"items"`
|
|
}
|
|
_ = json.Unmarshal(env.Data, &list)
|
|
if len(list.Items) < 3 {
|
|
t.Fatalf("expected 3 plans, got %#v", list.Items)
|
|
}
|
|
|
|
env, code = doAdminJSON(t, r, http.MethodPut, "/api/v1/admin/membership-plans/month", map[string]any{
|
|
"title": "月卡测", "duration_days": 30, "amount_cents": 2600, "active": true,
|
|
}, tok)
|
|
if code != 200 {
|
|
t.Fatalf("put failed %d %s", code, env.Message)
|
|
}
|
|
var plan struct {
|
|
DurationDays int `json:"duration_days"`
|
|
AmountCents int `json:"amount_cents"`
|
|
}
|
|
_ = json.Unmarshal(env.Data, &plan)
|
|
if plan.DurationDays != 30 || plan.AmountCents != 2600 {
|
|
t.Fatalf("unexpected plan %#v", plan)
|
|
}
|
|
|
|
env, code = doAdminJSON(t, r, http.MethodGet, "/api/v1/admin/membership-plans/month", nil, tok)
|
|
if code != 200 {
|
|
t.Fatalf("get %d", code)
|
|
}
|
|
_ = json.Unmarshal(env.Data, &plan)
|
|
if plan.DurationDays != 30 {
|
|
t.Fatalf("get mismatch %#v", plan)
|
|
}
|
|
|
|
_ = mustRegister(t, r)
|
|
env, code = doAdminJSON(t, r, http.MethodGet, "/api/v1/admin/users", nil, tok)
|
|
var users struct {
|
|
Items []struct {
|
|
ID string `json:"id"`
|
|
} `json:"items"`
|
|
}
|
|
_ = json.Unmarshal(env.Data, &users)
|
|
if len(users.Items) == 0 {
|
|
t.Fatal("need user")
|
|
}
|
|
env, code = doAdminJSON(t, r, http.MethodPost, "/api/v1/admin/users/"+users.Items[0].ID+"/membership/grant",
|
|
map[string]string{"plan": "month"}, tok)
|
|
if code != 200 {
|
|
t.Fatalf("grant %d %s", code, env.Message)
|
|
}
|
|
|
|
env, code = doAdminJSON(t, r, http.MethodGet, "/api/v1/admin/audit-logs", nil, tok)
|
|
if code != 200 {
|
|
t.Fatalf("audit %d", code)
|
|
}
|
|
var audit struct {
|
|
Items []struct {
|
|
Action string `json:"action"`
|
|
} `json:"items"`
|
|
}
|
|
_ = json.Unmarshal(env.Data, &audit)
|
|
found := false
|
|
for _, it := range audit.Items {
|
|
if it.Action == "membership.plans.update" {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Fatal("missing membership.plans.update audit")
|
|
}
|
|
}
|