- docs/backend: admin controllers, forms, lists and filters, relation manager, users and permissions, settings, partials and widgets, admin SPA - docs/services: storage, outbound HTTP, realtime, Web Push, search, parity testing and the Frontend and AJAX (not provided) page - Examples for cabana (with testdata/docs YAML), fetchguard, lighthouse and its centrifugo driver, flare, beachcomber and typesense, tide; lighthouse and beachcomber TestDocs* regions run on their Postgres harnesses - concept map rows link their guide pages and the not-provided rows the Frontend and AJAX page; index lists Backend, Database and Services - TestDocsRequiredPages asserts the D-08 section order
104 lines
3.4 KiB
Go
104 lines
3.4 KiB
Go
package cabana_test
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"testing"
|
|
|
|
"git.golem15.com/golem15/summercms/modules/backpack"
|
|
"git.golem15.com/golem15/summercms/modules/bouncer"
|
|
"git.golem15.com/golem15/summercms/modules/cabana"
|
|
"git.golem15.com/golem15/summercms/modules/compass"
|
|
"git.golem15.com/golem15/summercms/modules/party"
|
|
)
|
|
|
|
func ExampleCompileList() {
|
|
// The plugin embeds its controllers/ and models/ trees; the example reads
|
|
// the same files from testdata.
|
|
fsys := os.DirFS("testdata/docs")
|
|
list, err := cabana.CompileList("acme.blog", PostsController{}, fsys)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(list.Title, list.RecordsPerPage, list.PerPageOptions, list.ToolbarButtons)
|
|
for _, c := range list.Columns {
|
|
fmt.Printf("column %s type=%q searchable=%v sortable=%v\n", c.Key, c.Type, c.Searchable, c.Sortable)
|
|
}
|
|
for _, f := range list.Filters {
|
|
fmt.Printf("filter %s type=%s column=%s\n", f.Name, f.Type, f.Column)
|
|
}
|
|
// Output:
|
|
// acme.blog::lang.posts.title 20 [20 50 100] [create delete]
|
|
// column title type="" searchable=true sortable=true
|
|
// column published type="switch" searchable=false sortable=true
|
|
// column published_at type="datetime" searchable=false sortable=true
|
|
// filter published type=switch column=published
|
|
// filter published_at type=daterange column=published_at
|
|
}
|
|
|
|
func ExampleCompileForm() {
|
|
fsys := os.DirFS("testdata/docs")
|
|
form, err := cabana.CompileForm("acme.blog", PostsController{}, fsys)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
for _, f := range form.Fields {
|
|
fmt.Printf("%s %s span=%q tab=%q required=%v options=%d\n", f.Name, f.Type, f.Span, f.Tab, f.Required, len(f.Options))
|
|
}
|
|
// Output:
|
|
// title text span="left" tab="" required=true options=0
|
|
// slug text span="right" tab="" required=false options=0
|
|
// status dropdown span="left" tab="" required=false options=2
|
|
// published switch span="right" tab="" required=false options=0
|
|
// content textarea span="" tab="acme.blog::lang.posts.tab_content" required=false options=0
|
|
}
|
|
|
|
func ExampleActivate() {
|
|
cfg, err := compass.Open(compass.Options{Dir: "config", Env: "development", Environ: []string{}})
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
// Set through SUMMER_ADMIN__JWT__SECRET in a real deployment.
|
|
_ = cfg.Set("admin.jwt.secret", "test-only-secret-with-at-least-32-bytes")
|
|
_ = cfg.Set("backend.uri", "/admin")
|
|
|
|
routes, err := cabana.Activate(backpack.New(cfg), []party.Plugin{&BlogPlugin{}})
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(routes.Prefix)
|
|
|
|
editor := &bouncer.Principal{ID: 7, Backend: true, PermissionGrants: map[string]bool{"acme.blog.*": true}}
|
|
fmt.Println(cabana.Allows(editor, PostsController{}.RequiredPermissions()))
|
|
fmt.Println(cabana.Allows(editor, []string{"acme.shop.access_orders"}))
|
|
// Output:
|
|
// /admin
|
|
// true
|
|
// false
|
|
}
|
|
|
|
// TestDocsDeclarations checks the plugin declarations the Backend pages show.
|
|
func TestDocsDeclarations(t *testing.T) {
|
|
p := &BlogPlugin{}
|
|
if n := len(p.Permissions()); n != 2 {
|
|
t.Fatalf("Permissions() = %d entries", n)
|
|
}
|
|
if nav := p.Navigation(); len(nav) != 1 || nav[0].Controller != "acme.blog.posts" {
|
|
t.Fatalf("Navigation() = %+v", nav)
|
|
}
|
|
settings := p.Settings()
|
|
if len(settings) != 1 {
|
|
t.Fatalf("Settings() = %+v", settings)
|
|
}
|
|
if _, ok := settings[0].NewModel().(*BlogSettings); !ok {
|
|
t.Fatal("settings model is not *BlogSettings")
|
|
}
|
|
if rule := (BlogSettings{}).Rules()["posts_per_page"]; rule == "" {
|
|
t.Fatal("BlogSettings has no posts_per_page rule")
|
|
}
|
|
}
|