Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion cmd/store/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const (
progressBarSleepDelay = 10 // time.Millisecond
progressBarThrottleValue = 65
progressBarUpdateDelay = 5 * time.Millisecond
maxAssertionsPerWrite = 100
)

// createStore creates a new store with the given client configuration and store data.
Expand Down Expand Up @@ -226,9 +227,15 @@ func importAssertions(
StoreId: &storeID,
}

if len(assertions) > maxAssertionsPerWrite {
fmt.Fprintf(os.Stderr, "Warning: %d test assertions found, but only the first %d will be written\n",
len(assertions), maxAssertionsPerWrite)
assertions = assertions[:maxAssertionsPerWrite]
}

_, err := fgaClient.WriteAssertions(ctx).Body(assertions).Options(writeOptions).Execute()
if err != nil {
return fmt.Errorf("failed to import assertions: %w", err)
return fmt.Errorf("failed to import test assertions: %w", err)
}
}

Expand Down
69 changes: 66 additions & 3 deletions cmd/store/import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ import (
"github.com/openfga/cli/internal/storetest"
)

const (
testModelID = "model-1"
testStoreID = "store-1"
)

func TestImportStore(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -51,7 +56,7 @@ func TestImportStore(t *testing.T) {
Expectation: true,
},
}
modelID, storeID := "model-1", "store-1"
modelID, storeID := testModelID, testStoreID
expectedOptions := client.ClientWriteAssertionsOptions{AuthorizationModelId: &modelID, StoreId: &storeID}

importStoreTests := []struct {
Expand Down Expand Up @@ -215,6 +220,64 @@ func TestImportStore(t *testing.T) {
}
}

func TestImportStoreWithTruncatedAssertions(t *testing.T) {
t.Parallel()

modelID, storeID := testModelID, testStoreID
expectedOptions := client.ClientWriteAssertionsOptions{AuthorizationModelId: &modelID, StoreId: &storeID}

// Generate 150 users to create 150 assertions (exceeding 100 limit)
users := make([]string, 150)
for i := range 150 {
users[i] = "user:" + string(rune('a'+i/26)) + string(rune('a'+i%26))
}

// Only the first 100 assertions should be written
first100Assertions := make([]client.ClientAssertion, 100)
for i := range 100 {
first100Assertions[i] = client.ClientAssertion{
User: users[i],
Relation: "reader",
Object: "document:doc1",
Expectation: true,
}
}

mockCtrl := gomock.NewController(t)
mockFgaClient := mockclient.NewMockSdkClient(mockCtrl)

defer mockCtrl.Finish()

// Only expect a single write with the first 100 assertions
setupWriteAssertionsMock(mockCtrl, mockFgaClient, first100Assertions, expectedOptions)
setupWriteModelMock(mockCtrl, mockFgaClient, modelID)
setupCreateStoreMock(mockCtrl, mockFgaClient, storeID)

testStore := storetest.StoreData{
Model: `type user
type document
relations
define reader: [user]`,
Tests: []storetest.ModelTest{
{
Name: "Test",
Check: []storetest.ModelTestCheck{
{
Users: users,
Object: "document:doc1",
Assertions: map[string]bool{"reader": true},
},
},
},
},
}

_, err := importStore(t.Context(), &fga.ClientConfig{}, mockFgaClient, &testStore, "", "", 10, 1, "")
if err != nil {
t.Errorf("expected no error, got %v", err)
}
}

func TestUpdateStore(t *testing.T) {
t.Parallel()

Expand All @@ -225,8 +288,8 @@ func TestUpdateStore(t *testing.T) {
Expectation: true,
}}

modelID := "model-1"
storeID := "store-1"
modelID := testModelID
storeID := testStoreID
sampleTime := time.Now()
expectedOptions := client.ClientWriteAssertionsOptions{
AuthorizationModelId: &modelID,
Expand Down
1 change: 1 addition & 0 deletions internal/storetest/remotetest.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ func RunRemoteListUsersTest(
results := make([]ModelTestListUsersSingleResult, 0, len(listUsersTest.Assertions))

object, _ := convertStoreObjectToObject(listUsersTest.Object)

for relation, expectation := range listUsersTest.Assertions {
result := RunSingleRemoteListUsersTest(ctx, fgaClient,
client.ClientListUsersRequest{
Expand Down
Loading