By-model panel gains a segmented 1天/7天/全部 control. Selecting a range fetches /api/stats?since=<RFC3339> and re-renders only that table client-side, replicating the human/rate template helpers in JS; the existing /api/stats since param already drives the server-side filter. - internal/server/templates/admin.html: filter UI + JS, empty/loading states - internal/server/server_test.go: render test for the filter controls - scripts/test-instance.sh: build→start→stop→clean test-instance helper
This commit is contained in:
@@ -15,6 +15,7 @@ import (
|
||||
|
||||
"git.misaka.ren/M1saka/zhanlu_proxy/internal/auth"
|
||||
"git.misaka.ren/M1saka/zhanlu_proxy/internal/config"
|
||||
"git.misaka.ren/M1saka/zhanlu_proxy/internal/stats"
|
||||
"git.misaka.ren/M1saka/zhanlu_proxy/internal/store"
|
||||
)
|
||||
|
||||
@@ -365,6 +366,47 @@ func TestModelTestNoCredentials(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestAdminRendersModelRangeFilter verifies the admin page renders without
|
||||
// panic for both empty and populated summaries, and that the by-model panel
|
||||
// carries the 1d/7d/all range filter controls and a client-renderable tbody.
|
||||
func TestAdminRendersModelRangeFilter(t *testing.T) {
|
||||
populated := &stats.Summary{
|
||||
PerModel: []stats.ModelStat{
|
||||
{Model: "GLM-4.7", Requests: 3, PromptTokens: 10, CompletionTokens: 20, TotalTokens: 30, CachedTokens: 4},
|
||||
},
|
||||
}
|
||||
cases := []struct {
|
||||
name string
|
||||
summary *stats.Summary
|
||||
}{
|
||||
{"empty", &stats.Summary{}},
|
||||
{"populated", populated},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
var buf bytes.Buffer
|
||||
if err := adminTemplate.Execute(&buf, map[string]any{
|
||||
"Enabled": true,
|
||||
"Stats": tc.summary,
|
||||
"DBPath": "zhanlu.db",
|
||||
"PasswordEnabled": false,
|
||||
}); err != nil {
|
||||
t.Fatalf("%s: render admin: %v", tc.name, err)
|
||||
}
|
||||
body := buf.String()
|
||||
for _, want := range []string{
|
||||
`id="model-range"`,
|
||||
`data-range="1d"`,
|
||||
`data-range="7d"`,
|
||||
`data-range="all"`,
|
||||
`id="model-tbody"`,
|
||||
} {
|
||||
if !strings.Contains(body, want) {
|
||||
t.Fatalf("%s: admin output missing %q", tc.name, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// totNum extracts an int from a JSON-decoded numeric value (float64).
|
||||
func totNum(v any) int {
|
||||
f, _ := v.(float64)
|
||||
|
||||
Reference in New Issue
Block a user