コード例 #1
0
 def test_bulk_sms_send_multiproc(self):
     # close database connections manually to make sure they're not passed
     # to subprocesses
     for conn in django_db_connections.all():
         conn.close()
     # send the messages in parallel using 10 processes. use
     # multiprocessing rather than threads so we don't have to clean
     # up database connections that the threads might leave open.
     cache.close()
     pool = multiprocessing.Pool(10)
     try:
         for i in range(30):
             BulkMessageFactory(batch=self.batch, sms=None)
         for j in range(10):
             BulkMessageFactory(batch=self.batch, sms=None, deleted=True)
         # 40 is the first multiple of 10 greater than or equal to 31
         num_sent = send_messages(self.batch, num_to_send=40, map_=pool.map)
         batch = Batch.objects.get(pk=self.batch.pk)
         self.assertEqual(batch.errors, 0)
         self.assertEqual(batch.status, Batch.COMPLETED)
         # assert that we report the right number sent too
         self.assertEqual(num_sent, 30)
         self.assertEqual(len(self.outbound), 30)
     finally:
         pool.terminate()
         pool.join()
コード例 #2
0
ファイル: test_models.py プロジェクト: pysoft-net/SmartElect
 def test_unsent(self):
     msg1 = BulkMessageFactory(phone_number=u'555-1212', sms=None)
     BulkMessageFactory(phone_number=u'555-1212', sms=None)
     # ensure the manager method works
     self.assertEqual(BulkMessage.objects.unsent().count(), 2)
     # ensure the queryset method works on a filtered queryset
     self.assertEqual(
         BulkMessage.objects.filter(batch=msg1.batch).unsent().count(), 1)
コード例 #3
0
ファイル: test_models.py プロジェクト: pysoft-net/SmartElect
 def test_time_remaining(self):
     batch = BatchFactory(status=Batch.PENDING)
     [
         BulkMessageFactory(deleted=True, batch=batch, sms=None)
         for i in range(5)
     ]
     msgs = [BulkMessageFactory(batch=batch, sms=None) for i in range(10)]
     self.assertEqual(batch.time_remaining(),
                      datetime.timedelta(seconds=len(msgs) / 2))
コード例 #4
0
ファイル: test_models.py プロジェクト: pysoft-net/SmartElect
 def test_active(self):
     msg1 = BulkMessageFactory(phone_number=u'555-1212', deleted=True)
     msg2 = BulkMessageFactory(phone_number=u'555-1212', batch=msg1.batch)
     BulkMessageFactory(phone_number=u'555-1212')
     # ensure the manager method works
     self.assertEqual(BulkMessage.objects.active().count(), 2)
     # ensure the queryset method works on a filtered queryset
     self.assertEqual(
         BulkMessage.objects.filter(batch=msg2.batch).active().count(), 1)
コード例 #5
0
 def setUp(self):
     # create an approved Batch
     self.batch = BatchFactory(status=Batch.APPROVED)
     # add message to batch
     self.bulk_msg = BulkMessageFactory(
         batch=self.batch,
         phone_number=get_random_number_string(),
         message=u'.نآسف، مرحلة التسجيل عن طريق الرسائل النصية ليست متاحة',
         sms=None)
コード例 #6
0
 def test_bulk_sms_send_one_proc(self):
     for i in range(30):
         BulkMessageFactory(batch=self.batch, sms=None)
     for j in range(10):
         BulkMessageFactory(batch=self.batch, sms=None, deleted=True)
     num_sent = send_messages(self.batch)
     # 31 messages sent (30 + 1 from setUp)
     self.assertEqual(len(self.outbound), 31)
     # assert that we report the right number sent too
     self.assertEqual(num_sent, 31)
コード例 #7
0
 def test_sent_messages_dont_get_resent(self):
     for i in range(20):
         BulkMessageFactory(batch=self.batch, sms=None)
     for i in range(10):
         sms = SMSFactory()
         BulkMessageFactory(batch=self.batch, sms=sms)
         BulkMessageFactory(batch=self.batch,
                            sms=SMSFactory(),
                            deleted=True)
     send_messages(self.batch)
     # only 21 messages get sent out (20 + 1 from setUp)
     self.assertEqual(len(self.outbound), 21)
