2022-07-06 23:19:05 +02:00
|
|
|
package daos_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/pocketbase/pocketbase/daos"
|
|
|
|
"github.com/pocketbase/pocketbase/models"
|
2022-10-30 10:28:14 +02:00
|
|
|
"github.com/pocketbase/pocketbase/models/schema"
|
2022-07-06 23:19:05 +02:00
|
|
|
"github.com/pocketbase/pocketbase/tests"
|
|
|
|
"github.com/pocketbase/pocketbase/tools/list"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestExpandRecords(t *testing.T) {
|
|
|
|
app, _ := tests.NewTestApp()
|
|
|
|
defer app.Cleanup()
|
|
|
|
|
|
|
|
scenarios := []struct {
|
2022-10-30 10:28:14 +02:00
|
|
|
testName string
|
|
|
|
collectionIdOrName string
|
2022-07-19 12:09:54 +02:00
|
|
|
recordIds []string
|
|
|
|
expands []string
|
|
|
|
fetchFunc daos.ExpandFetchFunc
|
|
|
|
expectExpandProps int
|
2022-07-19 13:20:28 +02:00
|
|
|
expectExpandFailures int
|
2022-07-06 23:19:05 +02:00
|
|
|
}{
|
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"empty records",
|
|
|
|
"",
|
2022-07-06 23:19:05 +02:00
|
|
|
[]string{},
|
2022-10-30 10:28:14 +02:00
|
|
|
[]string{"self_rel_one", "self_rel_many.self_rel_one"},
|
2022-07-06 23:19:05 +02:00
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
2022-10-30 10:28:14 +02:00
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
0,
|
2022-07-19 12:09:54 +02:00
|
|
|
0,
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"empty expand",
|
|
|
|
"demo4",
|
|
|
|
[]string{"i9naidtvr6qsgb4", "qzaqccwrmva4o1n"},
|
2022-07-06 23:19:05 +02:00
|
|
|
[]string{},
|
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
2022-10-30 10:28:14 +02:00
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
0,
|
2022-07-19 12:09:54 +02:00
|
|
|
0,
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"empty fetchFunc",
|
|
|
|
"demo4",
|
|
|
|
[]string{"i9naidtvr6qsgb4", "qzaqccwrmva4o1n"},
|
|
|
|
[]string{"self_rel_one", "self_rel_many.self_rel_one"},
|
2022-07-06 23:19:05 +02:00
|
|
|
nil,
|
|
|
|
0,
|
2022-07-19 12:09:54 +02:00
|
|
|
2,
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"fetchFunc with error",
|
|
|
|
"demo4",
|
|
|
|
[]string{"i9naidtvr6qsgb4", "qzaqccwrmva4o1n"},
|
|
|
|
[]string{"self_rel_one", "self_rel_many.self_rel_one"},
|
2022-07-06 23:19:05 +02:00
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
|
|
|
return nil, errors.New("test error")
|
|
|
|
},
|
|
|
|
0,
|
2022-07-19 12:09:54 +02:00
|
|
|
2,
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"missing relation field",
|
|
|
|
"demo4",
|
|
|
|
[]string{"i9naidtvr6qsgb4", "qzaqccwrmva4o1n"},
|
|
|
|
[]string{"missing"},
|
2022-07-06 23:19:05 +02:00
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
2022-10-30 10:28:14 +02:00
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
0,
|
2022-07-19 12:09:54 +02:00
|
|
|
1,
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
2022-07-30 06:58:42 +02:00
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"existing, but non-relation type field",
|
|
|
|
"demo4",
|
|
|
|
[]string{"i9naidtvr6qsgb4", "qzaqccwrmva4o1n"},
|
2022-07-30 06:58:42 +02:00
|
|
|
[]string{"title"},
|
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
2022-10-30 10:28:14 +02:00
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
2022-07-30 06:58:42 +02:00
|
|
|
},
|
|
|
|
0,
|
|
|
|
1,
|
|
|
|
},
|
2022-07-06 23:19:05 +02:00
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"invalid/missing second level expand",
|
|
|
|
"demo4",
|
|
|
|
[]string{"i9naidtvr6qsgb4", "qzaqccwrmva4o1n"},
|
|
|
|
[]string{"rel_one_no_cascade.title"},
|
2022-07-06 23:19:05 +02:00
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
2022-10-30 10:28:14 +02:00
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
0,
|
2022-07-19 12:09:54 +02:00
|
|
|
1,
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"expand normalizations",
|
|
|
|
"demo4",
|
|
|
|
[]string{"i9naidtvr6qsgb4", "qzaqccwrmva4o1n"},
|
2022-07-06 23:19:05 +02:00
|
|
|
[]string{
|
2022-10-30 10:28:14 +02:00
|
|
|
"self_rel_one", "self_rel_many.self_rel_many.rel_one_no_cascade",
|
|
|
|
"self_rel_many.self_rel_one.self_rel_many.self_rel_one.rel_one_no_cascade",
|
|
|
|
"self_rel_many", "self_rel_many.",
|
|
|
|
" self_rel_many ", "",
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
2022-10-30 10:28:14 +02:00
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
9,
|
2022-07-19 12:09:54 +02:00
|
|
|
0,
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
2022-09-21 12:34:34 +02:00
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"single expand",
|
|
|
|
"users",
|
2022-09-21 12:34:34 +02:00
|
|
|
[]string{
|
2022-10-30 10:28:14 +02:00
|
|
|
"bgs820n361vj1qd",
|
|
|
|
"4q1xlclmfloku33",
|
|
|
|
"oap640cot4yru2s", // no rels
|
2022-09-21 12:34:34 +02:00
|
|
|
},
|
2022-10-30 10:28:14 +02:00
|
|
|
[]string{"rel"},
|
2022-09-21 12:34:34 +02:00
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
2022-10-30 10:28:14 +02:00
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
2022-09-21 12:34:34 +02:00
|
|
|
},
|
2022-10-30 10:28:14 +02:00
|
|
|
2,
|
2022-09-21 12:34:34 +02:00
|
|
|
0,
|
|
|
|
},
|
2022-07-06 23:19:05 +02:00
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"maxExpandDepth reached",
|
|
|
|
"demo4",
|
|
|
|
[]string{"qzaqccwrmva4o1n"},
|
|
|
|
[]string{"self_rel_many.self_rel_many.self_rel_many.self_rel_many.self_rel_many.self_rel_many.self_rel_many.self_rel_many.self_rel_many.self_rel_many.self_rel_many.self_rel_many"},
|
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
2022-10-30 10:28:14 +02:00
|
|
|
6,
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"simple indirect expand",
|
|
|
|
"demo3",
|
|
|
|
[]string{"lcl9d87w22ml6jy"},
|
|
|
|
[]string{"demo4(rel_one_no_cascade_required)"},
|
2022-07-06 23:19:05 +02:00
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
2022-10-30 10:28:14 +02:00
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
2022-10-30 10:28:14 +02:00
|
|
|
1,
|
2022-07-19 12:09:54 +02:00
|
|
|
0,
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"nested indirect expand",
|
|
|
|
"demo3",
|
|
|
|
[]string{"lcl9d87w22ml6jy"},
|
|
|
|
[]string{
|
|
|
|
"demo4(rel_one_no_cascade_required).self_rel_many.self_rel_many.self_rel_one",
|
|
|
|
},
|
2022-07-06 23:19:05 +02:00
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
2022-10-30 10:28:14 +02:00
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
2022-10-30 10:28:14 +02:00
|
|
|
5,
|
2022-07-19 12:09:54 +02:00
|
|
|
0,
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-10-30 10:28:14 +02:00
|
|
|
for _, s := range scenarios {
|
2022-07-06 23:19:05 +02:00
|
|
|
ids := list.ToUniqueStringSlice(s.recordIds)
|
2022-10-30 10:28:14 +02:00
|
|
|
records, _ := app.Dao().FindRecordsByIds(s.collectionIdOrName, ids)
|
2022-07-19 12:09:54 +02:00
|
|
|
failed := app.Dao().ExpandRecords(records, s.expands, s.fetchFunc)
|
2022-07-06 23:19:05 +02:00
|
|
|
|
2022-07-19 13:20:28 +02:00
|
|
|
if len(failed) != s.expectExpandFailures {
|
2022-10-30 10:28:14 +02:00
|
|
|
t.Errorf("[%s] Expected %d failures, got %d: \n%v", s.testName, s.expectExpandFailures, len(failed), failed)
|
2022-07-06 23:19:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
encoded, _ := json.Marshal(records)
|
|
|
|
encodedStr := string(encoded)
|
2022-10-30 10:28:14 +02:00
|
|
|
totalExpandProps := strings.Count(encodedStr, schema.FieldNameExpand)
|
2022-07-06 23:19:05 +02:00
|
|
|
|
|
|
|
if s.expectExpandProps != totalExpandProps {
|
2022-10-30 10:28:14 +02:00
|
|
|
t.Errorf("[%s] Expected %d expand props, got %d: \n%v", s.testName, s.expectExpandProps, totalExpandProps, encodedStr)
|
2022-07-06 23:19:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestExpandRecord(t *testing.T) {
|
|
|
|
app, _ := tests.NewTestApp()
|
|
|
|
defer app.Cleanup()
|
|
|
|
|
|
|
|
scenarios := []struct {
|
2022-10-30 10:28:14 +02:00
|
|
|
testName string
|
|
|
|
collectionIdOrName string
|
2022-07-19 12:09:54 +02:00
|
|
|
recordId string
|
|
|
|
expands []string
|
|
|
|
fetchFunc daos.ExpandFetchFunc
|
|
|
|
expectExpandProps int
|
2022-07-19 13:20:28 +02:00
|
|
|
expectExpandFailures int
|
2022-07-06 23:19:05 +02:00
|
|
|
}{
|
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"empty expand",
|
|
|
|
"demo4",
|
|
|
|
"i9naidtvr6qsgb4",
|
2022-07-06 23:19:05 +02:00
|
|
|
[]string{},
|
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
2022-10-30 10:28:14 +02:00
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
0,
|
2022-07-19 12:09:54 +02:00
|
|
|
0,
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"empty fetchFunc",
|
|
|
|
"demo4",
|
|
|
|
"i9naidtvr6qsgb4",
|
|
|
|
[]string{"self_rel_one", "self_rel_many.self_rel_one"},
|
2022-07-06 23:19:05 +02:00
|
|
|
nil,
|
|
|
|
0,
|
2022-07-19 12:09:54 +02:00
|
|
|
2,
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"fetchFunc with error",
|
|
|
|
"demo4",
|
|
|
|
"i9naidtvr6qsgb4",
|
|
|
|
[]string{"self_rel_one", "self_rel_many.self_rel_one"},
|
2022-07-06 23:19:05 +02:00
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
|
|
|
return nil, errors.New("test error")
|
|
|
|
},
|
|
|
|
0,
|
2022-07-19 12:09:54 +02:00
|
|
|
2,
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"missing relation field",
|
|
|
|
"demo4",
|
|
|
|
"i9naidtvr6qsgb4",
|
|
|
|
[]string{"missing"},
|
2022-07-06 23:19:05 +02:00
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
2022-10-30 10:28:14 +02:00
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
0,
|
2022-07-19 12:09:54 +02:00
|
|
|
1,
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"existing, but non-relation type field",
|
|
|
|
"demo4",
|
|
|
|
"i9naidtvr6qsgb4",
|
|
|
|
[]string{"title"},
|
2022-07-06 23:19:05 +02:00
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
2022-10-30 10:28:14 +02:00
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
0,
|
2022-07-19 12:09:54 +02:00
|
|
|
1,
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"invalid/missing second level expand",
|
|
|
|
"demo4",
|
|
|
|
"qzaqccwrmva4o1n",
|
|
|
|
[]string{"rel_one_no_cascade.title"},
|
2022-07-06 23:19:05 +02:00
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
2022-10-30 10:28:14 +02:00
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
2022-07-19 12:09:54 +02:00
|
|
|
0,
|
2022-10-30 10:28:14 +02:00
|
|
|
1,
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"expand normalizations",
|
|
|
|
"demo4",
|
|
|
|
"qzaqccwrmva4o1n",
|
|
|
|
[]string{
|
|
|
|
"self_rel_one", "self_rel_many.self_rel_many.rel_one_no_cascade",
|
|
|
|
"self_rel_many.self_rel_one.self_rel_many.self_rel_one.rel_one_no_cascade",
|
|
|
|
"self_rel_many", "self_rel_many.",
|
|
|
|
" self_rel_many ", "",
|
|
|
|
},
|
2022-07-06 23:19:05 +02:00
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
2022-10-30 10:28:14 +02:00
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
2022-10-30 10:28:14 +02:00
|
|
|
8,
|
2022-07-19 12:09:54 +02:00
|
|
|
0,
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
{
|
2022-10-30 10:28:14 +02:00
|
|
|
"no rels to expand",
|
|
|
|
"users",
|
|
|
|
"oap640cot4yru2s",
|
|
|
|
[]string{"rel"},
|
2022-07-06 23:19:05 +02:00
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
2022-10-30 10:28:14 +02:00
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"maxExpandDepth reached",
|
|
|
|
"demo4",
|
|
|
|
"qzaqccwrmva4o1n",
|
|
|
|
[]string{"self_rel_many.self_rel_many.self_rel_many.self_rel_many.self_rel_many.self_rel_many.self_rel_many.self_rel_many.self_rel_many.self_rel_many.self_rel_many.self_rel_many"},
|
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
|
|
|
6,
|
2022-07-19 12:09:54 +02:00
|
|
|
0,
|
2022-07-06 23:19:05 +02:00
|
|
|
},
|
2022-10-30 10:28:14 +02:00
|
|
|
{
|
|
|
|
"simple indirect expand",
|
|
|
|
"demo3",
|
|
|
|
"lcl9d87w22ml6jy",
|
|
|
|
[]string{"demo4(rel_one_no_cascade_required)"},
|
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
|
|
|
},
|
|
|
|
1,
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"nested indirect expand",
|
|
|
|
"demo3",
|
|
|
|
"lcl9d87w22ml6jy",
|
|
|
|
[]string{
|
|
|
|
"demo4(rel_one_no_cascade_required).self_rel_many.self_rel_many.self_rel_one",
|
|
|
|
},
|
|
|
|
func(c *models.Collection, ids []string) ([]*models.Record, error) {
|
|
|
|
return app.Dao().FindRecordsByIds(c.Id, ids, nil)
|
|
|
|
},
|
|
|
|
5,
|
|
|
|
0,
|
|
|
|
},
|
2022-07-06 23:19:05 +02:00
|
|
|
}
|
|
|
|
|
2022-10-30 10:28:14 +02:00
|
|
|
for _, s := range scenarios {
|
|
|
|
record, _ := app.Dao().FindRecordById(s.collectionIdOrName, s.recordId)
|
2022-07-19 12:09:54 +02:00
|
|
|
failed := app.Dao().ExpandRecord(record, s.expands, s.fetchFunc)
|
2022-07-06 23:19:05 +02:00
|
|
|
|
2022-07-19 13:20:28 +02:00
|
|
|
if len(failed) != s.expectExpandFailures {
|
2022-10-30 10:28:14 +02:00
|
|
|
t.Errorf("[%s] Expected %d failures, got %d: \n%v", s.testName, s.expectExpandFailures, len(failed), failed)
|
2022-07-06 23:19:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
encoded, _ := json.Marshal(record)
|
|
|
|
encodedStr := string(encoded)
|
2022-10-30 10:28:14 +02:00
|
|
|
totalExpandProps := strings.Count(encodedStr, schema.FieldNameExpand)
|
2022-07-06 23:19:05 +02:00
|
|
|
|
|
|
|
if s.expectExpandProps != totalExpandProps {
|
2022-10-30 10:28:14 +02:00
|
|
|
t.Errorf("[%s] Expected %d expand props, got %d: \n%v", s.testName, s.expectExpandProps, totalExpandProps, encodedStr)
|
2022-07-06 23:19:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|