Skip to content

Commit

Permalink
Small improvement in tuple package to remove TODO
Browse files Browse the repository at this point in the history
  • Loading branch information
josephschorr committed Feb 21, 2024
1 parent 40d6692 commit 3f77ff2
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
17 changes: 15 additions & 2 deletions pkg/tuple/tuple.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

v1 "github.com/authzed/authzed-go/proto/authzed/api/v1"
"github.com/jzelinskie/stringz"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/structpb"

core "github.com/authzed/spicedb/pkg/proto/core/v1"
Expand Down Expand Up @@ -271,9 +272,21 @@ func Delete(tpl *core.RelationTuple) *core.RelationTupleUpdate {
}
}

// Equal returns true if the two relationships are exactly the same.
func Equal(lhs, rhs *core.RelationTuple) bool {
// TODO(jschorr): Use a faster method then string comparison for caveats.
return OnrEqual(lhs.ResourceAndRelation, rhs.ResourceAndRelation) && OnrEqual(lhs.Subject, rhs.Subject) && MustStringCaveat(lhs.Caveat) == MustStringCaveat(rhs.Caveat)
return OnrEqual(lhs.ResourceAndRelation, rhs.ResourceAndRelation) && OnrEqual(lhs.Subject, rhs.Subject) && caveatEqual(lhs.Caveat, rhs.Caveat)
}

func caveatEqual(lhs, rhs *core.ContextualizedCaveat) bool {
if lhs == nil && rhs == nil {
return true
}

if lhs == nil || rhs == nil {
return false
}

return lhs.CaveatName == rhs.CaveatName && proto.Equal(lhs.Context, rhs.Context)
}

// MustToRelationship converts a RelationTuple into a Relationship. Will panic if
Expand Down
33 changes: 33 additions & 0 deletions pkg/tuple/tuple_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -583,12 +583,17 @@ func TestEqual(t *testing.T) {
},
},
),
MustParse("document:foo#viewer@user:tom[somecaveat:{\"hi\":\"there\"}]"),
MustParse("document:foo#viewer@user:tom[somecaveat:{\"hi\":{\"yo\":123}}]"),
MustParse("document:foo#viewer@user:tom[somecaveat:{\"hi\":{\"yo\":{\"hey\":true}}, \"hi2\":{\"yo2\":{\"hey2\":false}}}]"),
MustParse("document:foo#viewer@user:tom[somecaveat:{\"hi\":{\"yo\":{\"hey\":true}}, \"hi2\":{\"yo2\":{\"hey2\":[1,2,3]}}}]"),
}

for _, tc := range equalTestCases {
t.Run(MustString(tc), func(t *testing.T) {
require := require.New(t)
require.True(Equal(tc, tc.CloneVT()))
require.True(Equal(tc, MustParse(MustString(tc))))
})
}

Expand Down Expand Up @@ -725,12 +730,40 @@ func TestEqual(t *testing.T) {
},
),
},
{
name: "missing caveat context via string",
lhs: MustParse("document:foo#viewer@user:tom[somecaveat:{\"hi\":\"there\"}]"),
rhs: MustParse("document:foo#viewer@user:tom[somecaveat]"),
},
{
name: "mismatch caveat context via string",
lhs: MustParse("document:foo#viewer@user:tom[somecaveat:{\"hi\":\"there\"}]"),
rhs: MustParse("document:foo#viewer@user:tom[somecaveat:{\"hi\":\"there2\"}]"),
},
{
name: "mismatch caveat name",
lhs: MustParse("document:foo#viewer@user:tom[somecaveat]"),
rhs: MustParse("document:foo#viewer@user:tom[somecaveat2]"),
},
{
name: "mismatch caveat context, deeply nested",
lhs: MustParse("document:foo#viewer@user:tom[somecaveat:{\"hi\":{\"yo\":123}}]"),
rhs: MustParse("document:foo#viewer@user:tom[somecaveat:{\"hi\":{\"yo\":124}}]"),
},
{
name: "mismatch caveat context, deeply nested with array",
lhs: MustParse("document:foo#viewer@user:tom[somecaveat:{\"hi\":{\"yo\":[1,2,3]}}]"),
rhs: MustParse("document:foo#viewer@user:tom[somecaveat:{\"hi\":{\"yo\":[1,2,4]}}]"),
},
}

for _, tc := range notEqualTestCases {
t.Run(tc.name, func(t *testing.T) {
require := require.New(t)
require.False(Equal(tc.lhs, tc.rhs))
require.False(Equal(tc.rhs, tc.lhs))
require.False(Equal(tc.lhs, MustParse(MustString(tc.rhs))))
require.False(Equal(tc.rhs, MustParse(MustString(tc.lhs))))
})
}
}

0 comments on commit 3f77ff2

Please sign in to comment.