"""Tests for Profile v2 Handlers.""" import uuid from unittest.mock import MagicMock, patch import pytest from flask.app import AppContext from flask.testing import FlaskClient from permissions.types import Subaccount, Vendor @pytest.mark.parametrize( ( 'context_type', 'profile_type', 'profile_id', 'identity_id', 'vendors_list', 'expected_status', 'expected_response', ), [ pytest.param( 'account', '', '', '550e8400-e29b-41d4-a716-446655440000', None, 403, {'code': 'authorization_error', 'message': 'access denied'}, id='wrong_context_type', ), pytest.param( 'profile', 'AbacusProfile', '12345', '550e8400-e29b-41d4-a716-446655440000', [ Vendor(vendor_uuid='vendor-uuid-123', vendor_id=101), Vendor(vendor_uuid='vendor-uuid-456', vendor_id=102), ], 200, { 'vendors': [ {'vendor_uuid': 'vendor-uuid-123', 'vendor_id': 101}, {'vendor_uuid': 'vendor-uuid-456', 'vendor_id': 102}, ] }, id='happy_path', ), ], ) @patch('permissions.logic.vendor.get_directly_accessible_vendors_by_profile') @patch('permissions.utils.api_utils.g') @patch('permissions.handlers.profile_v2_handlers.g') def test_get_directly_accessible_vendors_by_profile_route( mock_g: MagicMock, mock_g2: MagicMock, mock_get_vendors: MagicMock, context_type: str, profile_type: str, profile_id: str, identity_id: str, vendors_list, expected_status: int, expected_response: list | dict, app_context: AppContext, fixture_client: FlaskClient, ) -> None: """Test the Flask route handler for get_directly_accessible_vendors_by_profile.""" # Mock the request context mock_g.request_context.context_type = context_type mock_g.request_context.profile_type = profile_type mock_g.request_context.profile_id = profile_id mock_g.request_context.jwt_identity_id = identity_id mock_g2.request_context.jwt_identity_id = identity_id # Mock the vendor logic function mock_get_vendors.return_value = vendors_list if vendors_list else [] headers = { 'Orchard-Identity-Id': identity_id, 'Orchard-Profile-Id': profile_id, 'Orchard-Profile-Type': profile_type, 'Orchard-Requestor-Service': 'ows-account', } handler_response = fixture_client.get('/v2/profile/self/vendors/direct-access', headers=headers) # Check the result assert handler_response assert handler_response.status_code == expected_status assert handler_response.json == expected_response # Verify function calls based on test case if expected_status == 200: mock_get_vendors.assert_called_once_with( identity_id=uuid.UUID(identity_id), profile_id=int(profile_id), profile_type=profile_type, ) else: # For error cases, vendor logic function should not be called mock_get_vendors.assert_not_called() @pytest.mark.parametrize( ( 'context_type', 'profile_type', 'profile_id', 'identity_id', 'has_access_result', 'expected_status', 'expected_response', ), [ pytest.param( 'account', '', '', '550e8400-e29b-41d4-a716-446655440000', None, 403, {'code': 'authorization_error', 'message': 'access denied'}, id='wrong_context_type', ), pytest.param( 'profile', 'AbacusProfile', '12345', '550e8400-e29b-41d4-a716-446655440000', True, 200, {'has_access': True}, id='happy_path_has_access', ), pytest.param( 'profile', 'AbacusProfile', '12345', '550e8400-e29b-41d4-a716-446655440000', False, 200, {'has_access': False}, id='happy_path_no_access', ), ], ) @patch('permissions.models.profile.check_vendor_star_access_v2') @patch('permissions.handlers.profile_v2_handlers.g') def test_check_profile_all_label_access_route( mock_g: MagicMock, mock_check_access: MagicMock, context_type: str, profile_type: str, profile_id: str, identity_id: str, has_access_result: bool, expected_status: int, expected_response: dict, app_context: AppContext, fixture_client: FlaskClient, ) -> None: """Test the Flask route handler for check_profile_all_label_access.""" # Mock the request context mock_g.request_context.context_type = context_type mock_g.request_context.profile_type = profile_type mock_g.request_context.profile_id = profile_id mock_g.request_context.identity_id = identity_id # Mock the profile model function mock_check_access.return_value = has_access_result headers = { 'Orchard-Identity-Id': identity_id, 'Orchard-Profile-Id': profile_id, 'Orchard-Profile-Type': profile_type, 'Orchard-Requestor-Service': 'ows-account', } handler_response = fixture_client.get('/v2/profile/self/all-label-access', headers=headers) # Check the result assert handler_response assert handler_response.status_code == expected_status assert handler_response.json == expected_response # Verify function calls based on test case if expected_status == 200: mock_check_access.assert_called_once_with( identity_id=uuid.UUID(identity_id), profile_id=int(profile_id), profile_type=profile_type, ) else: # For error cases, profile model function should not be called mock_check_access.assert_not_called() @pytest.mark.parametrize( ( 'context_type', 'profile_type', 'profile_id', 'identity_id', 'subaccounts_list', 'expected_status', 'expected_response', ), [ pytest.param( 'account', '', '', '550e8400-e29b-41d4-a716-446655440000', None, 403, {'code': 'authorization_error', 'message': 'access denied'}, id='wrong_context_type', ), pytest.param( 'profile', 'AbacusProfile', '12345', '550e8400-e29b-41d4-a716-446655440000', [ Subaccount(subaccount_uuid='subaccount-uuid-123', subaccount_id=201), Subaccount(subaccount_uuid='subaccount-uuid-456', subaccount_id=202), ], 200, { 'subaccounts': [ {'subaccount_uuid': 'subaccount-uuid-123', 'subaccount_id': 201}, {'subaccount_uuid': 'subaccount-uuid-456', 'subaccount_id': 202}, ] }, id='happy_path', ), ], ) @patch('permissions.logic.subaccount.get_directly_accessible_subaccounts_by_profile') @patch('permissions.utils.api_utils.g') @patch('permissions.handlers.profile_v2_handlers.g') def test_get_directly_accessible_subaccounts_by_profile_route( mock_g: MagicMock, mock_g2: MagicMock, mock_get_subaccounts: MagicMock, context_type: str, profile_type: str, profile_id: str, identity_id: str, subaccounts_list, expected_status: int, expected_response: list | dict, app_context: AppContext, fixture_client: FlaskClient, ) -> None: """Test the Flask route handler for get_directly_accessible_subaccounts_by_profile.""" # Mock the request context mock_g.request_context.context_type = context_type mock_g.request_context.profile_type = profile_type mock_g.request_context.profile_id = profile_id mock_g.request_context.jwt_identity_id = identity_id mock_g2.request_context.jwt_identity_id = identity_id # Mock the subaccount logic function mock_get_subaccounts.return_value = subaccounts_list if subaccounts_list else [] headers = { 'Orchard-Identity-Id': identity_id, 'Orchard-Profile-Id': profile_id, 'Orchard-Profile-Type': profile_type, 'Orchard-Requestor-Service': 'ows-account', } handler_response = fixture_client.get( '/v2/profile/self/subaccounts/direct-access', headers=headers ) # Check the result assert handler_response assert handler_response.status_code == expected_status assert handler_response.json == expected_response # Verify function calls based on test case if expected_status == 200: mock_get_subaccounts.assert_called_once_with( identity_id=uuid.UUID(identity_id), profile_id=int(profile_id), profile_type=profile_type, ) else: # For error cases, subaccount logic function should not be called mock_get_subaccounts.assert_not_called()