Some checks failed
CI / Run lints and checks (push) Failing after 47s
CI / Run tests (push) Failing after 1s
CI / Run race tests (push) Failing after 5s
CI / Build CLI docs (push) Has been skipped
CI / Run buf actions (push) Failing after 5s
CodeQL / Analyze (go) (push) Failing after 3s
CodeQL / Analyze (javascript) (push) Failing after 2s
Docker Image Scanners / scanners (push) Failing after 3s
Format / format (push) Failing after 3s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Draft newsletter (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
119 lines
2.9 KiB
Go
119 lines
2.9 KiB
Go
// Copyright © 2023 Ory Corp
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package relationtuple
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"reflect"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
|
|
"github.com/ory/keto/ketoapi"
|
|
)
|
|
|
|
func TestRelationCollection(t *testing.T) {
|
|
t.Run("case=prints all", func(t *testing.T) {
|
|
expected := make([]*ketoapi.RelationTuple, 3)
|
|
for i := range expected {
|
|
expected[i] = &ketoapi.RelationTuple{
|
|
Namespace: "n" + strconv.Itoa(i),
|
|
Object: "o" + strconv.Itoa(i),
|
|
Relation: "r" + strconv.Itoa(i),
|
|
SubjectID: new("s" + strconv.Itoa(i)),
|
|
}
|
|
}
|
|
expected[2].SubjectSet = &ketoapi.SubjectSet{
|
|
Namespace: "sn",
|
|
Object: "so",
|
|
Relation: "sr",
|
|
}
|
|
expected[2].SubjectID = nil
|
|
|
|
proto := make([]*rts.RelationTuple, 3)
|
|
for i := range expected {
|
|
proto[i] = &rts.RelationTuple{
|
|
Namespace: "n" + strconv.Itoa(i),
|
|
Object: "o" + strconv.Itoa(i),
|
|
Relation: "r" + strconv.Itoa(i),
|
|
Subject: rts.NewSubjectID("s" + strconv.Itoa(i)),
|
|
}
|
|
}
|
|
proto[2].Subject = rts.NewSubjectSet("sn", "so", "sr")
|
|
|
|
for i, c := range []*Collection{
|
|
NewAPICollection(expected),
|
|
MustNewProtoCollection(proto),
|
|
} {
|
|
t.Run(fmt.Sprintf("case=%d", i), func(t *testing.T) {
|
|
var vals []string
|
|
for _, row := range c.Table() {
|
|
vals = append(vals, row...)
|
|
}
|
|
|
|
ev := reflect.ValueOf(expected)
|
|
for el := 0; el < ev.Len(); el++ {
|
|
et := reflect.TypeOf(expected).Elem().Elem()
|
|
|
|
for f := 0; f < et.NumField(); f++ {
|
|
v := ev.Index(el).Elem().Field(f)
|
|
// private field or nil
|
|
if !v.CanSet() || (v.Kind() == reflect.Pointer && v.IsNil()) {
|
|
continue
|
|
}
|
|
|
|
switch k := v.Kind(); {
|
|
case k == reflect.String:
|
|
assert.Contains(t, vals, v.String())
|
|
case k == reflect.Pointer && v.Elem().Kind() == reflect.String:
|
|
assert.Contains(t, vals, v.Elem().String())
|
|
default:
|
|
t.Logf("unhandled kind %s %T", v.Kind(), v.Interface())
|
|
str := v.MethodByName("String").Call(nil)[0].String()
|
|
assert.Contains(t, vals, str)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("func=NewProtoCollection", func(t *testing.T) {
|
|
_, err := NewProtoCollection([]*rts.RelationTuple{{ /*subject is nil*/ }})
|
|
require.ErrorIs(t, err, ketoapi.ErrNilSubject())
|
|
})
|
|
|
|
t.Run("func=json", func(t *testing.T) {
|
|
ts := []*ketoapi.RelationTuple{
|
|
{
|
|
Namespace: "n",
|
|
Object: "o",
|
|
Relation: "r",
|
|
SubjectID: new("s"),
|
|
},
|
|
{
|
|
Namespace: "n",
|
|
Object: "o",
|
|
Relation: "r",
|
|
SubjectSet: &ketoapi.SubjectSet{
|
|
Namespace: "sn",
|
|
Object: "so",
|
|
Relation: "sr",
|
|
},
|
|
},
|
|
}
|
|
expected, err := json.Marshal(ts)
|
|
require.NoError(t, err)
|
|
|
|
collection := NewAPICollection(ts)
|
|
actual, err := json.Marshal(collection)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, string(expected), string(actual))
|
|
})
|
|
}
|