@@ -235,6 +235,19 @@ def test_connection_expired_no_bearer(platform):
235235 assert platform ._connection_expired (conn ) is True
236236
237237
238+ @patch ("app.platforms.implementations.openeo.jwt.decode" )
239+ def test_connection_expired_exception (mock_decode , platform ):
240+ mock_decode .side_effect = jwt .DecodeError ("Invalid token" )
241+ exp = int (
242+ (
243+ datetime .datetime .now (datetime .timezone .utc ) + datetime .timedelta (hours = 1 )
244+ ).timestamp ()
245+ )
246+ token = jwt .encode ({"sub" : "user" , "exp" : exp }, "secret" , algorithm = "HS256" )
247+ conn = _make_conn_with_token (token )
248+ assert platform ._connection_expired (conn ) is True
249+
250+
238251@pytest .mark .asyncio
239252@patch (
240253 "app.platforms.implementations.openeo.exchange_token_for_provider" ,
@@ -298,6 +311,154 @@ async def test_authenticate_user_with_client_credentials(
298311 assert returned is conn
299312
300313
314+ @pytest .mark .asyncio
315+ @patch (
316+ "app.platforms.implementations.openeo.exchange_token_for_provider" ,
317+ new_callable = AsyncMock ,
318+ )
319+ async def test_authenticate_user_config_missing_url (
320+ mock_exchange , monkeypatch , platform
321+ ):
322+ url = "https://openeo.foo.bar"
323+
324+ # prepare fake connection and spy method
325+ conn = MagicMock ()
326+ conn .authenticate_oidc_client_credentials = MagicMock ()
327+
328+ # ensure the exchange mock exists but is not awaited
329+ with pytest .raises (
330+ ValueError , match = "No OpenEO backend configuration found for URL"
331+ ):
332+ await platform ._authenticate_user ("user-token" , url , conn )
333+
334+ mock_exchange .assert_not_awaited ()
335+
336+
337+ @pytest .mark .asyncio
338+ @patch (
339+ "app.platforms.implementations.openeo.exchange_token_for_provider" ,
340+ new_callable = AsyncMock ,
341+ )
342+ async def test_authenticate_user_config_unsupported_method (
343+ mock_exchange , monkeypatch , platform
344+ ):
345+ url = "https://openeo.vito.be"
346+ # disable user credentials path -> use client credentials
347+ settings .openeo_backend_config [url ].auth_method = "FOOBAR"
348+
349+ # prepare fake connection and spy method
350+ conn = MagicMock ()
351+ conn .authenticate_oidc_client_credentials = MagicMock ()
352+
353+ # ensure the exchange mock exists but is not awaited
354+ with pytest .raises (
355+ ValueError , match = "No OpenEO backend configuration found for URL"
356+ ):
357+ await platform ._authenticate_user ("user-token" , url , conn )
358+
359+ mock_exchange .assert_not_awaited ()
360+
361+
362+ @pytest .mark .asyncio
363+ @patch (
364+ "app.platforms.implementations.openeo.exchange_token_for_provider" ,
365+ new_callable = AsyncMock ,
366+ )
367+ async def test_authenticate_user_config_missing_credentials (
368+ mock_exchange , monkeypatch , platform
369+ ):
370+ url = "https://openeo.vito.be"
371+ # disable user credentials path -> use client credentials
372+ settings .openeo_backend_config [url ].auth_method = (
373+ OpenEOAuthMethod .CLIENT_CREDENTIALS
374+ )
375+ settings .openeo_backend_config [url ].client_credentials = None
376+
377+ # prepare fake connection and spy method
378+ conn = MagicMock ()
379+ conn .authenticate_oidc_client_credentials = MagicMock ()
380+
381+ # ensure the exchange mock exists but is not awaited
382+ with pytest .raises (
383+ ValueError , match = "Client credentials not configured for OpenEO backend"
384+ ):
385+ await platform ._authenticate_user ("user-token" , url , conn )
386+
387+ mock_exchange .assert_not_awaited ()
388+
389+
390+ @pytest .mark .asyncio
391+ @patch (
392+ "app.platforms.implementations.openeo.exchange_token_for_provider" ,
393+ new_callable = AsyncMock ,
394+ )
395+ async def test_authenticate_user_config_format_issue_credentials (
396+ mock_exchange , monkeypatch , platform
397+ ):
398+ url = "https://openeo.vito.be"
399+ # disable user credentials path -> use client credentials
400+ settings .openeo_backend_config [url ].auth_method = (
401+ OpenEOAuthMethod .CLIENT_CREDENTIALS
402+ )
403+ settings .openeo_backend_config [url ].client_credentials = "foobar"
404+
405+ # prepare fake connection and spy method
406+ conn = MagicMock ()
407+ conn .authenticate_oidc_client_credentials = MagicMock ()
408+
409+ # ensure the exchange mock exists but is not awaited
410+ with pytest .raises (ValueError , match = "Invalid client credentials format for" ):
411+ await platform ._authenticate_user ("user-token" , url , conn )
412+
413+ mock_exchange .assert_not_awaited ()
414+
415+
416+ @pytest .mark .asyncio
417+ @patch (
418+ "app.platforms.implementations.openeo.exchange_token_for_provider" ,
419+ new_callable = AsyncMock ,
420+ )
421+ async def test_authenticate_user_config_missing_provider (
422+ mock_exchange , monkeypatch , platform
423+ ):
424+ url = "https://openeo.vito.be"
425+ # disable user credentials path -> use client credentials
426+ settings .openeo_backend_config [url ].token_provider = None
427+
428+ # prepare fake connection and spy method
429+ conn = MagicMock ()
430+ conn .authenticate_oidc_client_credentials = MagicMock ()
431+
432+ # ensure the exchange mock exists but is not awaited
433+ with pytest .raises (ValueError , match = "must define" ):
434+ await platform ._authenticate_user ("user-token" , url , conn )
435+
436+ mock_exchange .assert_not_awaited ()
437+
438+
439+ @pytest .mark .asyncio
440+ @patch (
441+ "app.platforms.implementations.openeo.exchange_token_for_provider" ,
442+ new_callable = AsyncMock ,
443+ )
444+ async def test_authenticate_user_config_missing_prefix (
445+ mock_exchange , monkeypatch , platform
446+ ):
447+ url = "https://openeo.vito.be"
448+ # disable user credentials path -> use client credentials
449+ settings .openeo_backend_config [url ].token_prefix = None
450+
451+ # prepare fake connection and spy method
452+ conn = MagicMock ()
453+ conn .authenticate_oidc_client_credentials = MagicMock ()
454+
455+ # ensure the exchange mock exists but is not awaited
456+ with pytest .raises (ValueError , match = "must define" ):
457+ await platform ._authenticate_user ("user-token" , url , conn )
458+
459+ mock_exchange .assert_not_awaited ()
460+
461+
301462@pytest .mark .asyncio
302463@patch ("app.platforms.implementations.openeo.openeo.connect" )
303464@patch .object (OpenEOPlatform , "_authenticate_user" , new_callable = AsyncMock )
0 commit comments