Files
sm-user-plugin/models/permission_set_test.go
Jakub Zych 493a3ff47c test: unit tests for the admin class functions, the models and the admin registration
- classes: every admin action for its changed-row count and idempotency, the ban across several throttle rows, the cleanup of a permanent delete
- classes: the privileged list and IsPrivilegedMember (D-30), also through a handle that carries conditions
- classes: the five-minute boundary of last_seen
- models: PermissionSet round trip, the slug table shared with the SPA, Fillable and Rules, fields that never marshal, the group filter value
- TestAdminRegistration: permissions, navigation, embedded files and phrase keys in en and pl; the admin secret is required
2026-10-05 15:15:28 +02:00

91 lines
3.5 KiB
Go

package models
import (
"reflect"
"testing"
)
// TestPermissionSetRoundTrip: what Value writes, Scan and ParsePermissionSet
// read back unchanged; Text is the same text for a plain string column.
func TestPermissionSetRoundTrip(t *testing.T) {
for _, tc := range []struct {
name string
set PermissionSet
text string // "" stands for NULL
back PermissionSet
}{
{"allow and deny", PermissionSet{"blog.post": 1, "blog.edit": -1}, `{"blog.edit":-1,"blog.post":1}`, PermissionSet{"blog.post": 1, "blog.edit": -1}},
{"a zero is not stored", PermissionSet{"blog.post": 1, "blog.zero": 0}, `{"blog.post":1}`, PermissionSet{"blog.post": 1}},
{"a wildcard code", PermissionSet{"blog.*": 1}, `{"blog.*":1}`, PermissionSet{"blog.*": 1}},
{"an empty set", PermissionSet{}, "", PermissionSet{}},
{"a nil set", nil, "", PermissionSet{}},
{"only zeros", PermissionSet{"blog.zero": 0}, "", PermissionSet{}},
} {
t.Run(tc.name, func(t *testing.T) {
value, err := tc.set.Value()
if err != nil {
t.Fatal(err)
}
text := tc.set.Text()
if tc.text == "" {
if value != nil || text != nil {
t.Fatalf("Value = %#v, Text = %v, want NULL", value, text)
}
} else if value != tc.text || text == nil || *text != tc.text {
t.Fatalf("Value = %#v, Text = %v, want %s", value, text, tc.text)
}
var scanned PermissionSet
if err := scanned.Scan(value); err != nil || !reflect.DeepEqual(scanned, tc.back) {
t.Fatalf("Scan(Value) = %v %v, want %v", scanned, err, tc.back)
}
parsed, err := ParsePermissionSet([]byte(tc.text))
if err != nil || !reflect.DeepEqual(parsed, tc.back) {
t.Fatalf("ParsePermissionSet(%q) = %v %v, want %v", tc.text, parsed, err, tc.back)
}
})
}
if got := (PermissionSet{}).GormDataType(); got != "text" {
t.Fatalf("GormDataType = %q", got)
}
}
// TestParsePermissionSet: the tolerant read of what PHP may have stored, and
// the error for content that is not a JSON object.
func TestParsePermissionSet(t *testing.T) {
for raw, want := range map[string]PermissionSet{
"": {},
" ": {},
"[]": {},
"null": {},
" {} ": {},
`{"a":1,"b":"1","c":" -1 "}`: {"a": 1, "b": 1, "c": -1},
// Values that are not integers are skipped, never read as granted.
`{"a":true,"b":"yes","c":1.5,"d":null,"e":[1],"f":{"x":1},"g":1}`: {"g": 1},
`{"big":99999999999999999999}`: {},
} {
got, err := ParsePermissionSet([]byte(raw))
if err != nil || got == nil || !reflect.DeepEqual(got, want) {
t.Errorf("ParsePermissionSet(%q) = %v %v, want %v", raw, got, err, want)
}
}
for _, raw := range []string{`{"a":1`, `["a"]`, `1`, `"a"`, `true`, `{"a":1}{"b":1}`, `{"a":1} x`} {
if got, err := ParsePermissionSet([]byte(raw)); err == nil {
t.Errorf("ParsePermissionSet(%q) = %v, want an error", raw, got)
}
}
// Scan keeps the previous value on an error and takes text or bytes.
set := PermissionSet{"kept": 1}
if err := set.Scan(`["a"]`); err == nil || !reflect.DeepEqual(set, PermissionSet{"kept": 1}) {
t.Fatalf("a failed Scan changed the set: %v %v", set, err)
}
if err := set.Scan([]byte(`{"a":-1}`)); err != nil || !reflect.DeepEqual(set, PermissionSet{"a": -1}) {
t.Fatalf("Scan(bytes) = %v %v", set, err)
}
if err := set.Scan(nil); err != nil || set == nil || len(set) != 0 {
t.Fatalf("Scan(nil) = %#v %v", set, err)
}
if err := set.Scan(3.5); err == nil {
t.Fatal("Scan accepted a float")
}
}