Skip to content

Commit 0b73a5a

Browse files
committed
refactor and test: import assertions when importing store
1 parent 63895d9 commit 0b73a5a

File tree

2 files changed

+224
-69
lines changed

2 files changed

+224
-69
lines changed

cmd/store/import.go

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,11 @@ func importStore(
130130
}
131131
}
132132

133-
err = importAssertions(fgaClient, storeData.Tests, response.Store.Id, response.Model.AuthorizationModelId)
134-
if err != nil {
135-
return nil, err
133+
if len(storeData.Tests) != 0 && response.Model != nil {
134+
err = importAssertions(fgaClient, storeData.Tests, response.Store.Id, response.Model.AuthorizationModelId)
135+
if err != nil {
136+
return nil, err
137+
}
136138
}
137139

138140
return response, nil
@@ -196,17 +198,21 @@ func importAssertions(
196198
var assertions []client.ClientAssertion
197199

198200
for _, modelTest := range modelTests {
199-
checkAssertions := getCheckAssertions(modelTest.Check)
200-
assertions = append(assertions, checkAssertions...)
201+
if len(modelTest.Check) > 0 {
202+
checkAssertions := getCheckAssertions(modelTest.Check)
203+
assertions = append(assertions, checkAssertions...)
204+
}
201205
}
202206

203-
writeOptions := client.ClientWriteAssertionsOptions{
204-
AuthorizationModelId: &modelId,
205-
StoreId: &storeId,
206-
}
207+
if len(assertions) > 0 {
208+
writeOptions := client.ClientWriteAssertionsOptions{
209+
AuthorizationModelId: &modelId,
210+
StoreId: &storeId,
211+
}
207212

208-
if _, err := fgaClient.WriteAssertions(context.Background()).Body(assertions).Options(writeOptions).Execute(); err != nil {
209-
return fmt.Errorf("failed to import assertions: %w", err)
213+
if _, err := fgaClient.WriteAssertions(context.Background()).Body(assertions).Options(writeOptions).Execute(); err != nil {
214+
return fmt.Errorf("failed to import assertions: %w", err)
215+
}
210216
}
211217
return nil
212218
}

cmd/store/import_test.go

Lines changed: 207 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -8,76 +8,225 @@ import (
88
"github.com/openfga/go-sdk/client"
99
"go.uber.org/mock/gomock"
1010
"testing"
11+
"time"
1112
)
1213

1314
func TestImportStore(t *testing.T) {
1415
t.Parallel()
1516

16-
t.Run("imports assertions into store", func(t *testing.T) {
17-
mockCtrl := gomock.NewController(t)
18-
defer mockCtrl.Finish()
19-
20-
mockFgaClient := mockclient.NewMockSdkClient(mockCtrl)
21-
clientConfig := fga.ClientConfig{}
22-
23-
mockWriteAssertions := mockclient.NewMockSdkClientWriteAssertionsRequestInterface(mockCtrl)
24-
mockCreateStore := mockclient.NewMockSdkClientCreateStoreRequestInterface(mockCtrl)
25-
mockWriteModel := mockclient.NewMockSdkClientWriteAuthorizationModelRequestInterface(mockCtrl)
26-
27-
expectedAssertions := []client.ClientAssertion{{
28-
User: "user:anne",
29-
Relation: "reader",
30-
Object: "document:doc1",
31-
Expectation: true,
32-
}}
33-
34-
modelID := "model-1"
35-
storeID := "store-1"
36-
expectedOptions := client.ClientWriteAssertionsOptions{
37-
AuthorizationModelId: &modelID,
38-
StoreId: &storeID,
39-
}
40-
41-
mockFgaClient.EXPECT().CreateStore(context.Background()).Return(mockCreateStore)
42-
mockCreateStore.EXPECT().Body(gomock.Any()).Return(mockCreateStore)
43-
mockCreateStore.EXPECT().Execute().Return(&client.ClientCreateStoreResponse{Id: "store-1"}, nil)
44-
45-
mockFgaClient.EXPECT().SetStoreId("store-1")
46-
47-
mockFgaClient.EXPECT().WriteAuthorizationModel(context.Background()).Return(mockWriteModel)
48-
mockWriteModel.EXPECT().Body(gomock.Any()).Return(mockWriteModel)
49-
mockWriteModel.EXPECT().Execute().Return(&client.ClientWriteAuthorizationModelResponse{AuthorizationModelId: "model-1"}, nil)
50-
51-
mockFgaClient.EXPECT().WriteAssertions(context.Background()).Return(mockWriteAssertions)
52-
mockWriteAssertions.EXPECT().Body(expectedAssertions).Return(mockWriteAssertions)
53-
mockWriteAssertions.EXPECT().Options(expectedOptions).Return(mockWriteAssertions)
54-
mockWriteAssertions.EXPECT().Execute().Return(nil, nil)
55-
56-
testStore := &storetest.StoreData{
57-
Name: "test-store",
58-
Model: `type user
17+
mockCtrl := gomock.NewController(t)
18+
defer mockCtrl.Finish()
19+
20+
mockFgaClient := mockclient.NewMockSdkClient(mockCtrl)
21+
clientConfig := fga.ClientConfig{}
22+
23+
expectedAssertions := []client.ClientAssertion{{
24+
User: "user:anne",
25+
Relation: "reader",
26+
Object: "document:doc1",
27+
Expectation: true,
28+
}}
29+
30+
modelID := "model-1"
31+
storeID := "store-1"
32+
sampleTime := time.Now()
33+
expectedOptions := client.ClientWriteAssertionsOptions{
34+
AuthorizationModelId: &modelID,
35+
StoreId: &storeID,
36+
}
37+
38+
defaultStore := storetest.StoreData{
39+
Name: "test-store",
40+
Model: `type user
41+
type document
42+
relations
43+
define reader: [user]`,
44+
Tests: []storetest.ModelTest{
45+
{
46+
Name: "Test",
47+
Check: []storetest.ModelTestCheck{
48+
{
49+
User: "user:anne",
50+
Object: "document:doc1",
51+
Assertions: map[string]bool{
52+
"reader": true,
53+
},
54+
},
55+
},
56+
},
57+
},
58+
}
59+
60+
importStoreTests := []struct {
61+
name string
62+
mockWriteAssertions bool
63+
mockGetStore bool
64+
mockCreateStore bool
65+
mockWriteModel bool
66+
testStore storetest.StoreData
67+
storeId string
68+
}{
69+
{
70+
name: "import store with assertions",
71+
mockWriteAssertions: true,
72+
mockGetStore: false,
73+
mockWriteModel: true,
74+
mockCreateStore: true,
75+
testStore: defaultStore,
76+
storeId: "",
77+
},
78+
{
79+
name: "create new store without assertions",
80+
mockWriteAssertions: false,
81+
mockCreateStore: true,
82+
mockGetStore: false,
83+
mockWriteModel: false,
84+
testStore: storetest.StoreData{
85+
Name: "test-store",
86+
},
87+
storeId: "",
88+
},
89+
{
90+
name: "create new store without check assertions",
91+
mockCreateStore: true,
92+
mockWriteModel: true,
93+
mockWriteAssertions: false,
94+
testStore: storetest.StoreData{
95+
Name: "test-store",
96+
Model: `type user
97+
type document
98+
relations
99+
define reader: [user]`,
100+
Tests: []storetest.ModelTest{
101+
{
102+
Name: "Test",
103+
ListObjects: []storetest.ModelTestListObjects{
104+
{
105+
User: "user:anne",
106+
Type: "organization",
107+
Assertions: map[string][]string{
108+
"member": {"organization:acme"},
109+
},
110+
},
111+
},
112+
},
113+
},
114+
},
115+
storeId: "",
116+
},
117+
{
118+
name: "do not write assertions if imported store does not have a model",
119+
mockCreateStore: true,
120+
mockWriteAssertions: false,
121+
testStore: storetest.StoreData{
122+
Name: "test-store",
123+
Tests: []storetest.ModelTest{
124+
{
125+
Name: "Test",
126+
ListObjects: []storetest.ModelTestListObjects{
127+
{
128+
User: "user:anne",
129+
Type: "organization",
130+
Assertions: map[string][]string{
131+
"member": {"organization:acme"},
132+
},
133+
},
134+
},
135+
},
136+
},
137+
},
138+
storeId: "",
139+
},
140+
{
141+
name: "update store with assertions",
142+
mockWriteAssertions: true,
143+
mockGetStore: true,
144+
mockWriteModel: true,
145+
testStore: storetest.StoreData{
146+
Name: "test-store",
147+
Model: `type user
59148
type document
60149
relations
61150
define reader: [user]`,
62-
Tests: []storetest.ModelTest{
63-
{
64-
Name: "Test",
65-
Check: []storetest.ModelTestCheck{
66-
{
67-
User: "user:anne",
68-
Object: "document:doc1",
69-
Assertions: map[string]bool{
70-
"reader": true,
151+
Tests: []storetest.ModelTest{
152+
{
153+
Name: "Test",
154+
Check: []storetest.ModelTestCheck{
155+
{
156+
User: "user:anne",
157+
Object: "document:doc1",
158+
Assertions: map[string]bool{
159+
"reader": true,
160+
},
71161
},
72162
},
73163
},
74164
},
75165
},
76-
}
77-
_, err := importStore(&clientConfig, mockFgaClient, testStore, "", "", 1, 1, "")
166+
storeId: storeID,
167+
},
168+
{
169+
name: "update store without assertions",
170+
mockWriteAssertions: false,
171+
mockGetStore: true,
172+
mockWriteModel: true,
173+
testStore: storetest.StoreData{
174+
Name: "test-store",
175+
Model: `type user
176+
type document
177+
relations
178+
define reader: [user]`,
179+
},
180+
storeId: storeID,
181+
},
182+
}
183+
184+
for _, test := range importStoreTests {
185+
186+
t.Run(test.name, func(t *testing.T) {
187+
188+
if test.mockWriteAssertions {
189+
mockWriteAssertions := mockclient.NewMockSdkClientWriteAssertionsRequestInterface(mockCtrl)
190+
mockFgaClient.EXPECT().WriteAssertions(context.Background()).Return(mockWriteAssertions)
191+
mockWriteAssertions.EXPECT().Body(expectedAssertions).Return(mockWriteAssertions)
192+
mockWriteAssertions.EXPECT().Options(expectedOptions).Return(mockWriteAssertions)
193+
mockWriteAssertions.EXPECT().Execute().Return(nil, nil)
194+
} else {
195+
mockFgaClient.EXPECT().WriteAssertions(context.Background()).Times(0)
196+
}
197+
198+
if test.mockWriteModel {
199+
mockWriteModel := mockclient.NewMockSdkClientWriteAuthorizationModelRequestInterface(mockCtrl)
200+
mockFgaClient.EXPECT().WriteAuthorizationModel(context.Background()).Return(mockWriteModel)
201+
mockWriteModel.EXPECT().Body(gomock.Any()).Return(mockWriteModel)
202+
mockWriteModel.EXPECT().Execute().Return(&client.ClientWriteAuthorizationModelResponse{AuthorizationModelId: modelID}, nil)
203+
}
204+
205+
if test.mockCreateStore {
206+
mockCreateStore := mockclient.NewMockSdkClientCreateStoreRequestInterface(mockCtrl)
207+
mockFgaClient.EXPECT().CreateStore(context.Background()).Return(mockCreateStore)
208+
mockCreateStore.EXPECT().Body(gomock.Any()).Return(mockCreateStore)
209+
mockCreateStore.EXPECT().Execute().Return(&client.ClientCreateStoreResponse{Id: storeID}, nil)
210+
mockFgaClient.EXPECT().SetStoreId(storeID)
211+
}
212+
213+
if test.mockGetStore {
214+
mockGetStore := mockclient.NewMockSdkClientGetStoreRequestInterface(mockCtrl)
215+
mockFgaClient.EXPECT().GetStore(context.Background()).Return(mockGetStore)
216+
mockGetStore.EXPECT().Execute().Return(&client.ClientGetStoreResponse{Id: storeID, Name: "test-store", CreatedAt: sampleTime, UpdatedAt: sampleTime}, nil)
217+
}
218+
219+
var err error
220+
if storeID != "" {
221+
_, err = importStore(&clientConfig, mockFgaClient, &test.testStore, "", test.storeId, 1, 1, "")
222+
} else {
223+
_, err = importStore(&clientConfig, mockFgaClient, &test.testStore, "", "", 1, 1, "")
224+
}
225+
226+
if err != nil {
227+
t.Errorf("expected no error, got %v", err)
228+
}
78229

79-
if err != nil {
80-
t.Errorf("expected no error, got %v", err)
81-
}
82-
})
230+
})
231+
}
83232
}

0 commit comments

Comments
 (0)