"""Test helper functions.""" from datetime import date, datetime from decimal import Decimal from oto import status import pytest from collaborator.constants import error from collaborator.constants.header import COLLABORATOR_RESOURCE, LABEL_RESOURCE from collaborator.utils import helpers from collaborator.utils.error import OwsError from collaborator.utils.typing import AuthorizedResources, Resource from tests.testutils import mock_auth def test_batch(): """Test batch function.""" input_list = [1, 2, 3, 4, 5, 6, 7, 8] batch_size = 2 expected_batches_number = 4 expected_result = [[1, 2], [3, 4], [5, 6], [7, 8]] created_batches = helpers.batch(input_list, batch_size) assert len(created_batches) == expected_batches_number assert created_batches == expected_result @pytest.mark.parametrize( "input_data, expected", [ (1234, 1234), (42.01, 42.01), (True, True), (Decimal(12.34), 12.34), ("text", "text"), (date(1983, 11, 11), "1983-11-11"), (datetime(2010, 4, 20, 13, 3, 7), "2010-04-20T13:03:07"), ([1, "two", Decimal(3.14), date(2001, 2, 3)], [1, "two", 3.14, "2001-02-03"]), ( {"number": Decimal(3.14), "date": date(2001, 2, 3)}, {"number": 3.14, "date": "2001-02-03"}, ), ( [{"date": date(2001, 2, 3)}, {"date": date(2010, 9, 8)}], [{"date": "2001-02-03"}, {"date": "2010-09-08"}], ), ], ) def test_sanitize_data(input_data, expected): """Test sanitizing data.""" result = helpers.sanitize_data(input_data) assert type(result) is type(expected) assert result == expected def test_check_vendor_authorization(): """Test check_vendors_authorization function when successful.""" authorized_resources = AuthorizedResources() authorized_resources.extend( [ Resource(LABEL_RESOURCE, "25153"), Resource(LABEL_RESOURCE, "25154"), Resource(LABEL_RESOURCE, "25155"), ] ) ids = ["25154", "25155"] helpers.check_vendors_authorization(authorized_resources, ids) def test_check_vendor_authorization_failure(): """Test check_vendors_authorization function when unsuccessful.""" authorized_resources = AuthorizedResources() authorized_resources.extend([Resource(LABEL_RESOURCE, "25155")]) vendor_ids = ["25155", "25156"] with pytest.raises(OwsError) as err: helpers.check_vendors_authorization(authorized_resources, vendor_ids) assert err.value.status == status.FORBIDDEN assert err.value.code == error.ERROR_CODE_AUTHORIZATION assert err.value.message == error.ERROR_MESSAGE_FORBIDDEN_USER def test_check_vendor_authorization_failure_no_throw(): """Test check_vendors_authorization function when unsuccessful.""" authorized_resources = AuthorizedResources() authorized_resources.extend([Resource(LABEL_RESOURCE, "25155")]) vendor_ids = ["25155", "25156"] result = helpers.check_vendors_authorization( authorized_resources, vendor_ids, throw_if_unauthorized=False ) assert result == ["25155"] def test_check_vendor_authorization_via_collaborator(mocker): """Test check_vendors_authorization function when successful.""" mock_collabs = [{"id": "171", "vendor_id": "25153"}] mock_get_collabs_by_ids = mocker.patch.object( helpers.CollaboratorPersister, "get_by_ids" ) mock_get_collabs_by_ids.return_value = mock_collabs ids = ["25153"] authorized_resources = AuthorizedResources() authorized_resources.extend( [ Resource(COLLABORATOR_RESOURCE, "171"), ] ) result = helpers.check_vendors_authorization( authorized_resources, ids, allow_access_via_collaborator=True ) assert result == ["25153"] mock_get_collabs_by_ids.assert_called_with(["171"], True) def test_check_collaborators_authorization_label_resources(mocker): """Test check_collaborators_authorization function when successful.""" mock_collabs = [ {"id": "25154", "vendor_id": "1"}, {"id": "25155", "vendor_id": "2"}, ] mock_get_collabs_by_ids = mocker.patch.object( helpers.CollaboratorPersister, "get_by_ids" ) mock_get_collabs_by_ids.return_value = mock_collabs authorized_resources = AuthorizedResources() authorized_resources.extend( [ Resource(type=LABEL_RESOURCE, id="1"), Resource(type=LABEL_RESOURCE, id="2"), Resource(type=LABEL_RESOURCE, id="3"), ] ) collabs_ids = ["25154", "25153"] collabs = helpers.check_collaborators_authorization( authorized_resources, collabs_ids ) mock_get_collabs_by_ids.assert_called_with(collabs_ids, True) assert collabs == {collab["id"]: collab for collab in mock_collabs} def test_check_collaborators_authorization_collaborator_resources(mocker): """Test check_collaborators_authorization function when successful.""" mock_collabs = [ {"id": "25154", "vendor_id": "1"}, {"id": "25155", "vendor_id": "2"}, ] mock_get_collabs_by_ids = mocker.patch.object( helpers.CollaboratorPersister, "get_by_ids" ) mock_get_collabs_by_ids.return_value = mock_collabs authorized_resources = AuthorizedResources() authorized_resources.extend( [ Resource(type=COLLABORATOR_RESOURCE, id="25153"), Resource(type=COLLABORATOR_RESOURCE, id="25154"), Resource(type=COLLABORATOR_RESOURCE, id="25155"), ] ) collabs_ids = ["25154", "25153"] collabs = helpers.check_collaborators_authorization( authorized_resources, collabs_ids ) mock_get_collabs_by_ids.assert_called_with(collabs_ids, True) assert collabs == {collab["id"]: collab for collab in mock_collabs} def test_check_collaborators_authorization_failure(mocker): """Test check_collaborators_authorization fails.""" mock_collabs = [ {"id": "25154", "vendor_id": "1"}, {"id": "25155", "vendor_id": "2"}, ] mock_get_collabs_by_ids = mocker.patch.object( helpers.CollaboratorPersister, "get_by_ids" ) mock_get_collabs_by_ids.return_value = mock_collabs authorized_resources = AuthorizedResources() authorized_resources.extend([Resource(type="bogus", id="25153")]) collabs_ids = ["25154", "25153"] with pytest.raises(OwsError) as err: helpers.check_collaborators_authorization(authorized_resources, collabs_ids) assert err.value.status == status.FORBIDDEN assert err.value.code == error.ERROR_CODE_AUTHORIZATION assert err.value.message == error.ERROR_MESSAGE_FORBIDDEN_USER def test_check_collaborators_authorization_failure_no_throw(mocker): """Test check_collaborators_authorization fails.""" mock_collabs = [ {"id": "25153", "vendor_id": "1"}, {"id": "25154", "vendor_id": "2"}, ] mock_get_collabs_by_ids = mocker.patch.object( helpers.CollaboratorPersister, "get_by_ids" ) mock_get_collabs_by_ids.return_value = mock_collabs authorized_resources = AuthorizedResources() authorized_resources.extend([Resource(type=COLLABORATOR_RESOURCE, id="25153")]) collabs_ids = ["25153", "25154"] result = helpers.check_collaborators_authorization( authorized_resources, collabs_ids, throw_if_unauthorized=False ) assert result == {"25153": {"id": "25153", "vendor_id": "1"}} def test_get_from_response(): """Test get_from_response succeeds.""" result = helpers.get_from_response({"test": 1243}, "test") assert result == 1243 def test_get_from_response_missing_attr(): """Test get_from_response raises when the attribute is absent.""" with pytest.raises(OwsError) as err: helpers.get_from_response({}, "test") assert err.value.code == error.ERROR_CODE_NONETYPE_ACCESS_ATTEMPT assert err.value.message == error.ERROR_MESSAGE_NONETYPE_ACCESS_ATTEMPT.format( attr="test" ) @pytest.mark.parametrize( "resource_id, vendor_id, expected", [ (1234, 1234, True), (1234, 5678, False), ], ) def test_check_admin_access_to_vendor(mocker, resource_id, vendor_id, expected): """Test check_admin_access_to_vendor.""" mock_auth(mocker, resource_id) assert expected == helpers.check_admin_access_to_vendor( "1234", vendor_id, throw_if_unauthorized=False )