コード例 #8
0
 def test_once_all_are_sent_next_send_completes_batch(self):
     for i in range(20):
         BulkMessageFactory(batch=self.batch, sms=None)
     BulkMessageFactory(batch=self.batch, sms=None, deleted=True)
     # send out all the messages (21)
     send_messages(self.batch)
     self.assertEqual(len(self.outbound), 21)
     # send again
     BulkMessageFactory(batch=self.batch, sms=None, deleted=True)
     send_messages(self.batch)
     # now batch should be completed
     batch = Batch.objects.get(pk=self.batch.pk)
     self.assertEqual(batch.status, Batch.COMPLETED)
コード例 #9
0
ファイル: test_models.py プロジェクト: pysoft-net/SmartElect
 def test_time_remaining_one_message(self):
     # if there are any messages at all, should still return a True value for the template
     batch = BatchFactory(status=Batch.PENDING)
     BulkMessageFactory(batch=batch, sms=None)
     # using assertTrue because the key is that we want the return value to be boolean True
     # for the template to NOT display the 'Finished' default
     self.assertTrue(batch.time_remaining())
コード例 #10
0
    def test_send_is_threadsafe(self):
        """
        Ensure send_message_by_id does not accidentally send more than one
        SMS to the same user if it happens to be running more than once with the
        same ID.
        """
        trigger = threading.Event()

        def target(pk):
            # wait until all threads have started before attempting to send
            trigger.wait()
            send_message_by_id(pk)
            # workaround https://code.djangoproject.com/ticket/22420
            for conn in django_db_connections.all():
                conn.close()

        m = BulkMessageFactory(batch=self.batch, sms=None)
        threads = [
            threading.Thread(target=target, args=(m.pk, )) for i in range(10)
        ]
        for t in threads:
            t.start()
        # wake up all threads at the same time
        trigger.set()
        for t in threads:
            t.join()
        # only 1 message should be sent out in total
        self.assertEqual(len(self.outbound), 1)
コード例 #11
0
ファイル: test_sending.py プロジェクト: chaabni/SmartElect
 def setUp(self):
     # create an approved Batch
     self.batch = BatchFactory(status=Batch.APPROVED)
     # add message to batch
     self.bulk_msg = BulkMessageFactory(
         batch=self.batch,
         phone_number=get_random_number_string(),
         message=u'.نآسف، مرحلة التسجيل عن طريق الرسائل النصية ليست متاحة',
         sms=None
     )
コード例 #12
0
 def test_management_cmd(self):
     # Make sure the bulk sending management command works (for a single batch, at least).
     for i in range(50):
         BulkMessageFactory(batch=self.batch, sms=None)
     call_command('send_bulk_messages',
                  concurrent_workers=10,
                  msgs_per_sec=50,
                  send_forever=False)
     batch = Batch.objects.get(pk=self.batch.pk)
     self.assertEqual(batch.errors, 0)
     self.assertEqual(batch.status, Batch.COMPLETED)
     self.assertEqual(len(self.outbound), 50)
コード例 #13
0
ファイル: test_models.py プロジェクト: pysoft-net/SmartElect
 def test_get_random_messages_from_batch(self):
     batch = BatchFactory(status=Batch.PENDING)
     BatchFactory(status=Batch.PENDING, deleted=True)
     msgs = [BulkMessageFactory(batch=batch, sms=None) for i in range(10)]
     # the random message is one of our messages
     first_random_msg = batch.random_n_messages(n=1)[0]
     self.assertIn(first_random_msg, msgs)
     # get random message up to 10 times: shouldn't all be the same
     for i in range(10):
         next_random_msg = batch.random_n_messages(n=1)[0]
         if first_random_msg != next_random_msg:
             break
     self.assertNotEqual(first_random_msg, next_random_msg)
     # if we ask for more than exist, we only get the number that actually exist
     self.assertTrue(len(batch.random_n_messages(n=20)), 10)
