[refactor](alarm): end alerts by disarm or expiry, not a ring timer
An alert now rings from trigger until the owner disarms it; a subscriber silences only its own device. The owner instead sets a persistence cap (default 24h, hard cap 14 days) and the sweeper destroys expired alerts. Disarm ends an armed alert too, and every ending (delivered, expired, disarmed, deleted) converges on the one destruction path so their event-log reasons cannot drift.
This commit is contained in:
@@ -107,3 +107,38 @@ func TestLogoutServesBothMethods(t *testing.T) {
|
||||
t.Fatalf("PUT /auth/logout = %d, want 405", code)
|
||||
}
|
||||
}
|
||||
|
||||
// TestRouteLevelErrorsCarryMessages walks the error paths main.go registers
|
||||
// itself — the /action/ verb guard and the per-method guards on /auth/* — and
|
||||
// asserts the user's invariant: an error status never comes with an empty body.
|
||||
// The /action/ dispatch errors are plain text, the auth guards are plain text
|
||||
// too; both must carry a readable message.
|
||||
func TestRouteLevelErrorsCarryMessages(t *testing.T) {
|
||||
outer := newOuterMux(newAPIMux())
|
||||
|
||||
cases := []struct {
|
||||
method string
|
||||
path string
|
||||
body string
|
||||
want int
|
||||
}{
|
||||
{http.MethodPatch, "/action/createAlert", "", http.StatusMethodNotAllowed},
|
||||
{http.MethodGet, "/action/nope", "", http.StatusNotImplemented},
|
||||
{http.MethodPost, "/action/getAlert", `{"unknown":true}`, http.StatusBadRequest},
|
||||
{http.MethodPut, "/auth/login", "", http.StatusMethodNotAllowed},
|
||||
{http.MethodDelete, "/auth/me", "", http.StatusMethodNotAllowed},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
req := httptest.NewRequest(tc.method, tc.path, strings.NewReader(tc.body))
|
||||
rec := httptest.NewRecorder()
|
||||
outer.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != tc.want {
|
||||
t.Fatalf("%s %s = %d, want %d (body: %q)", tc.method, tc.path, rec.Code, tc.want, rec.Body.String())
|
||||
}
|
||||
if body := strings.TrimSpace(rec.Body.String()); body == "" {
|
||||
t.Fatalf("%s %s: status %d with an empty body — every error must carry a message", tc.method, tc.path, rec.Code)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user