示例#1
0
    def test_jsonex(self):
        """ Test de/coding messages """
        ### OutgoingMessage
        om_in = OutgoingMessage('+123', 'Test', '+987', 'fwd')
        om_in.options(allow_reply=True)
        # Encode, Decode
        j = jsonex_dumps(om_in)
        om_out = jsonex_loads(j)
        """ :type om_out: OutgoingMessage """
        # Check
        self.assertEqual(om_out.dst, '123')
        self.assertEqual(om_out.src, om_in.src)
        self.assertEqual(om_out.body, om_in.body)
        self.assertEqual(om_out.provider, om_in.provider)
        self.assertEqual(om_out.meta, None)
        self.assertEqual(om_out.provider_options.allow_reply, om_in.provider_options.allow_reply)
        self.assertEqual(om_out.provider_params, {})

        ### IncomingMessage
        im_in = IncomingMessage('+123', 'Test', 'abc123def', '+987', datetime(2019,1,1,15,0,0,875), {'a':1})
        # Encode, Decode
        j = jsonex_dumps(im_in)
        im_out = jsonex_loads(j)
        """ :type im_out: IncomingMessage """
        # Check
        self.assertEqual(im_out.src, im_in.src)
        self.assertEqual(im_out.body, im_in.body)
        self.assertEqual(im_out.msgid, im_in.msgid)
        self.assertEqual(im_out.dst, im_in.dst)
        self.assertEqual(im_out.rtime, im_in.rtime)
        self.assertEqual(im_out.meta, im_in.meta)
示例#2
0
    def test_jsonex(self):
        """ Test de/coding messages """
        ### OutgoingMessage
        om_in = OutgoingMessage('+123', 'Test', '+987', 'fwd')
        om_in.options(allow_reply=True)
        # Encode, Decode
        j = jsonex_dumps(om_in)
        om_out = jsonex_loads(j)
        """ :type om_out: OutgoingMessage """
        # Check
        self.assertEqual(om_out.dst, '123')
        self.assertEqual(om_out.src, om_in.src)
        self.assertEqual(om_out.body, om_in.body)
        self.assertEqual(om_out.provider, om_in.provider)
        self.assertEqual(om_out.meta, None)
        self.assertEqual(om_out.provider_options.allow_reply,
                         om_in.provider_options.allow_reply)
        self.assertEqual(om_out.provider_params, {})

        ### IncomingMessage
        im_in = IncomingMessage('+123', 'Test', 'abc123def', '+987',
                                datetime(2019, 1, 1, 15, 0, 0, 875), {'a': 1})
        # Encode, Decode
        j = jsonex_dumps(im_in)
        im_out = jsonex_loads(j)
        """ :type im_out: IncomingMessage """
        # Check
        self.assertEqual(im_out.src, im_in.src)
        self.assertEqual(im_out.body, im_in.body)
        self.assertEqual(im_out.msgid, im_in.msgid)
        self.assertEqual(im_out.dst, im_in.dst)
        self.assertEqual(im_out.rtime, im_in.rtime)
        self.assertEqual(im_out.meta, im_in.meta)
示例#3
0
    def test_senderId(self):
        gw = self.gw

        self._mock_response(200)  # OK
        message = OutgoingMessage('+123456', 'hey', provider='main')
        message.options(senderId='Fake sender')
        gw.send(message)
        request = self.requests.pop()
        self.assertEqual('Fake sender', request['SND'])
