0001-standardize-phonenumber-format-23443.patch
corbo/migrations/0011_auto_20180426_1334.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 |
from django.db import migrations |
|
5 | ||
6 |
from corbo.utils import format_phonenumber |
|
7 | ||
8 | ||
9 |
def format_sms_identifiers(apps, schema_editor): |
|
10 |
Subscription = apps.get_model('corbo', 'Subscription') |
|
11 |
uri = 'sms:' |
|
12 |
for subscription in Subscription.objects.filter(identifier__startswith=uri): |
|
13 |
_, phonenumber = subscription.identifier.split(':') |
|
14 |
subscription.identifier = uri + format_phonenumber(phonenumber) |
|
15 |
subscription.save() |
|
16 | ||
17 | ||
18 |
class Migration(migrations.Migration): |
|
19 | ||
20 |
dependencies = [ |
|
21 |
('corbo', '0010_broadcast_delivery_count'), |
|
22 |
] |
|
23 | ||
24 |
operations = [ |
|
25 |
migrations.RunPython(format_sms_identifiers, format_sms_identifiers), |
|
26 |
] |
corbo/models.py | ||
---|---|---|
11 | 11 |
from django.conf import settings |
12 | 12 |
from django.db import models |
13 | 13 |
from django.core.files.storage import DefaultStorage |
14 |
from django.core.exceptions import ValidationError |
|
14 | 15 |
from django.utils.translation import ugettext_lazy as _ |
15 | 16 | |
16 | 17 |
from ckeditor.fields import RichTextField |
... | ... | |
177 | 178 |
self.deliver_time = timezone.now() |
178 | 179 |
self.save() |
179 | 180 | |
180 | ||
181 | 181 |
class Meta: |
182 | 182 |
verbose_name = _('sent') |
183 | 183 |
ordering = ('-deliver_time',) |
... | ... | |
198 | 198 | |
199 | 199 |
class Meta: |
200 | 200 |
unique_together = ('category', 'identifier', 'uuid') |
201 | ||
202 |
def clean(self): |
|
203 |
if 'sms:' in self.identifier: |
|
204 |
uri, phonenumber = self.identifier.split(':') |
|
205 |
self.identifier = '%s:%s' % (uri, utils.format_phonenumber(phonenumber)) |
|
206 | ||
207 |
def save(self, *args, **kwargs): |
|
208 |
self.clean() |
|
209 |
return super(Subscription, self).save(*args, **kwargs) |
corbo/utils.py | ||
---|---|---|
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 | 17 |
import os |
18 |
import re |
|
18 | 19 |
import logging |
19 | 20 |
import requests |
20 | 21 |
import urlparse |
... | ... | |
103 | 104 |
else: |
104 | 105 |
logger.error('SMS send requested but no SMS gateway defined.') |
105 | 106 |
return sent |
107 | ||
108 | ||
109 |
def format_phonenumber(phonenumber): |
|
110 |
phonenumber = re.sub('\(.*?\)', '', phonenumber) |
|
111 |
phonenumber = re.sub('[^\d+]', '', phonenumber) |
|
112 |
if phonenumber: |
|
113 |
phonenumber = phonenumber[0] + re.sub('[^\d]', '', phonenumber[1:]) |
|
114 |
return phonenumber |
tests/conftest.py | ||
---|---|---|
131 | 131 |
return Tenant(domain_url=name, |
132 | 132 |
schema_name=name.replace('-', '_').replace('.', '_')) |
133 | 133 |
return make_tenant('corbo.example.net') |
134 | ||
135 | ||
136 |
@pytest.fixture(params=['06 10 20 30 40', '+33 6 10 20 30 40', |
|
137 |
'0033610203040', '+33 (0) 6 10 20 30 40', '0033+610203040+']) |
|
138 |
def phonenumber(request): |
|
139 |
return request.param |
tests/test_api.py | ||
---|---|---|
1 | 1 |
import pytest |
2 | ||
3 |
import urllib |
|
2 | 4 |
from uuid import uuid4 |
3 | 5 | |
4 | 6 | |
... | ... | |
70 | 72 | |
71 | 73 |
for identifier, name in channel_choices: |
72 | 74 |
for category in categories: |
73 |
uri = '%s:%s' % (identifier, uuid)
|
|
75 |
uri = '%s:%s' % (identifier, '00339988776655')
|
|
74 | 76 |
Subscription.objects.create(identifier=uri, uuid=uuid, category=category) |
75 | 77 |
resp = app.get(reverse('subscriptions'), params={'uuid': uuid}) |
76 | 78 |
assert len(resp.json['data']) == 2 |
... | ... | |
141 | 143 |
assert transport['id'] == 'mailto' |
142 | 144 |
assert transport['text'] == 'mailto' |
143 | 145 | |
144 |
def test_simple_sms_subscription(app, categories, user): |
|
146 |
def test_simple_sms_subscription(app, categories, user, phonenumber):
|
|
145 | 147 |
payload = {'category_id': 'alerts', 'transports': ['sms']} |
146 | 148 |
uuid = uuid4() |
147 |
url = '/api/subscribe/?uuid=%s&mobile=0607080900' % uuid |
|
149 |
url_params = urllib.urlencode({'uuid': uuid, 'mobile': phonenumber}) |
|
150 |
url = '/api/subscribe/?' + url_params |
|
148 | 151 |
app.authorization = ('Basic', ('john.doe', 'password')) |
149 | 152 |
resp = app.post_json(url, params=payload, status=200) |
153 |
assert Subscription.objects.get(uuid=uuid).identifier in ['sms:0610203040', 'sms:+33610203040', 'sms:0033610203040'] |
|
150 | 154 |
resp = app.get('/api/subscriptions/?uuid=%s' % uuid) |
151 | 155 |
data = resp.json['data'] |
152 | 156 |
print resp.json |
tests/test_data_migrations.py | ||
---|---|---|
1 |
import uuid |
|
2 | ||
3 |
import pytest |
|
4 | ||
5 |
from django.db import connection |
|
6 |
from django.db.migrations.executor import MigrationExecutor |
|
7 | ||
8 |
pytestmark = pytest.mark.django_db |
|
9 | ||
10 | ||
11 |
def test_subscription_sms_identifier_format_migration(): |
|
12 |
executor = MigrationExecutor(connection) |
|
13 |
app = 'corbo' |
|
14 |
migrate_from = [(app, '0009_auto_20170120_1533')] |
|
15 |
migrate_to = [(app, '0011_auto_20180426_1334')] |
|
16 |
executor.migrate(migrate_from) |
|
17 |
executor.loader.build_graph() |
|
18 |
old_apps = executor.loader.project_state(migrate_from).apps |
|
19 |
Category = old_apps.get_model('corbo', 'Category') |
|
20 |
Subscription = old_apps.get_model('corbo', 'Subscription') |
|
21 |
category = Category.objects.create(name='Science', slug='science') |
|
22 |
for identifier in ('sms:06 10 20 30 40', 'sms:+33 6 10 20 30 40', 'sms:0033610203040', |
|
23 |
'mailto:john@doe.com', 'sms:+33 (0) 6 10 20 30 40'): |
|
24 |
Subscription.objects.create(uuid=uuid.uuid4().hex, category=category, identifier=identifier) |
|
25 |
executor.migrate(migrate_to) |
|
26 |
executor.loader.build_graph() |
|
27 |
apps = executor.loader.project_state(migrate_from).apps |
|
28 |
Subscription = apps.get_model('corbo', 'Subscription') |
|
29 |
assert Subscription.objects.count() == 5 |
|
30 |
valid_sms_identifier = ['sms:0610203040', 'sms:+33610203040', 'sms:0033610203040'] |
|
31 |
for subscription in Subscription.objects.filter(identifier__startswith='sms:'): |
|
32 |
assert subscription.identifier in valid_sms_identifier |
|
0 |
- |