コード例 #14
0
 def test_dont_get_deleted_bulkmessage_by_default(self):
     bulkmessage = BulkMessageFactory(deleted=True)
     self.assertNotIn(bulkmessage, BulkMessage.objects.all())
コード例 #15
0
ファイル: test_sending.py プロジェクト: chaabni/SmartElect
class SendingTest(LowLevelRouterMixin, TestCase):
    def setUp(self):
        # create an approved Batch
        self.batch = BatchFactory(status=Batch.APPROVED)
        # add message to batch
        self.bulk_msg = BulkMessageFactory(
            batch=self.batch,
            phone_number=get_random_number_string(),
            message=u'.نآسف، مرحلة التسجيل عن طريق الرسائل النصية ليست متاحة',
            sms=None
        )

    def test_send_one_bulk_message(self):
        # send message
        send_message_by_id(self.bulk_msg.pk)
        # -> sms is no longer 'None'
        sms = BulkMessage.objects.get(id=self.bulk_msg.id).sms
        self.assertTrue(sms)
        # -> from_number is REGISTRATION_SHORT_CODE (default)
        self.assertEqual(sms.from_number, settings.REGISTRATION_SHORT_CODE)
        # -> to_number is the phone number from the BulkMessage
        self.assertEqual(sms.to_number, self.bulk_msg.phone_number)
        # -> message is the message from the BulkMessage
        self.assertEqual(sms.message, self.bulk_msg.message)
        self.assertEqual(len(self.outbound), 1)

    @patch.object(LowLevelTestRouter, 'send_to_backend')
    def test_endpoint_is_passed_to_backend(self, mock_send_to_backend):
        # mock sending the message to check what params we send to the backend
        send_message_by_id(self.bulk_msg.pk)
        self.assertTrue(mock_send_to_backend.called)
        call_args, call_kwargs = mock_send_to_backend.call_args
        # by default, we should send endpoint=REGISTRATION_SHORT_CODE
        self.assertEqual(call_kwargs['context'], {'endpoint': settings.REGISTRATION_SHORT_CODE})

    def test_endpoint_passed_to_backend_is_customizable(self):
        self.bulk_msg.from_shortcode = settings.REPORTS_SHORT_CODE
        self.bulk_msg.save()
        # send message
        with patch.object(LowLevelTestRouter, 'send_to_backend') as mock_send_to_backend:
            send_message_by_id(self.bulk_msg.pk)
        self.assertTrue(mock_send_to_backend.called)
        call_args, call_kwargs = mock_send_to_backend.call_args
        self.assertEqual(call_kwargs['context'], {'endpoint': settings.REPORTS_SHORT_CODE})

    def test_endpoint_gets_saved_to_sms_object(self):
        self.bulk_msg.from_shortcode = settings.REPORTS_SHORT_CODE
        self.bulk_msg.save()
        # send message
        send_message_by_id(self.bulk_msg.pk)
        sms = BulkMessage.objects.get(id=self.bulk_msg.id).sms
        self.assertEqual(sms.from_number, settings.REPORTS_SHORT_CODE)

    def test_dont_send_msg_if_sms_field_set(self):
        # set the sms field
        self.bulk_msg.sms = SMSFactory()
        self.bulk_msg.save()
        send_message_by_id(self.bulk_msg.pk)
        # no message sent
        self.assertEqual(len(self.outbound), 0)

    def test_dont_send_msg_if_batch_inactive(self):
        self.batch.status = Batch.PENDING
        self.batch.save()
        send_message_by_id(self.bulk_msg.pk)
        # no message sent
        self.assertEqual(len(self.outbound), 0)

    def test_bulk_sms_send_one_proc(self):
        for i in range(30):
            BulkMessageFactory(batch=self.batch, sms=None)
        for j in range(10):
            BulkMessageFactory(batch=self.batch, sms=None, deleted=True)
        num_sent = send_messages(self.batch)
        # 31 messages sent (30 + 1 from setUp)
        self.assertEqual(len(self.outbound), 31)
        # assert that we report the right number sent too
        self.assertEqual(num_sent, 31)

    def test_sent_messages_dont_get_resent(self):
        for i in range(20):
            BulkMessageFactory(batch=self.batch, sms=None)
        for i in range(10):
            sms = SMSFactory()
            BulkMessageFactory(batch=self.batch, sms=sms)
            BulkMessageFactory(batch=self.batch, sms=SMSFactory(), deleted=True)
        send_messages(self.batch)
        # only 21 messages get sent out (20 + 1 from setUp)
        self.assertEqual(len(self.outbound), 21)

    def test_send_finite_number_each_time(self):
        for i in range(20):
            BulkMessageFactory(batch=self.batch, sms=None)
        send_messages(self.batch, num_to_send=10)
        # only 10 messages should be sent out each call
        self.assertEqual(len(self.outbound), 10)

    def test_once_all_are_sent_next_send_completes_batch(self):
        for i in range(20):
            BulkMessageFactory(batch=self.batch, sms=None)
        BulkMessageFactory(batch=self.batch, sms=None, deleted=True)
        # send out all the messages (21)
        send_messages(self.batch)
        self.assertEqual(len(self.outbound), 21)
        # send again
        BulkMessageFactory(batch=self.batch, sms=None, deleted=True)
        send_messages(self.batch)
        # now batch should be completed
        batch = Batch.objects.get(pk=self.batch.pk)
        self.assertEqual(batch.status, Batch.COMPLETED)

    def test_dont_send_batch_if_batch_inactive(self):
        self.batch.status = Batch.PENDING
        self.batch.save()
        send_messages(self.batch)
        # no message sent
        self.assertEqual(len(self.outbound), 0)

    @patch('bulk_sms.sending.get_router', autospec=True)
    def test_if_message_fails_error_incremented(self, mock_get_router):
        self.assertEqual(self.batch.errors, 0)
        # send the message, mocking an exception
        mock_get_router.return_value.send_to_backend.side_effect = MessageSendingError
        send_messages(self.batch)
        batch = Batch.objects.get(pk=self.batch.pk)
        self.assertEqual(batch.errors, 1)
        self.assertFalse(self.bulk_msg.sms)

    def test_send_to_invalid_id(self):
        """
        Ensure sending to an invalid ID returns gracefully
        """
        self.assertEqual(send_message_by_id(9999999), 0)

    @patch.object(LowLevelTestRouter, 'send_to_backend')
    def test_send_to_existing_connection(self, send_to_backend):
        """
        Ensure bulk messages to phone numbers with existing connections use that
        connection. This helps ensure (but does not guarantee) that messages to
        Thuraya phones won't be sent over Madar or Libyana.
        """
        # use a backend that's available in the test environment but not
        # in BULKSMS_BACKENDS
        conn = ConnectionFactory(identity=self.bulk_msg.phone_number,
                                 backend__name=settings.HTTPTESTER_BACKEND)
        old_count = Connection.objects.all().count()
        # send message
        send_message_by_id(self.bulk_msg.pk)
        # make sure send_to_backend was called with the correct backend name and
        # identity
        self.assertEqual(send_to_backend.call_count, 1)
        self.assertEqual(send_to_backend.call_args[1]['backend_name'], conn.backend.name)
        self.assertEqual(send_to_backend.call_args[1]['identities'], [conn.identity])
        # make sure no new connection object was created:
        new_count = Connection.objects.all().count()
        self.assertEqual(old_count, new_count)
