Completed
Push — master ( d1e883...1f56b4 )
by
unknown
01:28
created

LiveStatistics.test_daily_list()   A

Complexity

Conditions 1

Size

Total Lines 10

Duplication

Lines 10
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
c 0
b 0
f 0
dl 10
loc 10
rs 9.4285
1
# coding: utf8
2
3
"""
4
This software is licensed under the Apache 2 license, quoted below.
5
6
Copyright 2014 Crystalnix Limited
7
8
Licensed under the Apache License, Version 2.0 (the "License"); you may not
9
use this file except in compliance with the License. You may obtain a copy of
10
the License at
11
12
    http://www.apache.org/licenses/LICENSE-2.0
13
14
Unless required by applicable law or agreed to in writing, software
15
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17
License for the specific language governing permissions and limitations under
18
the License.
19
"""
20
from __future__ import unicode_literals
21
from builtins import bytes, range
22
23
import base64
24
from datetime import datetime, timedelta
25
from uuid import UUID
26
27
from django.core.urlresolvers import reverse
28
from django.contrib.auth import get_user_model
29
from django.core.files.uploadedfile import SimpleUploadedFile
30
from django.conf import settings
31
32
from lxml.builder import E
33
from rest_framework import status
34
from rest_framework.test import APITestCase, APIClient
35
from bitmapist import mark_event
36
from freezegun import freeze_time
37
import pytz
38
39
from omaha_server.utils import is_private
40
from omaha.statistics import userid_counting, get_users_versions, get_channel_statistics
41
from omaha.utils import redis
42
from omaha.serializers import (
43
    AppSerializer,
44
    DataSerializer,
45
    PlatformSerializer,
46
    ChannelSerializer,
47
    VersionSerializer,
48
    ActionSerializer,
49
    StatisticsMonthsSerializer,
50
    ServerVersionSerializer,
51
)
52
from omaha.factories import ApplicationFactory, DataFactory, PlatformFactory, ChannelFactory, VersionFactory, ActionFactory
53
from omaha.models import Application, Data, Channel, Platform, Version, Action
54
from omaha.tests import fixtures
55
from omaha.tests.utils import temporary_media_root, create_app_xml
56
from sparkle.models import SparkleVersion
57
from sparkle.statistics import userid_counting as mac_userid_counting
58
User = get_user_model()
59
60
61
class BaseTest(object):
62
    url = None
63
    url_args = ()
64
    url_detail = None
65
    factory = None
66
    serializer = None
67
    maxDiff = None
68
    is_private = True
69
70
    def _is_private(self):
71
        if not self.is_private and not settings.IS_PRIVATE:
72
            return True
73
        elif self.is_private and settings.IS_PRIVATE:
74
            return True
75
        else:
76
            return False
77
78
    def setUp(self):
79
        self.objects = self.factory.create_batch(10)
80
        self.user = User.objects.create_user(username='test', password='secret', email='[email protected]')
81
        self.client.credentials(
82
            HTTP_AUTHORIZATION='Basic %s' % base64.b64encode(bytes('{}:{}'.format('test', 'secret'), 'utf8')).decode())
83
84
    def test_unauthorized(self):
85
        if not self._is_private():
86
            return
87
        client = APIClient()
88
        response = client.get(reverse(self.url, args=self.url_args), format='json')
89
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
90
91
    def test_list(self):
92
        if not self._is_private():
93
            return
94
        response = self.client.get(reverse(self.url, args=self.url_args), format='json')
95
        self.assertEqual(response.status_code, status.HTTP_200_OK)
96
        self.assertEqual(len(response.data), 10)
97
        self.assertEqual(self.serializer(self.objects, many=True).data, response.data[::-1])
98
99
    def test_detail(self):
100
        if not self._is_private():
101
            return
102
        obj = self.objects[0]
103
        url = reverse(self.url_detail, kwargs=dict(pk=obj.pk))
104
105
        response = self.client.get(url, format='json')
106
        self.assertEqual(response.status_code, status.HTTP_200_OK)
107
        self.assertDictEqual(response.data, self.serializer(obj).data)
108
109
110
class AppTest(BaseTest, APITestCase):
111
    url = 'application-list'
112
    url_detail = 'application-detail'
113
    factory = ApplicationFactory
114
    serializer = AppSerializer
115
116
    @is_private()
117
    def test_create(self):
118
        data = dict(id='test_id', name='test_name', data_set=[])
