mavweb: add notifications history page at /notifications
RecentNudges IPC method, store adapter, dispatch, and client proxy. Web UI at /notifications showing recent nudge history with color-coded outcomes, nav links from /dash and /history.
This commit is contained in:
@@ -52,6 +52,9 @@ type fakeCore struct {
|
||||
revertNewID int64
|
||||
revertErr error
|
||||
|
||||
// for handleNotifications tests
|
||||
nudgesErr error
|
||||
|
||||
// for handleHistory tests
|
||||
historyFacts []ipc.Fact
|
||||
historyErr error
|
||||
@@ -115,6 +118,9 @@ func (f *fakeCore) RecentFacts(_ context.Context, _ int) ([]ipc.Fact, error) {
|
||||
}
|
||||
|
||||
func (f *fakeCore) RecentNudges(_ context.Context, _ int) ([]ipc.Nudge, error) {
|
||||
if f.nudgesErr != nil {
|
||||
return nil, f.nudgesErr
|
||||
}
|
||||
if f.dashErr != nil {
|
||||
return nil, f.dashErr
|
||||
}
|
||||
@@ -549,6 +555,58 @@ func TestHandleDash(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
// --- handleNotifications ---
|
||||
|
||||
func TestHandleNotifications_NilCore_503(t *testing.T) {
|
||||
t.Parallel()
|
||||
rr := httptest.NewRecorder()
|
||||
handleNotifications(rr, httptest.NewRequest(http.MethodGet, "/notifications", nil), nil)
|
||||
if rr.Code != http.StatusServiceUnavailable {
|
||||
t.Errorf("status = %d, want 503", rr.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleNotifications_CoreError_502(t *testing.T) {
|
||||
t.Parallel()
|
||||
core := &fakeCore{nudgesErr: ipc.ErrNudgeNotFound}
|
||||
rr := httptest.NewRecorder()
|
||||
handleNotifications(rr, httptest.NewRequest(http.MethodGet, "/notifications", nil), core)
|
||||
if rr.Code != http.StatusBadGateway {
|
||||
t.Errorf("status = %d, want 502", rr.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleNotifications_Renders(t *testing.T) {
|
||||
t.Parallel()
|
||||
core := &fakeCore{
|
||||
nudges: []ipc.Nudge{
|
||||
{Rule: "test-rule", Channel: "telegram", Message: "hello world", Outcome: "pending"},
|
||||
{Rule: "other-rule", Channel: "voice", Message: "something happened", Outcome: "acted"},
|
||||
},
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handleNotifications(rr, httptest.NewRequest(http.MethodGet, "/notifications", nil), core)
|
||||
if rr.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d, want 200; body=%s", rr.Code, rr.Body.String())
|
||||
}
|
||||
body := rr.Body.String()
|
||||
if !strings.Contains(body, "test-rule") {
|
||||
t.Error("rendered output missing rule name")
|
||||
}
|
||||
if !strings.Contains(body, "telegram") {
|
||||
t.Error("rendered output missing channel")
|
||||
}
|
||||
if !strings.Contains(body, "pending") {
|
||||
t.Error("rendered output missing outcome")
|
||||
}
|
||||
if !strings.Contains(body, "hello world") {
|
||||
t.Error("rendered output missing message")
|
||||
}
|
||||
if !strings.Contains(body, "other-rule") {
|
||||
t.Error("rendered output missing second rule")
|
||||
}
|
||||
}
|
||||
|
||||
// --- handleHistory ---
|
||||
|
||||
func TestHandleHistory(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user