Projet

Général

Profil

0001-api-add-sms-subscriptions-19846.patch

Serghei Mihai (congés, retour 15/05), 15 novembre 2017 11:32

Télécharger (11,1 ko)

Voir les différences:

Subject: [PATCH] api: add sms subscriptions (#19846)

 corbo/api_views.py | 68 ++++++++++++++++++++++------------------------
 tests/test_api.py  | 80 ++++++++++++++++++++++++++++++++----------------------
 2 files changed, 79 insertions(+), 69 deletions(-)
corbo/api_views.py
41 41

  
42 42
class SubscriptionsView(APIView):
43 43

  
44
    def get_subscriptions(self, email, uuid=None):
44
    def get_subscriptions(self, uuid):
45 45
        subscriptions = defaultdict(dict)
46
        identifier = 'mailto:' + email
47
        for s in Subscription.objects.filter(Q(identifier=identifier) | Q(uuid=uuid)):
46
        for s in Subscription.objects.filter(uuid=uuid):
48 47
            cat_id = s.category.pk
49 48
            subscriptions[cat_id]['id'] = s.category.slug
50 49
            subscriptions[cat_id]['text'] = s.category.name
51
            transport_id, transport_name = identifier.split(':')
50
            transport_id, transport_name = s.identifier.split(':')
52 51
            transport = {'id': transport_id,
53 52
                         'text': transport_id}
54 53
            if 'transports' in subscriptions[cat_id]:
......
59 58
        return subscriptions.values()
60 59

  
61 60
    @transaction.atomic
62
    def update_subscriptions(self, category_slug, transports, email, uuid=None):
63
        uuid = uuid or u''
64
        identifier = u'mailto:'
65
        if email:
66
            identifier += email
61
    def update_subscriptions(self, category_slug, transports, uuid, email=None, mobile=None):
67 62
        try:
68 63
            cat = Category.objects.get(slug=category_slug)
69 64
        except Category.DoesNotExist:
......
71 66

  
72 67
        subcriptions = cat.subscription_set
73 68

  
74
        if email:
75
            if 'mailto' in transports:
76
                subcriptions.get_or_create(identifier=identifier, uuid=uuid)
77
                if uuid:
78
                    subcriptions.exclude(uuid=uuid).filter(identifier=identifier).delete()
79
            else:
80
                subcriptions.filter(identifier=identifier).delete()
69
        if 'mailto' in transports:
70
            if email:
71
                subcriptions.get_or_create(identifier='mailto:%s' % email, uuid=uuid)
72
        else:
73
            subcriptions.filter(uuid=uuid, identifier__startswith='mailto:').delete()
74

  
75
        if 'sms' in transports:
76
            if mobile:
77
                subcriptions.get_or_create(identifier='sms:%s' % mobile, uuid=uuid)
78
        else:
79
            subcriptions.filter(uuid=uuid, identifier__startswith='sms:').delete()
81 80

  
82 81
    def get(self, request):
83
        email = request.GET.get('email')
84 82
        uuid = request.GET.get('uuid')
85
        if not email:
86
            raise PermissionDenied('Email parameter required')
87
        return Response({'data': self.get_subscriptions(email, uuid)})
83
        if not uuid:
84
            raise PermissionDenied('Uuid parameter required')
85
        return Response({'data': self.get_subscriptions( uuid)})
88 86

  
89 87
    def post(self, request):
90
        email = request.GET.get('email')
91 88
        uuid = request.GET.get('uuid')
92
        if not email:
93
            raise PermissionDenied('Email parameter required')
89
        email = request.GET.get('email')
90
        mobile = request.GET.get('mobile')
91
        if not uuid:
92
            raise PermissionDenied('Uuid parameter required')
94 93
        data = json.loads(request.body)
95 94
        for subscription in data:
96 95
            self.update_subscriptions(subscription['id'], subscription['transports'],
97
                                      email, uuid)
96
                                      uuid, email, mobile)
98 97
        return Response({'data': True})
99 98

  
100 99
    def delete(self, request):
101
        email = request.GET.get('email')
102 100
        uuid = request.GET.get('uuid')
103
        if not email:
104
            raise PermissionDenied('Email parameter required')
105

  
106
        for subscription in self.get_subscriptions(email):
107
            self.update_subscriptions(subscription['id'], [], email, uuid)
101
        if not uuid:
102
            raise PermissionDenied('Uuid parameter required')
103
        for subscription in self.get_subscriptions(uuid):
104
            self.update_subscriptions(subscription['id'], [], uuid)
108 105
        return Response({'data': True})
109 106

  
110 107

  
......
113 110

  
114 111
    def post(self, request):
115 112
        email = request.GET.get('email')
113
        mobile = request.GET.get('mobile')
116 114
        uuid = request.GET.get('uuid')
117
        if not email:
118
            raise PermissionDenied('Email parameter required')
115
        if not uuid:
116
            raise PermissionDenied('Uuid parameter required')
119 117
        data = json.loads(request.body)
120 118

  
121
        category_id = data['category_id']
122
        transport = ('mailto',)
123

  
124
        self.update_subscriptions(category_id, transport, email, uuid)
119
        self.update_subscriptions(data['category_id'], data['transports'], uuid,
120
                                  email, mobile)
125 121

  
126 122
        return Response({'data': True})
tests/test_api.py
62 62
        assert category['transports'] == [{'id': 'mailto', 'text': 'Email'}, {'id': 'sms', 'text': 'SMS'}]
63 63

  
64 64

  
65
def test_get_subscriptions_by_email(app, categories, announces, user):
65
def test_get_subscriptions(app, categories, announces, user):
66 66
    resp = app.get(reverse('subscriptions'), status=403)
67
    foo = 'foo@example.com'