119
        response = self.client.post(reverse(self.url
120
                                            ), data, format='json')
121
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
122
        obj = Application.objects.get(id=response.data['id'])
123
        self.assertEqual(response.data, self.serializer(obj).data)
124
125
    @is_private()
126
    def test_update(self):
127
        data = dict(id='test_id', name='test_name', data_set=[])
128
        response = self.client.post(reverse(self.url), data, format='json')
129
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
130
        obj_id = response.data['id']
131
        obj = Application.objects.get(id=obj_id)
132
        self.assertEqual(obj.name, 'test_name')
133
        url = reverse(self.url_detail, kwargs=dict(pk=obj_id))
134
        response = self.client.patch(url, dict(name='test_other_name'))
135
        self.assertEqual(response.status_code, status.HTTP_200_OK)
136
        obj = Application.objects.get(id=obj_id)
137
        self.assertEqual(obj.name, 'test_other_name')
138
139
140 View Code Duplication
class DataTest(BaseTest, APITestCase):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
141
    url = 'data-list'
142
    url_detail = 'data-detail'
143
    factory = DataFactory
144
    serializer = DataSerializer
145
146
    @is_private()
147
    def test_create(self):
148
        app = ApplicationFactory.create()
149
        data = dict(name=0, app=app.pk)
150
        response = self.client.post(reverse(self.url), data, format='json')
151
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
152
        obj = Data.objects.get(id=response.data['id'])
153
        self.assertEqual(response.data, self.serializer(obj).data)
154
155
    @is_private()
156
    def test_update(self):
157
        app = ApplicationFactory.create()
158
        data = dict(name=0, app=app.pk)
159
        response = self.client.post(reverse(self.url), data, format='json')
160
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
161
        obj_id = response.data['id']
162
        obj = Data.objects.get(id=obj_id)
163
        self.assertEqual(obj.name, 0)
164
        url = reverse(self.url_detail, kwargs=dict(pk=obj_id))
165
        response = self.client.patch(url, dict(name=1))
166
        self.assertEqual(response.status_code, status.HTTP_200_OK)
167
        obj = Data.objects.get(id=obj_id)
168
        self.assertEqual(obj.name, 1)
169
170
171 View Code Duplication
class PlatformTest(BaseTest, APITestCase):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
172
    url = 'platform-list'
173
    url_detail = 'platform-detail'
174
    factory = PlatformFactory
175
    serializer = PlatformSerializer
176
177
    @is_private()
178
    def test_list(self):
179
        super(PlatformTest, self).test_list()
180
181
    @is_private()
182
    def test_create(self):
183
        data = dict(name='test_name')
184
        response = self.client.post(reverse(self.url), data, format='json')
185
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
186
        obj = Platform.objects.get(id=response.data['id'])
187
        self.assertEqual(response.data, self.serializer(obj).data)
188
189
    @is_private()
190
    def test_create(self):
191
        data = dict(name='test_name')
192
        response = self.client.post(reverse(self.url), data, format='json')
193
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
194
        obj_id = response.data['id']
195
        obj = Platform.objects.get(id=obj_id)
196
        self.assertEqual(obj.name, 'test_name')
197
        url = reverse(self.url_detail, kwargs=dict(pk=obj_id))
198
        response = self.client.patch(url, dict(name='test_name2'))
199
        self.assertEqual(response.status_code, status.HTTP_200_OK)
200
        obj = Platform.objects.get(id=obj_id)
201
        self.assertEqual(obj.name, 'test_name2')
202
203
204 View Code Duplication
class ChannelTest(BaseTest, APITestCase):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
205
    url = 'channel-list'
206
    url_detail = 'channel-detail'
207
    factory = ChannelFactory
208
    serializer = ChannelSerializer
209
210
    @is_private()
211
    def test_create(self):
212
        data = dict(name='test_name')
213
        response = self.client.post(reverse(self.url), data, format='json')
214
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
215
        obj = Channel.objects.get(id=response.data['id'])
216
        self.assertEqual(response.data, self.serializer(obj).data)
217
218
    @is_private()
219
    def test_update(self):
220
        data = dict(name='test_name')
221
        response = self.client.post(reverse(self.url), data, format='json')
222
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
223
        obj_id = response.data['id']
224
        obj = Channel.objects.get(id=obj_id)
225
        self.assertEqual(response.data, self.serializer(obj).data)
226
        url = reverse(self.url_detail, kwargs=dict(pk=obj_id))
227
        response = self.client.patch(url, dict(name='test_name2'))