示例#4
0
    def test_send(self):
        """ Test message send """
        gw = self.gw

        # OK
        self._mock_response(200)
        message = OutgoingMessage('+123456', 'hey', provider='main')
        message = gw.send(message)
        self.assertEqual(message.msgid, None)

        # Should fail with E001
        self._mock_response(500)
        self.assertRaises(error.E001, gw.send,
                          OutgoingMessage('+123456', 'hey', provider='main'))
    def test_error_send(self):
        """ Test message send """
        gw = self.gw
        bad_json = {
            'msg': 'Required parameter has format error',
            'code': 2,
            'detail': 'Format the parameter by prompt.'
        }
        responses.add(
            responses.POST,
            'https://sms.yunpian.com/v2/sms/single_send.json',
            json=bad_json,
            status=200,
        )

        try:
            message = gw.send(
                OutgoingMessage('+123456',
                                'hey',
                                src='dignio',
                                provider='main'))
            assert False
        except Exception as e:
            self.assertIn('2 Required parameter has format error', str(e))

        self.assertEqual(len(responses.calls), 1)
        self.assertIn('my_api_key1234', responses.calls[0].request.body)
    def test_events(self):
        """ Test events """

        # Counters
        self.recv = 0
        self.send = 0
        self.status = 0

        def inc_recv(message):
            self.recv += 1

        def inc_send(message):
            self.send += 1

        def inc_status(message):
            self.status += 1

        # Hooks
        self.gw.onReceive += inc_recv
        self.gw.onSend += inc_send
        self.gw.onStatus += inc_status

        # Emit some events
        provider = self.gw.get_provider('one')
        self.gw.send(OutgoingMessage('', ''))
        provider._receive_message(IncomingMessage('', ''))
        provider._receive_status(MessageStatus(''))

        # Check
        self.assertEqual(self.recv, 1)
        self.assertEqual(self.send, 1)
        self.assertEqual(self.status, 1)
示例#7
0
    def testSend(self):
        """ Send messages """

        # Send a message
        om = OutgoingMessage(
            '+1234',
            'Hi man!').options(senderId='me').params(a=1).route(1, 2, 3)
        rom = self.gw_client.send(om)

        # Check traffic
        traffic = self.lo.get_traffic()
        self.assertEqual(len(traffic), 1)
        tom = traffic.pop()

        for m in (om, rom, tom):
            self.assertEqual(m.src, None)
            self.assertEqual(m.dst, '1234')
            self.assertEqual(m.body, 'Hi man!')
            self.assertEqual(m.provider,
                             'lo')  # Remote provider should be exposed
            self.assertEqual(m.provider_options.senderId, 'me')
            self.assertEqual(m.provider_params, {'a': 1})
            self.assertEqual(m.routing_values, [1, 2, 3])
            self.assertEqual(m.msgid, '1')
            self.assertEqual(m.meta, None)
 def test_send_success(self):
     """Test a successful AfricasTalking SMS send"""
     message_out = OutgoingMessage(
         '+254789789789', 'Hello Kenya',
         provider='africas_talking').params(target_country='KE')
     message_back = self.gw.send(message_out)
     self.assertEqual(message_back.msgid, '001')
 def test_send_failure(self):
     """Test a failing AfricasTalking SMS send"""
     message_out = OutgoingMessage(
         '+254789789789', 'Hello Kenya',
         provider='africas_talking').params(target_country='KE')
     self.assertRaises(AfricasTalkingProviderError, self.gw.send,
                       message_out)
示例#10
0
    def testStatus(self):
        """ Receive statuses """
        # Status receiver
        statuses = []
        def onStatus(status): statuses.append(status)
        self.gw_client.onStatus += onStatus

        # Subscriber
        incoming = []
        def subscriber(message): incoming.append(message)
        self.lo.subscribe('1234', subscriber)

        # Send a message, request status report
        om = OutgoingMessage('+1234', 'Hi man!').options(status_report=True)
        rom = self.gw_client.send(om)

        # Check
        self.assertEqual(len(statuses), 1)
        status = statuses.pop()
        ':type: MessageStatus'
        self.assertEqual(status.msgid, '1')
        self.assertIsInstance(status.rtime, datetime)
        self.assertEqual(status.provider, 'lo')
        self.assertEqual(status.accepted, True)
        self.assertEqual(status.delivered, True)
        self.assertEqual(status.expired, False)
        self.assertEqual(status.error, False)
        self.assertEqual(status.status_code, None)
        self.assertEqual(status.status, 'OK')
        self.assertEqual(status.meta, {})
    def test_send(self):
        """ Test message send """
        gw = self.gw
        ok_json = {
            'code': 0,
            'msg': 'OK',
            'count': 1,
            'fee': 0.05,
            'unit': 'RMB',
            'mobile': '123456',
            'sid': 16741236146
        }
        responses.add(
            responses.POST,
            'https://sms.yunpian.com/v2/sms/single_send.json',
            json=ok_json,
            status=200,
        )

        message = gw.send(
            OutgoingMessage('+123456', 'hey', src='dignio', provider='main'))
        self.assertEqual(len(responses.calls), 1)

        self.assertIn('my_api_key1234', responses.calls[0].request.body)
        self.assertIn('Google', responses.calls[0].request.body)
        self.assertEqual(message.msgid, 16741236146)
