feat(17-01): menu item type registry and dependent dropdown binding
- pact: HasMenuItemTypes, MenuItemType, MenuItemReference, MenuItemResolve,
ResolvedMenuItem, MenuItemAlternate, DependentOptionsProvider,
DependentOptionSet; Option gains Depth (omitempty)
- signpost (new module): boot-time registry with fail-loud key and pattern
checks, layered URL patterns incl. PatternFrom for list types, host
overrides at menu_items.patterns, Resolve and ReferenceOptions
- party: signpost.Activate after postcard, before Boot
- cabana: dependsOn on dropdowns (boot checks, controller-only), GET
fields/{field}/dependent-options with swag, inventories, conformance case
- companions fixture, TestSignpostSmoke, TestCompanionsDependentSmoke, docs
This commit is contained in:
@@ -32,6 +32,7 @@ import (
|
||||
"git.golem15.com/golem15/summercms/modules/pact"
|
||||
"git.golem15.com/golem15/summercms/modules/party"
|
||||
"git.golem15.com/golem15/summercms/modules/phrasebook"
|
||||
"git.golem15.com/golem15/summercms/modules/signpost"
|
||||
"git.golem15.com/golem15/summercms/modules/surf"
|
||||
"gocloud.dev/blob"
|
||||
"gocloud.dev/blob/memblob"
|
||||
@@ -286,6 +287,9 @@ func conformCases() []conformCase {
|
||||
{"GET /{vendor}/{plugin}/{controller}/fields/{field}/options", 200, "cabana.ListEnvelope-array_cabana_RelationOption", func(t *testing.T, e *conformEnv) *httptest.ResponseRecorder {
|
||||
return e.send(t, http.MethodGet, "/acme/conform/gadgets/fields/group/options?search="+e.stamp, nil, true)
|
||||
}, into[cabana.ListEnvelope[[]cabana.RelationOption]](), nil},
|
||||
{"GET /{vendor}/{plugin}/{controller}/fields/{field}/dependent-options", 200, "cabana.Envelope-cabana_AdminDependentOptionsResult", func(t *testing.T, e *conformEnv) *httptest.ResponseRecorder {
|
||||
return e.send(t, http.MethodGet, dependentOptionsPath("reference", "acme-page"), nil, true)
|
||||
}, into[cabana.Envelope[cabana.AdminDependentOptionsResult]](), nil},
|
||||
{"GET /{vendor}/{plugin}/{controller}/filters/{scope}/options", 200, "cabana.Envelope-array_cabana_FilterOption", func(t *testing.T, e *conformEnv) *httptest.ResponseRecorder {
|
||||
return e.send(t, http.MethodGet, "/acme/conform/gadgets/filters/grouped/options", nil, true)
|
||||
}, into[cabana.Envelope[[]cabana.FilterOption]](), nil},
|
||||
@@ -794,6 +798,7 @@ func newConformEnv(t *testing.T) *conformEnv {
|
||||
if err := gdb.AutoMigrate(models...); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
resetCompanions(t, gdb)
|
||||
// Gadget ids restart with the recreated table: drop the files and
|
||||
// bindings an earlier run left for them.
|
||||
if err := gdb.Exec(`DELETE FROM system_files WHERE attachment_type IN ('acme.conform.gadget', 'acme.conform.part') OR attachment_id IS NULL OR attachment_id = ''`).Error; err != nil {
|
||||
@@ -836,10 +841,15 @@ func newConformEnv(t *testing.T) *conformEnv {
|
||||
if err := attach.Publish(app, bucket); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
plugins := []party.Plugin{conformPlugin{stamp: stamp}}
|
||||
// The acme.companions fixture serves the Phase 17 routes (dependent
|
||||
// options) next to the gadgets.
|
||||
plugins := []party.Plugin{conformPlugin{stamp: stamp}, companionsPlugin{app: app}}
|
||||
if err := phrasebook.Activate(app, plugins); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := signpost.Activate(app, plugins); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
h, err := surf.Assemble(app, plugins)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
Reference in New Issue
Block a user