Passed
Pull Request — master (#1470)
by Tolga
02:39
created

internal/storage/context/tuples_test.go   B

Size/Duplication

Total Lines 264
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 45
eloc 172
dl 0
loc 264
rs 8.8
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
C context.TestQueryRelationships2 0 26 10
B context.TestQueryRelationships4 0 34 5
C context.TestQueryRelationships1 0 26 10
B context.TestQueryRelationships5 0 37 5
B context.TestQueryRelationships3 0 35 5
B context.TestQueryRelationships7 0 39 5
B context.TestQueryRelationships6 0 37 5
1
package context
2
3
import (
4
	"testing"
5
6
	"golang.org/x/exp/slices"
7
8
	"github.com/Permify/permify/pkg/database"
9
	base "github.com/Permify/permify/pkg/pb/base/v1"
10
	"github.com/Permify/permify/pkg/tuple"
11
)
12
13
func TestQueryRelationships1(t *testing.T) {
14
	tuples := []*base.Tuple{
15
		{Entity: &base.Entity{Type: "type1", Id: "1"}, Relation: "relation1", Subject: &base.Subject{Type: "type2", Id: "2", Relation: "relation2"}},
16
		{Entity: &base.Entity{Type: "type3", Id: "3"}, Relation: "relation3", Subject: &base.Subject{Type: "type4", Id: "4", Relation: "relation4"}},
17
		{Entity: &base.Entity{Type: "type5", Id: "5"}, Relation: "relation5", Subject: &base.Subject{Type: "type6", Id: "6", Relation: "relation6"}},
18
	}
19
20
	contextualTuples := NewContextualTuples(tuples...)
21
	filter := &base.TupleFilter{Entity: &base.EntityFilter{Type: "type1", Ids: []string{"1"}}, Relation: "relation1", Subject: &base.SubjectFilter{Type: "type2", Ids: []string{"2"}, Relation: "relation2"}}
22
23
	iterator, err := contextualTuples.QueryRelationships(filter, database.NewCursorPagination())
24
	if err != nil {
25
		t.Errorf("Unexpected error: %v", err)
26
	}
27
28
	if !iterator.HasNext() {
29
		t.Errorf("Expected at least one tuple, got none")
30
	}
31
32
	filteredTuple := iterator.GetNext()
33
	if filteredTuple.Entity.Type != "type1" || filteredTuple.Entity.Id != "1" || filteredTuple.Relation != "relation1" || filteredTuple.Subject.Type != "type2" || filteredTuple.Subject.Id != "2" || filteredTuple.Subject.Relation != "relation2" {
34
		t.Errorf("Unexpected tuple: %+v", filteredTuple)
35
	}
36
37
	if iterator.HasNext() {
38
		t.Errorf("Expected exactly one tuple, got more")
39
	}
40
}
41
42
func TestQueryRelationships2(t *testing.T) {
43
	tuples := []*base.Tuple{
44
		{Entity: &base.Entity{Type: "type", Id: "1"}, Relation: "relation1", Subject: &base.Subject{Type: "type2", Id: "2", Relation: "relation2"}},
45
		{Entity: &base.Entity{Type: "type", Id: "3"}, Relation: "relation3", Subject: &base.Subject{Type: "type4", Id: "4", Relation: "relation4"}},
46
		{Entity: &base.Entity{Type: "type", Id: "5"}, Relation: "relation5", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
47
	}
48
49
	contextualTuples := NewContextualTuples(tuples...)
50
	filter := &base.TupleFilter{Entity: &base.EntityFilter{Type: "type", Ids: []string{"5"}}, Relation: "relation5"}
51
52
	iterator, err := contextualTuples.QueryRelationships(filter, database.NewCursorPagination())
53
	if err != nil {
54
		t.Errorf("Unexpected error: %v", err)
55
	}
56
57
	if !iterator.HasNext() {
58
		t.Errorf("Expected at least one tuple, got none")
59
	}
60
61
	filteredTuple := iterator.GetNext()
62
	if filteredTuple.Entity.Type != "type" || filteredTuple.Entity.Id != "5" || filteredTuple.Relation != "relation5" || filteredTuple.Subject.Type != "user" || filteredTuple.Subject.Id != "6" || filteredTuple.Subject.Relation != "" {
63
		t.Errorf("Unexpected tuple: %+v", filteredTuple)
64
	}
65
66
	if iterator.HasNext() {
67
		t.Errorf("Expected exactly one tuple, got more")
68
	}
69
}
70
71
func TestQueryRelationships3(t *testing.T) {
72
	tuples := []*base.Tuple{
73
		{Entity: &base.Entity{Type: "type1", Id: "1"}, Relation: "relation1", Subject: &base.Subject{Type: "type1", Id: "1", Relation: "relation1"}},
74
		{Entity: &base.Entity{Type: "type1", Id: "3"}, Relation: "relation1", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
75
		{Entity: &base.Entity{Type: "type2", Id: "3"}, Relation: "relation2", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
76
		{Entity: &base.Entity{Type: "type2", Id: "2"}, Relation: "relation2", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
77
		{Entity: &base.Entity{Type: "type1", Id: "3"}, Relation: "relation1", Subject: &base.Subject{Type: "type2", Id: "4", Relation: "relation2"}},
78
		{Entity: &base.Entity{Type: "type3", Id: "1"}, Relation: "relation2", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
79
		{Entity: &base.Entity{Type: "type3", Id: "3"}, Relation: "relation2", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
80
	}
81
82
	contextualTuples := NewContextualTuples(tuples...)
83
	filter := &base.TupleFilter{Entity: &base.EntityFilter{Type: "type1", Ids: []string{"3"}}, Relation: "relation1"}
84
85
	iterator, err := contextualTuples.QueryRelationships(filter, database.NewCursorPagination())
86
	if err != nil {
87
		t.Errorf("Unexpected error: %v", err)
88
	}
89
90
	count := 0
91
	for iterator.HasNext() {
92
		filteredTuple := iterator.GetNext()
93
94
		count++
95
96
		if !slices.Contains([]string{
97
			"type1:3#relation1@user:6",
98
			"type1:3#relation1@type2:4#relation2",
99
		}, tuple.ToString(filteredTuple)) {
100
			t.Errorf("Unexpected tuple: %+v", filteredTuple)
101
		}
102
	}
103
104
	if count != 2 {
105
		t.Errorf("Unexpected count")
106
	}
107
}
108
109
func TestQueryRelationships4(t *testing.T) {
110
	tuples := []*base.Tuple{
111
		{Entity: &base.Entity{Type: "type1", Id: "1"}, Relation: "relation1", Subject: &base.Subject{Type: "type1", Id: "1", Relation: "relation1"}},
112
		{Entity: &base.Entity{Type: "type1", Id: "3"}, Relation: "relation1", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
113
		{Entity: &base.Entity{Type: "type2", Id: "3"}, Relation: "relation2", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
114
		{Entity: &base.Entity{Type: "type2", Id: "2"}, Relation: "relation2", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
115
		{Entity: &base.Entity{Type: "type1", Id: "3"}, Relation: "relation1", Subject: &base.Subject{Type: "type2", Id: "4", Relation: "relation2"}},
116
		{Entity: &base.Entity{Type: "type3", Id: "1"}, Relation: "relation2", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
117
		{Entity: &base.Entity{Type: "type3", Id: "3"}, Relation: "relation2", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
118
	}
119
120
	contextualTuples := NewContextualTuples(tuples...)
121
	filter := &base.TupleFilter{Entity: &base.EntityFilter{Type: "type1", Ids: []string{"3"}}, Relation: "relation1", Subject: &base.SubjectFilter{Type: "type2", Ids: []string{}, Relation: ""}}
122
123
	iterator, err := contextualTuples.QueryRelationships(filter, database.NewCursorPagination())
124
	if err != nil {
125
		t.Errorf("Unexpected error: %v", err)
126
	}
127
128
	count := 0
129
	for iterator.HasNext() {
130
		filteredTuple := iterator.GetNext()
131
132
		count++
133
134
		if !slices.Contains([]string{
135
			"type1:3#relation1@type2:4#relation2",
136
		}, tuple.ToString(filteredTuple)) {
137
			t.Errorf("Unexpected tuple: %+v", filteredTuple)
138
		}
139
	}
140
141
	if count != 1 {
142
		t.Errorf("Unexpected count")
143
	}
144
}
145
146
func TestQueryRelationships5(t *testing.T) {
147
	tuples := []*base.Tuple{
148
		{Entity: &base.Entity{Type: "type1", Id: "1"}, Relation: "relation1", Subject: &base.Subject{Type: "user", Id: "1", Relation: ""}},
149
		{Entity: &base.Entity{Type: "type1", Id: "3"}, Relation: "relation1", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
150
		{Entity: &base.Entity{Type: "type1", Id: "3"}, Relation: "relation1", Subject: &base.Subject{Type: "user", Id: "4", Relation: ""}},
151
152
		{Entity: &base.Entity{Type: "type2", Id: "2"}, Relation: "relation2", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
153
		{Entity: &base.Entity{Type: "type2", Id: "3"}, Relation: "relation1", Subject: &base.Subject{Type: "user", Id: "5", Relation: ""}},
154
		{Entity: &base.Entity{Type: "type3", Id: "1"}, Relation: "relation2", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
155
		{Entity: &base.Entity{Type: "type3", Id: "3"}, Relation: "relation2", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
156
	}
157
158
	contextualTuples := NewContextualTuples(tuples...)
159
	filter := &base.TupleFilter{Entity: &base.EntityFilter{Type: "type1", Ids: []string{"1", "3"}}, Relation: "relation1", Subject: &base.SubjectFilter{Type: "user", Ids: []string{"1", "6", "4", "7"}, Relation: ""}}
160
161
	iterator, err := contextualTuples.QueryRelationships(filter, database.NewCursorPagination())
162
	if err != nil {
163
		t.Errorf("Unexpected error: %v", err)
164
	}
165
166
	count := 0
167
	for iterator.HasNext() {
168
		filteredTuple := iterator.GetNext()
169
170
		count++
171
172
		if !slices.Contains([]string{
173
			"type1:1#relation1@user:1",
174
			"type1:3#relation1@user:6",
175
			"type1:3#relation1@user:4",
176
		}, tuple.ToString(filteredTuple)) {
177
			t.Errorf("Unexpected tuple: %+v", filteredTuple)
178
		}
179
	}
180
181
	if count != 3 {
182
		t.Errorf("Unexpected count")
183
	}
184
}
185
186
func TestQueryRelationships6(t *testing.T) {
187
	tuples := []*base.Tuple{
188
		{Entity: &base.Entity{Type: "type1", Id: "2"}, Relation: "relation1", Subject: &base.Subject{Type: "user", Id: "1", Relation: ""}},
189
		{Entity: &base.Entity{Type: "type1", Id: "3"}, Relation: "relation1", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
190
		{Entity: &base.Entity{Type: "type1", Id: "3"}, Relation: "relation1", Subject: &base.Subject{Type: "user", Id: "4", Relation: ""}},
191
		{Entity: &base.Entity{Type: "type2", Id: "12"}, Relation: "relation2", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
192
		{Entity: &base.Entity{Type: "type2", Id: "32"}, Relation: "relation1", Subject: &base.Subject{Type: "user", Id: "5", Relation: ""}},
193
		{Entity: &base.Entity{Type: "type3", Id: "43"}, Relation: "relation2", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
194
		{Entity: &base.Entity{Type: "type3", Id: "56"}, Relation: "relation2", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
195
	}
196
197
	contextualTuples := NewContextualTuples(tuples...)
198
	filter := &base.TupleFilter{Entity: &base.EntityFilter{Type: "", Ids: []string{"1", "3", "12", "32", "43", "56"}}, Relation: "", Subject: &base.SubjectFilter{Type: "user", Ids: []string{"1", "6", "4", "7"}, Relation: ""}}
199
200
	iterator, err := contextualTuples.QueryRelationships(filter, database.NewCursorPagination(database.Cursor("Mw=="), database.Sort("entity_id")))
201
	if err != nil {
202
		t.Errorf("Unexpected error: %v", err)
203
	}
204
205
	count := 0
206
	for iterator.HasNext() {
207
		filteredTuple := iterator.GetNext()
208
209
		count++
210
211
		if !slices.Contains([]string{
212
			"type1:3#relation1@user:6",
213
			"type1:3#relation1@user:4",
214
			"type3:43#relation2@user:6",
215
			"type3:56#relation2@user:6",
216
		}, tuple.ToString(filteredTuple)) {
217
			t.Errorf("Unexpected tuple: %+v", filteredTuple)
218
		}
219
	}
220
221
	if count != 4 {
222
		t.Errorf("Unexpected count")
223
	}
224
}
225
226
func TestQueryRelationships7(t *testing.T) {
227
	tuples := []*base.Tuple{
228
		{Entity: &base.Entity{Type: "type1", Id: "2"}, Relation: "relation1", Subject: &base.Subject{Type: "user", Id: "1", Relation: ""}},
229
		{Entity: &base.Entity{Type: "type1", Id: "3"}, Relation: "relation1", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
230
		{Entity: &base.Entity{Type: "type1", Id: "3"}, Relation: "relation1", Subject: &base.Subject{Type: "user", Id: "4", Relation: ""}},
231
		{Entity: &base.Entity{Type: "type2", Id: "12"}, Relation: "relation2", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
232
		{Entity: &base.Entity{Type: "type2", Id: "32"}, Relation: "relation1", Subject: &base.Subject{Type: "user", Id: "5", Relation: ""}},
233
		{Entity: &base.Entity{Type: "type3", Id: "43"}, Relation: "relation2", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
234
		{Entity: &base.Entity{Type: "type3", Id: "56"}, Relation: "relation2", Subject: &base.Subject{Type: "user", Id: "6", Relation: ""}},
235
	}
236
237
	contextualTuples := NewContextualTuples(tuples...)
238
	filter := &base.TupleFilter{Entity: &base.EntityFilter{Type: "", Ids: []string{"1", "3", "12", "32", "43", "56"}}, Relation: "", Subject: &base.SubjectFilter{Type: "user", Ids: []string{"1", "6", "4", "5", "7"}, Relation: ""}}
239
240
	iterator, err := contextualTuples.QueryRelationships(filter, database.NewCursorPagination(database.Cursor("NA=="), database.Sort("subject_id")))
241
	if err != nil {
242
		t.Errorf("Unexpected error: %v", err)
243
	}
244
245
	count := 0
246
	for iterator.HasNext() {
247
		filteredTuple := iterator.GetNext()
248
249
		count++
250
251
		if !slices.Contains([]string{
252
			"type1:3#relation1@user:4",
253
			"type2:32#relation1@user:5",
254
			"type1:3#relation1@user:6",
255
			"type2:12#relation2@user:6",
256
			"type3:43#relation2@user:6",
257
			"type3:56#relation2@user:6",
258
		}, tuple.ToString(filteredTuple)) {
259
			t.Errorf("Unexpected tuple: %+v", filteredTuple)
260
		}
261
	}
262
263
	if count != 6 {
264
		t.Errorf("Unexpected count")
265
	}
266
}
267