"""Tests for the API utilities.""" import datetime from unittest.mock import MagicMock import flask import neo4j.time as neo_time import pytest from marshmallow import Schema, fields, validate from permissions.utils import api_utils class TestAccountSchema(Schema): """Dummy schema for testing purposes.""" account_id = fields.Integer(validate=validate.Range(min=1)) def test_post_validate_request_data(): """Test validation decorator calls decorated func.""" func = MagicMock() method = api_utils.validate_request_data(TestAccountSchema(), partial=True)(func) app = flask.Flask(__name__) with app.test_request_context('/', method='POST', json={'account_id': 10}): method() func.assert_called_once() called_kwargs = func.call_args[1] assert 'deserialize_schema' in called_kwargs assert called_kwargs['deserialize_schema']['account_id'] == 10 def test_post_validate_request_data_not_called(): """Test validation decorator doesn't call decorated func.""" func = MagicMock() method = api_utils.validate_request_data(TestAccountSchema(), partial=True)(func) app = flask.Flask(__name__) with app.test_request_context('/', method='POST', json={'account_id': 0}): flask.g.log = MagicMock() method() assert not func.called class TestGetSchema(Schema): """Dummy schema for testing purposes.""" account_id = fields.List(fields.Integer(validate=validate.Range(min=1))) def test_get_params_validate_request_data(): """Test validation decorator for query params.""" func = MagicMock() method = api_utils.validate_request_data(TestGetSchema(), partial=True)(func) app = flask.Flask(__name__) with app.test_request_context('/', method='GET', query_string={'account_id': '10'}): method() func.assert_called_once() called_kwargs = func.call_args[1] assert 'deserialize_schema' in called_kwargs assert called_kwargs['deserialize_schema']['account_id'] == [10] def test_head_validate_request_data(): """Test validation decorator for HEAD request.""" func = MagicMock() method = api_utils.validate_request_data(TestAccountSchema(), partial=True)(func) app = flask.Flask(__name__) with app.test_request_context('/', method='HEAD'): method() func.assert_called_once() called_kwargs = func.call_args[1] assert 'deserialize_schema' in called_kwargs def test_to_snake(): """Test to_snake method for dictionary.""" data = {'camelCase': 'value'} result = api_utils.to_snake(data) assert result == {'camel_case': 'value'} @pytest.mark.parametrize( ('data', 'expected'), [ ({'key': 'value'}, {'key': 'value'}), ( {'key': 'value', 'some_date': datetime.datetime.fromtimestamp(1585741340)}, {'key': 'value', 'some_date': datetime.datetime.fromtimestamp(1585741340).__str__()}, ), ( {'key': neo_time.DateTime.utc_from_timestamp(1585741340), 'foo': 'bar'}, {'key': neo_time.DateTime.utc_from_timestamp(1585741340).__str__(), 'foo': 'bar'}, ), ], ) def test_to_serializable_dict(data, expected): """Test to_serializable_dict method for dictionary.""" result = api_utils.to_serializable_dict(data) assert result == expected