feat(11.1-05): add the acme.blog walkthrough plugin with its model, migration and posts route

- docs/examples/blog: scaffolder output for acme.blog (make:plugin, make:model)
  in the root module, with a Post model, a fill allow-list and NewPost, the
  create migration and GET /api/blog/posts paginated through lagoon
- short tests activate the plugin, check the route with surf, the fill
  allow-list and the migration order
- docs/setup/porting-a-plugin.md: registration, model, migrations and routes
  sections with src= copies of the plugin
- TestDocsRequiredPages requires setup/porting-a-plugin
This commit is contained in:
Jakub Zych
2026-09-30 23:28:41 +02:00
parent 4e83d06025
commit 41a3190956
20 changed files with 798 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
package updates_test
import (
"os"
"regexp"
"slices"
"strings"
"testing"
"git.golem15.com/golem15/summercms/docs/examples/blog"
"git.golem15.com/golem15/summercms/docs/examples/blog/updates"
)
var migrationFile = regexp.MustCompile(`^(\d{14})_[a-z0-9_]+\.go$`)
func TestMigrationIDs(t *testing.T) {
if got := updates.CreatePosts().ID; got != "20260101000000_create_acme_blog_posts" {
t.Errorf("CreatePosts ID = %q", got)
}
// The plugin returns the set in registry.gen.go's order, which must be
// ascending by ID: gormigrate applies it in slice order.
var ids []string
for _, m := range (&blog.Plugin{}).Migrations() {
if m.Migrate == nil || m.Rollback == nil {
t.Errorf("migration %s has no Migrate or Rollback", m.ID)
}
ids = append(ids, m.ID)
}
if len(ids) == 0 {
t.Fatal("the plugin has no migrations")
}
if !slices.IsSorted(ids) {
t.Errorf("migration IDs are not in ascending order: %v", ids)
}
// Every migration file is named after its ID, and every ID has a file.
entries, err := os.ReadDir(".")
if err != nil {
t.Fatal(err)
}
var files []string
for _, e := range entries {
name := e.Name()
if e.IsDir() || name == "doc.go" || strings.HasSuffix(name, "_test.go") || !strings.HasSuffix(name, ".go") {
continue
}
if !migrationFile.MatchString(name) {
t.Errorf("%s does not start with a 14-digit timestamp", name)
continue
}
files = append(files, strings.TrimSuffix(name, ".go"))
}
if !slices.Equal(files, ids) {
t.Errorf("migration files %v, want one per ID %v", files, ids)
}
}