api: add sms subscriptions (#19846)

This commit is contained in:
Serghei Mihai 2017-11-02 00:52:34 +01:00
parent 5e8d93c858
commit 5591a1dc6c
2 changed files with 79 additions and 69 deletions

View File

@ -41,14 +41,13 @@ class NewslettersView(APIView):
class SubscriptionsView(APIView):
def get_subscriptions(self, email, uuid=None):
def get_subscriptions(self, uuid):
subscriptions = defaultdict(dict)
identifier = 'mailto:' + email
for s in Subscription.objects.filter(Q(identifier=identifier) | Q(uuid=uuid)):
for s in Subscription.objects.filter(uuid=uuid):
cat_id = s.category.pk
subscriptions[cat_id]['id'] = s.category.slug
subscriptions[cat_id]['text'] = s.category.name
transport_id, transport_name = identifier.split(':')
transport_id, transport_name = s.identifier.split(':')
transport = {'id': transport_id,
'text': transport_id}
if 'transports' in subscriptions[cat_id]:
@ -59,11 +58,7 @@ class SubscriptionsView(APIView):
return subscriptions.values()
@transaction.atomic
def update_subscriptions(self, category_slug, transports, email, uuid=None):
uuid = uuid or u''
identifier = u'mailto:'
if email:
identifier += email
def update_subscriptions(self, category_slug, transports, uuid, email=None, mobile=None):
try:
cat = Category.objects.get(slug=category_slug)
except Category.DoesNotExist:
@ -71,40 +66,42 @@ class SubscriptionsView(APIView):
subcriptions = cat.subscription_set
if email:
if 'mailto' in transports:
subcriptions.get_or_create(identifier=identifier, uuid=uuid)
if uuid:
subcriptions.exclude(uuid=uuid).filter(identifier=identifier).delete()
else:
subcriptions.filter(identifier=identifier).delete()
if 'mailto' in transports:
if email:
subcriptions.get_or_create(identifier='mailto:%s' % email, uuid=uuid)
else:
subcriptions.filter(uuid=uuid, identifier__startswith='mailto:').delete()
if 'sms' in transports:
if mobile:
subcriptions.get_or_create(identifier='sms:%s' % mobile, uuid=uuid)
else:
subcriptions.filter(uuid=uuid, identifier__startswith='sms:').delete()
def get(self, request):
email = request.GET.get('email')
uuid = request.GET.get('uuid')
if not email:
raise PermissionDenied('Email parameter required')
return Response({'data': self.get_subscriptions(email, uuid)})
if not uuid:
raise PermissionDenied('Uuid parameter required')
return Response({'data': self.get_subscriptions( uuid)})
def post(self, request):
email = request.GET.get('email')
uuid = request.GET.get('uuid')
if not email:
raise PermissionDenied('Email parameter required')
email = request.GET.get('email')
mobile = request.GET.get('mobile')
if not uuid:
raise PermissionDenied('Uuid parameter required')
data = json.loads(request.body)
for subscription in data:
self.update_subscriptions(subscription['id'], subscription['transports'],
email, uuid)
uuid, email, mobile)
return Response({'data': True})
def delete(self, request):
email = request.GET.get('email')
uuid = request.GET.get('uuid')
if not email:
raise PermissionDenied('Email parameter required')
for subscription in self.get_subscriptions(email):
self.update_subscriptions(subscription['id'], [], email, uuid)
if not uuid:
raise PermissionDenied('Uuid parameter required')
for subscription in self.get_subscriptions(uuid):
self.update_subscriptions(subscription['id'], [], uuid)
return Response({'data': True})
@ -113,14 +110,13 @@ class SubscribeView(SubscriptionsView):
def post(self, request):
email = request.GET.get('email')
mobile = request.GET.get('mobile')
uuid = request.GET.get('uuid')
if not email:
raise PermissionDenied('Email parameter required')
if not uuid:
raise PermissionDenied('Uuid parameter required')
data = json.loads(request.body)
category_id = data['category_id']
transport = ('mailto',)
self.update_subscriptions(category_id, transport, email, uuid)
self.update_subscriptions(data['category_id'], data['transports'], uuid,
email, mobile)
return Response({'data': True})

View File