コード例 #16
0
ファイル: test_models.py プロジェクト: chaabni/SmartElect
 def test_from_shortcode_validation(self):
     msg = BulkMessageFactory()
     msg.from_shortcode = get_random_number_string(length=5)
     with self.assertRaisesRegexp(ValidationError, 'Invalid shortcode'):
         msg.full_clean()
コード例 #17
0
ファイル: test_models.py プロジェクト: pysoft-net/SmartElect
 def test_from_shortcode_default(self):
     msg = BulkMessageFactory()
     self.assertEqual(msg.from_shortcode, settings.REGISTRATION_SHORT_CODE)
コード例 #18
0
ファイル: test_models.py プロジェクト: pysoft-net/SmartElect
 def test_from_shortcode_validation(self):
     msg = BulkMessageFactory()
     msg.from_shortcode = get_random_number_string(length=5)
     with self.assertRaisesRegexp(ValidationError, 'Invalid shortcode'):
         msg.full_clean()
コード例 #19
0
 def test_send_finite_number_each_time(self):
     for i in range(20):
         BulkMessageFactory(batch=self.batch, sms=None)
     send_messages(self.batch, num_to_send=10)
     # only 10 messages should be sent out each call
     self.assertEqual(len(self.outbound), 10)
コード例 #20
0
ファイル: test_models.py プロジェクト: pysoft-net/SmartElect
 def test_unicode_method(self):
     msg = BulkMessageFactory(phone_number=u'555-1212')
     self.assertIn('555-1212', str(msg))