示例#12
0
    def test_missing_number(self):
        """ Send to a missing number """
        msg = self.gw.send(OutgoingMessage('+0', 'you there?'))

        self.assertListEqual(self.provider.get_traffic(),
                             [msg])  # traffic works
        self.assertListEqual(self.events_log, [msg])
        self.assertEqual(self.subscriber_log,
                         [])  # no log as there was no subscriber
示例#13
0
    def testServerError(self):
        """ Test how errors are transferred from the server """

        # Erroneous subscribers
        def tired_subscriber(message):
            raise OverflowError('Tired')
        self.lo.subscribe('1234', tired_subscriber)

        def offline_subscriber(message):
            raise exc.ServerError('Offline')
        self.lo.subscribe('5678', offline_subscriber)

        # Send: 1
        om = OutgoingMessage('+1234', 'Hi man!')
        self.assertRaises(RuntimeError, self.gw_client.send, om)  # Unknown error classes are converted to RuntimeError

        # Send: 2
        om = OutgoingMessage('+5678', 'Hi man!')
        self.assertRaises(exc.ServerError, self.gw_client.send, om)  # Known errors: as is
示例#14
0
    def test_gsm7_encoding_invalid_character(self):
        message = OutgoingMessage('+123456',
                                  u'Vamos a aprender chino \u73a9.',
                                  provider='main')
        self._mock_response(200)
        self.gw.send(message)
        self.assertIn('is_hex', message.provider_params)

        request = self.requests.pop()
        self.assertEqual(CT_UCS2, request['CT'])

        message = OutgoingMessage('+123456',
                                  u'\u05de\u05d4 \u05e7\u05d5\u05e8\u05d4?',
                                  provider='main')
        self._mock_response(200)
        self.gw.send(message)

        request = self.requests.pop()
        self.assertEquals(CT_UCS2, request['CT'])
        self.assertEquals(b'05de05d4002005e705d505e805d4003f', request['HEX'])
示例#15
0
    def test_subscriber3_noreply(self):
        """ Test replying subscriber with disabled replies """
        msg = self.gw.send(
            OutgoingMessage('3', 'hi!').options(status_report=True,
                                                allow_reply=False))

        self.assertListEqual(self.provider.get_traffic(), [msg])
        self.assertEqual(len(self.events_log), 2)
        self.assertIsInstance(self.events_log[0],
                              MessageDelivered)  # delivered
        self.assertIs(self.events_log[1], msg)
        self.assertEqual(self.subscriber_log, ['3:None:hi!'])
    def test_routing(self):
        """ Test routing """

        # Sends through 'one'
        msg = self.gw.send(OutgoingMessage('', '').route('main', ''))
        self.assertEqual(msg.provider, 'one')

        # Sends through 'two'
        msg = self.gw.send(OutgoingMessage('', '').route('', 'alarm'))
        self.assertEqual(msg.provider, 'two')

        # Sends through 'three'
        msg = self.gw.send(OutgoingMessage('', '').route('', ''))
        self.assertEqual(msg.provider, 'three')

        # Send through 'one' (explicitly set)
        msg = self.gw.send(
            OutgoingMessage('', '', provider='one').route('', ''))
        self.assertEqual(msg.provider, 'one')

        # No routing specified: using the default route
        msg = self.gw.send(OutgoingMessage('', '', provider='one'))
        self.assertEqual(msg.provider, 'one')

        # Wrong provider specified
        self.assertRaises(AssertionError, self.gw.send,
                          OutgoingMessage('', '', provider='zzz'))