228
        self.assertEqual(response.status_code, status.HTTP_200_OK)
229
        obj = Channel.objects.get(id=obj_id)
230
        self.assertEqual(obj.name, 'test_name2')
231
232
class VersionTest(BaseTest, APITestCase):
233
    url = 'version-list'
234
    url_detail = 'version-detail'
235
    factory = VersionFactory
236
    serializer = VersionSerializer
237
238
    @is_private()
239
    @temporary_media_root(MEDIA_URL='http://cache.pack.google.com/edgedl/chrome/install/782.112/')
240
    def test_detail(self):
241
        super(VersionTest, self).test_detail()
242
243
    @is_private()
244
    @temporary_media_root(MEDIA_URL='http://cache.pack.google.com/edgedl/chrome/install/782.112/')
245
    def test_list(self):
246
        super(VersionTest, self).test_list()
247
248 View Code Duplication
    @is_private()
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
249
    @temporary_media_root(MEDIA_URL='http://cache.pack.google.com/edgedl/chrome/install/782.112/')
250
    def test_create(self):
251
        data = dict(
252
            app=ApplicationFactory.create().id,
253
            platform=PlatformFactory.create().id,
254
            channel=ChannelFactory.create().id,
255
            version='1.2.3.4',
256
            file=SimpleUploadedFile("chrome.exe", b'content'),
257
        )
258
        response = self.client.post(reverse(self.url), data)
259
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
260
        version = Version.objects.get(id=response.data['id'])
261
        self.assertEqual(response.data, self.serializer(version).data)
262
        self.assertEqual(version.file_size, len(b'content'))
263
        self.assertTrue(version.is_enabled)
264
265
    @is_private()
266
    @temporary_media_root(MEDIA_URL='http://cache.pack.google.com/edgedl/chrome/install/782.112/')
267
    def test_update(self):
268
        data = dict(
269
            app=ApplicationFactory.create().id,
270
            platform=PlatformFactory.create().id,
271
            channel=ChannelFactory.create().id,
272
            version='1.2.3.4',
273
            file=SimpleUploadedFile("chrome.exe", b'content'),
274
            is_enabled=False,
275
        )
276
        response = self.client.post(reverse(self.url), data)
277
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
278
        obj_id = response.data['id']
279
        version = Version.objects.get(id=obj_id)
280
        self.assertEqual(version.file_size, len(b'content'))
281
        self.assertFalse(version.is_enabled)
282
        url = reverse(self.url_detail, kwargs=dict(pk=obj_id))
283
        response = self.client.patch(url, dict(is_enabled=True))
284
        self.assertEqual(response.status_code, status.HTTP_200_OK)
285
        version = Version.objects.get(id=obj_id)
286
        self.assertEqual(version.file_size, len(b'content'))
287
        self.assertTrue(version.is_enabled)
288
289
290 View Code Duplication
class ActionTest(BaseTest, APITestCase):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
291
    url = 'action-list'
292
    url_detail = 'action-detail'
293
    factory = ActionFactory
294
    serializer = ActionSerializer
295
296
    @is_private()
297
    def test_create(self):
298
        version = VersionFactory.create()
299
        data = dict(event=1, version=version.pk)
300
        response = self.client.post(reverse(self.url), data, format='json')
301
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
302
        obj = Action.objects.get(id=response.data['id'])
303
        self.assertEqual(response.data, self.serializer(obj).data)
304
305
    @is_private()
306
    def test_update(self):
307
        version = VersionFactory.create()
308
        data = dict(event=1, version=version.pk)
309
        response = self.client.post(reverse(self.url), data, format='json')
310
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
311
        obj_id = response.data['id']
312
        obj = Action.objects.get(id=obj_id)
313
        self.assertEqual(response.data, self.serializer(obj).data)
314
        url = reverse(self.url_detail, kwargs=dict(pk=obj_id))
315
        response = self.client.patch(url, dict(event=2))
316
        self.assertEqual(response.status_code, status.HTTP_200_OK)
317
        obj = Action.objects.get(id=obj_id)
318
        self.assertEqual(obj.event, 2)
319
320
321
class LiveStatistics(APITestCase):
322
    maxDiff = None
323
324
    def _generate_fake_statistics(self):
325
        date = datetime(2016, 2, 13, 0)
326
        for i in range(self.n_hours):
327
            for id in range(0, i):
328
                mark_event('request:app:win:2.0.0.0', id, now=date, track_hourly=True)
