Select Git revision
field_test.go 7.87 KiB
package references
import (
"context"
"encoding/json"
"fmt"
"testing"
"git.perx.ru/perxis/perxis-go/pkg/items"
"git.perx.ru/perxis/perxis-go/pkg/items/mocks"
"git.perx.ru/perxis/perxis-go/pkg/schema"
"git.perx.ru/perxis/perxis-go/pkg/schema/field"
"git.perx.ru/perxis/perxis-go/pkg/schema/validate"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestReferenceField_Decode(t *testing.T) {
tests := []struct {
name string
field *field.Field
data interface{}
want interface{}
wantErr bool
}{
{
"Correct",
Field(nil),
map[string]interface{}{"collection_id": "media", "id": "11111111"},
&Reference{ID: "11111111", CollectionID: "media"},
false,
},
{
"Invalid CollectionID",
Field(nil),
map[string]interface{}{"collection_id": "media", "id": 11111111},
"decode error: ReferenceField decode error: field \"id\" required",
true,
},
{
"Extra Field",
Field(nil),
map[string]interface{}{"collection_id": "media", "id": "11111111", "extra": true},
&Reference{ID: "11111111", CollectionID: "media"},
false,
},
{
"Enabled",
Field(nil),
map[string]interface{}{"collection_id": "media", "id": "11111111", "disabled": true},
&Reference{ID: "11111111", CollectionID: "media", Disabled: true},
false,
},
{
"Disabled",
Field(nil),
map[string]interface{}{"collection_id": "media", "id": "11111111", "disabled": false},
&Reference{ID: "11111111", CollectionID: "media", Disabled: false},
false,
},
{
"Disabled wrong type",
Field(nil),
map[string]interface{}{"collection_id": "media", "id": "11111111", "disabled": 3},
&Reference{ID: "11111111", CollectionID: "media", Disabled: false},
false,
},
{
"Missing Field",
Field(nil),
map[string]interface{}{"id": "11111111"},
"decode error: ReferenceField decode error: field \"collection_id\" required",
true,
},
{
"Invalid type",
Field(nil),
"string",
"decode error: ReferenceField decode error: incorrect type: \"string\", expected \"map[string]interface{}\"",
true,
},
{
"Invalid element type",
Field(nil),
[]interface{}{"string"},
"decode error: ReferenceField decode error: incorrect type: \"slice\", expected \"map[string]interface{}\"",
true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := schema.Decode(nil, tt.field, tt.data)
if tt.wantErr {
require.Error(t, err)
assert.EqualError(t, err, tt.want.(string), fmt.Sprintf("Decode() error = %v, want %v", err, tt.want.(string)))
}
if !tt.wantErr {
require.NoError(t, err)
assert.Equal(t, got, tt.want, fmt.Sprintf("Decode() got = %v, want %v", got, tt.want))
}
})
}
}
func TestReferenceField_Encode(t *testing.T) {
tests := []struct {
name string
field *field.Field
data interface{}
want interface{}
wantErr bool
}{
{
"Correct",
Field(nil),
&Reference{ID: "11111111", CollectionID: "media"},
map[string]interface{}{"collection_id": "media", "id": "11111111", "disabled": false},
false,
},
{
"Enabled",
Field(nil),
&Reference{ID: "11111111", CollectionID: "media", Disabled: true},
map[string]interface{}{"collection_id": "media", "id": "11111111", "disabled": true},
false,
},
{
"Disabled",
Field(nil),
&Reference{ID: "11111111", CollectionID: "media", Disabled: false},
map[string]interface{}{"collection_id": "media", "id": "11111111", "disabled": false},
false,
},
{
"From Map",
Field(nil),
map[string]interface{}{"id": "11111111", "collection_id": "media"},
"encode error: ReferenceField encode error: incorrect type: \"map\", expected \"*Reference\"",
true,
},
{
"Invalid type",
Field(nil),
"string",
"encode error: ReferenceField encode error: incorrect type: \"string\", expected \"*Reference\"",
true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := schema.Encode(nil, tt.field, tt.data)
if tt.wantErr {
require.Error(t, err)
assert.EqualError(t, err, tt.want.(string), fmt.Sprintf("Encode() error = %v, want %v", err, tt.want.(string)))
}
if !tt.wantErr {
require.NoError(t, err)
assert.Equal(t, got, tt.want, fmt.Sprintf("Encode() got = %v, want %v", got, tt.want))
}
})
}
}
func TestReferenceField_PreSave(t *testing.T) {
ctx := context.Background()
rt := NewReferenceType()
t.Run("Nil Value", func(t *testing.T) {
svc := &mocks.Items{}
itemCtx := &items.Context{Items: svc, SpaceID: "sp", EnvID: "env"}
f := Field(nil)
_, _, err := rt.PreSave(ctx, f, nil, itemCtx)
require.NoError(t, err)
svc.AssertExpectations(t)
})
t.Run("Nil Context", func(t *testing.T) {
svc := &mocks.Items{}
f := Field(nil)
ref := &Reference{
ID: "111", CollectionID: "media",
}
_, _, err := rt.PreSave(ctx, f, ref, nil)
require.NoError(t, err)
svc.AssertExpectations(t)
})
t.Run("Referenced Items Exist", func(t *testing.T) {
t.Run("Correct", func(t *testing.T) {
svc := &mocks.Items{}
itemCtx := &items.Context{Items: svc, SpaceID: "sp", EnvID: "env"}
f := Field(nil)
ref := &Reference{
ID: "111", CollectionID: "media",
}
_, _, err := rt.PreSave(ctx, f, ref, itemCtx)
require.NoError(t, err)
svc.AssertExpectations(t)
})
t.Run("Item Not Found", func(t *testing.T) {
svc := &mocks.Items{}
itemCtx := &items.Context{Items: svc, SpaceID: "sp", EnvID: "env"}
f := Field(nil)
ref := &Reference{
ID: "111", CollectionID: "media",
}
_, _, err := rt.PreSave(ctx, f, ref, itemCtx)
require.NoError(t, err)
svc.AssertExpectations(t)
})
})
t.Run("Allowed Types", func(t *testing.T) {
t.Run("Correct", func(t *testing.T) {
svc := &mocks.Items{}
itemCtx := &items.Context{Items: svc, SpaceID: "sp", EnvID: "env"}
f := Field([]string{"media"})
ref := &Reference{
ID: "111", CollectionID: "media",
}
_, _, err := rt.PreSave(ctx, f, ref, itemCtx)
require.NoError(t, err)
svc.AssertExpectations(t)
})
t.Run("Not Allowed", func(t *testing.T) {
svc := &mocks.Items{}
f := Field([]string{"cars", "motorbikes"})
itemCtx := &items.Context{Items: svc, SpaceID: "sp", EnvID: "env"}
ref := &Reference{
ID: "111", CollectionID: "media",
}
_, _, err := rt.PreSave(ctx, f, ref, itemCtx)
require.Error(t, err)
assert.Equal(t, "usage of collection \"media\" not allowed", err.Error())
svc.AssertExpectations(t)
})
})
}
func TestReferenceField_Validate(t *testing.T) {
rt := NewReferenceType()
field.Register(rt)
t.Run("Max Elements", func(t *testing.T) {
t.Run("Correct", func(t *testing.T) {
f := Field(nil, validate.MaxItems(1))
refs := []*Reference{
{ID: "111", CollectionID: "media"},
}
err := validate.Validate(nil, f, refs)
require.NoError(t, err)
})
t.Run("Limit exceeded", func(t *testing.T) {
f := Field(nil, validate.MaxItems(1))
refs := []*Reference{
{ID: "111", CollectionID: "media"},
{ID: "222", CollectionID: "media"},
}
err := validate.Validate(nil, f, refs)
require.Error(t, err)
require.Contains(t, err.Error(), "validation error: maximum elements number is 1")
})
})
t.Run("Required", func(t *testing.T) {
t.Run("Correct", func(t *testing.T) {
f := Field(nil, validate.Required())
ref := &Reference{ID: "111", CollectionID: "media"}
err := validate.Validate(nil, f, ref)
require.NoError(t, err)
})
t.Run("Empty", func(t *testing.T) {
f := Field(nil, validate.Required())
ref := &Reference{}
err := validate.Validate(nil, f, ref)
require.Error(t, err)
require.Contains(t, err.Error(), "validation error: value is required")
})
})
}
func TestReference_JSON(t *testing.T) {
fld := Field([]string{"col1"}).AddOptions(validate.MaxItems(2))
b, err := json.MarshalIndent(fld, "", " ")
require.NoError(t, err)
res := field.NewField(nil)
err = json.Unmarshal(b, res)
require.NoError(t, err)
assert.Equal(t, fld, res)
}