0001-sms-add-a-button-to-test-sending-sms-45333.patch
passerelle/sms/forms.py | ||
---|---|---|
1 |
from django import forms |
|
2 |
from django.utils.translation import ugettext_lazy as _ |
|
3 | ||
4 | ||
5 |
class SmsTestSendForm(forms.Form): |
|
6 |
number = forms.CharField(label=_('To'), max_length=12) |
|
7 |
sender = forms.CharField(label=_('From'), max_length=12) |
|
8 |
message = forms.CharField(label=_('Message'), max_length=128) |
passerelle/sms/models.py | ||
---|---|---|
13 | 13 |
# |
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 |
import logging |
17 | 17 |
import re |
18 | 18 | |
19 | 19 |
from django.db import models |
20 | 20 |
from django.utils import six |
21 |
from django.utils.module_loading import import_string |
|
21 | 22 |
from django.utils.translation import ugettext_lazy as _ |
22 | 23 | |
23 | 24 |
from passerelle.base.models import BaseResource |
24 | 25 |
from passerelle.compat import json_loads |
25 | 26 |
from passerelle.utils.api import endpoint |
26 | 27 |
from passerelle.utils.jsonresponse import APIError |
27 | 28 | |
28 | 29 |
SEND_SCHEMA = { |
... | ... | |
60 | 61 |
default=u'33') |
61 | 62 |
default_trunk_prefix = models.CharField(verbose_name=_('Default trunk prefix'), max_length=2, |
62 | 63 |
default=u'0') # Yeah France first ! |
63 | 64 |
# FIXME: add regexp field, to check destination and from format |
64 | 65 |
max_message_length = models.IntegerField(_('Maximum message length'), default=160) |
65 | 66 | |
66 | 67 |
manager_view_template_name = 'passerelle/manage/messages_service_view.html' |
67 | 68 | |
69 |
@classmethod |
|
70 |
def get_management_urls(cls): |
|
71 |
return import_string('passerelle.sms.urls.management_urlpatterns') |
|
72 | ||
68 | 73 |
def clean_numbers(self, destinations): |
69 | 74 |
numbers = [] |
70 | 75 |
for dest in destinations: |
71 | 76 |
# most gateways needs the number prefixed by the country code, this is |
72 | 77 |
# really unfortunate. |
73 | 78 |
dest = dest.strip() |
74 | 79 |
number = ''.join(re.findall('[0-9]', dest)) |
75 | 80 |
if dest.startswith('+'): |
passerelle/sms/templates/passerelle/manage/messages_service_test_send.html | ||
---|---|---|
1 |
{% extends "passerelle/base.html" %} |
|
2 |
{% load i18n %} |
|
3 | ||
4 |
{% block appbar %} |
|
5 |
<h2>{% trans "Sending a test SMS" %}</h2> |
|
6 |
{% endblock %} |
|
7 | ||
8 |
{% block content %} |
|
9 | ||
10 |
<form method="post" enctype="multipart/form-data"> |
|
11 |
{% csrf_token %} |
|
12 |
{{ form.as_p }} |
|
13 |
<div class="buttons"> |
|
14 |
<button>{% trans "Send SMS" %}</button> |
|
15 |
<a class="cancel" href="{% url 'manage-home' %}">{% trans 'Cancel' %}</a> |
|
16 |
</div> |
|
17 |
</form> |
|
18 |
{% endblock %} |
passerelle/sms/templates/passerelle/manage/messages_service_view.html | ||
---|---|---|
1 | 1 |
{% extends "passerelle/manage/service_view.html" %} |
2 | 2 |
{% load i18n passerelle %} |
3 | 3 | |
4 | 4 |
{% block endpoints %} |
5 | 5 |
{{ block.super }} |
6 |
{% if perms.base.view_accessright %} |
|
7 |
<div> |
|
8 |
<a rel="popup" href="/manage{{ object.get_absolute_url }}test-send/"> |
|
9 |
{% trans 'Send a test message' %} |
|
10 |
</a> |
|
11 |
</div> |
|
12 |
{% endif %} |
|
6 | 13 |
{% endblock %} |
passerelle/sms/urls.py | ||
---|---|---|
1 |
from django.conf.urls import url |
|
2 | ||
3 |
from . import views |
|
4 | ||
5 |
management_urlpatterns = [ |
|
6 |
url(r'^(?P<slug>[\w,-]+)/test-send/$', |
|
7 |
views.SmsTestSendView.as_view(), name='sms-test-send'), |
|
8 |
] |
passerelle/sms/views.py | ||
---|---|---|
1 |
from django.apps import apps |
|
2 |
from django.contrib import messages |
|
3 |
from django.utils.translation import ugettext_lazy as _ |
|
4 |
from django.views.generic import FormView |
|
5 | ||
6 |
from passerelle.utils.jsonresponse import APIError |
|
7 | ||
8 |
from .forms import SmsTestSendForm |
|
9 | ||
10 | ||
11 |
class SmsTestSendView(FormView): |
|
12 |
form_class = SmsTestSendForm |
|
13 |
template_name = 'passerelle/manage/messages_service_test_send.html' |
|
14 | ||
15 |
def get_instance(self): |
|
16 |
name = self.kwargs['connector'] |
|
17 |
slug = self.kwargs['slug'] |
|
18 |
model_name = '%sSMSGateway' % name.capitalize() |
|
19 |
model = apps.get_model(name, model_name) |
|
20 |
return model.objects.get(slug=slug) |
|
21 | ||
22 |
def get_success_url(self): |
|
23 |
instance = self.get_instance() |
|
24 |
return instance.get_absolute_url() |
|
25 | ||
26 |
def form_valid(self, form): |
|
27 |
instance = self.get_instance() |
|
28 |
number = form.cleaned_data['number'] |
|
29 |
sender = form.cleaned_data['sender'] |
|
30 |
message = form.cleaned_data['message'] |
|
31 |
try: |
|
32 |
number = instance.clean_numbers([number])[0] |
|
33 |
instance.send_msg(text=message, sender=sender, destinations=[number]) |
|
34 |
except APIError as exc: |
|
35 |
messages.error(self.request, _('Sending SMS fails: %s' % exc)) |
|
36 |
else: |
|
37 |
messages.success(self.request, _('An SMS was just sent')) |
|
38 |
return super(SmsTestSendView, self).form_valid(form) |
tests/test_sms.py | ||
---|---|---|
1 | 1 |
import isodate |
2 | 2 |
import mock |
3 | 3 |
import pytest |
4 | 4 |
from requests import RequestException |
5 | 5 | |
6 | 6 |
from django.contrib.contenttypes.models import ContentType |
7 |
from django.core.urlresolvers import reverse |
|
7 | 8 | |
8 | 9 |
from passerelle.apps.ovh.models import OVHSMSGateway |
9 | 10 |
from passerelle.base.models import ApiUser, AccessRight, Job |
10 | 11 |
from passerelle.sms.models import SMSResource, SMSLog |
11 | 12 |
from passerelle.utils.jsonresponse import APIError |
12 | 13 | |
13 | 14 |
from test_manager import login, admin_user |
14 | 15 | |
... | ... | |
204 | 205 |
url = connector.API_URL % {'serviceName': 'sms-test42', 'login': 'john'} |
205 | 206 |
with utils.mock_url(url, resp, 200) as mocked: |
206 | 207 |
connector.jobs() |
207 | 208 |
job = Job.objects.get(id=job_id) |
208 | 209 |
assert job.status == 'completed' |
209 | 210 | |
210 | 211 |
request = mocked.handlers[0].call['requests'][0] |
211 | 212 |
assert 'X-Ovh-Signature' in request.headers |
213 | ||
214 | ||
215 |
@pytest.mark.parametrize('connector', [OVHSMSGateway], indirect=True) |
|
216 |
def test_sms_test_send(admin_user, app, connector): |
|
217 |
url = '/%s/%s/' % (connector.get_connector_slug(), connector.slug) |
|
218 |
resp = app.get(url) |
|
219 |
link = resp.html.find('div', {'id': 'endpoints'}).find_all('a')[-1] |
|
220 |
assert 'Send a test message' not in link.text |
|
221 | ||
222 |
app = login(app) |
|
223 |
resp = app.get(url) |
|
224 |
link = resp.html.find('div', {'id': 'endpoints'}).find_all('a')[-1] |
|
225 |
assert 'Send a test message' in link.text |
|
226 |
assert link['href'] == reverse('sms-test-send', kwargs={ |
|
227 |
'connector': connector.get_connector_slug(), 'slug': connector.slug}) |
|
228 | ||
229 |
resp = app.get(link['href']) |
|
230 |
resp.form['number'] = '+33688888888' |
|
231 |
resp.form['sender'] = '+33699999999' |
|
232 |
resp.form['message'] = 'hello' |
|
233 |
with mock.patch.object(OVHSMSGateway, 'send_msg') as send_function: |
|
234 |
send_function.return_value = {} |
|
235 |
resp.form.submit() |
|
236 |
connector.jobs() |
|
237 |
assert send_function.call_args[1] == { |
|
238 |
'text': 'hello', 'sender': '+33699999999', 'destinations': ['0033688888888']} |
|
212 |
- |