Skip to content

Commit 51f34bb

Browse files
committed
Add name filter support to ListStores
- Add name parameter to ClientListStoresOptions - Extend OpenFgaApi.listStores() method signatures - Update OpenFgaClient to pass name parameter - Add comprehensive unit and integration tests - Maintain full backward compatibility Resolves #157
1 parent ff7aa69 commit 51f34bb

6 files changed

Lines changed: 145 additions & 5 deletions

File tree

src/main/java/dev/openfga/sdk/api/OpenFgaApi.java

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,21 @@ private CompletableFuture<ApiResponse<ListObjectsResponse>> listObjects(
480480
*/
481481
public CompletableFuture<ApiResponse<ListStoresResponse>> listStores(Integer pageSize, String continuationToken)
482482
throws ApiException, FgaInvalidParameterException {
483-
return listStores(pageSize, continuationToken, this.configuration);
483+
return listStores(pageSize, continuationToken, null, this.configuration);
484+
}
485+
486+
/**
487+
* List all stores
488+
* Returns a paginated list of OpenFGA stores and a continuation token to get additional stores. The continuation token will be empty if there are no more stores.
489+
* @param pageSize (optional)
490+
* @param continuationToken (optional)
491+
* @param name (optional)
492+
* @return CompletableFuture&lt;ApiResponse&lt;ListStoresResponse&gt;&gt;
493+
* @throws ApiException if fails to make API call
494+
*/
495+
public CompletableFuture<ApiResponse<ListStoresResponse>> listStores(
496+
Integer pageSize, String continuationToken, String name) throws ApiException, FgaInvalidParameterException {
497+
return listStores(pageSize, continuationToken, name, this.configuration);
484498
}
485499

486500
/**
@@ -495,15 +509,31 @@ public CompletableFuture<ApiResponse<ListStoresResponse>> listStores(Integer pag
495509
public CompletableFuture<ApiResponse<ListStoresResponse>> listStores(
496510
Integer pageSize, String continuationToken, ConfigurationOverride configurationOverride)
497511
throws ApiException, FgaInvalidParameterException {
498-
return listStores(pageSize, continuationToken, this.configuration.override(configurationOverride));
512+
return listStores(pageSize, continuationToken, null, this.configuration.override(configurationOverride));
513+
}
514+
515+
/**
516+
* List all stores
517+
* Returns a paginated list of OpenFGA stores and a continuation token to get additional stores. The continuation token will be empty if there are no more stores.
518+
* @param pageSize (optional)
519+
* @param continuationToken (optional)
520+
* @param name (optional)
521+
* @param configurationOverride Override the {@link Configuration} this OpenFgaApi was constructed with
522+
* @return CompletableFuture&lt;ApiResponse&lt;ListStoresResponse&gt;&gt;
523+
* @throws ApiException if fails to make API call
524+
*/
525+
public CompletableFuture<ApiResponse<ListStoresResponse>> listStores(
526+
Integer pageSize, String continuationToken, String name, ConfigurationOverride configurationOverride)
527+
throws ApiException, FgaInvalidParameterException {
528+
return listStores(pageSize, continuationToken, name, this.configuration.override(configurationOverride));
499529
}
500530

501531
private CompletableFuture<ApiResponse<ListStoresResponse>> listStores(
502-
Integer pageSize, String continuationToken, Configuration configuration)
532+
Integer pageSize, String continuationToken, String name, Configuration configuration)
503533
throws ApiException, FgaInvalidParameterException {
504534

505535
String path = "/stores";
506-
path = pathWithParams(path, "page_size", pageSize, "continuation_token", continuationToken);
536+
path = pathWithParams(path, "page_size", pageSize, "continuation_token", continuationToken, "name", name);
507537

508538
Map<String, Object> methodParameters = new HashMap<>();
509539

src/main/java/dev/openfga/sdk/api/client/OpenFgaClient.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ public CompletableFuture<ClientListStoresResponse> listStores(ClientListStoresOp
9494
throws FgaInvalidParameterException {
9595
configuration.assertValid();
9696
var overrides = new ConfigurationOverride().addHeaders(options);
97-
return call(() -> api.listStores(options.getPageSize(), options.getContinuationToken(), overrides))
97+
return call(() -> api.listStores(
98+
options.getPageSize(), options.getContinuationToken(), options.getName(), overrides))
9899
.thenApply(ClientListStoresResponse::new);
99100
}
100101

src/main/java/dev/openfga/sdk/api/configuration/ClientListStoresOptions.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class ClientListStoresOptions implements AdditionalHeadersSupplier {
1818
private Map<String, String> additionalHeaders;
1919
private Integer pageSize;
2020
private String continuationToken;
21+
private String name;
2122

2223
public ClientListStoresOptions additionalHeaders(Map<String, String> additionalHeaders) {
2324
this.additionalHeaders = additionalHeaders;
@@ -46,4 +47,13 @@ public ClientListStoresOptions continuationToken(String continuationToken) {
4647
public String getContinuationToken() {
4748
return continuationToken;
4849
}
50+
51+
public ClientListStoresOptions name(String name) {
52+
this.name = name;
53+
return this;
54+
}
55+
56+
public String getName() {
57+
return name;
58+
}
4959
}

src/test-integration/java/dev/openfga/sdk/api/OpenFgaApiIntegrationTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,30 @@ public void listStores() throws Exception {
124124
}
125125
}
126126

127+
@Test
128+
public void listStoresWithNameFilter() throws Exception {
129+
// Given
130+
String testName = thisTestName();
131+
String targetStore = testName + "-target-store";
132+
String otherStore1 = testName + "-other-store-1";
133+
String otherStore2 = testName + "-other-store-2";
134+
135+
// Create multiple stores
136+
createStore(targetStore);
137+
createStore(otherStore1);
138+
createStore(otherStore2);
139+
140+
// When - Filter by name
141+
ListStoresResponse response =
142+
api.listStores(100, null, targetStore).get().getData();
143+
144+
// Then - Should only return the target store
145+
List<String> storeNames =
146+
response.getStores().stream().map(Store::getName).collect(java.util.stream.Collectors.toList());
147+
assertTrue(storeNames.contains(targetStore), "Target store should be in the filtered response");
148+
assertEquals(1, storeNames.size(), "Should return only one store when filtering by exact name");
149+
}
150+
127151
@Test
128152
public void readAuthModel() throws Exception {
129153
// Given

src/test-integration/java/dev/openfga/sdk/api/client/OpenFgaClientIntegrationTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,32 @@ public void listStores() throws Exception {
141141
}
142142
}
143143

144+
@Test
145+
public void listStoresWithNameFilter() throws Exception {
146+
// Given
147+
String testName = thisTestName();
148+
String targetStore = testName + "-target-store";
149+
String otherStore1 = testName + "-other-store-1";
150+
String otherStore2 = testName + "-other-store-2";
151+
152+
// Create multiple stores
153+
createStore(targetStore);
154+
createStore(otherStore1);
155+
createStore(otherStore2);
156+
157+
ClientListStoresOptions options = new ClientListStoresOptions().name(targetStore);
158+
159+
// When - Filter by name using client options
160+
ClientListStoresResponse response = fga.listStores(options).get();
161+
162+
// Then - Should only return the target store
163+
assertNotNull(response.getStores());
164+
List<String> storeNames =
165+
response.getStores().stream().map(Store::getName).collect(java.util.stream.Collectors.toList());
166+
assertTrue(storeNames.contains(targetStore), "Target store should be in the filtered response");
167+
assertEquals(1, storeNames.size(), "Should return only one store when filtering by exact name");
168+
}
169+
144170
@Test
145171
public void readAuthModel() throws Exception {
146172
// Given

src/test/java/dev/openfga/sdk/api/client/OpenFgaClientTest.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,55 @@ public void listStoresTest_withOptions() throws Exception {
294294
assertEquals(DEFAULT_STORE_NAME, response.getStores().get(0).getName());
295295
}
296296

297+
@Test
298+
public void listStoresTest_withNameFilter() throws Exception {
299+
// Given
300+
String responseBody =
301+
String.format("{\"stores\":[{\"id\":\"%s\",\"name\":\"%s\"}]}", DEFAULT_STORE_ID, DEFAULT_STORE_NAME);
302+
String storeName = "test-store";
303+
String getUrl = String.format("https://api.fga.example/stores?name=%s", storeName);
304+
mockHttpClient.onGet(getUrl).doReturn(200, responseBody);
305+
ClientListStoresOptions options = new ClientListStoresOptions().name(storeName);
306+
307+
// When
308+
ClientListStoresResponse response = fga.listStores(options).get();
309+
310+
// Then
311+
mockHttpClient.verify().get(getUrl).called(1);
312+
assertNotNull(response.getStores());
313+
assertEquals(1, response.getStores().size());
314+
assertEquals(DEFAULT_STORE_ID, response.getStores().get(0).getId());
315+
assertEquals(DEFAULT_STORE_NAME, response.getStores().get(0).getName());
316+
}
317+
318+
@Test
319+
public void listStoresTest_withAllParameters() throws Exception {
320+
// Given
321+
String responseBody =
322+
String.format("{\"stores\":[{\"id\":\"%s\",\"name\":\"%s\"}]}", DEFAULT_STORE_ID, DEFAULT_STORE_NAME);
323+
int pageSize = 10;
324+
String continuationToken = "continuationToken";
325+
String storeName = "test-store";
326+
String getUrl = String.format(
327+
"https://api.fga.example/stores?page_size=%d&continuation_token=%s&name=%s",
328+
pageSize, continuationToken, storeName);
329+
mockHttpClient.onGet(getUrl).doReturn(200, responseBody);
330+
ClientListStoresOptions options = new ClientListStoresOptions()
331+
.pageSize(pageSize)
332+
.continuationToken(continuationToken)
333+
.name(storeName);
334+
335+
// When
336+
ClientListStoresResponse response = fga.listStores(options).get();
337+
338+
// Then
339+
mockHttpClient.verify().get(getUrl).called(1);
340+
assertNotNull(response.getStores());
341+
assertEquals(1, response.getStores().size());
342+
assertEquals(DEFAULT_STORE_ID, response.getStores().get(0).getId());
343+
assertEquals(DEFAULT_STORE_NAME, response.getStores().get(0).getName());
344+
}
345+
297346
/**
298347
* Create a store.
299348
*/

0 commit comments

Comments
 (0)