Files
RenewCMS/test/role_repository_gaps_test.go
T

135 lines
4.4 KiB
Go

package test
import (
"RenewCMS/internal/domain/role"
"RenewCMS/internal/infrastructure/persistence/database"
"RenewCMS/internal/infrastructure/persistence/models"
persistence "RenewCMS/internal/infrastructure/persistence/repositories"
"errors"
"testing"
)
func TestRoleRepositoryFailures(t *testing.T) {
broken := func(t *testing.T, table string) *persistence.RoleRepository {
t.Helper()
db := openMigratedRolesDB(t)
if err := db.Migrator().DropTable(table); err != nil {
t.Fatal(err)
}
return persistence.NewRoleRepository(db)
}
t.Run("List fails when the roles table is missing", func(t *testing.T) {
if _, err := broken(t, "roles").List(); err == nil {
t.Error("expected error")
}
})
t.Run("Get distinguishes a missing role from a storage failure", func(t *testing.T) {
repo := persistence.NewRoleRepository(openMigratedRolesDB(t))
if _, err := repo.Get(9999); !errors.Is(err, role.ErrRoleNotFound) {
t.Errorf("want ErrRoleNotFound, got %v", err)
}
if _, err := broken(t, "roles").Get(1); err == nil || errors.Is(err, role.ErrRoleNotFound) {
t.Errorf("want storage error, got %v", err)
}
})
t.Run("GetByName reports a missing role", func(t *testing.T) {
repo := persistence.NewRoleRepository(openMigratedRolesDB(t))
if _, err := repo.GetByName("Nobody"); !errors.Is(err, role.ErrRoleNotFound) {
t.Errorf("want ErrRoleNotFound, got %v", err)
}
})
t.Run("List and role loading fail when grants cannot be read", func(t *testing.T) {
repo := broken(t, "role_permissions")
if _, err := repo.List(); err == nil {
t.Error("List: expected error")
}
if _, err := repo.Get(1); err == nil {
t.Error("Get: expected error")
}
})
t.Run("Create persists grants and returns them", func(t *testing.T) {
db := openMigratedRolesDB(t)
repo := persistence.NewRoleRepository(db)
created, err := repo.Create(role.Role{Name: "Contributor", Version: 1, Grants: []role.Grant{{Key: "content.read", Scope: role.ScopeAll}}})
if err != nil {
t.Fatal(err)
}
if len(created.Grants) != 1 || created.Grants[0].Key != "content.read" {
t.Errorf("returned grants: %+v", created.Grants)
}
if countRows(t, db, &models.RolePermission{}) != 73 {
t.Errorf("grant rows not stored")
}
})
t.Run("Create rolls back when the grants cannot be stored", func(t *testing.T) {
db := openMigratedRolesDB(t)
if err := db.Migrator().DropTable("role_permissions"); err != nil {
t.Fatal(err)
}
repo := persistence.NewRoleRepository(db)
before := countRows(t, db, &models.Role{})
_, err := repo.Create(role.Role{Name: "Contributor", Version: 1, Grants: []role.Grant{{Key: "content.read", Scope: role.ScopeAll}}})
if err == nil {
t.Fatal("expected error")
}
if countRows(t, db, &models.Role{}) != before {
t.Errorf("role row not rolled back")
}
})
t.Run("Create fails when the roles table is missing", func(t *testing.T) {
if _, err := broken(t, "roles").Create(role.Role{Name: "X", Version: 1}); err == nil {
t.Error("expected error")
}
})
t.Run("Save returns the stored role with its new grants", func(t *testing.T) {
db := openMigratedRolesDB(t)
repo := persistence.NewRoleRepository(db)
writer := storedRole(t, db, "Writer")
writer.Grants = []role.Grant{{Key: "media.delete", Scope: role.ScopeOwn}}
saved, err := repo.Save(writer)
if err != nil {
t.Fatal(err)
}
if saved.ID != writer.ID || len(saved.Grants) != 1 || saved.Grants[0].Key != "media.delete" {
t.Errorf("saved: %+v", saved)
}
})
t.Run("Save reports a missing role and storage failures", func(t *testing.T) {
repo := persistence.NewRoleRepository(openMigratedRolesDB(t))
if _, err := repo.Save(role.Role{ID: 9999, Name: "Ghost", Version: 1}); !errors.Is(err, role.ErrRoleNotFound) {
t.Errorf("want ErrRoleNotFound, got %v", err)
}
db := openMigratedRolesDB(t)
writer := storedRole(t, db, "Writer")
if err := db.Migrator().DropTable("role_permissions"); err != nil {
t.Fatal(err)
}
if _, err := persistence.NewRoleRepository(db).Save(writer); err == nil {
t.Error("expected storage error")
}
})
}
func TestBackfillUserRoleIDsWithoutBuiltInRoles(t *testing.T) {
db := openUnmigratedSQLite(t)
if err := db.AutoMigrate(&models.Role{}, &models.RolePermission{}, &models.User{}); err != nil {
t.Fatal(err)
}
createUserRow(t, db, 1, "owner", nil)
if err := database.BackfillUserRoleIDs(db); err != nil {
t.Fatal(err)
}
if userRow(t, db, 1).RoleID != nil {
t.Errorf("role_id must stay unset when no built-in role exists")
}
}