From 2b2d5cbd8db6e455dbdba8a70cd42844eaf1281b Mon Sep 17 00:00:00 2001 From: Richard Ogundele <63150179+richardogundele@users.noreply.github.com> Date: Fri, 26 Sep 2025 14:40:16 +0100 Subject: [PATCH 1/2] fix: add missing imports --- api_app/api/routes/resource_helpers.py | 9 ++- .../test_routes/test_resource_helpers.py | 58 +++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/api_app/api/routes/resource_helpers.py b/api_app/api/routes/resource_helpers.py index d3dff6594f..c949a968fa 100644 --- a/api_app/api/routes/resource_helpers.py +++ b/api_app/api/routes/resource_helpers.py @@ -26,6 +26,8 @@ ) from services.authentication import get_access_service from services.logging import logger +from services.access_service import AuthConfigValidationError +from core import config async def delete_validation(resource: Resource, resource_repo: ResourceRepository): @@ -158,7 +160,12 @@ def construct_location_header(operation: Operation) -> str: def get_identity_role_assignments(user): access_service = get_access_service() - return access_service.get_identity_role_assignments(user.id) + try: + return access_service.get_identity_role_assignments(user.id) + except AuthConfigValidationError: + if config.USER_MANAGEMENT_ENABLED: + raise + return [] def get_app_user_roles_assignments_emails(app_obj_id): diff --git a/api_app/tests_ma/test_api/test_routes/test_resource_helpers.py b/api_app/tests_ma/test_api/test_routes/test_resource_helpers.py index 31fb31e5f1..1f64136d29 100644 --- a/api_app/tests_ma/test_api/test_routes/test_resource_helpers.py +++ b/api_app/tests_ma/test_api/test_routes/test_resource_helpers.py @@ -1,3 +1,61 @@ +from types import SimpleNamespace +import pytest +from mock import patch + +from services.access_service import AuthConfigValidationError + + +@patch("api.routes.resource_helpers.get_access_service") +def test_get_identity_role_assignments_fallback_when_user_mgmt_disabled(get_access_service_mock): + # Arrange: access service raises auth config error + class FakeAccessService: + def get_identity_role_assignments(self, user_id: str): + raise AuthConfigValidationError("graph not available") + + get_access_service_mock.return_value = FakeAccessService() + + # Force feature disabled + from core import config as core_config + original_value = core_config.USER_MANAGEMENT_ENABLED + core_config.USER_MANAGEMENT_ENABLED = False + + try: + from api.routes import resource_helpers + user = SimpleNamespace(id="user-id") + + # Act + result = resource_helpers.get_identity_role_assignments(user) + + # Assert + assert result == [] + finally: + core_config.USER_MANAGEMENT_ENABLED = original_value + + +@patch("api.routes.resource_helpers.get_access_service") +def test_get_identity_role_assignments_raises_when_user_mgmt_enabled(get_access_service_mock): + # Arrange: access service raises auth config error + class FakeAccessService: + def get_identity_role_assignments(self, user_id: str): + raise AuthConfigValidationError("graph not available") + + get_access_service_mock.return_value = FakeAccessService() + + # Force feature enabled + from core import config as core_config + original_value = core_config.USER_MANAGEMENT_ENABLED + core_config.USER_MANAGEMENT_ENABLED = True + + try: + from api.routes import resource_helpers + user = SimpleNamespace(id="user-id") + + # Act / Assert + with pytest.raises(AuthConfigValidationError): + resource_helpers.get_identity_role_assignments(user) + finally: + core_config.USER_MANAGEMENT_ENABLED = original_value + import datetime from unittest.mock import AsyncMock import uuid From e61af8574d0771c6134b213d3cd2bccc63096f72 Mon Sep 17 00:00:00 2001 From: Richard Ogundele <63150179+richardogundele@users.noreply.github.com> Date: Fri, 3 Oct 2025 14:16:19 +0100 Subject: [PATCH 2/2] test: use unittest.mock and monkeypatch for USER_MANAGEMENT_ENABLED --- api_app/tests_ma/conftest.py | 2 +- api_app/tests_ma/test_api/conftest.py | 2 +- .../test_routes/test_resource_helpers.py | 46 ++++++++----------- 3 files changed, 21 insertions(+), 29 deletions(-) diff --git a/api_app/tests_ma/conftest.py b/api_app/tests_ma/conftest.py index 6245ec23ec..bc6155ada7 100644 --- a/api_app/tests_ma/conftest.py +++ b/api_app/tests_ma/conftest.py @@ -1,6 +1,6 @@ import pytest import pytest_asyncio -from mock import AsyncMock, patch +from unittest.mock import AsyncMock, patch from azure.cosmos.aio import CosmosClient, DatabaseProxy from api.dependencies.database import Database diff --git a/api_app/tests_ma/test_api/conftest.py b/api_app/tests_ma/test_api/conftest.py index b386ce32bd..99be35034d 100644 --- a/api_app/tests_ma/test_api/conftest.py +++ b/api_app/tests_ma/test_api/conftest.py @@ -1,6 +1,6 @@ import pytest import pytest_asyncio -from mock import patch +from unittest.mock import patch from fastapi import FastAPI from httpx import AsyncClient diff --git a/api_app/tests_ma/test_api/test_routes/test_resource_helpers.py b/api_app/tests_ma/test_api/test_routes/test_resource_helpers.py index 1f64136d29..9d1f4bf0cb 100644 --- a/api_app/tests_ma/test_api/test_routes/test_resource_helpers.py +++ b/api_app/tests_ma/test_api/test_routes/test_resource_helpers.py @@ -1,12 +1,12 @@ from types import SimpleNamespace import pytest -from mock import patch +from unittest.mock import patch from services.access_service import AuthConfigValidationError @patch("api.routes.resource_helpers.get_access_service") -def test_get_identity_role_assignments_fallback_when_user_mgmt_disabled(get_access_service_mock): +def test_get_identity_role_assignments_fallback_when_user_mgmt_disabled(get_access_service_mock, monkeypatch): # Arrange: access service raises auth config error class FakeAccessService: def get_identity_role_assignments(self, user_id: str): @@ -14,26 +14,22 @@ def get_identity_role_assignments(self, user_id: str): get_access_service_mock.return_value = FakeAccessService() - # Force feature disabled + # Force feature disabled using monkeypatch to avoid test pollution from core import config as core_config - original_value = core_config.USER_MANAGEMENT_ENABLED - core_config.USER_MANAGEMENT_ENABLED = False + monkeypatch.setattr(core_config, "USER_MANAGEMENT_ENABLED", False) - try: - from api.routes import resource_helpers - user = SimpleNamespace(id="user-id") + from api.routes import resource_helpers + user = SimpleNamespace(id="user-id") - # Act - result = resource_helpers.get_identity_role_assignments(user) + # Act + result = resource_helpers.get_identity_role_assignments(user) - # Assert - assert result == [] - finally: - core_config.USER_MANAGEMENT_ENABLED = original_value + # Assert + assert result == [] @patch("api.routes.resource_helpers.get_access_service") -def test_get_identity_role_assignments_raises_when_user_mgmt_enabled(get_access_service_mock): +def test_get_identity_role_assignments_raises_when_user_mgmt_enabled(get_access_service_mock, monkeypatch): # Arrange: access service raises auth config error class FakeAccessService: def get_identity_role_assignments(self, user_id: str): @@ -41,27 +37,23 @@ def get_identity_role_assignments(self, user_id: str): get_access_service_mock.return_value = FakeAccessService() - # Force feature enabled + # Force feature enabled using monkeypatch to avoid test pollution from core import config as core_config - original_value = core_config.USER_MANAGEMENT_ENABLED - core_config.USER_MANAGEMENT_ENABLED = True + monkeypatch.setattr(core_config, "USER_MANAGEMENT_ENABLED", True) - try: - from api.routes import resource_helpers - user = SimpleNamespace(id="user-id") + from api.routes import resource_helpers + user = SimpleNamespace(id="user-id") - # Act / Assert - with pytest.raises(AuthConfigValidationError): - resource_helpers.get_identity_role_assignments(user) - finally: - core_config.USER_MANAGEMENT_ENABLED = original_value + # Act / Assert + with pytest.raises(AuthConfigValidationError): + resource_helpers.get_identity_role_assignments(user) import datetime from unittest.mock import AsyncMock import uuid import pytest import pytest_asyncio -from mock import patch +from unittest.mock import patch import json from fastapi import HTTPException, status