test(09-12): add the phase 9 security matrix

- Guard isolation covers audience, secret, refresh, blacklist, and reset cutoff.
- The mounted admin route table must carry the backend guard.
- Fresh PostgreSQL migrate and rollback keep framework and plugin histories apart.
This commit is contained in:
Jakub Zych
2026-09-27 03:01:54 +02:00
parent 2efe51a168
commit 30bfd2d8d5
3 changed files with 513 additions and 0 deletions

View File

@@ -12,6 +12,77 @@ import (
"gorm.io/gorm"
)
func TestPhase09MigrationsFreshRollback(t *testing.T) {
assertNoAutoMigrate(t)
db, _ := dedicatedDB(t, "phase09_fresh")
gdb, err := Use(t.Context(), db)
if err != nil {
t.Fatal(err)
}
plugin := migPlugin{
id: "demo.keep",
migrations: []*gormigrate.Migration{{
ID: "202609240010_keep",
Migrate: func(tx *gorm.DB) error {
return tx.Exec(`CREATE TABLE phase09_keep (id BIGSERIAL PRIMARY KEY)`).Error
},
Rollback: func(tx *gorm.DB) error {
return tx.Exec(`DROP TABLE IF EXISTS phase09_keep`).Error
},
}},
}
if err := Migrate(gdb, []party.Plugin{plugin}); err != nil {
t.Fatal(err)
}
if !gdb.Migrator().HasTable("system_files") || !gdb.Migrator().HasTable("backend_users") || !gdb.Migrator().HasTable("phase09_keep") {
t.Fatal("fresh migrate did not keep framework, admin, and plugin tables together")
}
before := systemRoles(t, gdb)
if len(before) != 2 {
t.Fatalf("seeded roles = %v", before)
}
if err := Migrate(gdb, []party.Plugin{plugin}); err != nil {
t.Fatalf("repeated migrate: %v", err)
}
if after := systemRoles(t, gdb); len(after) != 2 || after["developer"].id != before["developer"].id || after["publisher"].id != before["publisher"].id {
t.Fatalf("roles changed on repeat: before=%v after=%v", before, after)
}
admin, err := migrator(gdb, "summercms.cabana", BackendAdminMigrations)
if err != nil {
t.Fatal(err)
}
if err := admin.RollbackLast(); err != nil {
t.Fatal(err)
}
for _, name := range []string{"backend_users", "backend_user_roles", "backend_jwt_blacklist"} {
if gdb.Migrator().HasTable(name) {
t.Fatalf("%s survived admin rollback", name)
}
}
if !gdb.Migrator().HasTable("system_files") || !gdb.Migrator().HasTable("phase09_keep") {
t.Fatal("admin rollback removed a framework or plugin table")
}
var attachIDs, pluginIDs []string
if err := gdb.Table("summer_migrations_summercms_attach").Pluck("id", &attachIDs).Error; err != nil {
t.Fatal(err)
}
if err := gdb.Table("summer_migrations_demo_keep").Pluck("id", &pluginIDs).Error; err != nil {
t.Fatal(err)
}
if strings.Join(attachIDs, ",") == "" || strings.Join(pluginIDs, ",") != "202609240010_keep" {
t.Fatalf("histories attach=%v plugin=%v", attachIDs, pluginIDs)
}
if err := Migrate(gdb, []party.Plugin{plugin}); err != nil {
t.Fatalf("migrate after rollback: %v", err)
}
if !gdb.Migrator().HasTable("backend_users") {
t.Fatal("admin tables were not recreated")
}
if again := systemRoles(t, gdb); len(again) != 2 {
t.Fatalf("roles after recreate = %v", again)
}
}
func TestBackendAdminMigration(t *testing.T) {
assertNoAutoMigrate(t)
db, _ := dedicatedDB(t, "lagoon_admin_mig")