def test_user_with_no_program_access(self): """ Test that a user with no program permissions will raise an exception """ with mute_signals(post_save): profile = ProfileFactory.create() with self.assertRaises(NoProgramAccessException): create_search_obj(profile.user)
def test_create_search_obj_filter(self, is_advance_search_capable): """ Test that Search objects are created with program-limiting and filled_out=True query parameters """ user = self.user if is_advance_search_capable else self.learner search_obj = create_search_obj(user) search_query_dict = search_obj.to_dict() expected_program_query = Q( 'bool', should=[Q('term', **{'program.id': self.program.id})], minimum_should_match=1, must=[Q('term', **{'program.is_learner': True})]) expected_filled_out_query = Q('term', **{'profile.filled_out': True}) expected_privacy_query = ~Q( # pylint: disable=invalid-unary-operand-type 'term', **{'profile.account_privacy': 'private'}) assert 'query' in search_query_dict assert 'bool' in search_query_dict['query'] assert 'filter' in search_query_dict['query']['bool'] assert len(search_query_dict['query']['bool'] ['filter']) == 2 if is_advance_search_capable else 3 expected_filters = [ expected_program_query.to_dict(), expected_filled_out_query.to_dict(), ] if not is_advance_search_capable: expected_filters.insert(0, expected_privacy_query.to_dict()) assert search_query_dict['query']['bool']['filter'] == expected_filters
def create(self, validated_data): user = self.context['request'].user search_obj = create_search_obj( user, search_param_dict=validated_data['query'] ) title = validated_data['title'] name = validated_data['name'] description = validated_data['description'] channel_type = validated_data['channel_type'] program_id = validated_data['program_id'] channel = add_channel( original_search=search_obj, title=title, name=name, description=description, channel_type=channel_type, program_id=program_id, creator_id=user.id, ) return { "title": title, "name": name, "query": channel.query.query, "description": description, "channel_type": channel_type, "program_id": program_id, }
def test_send_view(self): """ Test that the SearchResultMailView will accept and return expected values """ with patch( 'mail.views.get_all_query_matching_emails', autospec=True, return_value=self.email_results) as mock_get_emails, patch( 'mail.views.MailgunClient') as mock_mailgun_client, patch( 'mail.views.get_mail_vars', autospec=True, return_value=self.email_vars, ) as mock_get_mail_vars: mock_mailgun_client.send_batch.return_value = [Response()] resp_post = self.client.post(self.search_result_mail_url, data=self.request_data, format='json') assert resp_post.status_code == status.HTTP_200_OK assert resp_post.data == {} assert mock_get_emails.called assert mock_get_emails.call_args[0][0].to_dict() == create_search_obj( user=self.staff, search_param_dict=self.request_data['search_request'], filter_on_email_optin=True, ).to_dict() assert mock_mailgun_client.send_batch.called _, called_kwargs = mock_mailgun_client.send_batch.call_args assert called_kwargs['subject'] == self.request_data['email_subject'] self.assertIn(self.request_data['email_body'], called_kwargs['body']) self.assertIn('edit your settings', called_kwargs['body']) assert list(called_kwargs['recipients']) == self.recipient_tuples mock_get_mail_vars.assert_called_once_with(self.email_results)
def test_send_view(self): """ Test that the SearchResultMailView will accept and return expected values """ with patch( 'mail.views.get_all_query_matching_emails', autospec=True, return_value=self.email_results ) as mock_get_emails, patch( 'mail.views.MailgunClient' ) as mock_mailgun_client, patch( 'mail.views.get_mail_vars', autospec=True, return_value=self.email_vars, ) as mock_get_mail_vars: mock_mailgun_client.send_batch.return_value = [Response()] resp_post = self.client.post(self.search_result_mail_url, data=self.request_data, format='json') assert resp_post.status_code == status.HTTP_200_OK assert resp_post.data == {} assert mock_get_emails.called assert mock_get_emails.call_args[0][0].to_dict() == create_search_obj( user=self.staff, search_param_dict=self.request_data['search_request'], filter_on_email_optin=True, ).to_dict() assert mock_mailgun_client.send_batch.called _, called_kwargs = mock_mailgun_client.send_batch.call_args assert called_kwargs['subject'] == self.request_data['email_subject'] self.assertIn(self.request_data['email_body'], called_kwargs['body']) self.assertIn('edit your settings', called_kwargs['body']) assert list(called_kwargs['recipients']) == self.recipient_tuples mock_get_mail_vars.assert_called_once_with(self.email_results)
def test_create_search_obj_filter(self, is_advance_search_capable): """ Test that Search objects are created with program-limiting and filled_out=True query parameters """ user = self.user if is_advance_search_capable else self.learner search_obj = create_search_obj(user) search_query_dict = search_obj.to_dict() expected_program_query = Q( 'bool', should=[ Q('term', **{'program.id': self.program.id}) ], minimum_should_match=1, must=[ Q('term', **{'program.is_learner': True}) ] ) expected_filled_out_query = Q('term', **{'profile.filled_out': True}) expected_privacy_query = ~Q( # pylint: disable=invalid-unary-operand-type 'term', **{'profile.account_privacy': 'private'} ) assert 'query' in search_query_dict assert 'bool' in search_query_dict['query'] assert 'filter' in search_query_dict['query']['bool'] assert len(search_query_dict['query']['bool']['filter']) == 2 if is_advance_search_capable else 3 expected_filters = [ expected_program_query.to_dict(), expected_filled_out_query.to_dict(), ] if not is_advance_search_capable: expected_filters.insert(0, expected_privacy_query.to_dict()) assert search_query_dict['query']['bool']['filter'] == expected_filters
def create(self, validated_data): user = self.context['request'].user search_obj = create_search_obj( user, search_param_dict=validated_data['query']) title = validated_data['title'] name = validated_data['name'] description = validated_data['description'] channel_type = validated_data['channel_type'] program_id = validated_data['program_id'] channel = add_channel( original_search=search_obj, title=title, name=name, description=description, channel_type=channel_type, program_id=program_id, creator_id=user.id, ) return { "title": title, "name": name, "query": channel.query.query, "description": description, "channel_type": channel_type, "program_id": program_id, }
def test_size_param_in_query(self): """ Assert value of size attribute of search object is set to default settings. """ search_obj = create_search_obj(self.user) search_query_dict = search_obj.to_dict() assert 'size' in search_query_dict assert search_query_dict['size'] == 5
def test_all_query_matching_emails(self): """ Test that a set of search results will yield an expected set of emails """ search = create_search_obj(self.user) user_ids = self.program.programenrollment_set.values_list( "user__email", flat=True).exclude( user__email=self.user.email).order_by("-user__id") results = get_all_query_matching_emails(search) assert results == set(user_ids)
def test_search_for_field(self): """ Test that a set of search results will yield an expected set of values """ search = create_search_obj(self.user) user_ids = self.program.programenrollment_set.values_list( "user__id", flat=True).exclude(user__id=self.user.id).order_by("-user__id") results = search_for_field(search, 'user_id') assert results == set(user_ids)
def post(self, request, *args, **kargs): # pylint: disable=unused-argument """ POST method handler """ email_subject = request.data['email_subject'] email_body = request.data['email_body'] + get_email_footer( request.build_absolute_uri('/settings')) sender_name = full_name(request.user) search_obj = create_search_obj( request.user, search_param_dict=request.data.get('search_request'), filter_on_email_optin=True) emails = get_all_query_matching_emails(search_obj) if request.data.get('send_automatic_emails'): automatic_email = add_automatic_email( search_obj, email_subject=request.data['email_subject'], email_body=email_body, sender_name=sender_name, staff_user=request.user, ) try: with mark_emails_as_sent(automatic_email, emails) as user_ids: # user_ids should be all users with the matching email in emails # except some who were already sent email in the meantime recipient_emails = list( User.objects.filter(id__in=user_ids).values_list( 'email', flat=True)) MailgunClient.send_batch( subject=email_subject, body=email_body, recipients=( (context['email'], context) for context in get_mail_vars(recipient_emails)), sender_name=sender_name, ) except SendBatchException as send_batch_exception: success_emails = set(emails).difference( send_batch_exception.failed_recipient_emails) with mark_emails_as_sent(automatic_email, success_emails): pass raise else: MailgunClient.send_batch( subject=email_subject, body=email_body, recipients=((context['email'], context) for context in get_mail_vars(emails)), sender_name=sender_name, ) return Response(status=status.HTTP_200_OK, data={})
def test_all_query_matching_emails(self): """ Test that a set of search results will yield an expected set of emails """ search = create_search_obj(self.user) user_ids = self.program.programenrollment_set.values_list( "user__email", flat=True ).exclude( user__email=self.user.email ).order_by("-user__id") results = get_all_query_matching_emails(search) assert results == set(user_ids)
def test_search_for_field(self): """ Test that a set of search results will yield an expected set of values """ search = create_search_obj(self.user) user_ids = self.program.programenrollment_set.values_list( "user__id", flat=True ).exclude( user__id=self.user.id ).order_by("-user__id") results = search_for_field(search, 'user_id') assert results == set(user_ids)
def setUp(self): super().setUp() self.request_data = self.request_data.copy() self.request_data['send_automatic_emails'] = True for email in self.email_results: UserFactory.create(email=email) self.automatic_email = AutomaticEmailFactory.create() self.search_obj = create_search_obj( user=self.staff, search_param_dict=self.request_data['search_request'], filter_on_email_optin=True, )
def post(self, request, *args, **kargs): # pylint: disable=unused-argument """ POST method handler """ email_subject = request.data['email_subject'] email_body = request.data['email_body'] + get_email_footer(request.build_absolute_uri('/settings')) sender_name = full_name(request.user) search_obj = create_search_obj( request.user, search_param_dict=request.data.get('search_request'), filter_on_email_optin=True ) emails = get_all_query_matching_emails(search_obj) if request.data.get('send_automatic_emails'): automatic_email = add_automatic_email( search_obj, email_subject=request.data['email_subject'], email_body=email_body, sender_name=sender_name, staff_user=request.user, ) try: with mark_emails_as_sent(automatic_email, emails) as user_ids: # user_ids should be all users with the matching email in emails # except some who were already sent email in the meantime recipient_emails = list(User.objects.filter(id__in=user_ids).values_list('email', flat=True)) MailgunClient.send_batch( subject=email_subject, body=email_body, recipients=((context['email'], context) for context in get_mail_vars(recipient_emails)), sender_name=sender_name, ) except SendBatchException as send_batch_exception: success_emails = set(emails).difference(send_batch_exception.failed_recipient_emails) with mark_emails_as_sent(automatic_email, success_emails): pass raise else: MailgunClient.send_batch( subject=email_subject, body=email_body, recipients=((context['email'], context) for context in get_mail_vars(emails)), sender_name=sender_name, ) return Response(status=status.HTTP_200_OK, data={})
def test_create_search_obj_metadata(self, is_advance_search_capable, expected_index_type): """ Test that Search objects are created with proper metadata """ user = self.user if is_advance_search_capable else self.learner search_param_dict = {'size': 50} with patch('search.api.Search.update_from_dict', autospec=True) as mock_update_from_dict: search_obj = create_search_obj( user, search_param_dict=search_param_dict, ) expected_alias = get_default_alias(expected_index_type) assert search_obj._index == [expected_alias] # pylint: disable=protected-access assert mock_update_from_dict.call_count == 2 assert isinstance(mock_update_from_dict.call_args[0][0], Search) assert mock_update_from_dict.call_args[0][1] == search_param_dict