Skip to content

Commit 6ea62b0

Browse files
committed
Validate check definitions and add tests
1 parent e762df2 commit 6ea62b0

File tree

6 files changed

+69
-0
lines changed

6 files changed

+69
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ tests:
306306
# checks can also be defined for multiple users sharing the same expectation
307307
- object: group:employees
308308
users:
309+
# either "user" or "users" may be provided, but not both
309310
- user:3
310311
- user:4
311312
assertions:
@@ -584,6 +585,7 @@ tests: # required
584585
- user:carl
585586
assertions:
586587
can_view: false
588+
# either "user" or "users" may be provided, but not both
587589
list_objects: # a set of list objects to run
588590
- user: user:anne
589591
type: folder

cmd/store/import.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ func importStore(
121121
maxTuplesPerWrite, maxParallelRequests int,
122122
fileName string,
123123
) (*CreateStoreAndModelResponse, error) {
124+
if err := storeData.Validate(); err != nil {
125+
return nil, err //nolint:wrapcheck
126+
}
127+
124128
response, err := createOrUpdateStore(ctx, clientConfig, fgaClient, storeData, format, storeID, fileName)
125129
if err != nil {
126130
return nil, err

internal/storetest/read-from-input.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,9 @@ func ReadFromFile(fileName string, basePath string) (authorizationmodel.ModelFor
5454
return format, nil, err
5555
}
5656

57+
if err = storeData.Validate(); err != nil {
58+
return format, nil, err
59+
}
60+
5761
return format, &storeData, nil
5862
}

internal/storetest/storedata.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/openfga/go-sdk/client"
2727

2828
"github.com/openfga/cli/internal/authorizationmodel"
29+
"github.com/openfga/cli/internal/clierrors"
2930
"github.com/openfga/cli/internal/tuplefile"
3031
)
3132

@@ -138,3 +139,25 @@ func (storeData *StoreData) LoadTuples(basePath string) error {
138139

139140
return nil
140141
}
142+
143+
func (storeData *StoreData) Validate() error {
144+
var errs error
145+
146+
for _, test := range storeData.Tests {
147+
for index, check := range test.Check {
148+
if check.User != "" && len(check.Users) > 0 {
149+
msg := fmt.Sprintf("test %s check %d cannot contain both 'user' and 'users'", test.Name, index)
150+
errs = errors.Join(errs, fmt.Errorf("%w: %s", clierrors.ErrValidation, msg))
151+
} else if check.User == "" && len(check.Users) == 0 {
152+
msg := fmt.Sprintf("test %s check %d must specify 'user' or 'users'", test.Name, index)
153+
errs = errors.Join(errs, fmt.Errorf("%w: %s", clierrors.ErrValidation, msg))
154+
}
155+
}
156+
}
157+
158+
if errs != nil {
159+
return clierrors.ValidationError("storetests", errs.Error()) //nolint:wrapcheck
160+
}
161+
162+
return nil
163+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package storetest
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func TestStoreDataValidate(t *testing.T) {
11+
t.Parallel()
12+
13+
validSingle := StoreData{Tests: []ModelTest{{Name: "t1", Check: []ModelTestCheck{{
14+
User: "user:1", Object: "doc:1", Assertions: map[string]bool{"read": true},
15+
}}}}}
16+
assert.NoError(t, validSingle.Validate())
17+
18+
validUsers := StoreData{Tests: []ModelTest{{Name: "t1", Check: []ModelTestCheck{{
19+
Users: []string{"user:1", "user:2"}, Object: "doc:1", Assertions: map[string]bool{"read": true},
20+
}}}}}
21+
assert.NoError(t, validUsers.Validate())
22+
23+
invalidBoth := StoreData{Tests: []ModelTest{{Name: "t1", Check: []ModelTestCheck{{
24+
User: "user:1", Users: []string{"user:2"}, Object: "doc:1", Assertions: map[string]bool{"read": true},
25+
}}}}}
26+
require.Error(t, invalidBoth.Validate())
27+
28+
invalidNone := StoreData{Tests: []ModelTest{{Name: "t1", Check: []ModelTestCheck{{
29+
Object: "doc:1", Assertions: map[string]bool{"read": true},
30+
}}}}}
31+
require.Error(t, invalidNone.Validate())
32+
}

internal/storetest/tests.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ func RunTests(
3636
) (TestResults, error) {
3737
testResults := TestResults{}
3838

39+
if err := storeData.Validate(); err != nil {
40+
return testResults, err
41+
}
42+
3943
fgaServer, authModel, stopServerFn, err := getLocalServerModelAndTuples(storeData, format)
4044
if err != nil {
4145
return testResults, err

0 commit comments

Comments
 (0)