Files
bookhoard/cmd/server/tests/admin_library_page_test.go
John O'Keefe 9e831085ef fix(ui): derive Library Type dropdowns from library_types — audiobooks was missing
The audiobook library type shipped backend-complete (LibraryTypeAudiobooks
constant, allowed extensions, MIME map, schema seed row, GET
/api/libraries/types) but neither create-library form offered it: the
admin Create Library modal and the setup wizard's add-library step both
hardcoded their <option> lists to the original three types
(ebooks/comics/manga), so an audiobook library could not be created from
the UI.

Both dropdowns now render from the same DB-backed library_types table
the create API resolves types against — a future type appears without
template edits (the exact drift the rendering-ownership rule warns
about):

- templates/utils.go: OrderedLibraryTypes pins the historical dropdown
  order (ebooks, comics, manga, audiobooks) and appends unknown future
  types by name; LibraryTypeDisplayName renders labels with a
  capitalize-the-name fallback for types added without a label
- templates/admin_library.templ: new LibraryTypeOptions fragment used
  by the modal's select; AdminLibrary takes the types list
- templates/setup.templ: Setup takes the types list, same fragment
- internal/router/helpers.go: libraryTypeOptionsFor fetches via
  LibraryService.GetLibraryTypes, falling back to the built-in type
  names on DB failure so the forms stay usable (CreateLibrary still
  resolves the name against the DB, so the fallback is never
  authoritative)
- internal/router/frontend.go, internal/router/setup.go: pass the list
  into the two pages

Tests:
- templates/utils_test.go: pure unit tests for ordering + labels
- cmd/server/tests/admin_library_page_test.go: SSR regression —
  /admin/library must offer all four library types, audiobooks exactly
  once (options come from the DB loop, not a hardcode)
2026-10-18 16:38:03 -04:00

37 lines
1.2 KiB
Go

package main
import (
"net/http"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// The Library Type dropdown on /admin/library (and the setup wizard, which
// shares LibraryTypeOptions) must render from the DB-backed library_types
// table. Regression: audiobooks shipped backend-complete (constant, allowed
// extensions, MIME map, schema seed row, /api/libraries/types) while the
// dropdowns hardcoded the original three types, so an audiobook library
// could not be created from the UI.
func TestAdminLibraryPageDropdownCoversAllLibraryTypes(t *testing.T) {
if testing.Short() {
t.Skip("Skipping integration test in short mode")
}
setup := setupTestServer(t)
code, html := ssrGet(t, setup.Server.URL+"/admin/library", setup.Token)
require.Equal(t, http.StatusOK, code)
for _, typ := range []string{"ebooks", "comics", "manga", "audiobooks"} {
assert.Contains(t, html, `value="`+typ+`"`,
"library type %q missing from the create-library dropdown", typ)
}
assert.Contains(t, html, "Audiobooks")
// Options come from the DB loop, not the deleted hardcode: exactly one
// audiobooks option per page.
assert.Equal(t, 1, strings.Count(html, `value="audiobooks"`))
}