@@ -184,9 +184,10 @@ def test_configuration_client_credentials_missing_api_issuer(self):
184184 with self .assertRaises (openfga_sdk .ApiValueError ):
185185 credential .validate_credentials_config ()
186186
187- def test_configuration_client_credentials_missing_api_audience (self ):
187+ def test_configuration_client_credentials_without_api_audience (self ):
188188 """
189- Test credential with method client_credentials and configuration is missing api audience
189+ Test credential with method client_credentials and no api_audience is valid
190+ (audience is optional for standard OAuth2 servers)
190191 """
191192 credential = Credentials (
192193 method = "client_credentials" ,
@@ -196,14 +197,114 @@ def test_configuration_client_credentials_missing_api_audience(self):
196197 api_issuer = "issuer.fga.example" ,
197198 ),
198199 )
199- with self .assertRaises (openfga_sdk .ApiValueError ):
200- credential .validate_credentials_config ()
200+ credential .validate_credentials_config ()
201+ self .assertEqual (credential .method , "client_credentials" )
202+ self .assertIsNone (credential .configuration .api_audience )
203+
204+ def test_configuration_client_credentials_blank_api_audience_normalized (self ):
205+ """
206+ Test that blank/whitespace api_audience is normalized to None
207+ (common misconfiguration from env vars like FGA_API_AUDIENCE="")
208+ """
209+ credential = Credentials (
210+ method = "client_credentials" ,
211+ configuration = CredentialConfiguration (
212+ client_id = "myclientid" ,
213+ client_secret = "mysecret" ,
214+ api_issuer = "issuer.fga.example" ,
215+ api_audience = "" ,
216+ ),
217+ )
218+ credential .validate_credentials_config ()
219+ self .assertIsNone (credential .configuration .api_audience )
220+
221+ def test_configuration_client_credentials_whitespace_api_audience_normalized (self ):
222+ """
223+ Test that whitespace-only api_audience is normalized to None
224+ """
225+ credential = Credentials (
226+ method = "client_credentials" ,
227+ configuration = CredentialConfiguration (
228+ client_id = "myclientid" ,
229+ client_secret = "mysecret" ,
230+ api_issuer = "issuer.fga.example" ,
231+ api_audience = " " ,
232+ ),
233+ )
234+ credential .validate_credentials_config ()
235+ self .assertIsNone (credential .configuration .api_audience )
236+
237+ def test_configuration_client_credentials_blank_scopes_normalized (self ):
238+ """
239+ Test that blank scopes string is normalized to None
240+ """
241+ credential = Credentials (
242+ method = "client_credentials" ,
243+ configuration = CredentialConfiguration (
244+ client_id = "myclientid" ,
245+ client_secret = "mysecret" ,
246+ api_issuer = "issuer.fga.example" ,
247+ scopes = "" ,
248+ ),
249+ )
250+ credential .validate_credentials_config ()
251+ self .assertIsNone (credential .configuration .scopes )
252+
253+ def test_configuration_client_credentials_whitespace_scopes_normalized (self ):
254+ """
255+ Test that whitespace-only scopes string is normalized to None
256+ """
257+ credential = Credentials (
258+ method = "client_credentials" ,
259+ configuration = CredentialConfiguration (
260+ client_id = "myclientid" ,
261+ client_secret = "mysecret" ,
262+ api_issuer = "issuer.fga.example" ,
263+ scopes = " " ,
264+ ),
265+ )
266+ credential .validate_credentials_config ()
267+ self .assertIsNone (credential .configuration .scopes )
268+
269+ def test_configuration_client_credentials_empty_scopes_list_normalized (self ):
270+ """
271+ Test that empty scopes list is normalized to None
272+ """
273+ credential = Credentials (
274+ method = "client_credentials" ,
275+ configuration = CredentialConfiguration (
276+ client_id = "myclientid" ,
277+ client_secret = "mysecret" ,
278+ api_issuer = "issuer.fga.example" ,
279+ scopes = [],
280+ ),
281+ )
282+ credential .validate_credentials_config ()
283+ self .assertIsNone (credential .configuration .scopes )
284+
285+ def test_configuration_client_credentials_blank_scopes_list_normalized (self ):
286+ """
287+ Test that scopes list with only blank strings is normalized to None
288+ """
289+ credential = Credentials (
290+ method = "client_credentials" ,
291+ configuration = CredentialConfiguration (
292+ client_id = "myclientid" ,
293+ client_secret = "mysecret" ,
294+ api_issuer = "issuer.fga.example" ,
295+ scopes = ["" , " " ],
296+ ),
297+ )
298+ credential .validate_credentials_config ()
299+ self .assertIsNone (credential .configuration .scopes )
201300
202301
203302class TestCredentialsIssuer (IsolatedAsyncioTestCase ):
204303 def setUp (self ):
205304 # Setup a basic configuration that can be modified per test case
206- self .configuration = CredentialConfiguration (api_issuer = "https://example.com" )
305+ self .configuration = CredentialConfiguration (
306+ api_issuer = "https://abc.fga.example"
307+ )
207308 self .credentials = Credentials (
208309 method = "client_credentials" , configuration = self .configuration
209310 )
@@ -216,15 +317,15 @@ def test_valid_issuer_https(self):
216317
217318 def test_valid_issuer_with_oauth_endpoint_https (self ):
218319 # Test a valid HTTPS URL
219- self .configuration .api_issuer = "https://example.com /oauth/token"
320+ self .configuration .api_issuer = "https://abc.fga.example /oauth/token"
220321 result = self .credentials ._parse_issuer (self .configuration .api_issuer )
221- self .assertEqual (result , "https://example.com /oauth/token" )
322+ self .assertEqual (result , "https://abc.fga.example /oauth/token" )
222323
223324 def test_valid_issuer_with_some_endpoint_https (self ):
224325 # Test a valid HTTPS URL
225- self .configuration .api_issuer = "https://example.com /oauth/some/endpoint"
326+ self .configuration .api_issuer = "https://abc.fga.example /oauth/some/endpoint"
226327 result = self .credentials ._parse_issuer (self .configuration .api_issuer )
227- self .assertEqual (result , "https://example.com /oauth/some/endpoint" )
328+ self .assertEqual (result , "https://abc.fga.example /oauth/some/endpoint" )
228329
229330 def test_valid_issuer_http (self ):
230331 # Test a valid HTTP URL
@@ -242,7 +343,7 @@ def test_invalid_issuer_no_scheme(self):
242343
243344 def test_invalid_issuer_bad_scheme (self ):
244345 # Test an issuer with an unsupported scheme
245- self .configuration .api_issuer = "ftp://example.com "
346+ self .configuration .api_issuer = "ftp://abc.fga.example "
246347 with self .assertRaises (ApiValueError ):
247348 self .credentials ._parse_issuer (self .configuration .api_issuer )
248349
0 commit comments