2

Add dashboard activity leaderboards

This commit is contained in:
2026-03-12 15:48:33 +01:00
parent f15839cf51
commit 49bda65b3b
9 changed files with 534 additions and 26 deletions

View File

@@ -33,7 +33,7 @@ func TestHandlerServesOverviewAndManualActions(t *testing.T) {
}
recorder = httptest.NewRecorder()
request = httptest.NewRequest(http.MethodGet, "/api/overview?limit=10", nil)
request = httptest.NewRequest(http.MethodGet, "/api/overview?hours=24&limit=10", nil)
handler.ServeHTTP(recorder, request)
if recorder.Code != http.StatusOK {
t.Fatalf("unexpected overview status: %d", recorder.Code)
@@ -42,7 +42,7 @@ func TestHandlerServesOverviewAndManualActions(t *testing.T) {
if err := json.Unmarshal(recorder.Body.Bytes(), &overview); err != nil {
t.Fatalf("decode overview payload: %v", err)
}
if overview.TotalEvents != 1 || len(overview.RecentIPs) != 1 {
if overview.TotalEvents != 1 || len(overview.RecentIPs) != 1 || len(overview.TopIPsByEvents) != 1 {
t.Fatalf("unexpected overview payload: %+v", overview)
}
@@ -80,6 +80,18 @@ func TestHandlerServesOverviewAndManualActions(t *testing.T) {
if !strings.Contains(recorder.Body.String(), "Show known bots") {
t.Fatalf("overview page should expose the known bots toggle")
}
if !strings.Contains(recorder.Body.String(), "Top IPs by events") {
t.Fatalf("overview page should expose the top IPs by events block")
}
if !strings.Contains(recorder.Body.String(), "Top IPs by traffic") {
t.Fatalf("overview page should expose the top IPs by traffic block")
}
if !strings.Contains(recorder.Body.String(), "Top sources by events") {
t.Fatalf("overview page should expose the top sources block")
}
if !strings.Contains(recorder.Body.String(), "Top URLs by events") {
t.Fatalf("overview page should expose the top URLs block")
}
if !strings.Contains(recorder.Body.String(), "Show allowed") {
t.Fatalf("overview page should expose the allowed toggle")
}
@@ -121,12 +133,37 @@ type stubApp struct {
lastAction string
}
func (s *stubApp) GetOverview(context.Context, int) (model.Overview, error) {
func (s *stubApp) GetOverview(context.Context, time.Time, int) (model.Overview, error) {
now := time.Now().UTC()
return model.Overview{
TotalEvents: 1,
TotalIPs: 1,
BlockedIPs: 1,
TopIPsByEvents: []model.TopIPRow{{
IP: "203.0.113.10",
Events: 3,
TrafficBytes: 4096,
LastSeenAt: now,
}},
TopIPsByTraffic: []model.TopIPRow{{
IP: "203.0.113.10",
Events: 3,
TrafficBytes: 4096,
LastSeenAt: now,
}},
TopSources: []model.TopSourceRow{{
SourceName: "main",
Events: 3,
TrafficBytes: 4096,
LastSeenAt: now,
}},
TopURLs: []model.TopURLRow{{
Host: "example.test",
URI: "/wp-login.php",
Events: 3,
TrafficBytes: 4096,
LastSeenAt: now,
}},
RecentIPs: []model.IPState{{
IP: "203.0.113.10",
State: model.IPStateBlocked,
@@ -146,12 +183,12 @@ func (s *stubApp) GetOverview(context.Context, int) (model.Overview, error) {
}
func (s *stubApp) ListEvents(ctx context.Context, limit int) ([]model.Event, error) {
overview, _ := s.GetOverview(ctx, limit)
overview, _ := s.GetOverview(ctx, time.Time{}, limit)
return overview.RecentEvents, nil
}
func (s *stubApp) ListIPs(ctx context.Context, limit int, state string) ([]model.IPState, error) {
overview, _ := s.GetOverview(ctx, limit)
overview, _ := s.GetOverview(ctx, time.Time{}, limit)
return overview.RecentIPs, nil
}