"""Test api_utils.""" from unittest.mock import patch import pytest from flask import Flask from marshmallow import Schema, fields from account.utils.api_utils import validate_request_data class MinimalSchema(Schema): """Minimal test schema.""" name = fields.Str(required=True) age = fields.Int() @pytest.fixture def app(): """Create test app.""" app = Flask(__name__) return app def test_validate_request_data_with_valid_data(app): """Test validate_request_data with valid marshmallow schema.""" with app.test_request_context(json={'name': 'test', 'age': 25}, method='POST'): schema = MinimalSchema() @validate_request_data(schema) def dummy_handler(deserialize_schema): # Verify that the deserialized schema is properly passed assert deserialize_schema == {'name': 'test', 'age': 25} return 'success' result = dummy_handler() assert result == 'success' def test_validate_request_data_with_marshmallow_validation_error(app): """Test validate_request_data with data that fails marshmallow validation.""" with app.test_request_context(json={'age': 'not_an_integer'}, method='POST'): schema = MinimalSchema() @validate_request_data(schema) def dummy_handler(deserialize_schema): return 'success' with patch('account.utils.api_utils.sentry_client') as mock_sentry: result = dummy_handler() mock_sentry.capture_exception.assert_called_once() # The result should be a Flask response with validation error assert result is not None # For marshmallow ValidationError, the message should be a dict response_data = result.get_json() assert response_data['message'] == { 'age': ['Not a valid integer.'], 'name': ['Missing data for required field.'], } @pytest.mark.parametrize( 'invalid_json_data', [ pytest.param('invalid_string', id='string instead of dict'), pytest.param(True, id="boolean that can't use update method"), ], ) def test_validate_request_data_with_invalid_data(app, invalid_json_data): """Test validate_request_data with invalid data types.""" with app.test_request_context(json=invalid_json_data, method='POST'): schema = MinimalSchema() @validate_request_data(schema) def dummy_handler(deserialize_schema): return 'success' with patch('account.utils.api_utils.sentry_client') as mock_sentry: result = dummy_handler() mock_sentry.capture_exception.assert_called_once() # The result should be a Flask response with validation error assert result is not None # For AttributeError, the message should be a string response_data = result.get_json() assert "object has no attribute 'update'" in response_data['message'] def test_validate_request_data_with_get_request(app): """Test validate_request_data with GET request parameters.""" with app.test_request_context('/?name=test&age=25', method='GET'): schema = MinimalSchema() @validate_request_data(schema) def dummy_handler(deserialize_schema): # Verify that the deserialized schema is properly passed for GET requests assert deserialize_schema == {'name': 'test', 'age': 25} return 'success' result = dummy_handler() assert result == 'success' def test_validate_request_data_with_partial_validation(app): """Test validate_request_data with partial validation enabled.""" with app.test_request_context(json={'age': 30}, method='POST'): schema = MinimalSchema() @validate_request_data(schema, partial=True) def dummy_handler(deserialize_schema): # Verify that partial validation allows missing required fields assert deserialize_schema == {'age': 30} return 'success' result = dummy_handler() assert result == 'success'