68
    resp = app.get(reverse('subscriptions'), params={'email': foo}, status=403)
67
    uuid = str(uuid4())
68
    resp = app.get(reverse('subscriptions'), params={'uuid': uuid}, status=403)
69 69
    app.authorization = ('Basic', ('john.doe', 'password'))
70
    for identifier, name in channel_choices[:1]:
70

  
71
    for identifier, name in channel_choices:
71 72
        for category in categories:
72
            uri = '%s:%s' % (identifier, foo)
73
            Subscription.objects.create(identifier=uri, category=category)
74
            resp = app.get(reverse('subscriptions'), params={'email': foo})
75
            assert 'data' in resp.json
76
            data = resp.json['data']
77
            for d in data:
78
                assert d['id'] in [category.slug for category in categories]
79
                assert d['text'] in [category.name for category in categories]
80
                for t in d['transports']:
81
                    assert t['id'] == identifier
73
            uri = '%s:%s' % (identifier, uuid)
74
            Subscription.objects.create(identifier=uri, uuid=uuid, category=category)
75
        resp = app.get(reverse('subscriptions'), params={'uuid': uuid})
76
        assert len(resp.json['data']) == 2
77
        for d in resp.json['data']:
78
            assert d['id'] in [category.slug for category in categories]
79
            assert d['text'] in [category.name for category in categories]
80
            assert identifier in [transport['id'] for transport in d['transports']]
82 81

  
83 82

  
84 83
def test_update_subscriptions(app, categories, announces, user):
85
    params = urlencode({'email': 'foo@example.com',
86
                        'uuid': str(uuid4())})
84
    uuid = uuid4()
87 85
    app.authorization = ('Basic', ('john.doe', 'password'))
88
    subscriptions_url = reverse('subscriptions') + '?' + params
86
    subscriptions_url = '/api/subscriptions/?uuid=%s&email=user@example.com&mobile=0607080900' % uuid
89 87
    for category in categories:
90 88
        transports = []
91
        for identifier, name in channel_choices[:1]:
89
        for identifier, name in channel_choices:
92 90
            transports.append(identifier)
93
            category_id = str(category.id)
94
            subscriptions = [{'id': category_id,
91
            subscriptions = [{'id': category.slug,
95 92
                              'text': category.name,
96 93
                              'transports': transports}]
97 94
            resp = app.post_json(subscriptions_url, params=subscriptions)
98
            if resp.json['data']:
99
                resp = app.get(subscriptions_url)
100

  
101
                for cat in resp.json['data']:
102
                    if cat['id'] == category_id:
103
                        sub_transports = [c['id'] for c in cat['transports']]
104
                        assert sub_transports == transports
95
            resp = app.get(subscriptions_url)
96
            assert len(resp.json['data']) >= 1
97
            for cat in resp.json['data']:
98
                if cat['id'] == category.slug:
99
                    sub_transports = [c['id'] for c in cat['transports']]
100
                    assert sub_transports == transports
105 101

  
106 102

  
107 103
def test_delete_subscriptions(app, categories, announces, user):
108
    params = urlencode({'email': 'foo@example.com', 'uuid': str(uuid4())})
104
    params = urlencode({'uuid': str(uuid4())})
109 105
    subscriptions_url = reverse('subscriptions') + '?' + params
110 106
    resp = app.delete(subscriptions_url, status=403)
111 107
    app.authorization = ('Basic', ('john.doe', 'password'))
......
115 111
        assert resp.json['data'] == []
116 112

  
117 113

  
118
def test_simple_subscription(app, categories, user):
119
    payload = {'category_id': 'alerts'}
120
    url = '/api/subscribe/?email=john@example.net'
114
def test_simple_email_subscription(app, categories, user):
115
    payload = {'category_id': 'alerts', 'transports': ['mailto']}
116
    uuid = uuid4()
117
    url = '/api/subscribe/?uuid=%s&email=john@example.net' % uuid
121 118

  
122 119
    # anonymous
123 120
    resp = app.post_json(url, params=payload, status=403)
......
129 126
    assert resp.json['data'] is True
130 127

  
131 128
    # with wrong method
132
    resp = app.get('/api/subscribe/?email=john@example.net', status=405)
129
    resp = app.get('/api/subscribe/?uuid=%s&email=john@example.net' % uuid, status=405)
133 130
    assert resp.json['detail'] == 'Method "GET" not allowed.'
134 131

  
135 132
    # right method on right url
136
    resp = app.get('/api/subscriptions/?email=john@example.net', status=200)
133
    resp = app.get('/api/subscriptions/?uuid=%s' % uuid)
137 134

  
138 135
    data = resp.json['data']
139 136
    assert len(data) == 1
......
143 140
    transport = data[0]['transports'][0]
144 141
    assert transport['id'] == 'mailto'
145 142
    assert transport['text'] == 'mailto'
143

  
144
def test_simple_sms_subscription(app, categories, user):
145
    payload = {'category_id': 'alerts', 'transports': ['sms']}
146
    uuid = uuid4()
147
    url = '/api/subscribe/?uuid=%s&mobile=0607080900' % uuid
148
    app.authorization = ('Basic', ('john.doe', 'password'))
149
    resp = app.post_json(url, params=payload, status=200)
150
    resp = app.get('/api/subscriptions/?uuid=%s' % uuid)
151
    data = resp.json['data']
152
    print resp.json
153
    assert len(data) == 1
154
    assert data[0]['id'] == 'alerts'
155
    assert data[0]['text'] == 'Alerts'
156
    assert len(data[0]['transports']) == 1
157
    transport = data[0]['transports'][0]
158
    assert transport['id'] == 'sms'
159
    assert transport['text'] == 'sms'
146
-