"""Test handler utilities.""" import flask from oto import status import pytest from requests.structures import CaseInsensitiveDict import application from collaborator.constants.header import ( COLLABORATOR_RESOURCE, LABEL_RESOURCE, MONEYHUB_PROFILE, ORCHARD_PROFILE_TYPE, ) from collaborator.models.ows import ows_permissions from collaborator.utils import handlers from collaborator.utils.error import OwsError from collaborator.utils.typing import Resource, User @pytest.mark.parametrize( "param, expected", [ (None, None), ("true", True), ("TrUe", True), ("1", True), ("false", False), ("FaLsE", False), ("0", False), ("PC Load Letter? What the 🦑 does that mean?", None), ], ) def test_parse_boolean_parameter(param, expected): """Test parsing boolean parameters.""" result = handlers.parse_boolean_parameter(param) assert result == expected @pytest.mark.parametrize( "required_params, body_params", [ (["test"], {"test": "lol"}), (["test"], {"what": 42, "test": "lol", "yes": True}), (["test", "what", "yes"], {"what": 42, "test": "lol", "yes": True}), ], ) def test_require_body_params_success(required_params, body_params): """Test successfully requiring params.""" @handlers.require_body_params(required_params) def example(params): assert params == body_params return flask.Response() with application.app.test_request_context(json=body_params): result = example() assert isinstance(result, flask.Response) assert result.status_code == status.OK @pytest.mark.parametrize( "required_params, body_params", [ (["test"], {"tester": "lol"}), (["test"], {"TEST": "lol"}), (["test"], {"test": None}), (["test", "what", "yes"], {"test": "lol"}), (["test"], {}), ], ) def test_require_body_params_fail(required_params, body_params): """Test failing to have required params raises OwsError.""" @handlers.require_body_params(required_params) def example(params): return flask.Response() with application.app.test_request_context(json=body_params): with pytest.raises(OwsError) as err: example() assert err.value.code == "missing_params" @pytest.mark.parametrize( "profile_type, profile_id, resource_type", [ ("CollaboratorsProfile", "66666", LABEL_RESOURCE), ("MoneyhubProfile", "12345", COLLABORATOR_RESOURCE), ], ) def test_fetch_authorized_resources_profile_headers( mocker, profile_type, profile_id, resource_type ): """Test fetching accounts from ows-perissions based on profile headers.""" app = flask.Flask(__name__) mocker.patch.object(handlers, "_verify_profile_headers", return_value=True) mocker.patch.object( handlers, "_get_profile_type_profile_id", return_value=(profile_type, profile_id), ) mock_get_permissions = mocker.patch.object( ows_permissions, "get_permissions", return_value={ "items": [ {"id": 12345}, {"id": 67890}, {"id": "*"}, ] }, ) @handlers.fetch_authorized_resources def example(authorized_resources, user): assert authorized_resources == [ Resource(type=resource_type, id="12345"), Resource(type=resource_type, id="67890"), ] assert user == User( type="Orchard-Identity-Id", id="a9b460d3-74cc-41e6-9f40-a837915f9616" ) return True with app.test_request_context() as request_context: request_context.request.headers = CaseInsensitiveDict( { "Orchard-Identity-Id": "a9b460d3-74cc-41e6-9f40-a837915f9616", } ) result = example() assert result is True mock_get_permissions.assert_called_with(profile_type, profile_id, resource_type) def test_fetch_authorized_resources_profile_unexpected_profile_type(mocker): """Test fetching accounts with unexpected profile type raises OwsError.""" mocker.patch.object(handlers, "_verify_profile_headers", return_value=True) mocker.patch.object( handlers, "_get_profile_type_profile_id", return_value=("OtherProfile", "50505") ) mock_get_permissions = mocker.patch.object(ows_permissions, "get_permissions") @handlers.fetch_authorized_resources def example(): return True app = flask.Flask(__name__) headers = {"Orchard-Identity-Id": ""} with app.test_request_context("url") as req: req.request.headers = CaseInsensitiveDict(headers) with pytest.raises(OwsError) as err: example() assert err.value.status == status.FORBIDDEN mock_get_permissions.assert_not_called() def test_fetch_authorized_resources_no_headers(mocker): """Test fetching accounts with no headers.""" mocker.patch.object(handlers, "_verify_profile_headers", return_value=False) @handlers.fetch_authorized_resources def example(authorized_resources, user): return authorized_resources result = example() assert result == [] def test_fetch_profile_type(): """Test fetching profile type.""" @handlers.fetch_profile_type def example(profile_type): return profile_type headers = {ORCHARD_PROFILE_TYPE: MONEYHUB_PROFILE} app = flask.Flask(__name__) with app.test_request_context("url") as req: req.request.headers = CaseInsensitiveDict(headers) result = example() assert result == MONEYHUB_PROFILE