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('src/richmond/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 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 E_ScapeSentSMSStatusTestCase(TestCase): fixtures = ['user_set', 'opera_sentsms_set'] def setUp(self): self.client = APIClient() self.client.login('api', 'password') self.user = User.objects.get(username='******') def tearDown(self): pass def test_sms_status_list_since(self): """ Sorry this test needs some explanation. In the SentSMS model I'm using Django's `auto_now` and `auto_now_add` options to automatically timestamp the `created_at` and `updated_at` values. Downside of this is that you now no longer can set these values from the code. The fixture has a `SentSMS` entry from 2009. I'm using that date to make sure the `since` parameter gives us back that entry as well instead of only the most recent 50 ones (which I create manually in this test). """ january_2009 = datetime(2009,01,01,0,0,0) new_smss = mock_sent_messages(self.user, count=50) resp = self.client.get(reverse('api:e-scape:sms-status-list'), { 'since': january_2009 }) from django.utils import simplejson data = simplejson.loads(resp.content) self.assertEquals(len(data), 51) # respects the `since` parameter # overriding the `limit` parameter. # On top of the 50 newly created # entries it should also return the # 51st entry which is one from 2009 # in the fixtures file. self.assertEquals(resp.status_code, 200) def test_single_status(self): sent_sms = SentSMS.objects.latest('created_at') resp = self.client.get(reverse('api:e-scape:sms-status', kwargs={ "sms_id": sent_sms.pk })) from django.utils import simplejson json_sms = simplejson.loads(resp.content) self.assertEquals(json_sms['to_msisdn'], sent_sms.to_msisdn) self.assertEquals(json_sms['from_msisdn'], sent_sms.from_msisdn) self.assertEquals(json_sms['message'], sent_sms.message) self.assertEquals(json_sms['transport_status'], sent_sms.transport_status) self.assertEquals(resp.status_code, 200) def test_multiple_statuses(self): smss = mock_sent_messages(self.user, count=10) sms_ids = map(lambda sms: int(sms.pk), smss) sms_ids.sort() resp = self.client.get(reverse('api:e-scape:sms-status-list'), { 'id': sms_ids }) from django.utils import simplejson json_smss = simplejson.loads(resp.content) json_sms_ids = map(lambda sms: int(sms['id']), json_smss) json_sms_ids.sort() self.assertEquals(sms_ids, json_sms_ids) self.assertEquals(resp.status_code, 200)
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')
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 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_sending(self): self.assertEquals(SentSMS.objects.count(), 0) resp = self.client.post(reverse('api:clickatell: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:clickatell: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:clickatell: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(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', 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S") # MySQL format }) self.assertEquals(resp.status_code, 200) self.assertEquals(ReceivedSMS.objects.count(), 1)
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', 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S") # MySQL format }) # 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', 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S") # MySQL format }) 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)