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 uuid import UUID |
21
|
|
|
from datetime import datetime |
22
|
|
|
|
23
|
|
|
from django.test import TestCase |
24
|
|
|
from django.test.client import Client |
25
|
|
|
from django.contrib.auth import get_user_model |
26
|
|
|
from django.core.urlresolvers import reverse |
27
|
|
|
from django.db import connections |
28
|
|
|
|
29
|
|
|
import mock |
30
|
|
|
from pyquery import PyQuery as pq |
31
|
|
|
|
32
|
|
|
from omaha_server.utils import is_private |
33
|
|
|
from omaha.factories import ApplicationFactory, RequestFactory, AppRequestFactory, EventFactory |
34
|
|
|
from omaha.models import Request, AppRequest |
35
|
|
|
from omaha.views_admin import ( |
36
|
|
|
StatisticsView, |
37
|
|
|
RequestListView, |
38
|
|
|
) |
39
|
|
|
|
40
|
|
|
User = get_user_model() |
41
|
|
|
|
42
|
|
|
|
43
|
|
|
class AdminViewStatisticsTest(TestCase): |
44
|
|
|
def setUp(self): |
45
|
|
|
self.app1 = ApplicationFactory.create(name='app1', id='app1') |
46
|
|
|
self.app2 = ApplicationFactory.create(name='app2', id='app2') |
47
|
|
|
self.apps = [self.app1, self.app2] |
48
|
|
|
self.user = User.objects.create_superuser( |
49
|
|
|
username='test', email='[email protected]', password='test') |
50
|
|
|
|
51
|
|
|
@is_private() |
52
|
|
|
def test_statistics_view(self): |
53
|
|
|
view = StatisticsView() |
54
|
|
|
self.assertListEqual(list(view.get_queryset()), self.apps) |
55
|
|
|
|
56
|
|
|
|
57
|
|
|
class ViewsStaffMemberRequiredTest(TestCase): |
58
|
|
|
def setUp(self): |
59
|
|
|
self.client = Client() |
60
|
|
|
self.app = ApplicationFactory.create() |
61
|
|
|
self.request = Request.objects.create(version='1.0.0.0') |
62
|
|
|
self.app_request = AppRequest.objects.create( |
63
|
|
|
request=self.request, |
64
|
|
|
appid=self.app.id, |
65
|
|
|
) |
66
|
|
|
|
67
|
|
|
@is_private() |
68
|
|
|
def test_omaha_statistics(self): |
69
|
|
|
url = reverse('omaha_statistics') |
70
|
|
|
response = self.client.get(url) |
71
|
|
|
self.assertRedirects(response, '/admin/login/?next=%s' % url) |
72
|
|
|
|
73
|
|
|
@is_private() |
74
|
|
|
def test_omaha_statistics_detail(self): |
75
|
|
|
url = reverse('omaha_statistics_detail', kwargs=dict(name=self.app.name)) |
76
|
|
|
response = self.client.get(url) |
77
|
|
|
self.assertRedirects(response, '/admin/login/?next=%s' % url) |
78
|
|
|
|
79
|
|
|
@is_private() |
80
|
|
|
def test_omaha_request_list(self): |
81
|
|
|
url = reverse('omaha_request_list', kwargs=dict(name=self.app.name)) |
82
|
|
|
response = self.client.get(url) |
83
|
|
|
self.assertRedirects(response, '/admin/login/?next=%s' % url) |
84
|
|
|
|
85
|
|
|
@is_private() |
86
|
|
|
def test_omaha_request_detail(self): |
87
|
|
|
url = reverse('omaha_request_detail', kwargs=dict(pk=self.app_request.pk)) |
88
|
|
|
response = self.client.get(url) |
89
|
|
|
self.assertRedirects(response, '/admin/login/?next=%s' % url) |
90
|
|
|
|
91
|
|
|
@is_private() |
92
|
|
|
def test_omaha_preferences(self): |
93
|
|
|
url = reverse('set_preferences', args=['']) |
94
|
|
|
response = self.client.get(url) |
95
|
|
|
self.assertRedirects(response, '/admin/login/?next=%s' % url) |
96
|
|
|
|
97
|
|
|
@is_private() |
98
|
|
|
def test_omaha_monitoring(self): |
99
|
|
|
url = reverse('monitoring') |
100
|
|
|
response = self.client.get(url) |
101
|
|
|
self.assertRedirects(response, '/admin/login/?next=%s' % url) |
102
|
|
|
|
103
|
|
|
|
104
|
|
|
class AdminViewPreferencesTest(TestCase): |
105
|
|
|
def setUp(self): |
106
|
|
|
self.client = Client() |
107
|
|
|
self.user = User.objects.create_superuser( |
108
|
|
|
username='test', email='[email protected]', password='test') |
109
|
|
|
self.client.login(username='test', password='test') |
110
|
|
|
|
111
|
|
|
@is_private() |
112
|
|
|
def test_set_timezone(self): |
113
|
|
|
url = reverse('set_preferences', args=['Timezone']) |
114
|
|
|
timezone = 'Asia/Omsk' |
115
|
|
|
self.client.post(url, dict(Timezone__timezone=timezone), follow=True) |
116
|
|
|
response = self.client.get(url) |
117
|
|
|
self.assertEqual(self.client.session["django_timezone"], timezone) |
118
|
|
|
self.assertContains(response, '<option value="Asia/Omsk" selected="selected">Asia/Omsk +0600</option>') |
119
|
|
|
|
120
|
|
|
|
121
|
|
|
class FilteringAppRequestsByUserIdTest(TestCase): |
122
|
|
|
|
123
|
|
|
def setUp(self): |
124
|
|
|
self.client = Client() |
125
|
|
|
self.app = ApplicationFactory.create(id='{D0AB2EBC-931B-4013-9FEB-C9C4C2225C0}') |
126
|
|
|
self.userid1 = UUID(int=1) |
127
|
|
|
self.userid2 = UUID(int=2) |
128
|
|
|
self.app_req1 = AppRequestFactory(request=RequestFactory(userid=self.userid1)) |
129
|
|
|
self.app_req2 = AppRequestFactory(request=RequestFactory(userid=self.userid1)) |
130
|
|
|
self.app_req3 = AppRequestFactory(request=RequestFactory(userid=self.userid2)) |
131
|
|
|
self.user = User.objects.create_superuser( |
132
|
|
|
username='test', email='[email protected]', password='test') |
133
|
|
|
self.client.login(username='test', password='test') |
134
|
|
|
|
135
|
|
|
@is_private() |
136
|
|
|
def test_filtering(self): |
137
|
|
|
url = reverse('omaha_request_list', kwargs=dict(name=self.app.name)) |
138
|
|
|
data = {'request__userid': '', |
139
|
|
|
'request__created': '', |
140
|
|
|
'event_type': '', |
141
|
|
|
'event_result': ''} |
142
|
|
|
resp = self.client.get(url, data) |
143
|
|
|
d = pq(resp.content) |
144
|
|
|
res = d('#apprequest-table tbody tr') |
145
|
|
|
self.assertEqual(len(res), 3) |
146
|
|
|
data = {'request__userid': self.userid1, |
147
|
|
|
'request__created': '', |
148
|
|
|
'event_type': '', |
149
|
|
|
'event_result': ''} |
150
|
|
|
resp = self.client.get(url, data) |
151
|
|
|
d = pq(resp.content) |
152
|
|
|
res = d('#apprequest-table tbody tr') |
153
|
|
|
self.assertEqual(len(res), 2) |
154
|
|
|
|
155
|
|
|
|
156
|
|
|
class VersionUsageViewTest(TestCase): |
157
|
|
|
def setUp(self): |
158
|
|
|
self.client = Client() |
159
|
|
|
self.app = ApplicationFactory.create(id='{D0AB2EBC-931B-4013-9FEB-C9C4C2225C0}') |
160
|
|
|
self.userid1 = UUID(int=1) |
161
|
|
|
self.userid2 = UUID(int=2) |
162
|
|
|
self.userid3 = UUID(int=3) |
163
|
|
|
self.req1 = RequestFactory(userid=self.userid1, created=datetime(2015, 1, 1)) |
164
|
|
|
self.req2 = RequestFactory(userid=self.userid1, created=datetime(2015, 7, 7)) |
165
|
|
|
self.req3 = RequestFactory(userid=self.userid2) |
166
|
|
|
self.req4 = RequestFactory(userid=self.userid3) |
167
|
|
|
self.app_req1 = AppRequestFactory(request=self.req1, events=(EventFactory(eventtype=2, eventresult=1),)) |
168
|
|
|
self.app_req2 = AppRequestFactory(request=self.req2, events=(EventFactory(eventtype=3, eventresult=1),)) |
169
|
|
|
self.app_req3 = AppRequestFactory(request=self.req3, events=(EventFactory(eventtype=2, eventresult=1),)) |
170
|
|
|
self.app_req4 = AppRequestFactory(request=self.req4, events=(EventFactory(eventtype=2, eventresult=5),)) |
171
|
|
|
self.user = User.objects.create_superuser( |
172
|
|
|
username='test', email='[email protected]', password='test') |
173
|
|
|
self.client.login(username='test', password='test') |
174
|
|
|
|
175
|
|
|
@is_private() |
176
|
|
|
def test_table(self): |
177
|
|
|
if connections['default'].settings_dict['ENGINE'] != 'django.db.backends.postgresql_psycopg2': |
178
|
|
|
self.skipTest('Database should be postgreSQL') |
179
|
|
|
url = reverse('omaha_version_usage', kwargs=dict(name=self.app.name)) |
180
|
|
|
resp = self.client.get(url) |
181
|
|
|
d = pq(resp.content) |
182
|
|
|
res = d('#usage-table tbody tr') |
183
|
|
|
self.assertEqual(AppRequest.objects.count(), 4) |
184
|
|
|
self.assertEqual(len(res), 2) |
185
|
|
|
|
186
|
|
|
self.assertEqual(d("#usage-table tbody tr .userid").contents(), |
187
|
|
|
['00000000-0000-0000-0000-000000000001', '00000000-0000-0000-0000-000000000002']) |
188
|
|
|
self.assertEqual(d("#usage-table tbody tr .last_update").contents()[0], '07/07/2015 midnight') |
189
|
|
|
|
190
|
|
|
|
191
|
|
|
class ManualCleanupView(TestCase): |
192
|
|
|
def setUp(self): |
193
|
|
|
self.client = Client() |
194
|
|
|
self.user = User.objects.create_superuser( |
195
|
|
|
username='test', email='[email protected]', password='test') |
196
|
|
|
self.client.login(username='test', password='test') |
197
|
|
|
|
198
|
|
|
@is_private() |
|
|
|
|
199
|
|
|
def test_limit_size_field(self): |
200
|
|
|
data = dict(limit_size=10) |
201
|
|
|
url = reverse('manual_cleanup', args=['feedback__Feedback']) |
202
|
|
|
with mock.patch('omaha.tasks.deferred_manual_cleanup.apply_async') as mocked: |
203
|
|
|
self.client.post(url, data=data) |
204
|
|
|
|
205
|
|
|
mock_args, mock_kwargs = mocked.call_args |
206
|
|
|
data.update(dict(limit_days=None)) |
207
|
|
|
self.assertTrue(mocked.called) |
208
|
|
|
self.assertDictEqual(mock_args[1], data) |
209
|
|
|
|
210
|
|
|
@is_private() |
|
|
|
|
211
|
|
|
def test_limit_days_field(self): |
212
|
|
|
data = dict(limit_days=10) |
213
|
|
|
url = reverse('manual_cleanup', args=['feedback__Feedback']) |
214
|
|
|
with mock.patch('omaha.tasks.deferred_manual_cleanup.apply_async') as mocked: |
215
|
|
|
self.client.post(url, data=data) |
216
|
|
|
|
217
|
|
|
mock_args, mock_kwargs = mocked.call_args |
218
|
|
|
data.update(dict(limit_size=None)) |
219
|
|
|
self.assertTrue(mocked.called) |
220
|
|
|
self.assertDictEqual(mock_args[1], data) |
221
|
|
|
|
222
|
|
|
@is_private() |
223
|
|
|
def test_all_fields(self): |
224
|
|
|
data = dict(limit_size=40, limit_days=5) |
225
|
|
|
url = reverse('manual_cleanup', args=['feedback__Feedback']) |
226
|
|
|
with mock.patch('omaha.tasks.deferred_manual_cleanup.apply_async') as mocked: |
227
|
|
|
self.client.post(url, data=data) |
228
|
|
|
|
229
|
|
|
mock_args, mock_kwargs = mocked.call_args |
230
|
|
|
self.assertTrue(mocked.called) |
231
|
|
|
self.assertDictEqual(mock_args[1], data) |
232
|
|
|
|
233
|
|
|
|
234
|
|
|
class CrashManualCleanupView(TestCase): |
235
|
|
|
def setUp(self): |
236
|
|
|
self.client = Client() |
237
|
|
|
self.user = User.objects.create_superuser( |
238
|
|
|
username='test', email='[email protected]', password='test') |
239
|
|
|
self.client.login(username='test', password='test') |
240
|
|
|
|
241
|
|
|
@is_private() |
242
|
|
|
def test_limit_duplictated_field(self): |
243
|
|
|
data = dict(limit_duplicated=10) |
244
|
|
|
url = reverse('manual_cleanup', args=['crash__Crash']) |
245
|
|
|
with mock.patch('omaha.tasks.deferred_manual_cleanup.apply_async') as mocked: |
246
|
|
|
self.client.post(url, data=data) |
247
|
|
|
|
248
|
|
|
mock_args, mock_kwargs = mocked.call_args |
249
|
|
|
data.update(dict(limit_size=None, limit_days=None)) |
250
|
|
|
self.assertTrue(mocked.called) |
251
|
|
|
self.assertDictEqual(mock_args[1], data) |
252
|
|
|
|
253
|
|
|
@is_private() |
254
|
|
|
def test_all_fields(self): |
255
|
|
|
data = dict(limit_size=40, limit_days=5, limit_duplicated=73) |
256
|
|
|
url = reverse('manual_cleanup', args=['crash__Crash']) |
257
|
|
|
with mock.patch('omaha.tasks.deferred_manual_cleanup.apply_async') as mocked: |
258
|
|
|
self.client.post(url, data=data) |
259
|
|
|
|
260
|
|
|
mock_args, mock_kwargs = mocked.call_args |
261
|
|
|
self.assertTrue(mocked.called) |
262
|
|
|
self.assertDictEqual(mock_args[1], data) |
263
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.