diff --git a/docs/ahriman.core.formatters.rst b/docs/ahriman.core.formatters.rst index 974ce7cd..f1051fd2 100644 --- a/docs/ahriman.core.formatters.rst +++ b/docs/ahriman.core.formatters.rst @@ -20,6 +20,14 @@ ahriman.core.formatters.build\_printer module :no-undoc-members: :show-inheritance: +ahriman.core.formatters.configuration\_paths\_printer module +------------------------------------------------------------ + +.. automodule:: ahriman.core.formatters.configuration_paths_printer + :members: + :no-undoc-members: + :show-inheritance: + ahriman.core.formatters.configuration\_printer module ----------------------------------------------------- diff --git a/src/ahriman/web/views/user/login.py b/src/ahriman/web/views/user/login.py index 88f662ab..5f4e49f9 100644 --- a/src/ahriman/web/views/user/login.py +++ b/src/ahriman/web/views/user/login.py @@ -64,7 +64,11 @@ class LoginView(BaseView): HTTPMethodNotAllowed: in case if method is used, but OAuth is disabled HTTPUnauthorized: if case of authorization error """ - from ahriman.core.auth.oauth import OAuth + try: + from ahriman.core.auth.oauth import OAuth + except ImportError: + # no aioauth library found + raise HTTPMethodNotAllowed(self.request.method, ["POST"]) oauth_provider = self.validator if not isinstance(oauth_provider, OAuth): # there is actually property, but mypy does not like it anyway diff --git a/tests/ahriman/conftest.py b/tests/ahriman/conftest.py index 68ad9c9e..2a6c4d92 100644 --- a/tests/ahriman/conftest.py +++ b/tests/ahriman/conftest.py @@ -88,6 +88,30 @@ def get_package_status_extended(package: Package) -> dict[str, Any]: return {"status": BuildStatus().view(), "package": package.view()} +@pytest.helpers.register +def import_error(package: str, components: list[str], mocker: MockerFixture) -> MagicMock: + """ + mock import error + + Args: + package(str): package name to import + components(list[str]): component to import if any (e.g. from ... import ...) + mocker(MockerFixture): mocker object + + Returns: + MagicMock: mocked object + """ + import builtins + _import = builtins.__import__ + + def test_import(name: str, globals: Any, locals: Any, from_list: list[str], level: Any): + if name == package and (not components or any(component in from_list for component in components)): + raise ImportError + return _import(name, globals, locals, from_list, level) + + return mocker.patch.object(builtins, "__import__", test_import) + + # generic fixtures @pytest.fixture def aur_package_ahriman() -> AURPackage: diff --git a/tests/ahriman/web/views/user/test_views_user_login.py b/tests/ahriman/web/views/user/test_views_user_login.py index 0afc7e0a..d1e7eacb 100644 --- a/tests/ahriman/web/views/user/test_views_user_login.py +++ b/tests/ahriman/web/views/user/test_views_user_login.py @@ -25,6 +25,15 @@ async def test_get_default_validator(client_with_auth: TestClient) -> None: assert response.status == 405 +async def test_get_import_error(client_with_auth: TestClient, mocker: MockerFixture) -> None: + """ + must return 405 on import error + """ + pytest.helpers.import_error("ahriman.core.auth.oauth", ["OAuth"], mocker) + response = await client_with_auth.get("/api/v1/login") + assert response.status == 405 + + async def test_get_redirect_to_oauth(client_with_oauth_auth: TestClient) -> None: """ must redirect to OAuth service provider in case if no code is supplied