"""Tests for message processing module.""" import json from unittest.mock import MagicMock, call import pytest from oto import response from notifications_delivery.config import GET_STREAM_FEED_GROUPS from notifications_delivery.connectors import ses from notifications_delivery.logic import message_processing from notifications_delivery.models import ows_account, ows_features, ows_notifications, ows_users from notifications_delivery.utils import ( email_utils, message_detector, notification_extractor, template_renderer, ) def test_process_message_analytics_digest(monkeypatch): """Test processing analytics_digest message.""" notification_mock = { 'user_ids': ['alw:123', 'alw:456'], 'feed_name': 'label_analytics_digest', 'feed_id': 'vendor_123', 'template': 'analytics_digest', 'payload': { 'start_date': '2018-06-15', 'end_date': '2018-06-22', 'top_new_releases': [], 'top_tracks': [], 'top_releases': [], 'default_brand': 'awal', 'label_name': 'test label' } } users_info_mock = [ { 'type': 'alw', 'user_id': 'alw:123', 'first_name': 'John', 'last_name': 'Doe', 'email': 'johndoe@theorchard.com', 'account': { 'vendor_id': 123, 'subaccount_id': None } }, { 'type': 'alw', 'user_id': 'alw:456', 'first_name': 'Jane', 'last_name': 'Doe', 'email': 'janedoe@theorchard.com', 'account': { 'vendor_id': 123, 'subaccount_id': None } } ] monkeypatch.setattr( message_detector, 'get_message_type', MagicMock(return_value='Notification')) monkeypatch.setattr( notification_extractor, 'parse_message', MagicMock(return_value=notification_mock)) monkeypatch.setattr( ows_users, 'get_users_info', MagicMock(return_value=response.Response(users_info_mock))) monkeypatch.setattr( ows_account, 'get_vendor_company_brand', MagicMock(return_value=response.Response(message='theorchard')) ) monkeypatch.setattr( email_utils, 'format_notification_for_rendering', MagicMock()) monkeypatch.setattr( email_utils, 'get_email_subject', MagicMock(return_value='SUBJECT')) monkeypatch.setattr( email_utils, 'get_preview_text', MagicMock(return_value='PREVIEW TEXT')) monkeypatch.setattr( email_utils, 'generate_unsubscribe_url', MagicMock(return_value='UNSUBSCRIBE URL')) monkeypatch.setattr( email_utils, 'generate_identify_url', MagicMock(return_value='IDENTIFY URL')) monkeypatch.setattr( email_utils, 'generate_tracking_url', MagicMock(return_value='TRACKING URL')) monkeypatch.setattr( ows_features, 'get_user_features', MagicMock(return_value={})) monkeypatch.setattr( template_renderer, 'render_template', MagicMock(return_value='TEMPLATE')) monkeypatch.setattr( ses, 'send_email', MagicMock()) monkeypatch.setattr( email_utils, 'track_email_sent', MagicMock(return_value='TRACKING EMAIL')) monkeypatch.setattr( message_processing, 'is_valid_vendor', MagicMock(return_value=True)) monkeypatch.setattr( message_processing, 'logger', MagicMock(return_value='Test')) message = MagicMock(body='MESSAGE') result = message_processing.process_message(message) notification_extractor.parse_message.assert_called_once_with( 'MESSAGE', 'stream') ows_users.get_users_info.assert_called_once_with(['alw:123', 'alw:456']) email_utils.format_notification_for_rendering.assert_called_once_with( notification_mock) ows_account.get_vendor_company_brand.assert_has_calls([ call(123), call(123)]) email_utils.get_email_subject.assert_has_calls([ call( notification_mock['template'], notification_mock['payload'], 'en' ), call( notification_mock['template'], notification_mock['payload'], 'en' ) ]) email_utils.get_preview_text.assert_has_calls([ call( notification_mock['template'], notification_mock['payload'], 'en' ), call( notification_mock['template'], notification_mock['payload'], 'en' ) ]) email_utils.generate_unsubscribe_url.assert_has_calls([ call('alw:123', 'label_analytics_digest', 'vendor_123'), call('alw:456', 'label_analytics_digest', 'vendor_123'), ]) email_utils.generate_identify_url.assert_has_calls([ call(users_info_mock[0]), call(users_info_mock[1]) ]) email_utils.generate_tracking_url.assert_has_calls([ call( 'alw:123', 'label_analytics_digest', 'vendor_123', 'SUBJECT' ), call( 'alw:456', 'label_analytics_digest', 'vendor_123', 'SUBJECT' ) ]) email_utils.track_email_sent.assert_has_calls([ call( 'alw:123', 'label_analytics_digest', 'vendor_123' ), call( 'alw:456', 'label_analytics_digest', 'vendor_123' ) ]) template_renderer.render_template.assert_has_calls([ call( 'analytics_digest', { 'start_date': '2018-06-15', 'end_date': '2018-06-22', 'top_new_releases': [], 'top_tracks': [], 'top_releases': [], 'preview_text': 'PREVIEW TEXT', 'unsubscribe_url': 'UNSUBSCRIBE URL', 'identify_url': 'IDENTIFY URL', 'tracking_url': 'TRACKING URL', 'default_brand': 'awal', 'label_name': 'test label', }, 'en' ), call( 'analytics_digest', { 'start_date': '2018-06-15', 'end_date': '2018-06-22', 'top_new_releases': [], 'top_tracks': [], 'top_releases': [], 'preview_text': 'PREVIEW TEXT', 'unsubscribe_url': 'UNSUBSCRIBE URL', 'identify_url': 'IDENTIFY URL', 'tracking_url': 'TRACKING URL', 'default_brand': 'awal', 'label_name': 'test label', }, 'en' ) ]) ses.send_email.assert_has_calls([ call({ 'subject': 'SUBJECT', 'to': ['johndoe@theorchard.com'], 'sender': '"The Orchard Notifications" ', 'html_body': 'TEMPLATE', 'text_body': '' }), call({ 'subject': 'SUBJECT', 'to': ['janedoe@theorchard.com'], 'sender': '"The Orchard Notifications" ', 'html_body': 'TEMPLATE', 'text_body': '' }) ]) assert result def test_process_message_analytics_digest_ff(monkeypatch): """Test processing analytics_digest msg if notifications_analytics_digest_new_email FF is ON.""" notification_mock = { 'user_ids': ['alw:123', 'alw:456'], 'feed_name': 'label_analytics_digest', 'feed_id': 'vendor_123', 'template': 'analytics_digest', 'payload': { 'start_date': '2018-06-15', 'end_date': '2018-06-22', 'top_new_releases': [], 'top_tracks': [], 'top_releases': [], 'default_brand': 'awal', 'label_name': 'test label' } } users_info_mock = [ { 'type': 'alw', 'user_id': 'alw:123', 'first_name': 'John', 'last_name': 'Doe', 'email': 'johndoe@theorchard.com', 'account': { 'vendor_id': 123, 'subaccount_id': None } }, { 'type': 'alw', 'user_id': 'alw:456', 'first_name': 'Jane', 'last_name': 'Doe', 'email': 'janedoe@theorchard.com', 'account': { 'vendor_id': 123, 'subaccount_id': None } } ] monkeypatch.setattr( message_detector, 'get_message_type', MagicMock(return_value='Notification')) monkeypatch.setattr( notification_extractor, 'parse_message', MagicMock(return_value=notification_mock)) monkeypatch.setattr( ows_users, 'get_users_info', MagicMock(return_value=response.Response(users_info_mock))) monkeypatch.setattr( ows_account, 'get_vendor_company_brand', MagicMock(return_value=response.Response(message='theorchard')) ) monkeypatch.setattr( email_utils, 'format_notification_for_rendering', MagicMock()) monkeypatch.setattr( email_utils, 'get_email_subject', MagicMock(return_value='SUBJECT')) monkeypatch.setattr( email_utils, 'get_preview_text', MagicMock(return_value='PREVIEW TEXT')) monkeypatch.setattr( email_utils, 'generate_unsubscribe_url', MagicMock(return_value='UNSUBSCRIBE URL')) monkeypatch.setattr( email_utils, 'generate_identify_url', MagicMock(return_value='IDENTIFY URL')) monkeypatch.setattr( email_utils, 'generate_tracking_url', MagicMock(return_value='TRACKING URL')) monkeypatch.setattr( ows_features, 'get_user_features', MagicMock(return_value={ 'notifications_analytics_digest_new_email': 'enabled' })) monkeypatch.setattr( template_renderer, 'render_template', MagicMock(return_value='

rendered TEMPLATE

')) monkeypatch.setattr( ses, 'send_email', MagicMock()) monkeypatch.setattr( email_utils, 'track_email_sent', MagicMock(return_value='TRACKING EMAIL')) monkeypatch.setattr( message_processing, 'is_valid_vendor', MagicMock(return_value=True)) monkeypatch.setattr( message_processing, 'logger', MagicMock(return_value='Test')) message = MagicMock(body='MESSAGE') result = message_processing.process_message(message) notification_extractor.parse_message.assert_called_once_with( 'MESSAGE', 'stream') ows_users.get_users_info.assert_called_once_with(['alw:123', 'alw:456']) email_utils.format_notification_for_rendering.assert_called_once_with( notification_mock) ows_account.get_vendor_company_brand.assert_has_calls([ call(123), call(123)]) email_utils.get_email_subject.assert_has_calls([ call( notification_mock['template'], notification_mock['payload'], 'en' ), call( notification_mock['template'], notification_mock['payload'], 'en' ) ]) email_utils.get_preview_text.assert_has_calls([ call( notification_mock['template'], notification_mock['payload'], 'en' ), call( notification_mock['template'], notification_mock['payload'], 'en' ) ]) email_utils.generate_unsubscribe_url.assert_has_calls([ call('alw:123', 'label_analytics_digest', 'vendor_123'), call('alw:456', 'label_analytics_digest', 'vendor_123'), ]) email_utils.generate_identify_url.assert_has_calls([ call(users_info_mock[0]), call(users_info_mock[1]) ]) email_utils.generate_tracking_url.assert_has_calls([ call( 'alw:123', 'label_analytics_digest', 'vendor_123', 'SUBJECT' ), call( 'alw:456', 'label_analytics_digest', 'vendor_123', 'SUBJECT' ) ]) email_utils.track_email_sent.assert_has_calls([ call( 'alw:123', 'label_analytics_digest', 'vendor_123' ), call( 'alw:456', 'label_analytics_digest', 'vendor_123' ) ]) template_renderer.render_template.assert_has_calls([ call( 'branded_analytics_digest', { 'start_date': '2018-06-15', 'end_date': '2018-06-22', 'top_new_releases': [], 'top_tracks': [], 'top_releases': [], 'preview_text': 'PREVIEW TEXT', 'unsubscribe_url': 'UNSUBSCRIBE URL', 'identify_url': 'IDENTIFY URL', 'tracking_url': 'TRACKING URL', 'default_brand': 'awal', 'label_name': 'test label', }, 'en' ), call( 'branded_analytics_digest', { 'start_date': '2018-06-15', 'end_date': '2018-06-22', 'top_new_releases': [], 'top_tracks': [], 'top_releases': [], 'preview_text': 'PREVIEW TEXT', 'unsubscribe_url': 'UNSUBSCRIBE URL', 'identify_url': 'IDENTIFY URL', 'tracking_url': 'TRACKING URL', 'default_brand': 'awal', 'label_name': 'test label', }, 'en' ) ]) ses.send_email.assert_has_calls([ call({ 'subject': 'SUBJECT', 'to': ['johndoe@theorchard.com'], 'sender': '"The Orchard Notifications" ', 'html_body': '

rendered TEMPLATE

', 'text_body': '' }), call({ 'subject': 'SUBJECT', 'to': ['janedoe@theorchard.com'], 'sender': '"The Orchard Notifications" ', 'html_body': '

rendered TEMPLATE

', 'text_body': '' }) ]) assert result def test_process_message_spike_detector(monkeypatch): """Test processing spike_detector message.""" notification_mock = { 'user_ids': ['alw:123', 'alw:456'], 'feed_name': 'label_spike_detector', 'feed_id': 'vendor_123', 'template': 'spike_detector', 'payload': { 'date': '2018-06-15', 'trending_tracks': [], 'default_brand': 'awal', 'label_name': 'test label', } } users_info_mock = [ { 'type': 'alw', 'user_id': 'alw:123', 'first_name': 'John', 'last_name': 'Doe', 'email': 'johndoe@theorchard.com', 'account': { 'vendor_id': 123, 'subaccount_id': None } }, { 'type': 'alw', 'user_id': 'alw:456', 'first_name': 'Jane', 'last_name': 'Doe', 'email': 'janedoe@theorchard.com', 'account': { 'vendor_id': 123, 'subaccount_id': None } } ] monkeypatch.setattr( message_detector, 'get_message_type', MagicMock(return_value='Notification')) monkeypatch.setattr( notification_extractor, 'parse_message', MagicMock(return_value=notification_mock)) monkeypatch.setattr( ows_users, 'get_users_info', MagicMock(return_value=response.Response(users_info_mock))) monkeypatch.setattr( ows_account, 'get_vendor_company_brand', MagicMock(return_value=response.Response(message='theorchard')) ) monkeypatch.setattr( email_utils, 'format_notification_for_rendering', MagicMock()) monkeypatch.setattr( email_utils, 'get_email_subject', MagicMock(return_value='SUBJECT')) monkeypatch.setattr( email_utils, 'get_preview_text', MagicMock(return_value='PREVIEW TEXT')) monkeypatch.setattr( email_utils, 'generate_unsubscribe_url', MagicMock(return_value='UNSUBSCRIBE URL')) monkeypatch.setattr( email_utils, 'generate_identify_url', MagicMock(return_value='IDENTIFY URL')) monkeypatch.setattr( email_utils, 'generate_tracking_url', MagicMock(return_value='TRACKING URL')) monkeypatch.setattr( template_renderer, 'render_template', MagicMock(return_value='TEMPLATE')) monkeypatch.setattr( ses, 'send_email', MagicMock()) monkeypatch.setattr( email_utils, 'track_email_sent', MagicMock(return_value='TRACKING EMAIL')) monkeypatch.setattr( ows_features, 'get_user_features', MagicMock(return_value={})) monkeypatch.setattr( message_processing, 'is_valid_vendor', MagicMock(return_value=True)) monkeypatch.setattr( message_processing, 'logger', MagicMock(return_value='Test')) message = MagicMock(body='MESSAGE') result = message_processing.process_message(message) notification_extractor.parse_message.assert_called_once_with( 'MESSAGE', 'stream') ows_users.get_users_info.assert_called_once_with(['alw:123', 'alw:456']) email_utils.format_notification_for_rendering.assert_called_once_with( notification_mock) ows_account.get_vendor_company_brand.assert_has_calls([ call(123), call(123)]) email_utils.get_email_subject.assert_has_calls([ call( notification_mock['template'], notification_mock['payload'], 'en' ), call( notification_mock['template'], notification_mock['payload'], 'en' ) ]) email_utils.get_preview_text.assert_has_calls([ call( notification_mock['template'], notification_mock['payload'], 'en' ), call( notification_mock['template'], notification_mock['payload'], 'en' ) ]) email_utils.generate_unsubscribe_url.assert_has_calls([ call('alw:123', 'label_spike_detector', 'vendor_123'), call('alw:456', 'label_spike_detector', 'vendor_123'), ]) email_utils.generate_identify_url.assert_has_calls([ call(users_info_mock[0]), call(users_info_mock[1]) ]) email_utils.generate_tracking_url.assert_has_calls([ call( 'alw:123', 'label_spike_detector', 'vendor_123', 'SUBJECT' ), call( 'alw:456', 'label_spike_detector', 'vendor_123', 'SUBJECT' ) ]) email_utils.track_email_sent.assert_has_calls([ call( 'alw:123', 'label_spike_detector', 'vendor_123' ), call( 'alw:456', 'label_spike_detector', 'vendor_123' ) ]) template_renderer.render_template.assert_has_calls([ call( 'spike_detector', { 'date': '2018-06-15', 'trending_tracks': [], 'preview_text': 'PREVIEW TEXT', 'unsubscribe_url': 'UNSUBSCRIBE URL', 'identify_url': 'IDENTIFY URL', 'tracking_url': 'TRACKING URL', 'default_brand': 'awal', 'label_name': 'test label', }, 'en' ), call( 'spike_detector', { 'date': '2018-06-15', 'trending_tracks': [], 'preview_text': 'PREVIEW TEXT', 'unsubscribe_url': 'UNSUBSCRIBE URL', 'identify_url': 'IDENTIFY URL', 'tracking_url': 'TRACKING URL', 'default_brand': 'awal', 'label_name': 'test label', }, 'en' ) ]) ses.send_email.assert_has_calls([ call({ 'subject': 'SUBJECT', 'to': ['johndoe@theorchard.com'], 'sender': '"The Orchard Notifications" ', # noqa 'html_body': 'TEMPLATE', 'text_body': '' }), call({ 'subject': 'SUBJECT', 'to': ['janedoe@theorchard.com'], 'sender': '"The Orchard Notifications" ', # noqa 'html_body': 'TEMPLATE', 'text_body': '' }) ]) assert result def test_process_message_spike_detector_ff(monkeypatch): """Test processing spike_detector message if notifications_spike_detector_new_email FF is ON.""" notification_mock = { 'user_ids': ['alw:123', 'alw:456'], 'feed_name': 'label_spike_detector', 'feed_id': 'vendor_123', 'template': 'spike_detector', 'payload': { 'date': '2018-06-15', 'trending_tracks': [], 'default_brand': 'awal', 'label_name': 'test label', } } users_info_mock = [ { 'type': 'alw', 'user_id': 'alw:123', 'first_name': 'John', 'last_name': 'Doe', 'email': 'johndoe@theorchard.com', 'account': { 'vendor_id': 123, 'subaccount_id': None } }, { 'type': 'alw', 'user_id': 'alw:456', 'first_name': 'Jane', 'last_name': 'Doe', 'email': 'janedoe@theorchard.com', 'account': { 'vendor_id': 123, 'subaccount_id': None } } ] monkeypatch.setattr( message_detector, 'get_message_type', MagicMock(return_value='Notification')) monkeypatch.setattr( notification_extractor, 'parse_message', MagicMock(return_value=notification_mock)) monkeypatch.setattr( ows_users, 'get_users_info', MagicMock(return_value=response.Response(users_info_mock))) monkeypatch.setattr( ows_account, 'get_vendor_company_brand', MagicMock(return_value=response.Response(message='theorchard')) ) monkeypatch.setattr( email_utils, 'format_notification_for_rendering', MagicMock()) monkeypatch.setattr( email_utils, 'get_email_subject', MagicMock(return_value='SUBJECT')) monkeypatch.setattr( email_utils, 'get_preview_text', MagicMock(return_value='PREVIEW TEXT')) monkeypatch.setattr( email_utils, 'generate_unsubscribe_url', MagicMock(return_value='UNSUBSCRIBE URL')) monkeypatch.setattr( email_utils, 'generate_identify_url', MagicMock(return_value='IDENTIFY URL')) monkeypatch.setattr( email_utils, 'generate_tracking_url', MagicMock(return_value='TRACKING URL')) monkeypatch.setattr( template_renderer, 'render_template', MagicMock(return_value='TEMPLATE')) monkeypatch.setattr( ses, 'send_email', MagicMock()) monkeypatch.setattr( email_utils, 'track_email_sent', MagicMock(return_value='TRACKING EMAIL')) monkeypatch.setattr( ows_features, 'get_user_features', MagicMock(return_value={ 'notifications_spike_detector_new_email': 'enabled' })) monkeypatch.setattr( message_processing, 'is_valid_vendor', MagicMock(return_value=True)) monkeypatch.setattr( message_processing, 'logger', MagicMock(return_value='Test')) message = MagicMock(body='MESSAGE') result = message_processing.process_message(message) notification_extractor.parse_message.assert_called_once_with( 'MESSAGE', 'stream') ows_users.get_users_info.assert_called_once_with(['alw:123', 'alw:456']) email_utils.format_notification_for_rendering.assert_called_once_with( notification_mock) ows_account.get_vendor_company_brand.assert_has_calls([ call(123), call(123)]) email_utils.get_email_subject.assert_has_calls([ call( notification_mock['template'], notification_mock['payload'], 'en' ), call( notification_mock['template'], notification_mock['payload'], 'en' ) ]) email_utils.get_preview_text.assert_has_calls([ call( notification_mock['template'], notification_mock['payload'], 'en' ), call( notification_mock['template'], notification_mock['payload'], 'en' ) ]) email_utils.generate_unsubscribe_url.assert_has_calls([ call('alw:123', 'label_spike_detector', 'vendor_123'), call('alw:456', 'label_spike_detector', 'vendor_123'), ]) email_utils.generate_identify_url.assert_has_calls([ call(users_info_mock[0]), call(users_info_mock[1]) ]) email_utils.generate_tracking_url.assert_has_calls([ call( 'alw:123', 'label_spike_detector', 'vendor_123', 'SUBJECT' ), call( 'alw:456', 'label_spike_detector', 'vendor_123', 'SUBJECT' ) ]) email_utils.track_email_sent.assert_has_calls([ call( 'alw:123', 'label_spike_detector', 'vendor_123' ), call( 'alw:456', 'label_spike_detector', 'vendor_123' ) ]) template_renderer.render_template.assert_has_calls([ call( 'branded_spike_detector', { 'date': '2018-06-15', 'trending_tracks': [], 'preview_text': 'PREVIEW TEXT', 'unsubscribe_url': 'UNSUBSCRIBE URL', 'identify_url': 'IDENTIFY URL', 'tracking_url': 'TRACKING URL', 'default_brand': 'awal', 'label_name': 'test label', }, 'en' ), call( 'branded_spike_detector', { 'date': '2018-06-15', 'trending_tracks': [], 'preview_text': 'PREVIEW TEXT', 'unsubscribe_url': 'UNSUBSCRIBE URL', 'identify_url': 'IDENTIFY URL', 'tracking_url': 'TRACKING URL', 'default_brand': 'awal', 'label_name': 'test label', }, 'en' ) ]) ses.send_email.assert_has_calls([ call({ 'subject': 'SUBJECT', 'to': ['johndoe@theorchard.com'], 'sender': '"The Orchard Notifications" ', # noqa 'html_body': 'TEMPLATE', 'text_body': '' }), call({ 'subject': 'SUBJECT', 'to': ['janedoe@theorchard.com'], 'sender': '"The Orchard Notifications" ', # noqa 'html_body': 'TEMPLATE', 'text_body': '' }) ]) assert result def test_process_message_trending_tracks(monkeypatch): """Test processing trending_tracks message.""" notification_mock = { 'user_emails': ['john@gmail.com', 'jane@gmail.com'], 'feed_name': 'orchard_trending_tracks_united_states', 'feed_id': 'orchard', 'template': 'trending_tracks', 'payload': { 'start_date': '2018-08-18', 'end_date': '2018-08-24', 'country_group_name': 'United States', 'global_trending_tracks': [], 'trending_tracks': [], 'default_brand': 'awal', 'label_name': 'test label', } } monkeypatch.setattr( message_detector, 'get_message_type', MagicMock(return_value='Notification')) monkeypatch.setattr( notification_extractor, 'parse_message', MagicMock(return_value=notification_mock)) monkeypatch.setattr( email_utils, 'format_notification_for_rendering', MagicMock()) monkeypatch.setattr( email_utils, 'get_email_subject', MagicMock(return_value='SUBJECT')) monkeypatch.setattr( email_utils, 'get_preview_text', MagicMock(return_value='PREVIEW TEXT')) monkeypatch.setattr( email_utils, 'generate_unsubscribe_url', MagicMock(return_value='UNSUBSCRIBE URL')) monkeypatch.setattr( email_utils, 'generate_identify_url', MagicMock(return_value='IDENTIFY URL')) monkeypatch.setattr( email_utils, 'generate_tracking_url', MagicMock(return_value='TRACKING URL')) monkeypatch.setattr( template_renderer, 'render_template', MagicMock(return_value='TEMPLATE')) monkeypatch.setattr( ses, 'send_email', MagicMock()) monkeypatch.setattr( email_utils, 'track_email_sent', MagicMock(return_value='TRACKING EMAIL')) monkeypatch.setattr( message_processing, 'is_valid_vendor', MagicMock(return_value=True)) monkeypatch.setattr( message_processing, 'logger', MagicMock(return_value='Test')) message = MagicMock(body='MESSAGE') result = message_processing.process_message(message) notification_extractor.parse_message.assert_called_once_with( 'MESSAGE', 'stream') email_utils.format_notification_for_rendering.assert_called_once_with( notification_mock) email_utils.get_email_subject.assert_has_calls([ call( notification_mock['template'], notification_mock['payload'], 'en' ), call( notification_mock['template'], notification_mock['payload'], 'en' ) ]) email_utils.get_preview_text.assert_has_calls([ call( notification_mock['template'], notification_mock['payload'], 'en' ), call( notification_mock['template'], notification_mock['payload'], 'en' ) ]) email_utils.generate_unsubscribe_url.assert_has_calls([ call( 'john@gmail.com', 'orchard_trending_tracks_united_states', 'orchard' ), call( 'jane@gmail.com', 'orchard_trending_tracks_united_states', 'orchard' ), ]) email_utils.generate_identify_url.assert_has_calls([ call({'user_id': 'john@gmail.com', 'email': 'john@gmail.com'}), call({'user_id': 'jane@gmail.com', 'email': 'jane@gmail.com'}) ]) email_utils.generate_tracking_url.assert_has_calls([ call( 'john@gmail.com', 'orchard_trending_tracks_united_states', 'orchard', 'SUBJECT' ), call( 'jane@gmail.com', 'orchard_trending_tracks_united_states', 'orchard', 'SUBJECT' ) ]) email_utils.track_email_sent.assert_has_calls([ call( 'john@gmail.com', 'orchard_trending_tracks_united_states', 'orchard' ), call( 'jane@gmail.com', 'orchard_trending_tracks_united_states', 'orchard' ) ]) template_renderer.render_template.assert_has_calls([ call( 'trending_tracks', { 'start_date': '2018-08-18', 'end_date': '2018-08-24', 'country_group_name': 'United States', 'global_trending_tracks': [], 'trending_tracks': [], 'preview_text': 'PREVIEW TEXT', 'unsubscribe_url': 'UNSUBSCRIBE URL', 'identify_url': 'IDENTIFY URL', 'tracking_url': 'TRACKING URL', 'default_brand': 'awal', 'label_name': 'test label', }, 'en' ), call( 'trending_tracks', { 'start_date': '2018-08-18', 'end_date': '2018-08-24', 'country_group_name': 'United States', 'global_trending_tracks': [], 'trending_tracks': [], 'preview_text': 'PREVIEW TEXT', 'unsubscribe_url': 'UNSUBSCRIBE URL', 'identify_url': 'IDENTIFY URL', 'tracking_url': 'TRACKING URL', 'default_brand': 'awal', 'label_name': 'test label', }, 'en' ) ]) ses.send_email.assert_has_calls([ call({ 'subject': 'SUBJECT', 'to': ['john@gmail.com'], 'sender': '"Orchard Trending Tracks" ', 'html_body': 'TEMPLATE', 'text_body': '' }), call({ 'subject': 'SUBJECT', 'to': ['jane@gmail.com'], 'sender': '"Orchard Trending Tracks" ', 'html_body': 'TEMPLATE', 'text_body': '' }) ]) assert result def test_process_message_users_info(monkeypatch): """Test processing message when the users info are provided.""" notification_mock = { 'users_info': [ { 'type': 'alw', 'user_id': 'alw:123', 'first_name': 'John', 'last_name': 'Doe', 'email': 'johndoe@theorchard.com', 'language': 'fr', 'account': { 'vendor_id': 123, 'subaccount_id': None } }, { 'type': 'alw', 'user_id': 'alw:456', 'first_name': 'Jane', 'last_name': 'Doe', 'email': 'janedoe@theorchard.com', 'language': 'de', 'account': { 'vendor_id': 123, 'subaccount_id': None } } ], 'feed_name': 'label_analytics_digest', 'feed_id': 'vendor_123', 'template': 'analytics_digest', 'payload': { 'start_date': '2018-06-15', 'end_date': '2018-06-22', 'top_new_releases': [], 'top_tracks': [], 'top_releases': [], 'default_brand': 'awal', 'label_name': 'test label', } } monkeypatch.setattr( notification_extractor, 'parse_message', MagicMock(return_value=notification_mock)) monkeypatch.setattr( ows_users, 'get_users_info', MagicMock()) monkeypatch.setattr( ows_account, 'get_vendor_company_brand', MagicMock(return_value=response.Response(message='theorchard'))) monkeypatch.setattr( email_utils, 'format_notification_for_rendering', MagicMock()) monkeypatch.setattr( email_utils, 'get_email_subject', MagicMock(return_value='SUBJECT')) monkeypatch.setattr( email_utils, 'get_preview_text', MagicMock(return_value='PREVIEW TEXT')) monkeypatch.setattr( email_utils, 'generate_unsubscribe_url', MagicMock(return_value='UNSUBSCRIBE URL')) monkeypatch.setattr( email_utils, 'generate_identify_url', MagicMock(return_value='IDENTIFY URL')) monkeypatch.setattr( email_utils, 'generate_tracking_url', MagicMock(return_value='TRACKING URL')) monkeypatch.setattr( ows_features, 'get_user_features', MagicMock(return_value={})) monkeypatch.setattr( template_renderer, 'render_template', MagicMock(return_value='TEMPLATE')) monkeypatch.setattr( ses, 'send_email', MagicMock()) monkeypatch.setattr( email_utils, 'track_email_sent', MagicMock(return_value='TRACKING EMAIL')) monkeypatch.setattr( message_processing, 'is_valid_vendor', MagicMock(return_value=True)) monkeypatch.setattr( message_processing, 'logger', MagicMock(return_value=None)) message = MagicMock(body='MESSAGE') result = message_processing.process_message(message) notification_extractor.parse_message.assert_called_once_with( 'MESSAGE', 'stream') ows_users.get_users_info.assert_not_called() ows_account.get_vendor_company_brand.assert_has_calls([ call(123), call(123)]) email_utils.format_notification_for_rendering.assert_called_once_with( notification_mock) email_utils.get_email_subject.assert_has_calls([ call( notification_mock['template'], notification_mock['payload'], 'fr' ), call( notification_mock['template'], notification_mock['payload'], 'de' ) ]) email_utils.get_preview_text.assert_has_calls([ call( notification_mock['template'], notification_mock['payload'], 'fr' ), call( notification_mock['template'], notification_mock['payload'], 'de' ) ]) email_utils.generate_unsubscribe_url.assert_has_calls([ call('alw:123', 'label_analytics_digest', 'vendor_123'), call('alw:456', 'label_analytics_digest', 'vendor_123'), ]) email_utils.generate_identify_url.assert_has_calls([ call(notification_mock['users_info'][0]), call(notification_mock['users_info'][1]) ]) email_utils.generate_tracking_url.assert_has_calls([ call( 'alw:123', 'label_analytics_digest', 'vendor_123', 'SUBJECT' ), call( 'alw:456', 'label_analytics_digest', 'vendor_123', 'SUBJECT' ) ]) email_utils.track_email_sent.assert_has_calls([ call( 'alw:123', 'label_analytics_digest', 'vendor_123' ), call( 'alw:456', 'label_analytics_digest', 'vendor_123' ) ]) template_renderer.render_template.assert_has_calls([ call( 'analytics_digest', { 'start_date': '2018-06-15', 'end_date': '2018-06-22', 'top_new_releases': [], 'top_tracks': [], 'top_releases': [], 'preview_text': 'PREVIEW TEXT', 'unsubscribe_url': 'UNSUBSCRIBE URL', 'identify_url': 'IDENTIFY URL', 'tracking_url': 'TRACKING URL', 'default_brand': 'awal', 'label_name': 'test label', }, 'fr' ), call( 'analytics_digest', { 'start_date': '2018-06-15', 'end_date': '2018-06-22', 'top_new_releases': [], 'top_tracks': [], 'top_releases': [], 'preview_text': 'PREVIEW TEXT', 'unsubscribe_url': 'UNSUBSCRIBE URL', 'identify_url': 'IDENTIFY URL', 'tracking_url': 'TRACKING URL', 'default_brand': 'awal', 'label_name': 'test label', }, 'de' ) ]) ses.send_email.assert_has_calls([ call({ 'subject': 'SUBJECT', 'to': ['johndoe@theorchard.com'], 'sender': '"The Orchard Notifications" ', 'html_body': 'TEMPLATE', 'text_body': '' }), call({ 'subject': 'SUBJECT', 'to': ['janedoe@theorchard.com'], 'sender': '"The Orchard Notifications" ', 'html_body': 'TEMPLATE', 'text_body': '' }) ]) assert result def test_process_message_invalid_message(monkeypatch): """Test processing message when the message is invalid.""" monkeypatch.setattr( notification_extractor, 'parse_message', MagicMock(return_value=None)) message = MagicMock(body='MESSAGE') result = message_processing.process_message(message) assert not result assert result.errors == { 'code': 'message_processing_error', 'message': 'Invalid SQS message' } def test_process_message_ows_users_error(monkeypatch): """Test processing message when no users info is received.""" notification_mock = { 'user_ids': ['alw:123', 'alw:456'], 'feed_name': 'label_analytics_digest', 'feed_id': 'vendor_123', 'template': 'analytics_digest', 'payload': {} } ows_users_response_mock = response.Response([]) monkeypatch.setattr( message_detector, 'get_message_type', MagicMock(return_value='Notification')) monkeypatch.setattr( notification_extractor, 'parse_message', MagicMock(return_value=notification_mock)) monkeypatch.setattr( ows_users, 'get_users_info', MagicMock(return_value=ows_users_response_mock)) message = MagicMock(body='MESSAGE') result = message_processing.process_message(message) assert not result assert result.errors == { 'code': 'message_processing_error', 'message': 'No users to send email to' } def test_process_message_with_invalid_vendor_status(monkeypatch): """Test processing message when vendor status is not signed.""" notification_mock = { 'user_ids': ['alw:123', 'alw:456'], 'feed_name': 'label_analytics_digest', 'feed_id': 'vendor_123', 'template': 'analytics_digest', 'payload': {} } ows_users_response_mock = response.Response([ { 'type': 'alw', 'user_id': 'alw:123', 'first_name': 'John', 'last_name': 'Doe', 'email': 'johndoe@theorchard.com', 'language': 'fr', 'account': { 'vendor_id': 123, 'subaccount_id': None } }, { 'type': 'alw', 'user_id': 'alw:456', 'first_name': 'Jane', 'last_name': 'Doe', 'email': 'janedoe@theorchard.com', 'language': 'de', 'account': { 'vendor_id': 123, 'subaccount_id': None } }]) monkeypatch.setattr( message_detector, 'get_message_type', MagicMock(return_value='Notification')) monkeypatch.setattr( notification_extractor, 'parse_message', MagicMock(return_value=notification_mock)) monkeypatch.setattr( ows_users, 'get_users_info', MagicMock(return_value=ows_users_response_mock)) monkeypatch.setattr( message_processing, 'is_valid_vendor', MagicMock(return_value=False)) monkeypatch.setattr( message_processing, 'unsubscribe_alw_users', MagicMock(return_value=None)) monkeypatch.setattr( message_processing, 'unsubscribe_email_from_all_feeds', MagicMock(return_value=None)) message = MagicMock(body='MESSAGE') result = message_processing.process_message(message) assert not result assert result.errors == { 'code': 'message_processing_error', 'message': 'Invalid or inactive vendor: 123' } def test_process_message_with_invalid_email(monkeypatch): """Test processing message when email is not valid.""" notification_mock = { 'user_ids': ['alw:123', 'alw:456'], 'feed_name': 'label_analytics_digest', 'feed_id': 'vendor_123', 'template': 'analytics_digest', 'payload': {} } ows_users_response_mock = response.Response([ { 'type': 'alw', 'user_id': 'alw:123', 'first_name': 'John', 'last_name': 'Doe', 'email': 'invalid email', 'language': 'fr', 'account': { 'vendor_id': 123, 'subaccount_id': None } }]) monkeypatch.setattr( message_detector, 'get_message_type', MagicMock(return_value='Notification')) monkeypatch.setattr( notification_extractor, 'parse_message', MagicMock(return_value=notification_mock)) monkeypatch.setattr( ows_users, 'get_users_info', MagicMock(return_value=ows_users_response_mock)) monkeypatch.setattr( message_processing, 'is_valid_vendor', MagicMock(return_value=True)) monkeypatch.setattr( message_processing, 'unsubscribe_alw_users', MagicMock(return_value=None)) monkeypatch.setattr( message_processing, 'unsubscribe_email_from_all_feeds', MagicMock(return_value=None)) monkeypatch.setattr( ses, 'send_email', MagicMock(return_value=None)) message = MagicMock(body='MESSAGE') result = message_processing.process_message(message) assert not ses.send_email.called assert message_processing.unsubscribe_alw_users.called_with('invalid email') assert message_processing.unsubscribe_email_from_all_feeds.called_with('invalid email') assert result def test_process_message_ses_notification(monkeypatch): """Test processing message when bounced notification.""" monkeypatch.setattr( message_detector, 'get_message_type', MagicMock(return_value='Bounce')) monkeypatch.setattr( email_utils, 'extract_bounced_emails_from_ses_notification', MagicMock(return_value=['EMAIL', 'EMAIL_2'])) monkeypatch.setattr( email_utils, 'track_email_bounce', MagicMock()) monkeypatch.setattr( message_processing, 'unsubscribe_alw_users', MagicMock()) message = MagicMock(body='{}') result = message_processing.process_message(message) assert result assert email_utils.track_email_bounce.call_count == 2 email_utils.track_email_bounce.assert_has_calls([ call('EMAIL'), call('EMAIL_2')]) # assert message_processing.unsubscribe_alw_users.call_count == 2 def test_remove_inactive_users(): """Test removing inactive users.""" users = [ { 'email': 'email', 'active': 'Y' }, { 'email': 'email2', 'active': 'N' }, { 'email': 'email3', 'active': 'Y' }, { 'email': 'email4', 'active': None }, { 'email': 'email5' } ] result = message_processing.remove_inactive_users(users) expected_result = [ { 'email': 'email', 'active': 'Y' }, { 'email': 'email3', 'active': 'Y' }, { 'email': 'email5' } ] assert result == expected_result def test_remove_duplicate_users(): """Test removing duplicate users.""" users = [ { 'email': 'email', 'active': 'Y' }, { 'email': 'email2', 'active': 'Y' }, { 'email': 'email' } ] result = message_processing.remove_duplicate_users(users) expected_result = [ { 'email': 'email', 'active': 'Y' }, { 'email': 'email2', 'active': 'Y' } ] assert result == expected_result def test_unsubscribe_alw_users(monkeypatch): """Test unsubscribe alw users.""" monkeypatch.setattr( ows_users, 'get_alw_users_by_email', MagicMock( return_value=response.Response( {'items': [{ 'email': 'email', 'user_id': 123, 'vendor_id': 123 }]}))) monkeypatch.setattr( ows_notifications, 'get_vendor_subscriptions', MagicMock( return_value=response.Response( {'items': [ 'label_analytics_digest:alw_123', 'label_analytics_digest:oa_456' ]}))) monkeypatch.setattr( ows_notifications, 'unsubscribe_user', MagicMock()) message_processing.unsubscribe_alw_users('email') ows_notifications.unsubscribe_user.assert_has_calls([ call({ 'email': 'email', 'user_id': 123, 'vendor_id': 123 }, 'label_analytics_digest'), call({ 'email': 'email', 'user_id': 123, 'vendor_id': 123 }, 'label_spike_detector'), call({ 'email': 'email', 'user_id': 123, 'vendor_id': 123 }, 'label_video_product_rejection'), call({ 'email': 'email', 'user_id': 123, 'vendor_id': 123 }, 'label_video_product_approval') ]) def test_unsubscribe_alw_users_without_users_info(monkeypatch): """Test unsubscribe alw users without user info from ows-users.""" monkeypatch.setattr( ows_users, 'get_alw_users_by_email', MagicMock( return_value=response.create_error_response( code=500, message='error'))) monkeypatch.setattr( ows_notifications, 'unsubscribe_user', MagicMock()) message_processing.unsubscribe_alw_users('email') ows_notifications.unsubscribe_user.assert_not_called() @pytest.mark.parametrize( ('user_id_key', 'user_id_value'), [ pytest.param(None, None, id='No user id'), pytest.param('userId', 'TEST_USER_ID', id='userId as key and valid value'), pytest.param('user_id', 'TEST_USER_ID', id='user_id as key and valid value'), pytest.param('userId', None, id='userId as key and invalid value'), pytest.param('user_id', None, id='user_id as key and invalid value'), ] ) def test_general_notifications(user_id_key, user_id_value, monkeypatch): """Test processing GeneralNotification messages for various user_id scenarios.""" monkeypatch.setattr( template_renderer, 'render_template', MagicMock(return_value='TEMPLATE')) monkeypatch.setattr( ses, 'send_email', MagicMock()) monkeypatch.setattr( email_utils, 'track_generic_email_sent', MagicMock() ) monkeypatch.setattr( email_utils, 'generate_generic_tracking_url', MagicMock(return_value='TRACKING URL')) subject = 'Host Read Ad Assigned' message_body = { 'type': 'GeneralNotification', 'subject': subject, 'to': ['jodonnell@theorchard.com'], 'template': 'host_read_ad_assigned', 'lang': 'en', 'sender': "'The Orchard Podcasts' ", 'variables': { 'organization': 'orchard', } } expected_template_context = {'organization': 'orchard'} if user_id_key: message_body[user_id_key] = user_id_value if user_id_key and user_id_value: expected_template_context['tracking_url'] = 'TRACKING URL' message = MagicMock(body=json.dumps(message_body)) message_processing.process_message(message) template_renderer.render_template.assert_called_once_with( 'host_read_ad_assigned', expected_template_context, 'en' ) ses.send_email.assert_called_once_with({ 'html_body': 'TEMPLATE', 'sender': "'The Orchard Podcasts' ", 'subject': subject, 'text_body': '', 'to': ['jodonnell@theorchard.com'] }) if user_id_key and user_id_value: email_utils.generate_generic_tracking_url.assert_called_once_with( user_id_value, subject, ) email_utils.track_generic_email_sent.assert_called_once_with( user_id_value, subject, ) else: email_utils.generate_generic_tracking_url.assert_not_called() email_utils.track_generic_email_sent.assert_not_called() @pytest.mark.parametrize('email, expected_result', [ ('invalid email', False), (' ', False), ('valid.email@domain.com', True) ]) def test_is_valid_email(email, expected_result): """Test if email is valid.""" result = message_processing.is_valid_email(email) assert result == expected_result @pytest.mark.parametrize('users_response,notifications_calls', [ ( response.Response({'id': 'uuid', 'email': 'foo@theorchard.com'}), len(GET_STREAM_FEED_GROUPS) ), ( response.Response({}), 0 ), ( response.create_error_response('ERROR_CODE_OWS_USERS_REQUEST', 'some error'), 0 ), ]) def test_unsubscribe_email_from_all_feeds(users_response, notifications_calls, monkeypatch): """Test unsubscribe_email_from_all_feeds.""" monkeypatch.setattr(ows_users, 'get_identity_by_email', MagicMock(return_value=users_response)) monkeypatch.setattr(ows_notifications, 'user_subscription_toggle_off', MagicMock()) message_processing.unsubscribe_email_from_all_feeds('foo@theorchard.com') assert ows_users.get_identity_by_email.call_count == 1 assert ows_notifications.user_subscription_toggle_off.call_count == notifications_calls @pytest.mark.parametrize( ( 'template_name', 'company_brand', 'expected_email_subject', 'expected_template' ), [ ( 'digital_approval', 'awal', '[test] Congratulations! XYZ Product by Cool Cat Artist has been approved.', 'digital_approval', ), ( 'digital_approval', 'theorchard', '[test] XYZ Product by Cool Cat Artist has been approved', 'theorchard_digital_approval' ), ( 'digital_rejection', 'theorchard', '[test] We’ve encountered one or more issues with XYZ Product by Cool Cat Artist', 'digital_rejection' ) ]) def test_content_review_notification( template_name, company_brand, expected_email_subject, expected_template, monkeypatch ): """Test content review approval/ rejection notification.""" default_brand = 'awal' if company_brand == 'awal' else 'orchard' users_info_mock = [ { 'type': 'oa', 'user_id': 'oa:123', 'first_name': 'John', 'last_name': 'Doe', 'email': 'johndoe@theorchard.com', 'account': { 'vendor_id': 123, 'subaccount_id': None }, 'active': 'Y' } ] notification_mock = { 'user_ids': ['oa:123'], 'feed_name': 'label_release_approval', 'feed_id': 'vendor_123', 'template': template_name, 'payload': { 'product_name': 'XYZ Product', 'artist_name': 'Cool Cat Artist', 'sale_start_date': '2022-08-11', 'upc': '111221112', 'default_brand': default_brand }, 'users_info': users_info_mock } monkeypatch.setattr( message_detector, 'get_message_type', MagicMock(return_value='Notification')) monkeypatch.setattr( notification_extractor, 'parse_message', MagicMock(return_value=notification_mock)) monkeypatch.setattr( ows_users, 'get_users_info', MagicMock(return_value=response.Response(users_info_mock))) monkeypatch.setattr( email_utils, 'track_email_sent', MagicMock(return_value='TRACKING EMAIL')) monkeypatch.setattr( message_processing, 'is_valid_vendor', MagicMock(return_value=True)) monkeypatch.setattr( email_utils, 'format_notification_for_rendering', MagicMock()) monkeypatch.setattr( email_utils, 'get_preview_text', MagicMock(return_value='PREVIEW TEXT')) monkeypatch.setattr( message_processing, 'is_valid_email', MagicMock(return_value=True)) monkeypatch.setattr( template_renderer, 'render_template', MagicMock(return_value='TEMPLATE')) monkeypatch.setattr( ses, 'send_email', MagicMock()) monkeypatch.setattr( message_processing, 'logger', MagicMock(return_value='Test')) monkeypatch.setattr( email_utils, 'generate_unsubscribe_url', MagicMock(return_value='UNSUBSCRIBE URL')) monkeypatch.setattr( email_utils, 'generate_identify_url', MagicMock(return_value='IDENTIFY URL')) monkeypatch.setattr( email_utils, 'generate_tracking_url', MagicMock(return_value='TRACKING URL')) monkeypatch.setattr( ows_features, 'get_user_features', MagicMock(return_value={})) monkeypatch.setattr( ows_account, 'get_vendor_company_brand', MagicMock(return_value=response.Response(message=company_brand)) ) monkeypatch.setattr( template_renderer, 'render_template', MagicMock(return_value='TEMPLATE')) monkeypatch.setattr( ses, 'send_email', MagicMock()) message_body = { 'type': 'Notification', 'subject': 'SUBJECT', 'to': ['johndoe@theorchard.com'], 'template': 'digital_approval', 'lang': 'en', 'sender': '', 'variables': { 'organization': 'orchard', } } message = MagicMock(body=json.dumps(message_body)) message_processing.process_message(message) template_renderer.render_template.assert_called_once_with( expected_template, { 'product_name': 'XYZ Product', 'artist_name': 'Cool Cat Artist', 'upc': '111221112', 'sale_start_date': '2022-08-11', 'default_brand': default_brand, 'preview_text': 'PREVIEW TEXT', 'unsubscribe_url': 'UNSUBSCRIBE URL', 'identify_url': 'IDENTIFY URL', 'tracking_url': 'TRACKING URL' }, 'en' ) sender = '"The Orchard Notifications" ' if default_brand == 'awal': sender = '"AWAL Notifications" ' ses.send_email.assert_has_calls([ call({ 'subject': expected_email_subject, 'to': ['johndoe@theorchard.com'], 'sender': sender, 'html_body': 'TEMPLATE', 'text_body': '' }), call({ 'subject': expected_email_subject, 'to': ['cr_testing@sonymusic-pde.com'], 'sender': sender, 'html_body': 'TEMPLATE', 'text_body': '' }) ])