示例#17
0
    def test_send_message(self):
        """ Test outgoing message """
        # 1. Simple message
        with self._stubber() as st:
            st.add_response('publish',
                            expected_params={
                                'PhoneNumber': '+1999',
                                'Message': 'test 1',
                                'MessageAttributes': {}
                            },
                            service_response={'MessageId': '1'})
            self.assertEqual(
                '1',
                self.gw.send(OutgoingMessage('+1999', 'test 1')).msgid)

        # 2. Transactional message
        with self._stubber() as st:
            # 2. Transactional message with SenderId
            st.add_response('publish',
                            expected_params={
                                'PhoneNumber': '+1999',
                                'Message': 'test 2',
                                'MessageAttributes': {
                                    'AWS.SNS.SMS.SenderID': {
                                        'DataType': 'String',
                                        'StringValue': 'kolypto'
                                    },
                                    'AWS.SNS.SMS.SMSType': {
                                        'DataType': 'String',
                                        'StringValue': 'Transactional'
                                    },
                                }
                            },
                            service_response={'MessageId': '2'})
            self.assertEqual(
                '2',
                self.gw.send(
                    OutgoingMessage('+1999',
                                    'test 2').options(senderId='kolypto',
                                                      escalate=True)).msgid)
示例#18
0
    def test_subscriber1(self):
        """ Test delivering a message to a subscriber """
        msg = self.gw.send(
            OutgoingMessage('+1', 'hi!').options(status_report=True))

        self.assertListEqual(self.provider.get_traffic(), [msg])
        self.assertEqual(len(self.events_log), 2)
        self.assertIsInstance(self.events_log[0],
                              MessageDelivered)  # delivered
        self.assertSetEqual(self.events_log[0].states,
                            {'accepted', 'delivered'})
        self.assertIs(self.events_log[1], msg)
        self.assertEqual(self.subscriber_log, ['1:None:hi!'])
示例#19
0
    def test_missing_number_status(self):
        """ Send to a missing number with status report request """
        msg = self.gw.send(
            OutgoingMessage('+0', 'you there?').options(status_report=True))

        self.assertListEqual(self.provider.get_traffic(),
                             [msg])  # traffic works
        self.assertEqual(len(self.events_log), 2)
        self.assertIsInstance(self.events_log[0],
                              MessageAccepted)  # accepted, but not delivered
        self.assertSetEqual(self.events_log[0].states, {'accepted'})
        self.assertIs(self.events_log[1], msg)
        self.assertEqual(self.subscriber_log,
                         [])  # no log as there was no subscriber
示例#20
0
    def test_gsm7_valid_characters(self):
        self._mock_response(200)
        sent_message = self.gw.send(
            OutgoingMessage('+654321', u'Æ E A Å Edø.', provider='main'))
        self.assertNotIn('is_hex', sent_message.provider_params)
        request_1 = self.requests.pop()
        self.assertEquals(b'\xc6 E A \xc5 Ed\xf8.', request_1['TXT'])

        self._mock_response(200)
        sent_message_2 = self.gw.send(
            OutgoingMessage(
                '+654321',
                u'RaLejaLe hemmat i høssølæssom å naumøLa spikkjipørse.',
                provider='main'))

        # The modified OutgoingMessage will be returned in the http response.
        # Ensure that OutgoingMessage.body can still be jsonified:
        sent_message_2.body.encode('utf-8')

        request_2 = self.requests.pop()
        self.assertEquals(CT_PLAIN_TEXT, request_2['CT'])
        self.assertEquals(
            b'RaLejaLe hemmat i h\xf8ss\xf8l\xe6ssom \xe5 naum\xf8La spikkjip\xf8rse.',
            request_2['TXT'])

        self._mock_response(200)
        sent_message_3 = self.gw.send(
            OutgoingMessage(
                '+654321',
                u'Ñoño Yáñez come ñame en las mañanas con el niño.',
                provider='main'))
        self.assertNotIn('is_hex', sent_message_3.provider_params)
        request_3 = self.requests.pop()
        self.assertEquals(
            b'\xd1o\xf1o Y\xe1\xf1ez come \xf1ame en las ma\xf1anas con el ni\xf1o.',
            request_3['TXT'])
