class TechsysSMSHandlerTestCase(TestCase): fixtures = ['user_set'] def setUp(self): self.client = APIClient() self.client.login(username='******', password='******') # create the user we need to be authorized self.user = User.objects.get(username='******') def test_sms_receipts(self): """ E-Scape currently doesn't send us sms receipts, shouldn't respond """ resp = self.client.post(reverse('api:techsys:sms-receipt')) self.assertEquals(resp.status_code, 405) resp = self.client.get(reverse('api:techsys:sms-receipt')) self.assertEquals(resp.status_code, 405) def test_sms_sending(self): self.assertEquals(SentSMS.objects.count(), 0) resp = self.client.post(reverse('api:techsys:sms-send'), { 'to_msisdn': '27123456789', 'from_msisdn': '27123456789', 'message': 'yebo', }) self.assertEquals(resp.status_code, 200) self.assertEquals(SentSMS.objects.count(), 1) def test_batch_sms_sending(self): self.assertEquals(SentSMS.objects.count(), 0) resp = self.client.post(reverse('api:techsys:sms-send'), { 'to_msisdn': ['27123456780','27123456781','27123456782'], 'from_msisdn': '27123456789', 'message': 'yebo' }) self.assertEquals(resp.status_code, 200) self.assertEquals(SentSMS.objects.count(), 3) def test_template_sms_sending(self): # not implemented resp = self.client.post(reverse('api:techsys:sms-template-send')) self.assertEquals(resp.status_code, 405) def test_send_sms_response(self): """ We get the following back from E-scape when we send them an SMS, make sure we can parse it correctly""" good_response = """PS Bind: Message queued successfully""" bad_response = """Anything else really""" e = E_Scape("url", "bind") response = e.parse_response(good_response) self.assertRaises(Exception, e.parse_response, bad_response) def test_sms_receiving(self): # not implemented resp = self.client.post(reverse('api:techsys:sms-receive')) self.assertEquals(resp.status_code, 405)
class BaseSMSHandlerTestCase(TestCase): fixtures = ['user_set'] def setUp(self): self.client = APIClient() self.client.login(username='******', password='******') # get the user self.user = User.objects.get(username='******') # make sure the transport's set profile = self.user.get_profile() profile.transport = Transport.objects.create(name='Clickatell') profile.save() def test_sms_sending(self): self.assertEquals(SentSMS.objects.count(), 0) resp = self.client.post(reverse('api:sms-send'), { 'to_msisdn': '27123456789', 'from_msisdn': '27123456789', 'message': 'yebo', }) self.assertEquals(resp.status_code, 200) self.assertEquals(SentSMS.objects.count(), 1) self.assertEquals(SentSMSBatch.objects.count(), 1) batch = SentSMSBatch.objects.all()[0] self.assertEquals(batch.sentsms_set.count(), 1) def test_batch_sms_sending(self): self.assertEquals(SentSMS.objects.count(), 0) resp = self.client.post(reverse('api:sms-send'), { 'to_msisdn': ['27123456780', '27123456781', '27123456782'], 'from_msisdn': '27123456789', 'message': 'yebo', }) self.assertEquals(resp.status_code, 200) self.assertEquals(SentSMS.objects.count(), 3) self.assertEquals(SentSMSBatch.objects.count(), 1) batch = SentSMSBatch.objects.all()[0] self.assertEquals(batch.sentsms_set.count(), 3) def test_template_sms_sending(self): self.assertEquals(SentSMS.objects.count(), 0) resp = self.client.post(reverse('api:sms-template-send'), { 'to_msisdn': ['27123456780', '27123456781', '27123456782'], 'template_first_name': ['Name 1', 'Name 2', 'Name 3'], 'template_last_name': ['Surname 1', 'Surname 2', 'Surname 3'], 'from_msisdn': '27123456789', 'template': 'Hi {{first_name}} {{last_name}}', }) self.assertEquals(resp.status_code, 200) self.assertEquals(SentSMS.objects.count(), 3) self.assertEquals(SentSMSBatch.objects.count(), 1) batch = SentSMSBatch.objects.all()[0] self.assertEquals(batch.sentsms_set.count(), 3)
class ConversationHandlerTestCase(TestCase): fixtures = ['user_set'] def setUp(self): self.client = APIClient() self.client.login(username='******', password='******') # create the user we need to be authorized self.user = User.objects.get(username='******') # load the yaml data fp = open(os.path.join(settings.APP_ROOT, 'webapp', 'api', 'test_data', 'devquiz.yaml'), 'r') self.yaml_conversation = ''.join(fp.readlines()) def tearDown(self): pass def test_creation_of_conversation(self): """ Conversations should be able to be created by POSTing to the api """ resp = self.client.post(reverse('api:conversation'), self.yaml_conversation, content_type="application/x-yaml") self.assertContains(resp, 'Created', status_code=201) resp = self.client.get(reverse('api:conversation')) self.assertEquals(resp.status_code, 405)
class ClickatellSMSHandlerTestCase(TestCase): fixtures = ['user_set'] def setUp(self): self.client = APIClient() self.client.login(username='******', password='******') # create the user we need to be authorized self.user = User.objects.get(username='******') def test_sms_receipts(self): """ Receipts received from clickatell should update the status """ [sms] = mock_sent_messages(self.user, count=1, transport_name='Clickatell', transport_msg_id='a' * 32) self.assertEquals(sms.transport_status, '') resp = self.client.post(reverse('api:clickatell:sms-receipt'), { 'apiMsgId': 'a' * 32, 'cliMsgId': sms.pk, 'status': 8, # OK 'to': '27123456789', 'from': '27123456789', 'timestamp': int(time()), 'charge': 0.3 }) self.assertEquals(resp.status_code, 201) sms = SentSMS.objects.get(pk=sms.pk) # reload self.assertEquals(sms.transport_status, '8') def test_sms_receiving(self): self.assertEquals(ReceivedSMS.objects.count(), 0) resp = self.client.post(reverse('api:clickatell:sms-receive'), { 'to': '27123456789', 'from': '27123456789', 'moMsgId': 'a' * 12, 'api_id': 'b' * 12, 'text': 'hello world', # MySQL format 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S") }) self.assertEquals(resp.status_code, 200) self.assertEquals(ReceivedSMS.objects.count(), 1)
class OperaSMSHandlerTestCase(TestCase): fixtures = ["user_set"] def setUp(self): self.client = APIClient() self.client.login(username="******", password="******") # create the user we need to be authorized self.user = User.objects.get(username="******") def test_sms_receipts(self): """ Receipts received from opera should update the status """ [sms] = mock_sent_messages(self.user, count=1, transport_name="Opera", transport_msg_id="001efc31") self.assertEquals(sms.transport_status, "") raw_xml_post = """ <?xml version="1.0"?> <!DOCTYPE receipts> <receipts> <receipt> <msgid>26567958</msgid> <reference>001efc31</reference> <msisdn>+27123456789</msisdn> <status>D</status> <timestamp>20080831T15:59:24</timestamp> <billed>NO</billed> </receipt> </receipts> """ resp = self.client.post(reverse("api:opera:sms-receipt"), raw_xml_post.strip(), content_type="text/xml") sms = SentSMS.objects.get(pk=sms.pk) # reload self.assertEquals(sms.transport_status, "D") self.assertEquals(resp.status_code, 201) def test_sms_sending(self): self.assertEquals(SentSMS.objects.count(), 0) resp = self.client.post( reverse("api:opera:sms-send"), {"to_msisdn": "27123456789", "from_msisdn": "27123456789", "message": "yebo"} ) self.assertEquals(resp.status_code, 200) self.assertEquals(SentSMS.objects.count(), 1) def test_batch_sms_sending(self): self.assertEquals(SentSMS.objects.count(), 0) resp = self.client.post( reverse("api:opera:sms-send"), { "to_msisdn": ["27123456780", "27123456781", "27123456782"], "from_msisdn": "27123456789", "message": "yebo", }, ) self.assertEquals(resp.status_code, 200) self.assertEquals(SentSMS.objects.count(), 3) def test_template_sms_sending(self): self.assertEquals(SentSMS.objects.count(), 0) resp = self.client.post( reverse("api:opera:sms-template-send"), { "to_msisdn": ["27123456780", "27123456781", "27123456782"], "template_first_name": ["Name 1", "Name 2", "Name 3"], "template_last_name": ["Surname 1", "Surname 2", "Surname 3"], "from_msisdn": "27123456789", "template": "Hi {{first_name}} {{last_name}}", }, ) self.assertEquals(resp.status_code, 200) self.assertEquals(SentSMS.objects.count(), 3) def test_sms_receiving_with_text_plain_headers(self): """ By eavesdropping we got the following log, this is what opera sends. DTD is available at https://dragon.sa.operatelecom.com/MEnable/Client/Extra/bspostevent-1_0_0.dtd POST /api/v1/sms/opera/receive.xml HTTP/1.1 Content-Length: 1798 Content-Type: text/plain; charset=utf-8 Authorization: ... Host: .... """ receive_sms_doc = """ <?xml version="1.0"?> <!DOCTYPE bspostevent> <bspostevent> <field name="MOReference" type = "string">282341913</field> <field name="IsReceipt" type = "string">NO</field> <field name="RemoteNetwork" type = "string">mtn-za</field> <field name="BSDate-tomorrow" type = "string">20100605</field> <field name="BSDate-today" type = "string">20100604</field> <field name="ReceiveDate" type = "date">2010-06-04 15:51:25 +0000</field> <field name="Local" type = "string">*32323</field> <field name="ClientID" type = "string">4</field> <field name="ChannelID" type = "string">111</field> <field name="MessageID" type = "string">373736741</field> <field name="ReceiptStatus" type = "string"></field> <field name="Prefix" type = "string"></field> <field name="ClientName" type = "string">Praekelt</field> <field name="MobileDevice" type = "string"></field> <field name="BSDate-yesterday" type = "string">20100603</field> <field name="Remote" type = "string">+27831234567</field> <field name="State" type = "string">5</field> <field name="MobileNetwork" type = "string">mtn-za</field> <field name="MobileNumber" type = "string">+27831234567</field> <field name="Text" type = "string">Hello World</field> <field name="ServiceID" type = "string">20222</field> <field name="RegType" type = "string">1</field> <field name="NewSubscriber" type = "string">NO</field> <field name="Subscriber" type = "string">+27831234567</field> <field name="Parsed" type = "string"></field> <field name="ServiceName" type = "string">Prktl Vumi</field> <field name="BSDate-thisweek" type = "string">20100531</field> <field name="ServiceEndDate" type = "string">2010-06-30 07:47:00 +0200</field> <field name="Now" type = "date">2010-06-04 15:51:27 +0000</field> </bspostevent> """ self.assertEquals(ReceivedSMS.objects.count(), 0) resp = self.client.post( reverse("api:opera:sms-receive"), receive_sms_doc.strip(), content_type="text/plain; charset=utf-8" ) self.assertEquals(resp.status_code, 200) self.assertEquals(ReceivedSMS.objects.count(), 1) sms = ReceivedSMS.objects.latest() self.assertEquals(sms.received_at.strftime("%Y-%m-%d %H:%M:%S +0000"), "2010-06-04 15:51:25 +0000") self.assertEquals(sms.from_msisdn, "+27831234567") self.assertEquals(sms.to_msisdn, "*32323") self.assertEquals(sms.transport_name, "Opera")
class URLCallbackHandlerTestCase(TestCase): fixtures = ['user_set'] def setUp(self): self.client = APIClient() self.client.login(username='******', password='******') # create the user we need to be authorized self.user = User.objects.get(username='******') def tearDown(self): pass def test_setting_callback_url(self): self.assertEquals(URLCallback.objects.count(), 0) resp = self.client.post(reverse('api:url-callbacks-list'), { 'name': 'sms_receipt', 'url': 'http://localhost/url/sms/receipt', }) resp = self.client.post(reverse('api:url-callbacks-list'), { 'name': 'sms_received', 'url': 'http://localhost/url/sms/received', }) self.assertEquals(resp.status_code, 200) self.assertEquals(URLCallback.objects.count(), 2) resp = self.client.post(reverse('api:clickatell:sms-receive'), { 'to': '27123456789', 'from': '27123456789', 'moMsgId': 'a' * 12, 'api_id': 'b' * 12, 'text': 'hello world', # MySQL format: 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"), }) # this should show up in the testing log because pycurl can't # connect to the given host for the callback def test_setting_multiple_callback_urls(self): self.assertEquals(URLCallback.objects.count(), 0) for name, urls in [ ('sms_received', [ 'http://localhost/url/sms/received/1', 'http://localhost/url/sms/received/2', ]), ('sms_receipt', [ 'http://localhost/url/sms/receipt/1', 'http://localhost/url/sms/receipt/2', ])]: for url in urls: resp = self.client.post(reverse('api:url-callbacks-list'), { 'name': name, 'url': url, }) self.assertEquals(resp.status_code, 200) self.assertEquals(URLCallback.objects.count(), 4) resp = self.client.post(reverse('api:clickatell:sms-receive'), { 'to': '27123456789', 'from': '27123456789', 'moMsgId': 'a' * 12, 'api_id': 'b' * 12, 'text': 'hello world', # MySQL format 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"), }) def test_updating_callback_urls(self): self.assertEquals(URLCallback.objects.count(), 0) resp = self.client.post(reverse('api:url-callbacks-list'), { 'name': 'sms_receipt', 'url': 'http://localhost/url/sms/receipt', }) self.assertEquals(URLCallback.objects.count(), 1) data = json.loads(resp.content) resp = self.client.put(reverse('api:url-callback', kwargs={ 'callback_id': data['id'], }), { 'url': 'http://localhost/url/sms/receipt1' }) updated_callback = URLCallback.objects.latest('updated_at') self.assertEquals(updated_callback.url, 'http://localhost/url/sms/receipt1') def test_deleting_callback_urls(self): self.assertEquals(URLCallback.objects.count(), 0) resp = self.client.post(reverse('api:url-callbacks-list'), { 'name': 'sms_receipt', 'url': 'http://localhost/url/sms/receipt', }) data = json.loads(resp.content) self.assertEquals(URLCallback.objects.count(), 1) resp = self.client.delete(reverse('api:url-callback', kwargs={ 'callback_id': data['id'], })) self.assertEquals(resp.status_code, 204) self.assertEquals(resp.content, '') self.assertEquals(URLCallback.objects.count(), 0)
class E_ScapeSMSHandlerTestCase(TestCase): fixtures = ['user_set'] def setUp(self): self.client = APIClient() self.client.login(username='******', password='******') # create the user we need to be authorized self.user = User.objects.get(username='******') def test_sms_receipts(self): """ E-Scape currently doesn't send us sms receipts, shouldn't respond """ resp = self.client.post(reverse('api:e-scape:sms-receipt')) self.assertEquals(resp.status_code, 405) resp = self.client.get(reverse('api:e-scape:sms-receipt')) self.assertEquals(resp.status_code, 405) def test_sms_sending(self): self.assertEquals(SentSMS.objects.count(), 0) resp = self.client.post(reverse('api:e-scape:sms-send'), { 'to_msisdn': '27123456789', 'from_msisdn': '27123456789', 'message': 'yebo', }) self.assertEquals(resp.status_code, 200) self.assertEquals(SentSMS.objects.count(), 1) def test_batch_sms_sending(self): self.assertEquals(SentSMS.objects.count(), 0) resp = self.client.post(reverse('api:e-scape:sms-send'), { 'to_msisdn': ['27123456780','27123456781','27123456782'], 'from_msisdn': '27123456789', 'message': 'yebo' }) self.assertEquals(resp.status_code, 200) self.assertEquals(SentSMS.objects.count(), 3) def test_template_sms_sending(self): self.assertEquals(SentSMS.objects.count(), 0) resp = self.client.post(reverse('api:e-scape:sms-template-send'), { 'to_msisdn': ['27123456780','27123456781','27123456782'], 'template_first_name': ['Name 1', 'Name 2', 'Name 3'], 'template_last_name': ['Surname 1', 'Surname 2', 'Surname 3'], 'from_msisdn': '27123456789', 'template': 'Hi {{first_name}} {{last_name}}', }) self.assertEquals(resp.status_code, 200) self.assertEquals(SentSMS.objects.count(), 3) def test_send_sms_response(self): """ We get the following back from E-scape when we send them an SMS, make sure we can parse it correctly""" html = """ <table class="widefat" border="0"> <thead> <tr> <th>from</th> <th>to</th> <th>smsc</th> <th>status</th> <th>text</th> </tr> </thead> <tbody> <tr> <td>+35566</td> <td>+44778962937</td> <td>ESC-P1Celtel</td> <td>0: Accepted for delivery</td> <td> http://www.mobi-fee.com/link/g.lnk?ID=135</td> </tr> </tbody> <tfoot> <tr> <th>from</th> <th>to</th> <th>smsc</th> <th>status</th> <th>text</th> </tr> </tfoot> </table> """ e = E_Scape('api_id') [response] = e.parse_response(html) self.assertEquals(response.sender, '+35566') self.assertEquals(response.recipient, '+44778962937') self.assertEquals(response.smsc, 'ESC-P1Celtel') self.assertEquals(response.status, ['0', 'Accepted for delivery']) self.assertEquals(response.text, ' http://www.mobi-fee.com/link/g.lnk?ID=135') def test_sms_receiving(self): self.assertEquals(ReceivedSMS.objects.count(), 0) resp = self.client.get(reverse('api:e-scape:sms-receive'), { 'smsc': 'id of sms center', 'svc': 'name of the service', 's': 'originator', 'r': 'recipient', 'text': 'actual message' }) self.assertEquals(resp.status_code, 200) # make sure we don't send any headers or content. If we do we'll # automatically send a reply, currently that's not the # desired behaviour. self.assertEquals(resp.get('X-Kannel-From', None), None) self.assertEquals(resp.get('X-Kannel-To', None), None) self.assertEquals(resp.get('X-Kannel-SMSC', None), None) self.assertEquals(resp.get('X-Kannel-Service', None), None) self.assertEquals(resp.content, '') self.assertEquals(ReceivedSMS.objects.count(), 1) sms = ReceivedSMS.objects.latest() import time # grmbl messy datetime comparisons self.assertAlmostEqual( time.mktime(sms.received_at.utctimetuple()), time.mktime(datetime.utcnow().utctimetuple()), places=1 ) self.assertEquals(sms.from_msisdn, 'originator') self.assertEquals(sms.to_msisdn, 'recipient') self.assertEquals(sms.message, 'actual message') self.assertEquals(sms.transport_name, 'E-scape')