From 9ead1a9d7d70fd931b1833a93ce4e2fb39da610a Mon Sep 17 00:00:00 2001 From: Colin-b Date: Tue, 7 Jan 2025 12:15:27 +0100 Subject: [PATCH] Add base exception --- CHANGELOG.md | 1 + httpx_auth/__init__.py | 2 ++ httpx_auth/_errors.py | 33 +++++++++++-------- .../token_cache/test_json_token_file_cache.py | 3 ++ .../test_oauth2_authorization_code_async.py | 8 ++--- .../test_oauth2_authorization_code_sync.py | 15 ++++++--- ...st_oauth2_authorization_code_pkce_async.py | 8 ++--- ...est_oauth2_authorization_code_pkce_sync.py | 8 ++--- .../implicit/test_oauth2_implicit_sync.py | 14 +++++++- ...uth2_resource_owner_password_okta_async.py | 8 ++--- ...auth2_resource_owner_password_okta_sync.py | 8 ++--- ...st_oauth2_resource_owner_password_async.py | 8 ++--- ...est_oauth2_resource_owner_password_sync.py | 8 ++--- 13 files changed, 76 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b308ae1..dd56126 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Requires [`httpx`](https://www.python-httpx.org)==0.28.\* +- Exceptions issued by `httpx_auth` are now inheriting from `httpx_auth.HttpxAuthException`, itself inheriting from `httpx.HTTPError`, instead of `Exception`. ### Added - Explicit support for python `3.13`. diff --git a/httpx_auth/__init__.py b/httpx_auth/__init__.py index 1ab04ca..b948ba1 100644 --- a/httpx_auth/__init__.py +++ b/httpx_auth/__init__.py @@ -40,6 +40,7 @@ InvalidToken, TokenExpiryNotProvided, InvalidGrantRequest, + HttpxAuthException, ) from httpx_auth.version import __version__ @@ -67,6 +68,7 @@ "JsonTokenFileCache", "TokenMemoryCache", "AWS4Auth", + "HttpxAuthException", "GrantNotProvided", "TimeoutOccurred", "AuthenticationFailed", diff --git a/httpx_auth/_errors.py b/httpx_auth/_errors.py index 3247dd8..078fe41 100644 --- a/httpx_auth/_errors.py +++ b/httpx_auth/_errors.py @@ -4,39 +4,42 @@ import httpx -class AuthenticationFailed(Exception): +class HttpxAuthException(httpx.HTTPError): ... + + +class AuthenticationFailed(HttpxAuthException): """User was not authenticated.""" def __init__(self): - Exception.__init__(self, "User was not authenticated.") + HttpxAuthException.__init__(self, "User was not authenticated.") -class TimeoutOccurred(Exception): +class TimeoutOccurred(HttpxAuthException): """No response within timeout interval.""" def __init__(self, timeout: float): - Exception.__init__( + HttpxAuthException.__init__( self, f"User authentication was not received within {timeout} seconds." ) -class InvalidToken(Exception): +class InvalidToken(HttpxAuthException): """Token is invalid.""" def __init__(self, token_name: str): - Exception.__init__(self, f"{token_name} is invalid.") + HttpxAuthException.__init__(self, f"{token_name} is invalid.") -class GrantNotProvided(Exception): +class GrantNotProvided(HttpxAuthException): """Grant was not provided.""" def __init__(self, grant_name: str, dictionary_without_grant: dict): - Exception.__init__( + HttpxAuthException.__init__( self, f"{grant_name} not provided within {dictionary_without_grant}." ) -class InvalidGrantRequest(Exception): +class InvalidGrantRequest(HttpxAuthException): """ If the request failed client authentication or is invalid, the authorization server returns an error response as described in https://tools.ietf.org/html/rfc6749#section-5.2 """ @@ -64,7 +67,7 @@ class InvalidGrantRequest(Exception): } def __init__(self, response: Union[httpx.Response, dict]): - Exception.__init__(self, InvalidGrantRequest.to_message(response)) + HttpxAuthException.__init__(self, InvalidGrantRequest.to_message(response)) @staticmethod def to_message(response: Union[httpx.Response, dict]) -> str: @@ -114,17 +117,19 @@ def _pop(key: str) -> str: return message -class StateNotProvided(Exception): +class StateNotProvided(HttpxAuthException): """State was not provided.""" def __init__(self, dictionary_without_state: dict): - Exception.__init__( + HttpxAuthException.__init__( self, f"state not provided within {dictionary_without_state}." ) -class TokenExpiryNotProvided(Exception): +class TokenExpiryNotProvided(HttpxAuthException): """Token expiry was not provided.""" def __init__(self, token_body: dict): - Exception.__init__(self, f"Expiry (exp) is not provided in {token_body}.") + HttpxAuthException.__init__( + self, f"Expiry (exp) is not provided in {token_body}." + ) diff --git a/tests/features/token_cache/test_json_token_file_cache.py b/tests/features/token_cache/test_json_token_file_cache.py index 2073abc..511f253 100644 --- a/tests/features/token_cache/test_json_token_file_cache.py +++ b/tests/features/token_cache/test_json_token_file_cache.py @@ -2,6 +2,7 @@ import logging import pathlib +import httpx import pytest import jwt @@ -78,6 +79,8 @@ def failing_dump(*args): with pytest.raises(httpx_auth.AuthenticationFailed) as exception_info: same_cache.get_token("key1") assert str(exception_info.value) == "User was not authenticated." + assert isinstance(exception_info.value, httpx_auth.HttpxAuthException) + assert isinstance(exception_info.value, httpx.HTTPError) assert caplog.messages == [ "Cannot save tokens.", diff --git a/tests/oauth2/authorization_code/test_oauth2_authorization_code_async.py b/tests/oauth2/authorization_code/test_oauth2_authorization_code_async.py index a371282..6d45173 100644 --- a/tests/oauth2/authorization_code/test_oauth2_authorization_code_async.py +++ b/tests/oauth2/authorization_code/test_oauth2_authorization_code_async.py @@ -171,7 +171,7 @@ async def test_oauth2_authorization_code_flow_is_able_to_reuse_client( json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", - "expires_in": 10, + "expires_in": 2, "example_parameter": "example_value", }, match_content=b"grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA", @@ -190,7 +190,7 @@ async def test_oauth2_authorization_code_flow_is_able_to_reuse_client( tab.assert_success() - time.sleep(10) + time.sleep(2) tab = browser_mock.add_response( opened_url="https://provide_code?response_type=code&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F", reply_url="http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5", @@ -240,7 +240,7 @@ async def test_oauth2_authorization_code_flow_is_able_to_reuse_client_with_token json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", - "expires_in": 10, + "expires_in": 2, "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter": "example_value", }, @@ -260,7 +260,7 @@ async def test_oauth2_authorization_code_flow_is_able_to_reuse_client_with_token tab.assert_success() - time.sleep(10) + time.sleep(2) # response for refresh token grant httpx_mock.add_response( diff --git a/tests/oauth2/authorization_code/test_oauth2_authorization_code_sync.py b/tests/oauth2/authorization_code/test_oauth2_authorization_code_sync.py index 95e05f5..4c66de9 100644 --- a/tests/oauth2/authorization_code/test_oauth2_authorization_code_sync.py +++ b/tests/oauth2/authorization_code/test_oauth2_authorization_code_sync.py @@ -141,9 +141,12 @@ def test_with_invalid_request_error_uses_custom_failure( ) with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest): + with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) + assert isinstance(exception_info.value, httpx_auth.HttpxAuthException) + assert isinstance(exception_info.value, httpx.HTTPError) + tab.assert_failure( "invalid_request: The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed." ) @@ -166,7 +169,7 @@ def test_oauth2_authorization_code_flow_is_able_to_reuse_client( json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", - "expires_in": 10, + "expires_in": 2, "example_parameter": "example_value", }, match_content=b"grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA", @@ -185,7 +188,7 @@ def test_oauth2_authorization_code_flow_is_able_to_reuse_client( tab.assert_success() - time.sleep(10) + time.sleep(2) tab = browser_mock.add_response( opened_url="https://provide_code?response_type=code&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F", reply_url="http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5", @@ -234,7 +237,7 @@ def test_oauth2_authorization_code_flow_is_able_to_reuse_client_with_token_refre json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", - "expires_in": 10, + "expires_in": 2, "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter": "example_value", }, @@ -254,7 +257,7 @@ def test_oauth2_authorization_code_flow_is_able_to_reuse_client_with_token_refre tab.assert_success() - time.sleep(10) + time.sleep(2) # response for refresh token grant httpx_mock.add_response( @@ -631,6 +634,8 @@ def test_empty_token_is_invalid( str(exception_info.value) == "access_token not provided within {'access_token': '', 'token_type': 'example', 'expires_in': 3600, 'refresh_token': 'tGzv3JOkF0XG5Qx2TlKWIA', 'example_parameter': 'example_value'}." ) + assert isinstance(exception_info.value, httpx_auth.HttpxAuthException) + assert isinstance(exception_info.value, httpx.HTTPError) tab.assert_success() diff --git a/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce_async.py b/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce_async.py index 9e98a9f..29e54cd 100644 --- a/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce_async.py +++ b/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce_async.py @@ -169,7 +169,7 @@ async def test_oauth2_pkce_flow_is_able_to_reuse_client( json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", - "expires_in": 10, + "expires_in": 2, "example_parameter": "example_value", }, match_content=b"code_verifier=MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEx&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA", @@ -187,7 +187,7 @@ async def test_oauth2_pkce_flow_is_able_to_reuse_client( await client.get("https://authorized_only", auth=auth) tab.assert_success() - time.sleep(10) + time.sleep(2) tab = browser_mock.add_response( opened_url="https://provide_code?response_type=code&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256", reply_url="http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5", @@ -236,7 +236,7 @@ async def test_oauth2_pkce_flow_is_able_to_reuse_client_with_token_refresh( json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", - "expires_in": 10, + "expires_in": 2, "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter": "example_value", }, @@ -255,7 +255,7 @@ async def test_oauth2_pkce_flow_is_able_to_reuse_client_with_token_refresh( await client.get("https://authorized_only", auth=auth) tab.assert_success() - time.sleep(10) + time.sleep(2) httpx_mock.add_response( method="POST", diff --git a/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce_sync.py b/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce_sync.py index c1c3e5d..9f4b2de 100644 --- a/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce_sync.py +++ b/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce_sync.py @@ -164,7 +164,7 @@ def test_oauth2_pkce_flow_is_able_to_reuse_client( json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", - "expires_in": 10, + "expires_in": 2, "example_parameter": "example_value", }, match_content=b"code_verifier=MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEx&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA", @@ -182,7 +182,7 @@ def test_oauth2_pkce_flow_is_able_to_reuse_client( client.get("https://authorized_only", auth=auth) tab.assert_success() - time.sleep(10) + time.sleep(2) tab = browser_mock.add_response( opened_url="https://provide_code?response_type=code&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256", reply_url="http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5", @@ -230,7 +230,7 @@ def test_oauth2_pkce_flow_is_able_to_reuse_client_with_token_refresh( json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", - "expires_in": 10, + "expires_in": 2, "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter": "example_value", }, @@ -249,7 +249,7 @@ def test_oauth2_pkce_flow_is_able_to_reuse_client_with_token_refresh( client.get("https://authorized_only", auth=auth) tab.assert_success() - time.sleep(10) + time.sleep(2) httpx_mock.add_response( method="POST", diff --git a/tests/oauth2/implicit/test_oauth2_implicit_sync.py b/tests/oauth2/implicit/test_oauth2_implicit_sync.py index 19645de..3096c1e 100644 --- a/tests/oauth2/implicit/test_oauth2_implicit_sync.py +++ b/tests/oauth2/implicit/test_oauth2_implicit_sync.py @@ -349,6 +349,8 @@ def open(self, url, new): str(exception_info.value) == "User authentication was not received within 0.1 seconds." ) + assert isinstance(exception_info.value, httpx_auth.HttpxAuthException) + assert isinstance(exception_info.value, httpx.HTTPError) def test_browser_error(token_cache, httpx_mock: HTTPXMock, monkeypatch): @@ -380,6 +382,8 @@ def open(self, url, new): str(exception_info.value) == "User authentication was not received within 0.1 seconds." ) + assert isinstance(exception_info.value, httpx_auth.HttpxAuthException) + assert isinstance(exception_info.value, httpx.HTTPError) def test_state_change(token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock): @@ -416,9 +420,13 @@ def test_empty_token_is_invalid(token_cache, browser_mock: BrowserMock): ) with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidToken, match=" is invalid."): + with pytest.raises( + httpx_auth.InvalidToken, match=" is invalid." + ) as exception_info: client.get("https://authorized_only", auth=auth) + assert isinstance(exception_info.value, httpx_auth.HttpxAuthException) + assert isinstance(exception_info.value, httpx.HTTPError) tab.assert_success() @@ -435,6 +443,8 @@ def test_token_without_expiry_is_invalid(token_cache, browser_mock: BrowserMock) client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "Expiry (exp) is not provided in None." + assert isinstance(exception_info.value, httpx_auth.HttpxAuthException) + assert isinstance(exception_info.value, httpx.HTTPError) tab.assert_success() @@ -701,6 +711,8 @@ def test_oauth2_implicit_flow_post_failure_if_state_is_not_provided( str(exception_info.value) == f"state not provided within {{'access_token': ['{token}']}}." ) + assert isinstance(exception_info.value, httpx_auth.HttpxAuthException) + assert isinstance(exception_info.value, httpx.HTTPError) tab.assert_failure(f"state not provided within {{'access_token': ['{token}']}}.") diff --git a/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta_async.py b/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta_async.py index f81261d..cc008d5 100644 --- a/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta_async.py +++ b/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta_async.py @@ -71,7 +71,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client( json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", - "expires_in": 10, + "expires_in": 2, "example_parameter": "example_value", }, match_content=b"grant_type=password&username=test_user&password=test_pwd&scope=openid", @@ -91,7 +91,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client( async with httpx.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) - time.sleep(10) + time.sleep(2) httpx_mock.add_response( method="POST", @@ -139,7 +139,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_tok json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", - "expires_in": 10, + "expires_in": 2, "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter": "example_value", }, @@ -160,7 +160,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_tok async with httpx.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) - time.sleep(10) + time.sleep(2) httpx_mock.add_response( method="POST", diff --git a/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta_sync.py b/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta_sync.py index c9ae63e..e285f5f 100644 --- a/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta_sync.py +++ b/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta_sync.py @@ -67,7 +67,7 @@ def test_oauth2_password_credentials_flow_is_able_to_reuse_client( json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", - "expires_in": 10, + "expires_in": 2, "example_parameter": "example_value", }, match_content=b"grant_type=password&username=test_user&password=test_pwd&scope=openid", @@ -87,7 +87,7 @@ def test_oauth2_password_credentials_flow_is_able_to_reuse_client( with httpx.Client() as client: client.get("https://authorized_only", auth=auth) - time.sleep(10) + time.sleep(2) httpx_mock.add_response( method="POST", @@ -134,7 +134,7 @@ def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_token_ref json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", - "expires_in": 10, + "expires_in": 2, "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter": "example_value", }, @@ -155,7 +155,7 @@ def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_token_ref with httpx.Client() as client: client.get("https://authorized_only", auth=auth) - time.sleep(10) + time.sleep(2) httpx_mock.add_response( method="POST", diff --git a/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password_async.py b/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password_async.py index 66a233d..b070d87 100644 --- a/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password_async.py +++ b/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password_async.py @@ -64,7 +64,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client( json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", - "expires_in": 10, + "expires_in": 2, "example_parameter": "example_value", }, match_content=b"grant_type=password&username=test_user&password=test_pwd", @@ -81,7 +81,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client( async with httpx.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) - time.sleep(10) + time.sleep(2) httpx_mock.add_response( method="POST", @@ -124,7 +124,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_tok json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", - "expires_in": 10, + "expires_in": 2, "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter": "example_value", }, @@ -142,7 +142,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_tok async with httpx.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) - time.sleep(10) + time.sleep(2) httpx_mock.add_response( method="POST", diff --git a/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password_sync.py b/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password_sync.py index d18d6fb..3988419 100644 --- a/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password_sync.py +++ b/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password_sync.py @@ -60,7 +60,7 @@ def test_oauth2_password_credentials_flow_is_able_to_reuse_client( json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", - "expires_in": 10, + "expires_in": 2, "example_parameter": "example_value", }, match_content=b"grant_type=password&username=test_user&password=test_pwd", @@ -77,7 +77,7 @@ def test_oauth2_password_credentials_flow_is_able_to_reuse_client( with httpx.Client() as client: client.get("https://authorized_only", auth=auth) - time.sleep(10) + time.sleep(2) httpx_mock.add_response( method="POST", @@ -118,7 +118,7 @@ def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_token_ref json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", - "expires_in": 10, + "expires_in": 2, "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter": "example_value", }, @@ -136,7 +136,7 @@ def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_token_ref with httpx.Client() as client: client.get("https://authorized_only", auth=auth) - time.sleep(10) + time.sleep(2) httpx_mock.add_response( method="POST",