329
                mark_event('request:app:mac:4.0.0.1', id, now=date, track_hourly=True)
330
            for id in range(i, self.n_hours):
331
                mark_event('request:app:win:1.0.0.0', id, now=date, track_hourly=True)
332
                mark_event('request:app:mac:3.0.0.0', id, now=date, track_hourly=True)
333
            date += timedelta(hours=1)
334
335
    def setUp(self):
336
        self.user = User.objects.create_user(username='test', password='secret', email='[email protected]')
337
        self.client.credentials(
338
            HTTP_AUTHORIZATION='Basic %s' % base64.b64encode(bytes('{}:{}'.format('test', 'secret'), 'utf8')).decode())
339
340
        redis.flushdb()
341
        self.app = Application.objects.create(id='app', name='app')
342
        self.channel = Channel.objects.create(name='stable')
343
        self.platform = Platform.objects.create(name='win')
344
        self.version1 = Version.objects.create(
345
            app=self.app,
346
            platform=self.platform,
347
            channel=self.channel,
348
            version='1.0.0.0',
349
            file=SimpleUploadedFile('./chrome_installer.exe', False))
350
351
        self.version2 = Version.objects.create(
352
            app=self.app,
353
            platform=self.platform,
354
            channel=self.channel,
355
            version='2.0.0.0',
356
            file=SimpleUploadedFile('./chrome_installer.exe', False))
357
358
        self.sparkle_version1 = SparkleVersion.objects.create(
359
            app=self.app,
360
            channel=self.channel,
361
            version='0.0',
362
            short_version='3.0.0.0',
363
            file=SimpleUploadedFile('./chrome_installer.dmg', False))
364
365
        self.sparkle_version2 = SparkleVersion.objects.create(
366
            app=self.app,
367
            channel=self.channel,
368
            version='0.1',
369
            short_version='4.0.0.1',
370
            file=SimpleUploadedFile('./chrome_installer.dmg', False))
371
372
        self.n_hours = 36
373
        self._generate_fake_statistics()
374
375
        hours = [datetime(2016, 2, 13, 0, tzinfo=pytz.UTC) + timedelta(hours=hour)
376
                 for hour in range(self.n_hours)]
377
        self.win_statistics = [('1.0.0.0', [[hour.strftime("%Y-%m-%dT%H:%M:%S.%fZ"), self.n_hours - i]
378
                                            for (i, hour)in enumerate(hours)])]
379
        self.win_statistics.append(('2.0.0.0', [[hour.strftime("%Y-%m-%dT%H:%M:%S.%fZ"), i]
380
                                                for (i, hour)in enumerate(hours)]))
381
382
        self.mac_statistics = [('3.0.0.0', [[hour.strftime("%Y-%m-%dT%H:%M:%S.%fZ"), self.n_hours - i]
383
                                            for (i, hour)in enumerate(hours)])]
384
        self.mac_statistics.append(('4.0.0.1', [[hour.strftime("%Y-%m-%dT%H:%M:%S.%fZ"), i]
385
                                                for (i, hour)in enumerate(hours)]))
386
        self.data = {}
387
        self.data['hourly'] = dict(data=dict(win=dict(self.win_statistics),
388
                                             mac=dict(self.mac_statistics)))
389
        self.data['daily'] = dict(data=dict(win={'1.0.0.0': [['2016-02-13T00:00:00.000000Z', 36], ['2016-02-14T00:00:00.000000Z', 12]],
390
                                                 '2.0.0.0': [['2016-02-13T00:00:00.000000Z', 23], ['2016-02-14T00:00:00.000000Z', 35]]},
391
                                            mac={'4.0.0.1': [['2016-02-13T00:00:00.000000Z', 23], ['2016-02-14T00:00:00.000000Z', 35]],
392
                                                 '3.0.0.0': [['2016-02-13T00:00:00.000000Z', 36], ['2016-02-14T00:00:00.000000Z', 12]]}))
393
394
    @is_private()
395
    def test_unauthorized(self):
396
        client = APIClient()
397
        response = client.get(reverse('api-statistics-live', args=('app',)), format='json')
398
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
399
400 View Code Duplication
    @freeze_time("2016-02-16")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
401
    @is_private()
402
    def test_hourly_list(self):
403
        start = datetime(2016, 2, 13, 0)
404
        end = start + timedelta(hours=self.n_hours-1)
