"""Validation Schemas tests.""" from marshmallow import ValidationError import pytest from werkzeug.datastructures import ImmutableMultiDict from asset_transcoder.constants import schema def test_asset_upload_schema_success(): """Test AssetUploadSchema do successful validation.""" data = dict( object_id='1', object_type='episode', filename='filename.wav', original_filename='original_filename', asset_type='asset_type' ) result = schema.AssetUploadPayloadSchema().load(data) assert result['object_id'] == data['object_id'] def test_asset_upload_fails_on_non_string(): """Test that AssetUploadSchema fails with non string values.""" data = dict( object_id=1, object_type='episode', filename='filename.jpg', original_filename='original_filename', asset_type='asset_type' ) with pytest.raises(ValidationError): schema.AssetUploadPayloadSchema().load(data) def test_asset_delete_schema(): """Test that asset delete schema validates input.""" payload = { 'asset_type': 'artwork', 'object_id': '1', 'object_type': 'episode', 'updated_by': 'admin' } result = schema.AssetDeletePayloadSchema().load(payload) assert result assert 'updated_by' not in result def test_asset_delete_fails(): """Test that asset delete schema fails on unknown asset_type.""" payload = { 'asset_type': 'JPG', 'object_id': '1', 'object_type': 'episode', 'updated_by': 'admin' } with pytest.raises(ValidationError): schema.AssetDeletePayloadSchema().load(payload) def test_get_assets(): """Test that get assets splits into arrays.""" payload = { 'object_ids': '1,2', 'object_types': 'episode,podcast', } result = schema.GetAssetsByIdsAndTypesSchema().load(payload) assert result['object_ids'] == ['1', '2'] assert result['object_types'] == ['episode', 'podcast'] def test_get_assets_signed_url_duration(): """Test that signed_url_duration upper limit to 4 hours.""" payload = { 'object_ids': '1,2', 'object_types': 'episode,podcast', 'signed_url_duration': 240 } result = schema.GetAssetsByIdsAndTypesSchema().load(payload) assert result['signed_url_duration'] == 240 def test_get_assets_signed_url_duration_failed(): """Test that signed_url_duration upper limit to 4 hours failed.""" payload = { 'object_ids': '1,2', 'object_types': 'episode,podcast', 'signed_url_duration': 250 } with pytest.raises(ValidationError) as err: schema.GetAssetsByIdsAndTypesSchema().load(payload) assert err.value.messages == \ {'signed_url_duration': ['Must be greater than or equal to 10 and less than or equal to 240.']} def test_get_assets_bad_object_type(): """Test that assets throws error with bad object type.""" payload = { 'object_ids': '1,2', 'object_types': 'episode,mamaDucky', } with pytest.raises(ValidationError): schema.GetAssetsByIdsAndTypesSchema().load(payload) def test_get_assets_bad_arity(): """Test that assets throws error when array sizes dont match.""" payload = { 'object_ids': '1,2', 'object_types': 'episode', } with pytest.raises(ValidationError): schema.GetAssetsByIdsAndTypesSchema().load(payload) def test_get_assets_by_ids_and_type(): """Test that get assets splits into arrays.""" payload = { 'object_ids': '1,2', } result = schema.GetAssetsByIdsAndTypeSchema().load(payload) assert result['object_ids'] == ['1', '2'] def test_get_assets_by_id_and_type_episode(): """Test that get asset by id and type for episode object.""" payload = ImmutableMultiDict({ 'object_id': 1, 'object_type': 'episode', 'asset_type': 'WAV' }) result = schema.GetAssetByIdAndTypeSchema().load(payload) assert result['object_id'] == 1 assert result['object_type'] == 'episode' assert result['asset_type'] == ['WAV'] def test_get_assets_by_id_and_type_fails_episode(): """Test that get asset by id and type fails for non wav asset type for episode object.""" payload = ImmutableMultiDict({ 'object_id': 1, 'object_type': 'episode', 'asset_type': 'MP3' }) with pytest.raises(ValidationError) as err: schema.GetAssetByIdAndTypeSchema().load(payload) assert err.value.messages == {'asset_type': {0: ['Must be one of: TIF, JPG, WAV.']}} def test_get_assets_by_id_and_type_fails_episode_error_message(): """Test that get asset by id and type fails with error message for non wav asset type for episode object.""" payload = ImmutableMultiDict({ 'object_id': 1, 'object_type': 'episode', 'asset_type': 'JPG' }) with pytest.raises(ValidationError) as err: schema.GetAssetByIdAndTypeSchema().load(payload) assert err.value.messages == {'asset_type': ['Invalid for object_type: episode. It must be [WAV]']} def test_get_assets_by_id_and_type_podcast(): """Test that get asset by id and type for podcast object.""" payload = ImmutableMultiDict({ 'object_id': 1, 'object_type': 'podcast', 'asset_type': ['TIF', 'JPG'] }) result = schema.GetAssetByIdAndTypeSchema().load(payload) assert result['object_id'] == 1 assert result['object_type'] == 'podcast' assert result['asset_type'] == ['TIF', 'JPG'] def test_get_assets_by_id_and_type_fails_podcast(): """Test that get asset by id and type fails for non wav asset type for podcast object.""" payload = { 'object_id': 1, 'object_type': 'podcast', 'asset_type': 'WAV' } with pytest.raises(ValidationError) as err: schema.GetAssetByIdAndTypeSchema().load(ImmutableMultiDict(payload)) assert err.value.messages == {'asset_type': ['Invalid for object_type: podcast. It must be [TIF, JPG]']} def test_commit_schema(): """Test commit schema.""" payload = { 'object_id': '1', } result = schema.CommitAssetSchema().load(payload) assert result['object_id'] == '1' def test_commit_schema_fails(): """Test commit schema fails.""" payload = { 'object_id': 1, } with pytest.raises(ValidationError): schema.CommitAssetSchema().load(payload) def test_post_asset_general_status_schema(): """Test post asset general status schema.""" payload = { 'filename': 'filename', 'status': 'validation_error', 'errors': { 'image_invalid_mode': 'Invalid image mode: CMYK' }, 'timestamp': '2018-12-12T12:12:12.12Z' } result = schema.PostAssetGeneralStatusSchema().load(payload) assert result['filename'] == 'filename' def test_post_asset_general_status_schema_fails(): """Test post asset general status schema fails.""" with pytest.raises(ValidationError) as err: schema.PostAssetGeneralStatusSchema().load({}) assert err.value.messages == { 'filename': ['Missing data for required field.'], 'status': ['Missing data for required field.'], 'timestamp': ['Missing data for required field.'] } def test_post_asset_final_schema(): """Test post asset final status schema.""" payload = { 'filename': 'filename', 'status': 'encoding_completed', 'errors': None, 'timestamp': '2018-12-12T12:12:12.12Z', 'final_assets': [{ 'key': 'key', 'duration': 0, 'asset_type': 'WAV', 'asset_subtype': None }] } result = schema.PostAssetFinalSchema().load(payload) assert result['filename'] == 'filename' def test_post_asset_final_schema_fails(): """Test post asset final status schema fails.""" with pytest.raises(ValidationError) as err: schema.PostAssetFinalSchema().load({}) assert err.value.messages == { 'errors': ['Missing data for required field.'], 'filename': ['Missing data for required field.'], 'status': ['Missing data for required field.'], 'timestamp': ['Missing data for required field.'], 'final_assets': ['Missing data for required field.'] } def test_replicate_episodes_audio_assets_schema(): """Test replicate episodes audio assets schema.""" payload = { 'objects': [ { 'original_episode_id': 777, 'episode_id': 123 }, { 'original_episode_id': 888, 'episode_id': 456 }, { 'original_episode_id': 999, 'episode_id': 890 }, { 'original_episode_id': 555, 'episode_id': 111 } ] } result = schema.ReplicateEpisodesAudioAssetsSchema().load(payload) assert result == payload def test_replicate_episodes_audio_assets_schema_fails(): """Test replicate episodes audio assets schema fails.""" payload = { 'objects': [ { 'original_episode_id': 777, 'episode_id': 123 }, { 'original_episode_id': 888 }, { 'episode_id': 123 }, { 'original_episode_id': '444', 'episode_id': '6666' }, { 'original_episode_id': 'abc', 'episode_id': 'xyz' } ] } with pytest.raises(ValidationError) as err: schema.ReplicateEpisodesAudioAssetsSchema().load(payload) assert err.value.messages == { 'objects': { 1: { 'episode_id': ['Missing data for required field.'] }, 2: { 'original_episode_id': ['Missing data for required field.'] }, 4: { 'original_episode_id': ['Not a valid integer.'], 'episode_id': ['Not a valid integer.'] } } } payload = { 'objects': [] } with pytest.raises(ValidationError) as err: schema.ReplicateEpisodesAudioAssetsSchema().load(payload) assert err.value.messages == {'objects': ['Shorter than minimum length 1.']} payload = { 'test': [] } with pytest.raises(ValidationError) as err: schema.ReplicateEpisodesAudioAssetsSchema().load(payload) assert err.value.messages == {'objects': ['Missing data for required field.']} def test_podcast_artwork_schema_success(): """Test PodcastArtworkAssetsSchema do successful validation.""" data = dict( original_podcast_id=1, podcast_id=1 ) assert schema.PodcastArtworkAssetSchema().load(data) def test_podcast_artwork_schema_failure(): """Test that PodcastArtworkAssetsSchema failure.""" data = {} with pytest.raises(ValidationError) as err: schema.PodcastArtworkAssetSchema().load(data) assert err.value.messages == { 'original_podcast_id': ['Missing data for required field.'], 'podcast_id': ['Missing data for required field.'] }