from unittest.mock import MagicMock import pytest from huesoporro.actions.quotes.create_quote_action import CreateQuoteAction from huesoporro.actions.quotes.get_random_quote import GetRandomQuoteAction from huesoporro.actions.users.authenticate_user import AuthenticateUserAction from huesoporro.actions.users.get_user_by_jwt import GetUserByJWTAction from huesoporro.actions.users.refresh_user_jwt import RefreshUserJwtAction from huesoporro.infra.authenticator import TwitchAuthenticator from huesoporro.models import Quote, TwitchAuth from huesoporro.svc.users_svcs import IsValidTokenSvc, RefreshTokenSvc class AsyncMock(MagicMock): async def __call__(self, *args, **kwargs): return super().__call__(*args, **kwargs) @pytest.fixture def twitch_authenticator(s): return TwitchAuthenticator(s=s) @pytest.fixture def fake_twitch_authenticator(): return AsyncMock() @pytest.fixture def refresh_token_svc(twitch_authenticator, fake_twitch_authenticator, s): svc = RefreshTokenSvc(twitch_authenticator=twitch_authenticator) svc.twitch_authenticator = fake_twitch_authenticator return svc @pytest.fixture def is_valid_svc(twitch_authenticator, fake_twitch_authenticator): svc = IsValidTokenSvc(authenticator=twitch_authenticator) svc.authenticator = fake_twitch_authenticator return svc @pytest.fixture def get_user_by_jwt_action( s, get_user_by_username_svc, update_user_svc, is_valid_svc, refresh_token_svc ): return GetUserByJWTAction( get_user_by_username_svc=get_user_by_username_svc, update_user_svc=update_user_svc, refresh_token_svc=refresh_token_svc, is_valid_token_svc=is_valid_svc, s=s, ) @pytest.fixture def refresh_user_jwt_action( s, get_user_by_username_svc, update_user_svc, is_valid_svc, refresh_token_svc ): return RefreshUserJwtAction( get_user_by_username_svc=get_user_by_username_svc, update_user_svc=update_user_svc, refresh_token_svc=refresh_token_svc, is_valid_token_svc=is_valid_svc, s=s, ) @pytest.fixture def authenticate_user_action( # noqa: PLR0913 s, get_user_by_username_svc, get_twitch_auth_by_auth_code_svc, update_user_svc, create_user_svc, twitch_authenticator, ): return AuthenticateUserAction( get_user_by_username_svc=get_user_by_username_svc, update_user_svc=update_user_svc, create_user_svc=create_user_svc, get_tokens_by_auth_code_svc=get_twitch_auth_by_auth_code_svc, s=s, ) @pytest.fixture def get_random_quote_action(get_random_quote_svc): return GetRandomQuoteAction(get_random_quote_svc=get_random_quote_svc) @pytest.fixture def create_random_quote_action(create_quote_svc, is_mod_svc): return CreateQuoteAction(create_quote_svc=create_quote_svc, is_mod_svc=is_mod_svc) async def test_get_user_by_jwt_action_raises_value_error( get_user_by_jwt_action: GetUserByJWTAction, user, s ): with pytest.raises(ValueError, match=f"User {user.username} not found"): await get_user_by_jwt_action.run(jwt_token=user.encode(settings=s)) async def test_get_user_by_jwt_returns_user( get_user_by_jwt_action: GetUserByJWTAction, persisted_user, s, fake_twitch_authenticator, ): fake_twitch_authenticator.token_is_valid.return_value = True jwt = persisted_user.encode(settings=s) assert await get_user_by_jwt_action.run(jwt_token=jwt) async def test_get_user_by_jwt_returns_refreshed_user( get_user_by_jwt_action: GetUserByJWTAction, persisted_user, s, fake_twitch_authenticator, ): jwt = persisted_user.encode(settings=s) fake_twitch_authenticator.token_is_valid.return_value = False fake_twitch_authenticator.refresh_token.return_value = TwitchAuth( access_token="mocked", # noqa: S106 refresh_token="mocked", # noqa: S106 userinfo={}, ) assert await get_user_by_jwt_action.run(jwt_token=jwt) async def test_refresh_user_jwt_returns_none_on_valid_token( refresh_user_jwt_action: RefreshUserJwtAction, persisted_user, s, fake_twitch_authenticator, ): fake_twitch_authenticator.token_is_valid.return_value = True assert await refresh_user_jwt_action.run(user=persisted_user) is None async def test_refresh_user_jwt_returns_updated_user( refresh_user_jwt_action: RefreshUserJwtAction, persisted_user, s, fake_twitch_authenticator, ): fake_twitch_authenticator.token_is_valid.return_value = False fake_twitch_authenticator.refresh_token.return_value = TwitchAuth( access_token="mocked", # noqa: S106 refresh_token="mocked", # noqa: S106 userinfo={}, ) user = await refresh_user_jwt_action.run(user=persisted_user) assert user assert user.twitch_access_token == "mocked" # noqa: S105 assert user.twitch_refresh_token == "mocked" # noqa: S105 async def test_authenticate_existing_user_returns_user( persisted_user, authenticate_user_action, fake_twitch_authenticator ): fake_twitch_authenticator.get_token.return_value = TwitchAuth( access_token="mocked", # noqa: S106 refresh_token="mocked", # noqa: S106 userinfo={"preferred_username": persisted_user.username}, ) user = await authenticate_user_action.run(auth_code="mocked") assert user.id == persisted_user.id assert user.username == persisted_user.username assert user.twitch_access_token == "mocked" != persisted_user.twitch_access_token # noqa: S105 assert ( user.twitch_refresh_token == "mocked" # noqa: S105 != persisted_user.external_auth["twitch"].refresh_token ) async def test_authenticate_raises_value_error_on_not_allowed_user( authenticate_user_action, fake_twitch_authenticator ): fake_twitch_authenticator.get_token.return_value = TwitchAuth( access_token="mocked", # noqa: S106 refresh_token="mocked", # noqa: S106 userinfo={"preferred_username": "not_allowed"}, ) with pytest.raises(ValueError, match="User not_allowed is not allowed"): await authenticate_user_action.run(auth_code="mocked") async def test_authenticate_user( authenticate_user_action, fake_twitch_authenticator, user ): fake_twitch_authenticator.get_token.return_value = TwitchAuth( access_token="mocked", # noqa: S106 refresh_token="mocked", # noqa: S106 userinfo={"preferred_username": user.username}, ) user = await authenticate_user_action.run(auth_code="mocked") assert user.username == user.username async def test_get_random_quote_action( get_random_quote_action: GetRandomQuoteAction, persisted_quote: Quote ): assert ( await get_random_quote_action.run(persisted_quote.channel_name) == persisted_quote ) async def test_create_quote_action_returns_none_on_not_mod_user( create_random_quote_action: CreateQuoteAction, user ): assert ( await create_random_quote_action.run( user=user, channel=user.username, quote="mocked", author="mocked", username="mocked", ) is None ) async def test_create_quote_action( create_random_quote_action: CreateQuoteAction, user, quote: Quote, persisted_user ): quote.channel_name = persisted_user.username new_quote = await create_random_quote_action.run( user=persisted_user, username=user.username, channel=user.username, quote=quote.quote, is_active=quote.is_active, author=quote.author, ) assert new_quote quote.id = new_quote.id quote.created_at = new_quote.created_at quote.last_updated_at = new_quote.last_updated_at assert quote == new_quote