Skip to content
Open
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
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ custom-headers:
| [Create a Store](#create-store) | `create` | `--name` | `fga store create --name="FGA Demo Store"` |
| [Import a Store](#import-store) | `import` | `--file` | `fga store import --file store.fga.yaml` |
| [Export a Store](#export-store) | `export` | `--store-id` | `fga store export --store-id=01H0H015178Y2V4CX10C2KGHF4` |
| [List Stores](#list-stores) | `list` | | `fga store list` |
| [List Stores](#list-stores) | `list` | `--name` | `fga store list --name="FGA Demo Store"` |
| [Get a Store](#get-store) | `get` | `--store-id` | `fga store get --store-id=01H0H015178Y2V4CX10C2KGHF4` |
| [Delete a Store](#delete-store) | `delete` | `--store-id` | `fga store delete --store-id=01H0H015178Y2V4CX10C2KGHF4` |

Expand Down Expand Up @@ -364,10 +364,13 @@ fga store **list**

###### Parameters
* `--max-pages`: Max number of pages to retrieve (default: 20)
* `--name`: Filter stores by exact name (substrings and regexes are not supported)

###### Example
`fga store list`

`fga store list --name="FGA Demo Store"`

###### Response
```json
{
Expand Down
18 changes: 16 additions & 2 deletions cmd/store/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ import (
// MaxStoresPagesLength Limit the pages of stores so that we are not paginating indefinitely.
var MaxStoresPagesLength = 20 // up to 1000 records

func listStores(ctx context.Context, fgaClient client.SdkClient, maxPages int) (*openfga.ListStoresResponse, error) {
func listStores(
ctx context.Context,
fgaClient client.SdkClient,
maxPages int,
name string,
) (*openfga.ListStoresResponse, error) {
stores := []openfga.Store{}
continuationToken := ""
pageIndex := 0
Expand All @@ -40,6 +45,9 @@ func listStores(ctx context.Context, fgaClient client.SdkClient, maxPages int) (
options := client.ClientListStoresOptions{
ContinuationToken: &continuationToken,
}
if name != "" {
options.Name = &name
}

response, err := fgaClient.ListStores(ctx).Options(options).Execute()
if err != nil {
Expand Down Expand Up @@ -78,7 +86,12 @@ var listCmd = &cobra.Command{
return fmt.Errorf("failed to parse max pages due to %w", err)
}

response, err := listStores(cmd.Context(), fgaClient, maxPages)
name, err := cmd.Flags().GetString("name")
if err != nil {
return fmt.Errorf("failed to parse name due to %w", err)
}

response, err := listStores(cmd.Context(), fgaClient, maxPages, name)
if err != nil {
return err
}
Expand All @@ -89,4 +102,5 @@ var listCmd = &cobra.Command{

func init() {
listCmd.Flags().Int("max-pages", MaxStoresPagesLength, "Max number of pages to get.")
listCmd.Flags().String("name", "", "Filter stores by exact name. Substrings and regexes are not supported.")
}
42 changes: 37 additions & 5 deletions cmd/store/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestListStoresError(t *testing.T) {
mockRequest.EXPECT().Options(options).Return(mockExecute)
mockFgaClient.EXPECT().ListStores(t.Context()).Return(mockRequest)

_, err := listStores(t.Context(), mockFgaClient, 5)
_, err := listStores(t.Context(), mockFgaClient, 5, "")
if err == nil {
t.Error("Expect error but there is none")
}
Expand Down Expand Up @@ -67,7 +67,7 @@ func TestListStoresEmpty(t *testing.T) {
mockRequest.EXPECT().Options(options).Return(mockExecute)
mockFgaClient.EXPECT().ListStores(t.Context()).Return(mockRequest)

output, err := listStores(t.Context(), mockFgaClient, 5)
output, err := listStores(t.Context(), mockFgaClient, 5, "")
if err != nil {
t.Error(err)
}
Expand Down Expand Up @@ -118,7 +118,7 @@ func TestListStoresSinglePage(t *testing.T) {
mockRequest.EXPECT().Options(options).Return(mockExecute)
mockFgaClient.EXPECT().ListStores(t.Context()).Return(mockRequest)

output, err := listStores(t.Context(), mockFgaClient, 5)
output, err := listStores(t.Context(), mockFgaClient, 5, "")
if err != nil {
t.Error(err)
}
Expand Down Expand Up @@ -202,7 +202,7 @@ func TestListStoresMultiPage(t *testing.T) {
mockFgaClient.EXPECT().ListStores(t.Context()).Return(mockRequest2),
)

output, err := listStores(t.Context(), mockFgaClient, 5)
output, err := listStores(t.Context(), mockFgaClient, 5, "")
if err != nil {
t.Error(err)
}
Expand Down Expand Up @@ -256,7 +256,7 @@ func TestListStoresMultiPageMaxPage(t *testing.T) {
mockRequest1.EXPECT().Options(options1).Return(mockExecute1)
mockFgaClient.EXPECT().ListStores(t.Context()).Return(mockRequest1)

output, err := listStores(t.Context(), mockFgaClient, 1)
output, err := listStores(t.Context(), mockFgaClient, 1, "")
if err != nil {
t.Error(err)
}
Expand All @@ -272,3 +272,35 @@ func TestListStoresMultiPageMaxPage(t *testing.T) {
t.Errorf("Expected output %v actual %v", expectedOutput, string(outputTxt))
}
}

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

mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

const storeName = "my-store"

mockFgaClient := mockclient.NewMockSdkClient(mockCtrl)

mockExecute := mockclient.NewMockSdkClientListStoresRequestInterface(mockCtrl)

response := openfga.ListStoresResponse{
Stores: []openfga.Store{},
ContinuationToken: "",
}
mockExecute.EXPECT().Execute().Return(&response, nil)

mockRequest := mockclient.NewMockSdkClientListStoresRequestInterface(mockCtrl)
options := client.ClientListStoresOptions{
ContinuationToken: openfga.PtrString(""),
Name: openfga.PtrString(storeName),
}
mockRequest.EXPECT().Options(options).Return(mockExecute)
mockFgaClient.EXPECT().ListStores(t.Context()).Return(mockRequest)

_, err := listStores(t.Context(), mockFgaClient, 5, storeName)
if err != nil {
t.Error(err)
}
}
Loading