"""Tests for collaborator handlers.""" from datetime import datetime import json from unittest.mock import ANY, patch from owsresponse import response import pytest from collaborator.constants.split import RateType from collaborator.constants.split_type import SplitTypeId from collaborator.handlers import collaborator from collaborator.logic import reports from collaborator.schemas.split import SplitSchema from collaborator.utils import handlers @pytest.fixture(autouse=True) def _mock_auth(mocker, mock_account): """Mock authorization for every test.""" mocker.patch.object(handlers, "_verify_profile_headers") mocker.patch.object(collaborator, "check_collaborators_authorization") mock_get_account = mocker.patch.object( collaborator, "_account_from_collabs_auth_result" ) mock_get_account.return_value = mock_account @patch("collaborator.logic.collaborator.search_collaborators") def test_get_collaborators(mock_collab, test_client, mock_account): """Test GET /collaborators endpoint.""" mock_collab.return_value = response.Response(status=200, message="success") query_string = { "term": "test", "dimensions": "vendor_id", "offset": 10, "limit": 5, "has_recipient": "true", "exactly_match_term": "true", } result = test_client.get("/collaborators", query_string=query_string) mock_collab.assert_called_with( authorized_resources=[], vendor_id=None, dimensions=ANY, has_recipient=True, limit=5, offset=10, search_term="test", exactly_match_term=True, collaborator_type=None, ) assert result.status_code == 200 @patch("collaborator.utils.handlers.fetch_profile_resources") @patch("collaborator.models.ows.ows_users.get_profile_for_identity") def test_collaborator_dataloader_moneyhub_resources(m0, m1, auth_client, mocker): """Success get request.""" def _mock_check_auth(*args, **kwargs): collabs_by_id = iter([{1: "mp", 2: "mp"}, {2: "sp"}]) while True: yield next(collabs_by_id) mock_check_auth = mocker.patch.object( collaborator, "check_collaborators_authorization" ) mock_check_auth.side_effect = _mock_check_auth() request_data = {"collaborator_ids": ["1", "2", "3"]} result = auth_client.post( "/collaborators/dataloader", data=json.dumps(request_data), content_type="application/json", headers=[ ("orchard-profile-type", "SettingsProfile"), ], ) assert json.loads(result.data.decode()) == [ {"data": "mp"}, {"data": "sp"}, {"data": None}, ] def test_latest_reports_dataloader_returns_list(mocker, test_client): """Test latest reports dataloader.""" expected = [{"data": {"id": 10}}, {"data": None}] mocker.patch.object( reports, "get_latest_reports_by_collaborator_ids", return_value=expected ) result = test_client.post( "/collaborators/latest-reports-dataloader", data=json.dumps({"collaborator_ids": [1, 2]}), content_type="application/json", ) assert result.status_code == 200 assert result.json == expected # --------------------------------------------------------------------------- # GET /collaborators//splits # --------------------------------------------------------------------------- @patch("collaborator.logic.collaborator.get_splits_by_collaborator_id") def test_get_collaborator_splits_returns_logic_result(mock_get_splits, auth_client): """Returns 200 with the splits returned by the logic layer.""" mock_splits = [ SplitSchema( id=1, collaborator_id=42, identifier="1234", split_rate=1.234, split_type_id=SplitTypeId.SUBACCOUNT, rate_type=RateType.NET, created_date=datetime.now(), ), ] mock_get_splits.return_value = mock_splits result = auth_client.get( "/collaborators/42/splits", ) assert result.status_code == 200 assert result.get_json() == {"splits": [split.dump() for split in mock_splits]} mock_get_splits.assert_called_once_with(collaborator_id=42, split_types=None) @patch("collaborator.logic.collaborator.get_splits_by_collaborator_id") def test_get_collaborator_splits_passes_split_types_filter( mock_get_splits, auth_client ): """split_types from the body are forwarded to the logic layer.""" mock_get_splits.return_value = [] result = auth_client.get( "/collaborators/42/splits", query_string={"split_types": [1, 2]}, ) assert result.status_code == 200 mock_get_splits.assert_called_once_with(collaborator_id=42, split_types=[1, 2]) @patch("collaborator.logic.collaborator.get_splits_by_collaborator_id") def test_get_collaborator_splits_forbidden_when_not_authorised( mock_get_splits, auth_client, mocker ): """Returns 403 when caller is not authorised for the collaborator.""" from collaborator.constants import error from collaborator.utils.error import OwsError mocker.patch.object( collaborator, "check_collaborators_authorization", side_effect=OwsError.forbidden( code=error.ERROR_CODE_AUTHORIZATION, message=error.ERROR_MESSAGE_FORBIDDEN_USER, ), ) result = auth_client.get( "/collaborators/42/splits", ) assert result.status_code == 403 mock_get_splits.assert_not_called() def test_get_collaborator_splits_bad_request_on_invalid_split_type(auth_client): """Returns 400 when split_types contains an invalid SplitTypeId.""" result = auth_client.get( "/collaborators/42/splits", query_string={"split_types": [999]} ) assert result.status_code == 400