"""Tests for validation module.""" from typing import Any, Callable from unittest import mock import pytest from flask import Request, Response from transcoding.constants import field_const, transcoding as transcoding_constants from transcoding.validation import json_schema from transcoding.validation.schema import body def get_json_mock(response: Any) -> Callable[..., Any]: """Return mock json from request body.""" return lambda silent: response @pytest.fixture def valid_post_transcoding_body() -> dict[str, Any]: """Return valid post_transcoding body. Returns: dict: Body dict. """ return { field_const.INPUT: { field_const.BUCKET: "bucket_name", field_const.KEY: "track.wav", }, field_const.OUTPUT: { field_const.BUCKET: "output_bucket_name", field_const.TRANSCODING: [ { field_const.CONTAINER: "wave", field_const.CODEC: "pcm", field_const.SAMPLE_RATE: 48000, field_const.BIT_RATE: 1536000, field_const.CHANNELS: 2, field_const.BIT_DEPTH: 16, } ], }, field_const.STATUS_TOPIC_ALIAS: None, } def fixture_post_transcoding_function(request: Request) -> Response: """Mock real endpoint handler.""" @json_schema.validate_body(request, body.post_transcoding_schema) def function() -> Response: return Response("test_result") return function() def test_post_final_status_validate_body_success( valid_post_transcoding_body: dict[str, Any], ) -> None: """Assert that validate_body succeeds when body is valid.""" request = mock.Mock() request.get_json = get_json_mock(valid_post_transcoding_body) result = fixture_post_transcoding_function(request) assert result.data.decode() == "test_result" @pytest.mark.parametrize( "missing_field", [ field_const.INPUT, field_const.OUTPUT, ], ) def test_post_final_status_validate_body_failure( missing_field: str, valid_post_transcoding_body: dict[str, Any] ) -> None: """Assert that validate_body fails when field is missing.""" request = mock.Mock() valid_post_transcoding_body.pop(missing_field) request.get_json = get_json_mock(valid_post_transcoding_body) result = fixture_post_transcoding_function(request) assert result.status_code == 400 @pytest.mark.parametrize("object_field_name", [field_const.INPUT, field_const.OUTPUT]) def test_post_final_status_validate_body_message_failure( object_field_name: str, valid_post_transcoding_body: dict[str, Any] ) -> None: """Assert that validate_body fails when nested objects are string.""" request = mock.Mock() valid_post_transcoding_body[object_field_name] = "invalid value" request.get_json = get_json_mock(valid_post_transcoding_body) result = fixture_post_transcoding_function(request) assert result.status_code == 400 @pytest.fixture def valid_post_transcoding_job_status_body() -> dict[str, Any]: """Return valid post_transcoding_status body. Returns: dict: Body dict. """ return { field_const.STATUS: "completed", field_const.STATUS_DESCRIPTION: "completed_description", field_const.DURATION: 1099, } def fixture_post_transcoding_status_function(request: Request) -> Response: """Mock real endpoint handler.""" @json_schema.validate_body(request, body.post_transcoding_job_status_schema) def function() -> Response: return Response("test_result") return function() @pytest.mark.parametrize("status", transcoding_constants.INCOMING_TRANSCODING_STATUSES) def test_post_job_status_validate_body_success( status: str, valid_post_transcoding_job_status_body: dict[str, Any] ) -> None: """Assert that validate_body succeed.""" valid_post_transcoding_job_status_body["status"] = status request = mock.Mock() request.get_json = get_json_mock(valid_post_transcoding_job_status_body) result = fixture_post_transcoding_status_function(request) assert result.data.decode() == "test_result" def test_post_job_status_validate_body_missing_status( valid_post_transcoding_job_status_body: dict[str, Any], ) -> None: """Assert that validate_body fails when field is missing.""" request = mock.Mock() valid_post_transcoding_job_status_body.pop(field_const.STATUS) request.get_json = get_json_mock(valid_post_transcoding_job_status_body) result = fixture_post_transcoding_status_function(request) assert result.status_code == 400 @pytest.mark.parametrize( "missing_field", [field_const.STATUS_DESCRIPTION, field_const.DURATION] ) def test_post_job_status_validate_body_missing_optional_fields( valid_post_transcoding_job_status_body: dict[str, Any], missing_field: str ) -> None: """Assert that status_description is optional.""" request = mock.Mock() valid_post_transcoding_job_status_body.pop(missing_field) request.get_json = get_json_mock(valid_post_transcoding_job_status_body) result = fixture_post_transcoding_status_function(request) assert result.data.decode() == "test_result"