示例#21
0
    def test_subscriber3(self):
        """ Test replying subscriber """
        msg = self.gw.send(OutgoingMessage('++3', 'hi!').options())

        traffic = self.provider.get_traffic()
        self.assertIs(traffic[0], msg)
        self.assertIsInstance(traffic[1], IncomingMessage)
        self.assertEqual(traffic[1].src, '3')
        self.assertEqual(traffic[1].dst, None)
        self.assertEqual(traffic[1].body, 'hello')

        self.assertEqual(len(self.events_log), 2)
        self.assertIs(
            self.events_log[1],
            msg)  # onSend is only emitted once the Provider has finished
        self.assertEqual(self.events_log[0].body, 'hello')  # the reply
        self.assertEqual(self.subscriber_log, ['3:None:hi!'])
示例#22
0
    def test_send(self):
        """ Test send SMS """
        with Mocker() as m:
            m.post(
                'https://studio.twilio.com/v1/Flows/sid/Executions',
                request_headers={
                    'Authorization':
                    'Basic ZGFnOnNlY3JldA==',  # dag:secret
                    'Content-Type':
                    'application/x-www-form-urlencoded; charset=utf-8',
                },
                status_code=200,
                headers={},
                json={
                    'url':
                    'https://studio.twilio.com/v1/Flows/sid/Executions/FN0000',
                    # ... many more fields. See: https://www.twilio.com/docs/studio/rest-api/execution
                })

            om = self.gw.send(OutgoingMessage('+1999', 'Test'))
            self.assertEqual(om.msgid, 'Flows/sid/Executions/FN0000')
示例#23
0
    def send_message(cls,
                     package,
                     message_type,
                     to_number,
                     referer=None,
                     email=None):
        message = cls(package=package,
                      message_type=cls.types_by_name[message_type],
                      recipient_number=to_number,
                      content=cls.render_message(message_type, package,
                                                 referer))

        try:
            if not settings.TEST:
                if settings.SMS_PLATFORM == 'Twilio':
                    client = cls.get_twilio_client()
                    if client:
                        twilio_msg = client.messages.create(
                            body=message.content,
                            to=to_number,
                            from_=settings.TWILIO['SENDER_NR'])
                        message.twilio_sid = twilio_msg.sid

                elif settings.SMS_PLATFORM == 'GatewayAPI':
                    gateway.send(OutgoingMessage(to_number, message.content))

            if email:
                from_email = settings.EMAIL_HOST_USER or '*****@*****.**'
                send_mail(cls.subjects_by_name[message_type], message.content,
                          from_email, [email])

        except Exception as e:
            if settings.DEBUG:
                print(e)
            else:
                capture_exception(e)

        message.save()
    def test_send(self):
        """ Test message send """
        gw = self.gw

        # Mock the Target365 Api response.
        # See - https://generator.swagger.io/?url=https%3A%2F%2Ftest.target365.io%2Fapi%2Fswagger.json
        def send_callback(request):
            payload = json.loads(request.body)
            headers = {
                'Location':
                '/api/out-messages/{}'.format(payload['transactionId'])
            }
            return (201, headers, '')

        responses.add_callback(responses.POST,
                               'https://target365.api/api/out-messages',
                               callback=send_callback)

        # For the target365 src is mandatory
        message = gw.send(
            OutgoingMessage('+123456', 'hey', src='dignio', provider='main'))
        self.assertEqual(len(responses.calls), 1)
        self.assertTrue(message.msgid)
 def test_bad_number_failure(self):
     """Test a failing AfricasTalking SMS send (bad phone number)"""
     message_out = OutgoingMessage(
         '+254789789789', 'Hello Rwanda',
         provider='africas_talking').params(target_country='RW')
     self.assertRaises(InvalidNumberError, self.gw.send, message_out)
示例#26
0
 def test_basic_send(self):
     with LogCapture() as l:
         msg = self.gw.send(OutgoingMessage('+1234', 'body'))
         l.check(('smsframework.providers.log', 'INFO',
                  'Sent SMS to {}: {}'.format(msg.dst, msg.body)), )
示例#27
0
def send_sms(recipients, message):
    '''Send SMS to recipients with message'''
    for pnumber in recipients:
        GATEWAY.send(OutgoingMessage(pnumber, message))