Six findings from docs/audit-polish-2-2026-04-29.md DEFER list:
- F-23: hide STATUS column on /deadlines + /projects when every visible
row shares the same status. Toggled at render time via a CSS class on
the table; the column re-appears the moment filters re-introduce
variety.
- F-32: agenda urgency pill now renders only when it disagrees with
the day-bucket heading (e.g. an Überfällig deadline that lands in
HEUTE through a filter quirk). Common case drops the redundant tag.
- F-38: bottom-nav agenda badge already counted overdue+today (the
brief's option (b)); added a localized title + aria-label so the
count's semantics ("X überfällig + Y heute fällig") is no longer
ambiguous.
- F-40: glossary filter chips no longer mix EN+DE — DE shows
"Streitsachen / Erteilungsverfahren / Allgemein", EN keeps
"Litigation / Prosecution / General". Same i18n keys cover the
Suggest-modal category dropdown.
- F-48: /projects/{id}/sub-projects now 301-redirects to the canonical
/children URL via the existing redirects.go mechanism. Added a small
redirects_test.go to lock the alias in.
- F-49: dropped the meta-circular 2026-04-22 "Neuigkeiten / What's New"
changelog entry that referenced "this changelog" itself.
go build/vet/test clean, bun run build clean.
F-25 (mobile tables → card layout) is redesign-class and is scoped at
the bottom of the PR description as t-paliad-074, not implemented here.
35 lines
1005 B
Go
35 lines
1005 B
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
)
|
|
|
|
// Ensures the /projects/{id}/sub-projects alias from F-48 lands on the
|
|
// canonical /projects/{id}/children URL. The redirect is wired on the OUTER
|
|
// mux so it fires before auth middleware.
|
|
func TestRegisterLegacyRedirects_SubProjectsAlias(t *testing.T) {
|
|
mux := http.NewServeMux()
|
|
registerLegacyRedirects(mux)
|
|
|
|
cases := []struct {
|
|
path string
|
|
want string
|
|
}{
|
|
{"/projects/abc-123/sub-projects", "/projects/abc-123/children"},
|
|
{"/projects/abc-123/sub-projects?foo=bar", "/projects/abc-123/children?foo=bar"},
|
|
}
|
|
for _, tc := range cases {
|
|
req := httptest.NewRequest(http.MethodGet, tc.path, nil)
|
|
w := httptest.NewRecorder()
|
|
mux.ServeHTTP(w, req)
|
|
if w.Code != http.StatusMovedPermanently {
|
|
t.Fatalf("%s: status = %d, want %d", tc.path, w.Code, http.StatusMovedPermanently)
|
|
}
|
|
if got := w.Header().Get("Location"); got != tc.want {
|
|
t.Fatalf("%s: Location = %q, want %q", tc.path, got, tc.want)
|
|
}
|
|
}
|
|
}
|