コード例 #21
0
class SendingTest(LowLevelRouterMixin, TestCase):
    def setUp(self):
        # create an approved Batch
        self.batch = BatchFactory(status=Batch.APPROVED)
        # add message to batch
        self.bulk_msg = BulkMessageFactory(
            batch=self.batch,
            phone_number=get_random_number_string(),
            message=u'.نآسف، مرحلة التسجيل عن طريق الرسائل النصية ليست متاحة',
            sms=None)

    def test_send_one_bulk_message(self):
        # send message
        send_message_by_id(self.bulk_msg.pk)
        # -> sms is no longer 'None'
        sms = BulkMessage.objects.get(id=self.bulk_msg.id).sms
        self.assertTrue(sms)
        # -> from_number is REGISTRATION_SHORT_CODE (default)
        self.assertEqual(sms.from_number, settings.REGISTRATION_SHORT_CODE)
        # -> to_number is the phone number from the BulkMessage
        self.assertEqual(sms.to_number, self.bulk_msg.phone_number)
        # -> message is the message from the BulkMessage
        self.assertEqual(sms.message, self.bulk_msg.message)
        self.assertEqual(len(self.outbound), 1)

    @patch.object(LowLevelTestRouter, 'send_to_backend')
    def test_endpoint_is_passed_to_backend(self, mock_send_to_backend):
        # mock sending the message to check what params we send to the backend
        send_message_by_id(self.bulk_msg.pk)
        self.assertTrue(mock_send_to_backend.called)
        call_args, call_kwargs = mock_send_to_backend.call_args
        # by default, we should send endpoint=REGISTRATION_SHORT_CODE
        self.assertEqual(call_kwargs['context'],
                         {'endpoint': settings.REGISTRATION_SHORT_CODE})

    def test_endpoint_passed_to_backend_is_customizable(self):
        self.bulk_msg.from_shortcode = settings.REPORTS_SHORT_CODE
        self.bulk_msg.save()
        # send message
        with patch.object(LowLevelTestRouter,
                          'send_to_backend') as mock_send_to_backend:
            send_message_by_id(self.bulk_msg.pk)
        self.assertTrue(mock_send_to_backend.called)
        call_args, call_kwargs = mock_send_to_backend.call_args
        self.assertEqual(call_kwargs['context'],
                         {'endpoint': settings.REPORTS_SHORT_CODE})

    def test_endpoint_gets_saved_to_sms_object(self):
        self.bulk_msg.from_shortcode = settings.REPORTS_SHORT_CODE
        self.bulk_msg.save()
        # send message
        send_message_by_id(self.bulk_msg.pk)
        sms = BulkMessage.objects.get(id=self.bulk_msg.id).sms
        self.assertEqual(sms.from_number, settings.REPORTS_SHORT_CODE)

    def test_dont_send_msg_if_sms_field_set(self):
        # set the sms field
        self.bulk_msg.sms = SMSFactory()
        self.bulk_msg.save()
        send_message_by_id(self.bulk_msg.pk)
        # no message sent
        self.assertEqual(len(self.outbound), 0)

    def test_dont_send_msg_if_batch_inactive(self):
        self.batch.status = Batch.PENDING
        self.batch.save()
        send_message_by_id(self.bulk_msg.pk)
        # no message sent
        self.assertEqual(len(self.outbound), 0)

    def test_bulk_sms_send_one_proc(self):
        for i in range(30):
            BulkMessageFactory(batch=self.batch, sms=None)
        for j in range(10):
            BulkMessageFactory(batch=self.batch, sms=None, deleted=True)
        num_sent = send_messages(self.batch)
        # 31 messages sent (30 + 1 from setUp)
        self.assertEqual(len(self.outbound), 31)
        # assert that we report the right number sent too
        self.assertEqual(num_sent, 31)

    def test_sent_messages_dont_get_resent(self):
        for i in range(20):
            BulkMessageFactory(batch=self.batch, sms=None)
        for i in range(10):
            sms = SMSFactory()
            BulkMessageFactory(batch=self.batch, sms=sms)
            BulkMessageFactory(batch=self.batch,
                               sms=SMSFactory(),
                               deleted=True)
        send_messages(self.batch)
        # only 21 messages get sent out (20 + 1 from setUp)
        self.assertEqual(len(self.outbound), 21)

    def test_send_finite_number_each_time(self):
        for i in range(20):
            BulkMessageFactory(batch=self.batch, sms=None)
        send_messages(self.batch, num_to_send=10)
        # only 10 messages should be sent out each call
        self.assertEqual(len(self.outbound), 10)

    def test_once_all_are_sent_next_send_completes_batch(self):
        for i in range(20):
            BulkMessageFactory(batch=self.batch, sms=None)
        BulkMessageFactory(batch=self.batch, sms=None, deleted=True)
        # send out all the messages (21)
        send_messages(self.batch)
        self.assertEqual(len(self.outbound), 21)
        # send again
        BulkMessageFactory(batch=self.batch, sms=None, deleted=True)
        send_messages(self.batch)
        # now batch should be completed
        batch = Batch.objects.get(pk=self.batch.pk)
        self.assertEqual(batch.status, Batch.COMPLETED)

    def test_dont_send_batch_if_batch_inactive(self):
        self.batch.status = Batch.PENDING
        self.batch.save()
        send_messages(self.batch)
        # no message sent
        self.assertEqual(len(self.outbound), 0)

    @patch('bulk_sms.sending.get_router', autospec=True)
    def test_if_message_fails_error_incremented(self, mock_get_router):
        self.assertEqual(self.batch.errors, 0)
        # send the message, mocking an exception
        mock_get_router.return_value.send_to_backend.side_effect = MessageSendingError
        send_messages(self.batch)
        batch = Batch.objects.get(pk=self.batch.pk)
        self.assertEqual(batch.errors, 1)
        self.assertFalse(self.bulk_msg.sms)

    def test_send_to_invalid_id(self):
        """
        Ensure sending to an invalid ID returns gracefully
        """
        self.assertEqual(send_message_by_id(9999999), 0)

    @patch.object(LowLevelTestRouter, 'send_to_backend')
    def test_send_to_existing_connection(self, send_to_backend):
        """
        Ensure bulk messages to phone numbers with existing connections use that
        connection. This helps ensure (but does not guarantee) that messages to
        Thuraya phones won't be sent over Madar or Libyana.
        """
        # use a backend that's available in the test environment but not
        # in BULKSMS_BACKENDS
        conn = ConnectionFactory(identity=self.bulk_msg.phone_number,
                                 backend__name=settings.HTTPTESTER_BACKEND)
        old_count = Connection.objects.all().count()
        # send message
        send_message_by_id(self.bulk_msg.pk)
        # make sure send_to_backend was called with the correct backend name and
        # identity
        self.assertEqual(send_to_backend.call_count, 1)
        self.assertEqual(send_to_backend.call_args[1]['backend_name'],
                         conn.backend.name)
        self.assertEqual(send_to_backend.call_args[1]['identities'],
                         [conn.identity])
        # make sure no new connection object was created:
        new_count = Connection.objects.all().count()
        self.assertEqual(old_count, new_count)