405
        response = self.client.get(reverse('api-statistics-live', args=('app',)),
406
                                   dict(start=start.isoformat(), end=end.isoformat()),
407
                                   format='json')
408
        self.assertEqual(response.status_code, status.HTTP_200_OK)
409
        self.assertDictEqual(StatisticsMonthsSerializer(self.data['hourly']).data, response.data)
410
411 View Code Duplication
    @freeze_time("2016-03-16")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
412
    @is_private()
413
    def test_daily_list(self):
414
        start = datetime(2016, 2, 13, 0)
415
        end = start + timedelta(hours=self.n_hours-1)
416
        response = self.client.get(reverse('api-statistics-live', args=('app',)),
417
                                   dict(start=start.isoformat(), end=end.isoformat()),
418
                                   format='json')
419
        self.assertEqual(response.status_code, status.HTTP_200_OK)
420
        self.assertDictEqual(StatisticsMonthsSerializer(self.data['daily']).data, response.data)
421
422
423
class StatisticsMonthsMixin(object):
424
    url = None
425
    url_args = ()
426
    serializer = None
427
    url_get_params = None
428
429
    def _generate_fake_statistics(self):
430
        now = datetime.now()
431
        prev_year = now.year - 1
432
433
        for i in range(1, 13):
434
            date = datetime(year=prev_year, month=i, day=10)
435
            for id in range(1, i + 1):
436
                user_id = UUID(int=id)
437
                userid_counting(user_id, self.install_app_list, self.platform.name, now=date)
438
                user_id = UUID(int=1000 + id)
439
                mac_userid_counting(user_id, self.mac_app, 'mac', now=date)
440
            userid_counting(UUID(int=i), self.uninstall_app_list, self.platform.name, now=date)
441
442
        user_id = UUID(int=13)
443
        userid_counting(user_id, self.install_app_list, self.platform.name, now=datetime(year=now.year, month=1, day=1))
444
        userid_counting(user_id, self.uninstall_app_list, self.platform.name, now=datetime(year=now.year, month=1, day=1))
445
        user_id = UUID(int=1013)
446
        mac_userid_counting(user_id, self.mac_app, 'mac', now=datetime(year=now.year, month=1, day=1))
447
448
    @freeze_time("2016-01-27")
449
    @temporary_media_root()
450
    def setUp(self):
451
        self.user = User.objects.create_user(username='test', password='secret', email='[email protected]')
452
        self.client.credentials(
453
            HTTP_AUTHORIZATION='Basic %s' % base64.b64encode(bytes('{}:{}'.format('test', 'secret'), 'utf8')).decode())
454
455
        redis.flushdb()
456
        self.app = Application.objects.create(id='app', name='app')
457
        self.channel = Channel.objects.create(name='stable')
458
        self.platform = Platform.objects.create(name='win')
459
        self.version1 = Version.objects.create(
460
            app=self.app,
461
            platform=self.platform,
462
            channel=self.channel,
463
            version='1.0.0.0',
464
            file=SimpleUploadedFile('./chrome_installer.exe', False))
465
        self.version2 = Version.objects.create(
466
            app=self.app,
467
            platform=self.platform,
468
            channel=self.channel,
469
            version='2.0.0.0',
470
            file=SimpleUploadedFile('./chrome_installer.exe', False))
471
        self.mac_version = SparkleVersion.objects.create(
472
            app=self.app,
473
            channel=self.channel,
474
            version='782.112',
475
            short_version='13.0.782.112',
476
            dsa_signature='MCwCFCdoW13VBGJWIfIklKxQVyetgxE7AhQTVuY9uQT0KOV1UEk21epBsGZMPg==',
477
            file=SimpleUploadedFile('./chrome.dmg', b'_' * 1024),
478
            file_size=1024)
479
        app_kwargs = dict(appid=self.app.id, version=str(self.version1.version))
480
        install_app = create_app_xml(events=[fixtures.event_install_success], **app_kwargs)
481
        uninstall_app = create_app_xml(events=[fixtures.event_uninstall_success], **app_kwargs)
482
        self.install_app_list = [install_app]
483
        self.uninstall_app_list = [uninstall_app]
484
        self.mac_app = dict(appid=self.app.id, version=str(self.mac_version.short_version))
485
486
        self._generate_fake_statistics()
487
        now = datetime.now()
488
        updates = [(datetime(now.year-1, x, 1).strftime("%Y-%m"), x - 1) for x in range(2, 13)]
489
        updates.append((datetime(now.year, 1, 1).strftime("%Y-%m"), 0))
