Files
cpa-plugin/internal/webdemo/server_test.go
T

156 lines
4.7 KiB
Go

package webdemo
import (
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
func TestServerServesSplitUIAndFakeInput(t *testing.T) {
server := httptest.NewServer(NewServer(NewFakeInput()))
defer server.Close()
for _, path := range []string{"/ui", "/ui-config.js", "/styles/base.css", "/styles/keys.css", "/styles/usage.css", "/styles/pricing.css", "/app/main.js", "/app/core/runtime.js", "/app/features/keys.js", "/app/features/usage.js", "/app/features/pricing.js"} {
response, err := http.Get(server.URL + path)
if err != nil {
t.Fatal(err)
}
if response.StatusCode != http.StatusOK {
response.Body.Close()
t.Fatalf("GET %s status = %d", path, response.StatusCode)
}
response.Body.Close()
}
configResponse, err := http.Get(server.URL + "/ui-config.js")
if err != nil {
t.Fatal(err)
}
defer configResponse.Body.Close()
configBody, err := io.ReadAll(configResponse.Body)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(string(configBody), "demoPerspectives:true") {
t.Fatalf("demo config does not enable perspective switch: %s", configBody)
}
response, err := http.Get(server.URL + managementBase + "/usage?page=2&page_size=100&model=deepseek")
if err != nil {
t.Fatal(err)
}
defer response.Body.Close()
var usage struct {
Records []fakeUsage `json:"records"`
Page map[string]any `json:"pagination"`
}
if err := json.NewDecoder(response.Body).Decode(&usage); err != nil {
t.Fatal(err)
}
if response.StatusCode != http.StatusOK || len(usage.Records) == 0 || usage.Page["page"] != float64(2) {
t.Fatalf("unexpected fake usage response: status=%d records=%d page=%v", response.StatusCode, len(usage.Records), usage.Page)
}
for _, record := range usage.Records {
if !strings.Contains(record.Model, "deepseek") {
t.Fatalf("unexpected filtered model %q", record.Model)
}
}
response, err = http.Get(server.URL + managementBase + "/usage?page=1&page_size=1")
if err != nil {
t.Fatal(err)
}
defer response.Body.Close()
var allUsage struct {
Page struct {
Total int `json:"total"`
} `json:"pagination"`
}
if err := json.NewDecoder(response.Body).Decode(&allUsage); err != nil {
t.Fatal(err)
}
if allUsage.Page.Total != fakeUsageCount {
t.Fatalf("fake usage total = %d, want %d", allUsage.Page.Total, fakeUsageCount)
}
}
func TestFakeInputSupportsKeyMutation(t *testing.T) {
server := httptest.NewServer(NewServer(NewFakeInput()))
defer server.Close()
body := `{"name":"Demo User","route_mode":"auto","all_models":true,"billing":{"quota_usd":"25","reset_period":"none","max_concurrency":4}}`
request, err := http.NewRequest(http.MethodPost, server.URL+managementBase+"/keys", strings.NewReader(body))
if err != nil {
t.Fatal(err)
}
request.Header.Set("Content-Type", "application/json")
response, err := http.DefaultClient.Do(request)
if err != nil {
t.Fatal(err)
}
defer response.Body.Close()
var key fakeKey
if err := json.NewDecoder(response.Body).Decode(&key); err != nil {
t.Fatal(err)
}
if response.StatusCode != http.StatusOK || key.Name != "Demo User" || key.Billing["balance_usd"] != "25.000000" {
t.Fatalf("unexpected created key: status=%d key=%+v", response.StatusCode, key)
}
}
func TestFakeDashboardIncludesSevenDailyCosts(t *testing.T) {
server := httptest.NewServer(NewServer(NewFakeInput()))
defer server.Close()
response, err := http.Get(server.URL + managementBase + "/usage-summary")
if err != nil {
t.Fatal(err)
}
defer response.Body.Close()
var dashboard struct {
Days []struct {
Date string `json:"date"`
CostUSD float64 `json:"cost_usd"`
} `json:"days"`
Users []struct {
Days []struct {
CostUSD float64 `json:"cost_usd"`
} `json:"days"`
} `json:"users"`
}
if err := json.NewDecoder(response.Body).Decode(&dashboard); err != nil {
t.Fatal(err)
}
if len(dashboard.Days) != 7 || dashboard.Days[6].CostUSD <= 0 || len(dashboard.Users) == 0 || len(dashboard.Users[0].Days) != 7 {
t.Fatalf("unexpected daily costs: %+v", dashboard.Days)
}
}
func TestDatabaseInputServesStandaloneBillingDatabase(t *testing.T) {
input, err := NewDatabaseInput(t.TempDir() + "/billing.db")
if err != nil {
t.Fatal(err)
}
defer input.Close()
server := httptest.NewServer(NewServer(input))
defer server.Close()
response, err := http.Get(server.URL + managementBase + "/keys")
if err != nil {
t.Fatal(err)
}
defer response.Body.Close()
var payload struct {
Keys []fakeKey `json:"keys"`
}
if err := json.NewDecoder(response.Body).Decode(&payload); err != nil {
t.Fatal(err)
}
if response.StatusCode != http.StatusOK || len(payload.Keys) != 1 {
t.Fatalf("database input keys: status=%d keys=%d", response.StatusCode, len(payload.Keys))
}
}