blob: f40ea601d4e16772ac3eb5f5f23ef168ebd4e407 [file] [log] [blame]
Dirk Vogtc9e10ab2016-10-12 13:58:15 +02001from django.contrib.auth.models import User
Dirk Vogtf2a33422016-10-11 17:17:26 +02002from rest_framework.test import APITestCase
3from rest_framework.test import APIClient
Dirk Vogt36635692016-10-17 12:19:10 +02004from rest_framework import status
Dirk Vogtc9e10ab2016-10-12 13:58:15 +02005import datetime
Dirk Vogt36635692016-10-17 12:19:10 +02006import tempfile
Dirk Vogtf130c752016-08-23 14:45:01 +02007
8# Create your tests here.
Dirk Vogtf2a33422016-10-11 17:17:26 +02009
10
11class DeviceTestCase(APITestCase):
12
13 def setUp(self):
Franz-Xaver Geigerd9943352018-02-27 14:26:41 +010014 self.url = "/hiccup/api/v1/devices/register/"
Dirk Vogtf2a33422016-10-11 17:17:26 +020015
16 def test(self):
Franz-Xaver Geigerd9943352018-02-27 14:26:41 +010017 request = self.client.post(self.url, device_register_data)
Dirk Vogtf2a33422016-10-11 17:17:26 +020018 self.assertTrue("token" in request.data)
19 self.assertTrue("uuid" in request.data)
Dirk Vogt36635692016-10-17 12:19:10 +020020 self.assertEqual(request.status_code, status.HTTP_200_OK)
Dirk Vogtf2a33422016-10-11 17:17:26 +020021
Franz-Xaver Geigerd9943352018-02-27 14:26:41 +010022 def test_create_missing_fields(self):
23 request = self.client.post(self.url)
24 self.assertEqual(request.status_code, status.HTTP_400_BAD_REQUEST)
25
26 def test_create_missing_board_date(self):
27 request = self.client.post(self.url, {
28 "board_date": device_register_data["board_date"]
29 })
30 self.assertEqual(request.status_code, status.HTTP_400_BAD_REQUEST)
31
32 def test_create_missing_chipset(self):
33 request = self.client.post(self.url, {
34 "chipset": device_register_data["chipset"]
35 })
36 self.assertEqual(request.status_code, status.HTTP_400_BAD_REQUEST)
37
38 def test_create_invalid_board_date(self):
39 request = self.client.post(self.url, {
40 "board_date": "not_a_valid_date"
41 })
42 self.assertEqual(request.status_code, status.HTTP_400_BAD_REQUEST)
43
Borjan Tchakaloff866f75e2018-03-01 12:04:00 +040044 def test_create_non_existent_time_board_date(self):
45 """
46 Test the resolution of a naive date-time in which the Europe/Amsterdam daylight saving
47 time transition moved the time "forward".
48 """
49 data = device_register_data.copy()
50 # In 2017, the Netherlands changed from CET to CEST on March, 26 at 02:00
51 data['board_date'] = '2017-03-26 02:34:56'
52 request = self.client.post(self.url, data)
53 self.assertEqual(request.status_code, status.HTTP_200_OK)
54
55 def test_create_ambiguous_time_board_date(self):
56 """
57 Test the resolution of a naive date-time in which the Europe/Amsterdam daylight saving
58 time transition moved the time "backward".
59 """
60 data = device_register_data.copy()
61 # In 2017, the Netherlands changed from CEST to CET on October, 29 at 03:00
62 data['board_date'] = '2017-10-29 02:34:56'
63 request = self.client.post(self.url, data)
64 self.assertEqual(request.status_code, status.HTTP_200_OK)
65
Franz-Xaver Geigerd9943352018-02-27 14:26:41 +010066
Dirk Vogtf2a33422016-10-11 17:17:26 +020067# Create your tests here.
68
Dirk Vogt8e656152017-05-04 23:12:13 +020069device_register_data = {
70 "board_date": str(datetime.datetime(year=2016, month=1, day=1)),
71 "chipset": "chipset"
Dirk Vogtf2a33422016-10-11 17:17:26 +020072
Dirk Vogt8e656152017-05-04 23:12:13 +020073}
Dirk Vogtf2a33422016-10-11 17:17:26 +020074class ListDevicesTestCase(APITestCase):
75
76 def setUp(self):
77 self.password = "test"
78 self.admin = User.objects.create_superuser(
79 'myuser', 'myemail@test.com', self.password)
Dirk Vogt8e656152017-05-04 23:12:13 +020080 self.client.post("/hiccup/api/v1/devices/register/", device_register_data)
81 request = self.client.post("/hiccup/api/v1/devices/register/", device_register_data)
Dirk Vogtf2a33422016-10-11 17:17:26 +020082 self.uuid_to_retrieve = request.data['uuid']
83 self.token_to_retrieve = request.data['token']
Dirk Vogt8e656152017-05-04 23:12:13 +020084 request = self.client.post("/hiccup/api/v1/devices/register/", device_register_data)
Dirk Vogtf2a33422016-10-11 17:17:26 +020085 self.uuid_to_delete = request.data['uuid']
86 self.token_to_delete = request.data['token']
87
88 def test_device_list(self):
89 client = APIClient()
90 client.login(username='myuser', password='test')
91 request = client.get("/hiccup/api/v1/devices/", {})
Dirk Vogt8e656152017-05-04 23:12:13 +020092 self.assertTrue(request.data['results'][1]['uuid'] is not '')
93 self.assertTrue(len(request.data['results']) >= 3)
Dirk Vogt36635692016-10-17 12:19:10 +020094 self.assertEqual(request.status_code, status.HTTP_200_OK)
Dirk Vogtf2a33422016-10-11 17:17:26 +020095 client.logout()
96
97 def test_device_list_unauth(self):
98 client = APIClient()
99 request = client.get("/hiccup/api/v1/devices/", {})
Dirk Vogt36635692016-10-17 12:19:10 +0200100 self.assertEqual(request.status_code, status.HTTP_401_UNAUTHORIZED)
Dirk Vogtf2a33422016-10-11 17:17:26 +0200101
102 def test_retrieve_device_auth(self):
103 client = APIClient()
104 client.login(username='myuser', password='test')
105 request = client.get(
106 "/hiccup/api/v1/devices/{}/".format(self.uuid_to_retrieve), {})
Dirk Vogt36635692016-10-17 12:19:10 +0200107 self.assertEqual(request.status_code, status.HTTP_200_OK)
Dirk Vogtf2a33422016-10-11 17:17:26 +0200108 self.assertEqual(request.data['uuid'], str(self.uuid_to_retrieve))
109 self.assertEqual(request.data['token'], self.token_to_retrieve)
110 client.logout()
111
112 def test_retrieve_device_unauth(self):
113 client = APIClient()
114 request = client.get(
115 "/hiccup/api/v1/devices/{}/".format(self.uuid_to_retrieve), {})
Dirk Vogt36635692016-10-17 12:19:10 +0200116 self.assertEqual(request.status_code, status.HTTP_401_UNAUTHORIZED)
Dirk Vogtf2a33422016-10-11 17:17:26 +0200117
118 def test_delete_device_auth(self):
119 client = APIClient()
120 client.login(username='myuser', password='test')
121 url = "/hiccup/api/v1/devices/{}/".format(self.uuid_to_delete)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200122 request = client.delete(
123 url.format(self.uuid_to_delete), {})
Dirk Vogt36635692016-10-17 12:19:10 +0200124 self.assertEqual(request.status_code, status.HTTP_204_NO_CONTENT)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200125 request = client.delete(
126 url.format(self.uuid_to_delete), {})
Dirk Vogt36635692016-10-17 12:19:10 +0200127 self.assertEqual(request.status_code, status.HTTP_404_NOT_FOUND)
Dirk Vogtf2a33422016-10-11 17:17:26 +0200128 client.logout()
129
Dirk Vogtf2a33422016-10-11 17:17:26 +0200130
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200131class HeartbeatListTestCase(APITestCase):
Dirk Vogtf2a33422016-10-11 17:17:26 +0200132
133 def setUp(self):
Dirk Vogt67eb1482016-10-13 12:42:56 +0200134 self.setup_users()
135 self.data = self.create_dummy_data(self.uuid)
136 self.url = "/hiccup/api/v1/heartbeats/"
Dirk Vogte1784882016-10-13 16:09:38 +0200137 self.url_by_uuid = "/hiccup/api/v1/devices/{}/heartbeats/"
Dirk Vogt67eb1482016-10-13 12:42:56 +0200138
139 def setup_users(self):
Dirk Vogtf2a33422016-10-11 17:17:26 +0200140 self.password = "test"
Dirk Vogt8e656152017-05-04 23:12:13 +0200141 request = self.client.post("/hiccup/api/v1/devices/register/", device_register_data)
Dirk Vogtf2a33422016-10-11 17:17:26 +0200142 self.uuid = request.data['uuid']
143 self.token = request.data['token']
Dirk Vogt8e656152017-05-04 23:12:13 +0200144 request = self.client.post("/hiccup/api/v1/devices/register/", device_register_data)
Dirk Vogtf2a33422016-10-11 17:17:26 +0200145 self.other_uuid = request.data['uuid']
146 self.other_token = request.data['token']
Dirk Vogt67eb1482016-10-13 12:42:56 +0200147 self.admin = User.objects.create_superuser(
148 'myuser', 'myemail@test.com', self.password)
149 self.admin = APIClient()
150 self.admin.login(username='myuser', password='test')
151 self.user = APIClient()
152 self.other_user = APIClient()
153 self.user.credentials(HTTP_AUTHORIZATION='Token ' + self.token)
154 self.other_user.credentials(HTTP_AUTHORIZATION='Token '
155 + self.other_token)
156 self.noauth_client = APIClient()
Dirk Vogtf2a33422016-10-11 17:17:26 +0200157
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200158 def create_dummy_data(self, uuid="not set"):
159 return {
160 'uuid': uuid,
161 'app_version': 2,
162 'uptime': "2 Hours",
163 'build_fingerprint': "models.CharField(max_length=200)",
Borjan Tchakaloff6f239a62018-02-19 09:05:50 +0100164 'radio_version': 'XXXX.X-FP2-X-XX',
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200165 'date': str(datetime.datetime(year=2016, month=1, day=1))
166 }
167
168 def test_create_no_auth(self):
Dirk Vogt67eb1482016-10-13 12:42:56 +0200169 request = self.noauth_client.post(self.url, self.data)
Dirk Vogt36635692016-10-17 12:19:10 +0200170 self.assertEqual(request.status_code, status.HTTP_401_UNAUTHORIZED)
Dirk Vogtf2a33422016-10-11 17:17:26 +0200171
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200172 def test_create_as_admin(self):
Dirk Vogt67eb1482016-10-13 12:42:56 +0200173 request = self.admin.post(self.url, self.data)
Dirk Vogt36635692016-10-17 12:19:10 +0200174 self.assertEqual(request.status_code, status.HTTP_201_CREATED)
Dirk Vogt67eb1482016-10-13 12:42:56 +0200175 self.assertTrue(request.data['id'] > 0)
Dirk Vogtf2a33422016-10-11 17:17:26 +0200176
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200177 def test_create_as_admin_not_existing_device(self):
Dirk Vogt67eb1482016-10-13 12:42:56 +0200178 request = self.admin.post(self.url,
179 self.create_dummy_data())
Dirk Vogt36635692016-10-17 12:19:10 +0200180 self.assertEqual(request.status_code, status.HTTP_404_NOT_FOUND)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200181
182 def test_create_as_uuid_owner(self):
Dirk Vogt67eb1482016-10-13 12:42:56 +0200183 request = self.user.post(self.url,
184 self.create_dummy_data(self.uuid))
Dirk Vogt36635692016-10-17 12:19:10 +0200185 self.assertEqual(request.status_code, status.HTTP_201_CREATED)
Dirk Vogt67eb1482016-10-13 12:42:56 +0200186 self.assertTrue(request.data['id'] == -1)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200187
188 def test_create_as_uuid_not_owner(self):
Dirk Vogt67eb1482016-10-13 12:42:56 +0200189 request = self.user.post(self.url,
190 self.create_dummy_data(self.other_uuid))
Dirk Vogt36635692016-10-17 12:19:10 +0200191 self.assertEqual(request.status_code, status.HTTP_403_FORBIDDEN)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200192
Dirk Vogt67eb1482016-10-13 12:42:56 +0200193 def post_multiple(self, client, data, count=5):
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200194 for i in range(count):
Dirk Vogt67eb1482016-10-13 12:42:56 +0200195 client.post(self.url, data)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200196
197 def test_list(self):
198 count = 5
Dirk Vogt67eb1482016-10-13 12:42:56 +0200199 self.post_multiple(self.user, self.data, count)
200 request = self.admin.get(self.url)
Dirk Vogt36635692016-10-17 12:19:10 +0200201 self.assertEqual(request.status_code, status.HTTP_200_OK)
Dirk Vogt8e656152017-05-04 23:12:13 +0200202 self.assertTrue(len(request.data['results']) == count)
Dirk Vogte1784882016-10-13 16:09:38 +0200203
Franz-Xaver Geigerd612fd22018-02-28 10:33:08 +0100204 def retrieve_single(self, user):
Dirk Vogte1784882016-10-13 16:09:38 +0200205 count = 5
Dirk Vogte1784882016-10-13 16:09:38 +0200206 self.post_multiple(self.user, self.data, count)
207 url = "{}1/".format(self.url)
208 request = user.get(url)
Franz-Xaver Geigerd612fd22018-02-28 10:33:08 +0100209 return request.status_code
210
211 def test_retrieve_single_admin(self):
212 self.assertEqual(
213 self.retrieve_single(self.admin),
214 status.HTTP_200_OK)
Dirk Vogte1784882016-10-13 16:09:38 +0200215
216 def test_retrieve_single_noauth(self):
Franz-Xaver Geigerd612fd22018-02-28 10:33:08 +0100217 self.assertEqual(
218 self.retrieve_single(self.user),
219 status.HTTP_403_FORBIDDEN)
Dirk Vogte1784882016-10-13 16:09:38 +0200220
221 def test_retrieve_single_device_owner(self):
Franz-Xaver Geigerd612fd22018-02-28 10:33:08 +0100222 self.assertEqual(
223 self.retrieve_single(self.noauth_client),
224 status.HTTP_401_UNAUTHORIZED)
Dirk Vogte1784882016-10-13 16:09:38 +0200225
Franz-Xaver Geigerd612fd22018-02-28 10:33:08 +0100226 def retrieve_single_by_device(self, user):
Dirk Vogt0d9d5d22016-10-13 16:17:57 +0200227 count = 5
Dirk Vogt0d9d5d22016-10-13 16:17:57 +0200228 self.post_multiple(self.user, self.data, count)
229 url = "{}1/".format(self.url_by_uuid.format(self.uuid))
Dirk Vogt0d9d5d22016-10-13 16:17:57 +0200230 request = user.get(url)
Franz-Xaver Geigerd612fd22018-02-28 10:33:08 +0100231 return request.status_code
232
233 def test_retreive_single_by_device_admin(self):
234 self.assertEqual(
235 self.retrieve_single_by_device(self.admin),
236 status.HTTP_200_OK)
Dirk Vogt0d9d5d22016-10-13 16:17:57 +0200237
238 def test_retrieve_single_by_device_noauth(self):
Franz-Xaver Geigerd612fd22018-02-28 10:33:08 +0100239 self.assertEqual(
240 self.retrieve_single_by_device(self.user),
241 status.HTTP_403_FORBIDDEN)
Dirk Vogt0d9d5d22016-10-13 16:17:57 +0200242
243 def test_retrieve_single_by_device_device_owner(self):
Franz-Xaver Geigerd612fd22018-02-28 10:33:08 +0100244 self.assertEqual(
245 self.retrieve_single_by_device(self.noauth_client),
246 status.HTTP_401_UNAUTHORIZED)
Dirk Vogt0d9d5d22016-10-13 16:17:57 +0200247
Dirk Vogte1784882016-10-13 16:09:38 +0200248 def test_list_by_uuid(self):
249 count = 5
250 self.post_multiple(self.user, self.data, count)
251 self.post_multiple(self.admin, self.create_dummy_data(self.other_uuid),
252 count)
253 url = self.url_by_uuid.format(self.uuid)
254 request = self.admin.get(url)
Dirk Vogt36635692016-10-17 12:19:10 +0200255 self.assertEqual(request.status_code, status.HTTP_200_OK)
Dirk Vogt8e656152017-05-04 23:12:13 +0200256 self.assertTrue(len(request.data['results']) == count)
Dirk Vogte1784882016-10-13 16:09:38 +0200257
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200258 def test_list_noauth(self):
259 count = 5
Dirk Vogt67eb1482016-10-13 12:42:56 +0200260 self.post_multiple(self.user, self.data, count)
261 request = self.noauth_client.get(self.url)
Dirk Vogt36635692016-10-17 12:19:10 +0200262 self.assertEqual(request.status_code, status.HTTP_401_UNAUTHORIZED)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200263
264 def test_list_device_owner(self):
265 count = 5
Dirk Vogt67eb1482016-10-13 12:42:56 +0200266 self.post_multiple(self.user, self.data, count)
267 request = self.user.get(self.url)
Dirk Vogt36635692016-10-17 12:19:10 +0200268 self.assertEqual(request.status_code, status.HTTP_403_FORBIDDEN)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200269
Borjan Tchakaloff869cf922018-02-19 11:01:16 +0100270 def test_no_radio_version(self):
271 data = self.data.copy()
272 data.pop('radio_version')
273 self.post_multiple(self.user, data, 1)
274 url = self.url_by_uuid.format(self.uuid)
275 request = self.admin.get(url)
276 self.assertEqual(request.status_code, status.HTTP_200_OK)
277 self.assertEqual(len(request.data['results']), 1)
278 self.assertIsNone(request.data['results'][0]['radio_version'])
279
280 def test_radio_version_field(self):
281 self.post_multiple(self.user, self.data, 1)
282 url = self.url_by_uuid.format(self.uuid)
283 request = self.admin.get(url)
284 self.assertEqual(request.status_code, status.HTTP_200_OK)
285 self.assertEqual(len(request.data['results']), 1)
286 self.assertEqual(request.data['results'][0]['radio_version'],
287 self.data['radio_version'])
288
Borjan Tchakaloff866f75e2018-03-01 12:04:00 +0400289 def test_send_non_existent_time(self):
290 """
291 Test the resolution of a naive date-time in which the Europe/Amsterdam daylight saving
292 time transition moved the time "forward".
293 """
294 data = self.data.copy()
295 # In 2017, the Netherlands changed from CET to CEST on March, 26 at 02:00
296 data['date'] = '2017-03-26 02:34:56'
297 request = self.user.post(self.url, data)
298 self.assertEqual(request.status_code, status.HTTP_201_CREATED)
299
300 def test_send_ambiguous_time(self):
301 """
302 Test the resolution of a naive date-time in which the Europe/Amsterdam daylight saving
303 time transition moved the time "backward".
304 """
305 data = self.data.copy()
306 # In 2017, the Netherlands changed from CEST to CET on October, 29 at 03:00
307 data['date'] = '2017-10-29 02:34:56'
308 request = self.user.post(self.url, data)
309 self.assertEqual(request.status_code, status.HTTP_201_CREATED)
310
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200311
Dirk Vogt67eb1482016-10-13 12:42:56 +0200312def create_crashreport(uuid="not set"):
313 return {
314 'uuid': uuid,
315 'is_fake_report': 0,
316 'app_version': 2,
317 'uptime': "2 Hours",
318 'build_fingerprint': "models.CharField(max_length=200)",
Borjan Tchakaloff6f239a62018-02-19 09:05:50 +0100319 'radio_version': 'XXXX.X-FP2-X-XX',
Dirk Vogt67eb1482016-10-13 12:42:56 +0200320 'boot_reason': "models.CharField(max_length=200)",
321 'power_on_reason': "models.CharField(max_length=200)",
322 'power_off_reason': "models.CharField(max_length=200)",
323 'date': str(datetime.datetime(year=2016, month=1, day=1))
324 }
325
326
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200327class CrashreportListTestCase(HeartbeatListTestCase):
328
329 def setUp(self):
Dirk Vogt67eb1482016-10-13 12:42:56 +0200330 self.setup_users()
331 self.data = self.create_dummy_data(self.uuid)
332 self.url = "/hiccup/api/v1/crashreports/"
Dirk Vogte1784882016-10-13 16:09:38 +0200333 self.url_by_uuid = "/hiccup/api/v1/devices/{}/crashreports/"
Dirk Vogt67eb1482016-10-13 12:42:56 +0200334
335 def create_dummy_data(self, uuid="not set"):
336 return create_crashreport(uuid)
337
338
339class LogfileUploadTest(APITestCase):
340 def setUp(self):
341 self.setup_users()
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200342 # we need a device
Dirk Vogt67eb1482016-10-13 12:42:56 +0200343 self.user.post("/hiccup/api/v1/crashreports/",
344 create_crashreport(self.uuid))
345 self.user.post("/hiccup/api/v1/crashreports/",
346 create_crashreport(self.uuid))
347 self.user.post("/hiccup/api/v1/crashreports/",
348 create_crashreport(self.other_uuid))
349 self.user.post("/hiccup/api/v1/crashreports/",
350 create_crashreport(self.other_uuid))
351
352 def setup_users(self):
353 self.password = "test"
Dirk Vogt8e656152017-05-04 23:12:13 +0200354 request = self.client.post("/hiccup/api/v1/devices/register/", device_register_data)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200355 self.uuid = request.data['uuid']
356 self.token = request.data['token']
Dirk Vogt8e656152017-05-04 23:12:13 +0200357 request = self.client.post("/hiccup/api/v1/devices/register/", device_register_data)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200358 self.other_uuid = request.data['uuid']
359 self.other_token = request.data['token']
Dirk Vogt67eb1482016-10-13 12:42:56 +0200360 self.admin = User.objects.create_superuser(
361 'myuser', 'myemail@test.com', self.password)
Dirk Vogt67eb1482016-10-13 12:42:56 +0200362 self.user = APIClient()
363 self.other_user = APIClient()
364 self.user.credentials(HTTP_AUTHORIZATION='Token ' + self.token)
365 self.other_user.credentials(HTTP_AUTHORIZATION='Token '
366 + self.other_token)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200367
Dirk Vogt36635692016-10-17 12:19:10 +0200368 def get_url(self, uuid, report_id, filename):
369 return ("/hiccup/api/v1/devices/{}/crashreports/{}/logfile_put/{}/".
370 format(uuid, report_id, "test.log"))
371
Dirk Vogt67eb1482016-10-13 12:42:56 +0200372 def test_Logfile_upload_as_admin(self):
Dirk Vogt36635692016-10-17 12:19:10 +0200373 self.client.force_authenticate(self.admin)
374 f = tempfile.NamedTemporaryFile('w+', suffix=".log", delete=True)
375 f.write(u"blihblahblub")
376 request = self.client.post(
377 self.get_url(self.uuid, 1, f.name),
378 {'file': f}, format="multipart")
379 self.assertEqual(status.HTTP_201_CREATED, request.status_code)