feat(docs): "?" help affordance on every filter mount + docs loader fixes
The filter manual (1ed1602e) was reachable only by knowing /docs
already existed — nothing in the UI pointed at it (the parked manual
plan's open decision). Every filter-builder mount now carries a "?"
in its header linking to the guide (opens in a new tab so drawer and
editor state survive): the All Books drawer and the collection rules
page — the two mounts sharing FilterBuilderRows. The docs home
indexes the manual (guide, cookbook, generated field reference).
Two docs-loader fixes surfaced by pinning this:
- Folder URLs resolve to their index page: /docs/user/filters now
serves user/filters/index.md (the manual is a folder: guide +
cookbook + generated reference); previously only root /docs had
index handling.
- The docs folder path is resolved by walking upward (bounded):
`go test` runs test binaries from the PACKAGE directory, so the
relative "docs" path resolved to a folder that didn't exist there
and every /docs route 404'd in tests while working in prod —
found by the new pin, fixed so tests exercise the docs routes
exactly as prod serves them.
Pins: TestFilterHelpAffordance (folder URL serves the guide; drawer
and rules pages carry the link). internal/docs suite + full suite
green (239s).
This commit is contained in:
1 parent
1ed1602e70
commit
a4dc03984c
7 files changed
+118
-24
No files matched your search
@@ -2520,3 +2520,60 @@ func TestFilterLabelsEndpoint(t *testing.T) {
|
||||
assert.Equal(t, http.StatusBadRequest, code, "%s", string(body))
|
||||
})
|
||||
}
|
||||
|
||||
// ---- the "?" affordance: the builder links to its manual ----
|
||||
|
||||
// TestFilterHelpAffordance pins the help links (2026-11-01): every
|
||||
// filter-builder mount carries a "?" linking to the manual, and the
|
||||
// manual's FOLDER URL resolves to its index page (the docs loader's
|
||||
// folder-index fallback — the guide is docs/user/filters/index.md).
|
||||
func TestFilterHelpAffordance(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
regToken := setup.RegularToken
|
||||
|
||||
t.Run("docs_folder_url_serves_the_guide", func(t *testing.T) {
|
||||
req, _ := http.NewRequest("GET", setup.Server.URL+"/docs/user/filters", nil)
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
_ = resp.Body.Close()
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode, "the folder URL resolves to index.md; body: %.400s", string(body))
|
||||
assert.Contains(t, string(body), "Filters — the complete guide")
|
||||
})
|
||||
|
||||
t.Run("drawer_carries_help_link", func(t *testing.T) {
|
||||
req, _ := http.NewRequest("GET", setup.Server.URL+"/bookshelf", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+regToken)
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
_ = resp.Body.Close()
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
assert.Contains(t, string(body), `href="/docs/user/filters"`,
|
||||
"the All Books drawer links to the filter guide")
|
||||
})
|
||||
|
||||
t.Run("rules_page_carries_help_link", func(t *testing.T) {
|
||||
marker := fmt.Sprintf("helpaff%d", time.Now().UnixNano()%100000)
|
||||
code, body := podcastAuthed(t, setup, regToken, "POST", "/api/collections",
|
||||
`{"name":"test HelpAff `+marker+`","filter_tree":{"scope":"episodes","mode":"all","children":[]}}`)
|
||||
require.Equal(t, http.StatusCreated, code, "%s", string(body))
|
||||
var coll struct {
|
||||
ID string `json:"id"`
|
||||
}
|
||||
require.NoError(t, json.Unmarshal(body, &coll))
|
||||
t.Cleanup(func() {
|
||||
podcastAuthed(t, setup, regToken, "DELETE", "/api/collections/"+coll.ID, "")
|
||||
})
|
||||
|
||||
req, _ := http.NewRequest("GET", setup.Server.URL+"/collections/"+coll.ID+"/rules", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+regToken)
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
pageBody, _ := io.ReadAll(resp.Body)
|
||||
_ = resp.Body.Close()
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
assert.Contains(t, string(pageBody), `href="/docs/user/filters"`,
|
||||
"the collection rules editor links to the filter guide")
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user