"""Unit tests for Promo Player logic.""" import datetime from unittest.mock import MagicMock from unittest.mock import patch from owsrequest import request as requests from owsrequest import test_utils from promo_player import config from promo_player.api import app from promo_player.constants import promo_player as promo_player_constants from promo_player.constants import service_name from promo_player.logic import asset from promo_player.logic import feature from promo_player.logic import product from promo_player.logic import promo_player from promo_player.logic import s3 from promo_player.logic import track def test_get_for_frontend_promo_player_error(monkeypatch, fixture_fatal): """Test that an error is returned if the promo player calls fails.""" monkeypatch.setattr( promo_player, 'get_and_validate', MagicMock(return_value=fixture_fatal)) code = '0123456789abcdefghij' correlation_id = 'CORRELATION ID' with app.test_request_context(): result = promo_player._get_for_frontend(code, correlation_id) assert result.status == fixture_fatal.status def test_get_for_frontend_parrallel_error( monkeypatch, fixture_validated_promo_player_response, fixture_fatal, fixture_success): """Test that an error is returned if one of the parrallel call fails.""" monkeypatch.setattr( promo_player, 'get_and_validate', MagicMock(return_value=fixture_validated_promo_player_response)) monkeypatch.setattr( track, 'get_tracks', MagicMock(return_value=fixture_fatal)) monkeypatch.setattr( feature, 'is_promo_player_product_delivered_version_enabled_for_label', MagicMock(return_value=False)) monkeypatch.setattr( asset, 'get_product_assets', MagicMock(return_value=fixture_success)) monkeypatch.setattr( asset, 'get_product_cover_url', MagicMock(return_value=fixture_success)) monkeypatch.setattr( s3, 'get_shared_static_assets_version', MagicMock(return_value=fixture_success)) monkeypatch.setattr( s3, 'get_player_static_assets_version', MagicMock(return_value=fixture_success)) code = '0123456789abcdefghij' correlation_id = 'CORRELATION ID' with app.test_request_context(): result = promo_player._get_for_frontend(code, correlation_id) assert result.status == fixture_fatal.status def test_get_for_frontend_success( monkeypatch, fixture_validated_promo_player_response, fixture_tracks_response, fixture_assets_response, fixture_cover_response, fixture_version_response): """Test that a response with the correct data is returned.""" monkeypatch.setattr( promo_player, 'get_and_validate', MagicMock(return_value=fixture_validated_promo_player_response)) monkeypatch.setattr( track, 'get_tracks', MagicMock(return_value=fixture_tracks_response)) monkeypatch.setattr( asset, 'get_product_assets', MagicMock(return_value=fixture_assets_response)) monkeypatch.setattr( asset, 'get_product_cover_url', MagicMock(return_value=fixture_cover_response)) monkeypatch.setattr( s3, 'get_shared_static_assets_version', MagicMock(return_value=fixture_version_response)) monkeypatch.setattr( s3, 'get_player_static_assets_version', MagicMock(return_value=fixture_version_response)) monkeypatch.setattr( product, 'get_artist_name', MagicMock(return_value='ARTIST')) monkeypatch.setattr( track, 'map_tracks', MagicMock(return_value=['MAPPED TRACKS'])) monkeypatch.setattr( feature, 'is_promo_player_product_delivered_version_enabled_for_label', MagicMock(return_value=False)) monkeypatch.setattr(config, 'CDN_URL', 'https://cdn.test') expected_result = { 'skin': fixture_validated_promo_player_response.message[ 'promo_player']['skin'], 'product_name': fixture_validated_promo_player_response.message[ 'product_details']['product_name'], 'artist_name': 'ARTIST', 'artwork_url': fixture_cover_response.message, 'shared_assets_url': 'https://cdn.test/shared/{0}'.format( fixture_version_response.message), 'player_assets_url': 'https://cdn.test/frontend-audio-player/{0}' .format(fixture_version_response.message), 'tracks': ['MAPPED TRACKS'] } code = '0123456789abcdefghij' correlation_id = 'CORRELATION ID' with app.test_request_context(): result = promo_player._get_for_frontend(code, correlation_id) assert result.message == expected_result def test_get_for_frontend_success_with_delivered_product_version( monkeypatch, fixture_validated_promo_player_response, fixture_tracks_response, fixture_assets_response, fixture_cover_response, fixture_version_response): """Test that a response with the correct data is returned.""" monkeypatch.setattr( promo_player, 'get_and_validate', MagicMock(return_value=fixture_validated_promo_player_response)) monkeypatch.setattr( track, 'get_tracks', MagicMock(return_value=fixture_tracks_response)) monkeypatch.setattr( asset, 'get_product_assets', MagicMock(return_value=fixture_assets_response)) monkeypatch.setattr( asset, 'get_product_cover_url', MagicMock(return_value=fixture_cover_response)) monkeypatch.setattr( s3, 'get_shared_static_assets_version', MagicMock(return_value=fixture_version_response)) monkeypatch.setattr( s3, 'get_player_static_assets_version', MagicMock(return_value=fixture_version_response)) monkeypatch.setattr( product, 'get_artist_name', MagicMock(return_value='ARTIST')) monkeypatch.setattr( track, 'map_tracks', MagicMock(return_value=['MAPPED TRACKS'])) monkeypatch.setattr( feature, 'is_promo_player_product_delivered_version_enabled_for_label', MagicMock(return_value=True)) monkeypatch.setattr(config, 'CDN_URL', 'https://cdn.test') expected_result = { 'skin': 'light', 'product_name': 'Two (Test)', 'artist_name': 'ARTIST', 'artwork_url': fixture_cover_response.message, 'shared_assets_url': 'https://cdn.test/shared/{0}'.format( fixture_version_response.message), 'player_assets_url': 'https://cdn.test/frontend-audio-player/{0}' .format(fixture_version_response.message), 'tracks': ['MAPPED TRACKS'] } code = '0123456789abcdefghij' correlation_id = 'CORRELATION ID' with app.test_request_context(): result = promo_player._get_for_frontend(code, correlation_id) assert result.message == expected_result def test_get_track_manifest_url_promo_player_error( monkeypatch, fixture_fatal): """Test that an error is returned if the promo player calls fails.""" monkeypatch.setattr( promo_player, 'get_and_validate', MagicMock(return_value=fixture_fatal)) code = '0123456789abcdefghij' track_id = 1 result = promo_player.get_track_manifest_url(code, track_id) assert result.status == fixture_fatal.status def test_get_track_manifest_url_track_error( monkeypatch, fixture_validated_promo_player_response, fixture_fatal): """Test that an error is returned if the track calls fails.""" monkeypatch.setattr( promo_player, 'get_and_validate', MagicMock(return_value=fixture_validated_promo_player_response)) monkeypatch.setattr( track, 'get_by_track_id', MagicMock(return_value=fixture_fatal)) code = '0123456789abcdefghij' track_id = 1 result = promo_player.get_track_manifest_url(code, track_id) assert result.status == fixture_fatal.status def test_get_track_manifest_url_product_error( monkeypatch, fixture_validated_promo_player_response, fixture_track_bad_product_response): """Test that error is returned if the track isn't part of the product.""" monkeypatch.setattr( promo_player, 'get_and_validate', MagicMock(return_value=fixture_validated_promo_player_response)) monkeypatch.setattr( track, 'get_by_track_id', MagicMock(return_value=fixture_track_bad_product_response)) code = '0123456789abcdefghij' track_id = 1 result = promo_player.get_track_manifest_url(code, track_id) assert result.status == 404 def test_get_track_manifest_url_success( monkeypatch, fixture_validated_promo_player_response, fixture_track_response, fixture_manifest_url_response): """Test that a manifest URL is returned.""" monkeypatch.setattr( promo_player, 'get_and_validate', MagicMock(return_value=fixture_validated_promo_player_response)) monkeypatch.setattr( track, 'get_by_track_id', MagicMock(return_value=fixture_track_response)) monkeypatch.setattr( asset, 'get_track_manifest_url', MagicMock(return_value=fixture_manifest_url_response)) code = '0123456789abcdefghij' track_id = 1 result = promo_player.get_track_manifest_url(code, track_id) assert result.status == 200 assert result.message['url'] == \ fixture_manifest_url_response.message['url'] def test_get_and_validate_promo_player_error(monkeypatch, fixture_fatal): """Test that an error is returned if the call to ows-promo-player fails.""" monkeypatch.setattr( promo_player, 'get_by_code', MagicMock(return_value=fixture_fatal)) code = '0123456789abcdefghij' result = promo_player.get_and_validate(code) assert result.status == fixture_fatal.status def test_get_and_validate_promo_player_inactive( monkeypatch, fixture_inactive_promo_player_response): """Test that an error is returned if the promo player is not active.""" monkeypatch.setattr( promo_player, 'get_by_code', MagicMock(return_value=fixture_inactive_promo_player_response)) code = '0123456789abcdefghij' result = promo_player.get_and_validate(code) assert result.status == 404 def test_get_and_validate_product_error( monkeypatch, fixture_promo_player_response, fixture_fatal): """Test that an error is returned if the call to ows-product fails.""" monkeypatch.setattr( promo_player, 'get_by_code', MagicMock(return_value=fixture_promo_player_response)) monkeypatch.setattr( product, 'get_by_product_id', MagicMock(return_value=fixture_fatal)) code = '0123456789abcdefghij' result = promo_player.get_and_validate(code) assert result.status == fixture_fatal.status def test_get_and_validate_expired( monkeypatch, fixture_promo_player_response, fixture_product_response): """Test that an error is returned if the promo player has expired.""" monkeypatch.setattr( promo_player, 'get_by_code', MagicMock(return_value=fixture_promo_player_response)) monkeypatch.setattr( product, 'get_by_product_id', MagicMock(return_value=fixture_product_response)) monkeypatch.setattr( promo_player, 'has_expired', MagicMock(return_value=True)) monkeypatch.setattr( promo_player, 'deactivate', MagicMock(return_value=True)) code = '0123456789abcdefghij' result = promo_player.get_and_validate(code) promo_player.deactivate.assert_called_with( fixture_promo_player_response.message['promo_player_id']) assert result.status == 404 def test_get_and_validate_success( monkeypatch, fixture_promo_player_response, fixture_product_response): """Test that a promo player is retrieved, validated and returned.""" monkeypatch.setattr( promo_player, 'get_by_code', MagicMock(return_value=fixture_promo_player_response)) monkeypatch.setattr( product, 'get_by_product_id', MagicMock(return_value=fixture_product_response)) monkeypatch.setattr( promo_player, 'has_expired', MagicMock(return_value=False)) code = '0123456789abcdefghij' expected_result = { 'promo_player': fixture_promo_player_response.message, 'product_details': fixture_product_response.message } result = promo_player.get_and_validate(code) assert result.message == expected_result def test_get_and_validate_without_product_success( monkeypatch, fixture_promo_player_without_product_response): """Test that a promo player without product is validated and returned.""" monkeypatch.setattr( promo_player, 'get_by_code', MagicMock(return_value=fixture_promo_player_without_product_response)) monkeypatch.setattr( promo_player, 'has_expired', MagicMock(return_value=False)) code = '0123456789abcdefghij' expected_result = { 'promo_player': fixture_promo_player_without_product_response.message, 'product_details': {} } result = promo_player.get_and_validate(code) assert result.message == expected_result def test_get_by_code(monkeypatch): """Test retrieving a promo player by code from ows-promo-player.""" code = '0123456789abcdefghij' json_response_mock = { 'promo_player_id': 1 } path = '/player/code/{code}'.format(code=code) call_specs = [{ 'service': service_name.OWS_PROMO_PLAYER, 'path': path, 'status': 200, 'json': json_response_mock }] monkeypatch.setattr( requests, 'get', test_utils.mock_ows_requests(call_specs)) result = promo_player.get_by_code(code) assert result.message['promo_player_id'] == 1 def test_get_by_code_error(monkeypatch): """Test that an error response is returned if the request fails.""" code = '0123456789abcdefghij' path = '/player/code/{code}'.format(code=code) call_specs = [{ 'service': service_name.OWS_PROMO_PLAYER, 'path': path, 'status': 404 }] monkeypatch.setattr( requests, 'get', test_utils.mock_ows_requests(call_specs)) result = promo_player.get_by_code(code) assert result.status == 404 def test_has_expired_release_past(monkeypatch, fixture_now): """Test expiration on product release with a date in the past.""" expiration_mode = promo_player_constants.EXPIRATION_MODE_RELEASE release_date = '1991-01-01' expiry_time = None result = promo_player.has_expired( expiration_mode, release_date, expiry_time) assert result def test_has_expired_release_future(monkeypatch, fixture_now): """Test expiration on product release with a date in the future.""" expiration_mode = promo_player_constants.EXPIRATION_MODE_RELEASE release_date = '2991-01-01' expiry_time = None result = promo_player.has_expired( expiration_mode, release_date, expiry_time) assert not result def test_has_expired_release_no_date(monkeypatch, fixture_now): """Test expiration on product release without a date.""" expiration_mode = promo_player_constants.EXPIRATION_MODE_RELEASE release_date = None expiry_time = None result = promo_player.has_expired( expiration_mode, release_date, expiry_time) assert not result def test_has_expired_time_past(monkeypatch, fixture_now): """Test expiration on expiry time with a time in the past.""" expiration_mode = promo_player_constants.EXPIRATION_MODE_TIME release_date = None expiry_time = datetime.datetime.strptime( '1991-01-01', '%Y-%m-%d').timestamp() result = promo_player.has_expired( expiration_mode, release_date, expiry_time) assert result def test_has_expired_time_future(monkeypatch, fixture_now): """Test expiration on expiry time with a time in the future.""" expiration_mode = promo_player_constants.EXPIRATION_MODE_TIME release_date = None expiry_time = datetime.datetime.strptime( '2991-01-01', '%Y-%m-%d').timestamp() result = promo_player.has_expired( expiration_mode, release_date, expiry_time) assert not result def test_has_expired_time_no_time(monkeypatch, fixture_now): """Test expiration on expiry time with no time.""" expiration_mode = promo_player_constants.EXPIRATION_MODE_TIME release_date = None expiry_time = None result = promo_player.has_expired( expiration_mode, release_date, expiry_time) assert not result def test_has_expired_none(monkeypatch, fixture_now): """Test expiration when no expiration mode.""" expiration_mode = 'none' release_date = None expiry_time = None result = promo_player.has_expired( expiration_mode, release_date, expiry_time) assert not result def test_deactivate(monkeypatch): """Test deactivating a promo player by calling ows-promo-player.""" promo_player_id = 456 path = '/player/{promo_player_id}'.format(promo_player_id=promo_player_id) expected_data = {'active': False} json_response_mock = { 'promo_player_id': promo_player_id } call_specs = [{ 'service': service_name.OWS_PROMO_PLAYER, 'path': path, 'status': 200, 'json': json_response_mock }] monkeypatch.setattr( requests, 'put', test_utils.mock_ows_requests(call_specs)) with patch.object(requests, 'put', wraps=requests.put) as spy: promo_player.deactivate(promo_player_id) spy.assert_called_with( service_name.OWS_PROMO_PLAYER, path, json=expected_data)