490
        installs = [(datetime(now.year-1, x, 1).strftime("%Y-%m"), 1) for x in range(2, 13)]
491
        installs.append((datetime(now.year, 1, 1).strftime("%Y-%m"), 1))
492
        uninstalls = [(datetime(now.year-1, x, 1).strftime("%Y-%m"), 1) for x in range(2, 13)]
493
        uninstalls.append((datetime(now.year, 1, 1).strftime("%Y-%m"), 1))
494
495
        win_platform_statistics = dict(new=installs, updates=updates, uninstalls=uninstalls)
496
        mac_platform_statistics = dict(new=installs, updates=updates)
497
        self.users_statistics = dict(win=win_platform_statistics, mac=mac_platform_statistics)
498
        self.data = dict(data=dict(self.users_statistics))
499
500
    @is_private()
501
    def test_unauthorized(self):
502
        client = APIClient()
503
        response = client.get(reverse(self.url, args=self.url_args), format='json')
504
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
505
506
    @is_private()
507
    def test_list(self):
508
        response = self.client.get(reverse(self.url, args=self.url_args), self.url_get_params, format='json')
509
        self.assertEqual(response.status_code, status.HTTP_200_OK)
510
        self.assertEqual(self.serializer(self.data).data, response.data)
511
512
    @freeze_time("2016-01-27")
513
    @is_private()
514
    def test_default_list(self):
515
        data_detail = self.data.copy()
516
        response = self.client.get(reverse(self.url, args=self.url_args), format='json')
517
        self.assertEqual(response.status_code, status.HTTP_200_OK)
518
        self.assertEqual(self.serializer(data_detail).data, response.data)
519
520
521
class StatisticsMonthsDetailTest(StatisticsMonthsMixin, APITestCase):
522
    url = 'api-statistics-months-detail'
523
    url_args = ('app',)
524
    serializer = StatisticsMonthsSerializer
525
    url_get_params = dict(start='2015-2', end='2016-1')
526
527
    @is_private()
528
    def test_list(self):
529
        data_detail = self.data.copy()
530
        response = self.client.get(reverse(self.url, args=self.url_args), self.url_get_params, format='json')
531
        self.assertEqual(response.status_code, status.HTTP_200_OK)
532
        self.assertEqual(self.serializer(data_detail).data, response.data)
533
534
535
class StatisticsVersionsTest(StatisticsMonthsMixin, APITestCase):
536
    url = 'api-statistics-versions'
537
    url_args = ('app',)
538
    serializer = StatisticsMonthsSerializer
539
    url_get_params = dict(date='2016-01')
540
541
    @freeze_time("2016-01-27")
542
    def setUp(self):
543
        super(StatisticsVersionsTest, self).setUp()
544
        data = get_users_versions(self.app.id)
545
        self.data = dict(data=dict(data))
546
547
548
class StatisticsChannelsTest(StatisticsMonthsMixin, APITestCase):
549
    url = 'api-statistics-channels'
550
    url_args = ('app',)
551
    serializer = StatisticsMonthsSerializer
552
    url_get_params = dict(date='2016-01')
553
554
    @freeze_time("2016-01-27")
555
    def setUp(self):
556
        super(StatisticsChannelsTest, self).setUp()
557
        data = get_channel_statistics(self.app.id)
558
        self.data = dict(data=dict(data))
559
560
    @is_private()
561
    def test_list(self):
562
        data_detail = self.data.copy()
563
        response = self.client.get(reverse(self.url, args=self.url_args), dict(date='2016-1'), format='json')
564
        self.assertEqual(response.status_code, status.HTTP_200_OK)
565
        self.assertEqual(self.serializer(data_detail).data, response.data)
566
567
568
class ServerVersionTest(APITestCase):
569
    url = 'api-version'
570
    serializer = ServerVersionSerializer
571
572
    def setUp(self):
573
        self.user = User.objects.create_user(username='test', password='secret', email='[email protected]')
574
        self.client.credentials(
575
            HTTP_AUTHORIZATION='Basic %s' % base64.b64encode(bytes('{}:{}'.format('test', 'secret'), 'utf8')).decode())
576
        self.data = dict(version=settings.APP_VERSION)
577
578
    @is_private()
579
    def test(self):
580
        response = self.client.get(reverse(self.url), format='json')
581
        self.assertEqual(response.status_code, status.HTTP_200_OK)
582
        self.assertEqual(self.serializer(self.data).data, response.data)
583