@ -62,50 +62,46 @@ def test_get_newsletters(app, categories, announces, user):
assert category['transports'] == [{'id': 'mailto', 'text': 'Email'}, {'id': 'sms', 'text': 'SMS'}]
def test_get_subscriptions_by_email(app, categories, announces, user):
def test_get_subscriptions(app, categories, announces, user):
resp = app.get(reverse('subscriptions'), status=403)
foo = 'foo@example.com'
resp = app.get(reverse('subscriptions'), params={'email': foo}, status=403)
uuid = str(uuid4())
resp = app.get(reverse('subscriptions'), params={'uuid': uuid}, status=403)
app.authorization = ('Basic', ('john.doe', 'password'))
for identifier, name in channel_choices[:1]:
for identifier, name in channel_choices:
for category in categories:
uri = '%s:%s' % (identifier, foo)
Subscription.objects.create(identifier=uri, category=category)
resp = app.get(reverse('subscriptions'), params={'email': foo})
assert 'data' in resp.json
data = resp.json['data']
for d in data:
assert d['id'] in [category.slug for category in categories]
assert d['text'] in [category.name for category in categories]
for t in d['transports']:
assert t['id'] == identifier
uri = '%s:%s' % (identifier, uuid)
Subscription.objects.create(identifier=uri, uuid=uuid, category=category)
resp = app.get(reverse('subscriptions'), params={'uuid': uuid})
assert len(resp.json['data']) == 2
for d in resp.json['data']:
assert d['id'] in [category.slug for category in categories]
assert d['text'] in [category.name for category in categories]
assert identifier in [transport['id'] for transport in d['transports']]
def test_update_subscriptions(app, categories, announces, user):
params = urlencode({'email': 'foo@example.com',
'uuid': str(uuid4())})
uuid = uuid4()
app.authorization = ('Basic', ('john.doe', 'password'))
subscriptions_url = reverse('subscriptions') + '?' + params
subscriptions_url = '/api/subscriptions/?uuid=%s&email=user@example.com&mobile=0607080900' % uuid
for category in categories:
transports = []
for identifier, name in channel_choices[:1]:
for identifier, name in channel_choices:
transports.append(identifier)
category_id = str(category.id)
subscriptions = [{'id': category_id,
subscriptions = [{'id': category.slug,
'text': category.name,
'transports': transports}]
resp = app.post_json(subscriptions_url, params=subscriptions)
if resp.json['data']:
resp = app.get(subscriptions_url)
for cat in resp.json['data']:
if cat['id'] == category_id:
sub_transports = [c['id'] for c in cat['transports']]
assert sub_transports == transports
resp = app.get(subscriptions_url)
assert len(resp.json['data']) >= 1
for cat in resp.json['data']:
if cat['id'] == category.slug:
sub_transports = [c['id'] for c in cat['transports']]
assert sub_transports == transports
def test_delete_subscriptions(app, categories, announces, user):
params = urlencode({'email': 'foo@example.com', 'uuid': str(uuid4())})
params = urlencode({'uuid': str(uuid4())})
subscriptions_url = reverse('subscriptions') + '?' + params
resp = app.delete(subscriptions_url, status=403)
app.authorization = ('Basic', ('john.doe', 'password'))
@ -115,9 +111,10 @@ def test_delete_subscriptions(app, categories, announces, user):
assert resp.json['data'] == []
def test_simple_subscription(app, categories, user):
payload = {'category_id': 'alerts'}
url = '/api/subscribe/?email=john@example.net'
def test_simple_email_subscription(app, categories, user):
payload = {'category_id': 'alerts', 'transports': ['mailto']}
uuid = uuid4()
url = '/api/subscribe/?uuid=%s&email=john@example.net' % uuid
# anonymous
resp = app.post_json(url, params=payload, status=403)
@ -129,11 +126,11 @@ def test_simple_subscription(app, categories, user):
assert resp.json['data'] is True
# with wrong method
resp = app.get('/api/subscribe/?email=john@example.net', status=405)
resp = app.get('/api/subscribe/?uuid=%s&email=john@example.net' % uuid, status=405)
assert resp.json['detail'] == 'Method "GET" not allowed.'
# right method on right url
resp = app.get('/api/subscriptions/?email=john@example.net', status=200)
resp = app.get('/api/subscriptions/?uuid=%s' % uuid)
data = resp.json['data']
assert len(data) == 1
@ -143,3 +140,20 @@ def test_simple_subscription(app, categories, user):
transport = data[0]['transports'][0]
assert transport['id'] == 'mailto'
assert transport['text'] == 'mailto'
def test_simple_sms_subscription(app, categories, user):
payload = {'category_id': 'alerts', 'transports': ['sms']}
uuid = uuid4()
url = '/api/subscribe/?uuid=%s&mobile=0607080900' % uuid
app.authorization = ('Basic', ('john.doe', 'password'))
resp = app.post_json(url, params=payload, status=200)
resp = app.get('/api/subscriptions/?uuid=%s' % uuid)
data = resp.json['data']
print resp.json
assert len(data) == 1
assert data[0]['id'] == 'alerts'
assert data[0]['text'] == 'Alerts'
assert len(data[0]['transports']) == 1
transport = data[0]['transports'][0]
assert transport['id'] == 'sms'
assert transport['text'] == 'sms'