You've already forked pocketbase
mirror of
https://github.com/pocketbase/pocketbase.git
synced 2025-12-07 18:42:43 +02:00
initial v0.8 pre-release
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
package models_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
||||
"github.com/pocketbase/pocketbase/models"
|
||||
"github.com/pocketbase/pocketbase/tools/list"
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
)
|
||||
|
||||
func TestCollectionTableName(t *testing.T) {
|
||||
@@ -23,3 +27,370 @@ func TestCollectionBaseFilesPath(t *testing.T) {
|
||||
t.Fatalf("Expected path %s, got %s", expected, m.BaseFilesPath())
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectionIsBase(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
collection models.Collection
|
||||
expected bool
|
||||
}{
|
||||
{models.Collection{}, false},
|
||||
{models.Collection{Type: "unknown"}, false},
|
||||
{models.Collection{Type: models.CollectionTypeBase}, true},
|
||||
{models.Collection{Type: models.CollectionTypeAuth}, false},
|
||||
}
|
||||
|
||||
for i, s := range scenarios {
|
||||
result := s.collection.IsBase()
|
||||
if result != s.expected {
|
||||
t.Errorf("(%d) Expected %v, got %v", i, s.expected, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectionIsAuth(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
collection models.Collection
|
||||
expected bool
|
||||
}{
|
||||
{models.Collection{}, false},
|
||||
{models.Collection{Type: "unknown"}, false},
|
||||
{models.Collection{Type: models.CollectionTypeBase}, false},
|
||||
{models.Collection{Type: models.CollectionTypeAuth}, true},
|
||||
}
|
||||
|
||||
for i, s := range scenarios {
|
||||
result := s.collection.IsAuth()
|
||||
if result != s.expected {
|
||||
t.Errorf("(%d) Expected %v, got %v", i, s.expected, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectionMarshalJSON(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
name string
|
||||
collection models.Collection
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
"no type",
|
||||
models.Collection{Name: "test"},
|
||||
`{"id":"","created":"","updated":"","name":"test","type":"","system":false,"schema":[],"listRule":null,"viewRule":null,"createRule":null,"updateRule":null,"deleteRule":null,"options":{}}`,
|
||||
},
|
||||
{
|
||||
"unknown type + non empty options",
|
||||
models.Collection{Name: "test", Type: "unknown", ListRule: types.Pointer("test_list"), Options: types.JsonMap{"test": 123}},
|
||||
`{"id":"","created":"","updated":"","name":"test","type":"unknown","system":false,"schema":[],"listRule":"test_list","viewRule":null,"createRule":null,"updateRule":null,"deleteRule":null,"options":{}}`,
|
||||
},
|
||||
{
|
||||
"base type + non empty options",
|
||||
models.Collection{Name: "test", Type: models.CollectionTypeBase, ListRule: types.Pointer("test_list"), Options: types.JsonMap{"test": 123}},
|
||||
`{"id":"","created":"","updated":"","name":"test","type":"base","system":false,"schema":[],"listRule":"test_list","viewRule":null,"createRule":null,"updateRule":null,"deleteRule":null,"options":{}}`,
|
||||
},
|
||||
{
|
||||
"auth type + non empty options",
|
||||
models.Collection{BaseModel: models.BaseModel{Id: "test"}, Type: models.CollectionTypeAuth, Options: types.JsonMap{"test": 123, "allowOAuth2Auth": true, "minPasswordLength": 4}},
|
||||
`{"id":"test","created":"","updated":"","name":"","type":"auth","system":false,"schema":[],"listRule":null,"viewRule":null,"createRule":null,"updateRule":null,"deleteRule":null,"options":{"allowEmailAuth":false,"allowOAuth2Auth":true,"allowUsernameAuth":false,"exceptEmailDomains":null,"manageRule":null,"minPasswordLength":4,"onlyEmailDomains":null,"requireEmail":false}}`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
result, err := s.collection.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Errorf("(%s) Unexpected error %v", s.name, err)
|
||||
continue
|
||||
}
|
||||
if string(result) != s.expected {
|
||||
t.Errorf("(%s) Expected\n%v \ngot \n%v", s.name, s.expected, string(result))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectionBaseOptions(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
name string
|
||||
collection models.Collection
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
"no type",
|
||||
models.Collection{Options: types.JsonMap{"test": 123}},
|
||||
"{}",
|
||||
},
|
||||
{
|
||||
"unknown type",
|
||||
models.Collection{Type: "anything", Options: types.JsonMap{"test": 123}},
|
||||
"{}",
|
||||
},
|
||||
{
|
||||
"different type",
|
||||
models.Collection{Type: models.CollectionTypeAuth, Options: types.JsonMap{"test": 123, "minPasswordLength": 4}},
|
||||
"{}",
|
||||
},
|
||||
{
|
||||
"base type",
|
||||
models.Collection{Type: models.CollectionTypeBase, Options: types.JsonMap{"test": 123}},
|
||||
"{}",
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
result := s.collection.BaseOptions()
|
||||
|
||||
encoded, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if strEncoded := string(encoded); strEncoded != s.expected {
|
||||
t.Errorf("(%s) Expected \n%v \ngot \n%v", s.name, s.expected, strEncoded)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectionAuthOptions(t *testing.T) {
|
||||
options := types.JsonMap{"test": 123, "minPasswordLength": 4}
|
||||
expectedSerialization := `{"manageRule":null,"allowOAuth2Auth":false,"allowUsernameAuth":false,"allowEmailAuth":false,"requireEmail":false,"exceptEmailDomains":null,"onlyEmailDomains":null,"minPasswordLength":4}`
|
||||
|
||||
scenarios := []struct {
|
||||
name string
|
||||
collection models.Collection
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
"no type",
|
||||
models.Collection{Options: options},
|
||||
expectedSerialization,
|
||||
},
|
||||
{
|
||||
"unknown type",
|
||||
models.Collection{Type: "anything", Options: options},
|
||||
expectedSerialization,
|
||||
},
|
||||
{
|
||||
"different type",
|
||||
models.Collection{Type: models.CollectionTypeBase, Options: options},
|
||||
expectedSerialization,
|
||||
},
|
||||
{
|
||||
"auth type",
|
||||
models.Collection{Type: models.CollectionTypeAuth, Options: options},
|
||||
expectedSerialization,
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
result := s.collection.AuthOptions()
|
||||
|
||||
encoded, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if strEncoded := string(encoded); strEncoded != s.expected {
|
||||
t.Errorf("(%s) Expected \n%v \ngot \n%v", s.name, s.expected, strEncoded)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizeOptions(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
name string
|
||||
collection models.Collection
|
||||
expected string // serialized options
|
||||
}{
|
||||
{
|
||||
"unknown type",
|
||||
models.Collection{Type: "unknown", Options: types.JsonMap{"test": 123, "minPasswordLength": 4}},
|
||||
"{}",
|
||||
},
|
||||
{
|
||||
"base type",
|
||||
models.Collection{Type: models.CollectionTypeBase, Options: types.JsonMap{"test": 123, "minPasswordLength": 4}},
|
||||
"{}",
|
||||
},
|
||||
{
|
||||
"auth type",
|
||||
models.Collection{Type: models.CollectionTypeAuth, Options: types.JsonMap{"test": 123, "minPasswordLength": 4}},
|
||||
`{"allowEmailAuth":false,"allowOAuth2Auth":false,"allowUsernameAuth":false,"exceptEmailDomains":null,"manageRule":null,"minPasswordLength":4,"onlyEmailDomains":null,"requireEmail":false}`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
if err := s.collection.NormalizeOptions(); err != nil {
|
||||
t.Errorf("(%s) Unexpected error %v", s.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
encoded, err := json.Marshal(s.collection.Options)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if strEncoded := string(encoded); strEncoded != s.expected {
|
||||
t.Errorf("(%s) Expected \n%v \ngot \n%v", s.name, s.expected, strEncoded)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeOptions(t *testing.T) {
|
||||
m := models.Collection{
|
||||
Options: types.JsonMap{"test": 123},
|
||||
}
|
||||
|
||||
result := struct {
|
||||
Test int
|
||||
}{}
|
||||
|
||||
if err := m.DecodeOptions(&result); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if result.Test != 123 {
|
||||
t.Fatalf("Expected %v, got %v", 123, result.Test)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetOptions(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
name string
|
||||
collection models.Collection
|
||||
options any
|
||||
expected string // serialized options
|
||||
}{
|
||||
{
|
||||
"no type",
|
||||
models.Collection{},
|
||||
map[string]any{},
|
||||
"{}",
|
||||
},
|
||||
{
|
||||
"unknown type + non empty options",
|
||||
models.Collection{Type: "unknown", Options: types.JsonMap{"test": 123}},
|
||||
map[string]any{"test": 456, "minPasswordLength": 4},
|
||||
"{}",
|
||||
},
|
||||
{
|
||||
"base type",
|
||||
models.Collection{Type: models.CollectionTypeBase, Options: types.JsonMap{"test": 123}},
|
||||
map[string]any{"test": 456, "minPasswordLength": 4},
|
||||
"{}",
|
||||
},
|
||||
{
|
||||
"auth type",
|
||||
models.Collection{Type: models.CollectionTypeAuth, Options: types.JsonMap{"test": 123}},
|
||||
map[string]any{"test": 456, "minPasswordLength": 4},
|
||||
`{"allowEmailAuth":false,"allowOAuth2Auth":false,"allowUsernameAuth":false,"exceptEmailDomains":null,"manageRule":null,"minPasswordLength":4,"onlyEmailDomains":null,"requireEmail":false}`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
if err := s.collection.SetOptions(s.options); err != nil {
|
||||
t.Errorf("(%s) Unexpected error %v", s.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
encoded, err := json.Marshal(s.collection.Options)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if strEncoded := string(encoded); strEncoded != s.expected {
|
||||
t.Errorf("(%s) Expected \n%v \ngot \n%v", s.name, s.expected, strEncoded)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectionBaseOptionsValidate(t *testing.T) {
|
||||
opt := models.CollectionBaseOptions{}
|
||||
if err := opt.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectionAuthOptionsValidate(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
name string
|
||||
options models.CollectionAuthOptions
|
||||
expectedErrors []string
|
||||
}{
|
||||
{
|
||||
"empty",
|
||||
models.CollectionAuthOptions{},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"empty string ManageRule",
|
||||
models.CollectionAuthOptions{ManageRule: types.Pointer("")},
|
||||
[]string{"manageRule"},
|
||||
},
|
||||
{
|
||||
"minPasswordLength < 5",
|
||||
models.CollectionAuthOptions{MinPasswordLength: 3},
|
||||
[]string{"minPasswordLength"},
|
||||
},
|
||||
{
|
||||
"minPasswordLength > 72",
|
||||
models.CollectionAuthOptions{MinPasswordLength: 73},
|
||||
[]string{"minPasswordLength"},
|
||||
},
|
||||
{
|
||||
"both OnlyDomains and ExceptDomains set",
|
||||
models.CollectionAuthOptions{
|
||||
OnlyEmailDomains: []string{"example.com", "test.com"},
|
||||
ExceptEmailDomains: []string{"example.com", "test.com"},
|
||||
},
|
||||
[]string{"onlyEmailDomains", "exceptEmailDomains"},
|
||||
},
|
||||
{
|
||||
"only OnlyDomains set",
|
||||
models.CollectionAuthOptions{
|
||||
OnlyEmailDomains: []string{"example.com", "test.com"},
|
||||
},
|
||||
[]string{},
|
||||
},
|
||||
{
|
||||
"only ExceptEmailDomains set",
|
||||
models.CollectionAuthOptions{
|
||||
ExceptEmailDomains: []string{"example.com", "test.com"},
|
||||
},
|
||||
[]string{},
|
||||
},
|
||||
{
|
||||
"all fields with valid data",
|
||||
models.CollectionAuthOptions{
|
||||
ManageRule: types.Pointer("test"),
|
||||
AllowOAuth2Auth: true,
|
||||
AllowUsernameAuth: true,
|
||||
AllowEmailAuth: true,
|
||||
RequireEmail: true,
|
||||
ExceptEmailDomains: []string{"example.com", "test.com"},
|
||||
OnlyEmailDomains: nil,
|
||||
MinPasswordLength: 5,
|
||||
},
|
||||
[]string{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
result := s.options.Validate()
|
||||
|
||||
// parse errors
|
||||
errs, ok := result.(validation.Errors)
|
||||
if !ok && result != nil {
|
||||
t.Errorf("(%s) Failed to parse errors %v", s.name, result)
|
||||
continue
|
||||
}
|
||||
|
||||
if len(errs) != len(s.expectedErrors) {
|
||||
t.Errorf("(%s) Expected error keys %v, got errors \n%v", s.name, s.expectedErrors, result)
|
||||
continue
|
||||
}
|
||||
|
||||
for key := range errs {
|
||||
if !list.ExistInSlice(key, s.expectedErrors) {
|
||||
t.Errorf("(%s) Unexpected error key %q in \n%v", s.name, key, errs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user