sms: send SMS asynchronously (#21465)
This commit is contained in:
parent
b9048993be
commit
115b0bb78c
|
@ -77,10 +77,14 @@ class SMSResource(BaseResource):
|
|||
data['to'] = self.clean_numbers(data['to'])
|
||||
logging.info('sending SMS to %r from %r', data['to'], data['from'])
|
||||
stop = not bool('nostop' in request.GET)
|
||||
# unfortunately it lacks a batch API...
|
||||
result = {'data': self.send_msg(data['message'], data['from'], data['to'], stop=stop)}
|
||||
self.add_job('send_job',
|
||||
text=data['message'], sender=data['from'], destinations=data['to'],
|
||||
stop=stop)
|
||||
return {'err': 0}
|
||||
|
||||
def send_job(self, *args, **kwargs):
|
||||
self.send_msg(**kwargs)
|
||||
SMSLog.objects.create(appname=self.get_connector_slug(), slug=self.slug)
|
||||
return result
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
|
|
@ -24,7 +24,8 @@ from django.contrib.contenttypes.models import ContentType
|
|||
from django.utils.encoding import force_text
|
||||
|
||||
from passerelle.apps.orange.models import OrangeSMSGateway, OrangeError
|
||||
from passerelle.base.models import ApiUser, AccessRight
|
||||
|
||||
from passerelle.base.models import ApiUser, AccessRight, Job
|
||||
from passerelle.utils.jsonresponse import APIError
|
||||
|
||||
|
||||
|
@ -163,13 +164,20 @@ def test_diffusion(app, connector):
|
|||
|
||||
def test_send_msg(app, connector):
|
||||
url = '/%s/%s/send/' % (connector.get_connector_slug(), connector.slug)
|
||||
with httmock.HTTMock(response_token_ok, response_group_ok, response_diffusion_ok):
|
||||
resp = app.post_json(url, params=PAYLOAD, status=200)
|
||||
assert Job.objects.count() == 0
|
||||
resp = app.post_json(url, params=PAYLOAD, status=200)
|
||||
assert not resp.json['err']
|
||||
assert resp.json['data']['status'] == "I'm ok"
|
||||
assert Job.objects.count() == 1
|
||||
with httmock.HTTMock(response_token_ok, response_group_ok, response_diffusion_ok):
|
||||
connector.jobs()
|
||||
assert Job.objects.all()[0].status == 'completed'
|
||||
|
||||
# not 201
|
||||
resp = app.post_json(url, params=PAYLOAD, status=200)
|
||||
assert not resp.json['err']
|
||||
assert Job.objects.count() == 2
|
||||
with httmock.HTTMock(response_token_ok, response_group_ok, response_500):
|
||||
resp = app.post_json(url, params=PAYLOAD, status=200)
|
||||
assert resp.json['err']
|
||||
assert resp.json['err_desc'] == 'Orange fails to send SMS: 500, my_error'
|
||||
connector.jobs()
|
||||
job = Job.objects.all()[1]
|
||||
assert job.status == 'failed'
|
||||
assert 'Orange fails to send SMS: 500, my_error' in job.status_details['error_summary']
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import isodate
|
||||
import mock
|
||||
import pytest
|
||||
from requests import RequestException
|
||||
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
from passerelle.apps.ovh.models import OVHSMSGateway
|
||||
from passerelle.base.models import ApiUser, AccessRight
|
||||
from passerelle.base.models import ApiUser, AccessRight, Job
|
||||
from passerelle.sms.models import SMSResource, SMSLog
|
||||
from passerelle.utils.jsonresponse import APIError
|
||||
|
||||
|
@ -52,7 +54,7 @@ def connector(request, db):
|
|||
return c
|
||||
|
||||
|
||||
def test_connectors(app, connector):
|
||||
def test_connectors(app, connector, freezer):
|
||||
path = '/%s/%s/send/' % (connector.get_connector_slug(), connector.slug)
|
||||
result = app.post_json(path, params={})
|
||||
assert result.json['err'] == 1
|
||||
|
@ -63,12 +65,34 @@ def test_connectors(app, connector):
|
|||
'from': '+33699999999',
|
||||
'to': ['+33688888888', '+33677777777'],
|
||||
}
|
||||
for test_vector in getattr(connector, 'TEST_DEFAULTS', {}).get('test_vectors', []):
|
||||
with utils.mock_url(connector.URL, test_vector['response']):
|
||||
result = app.post_json(path, params=payload)
|
||||
for key, value in test_vector['result'].items():
|
||||
assert key in result.json
|
||||
assert result.json[key] == value
|
||||
test_vectors = getattr(connector, 'TEST_DEFAULTS', {}).get('test_vectors', [])
|
||||
total = len(test_vectors)
|
||||
nb_failed = 0
|
||||
assert Job.objects.count() == 0
|
||||
for test_vector in test_vectors:
|
||||
|
||||
# register job
|
||||
freezer.move_to('2019-01-01 00:00:00')
|
||||
result = app.post_json(path, params=payload)
|
||||
assert result.json['err'] == 0
|
||||
job_id = Job.objects.get(status='registered').id
|
||||
|
||||
# perform job
|
||||
freezer.move_to('2019-01-01 01:00:03')
|
||||
with utils.mock_url(
|
||||
connector.URL,
|
||||
test_vector.get('response', ''),
|
||||
test_vector.get('status_code', 200)):
|
||||
connector.jobs()
|
||||
job = Job.objects.get(id=job_id)
|
||||
if job.status == 'failed':
|
||||
assert len(job.status_details['error_summary']) > 0
|
||||
assert test_vector['result']['err_desc'] in job.status_details['error_summary']
|
||||
nb_failed += 1
|
||||
else:
|
||||
assert job.status == 'completed'
|
||||
assert Job.objects.count() == total
|
||||
assert SMSLog.objects.count() == total - nb_failed
|
||||
|
||||
|
||||
def test_manage_views(admin_user, app, connector):
|
||||
|
@ -95,7 +119,8 @@ def test_sms_max_message_length(app, connector):
|
|||
with mock.patch.object(OVHSMSGateway, 'send_msg') as send_function:
|
||||
send_function.return_value = {}
|
||||
result = app.post_json(path, params=payload)
|
||||
assert send_function.call_args[0][0] == 'a' * connector.max_message_length
|
||||
connector.jobs()
|
||||
assert send_function.call_args[1]['text'] == 'a' * connector.max_message_length
|
||||
|
||||
|
||||
@pytest.mark.parametrize('connector', [OVHSMSGateway], indirect=True)
|
||||
|
@ -111,4 +136,5 @@ def test_sms_log(app, connector):
|
|||
with mock.patch.object(OVHSMSGateway, 'send_msg') as send_function:
|
||||
send_function.return_value = {}
|
||||
result = app.post_json(path, params=payload)
|
||||
connector.jobs()
|
||||
assert SMSLog.objects.filter(appname=connector.get_connector_slug(), slug=connector.slug).exists()
|
||||
|
|
|
@ -32,7 +32,7 @@ class FakedResponse(mock.Mock):
|
|||
return json_loads(self.content)
|
||||
|
||||
|
||||
def mock_url(url=None, response='', status_code=200, headers=None):
|
||||
def mock_url(url=None, response='', status_code=200, headers=None, exception=None):
|
||||
urlmatch_kwargs = {}
|
||||
if url:
|
||||
parsed = urlparse.urlparse(url)
|
||||
|
@ -46,6 +46,8 @@ def mock_url(url=None, response='', status_code=200, headers=None):
|
|||
|
||||
@httmock.urlmatch(**urlmatch_kwargs)
|
||||
def mocked(url, request):
|
||||
if exception:
|
||||
raise exception
|
||||
return httmock.response(status_code, response, headers, request=request)
|
||||
return httmock.HTTMock(mocked)
|
||||
|
||||
|
|
Loading…
Reference in New Issue