예제 #1
0
 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)
예제 #2
0
 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)
예제 #3
0
 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
예제 #4
0
    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,
        }
예제 #5
0
    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)
예제 #6
0
    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)
예제 #7
0
 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
예제 #8
0
    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,
        }
예제 #9
0
 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
예제 #10
0
 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
예제 #11
0
 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)
예제 #12
0
 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)
예제 #13
0
    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={})
예제 #14
0
 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)
예제 #15
0
 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)
예제 #16
0
    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,
        )
예제 #17
0
    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,
        )
예제 #18
0
    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={})
예제 #19
0
 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
예제 #20
0
 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