"""Validation Schemas tests.""" import decimal from marshmallow import ValidationError import pytest from werkzeug.datastructures import ImmutableMultiDict from podcast.constants import analytics as analytics_constants from podcast.constants import schema from podcast.constants.error import ( ERROR_INCORRECT_DATE_FORMAT, ERROR_REQUIRED_DATE, ERROR_START_DATE_GREATER_THAN_END_DATE) from podcast.utils.exc import OwsError def test_insertion_points_success(): """Test InsertionPoint Schema validation success.""" payload = [ {'point_type': 'mid', 'count': 1, 'timecode': '3.14'}, {'point_type': 'pre', 'count': 3, 'timecode': '20.12'}, ] result = schema.InsertionPointsPayloadSchema(many=True).load(payload) assert result[0]['timecode'] == decimal.Decimal(payload[0]['timecode']) def test_insertion_points_unknown_type(): """Test InsertionPoint Schema fails with unknown point_type.""" payload = [ {'point_type': 'mid', 'count': 1, 'timecode': '3.14'}, {'point_type': 'pre_pro', 'count': 3, 'timecode': '20.12'}, ] with pytest.raises(ValidationError): schema.InsertionPointsPayloadSchema(many=True).load(payload) def test_insertion_points_extra_field(): """Test InsertionPoint Schema fails with extra field.""" payload = [ {'point_type': 'mid', 'count': 1, 'timecode': '3.14'}, {'point_type': 'pre', 'count': 3, 'timecode': '20.12', 'episode_id': 1}, ] with pytest.raises(ValidationError): schema.InsertionPointsPayloadSchema(many=True).load(payload) def test_insertion_points_non_decimal_compatible(): """Test InsertionPoint Schema fails with non decimal timecode.""" payload = [ {'point_type': 'mid', 'count': 1, 'timecode': '3,14'}, {'point_type': 'pre', 'count': 3, 'timecode': '20,14'}, ] with pytest.raises(ValidationError): schema.InsertionPointsPayloadSchema(many=True).load(payload) def test_episode_published_date_error_on_int(): """Test that Validation Error is thrown for published_date to be a string.""" payload = dict( podcast_id=1, title='title', description='description', season_number=1, episode_number=1, episode_type='full', content='clean', megaphone_id='6bf5bea4-a1d4-11e6-8dea-b334e2aa4880', published_date=3242342 ) with pytest.raises(ValidationError): schema.DraftEpisodeSchema().load(payload) def test_draft_episode_external_id_errors(): """Test draft episode validation errors for external id.""" payload = dict( podcast_id=1, title='title', description='description', season_number=1, episode_number=1, episode_type='full', content='clean', megaphone_id='6bf5bea4-a1d4-11e6-8dea-b334e2aa4880', draft=True ) payload['external_id'] = \ 'external_id_test_size_exceeding_64_characters_of_string_dummy_val' with pytest.raises(ValidationError) as err: schema.DraftEpisodeSchema().load(payload) assert err.value.messages == { 'external_id': [ 'Longer than maximum length 64.' ] } payload['external_id'] = 1234 with pytest.raises(ValidationError) as err2: schema.DraftEpisodeSchema().load(payload) assert err2.value.messages == { 'external_id': [ 'Not a valid string.' ] } def test_draft_episode_external_id_validation_success(): """Test that Validation is success for external_id.""" payload = dict( podcast_id=1, title='title', description='description', season_number=1, episode_number=1, episode_type='full', content='clean', megaphone_id='6bf5bea4-a1d4-11e6-8dea-b334e2aa4880', published_date='2019-12-26T16:52:01.000Z', planned_pre_roll_count=1, planned_post_roll_count=0, draft=True, external_id=None, is_reviewed=False, apple_id='apple-id' ) result = schema.DraftEpisodeSchema().load(payload) assert result['external_id'] is None assert result['is_reviewed'] is False assert result['apple_id'] == 'apple-id' def test_episode_published_date_validation_success(): """Test that Validation is success for published_date to be a unic timestamp.""" payload = dict( podcast_id=1, title='title', description='description', season_number=1, episode_number=1, episode_type='full', content='clean', megaphone_id='6bf5bea4-a1d4-11e6-8dea-b334e2aa4880', published_date='2019-12-26T16:52:01.000Z', planned_pre_roll_count=1, planned_post_roll_count=0, draft=True ) result = schema.DraftEpisodeSchema().load(payload) assert result['published_date'] == payload['published_date'] def test_episode_exclude_undefined_fields(): """Test that Validation doesn't propagate field undefined in schema.""" payload = dict( id=1, podcast_id=1, title='title', description='description', season_number=1, episode_number=1, episode_type='full', content='clean', megaphone_id='6bf5bea4-a1d4-11e6-8dea-b334e2aa4880', published_date='2019-12-26T16:52:01.000Z', created_at='2019-12-26T16:52:01.000Z', draft=True, crud='crud', apple_id='apple-id' ) result = schema.DraftEpisodeSchema().load(payload) assert 'id' not in result assert 'created_at' not in result assert 'crud' not in result def test_publish_episode_schema_success(): """Test that Validation is success.""" payload = dict( podcast_id=1, title='title', description='description', season_number=1, episode_number=1, episode_type='full', content='clean', megaphone_id='6bf5bea4-a1d4-11e6-8dea-b334e2aa4880', published_date='2019-12-26T16:52:01.000Z', planned_pre_roll_count=1, planned_post_roll_count=0, draft=False, external_id='test_external_id', is_reviewed=True, apple_id='apple-id' ) result = schema.PublishEpisodeSchema().load(payload) assert result['external_id'] == 'test_external_id' assert result['is_reviewed'] is True assert result['apple_id'] == 'apple-id' def test_publish_episode_external_id_errors(): """Test publish episode validation errors for external id.""" payload = dict( podcast_id=1, title='title', description='description', season_number=1, episode_number=1, episode_type='full', content='clean', megaphone_id='6bf5bea4-a1d4-11e6-8dea-b334e2aa4880', published_date='2019-12-26T16:52:01.000Z', planned_pre_roll_count=1, planned_post_roll_count=0, draft=False ) payload['external_id'] = \ 'external_id_test_size_exceeding_64_characters_of_string_dummy_val' with pytest.raises(ValidationError) as err: schema.PublishEpisodeSchema().load(payload) assert err.value.messages == { 'external_id': [ 'Longer than maximum length 64.' ] } payload['external_id'] = 1234 with pytest.raises(ValidationError) as err2: schema.PublishEpisodeSchema().load(payload) assert err2.value.messages == { 'external_id': [ 'Not a valid string.' ] } def test_publish_episode_schema_fails_missing_required_fields(): """Test that Validation fails if required fields are missing.""" payload = dict( podcast_id=1, megaphone_id='6bf5bea4-a1d4-11e6-8dea-b334e2aa4880', draft=True ) with pytest.raises(ValidationError) as err: schema.PublishEpisodeSchema().load(payload) assert err.value.messages == { 'title': ['Missing data for required field.'], 'description': ['Missing data for required field.'], 'episode_type': ['Missing data for required field.'], 'published_date': ['Missing data for required field.'], 'content': ['Missing data for required field.'] } def test_publish_episode_schema_fails_invalid_data_in_fields(): """Test that Validation fails if invalid data in fields.""" payload = dict( podcast_id=1, title='Invalid Episode', megaphone_id='6bf5bea4-a1d4-11e6-8dea-b334e2aa4880', description='description', episode_type='full', content='clean', published_date='2019-12-26T16:52:01.000Z', season_number=0, episode_number='0', draft=True, is_reviewed=None ) with pytest.raises(ValidationError) as err: schema.PublishEpisodeSchema().load(payload) assert err.value.messages == { 'season_number': ['Must be greater than or equal to 1.'], 'episode_number': ['Must be greater than or equal to 1.'], 'is_reviewed': ['Field may not be null.'] } def test_draft_episode_schema_fails_invalid_data_in_fields(): """Test that Validation fails if invalid data in fields.""" payload = dict( podcast_id=1, title='Invalid Episode', megaphone_id='6bf5bea4-a1d4-11e6-8dea-b334e2aa4880', season_number=0, episode_number='0', draft=True, is_reviewed=None ) with pytest.raises(ValidationError) as err: schema.DraftEpisodeSchema().load(payload) assert err.value.messages == { 'season_number': ['Must be greater than or equal to 1.'], 'episode_number': ['Must be greater than or equal to 1.'], 'is_reviewed': ['Field may not be null.'] } 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_partial_podcast_schema_fields_not_required(participant_fixture): """Test that partial podcast schema fields are not required.""" payload = dict( network_id=1, title='title', host='localhost', owner='Billy', description='Description', slug='awesome-slug', copyright='copyright', link='http://localhost', email='mail@email.com', explicit='clean', language='en', show_type='episodic', categories=[1], participants=[participant_fixture], feed_type='public-rss', channel_id='awesome-channel-id' ) result = schema.UpdatePodcastSchema().load(payload) assert result result = schema.UpdatePodcastSchema(partial=True).load({}) assert result == {} def test_create_podcast_schema(participant_fixture, seasons_fixture): """Test that partial podcast schema fields are not required.""" payload = dict( network_id=1, title='title', host='localhost', owner='Billy', description='Description', slug='awesome-slug', copyright='copyright', link='http://localhost', email='mail@email.com', explicit='clean', language='en', show_type='episodic', categories=[1], artwork_filename='cow', participants=[participant_fixture], seasons=seasons_fixture ) assert schema.CreatePodcastSchema().load(payload) def test_create_test_podcast_schema(): """Test that artwork field not required for test podcast.""" payload = dict( network_id=1, title='title', host='localhost', owner='Billy', description='Description', slug='awesome-slug', copyright='copyright', link='http://localhost', email='mail@email.com', explicit='clean', language='en', show_type='episodic', categories=[1], participants=[], channel_id='awesome-channel-id' ) assert schema.CreatePodcastSchema(exclude=['artwork_filename']).load(payload) def test_podcast_schema_no_extra_fields(seasons_fixture): """Test that extra fields are excluded from result.""" payload = dict( network_id=1, title='title', host='localhost', owner='Billy', description='Description', slug='awesome-slug', copyright='copyright', link='http://localhost', email='mail@email.com', explicit='clean', language='en', show_type='episodic', categories=[1], some_other_field='value', seasons=seasons_fixture, channel_id='awesome-channel-id' ) result = schema.UpdatePodcastSchema().load(payload) assert 'network_id' not in result assert 'slug' not in result def test_create_podcast_schema_seasons_failure(participant_fixture, seasons_fixture): """Test that create podcast schema fails for incorrect seasons data.""" seasons_fixture[1] = {'number': 2} payload = dict( network_id=1, title='title', host='localhost', owner='Billy', description='Description', slug='awesome-slug', copyright='copyright', link='http://localhost', email='mail@email.com', explicit='clean', language='en', show_type='episodic', categories=[1], artwork_filename='cow', participants=[participant_fixture], seasons=seasons_fixture ) with pytest.raises(ValidationError) as e: schema.CreatePodcastSchema().load(payload) assert e.value.messages == { 'seasons': {1: {'name': ['Missing data for required field.']}} } def test_planned_inventory_success(planned_inventory_fixture): """Test that planned inventory works.""" result = schema.PlannedInventorySchema().load(planned_inventory_fixture) assert result def test_planned_inventory_no_date(planned_inventory_fixture): """Test planned inventory date is required.""" planned_inventory_fixture['dates'] = None with pytest.raises(ValidationError): schema.PlannedInventorySchema().load(planned_inventory_fixture) def test_negative_roll(planned_inventory_fixture): """Test planned inventory mid roll must be positive.""" planned_inventory_fixture['mid_rolls'] = -1 with pytest.raises(ValidationError): schema.PlannedInventorySchema().load(planned_inventory_fixture) def test_ad_read_success(ad_read_fixture): """Test that ad read works.""" result = schema.AdReadSchema().load(ad_read_fixture) assert result assert ad_read_fixture == result def test_ad_read_failure(ad_read_fixture_2): """Test that ad read fails.""" ad_read_fixture_2['campaign_id'] = None with pytest.raises(ValidationError) as e: schema.AdReadSchema().load(ad_read_fixture_2) assert e.value.messages == { 'campaign_id': ['Field may not be null.'], 'assignee_ids': ['Longer than maximum length 5.'] } @pytest.mark.parametrize(( 'data', 'expected_result' ), [ ( {'ad_action_id': 555, 'comment': 'whatever'}, {'ad_action_id': 555, 'comment': 'whatever'} ), ( {'comment': 'whatever'}, {'ad_action_id': ['Missing data for required field.']} ), ( {'ad_action_id': 555}, {'comment': ['Missing data for required field.']} ) ]) def test_ad_read_comment_create(data, expected_result): """Test ad read comment creation.""" try: result = schema.CreateAdReadCommentSchema().load(data) except Exception as e: result = e.messages assert result == expected_result @pytest.mark.parametrize(( 'data', 'expected_result' ), [ ( {'limit': 50, 'offset': 0}, {'limit': 50, 'offset': 0} ), ( {'limit': 50}, {'limit': 50} ), ( {'offset': 0}, {'offset': 0} ) ]) def test_ad_read_comment_get(data, expected_result): """Test ad read comment fetch.""" try: result = schema.GetAdReadCommentsSchema().load(data) except Exception as e: result = e.messages assert result == expected_result def test_create_admin_user_success(admin_user_fixture): """Test create admin user schema validation success.""" result = schema.CreateUserSchema().load(admin_user_fixture) assert result == admin_user_fixture def test_create_producer_user_success(user_fixture): """Test create producer user schema validation success.""" result = schema.CreateUserSchema().load(user_fixture) assert result == { 'name': 'First Last', 'email': 'email@theorchard.com', 'network_ids': [1], 'role': 'producer', 'organization': 'orchard', 'all_networks': False } def test_create_network_admin_user_success(network_user_fixture): """Test create network admin user schema validation success.""" result = schema.CreateUserSchema().load(network_user_fixture) assert result == network_user_fixture def test_create_network_admin_user_failures(network_user_fixture): """Test create network admin user schema validation fails.""" network_user_fixture['network_ids'] = {1: 'network 1'} with pytest.raises(ValidationError) as err: schema.CreateUserSchema().load(network_user_fixture) assert err.value.messages == {'network_ids': ['Not a valid list.']} network_user_fixture['network_ids'] = [] with pytest.raises(ValidationError) as err: schema.CreateUserSchema().load(network_user_fixture) assert err.value.messages == { 'network_ids': ['Missing data for required field.'] } def test_create_show_level_podcast_access_user_success(show_level_podcast_user_fixture): """Test create show level podcast user schema validation success.""" result = schema.CreateUserSchema().load(show_level_podcast_user_fixture) assert result == show_level_podcast_user_fixture def test_create_show_level_show_family_access_user_success(show_level_show_family_user_fixture): """Test create show level show_family user schema validation success.""" result = schema.CreateUserSchema().load(show_level_show_family_user_fixture) assert result == show_level_show_family_user_fixture def test_update_user_success(user_fixture): """Test a valid payload does not blow up.""" schema.UpdateUserSchema().load({'network_ids': [1]}) def test_update_podcast_level_user_success(user_fixture): """Test a valid payload does not blow up.""" schema.UpdateUserSchema().load({'podcast_ids': [1]}) def test_update_show_family_level_user_success(user_fixture): """Test a valid payload does not blow up.""" result = schema.UpdateUserSchema().load({'show_family_ids': [1]}) assert result == {'show_family_ids': [1]} def test_update_user_failure(user_fixture): """Test create user schema validation fails.""" with pytest.raises(ValidationError): schema.UpdateUserSchema().load(user_fixture) def test_update_user_last_login_success(user_fixture): """Test a valid update user last login payload does not blow up.""" schema.UpdateUserLastLoginSchema().load({'last_login': '2022-10-03T13:13:00.000Z'}) def test_update_user_last_login_failure(user_fixture): """Test update user last login validation fails.""" with pytest.raises(ValidationError) as err1: schema.UpdateUserLastLoginSchema().load({'dummy': '2022-10-03T13:13:00.000Z'}) err1.value.messages == {'dummy': ['Unknown field.']} with pytest.raises(ValidationError) as err2: schema.UpdateUserLastLoginSchema().load({'last_login': '2022-10-03'}) err2.value.messages == {'last_login': ['Not a valid datetime.']} def test_update_user_role_success(mock_current_admin_user): """Test a user role update.""" schema.UpdateUserSchema().load({'network_ids': [1], 'role': 'network-admin'}) def test_publish_fail(): """Test that Validation doesn't propagate field undefined in schema.""" payload = dict( id=1, podcast_id=1, season_number=-1, episode_number=0, megaphone_id='6bf5bea4-a1d4-11e6-8dea-b334e2aa4880', created_at='2019-12-26T16:52:01.000Z', draft=False, ) with pytest.raises(OwsError) as e: schema.validate_episode(payload) assert e.value.message == { 'season_number': ['Must be greater than or equal to 1.'], 'episode_number': ['Must be greater than or equal to 1.'], 'title': ['Missing data for required field.'], 'content': ['Missing data for required field.'], 'description': ['Missing data for required field.'], 'episode_type': ['Missing data for required field.'], 'published_date': ['Missing data for required field.'] } def test_ownership_check_success(): """Test ownership check schema validation success.""" data = { 'object_type': 'network', 'object_id': '1' } result = schema.CheckOwnershipSchema().load(data) assert result == data def test_ownership_check_fail_wrong_type(): """Test ownership check fails due to wrong object_type.""" data = { 'object_type': 'cow', 'object_id': '1' } with pytest.raises(ValidationError) as err: schema.CheckOwnershipSchema().load(data) assert err.value.messages == { 'object_type': ['Must be one of: network, podcast, episode, adupload.'] } def test_ownership_check_fail(): """Test ownership check fails due to required fields.""" with pytest.raises(ValidationError) as err: schema.CheckOwnershipSchema().load({}) assert err.value.messages == { 'object_id': ['Missing data for required field.'], 'object_type': ['Missing data for required field.'] } def test_top_analytics_fail(): """Test top analytics fails due to required fields.""" with pytest.raises(ValidationError) as err: schema.TopAnalyticsSchema().load(ImmutableMultiDict({})) assert err.value.messages == { 'limit': ['Missing data for required field.'], 'offset': ['Missing data for required field.'], 'date_range': ['Missing data for required field.'] } def test_top_analytics_fails_for_custom_date(): """Test top analytics fails if start_date greater than end_date.""" with pytest.raises(ValidationError) as err: schema.TopAnalyticsSchema().load(ImmutableMultiDict({ 'limit': 9, 'offset': 2, 'date_range': analytics_constants.CUSTOM, 'network_id': 1, 'start_date': '2021-01-05', 'end_date': '2021-01-01' })) assert err.value.messages == { 'start_date': [ERROR_START_DATE_GREATER_THAN_END_DATE] } def test_top_analytics_fails_for_empty_start_date(): """Test top analytics fails if start_date is empty.""" with pytest.raises(ValidationError) as err: schema.TopAnalyticsSchema().load(ImmutableMultiDict({ 'limit': 9, 'offset': 2, 'date_range': analytics_constants.CUSTOM, 'network_id': 1 })) assert err.value.messages == { 'start_date': [ERROR_REQUIRED_DATE] } def test_top_analytics_fails_for_empty_end_date(): """Test top analytics fails if end_date is empty.""" with pytest.raises(ValidationError) as err: schema.TopAnalyticsSchema().load(ImmutableMultiDict({ 'limit': 9, 'offset': 2, 'date_range': analytics_constants.CUSTOM, 'network_id': 1, 'start_date': '2021-01-01' })) assert err.value.messages == { 'end_date': [ERROR_REQUIRED_DATE] } def test_top_analytics_fails_for_invalid_date(): """Test top analytics fails if end_date is empty.""" with pytest.raises(ValidationError) as err: schema.TopAnalyticsSchema().load(ImmutableMultiDict({ 'limit': 9, 'offset': 2, 'date_range': analytics_constants.CUSTOM, 'network_id': 1, 'start_date': 'abcd', 'end_date': 'sd' })) assert err.value.messages == { 'date_fields': [ERROR_INCORRECT_DATE_FORMAT] } def test_top_analytics(): """Test top analytics passes.""" result = schema.TopAnalyticsSchema().load(ImmutableMultiDict({ 'limit': 9, 'offset': 2, 'date_range': analytics_constants.ALL_TIME, })) assert result['network_id'] is None def test_top_analytics_has_optional_network_id(): """Test top analytics passes.""" schema.TopAnalyticsSchema().load(ImmutableMultiDict({ 'limit': 9, 'offset': 2, 'date_range': analytics_constants.ALL_TIME, 'network_id': 1 })) def test_top_analytics_has_optional_podcast_id(): """Test top analytics passes.""" schema.TopAnalyticsSchema().load(ImmutableMultiDict({ 'limit': 9, 'offset': 2, 'date_range': analytics_constants.ALL_TIME, 'podcast_id': 1 })) def test_top_analytics_sort_field_valid(): """Test top analytics passes.""" schema.TopAnalyticsSchema().load(ImmutableMultiDict({ 'limit': 9, 'offset': 2, 'date_range': analytics_constants.ALL_TIME, 'sort_field': 'downloads' })) def test_top_analytics_sort_field_invalid(): """Test top analytics fails with invalid sort field.""" with pytest.raises(ValidationError) as err: schema.TopAnalyticsSchema().load(ImmutableMultiDict({ 'limit': 9, 'offset': 2, 'date_range': analytics_constants.ALL_TIME, 'sort_field': 'networks_ids' })) assert err.value.messages == { 'sort_field': ['Must be one of: downloads, published_date.'] } def test_daily_podcast_downloads_fail(): """Test top daily podcast fails due to required fields.""" with pytest.raises(ValidationError) as err: schema.DailyPodcastDownloadsSchema().load(ImmutableMultiDict({})) assert err.value.messages == { 'podcast_ids': ['Missing data for required field.'], 'date_range': ['Missing data for required field.'] } def test_daily_podcast_downloads_fails_for_custom_date(): """Test top daily podcast fails if start_date greater than end_date.""" with pytest.raises(ValidationError) as err: schema.DailyPodcastDownloadsSchema().load(ImmutableMultiDict({ 'podcast_ids': ['9', '12'], 'date_range': analytics_constants.CUSTOM, 'start_date': '2020-01-05', 'end_date': '2020-01-01', 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] })) assert err.value.messages == { 'start_date': [ERROR_START_DATE_GREATER_THAN_END_DATE] } def test_daily_podcast_downloads_fails_for_empty_start_date(): """Test top daily podcast fails if start_date is empty.""" with pytest.raises(ValidationError) as err: schema.DailyPodcastDownloadsSchema().load(ImmutableMultiDict({ 'podcast_ids': ['9', '12'], 'date_range': analytics_constants.CUSTOM, 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] })) assert err.value.messages == { 'start_date': [ERROR_REQUIRED_DATE] } def test_daily_podcast_downloads_fails_for_empty_end_date(): """Test top daily podcast fails if end_date is empty.""" with pytest.raises(ValidationError) as err: schema.DailyPodcastDownloadsSchema().load(ImmutableMultiDict({ 'podcast_ids': ['9', '12'], 'date_range': analytics_constants.CUSTOM, 'start_date': '2020-01-01', 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] })) assert err.value.messages == { 'end_date': [ERROR_REQUIRED_DATE] } def test_daily_podcast_downloads(): """Test top daily podcasts.""" result = schema.DailyPodcastDownloadsSchema().load(ImmutableMultiDict({ 'podcast_ids': ['9', '12'], 'date_range': analytics_constants.ALL_TIME, 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] })) assert result == { 'podcast_ids': [9, 12], 'date_range': analytics_constants.ALL_TIME, 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] } def test_daily_episode_downloads_fail(): """Test top daily episode fails due to required fields.""" with pytest.raises(ValidationError) as err: schema.DailyEpisodeDownloadsSchema().load(ImmutableMultiDict({})) assert err.value.messages == { 'episode_ids': ['Missing data for required field.'], 'date_range': ['Missing data for required field.'] } def test_daily_episode_downloads_fails_for_custom_date(): """Test top daily episode fails if start_date greater than end_date.""" with pytest.raises(ValidationError) as err: schema.DailyEpisodeDownloadsSchema().load(ImmutableMultiDict({ 'podcast_ids': ['9', '12'], 'date_range': analytics_constants.CUSTOM, 'start_date': '2020-01-05', 'end_date': '2020-01-01', 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] })) assert err.value.messages == { 'start_date': [ERROR_START_DATE_GREATER_THAN_END_DATE] } def test_daily_episode_downloads_fails_for_empty_start_date(): """Test top daily episode fails if start_date is empty.""" with pytest.raises(ValidationError) as err: schema.DailyEpisodeDownloadsSchema().load(ImmutableMultiDict({ 'podcast_ids': ['9', '12'], 'date_range': analytics_constants.CUSTOM, 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] })) assert err.value.messages == { 'start_date': [ERROR_REQUIRED_DATE] } def test_daily_episode_downloads_fails_for_empty_end_date(): """Test top daily episode fails if end_date is empty.""" with pytest.raises(ValidationError) as err: schema.DailyEpisodeDownloadsSchema().load(ImmutableMultiDict({ 'podcast_ids': ['9', '12'], 'date_range': analytics_constants.CUSTOM, 'start_date': '2020-01-01', 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] })) assert err.value.messages == { 'end_date': [ERROR_REQUIRED_DATE] } def test_daily_episode_downloads(): """Test top daily episodes.""" result = schema.DailyEpisodeDownloadsSchema().load(ImmutableMultiDict({ 'episode_ids': ['9', '12'], 'date_range': analytics_constants.ALL_TIME, 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] })) assert result == { 'episode_ids': [9, 12], 'date_range': analytics_constants.ALL_TIME, 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] } def test_daily_network_downloads_fail(): """Test top daily network fails due to required fields.""" with pytest.raises(ValidationError) as err: schema.DailyNetworkDownloadsSchema().load(ImmutableMultiDict({})) assert err.value.messages == { 'network_ids': ['Missing data for required field.'], 'date_range': ['Missing data for required field.'] } def test_daily_network_downloads_fails_for_custom_date(): """Test top daily network fails if start_date greater than end_date.""" with pytest.raises(ValidationError) as err: schema.DailyNetworkDownloadsSchema().load(ImmutableMultiDict({ 'network_ids': ['9', '12'], 'date_range': analytics_constants.CUSTOM, 'start_date': '2020-01-05', 'end_date': '2020-01-01', 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] })) assert err.value.messages == { 'start_date': [ERROR_START_DATE_GREATER_THAN_END_DATE] } def test_daily_network_downloads_fails_for_empty_start_date(): """Test top daily network fails if start_date is empty.""" with pytest.raises(ValidationError) as err: schema.DailyNetworkDownloadsSchema().load(ImmutableMultiDict({ 'network_ids': ['9', '12'], 'date_range': analytics_constants.CUSTOM, 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] })) assert err.value.messages == { 'start_date': [ERROR_REQUIRED_DATE] } def test_daily_network_downloads_fails_for_empty_end_date(): """Test top daily network fails if end_date is empty.""" with pytest.raises(ValidationError) as err: schema.DailyNetworkDownloadsSchema().load(ImmutableMultiDict({ 'network_ids': ['9', '12'], 'date_range': analytics_constants.CUSTOM, 'start_date': '2020-01-01', 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] })) assert err.value.messages == { 'end_date': [ERROR_REQUIRED_DATE] } def test_daily_network_downloads(): """Test top daily networks.""" result = schema.DailyNetworkDownloadsSchema().load(ImmutableMultiDict({ 'network_ids': ['9', '12'], 'date_range': analytics_constants.ALL_TIME, 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] })) assert result == { 'network_ids': [9, 12], 'date_range': analytics_constants.ALL_TIME, 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] } def test_daily_country_downloads(): """Test daily country downloads.""" result = schema.DailyCountryDownloadsSchema().load(ImmutableMultiDict({ 'object_id': '8', 'object_type': analytics_constants.PODCAST, 'date_range': analytics_constants.ALL_TIME, 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] })) assert result == { 'object_id': 8, 'object_type': analytics_constants.PODCAST, 'date_range': analytics_constants.ALL_TIME, 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] } def test_daily_country_download_fail(): """Test daily country downloads.""" with pytest.raises(ValidationError) as err: schema.DailyCountryDownloadsSchema().load(ImmutableMultiDict({ 'object_id': '8', 'object_type': analytics_constants.PODCAST, 'date_range': analytics_constants.ALL_TIME, 'countries': [], 'players': ['Player1', 'Player2', 'Player3', 'Player4', 'Player5', 'Player6'] })) assert err.value.messages == { 'countries': ['Length must be between 1 and 10.'], 'players': ['Longer than maximum length 5.'] } def test_daily_country_download_fails_for_custom_date(): """Test top daily country download fails if start_date greater than end_date.""" with pytest.raises(ValidationError) as err: schema.DailyCountryDownloadsSchema().load(ImmutableMultiDict({ 'network_ids': ['9', '12'], 'date_range': analytics_constants.CUSTOM, 'start_date': '2020-01-05', 'end_date': '2020-01-01', 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] })) assert err.value.messages == { 'start_date': [ERROR_START_DATE_GREATER_THAN_END_DATE] } def test_daily_country_download_fails_for_empty_start_date(): """Test top daily country download if start_date is empty.""" with pytest.raises(ValidationError) as err: schema.DailyCountryDownloadsSchema().load(ImmutableMultiDict({ 'network_ids': ['9', '12'], 'date_range': analytics_constants.CUSTOM, 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] })) assert err.value.messages == { 'start_date': [ERROR_REQUIRED_DATE] } def test_daily_country_download_fails_for_empty_end_date(): """Test top daily country download if end_date is empty.""" with pytest.raises(ValidationError) as err: schema.DailyCountryDownloadsSchema().load(ImmutableMultiDict({ 'network_ids': ['9', '12'], 'date_range': analytics_constants.CUSTOM, 'start_date': '2020-01-01', 'countries': ['AA', 'BB'], 'players': ['Player1', 'Player2'] })) assert err.value.messages == { 'end_date': [ERROR_REQUIRED_DATE] } def test_podcast_links_schema(): """Test podcast links schema.""" result = schema.CreatePodcastLinksSchema().load({ 'podcast_id': 1, 'links': [{'store_id': 1, 'link': 'cow'}] }) assert result == { 'podcast_id': 1, 'links': [{'store_id': 1, 'link': 'cow'}] } def test_podcast_links_schema_fails(): """Test podcast links fail schema.""" with pytest.raises(ValidationError) as err: schema.CreatePodcastLinksSchema().load({}) assert err.value.messages == { 'podcast_id': ['Missing data for required field.'], 'links': ['Missing data for required field.'], } with pytest.raises(ValidationError) as err: schema.CreatePodcastLinksSchema().load({ 'podcast_id': 1, 'links': [{}] }) assert err.value.messages == { 'links': { 0: { 'link': ['Missing data for required field.'], 'store_id': ['Missing data for required field.'] } } } def test_episode_link_schema(): """Test episode link schema.""" result = schema.CreateEpisodeLinkSchema().load({ 'podcast_id': 1, 'episode_id': 1, 'store_id': 1, 'link': 'link' }) assert result == { 'podcast_id': 1, 'episode_id': 1, 'store_id': 1, 'link': 'link' } def test_episode_link_schema_fails(): """Test episode links fail schema.""" with pytest.raises(ValidationError) as err: schema.CreateEpisodeLinkSchema().load({}) assert err.value.messages == { 'podcast_id': ['Missing data for required field.'], 'episode_id': ['Missing data for required field.'], 'store_id': ['Missing data for required field.'], 'link': ['Missing data for required field.'] } def test_get_users_schema(): """Test get users schema validation succeeds.""" result = schema.GetUsersSchema().load(ImmutableMultiDict({ 'limit': 0, 'offset': 0, 'organization': None, 'network_ids': [] })) assert result result = schema.GetUsersSchema().load(ImmutableMultiDict({ 'limit': 0, 'offset': 0, 'organization': None, 'network_ids': ['9', '12'] })) assert result['network_ids'] == [9, 12] def test_get_users_schema_fails(): """Test get users schema validation fails.""" with pytest.raises(ValidationError) as err: schema.GetUsersSchema().load(ImmutableMultiDict({'organization': 'organization'})) assert err.value.messages == { 'organization': ['Must be one of: orchard, sme.'], } def test_favorite_chart_schema_fails(): """Test get user favorite chart schema validation fails.""" with pytest.raises(ValidationError) as err: schema.ToggleUserChartFavoriteSchema().load({}) assert err.value.messages == { 'category': ['Missing data for required field.'], 'country': ['Missing data for required field.'], 'store': ['Missing data for required field.'], 'chart_type': ['Missing data for required field.'] } def test_create_network_schema_fails(): """Test create network schema validation fails.""" with pytest.raises(ValidationError) as err: schema.CreateNetworkSchema().load({}) assert err.value.messages == { 'code': ['Missing data for required field.'], 'name': ['Missing data for required field.'] } def test_get_podcast_chart_schema(): """Test get podcast chart schema validation fails.""" schema.ChartableChartSchema().load({ 'category': 'music', 'country': 'US', 'store': 'spotify', 'report_date': '2021-01-01' }) def test_get_podcast_chart_schema_fails(): """Test get podcast chart schema validation fails.""" with pytest.raises(ValidationError) as err: schema.ChartableChartSchema().load({ 'category': 'music', 'store': 'spotify', 'report_date': '2021-01-01' }) assert err.value.messages == { 'country': ['Missing data for required field.'] } def test_get_episode_chart_schema(): """Test get episode chart schema validation fails.""" schema.ChartableEpisodeChartSchema().load({ 'category': 'music', 'country': 'US', 'report_date': '2021-01-01' }) def test_get_episode_chart_schema_fails(): """Test get episode chart schema validation fails.""" with pytest.raises(ValidationError) as err: schema.ChartableEpisodeChartSchema().load({ 'category': 'music', 'country': 'US', }) assert err.value.messages == { 'report_date': ['Missing data for required field.'] } def test_player_daily_downloads_success(player_daily_downloads_data_fixture): """Test DailyPlayerDownloadsSchema do successful validation.""" data = ImmutableMultiDict(player_daily_downloads_data_fixture) result = schema.DailyPlayerDownloadsSchema().load(data) assert result['players'] == player_daily_downloads_data_fixture['players'] def test_player_daily_downloads_fails(player_daily_downloads_data_fixture): """Test that DailyPlayerDownloadsSchema fails on invalid data.""" player_daily_downloads_data_fixture['object_type'] = 'invalid_type' data = ImmutableMultiDict(player_daily_downloads_data_fixture) with pytest.raises(ValidationError) as err1: schema.DailyPlayerDownloadsSchema().load(data) assert err1.value.messages == {'object_type': ['Must be one of: podcast, network, episode.']} player_daily_downloads_data_fixture['object_type'] = \ analytics_constants.NETWORK player_daily_downloads_data_fixture['countries'] = ['c1', 'c2', 'c3', 'c4', 'c5', 'c6'] player_daily_downloads_data_fixture['players'] = [] data = ImmutableMultiDict(player_daily_downloads_data_fixture) with pytest.raises(ValidationError) as err2: schema.DailyPlayerDownloadsSchema().load(data) assert err2.value.messages == { 'countries': ['Longer than maximum length 5.'], 'players': ['Length must be between 1 and 10.'] } def test_daily_player_download_fails_for_custom_date(): """Test top daily player download fails if start_date greater than end_date.""" with pytest.raises(ValidationError) as err: schema.DailyPlayerDownloadsSchema().load(ImmutableMultiDict({ 'object_id': 1, 'object_type': analytics_constants.NETWORK, 'date_range': analytics_constants.CUSTOM, 'countries': ['US', 'UK'], 'players': ['Player1', 'Player2'], 'start_date': '2021-01-05', 'end_date': '2021-01-01' })) assert err.value.messages == { 'start_date': [ERROR_START_DATE_GREATER_THAN_END_DATE] } def test_daily_player_download_fails_for_empty_start_date(): """Test top daily player download if start_date is empty.""" with pytest.raises(ValidationError) as err: schema.DailyPlayerDownloadsSchema().load(ImmutableMultiDict({ 'object_id': 1, 'object_type': analytics_constants.NETWORK, 'date_range': analytics_constants.CUSTOM, 'countries': ['US', 'UK'], 'players': ['Player1', 'Player2'] })) assert err.value.messages == { 'start_date': [ERROR_REQUIRED_DATE] } def test_daily_player_download_fails_for_empty_end_date(): """Test top daily player download if end_date is empty.""" with pytest.raises(ValidationError) as err: schema.DailyPlayerDownloadsSchema().load(ImmutableMultiDict({ 'object_id': 1, 'object_type': analytics_constants.NETWORK, 'date_range': analytics_constants.CUSTOM, 'countries': ['US', 'UK'], 'players': ['Player1', 'Player2'], 'start_date': '2021-01-05' })) assert err.value.messages == { 'end_date': [ERROR_REQUIRED_DATE] } def test_create_ad_action_comment_schema(): """Test create ad action comment schema validation success.""" schema.CreateAdReadCommentSchema().load({ 'ad_action_id': 1, 'comment': 'test comment' }) def test_create_ad_action_comment_schema_failure(): """Test create ad action commentschema validation failure.""" with pytest.raises(ValidationError) as err: schema.CreateAdReadCommentSchema().load({'ad_action_id': 'aa'}) assert err.value.messages == { 'ad_action_id': ['Not a valid integer.'], 'comment': ['Missing data for required field.'] } def test_create_feed_schema_success_for_feed_type_public_rss(): """Test create feed schema validation success for feed_type public_rss.""" payload = dict( podcast_id=1, show_family_id=1, title='test_feed_title', description='test_feed_summary', artwork_filename='test_artwork_file.jpg', feed_type='public-rss', slug='testslugforpublicrss', is_copy_ad_locations=True ) assert schema.CreateFeedSchema().load(payload) def test_create_feed_schema_fails_for_feed_type_public_rss(): """Test create feed schema validation fails for feed_type public_rss.""" payload = dict( podcast_id=1, show_family_id=1, title='test_feed_title', description='test_feed_summary', artwork_filename='test_artwork_file.jpg', feed_type='public-rss', ) with pytest.raises(ValidationError) as err: schema.CreateFeedSchema().load(payload) assert err.value.messages == { 'slug': ['Missing data for required field.'] } def test_create_feed_schema_success_for_feed_type_private_rss(): """Test create feed schema validation success for feed_type private_rss.""" payload = dict( podcast_id=1, show_family_id=1, title='test_feed_title', description='test_feed_summary', artwork_filename='test_artwork_file.jpg', feed_type='private-rss', slug='test-slug-for-private-rss' ) assert schema.CreateFeedSchema().load(payload) def test_create_feed_schema_fails_for_feed_type_private_rss(): """Test create feed schema validation fails for feed_type private_rss.""" payload = dict( podcast_id=1, show_family_id=1, title='test_feed_title', description='test_feed_summary', artwork_filename='test_artwork_file.jpg', feed_type='private-rss', ) with pytest.raises(ValidationError) as err: schema.CreateFeedSchema().load(payload) assert err.value.messages == { 'slug': ['Missing data for required field.'] } def test_create_feed_schema_fails_for_slug_length(): """Test create feed schema validation fails for slug length.""" payload = dict( podcast_id=1, show_family_id=1, title='test_feed_title', description='test_feed_summary', artwork_filename='test_artwork_file.jpg', feed_type='private-rss', slug="""aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb""" """bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccccccccccccccccccccccccccccccccc""" """bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccccccccccccccccccccccccccccccccc""" ) with pytest.raises(ValidationError) as err: schema.CreateFeedSchema().load(payload) assert err.value.messages == { 'slug': ['Longer than maximum length 255.'] } def test_create_feed_schema_fails_for_invalid_slug(): """Test create feed schema validation fails for feed_type private_rss.""" payload = dict( podcast_id=1, show_family_id=1, title='test_feed_title', description='test_feed_summary', artwork_filename='test_artwork_file.jpg', feed_type='private-rss', slug='test slug' ) with pytest.raises(ValidationError) as err: schema.CreateFeedSchema().load(payload) assert err.value.messages == { 'slug': ['String does not match expected pattern.'] } def test_create_feed_schema_success_for_feed_type_apple_subscription(): """Test create feed schema validation success for feed_type apple_subscription.""" payload = dict( podcast_id=1, show_family_id=1, title='test_feed_title', description='test_feed_summary', artwork_filename='test_artwork_file.jpg', feed_type='apple-subscription', channel_id='1234567890' ) assert schema.CreateFeedSchema().load(payload) def test_create_feed_schema_fails_for_feed_type_apple_subscription(): """Test create feed schema validation fails for feed_type apple_subscription.""" payload = dict( podcast_id=1, show_family_id=1, title='test_feed_title', description='test_feed_summary', artwork_filename='test_artwork_file.jpg', feed_type='apple-subscription' ) with pytest.raises(ValidationError) as err: schema.CreateFeedSchema().load(payload) assert err.value.messages == { 'channel_id': ['Missing data for required field.'] } def test_create_feed_schema_success_for_feed_type_youtube(): """Test create feed schema validation success for feed_type youtube.""" payload = dict( podcast_id=1, show_family_id=1, title='test_feed_title', description='test_feed_summary', artwork_filename='test_artwork_file.jpg', feed_type='youtube', channel_id='XYZ1234' ) assert schema.CreateFeedSchema().load(payload) def test_create_feed_schema_fails_for_feed_type_youtube(): """Test create feed schema validation fails for feed_type youtube.""" payload = dict( podcast_id=1, show_family_id=1, title='test_feed_title', description='test_feed_summary', artwork_filename='test_artwork_file.jpg', feed_type='youtube' ) with pytest.raises(ValidationError) as err: schema.CreateFeedSchema().load(payload) assert err.value.messages == { 'channel_id': ['Missing data for required field.'] } def test_create_feed_schema_fails_for_channel_id_length(): """Test create feed schema validation fails for channel id length.""" payload = dict( podcast_id=1, show_family_id=1, title='test_feed_title', description='test_feed_summary', artwork_filename='test_artwork_file.jpg', feed_type='apple-subscription', channel_id='aaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbccccccccccccccccccccc' ) with pytest.raises(ValidationError) as err: schema.CreateFeedSchema().load(payload) assert err.value.messages == { 'channel_id': ['Longer than maximum length 50.'] } def test_create_podcast_schema_success_for_feed_type_public_rss(): """Test create podcast schema validation success for feed_type public_rss.""" payload = dict( network_id=1, title='title', host='localhost', owner='Billy', description='Description', slug='awesome-slug', copyright='copyright', link='http://localhost', email='mail@email.com', explicit='clean', language='en', show_type='episodic', categories=[1], artwork_filename='cow', feed_type='public-rss' ) assert schema.CreatePodcastSchema().load(payload) def test_create_podcast_schema_success_for_feed_type_private_rss(): """Test create podcast schema validation success for feed_type private_rss.""" payload = dict( network_id=1, title='title', host='localhost', owner='Billy', description='Description', slug='awesome-slug', copyright='copyright', link='http://localhost', email='mail@email.com', explicit='clean', language='en', show_type='episodic', categories=[1], artwork_filename='cow', feed_type='private-rss' ) assert schema.CreatePodcastSchema().load(payload) def test_create_podcast_schema_fails_for_feed_type_private_rss(): """Test create podcast schema validation fails for feed_type private_rss.""" payload = dict( network_id=1, title='title', host='localhost', owner='Billy', description='Description', copyright='copyright', link='http://localhost', email='mail@email.com', explicit='clean', language='en', show_type='episodic', categories=[1], artwork_filename='cow', feed_type='private-rss' ) with pytest.raises(ValidationError) as err: schema.CreatePodcastSchema().load(payload) assert err.value.messages == { 'slug': ['Missing data for required field.'] } def test_create_podcast_schema_fails_for_slug_length(seasons_fixture): """Test create podcast schema validation fails for slug length.""" payload = dict( network_id=1, title='title', host='localhost', owner='Billy', description='Description', copyright='copyright', link='http://localhost', email='mail@email.com', explicit='clean', language='en', show_type='episodic', categories=[1], artwork_filename='cow', feed_type='private-rss', slug="""aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb""" """bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccccccccccccccccccccccccccccccccc""" """bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccccccccccccccccccccccccccccccccc""" ) with pytest.raises(ValidationError) as err: schema.CreatePodcastSchema().load(payload) assert err.value.messages == { 'slug': ['Longer than maximum length 255.'] } def test_create_podcast_schema_fails_for_invalid_slug(): """Test create podcast schema validation fails for feed_type private_rss.""" payload = dict( network_id=1, title='title', host='localhost', owner='Billy', description='Description', copyright='copyright', link='http://localhost', email='mail@email.com', explicit='clean', language='en', show_type='episodic', categories=[1], artwork_filename='cow', feed_type='private-rss', slug="""test slug""" ) with pytest.raises(ValidationError) as err: schema.CreatePodcastSchema().load(payload) assert err.value.messages == { 'slug': ['String does not match expected pattern.'] } def test_create_podcast_schema_success_for_feed_type_apple_subscription(seasons_fixture): """Test create podcast schema validation success for feed_type apple_subscription.""" payload = dict( network_id=1, title='title', host='localhost', owner='Billy', description='Description', copyright='copyright', link='http://localhost', email='mail@email.com', explicit='clean', language='en', show_type='episodic', categories=[1], artwork_filename='cow', feed_type='apple-subscription', channel_id='1234567890' ) assert schema.CreatePodcastSchema().load(payload) def test_create_podcast_schema_fails_for_feed_type_apple_subscription(seasons_fixture): """Test create podcast schema validation fails for feed_type apple_subscription.""" payload = dict( network_id=1, title='title', host='localhost', owner='Billy', description='Description', copyright='copyright', link='http://localhost', email='mail@email.com', explicit='clean', language='en', show_type='episodic', categories=[1], artwork_filename='cow', feed_type='apple-subscription', ) with pytest.raises(ValidationError) as err: schema.CreatePodcastSchema().load(payload) assert err.value.messages == { 'channel_id': ['Missing data for required field.'] } def test_create_podcast_schema_success_for_feed_type_youtube(): """Test create podcast schema validation success for feed_type youtube.""" payload = dict( network_id=1, title='title', host='localhost', owner='Billy', description='Description', copyright='copyright', link='http://localhost', email='mail@email.com', explicit='clean', language='en', show_type='episodic', categories=[1], artwork_filename='cow', feed_type='youtube', channel_id='XYZ1234' ) assert schema.CreatePodcastSchema().load(payload) def test_create_podcast_schema_fails_for_feed_type_youtube(seasons_fixture): """Test create podcast schema validation fails for feed_type youtube.""" payload = dict( network_id=1, title='title', host='localhost', owner='Billy', description='Description', copyright='copyright', link='http://localhost', email='mail@email.com', explicit='clean', language='en', show_type='episodic', categories=[1], artwork_filename='cow', feed_type='youtube', ) with pytest.raises(ValidationError) as err: schema.CreatePodcastSchema().load(payload) assert err.value.messages == { 'channel_id': ['Missing data for required field.'] } def test_create_podcast_schema_fails_for_channel_id_length(seasons_fixture): """Test create podcast schema validation fails for channel id length.""" payload = dict( network_id=1, title='title', host='localhost', owner='Billy', description='Description', copyright='copyright', link='http://localhost', email='mail@email.com', explicit='clean', language='en', show_type='episodic', categories=[1], artwork_filename='cow', feed_type='youtube', channel_id='aaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbccccccccccccccccccccc' ) with pytest.raises(ValidationError) as err: schema.CreatePodcastSchema().load(payload) assert err.value.messages == { 'channel_id': ['Longer than maximum length 50.'] } def test_create_podcast_schema_fails_for_invalid_feed_type(seasons_fixture): """Test create podcast schema validation fails for channel id length.""" payload = dict( network_id=1, title='title', host='localhost', owner='Billy', description='Description', copyright='copyright', link='http://localhost', email='mail@email.com', explicit='clean', language='en', show_type='episodic', categories=[1], artwork_filename='cow', feed_type='you tube', channel_id='ok' ) with pytest.raises(ValidationError) as err: schema.CreatePodcastSchema().load(payload) assert err.value.messages == { 'feed_type': ['Must be one of: public-rss, private-rss, apple-subscription, youtube.'] } def test_replicate_single_episode_success(replicate_single_episode_fixture): """Test replicate single episode validation success.""" result = schema.ReplicateSingleEpisodeSchema().load(replicate_single_episode_fixture) result == replicate_single_episode_fixture def test_replicate_single_episode_success_ad_locations(replicate_single_episode_fixture): """Test replicate single episode validation success.""" replicate_single_episode_fixture['copy_ad_locations_podcast_ids'] = [1] result = schema.ReplicateSingleEpisodeSchema().load(replicate_single_episode_fixture) result == replicate_single_episode_fixture def test_replicate_single_episode_failure(): """Test replicate single episode validation failure.""" payload = { 'podcast_ids': [], 'original_episode_id': 'abc' } with pytest.raises(ValidationError) as err: schema.ReplicateSingleEpisodeSchema().load(payload) assert err.value.messages == { 'original_episode_id': ['Not a valid integer.'], 'podcast_ids': ['Shorter than minimum length 1.'] } second_payload = {} with pytest.raises(ValidationError) as err_2: schema.ReplicateSingleEpisodeSchema().load(second_payload) assert err_2.value.messages == { 'original_episode_id': ['Missing data for required field.'], 'podcast_ids': ['Missing data for required field.'] } def test_update_episode_replication_status_success(update_episode_replication_status_fixture): """Test update episode replication status validation success.""" result = schema.UpdateEpisodeReplicationStatusSchema().load(update_episode_replication_status_fixture) result == update_episode_replication_status_fixture def test_update_episode_replication_status_failure(): """Test update episode replication status validation failure.""" payload = {} with pytest.raises(ValidationError) as err: schema.UpdateEpisodeReplicationStatusSchema().load(payload) assert err.value.messages == { 'ids': ['Missing data for required field.'], 'show_family_id': ['Missing data for required field.'] } second_payload = { 'ids': ['abc'], 'show_family_id': 'xyz' } with pytest.raises(ValidationError) as err_2: schema.UpdateEpisodeReplicationStatusSchema().load(second_payload) assert err_2.value.messages == { 'ids': {0: ['Not a valid integer.']}, 'show_family_id': ['Not a valid integer.'] } def test_replicate_episodes_schema_success(seasons_fixture): """Test replicate episodes schema success.""" payload = dict( original_podcast_id=1, podcast_id=1, original_episode_ids=[1, 2], seasons=seasons_fixture, replication_type='bulk', is_copy_apple_episode_id=True ) assert schema.ReplicateEpisodesSchema().load(payload) def test_replicate_episodes_schema_fails(): """Test replicate episodes schema failure.""" payload = dict(is_copy_apple_episode_id='whatever') with pytest.raises(ValidationError) as err: schema.ReplicateEpisodesSchema().load(payload) assert err.value.messages == { 'replication_type': ['Missing data for required field.'], 'original_podcast_id': ['Missing data for required field.'], 'podcast_id': ['Missing data for required field.'], 'original_episode_ids': ['Missing data for required field.'], 'is_copy_apple_episode_id': ['Not a valid boolean.'] } def test_update_podcast_schema_fails_for_channel_id_length(): """Test update podcast schema validation fails for channel id length.""" payload = dict( network_id=1, title='title', host='localhost', owner='Billy', description='Description', slug='awesome-slug', copyright='copyright', link='http://localhost', email='mail@email.com', explicit='clean', language='en', show_type='episodic', categories=[1], feed_type='public-rss', channel_id='awesome-channel-iddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' ) with pytest.raises(ValidationError) as err: schema.UpdatePodcastSchema().load(payload) assert err.value.messages == { 'channel_id': ['Longer than maximum length 50.'] } def test_draft_episode_fails_for_apple_id(): """Test draft episode schema does not allow apple_id > 20.""" payload = dict( id=1, podcast_id=1, title='title', description='description', season_number=1, episode_number=1, episode_type='full', content='clean', megaphone_id='6bf5bea4-a1d4-11e6-8dea-b334e2aa4880', published_date='2019-12-26T16:52:01.000Z', created_at='2019-12-26T16:52:01.000Z', draft=True, crud='crud', apple_id='apple-iddddddddddddddddddddddddddddddddddddddddddddddd' ) with pytest.raises(ValidationError) as err: schema.DraftEpisodeSchema().load(payload) assert err.value.messages == { 'apple_id': ['Longer than maximum length 20.'] } def test_publish_episode_fails_for_apple_id(): """Test publish episode schema does not allow apple_id > 20.""" payload = dict( id=1, podcast_id=1, title='title', description='description', season_number=1, episode_number=1, episode_type='full', content='clean', megaphone_id='6bf5bea4-a1d4-11e6-8dea-b334e2aa4880', published_date='2019-12-26T16:52:01.000Z', created_at='2019-12-26T16:52:01.000Z', draft=True, crud='crud', apple_id='apple-iddddddddddddddddddddddddddddddddddddddddddddddd' ) with pytest.raises(ValidationError) as err: schema.PublishEpisodeSchema().load(payload) assert err.value.messages == { 'apple_id': ['Longer than maximum length 20.'] }