blob: 7e8d94e70a83e2a1222d01959c6912244cdc079e [file] [log] [blame]
Franz-Xaver Geiger4d022d52018-03-20 13:12:49 +01001import os
2import tempfile
3
Dirk Vogtc9e10ab2016-10-12 13:58:15 +02004from django.contrib.auth.models import User
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +01005from django.urls import reverse
Dirk Vogtf2a33422016-10-11 17:17:26 +02006from rest_framework.test import APITestCase
7from rest_framework.test import APIClient
Dirk Vogt36635692016-10-17 12:19:10 +02008from rest_framework import status
Dirk Vogtf130c752016-08-23 14:45:01 +02009
Borjan Tchakaloffec814a72018-02-28 11:16:53 +040010
11class Dummy(object):
12 DEFAULT_DUMMY_DEVICE_REGISTER_VALUES = {
13 'board_date': '2015-12-15T01:23:45Z',
14 'chipset': 'Qualcomm MSM8974PRO-AA',
15 }
16
17 DEFAULT_DUMMY_HEARTBEAT_VALUES = {
18 'uuid': None,
19 'app_version': 10100,
20 'uptime': (
21 'up time: 16 days, 21:49:56, idle time: 5 days, 20:55:04, '
22 'sleep time: 10 days, 20:46:27'),
23 'build_fingerprint': (
24 'Fairphone/FP2/FP2:6.0.1/FP2-gms-18.03.1/FP2-gms-18.03.1:user/'
25 'release-keys'),
26 'radio_version': '4437.1-FP2-0-08',
27 'date': '2018-03-19T09:58:30.386Z',
28 }
29
30 DEFAULT_DUMMY_CRASHREPORTS_VALUES = DEFAULT_DUMMY_HEARTBEAT_VALUES.copy()
31 DEFAULT_DUMMY_CRASHREPORTS_VALUES.update({
32 'is_fake_report': 0,
33 'boot_reason': 'why?',
34 'power_on_reason': 'it was powered on',
35 'power_off_reason': 'something happened and it went off',
36 })
37
38 @staticmethod
39 def _update_copy(original, update):
40 """Merge fields of update into a copy of original"""
41 data = original.copy()
42 data.update(update)
43 return data
44
45 @staticmethod
46 def device_register_data(**kwargs):
47 """
48 Return the data required to register a device.
49
50 Use the values passed as keyword arguments or default to
51 the ones from `Dummy.DEFAULT_DUMMY_DEVICE_REGISTER_VALUES`.
52 """
53 return Dummy._update_copy(
54 Dummy.DEFAULT_DUMMY_DEVICE_REGISTER_VALUES, kwargs)
55
56 @staticmethod
57 def heartbeat_data(**kwargs):
58 """
59 Return the data required to create a heartbeat.
60
61 Use the values passed as keyword arguments or default to
62 the ones from `Dummy.DEFAULT_DUMMY_HEARTBEAT_VALUES`.
63 """
64 return Dummy._update_copy(Dummy.DEFAULT_DUMMY_HEARTBEAT_VALUES, kwargs)
65
66 @staticmethod
67 def crashreport_data(**kwargs):
68 """
69 Return the data required to create a crashreport.
70
71 Use the values passed as keyword arguments or default to
72 the ones from `Dummy.DEFAULT_DUMMY_CRASHREPORTS_VALUES`.
73 """
74 return Dummy._update_copy(
75 Dummy.DEFAULT_DUMMY_CRASHREPORTS_VALUES, kwargs)
Dirk Vogtf2a33422016-10-11 17:17:26 +020076
77
78class DeviceTestCase(APITestCase):
79
80 def setUp(self):
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +010081 self.url = reverse("api_v1_register_device")
Dirk Vogtf2a33422016-10-11 17:17:26 +020082
83 def test(self):
Borjan Tchakaloffec814a72018-02-28 11:16:53 +040084 request = self.client.post(self.url, Dummy.device_register_data())
Dirk Vogtf2a33422016-10-11 17:17:26 +020085 self.assertTrue("token" in request.data)
86 self.assertTrue("uuid" in request.data)
Dirk Vogt36635692016-10-17 12:19:10 +020087 self.assertEqual(request.status_code, status.HTTP_200_OK)
Dirk Vogtf2a33422016-10-11 17:17:26 +020088
Franz-Xaver Geigerd9943352018-02-27 14:26:41 +010089 def test_create_missing_fields(self):
90 request = self.client.post(self.url)
91 self.assertEqual(request.status_code, status.HTTP_400_BAD_REQUEST)
92
93 def test_create_missing_board_date(self):
Borjan Tchakaloffec814a72018-02-28 11:16:53 +040094 data = Dummy.device_register_data()
95 data.pop('board_date')
96 request = self.client.post(self.url, data)
Franz-Xaver Geigerd9943352018-02-27 14:26:41 +010097 self.assertEqual(request.status_code, status.HTTP_400_BAD_REQUEST)
98
99 def test_create_missing_chipset(self):
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400100 data = Dummy.device_register_data()
101 data.pop('chipset')
102 request = self.client.post(self.url, data)
Franz-Xaver Geigerd9943352018-02-27 14:26:41 +0100103 self.assertEqual(request.status_code, status.HTTP_400_BAD_REQUEST)
104
105 def test_create_invalid_board_date(self):
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400106 data = Dummy.device_register_data()
107 data['board_date'] = 'not_a_valid_date'
108 request = self.client.post(self.url, data)
Franz-Xaver Geigerd9943352018-02-27 14:26:41 +0100109 self.assertEqual(request.status_code, status.HTTP_400_BAD_REQUEST)
110
Borjan Tchakaloff866f75e2018-03-01 12:04:00 +0400111 def test_create_non_existent_time_board_date(self):
112 """
113 Test the resolution of a naive date-time in which the Europe/Amsterdam daylight saving
114 time transition moved the time "forward".
115 """
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400116 data = Dummy.device_register_data()
Borjan Tchakaloff866f75e2018-03-01 12:04:00 +0400117 # In 2017, the Netherlands changed from CET to CEST on March, 26 at 02:00
118 data['board_date'] = '2017-03-26 02:34:56'
119 request = self.client.post(self.url, data)
120 self.assertEqual(request.status_code, status.HTTP_200_OK)
121
122 def test_create_ambiguous_time_board_date(self):
123 """
124 Test the resolution of a naive date-time in which the Europe/Amsterdam daylight saving
125 time transition moved the time "backward".
126 """
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400127 data = Dummy.device_register_data()
Borjan Tchakaloff866f75e2018-03-01 12:04:00 +0400128 # In 2017, the Netherlands changed from CEST to CET on October, 29 at 03:00
129 data['board_date'] = '2017-10-29 02:34:56'
130 request = self.client.post(self.url, data)
131 self.assertEqual(request.status_code, status.HTTP_200_OK)
132
Franz-Xaver Geigerd9943352018-02-27 14:26:41 +0100133
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400134class DeviceRegisterAPITestCase(APITestCase):
135 """Base class that offers device registration as well as base users
Dirk Vogtf2a33422016-10-11 17:17:26 +0200136
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400137 Attributes:
138 number_of_devices_created (int): The number of devices created in the
139 database.
140 """
Dirk Vogtf2a33422016-10-11 17:17:26 +0200141
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100142 REGISTER_DEVICE_URL = "api_v1_register_device"
143
Dirk Vogtf2a33422016-10-11 17:17:26 +0200144 def setUp(self):
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400145 self.number_of_devices_created = 0
146
147 _, response_data = self._register_device()
148 self.uuid = response_data['uuid']
149 self.token = response_data['token']
150 self.user = APIClient()
151 self.user.credentials(HTTP_AUTHORIZATION='Token ' + self.token)
152
153 _, response_data = self._register_device()
154 self.other_uuid = response_data['uuid']
155 self.other_token = response_data['token']
156 self.other_user = APIClient()
157 self.other_user.credentials(
158 HTTP_AUTHORIZATION='Token ' + self.other_token)
159
160 self.noauth_client = APIClient()
161
162 self.admin_user = User.objects.create_superuser(
163 'somebody', 'somebody@example.com', 'thepassword')
164 self.admin = APIClient()
165 self.admin.force_authenticate(self.admin_user)
166
167 def _register_device(self, **kwargs):
168 """Register a new device
169
170 Arguments:
171 **kwargs: The data to pass the dummy data creation
172 method `Dummy.device_register_data`.
173 Returns:
174 (dict(str, str), dict(str, str)): The tuple composed of the device
175 data that was used for the registration and the data returned by
176 the server in return.
177 """
178 data = Dummy.device_register_data(**kwargs)
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100179 response = self.client.post(reverse(self.REGISTER_DEVICE_URL), data)
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400180 self.assertEqual(response.status_code, status.HTTP_200_OK)
181 self.number_of_devices_created += 1
182
183 return (data, response.data)
184
185
186class ListDevicesTestCase(DeviceRegisterAPITestCase):
Dirk Vogtf2a33422016-10-11 17:17:26 +0200187
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100188 LIST_CREATE_URL = "api_v1_list_devices"
189 RETRIEVE_URL = "api_v1_retrieve_device"
190
Dirk Vogtf2a33422016-10-11 17:17:26 +0200191 def test_device_list(self):
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100192 request = self.admin.get(reverse(self.LIST_CREATE_URL), {})
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400193 self.assertIsNot(request.data['results'][1]['uuid'], '')
194 self.assertEqual(
195 len(request.data['results']), self.number_of_devices_created)
Dirk Vogt36635692016-10-17 12:19:10 +0200196 self.assertEqual(request.status_code, status.HTTP_200_OK)
Dirk Vogtf2a33422016-10-11 17:17:26 +0200197
198 def test_device_list_unauth(self):
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100199 request = self.client.get(reverse(self.LIST_CREATE_URL), {})
Dirk Vogt36635692016-10-17 12:19:10 +0200200 self.assertEqual(request.status_code, status.HTTP_401_UNAUTHORIZED)
Dirk Vogtf2a33422016-10-11 17:17:26 +0200201
202 def test_retrieve_device_auth(self):
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400203 request = self.admin.get(
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100204 reverse(self.RETRIEVE_URL, args=[self.uuid]), {})
Dirk Vogt36635692016-10-17 12:19:10 +0200205 self.assertEqual(request.status_code, status.HTTP_200_OK)
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400206 self.assertEqual(request.data['uuid'], str(self.uuid))
207 self.assertEqual(request.data['token'], self.token)
Dirk Vogtf2a33422016-10-11 17:17:26 +0200208
209 def test_retrieve_device_unauth(self):
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400210 request = self.client.get(
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100211 reverse(self.RETRIEVE_URL, args=[self.uuid]), {})
Dirk Vogt36635692016-10-17 12:19:10 +0200212 self.assertEqual(request.status_code, status.HTTP_401_UNAUTHORIZED)
Dirk Vogtf2a33422016-10-11 17:17:26 +0200213
214 def test_delete_device_auth(self):
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100215 url = reverse(self.RETRIEVE_URL, args=[self.other_uuid])
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400216 request = self.admin.delete(url, {})
Dirk Vogt36635692016-10-17 12:19:10 +0200217 self.assertEqual(request.status_code, status.HTTP_204_NO_CONTENT)
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400218 request = self.admin.delete(url, {})
Dirk Vogt36635692016-10-17 12:19:10 +0200219 self.assertEqual(request.status_code, status.HTTP_404_NOT_FOUND)
Dirk Vogtf2a33422016-10-11 17:17:26 +0200220
Dirk Vogtf2a33422016-10-11 17:17:26 +0200221
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400222class HeartbeatListTestCase(DeviceRegisterAPITestCase):
223
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100224 LIST_CREATE_URL = "api_v1_heartbeats"
225 RETRIEVE_URL = "api_v1_heartbeat"
226 LIST_CREATE_BY_UUID_URL = "api_v1_heartbeats_by_uuid"
227 RETRIEVE_BY_UUID_URL = "api_v1_heartbeat_by_uuid"
228
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400229 @staticmethod
230 def _create_dummy_data(**kwargs):
231 return Dummy.heartbeat_data(**kwargs)
232
233 def _post_multiple(self, client, data, count):
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100234 return [
235 client.post(reverse(self.LIST_CREATE_URL), data)
236 for _ in range(count)]
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400237
238 def _retrieve_single(self, user):
239 count = 5
Borjan Tchakaloff3340e482018-03-19 15:16:25 +0400240 requests = self._post_multiple(self.admin, self.data, count)
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400241 self.assertEqual(len(requests), count)
242 self.assertEqual(requests[0].status_code, status.HTTP_201_CREATED)
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100243 url = reverse(self.RETRIEVE_URL, args=[requests[0].data['id']])
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400244 request = user.get(url)
245 return request.status_code
246
247 def _retrieve_single_by_device(self, user):
248 count = 5
249 requests = self._post_multiple(self.user, self.data, count)
250 self.assertEqual(len(requests), count)
251 self.assertEqual(requests[0].status_code, status.HTTP_201_CREATED)
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100252 url = reverse(self.RETRIEVE_BY_UUID_URL, args=[
253 self.uuid, requests[0].data['device_local_id']])
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400254 request = user.get(url)
255 return request.status_code
Dirk Vogtf2a33422016-10-11 17:17:26 +0200256
257 def setUp(self):
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400258 super(HeartbeatListTestCase, self).setUp()
259 self.data = self._create_dummy_data(uuid=self.uuid)
Dirk Vogt67eb1482016-10-13 12:42:56 +0200260
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200261 def test_create_no_auth(self):
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100262 request = self.noauth_client.post(
263 reverse(self.LIST_CREATE_URL), self.data)
Dirk Vogt36635692016-10-17 12:19:10 +0200264 self.assertEqual(request.status_code, status.HTTP_401_UNAUTHORIZED)
Dirk Vogtf2a33422016-10-11 17:17:26 +0200265
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200266 def test_create_as_admin(self):
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100267 request = self.admin.post(reverse(self.LIST_CREATE_URL), self.data)
Dirk Vogt36635692016-10-17 12:19:10 +0200268 self.assertEqual(request.status_code, status.HTTP_201_CREATED)
Dirk Vogt67eb1482016-10-13 12:42:56 +0200269 self.assertTrue(request.data['id'] > 0)
Dirk Vogtf2a33422016-10-11 17:17:26 +0200270
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200271 def test_create_as_admin_not_existing_device(self):
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100272 request = self.admin.post(
273 reverse(self.LIST_CREATE_URL), self._create_dummy_data())
Dirk Vogt36635692016-10-17 12:19:10 +0200274 self.assertEqual(request.status_code, status.HTTP_404_NOT_FOUND)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200275
276 def test_create_as_uuid_owner(self):
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400277 request = self.user.post(
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100278 reverse(self.LIST_CREATE_URL),
279 self._create_dummy_data(uuid=self.uuid))
Dirk Vogt36635692016-10-17 12:19:10 +0200280 self.assertEqual(request.status_code, status.HTTP_201_CREATED)
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400281 self.assertEqual(request.data['id'], -1)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200282
283 def test_create_as_uuid_not_owner(self):
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400284 request = self.user.post(
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100285 reverse(self.LIST_CREATE_URL),
286 self._create_dummy_data(uuid=self.other_uuid))
Dirk Vogt36635692016-10-17 12:19:10 +0200287 self.assertEqual(request.status_code, status.HTTP_403_FORBIDDEN)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200288
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200289 def test_list(self):
290 count = 5
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400291 self._post_multiple(self.user, self.data, count)
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100292 request = self.admin.get(reverse(self.LIST_CREATE_URL))
Dirk Vogt36635692016-10-17 12:19:10 +0200293 self.assertEqual(request.status_code, status.HTTP_200_OK)
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400294 self.assertEqual(len(request.data['results']), count)
Franz-Xaver Geigerd612fd22018-02-28 10:33:08 +0100295
296 def test_retrieve_single_admin(self):
297 self.assertEqual(
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400298 self._retrieve_single(self.admin), status.HTTP_200_OK)
Dirk Vogte1784882016-10-13 16:09:38 +0200299
300 def test_retrieve_single_device_owner(self):
Franz-Xaver Geigerd612fd22018-02-28 10:33:08 +0100301 self.assertEqual(
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400302 self._retrieve_single(self.user), status.HTTP_403_FORBIDDEN)
303
304 def test_retrieve_single_noauth(self):
305 self.assertEqual(
306 self._retrieve_single(self.noauth_client),
Franz-Xaver Geigerd612fd22018-02-28 10:33:08 +0100307 status.HTTP_401_UNAUTHORIZED)
Dirk Vogte1784882016-10-13 16:09:38 +0200308
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400309 def test_retrieve_single_by_device_admin(self):
Franz-Xaver Geigerd612fd22018-02-28 10:33:08 +0100310 self.assertEqual(
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400311 self._retrieve_single_by_device(self.admin), status.HTTP_200_OK)
Dirk Vogt0d9d5d22016-10-13 16:17:57 +0200312
313 def test_retrieve_single_by_device_device_owner(self):
Franz-Xaver Geigerd612fd22018-02-28 10:33:08 +0100314 self.assertEqual(
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400315 self._retrieve_single_by_device(self.user),
316 status.HTTP_403_FORBIDDEN)
317
318 def test_retrieve_single_by_device_noauth(self):
319 self.assertEqual(
320 self._retrieve_single_by_device(self.noauth_client),
Franz-Xaver Geigerd612fd22018-02-28 10:33:08 +0100321 status.HTTP_401_UNAUTHORIZED)
Dirk Vogt0d9d5d22016-10-13 16:17:57 +0200322
Dirk Vogte1784882016-10-13 16:09:38 +0200323 def test_list_by_uuid(self):
324 count = 5
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400325 self._post_multiple(self.user, self.data, count)
326 self._post_multiple(
327 self.admin, self._create_dummy_data(uuid=self.other_uuid), count)
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100328 url = reverse(self.LIST_CREATE_BY_UUID_URL, args=[self.uuid])
Dirk Vogte1784882016-10-13 16:09:38 +0200329 request = self.admin.get(url)
Dirk Vogt36635692016-10-17 12:19:10 +0200330 self.assertEqual(request.status_code, status.HTTP_200_OK)
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400331 self.assertEqual(len(request.data['results']), count)
Dirk Vogte1784882016-10-13 16:09:38 +0200332
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200333 def test_list_noauth(self):
334 count = 5
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400335 self._post_multiple(self.user, self.data, count)
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100336 request = self.noauth_client.get(reverse(self.LIST_CREATE_URL))
Dirk Vogt36635692016-10-17 12:19:10 +0200337 self.assertEqual(request.status_code, status.HTTP_401_UNAUTHORIZED)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200338
339 def test_list_device_owner(self):
340 count = 5
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400341 self._post_multiple(self.user, self.data, count)
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100342 request = self.user.get(reverse(self.LIST_CREATE_URL))
Dirk Vogt36635692016-10-17 12:19:10 +0200343 self.assertEqual(request.status_code, status.HTTP_403_FORBIDDEN)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200344
Borjan Tchakaloff869cf922018-02-19 11:01:16 +0100345 def test_no_radio_version(self):
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400346 data = self._create_dummy_data(uuid=self.uuid)
Borjan Tchakaloff869cf922018-02-19 11:01:16 +0100347 data.pop('radio_version')
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100348 request = self.user.post(reverse(self.LIST_CREATE_URL), data)
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400349 self.assertEqual(request.status_code, status.HTTP_201_CREATED)
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100350 url = reverse(self.LIST_CREATE_BY_UUID_URL, args=[self.uuid])
Borjan Tchakaloff869cf922018-02-19 11:01:16 +0100351 request = self.admin.get(url)
352 self.assertEqual(request.status_code, status.HTTP_200_OK)
353 self.assertEqual(len(request.data['results']), 1)
354 self.assertIsNone(request.data['results'][0]['radio_version'])
355
356 def test_radio_version_field(self):
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100357 request = self.user.post(reverse(self.LIST_CREATE_URL), self.data)
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400358 self.assertEqual(request.status_code, status.HTTP_201_CREATED)
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100359 url = reverse(self.LIST_CREATE_BY_UUID_URL, args=[self.uuid])
Borjan Tchakaloff869cf922018-02-19 11:01:16 +0100360 request = self.admin.get(url)
361 self.assertEqual(request.status_code, status.HTTP_200_OK)
362 self.assertEqual(len(request.data['results']), 1)
363 self.assertEqual(request.data['results'][0]['radio_version'],
364 self.data['radio_version'])
365
Borjan Tchakaloff866f75e2018-03-01 12:04:00 +0400366 def test_send_non_existent_time(self):
367 """
368 Test the resolution of a naive date-time in which the Europe/Amsterdam daylight saving
369 time transition moved the time "forward".
370 """
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400371 data = self._create_dummy_data(uuid=self.uuid)
Borjan Tchakaloff866f75e2018-03-01 12:04:00 +0400372 # In 2017, the Netherlands changed from CET to CEST on March, 26 at 02:00
373 data['date'] = '2017-03-26 02:34:56'
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100374 request = self.user.post(reverse(self.LIST_CREATE_URL), data)
Borjan Tchakaloff866f75e2018-03-01 12:04:00 +0400375 self.assertEqual(request.status_code, status.HTTP_201_CREATED)
376
377 def test_send_ambiguous_time(self):
378 """
379 Test the resolution of a naive date-time in which the Europe/Amsterdam daylight saving
380 time transition moved the time "backward".
381 """
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400382 data = self._create_dummy_data(uuid=self.uuid)
Borjan Tchakaloff866f75e2018-03-01 12:04:00 +0400383 # In 2017, the Netherlands changed from CEST to CET on October, 29 at 03:00
384 data['date'] = '2017-10-29 02:34:56'
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100385 request = self.user.post(reverse(self.LIST_CREATE_URL), data)
Borjan Tchakaloff866f75e2018-03-01 12:04:00 +0400386 self.assertEqual(request.status_code, status.HTTP_201_CREATED)
387
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200388
389class CrashreportListTestCase(HeartbeatListTestCase):
390
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100391 LIST_CREATE_URL = "api_v1_crashreports"
392 RETRIEVE_URL = "api_v1_crashreport"
393 LIST_CREATE_BY_UUID_URL = "api_v1_crashreports_by_uuid"
394 RETRIEVE_BY_UUID_URL = "api_v1_crashreport_by_uuid"
Dirk Vogt67eb1482016-10-13 12:42:56 +0200395
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400396 @staticmethod
397 def _create_dummy_data(**kwargs):
398 return Dummy.crashreport_data(**kwargs)
Dirk Vogt67eb1482016-10-13 12:42:56 +0200399
400
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400401class LogfileUploadTest(DeviceRegisterAPITestCase):
402
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100403 LIST_CREATE_URL = "api_v1_crashreports"
404 PUT_LOGFILE_URL = "api_v1_putlogfile_for_device_id"
405
Dirk Vogt67eb1482016-10-13 12:42:56 +0200406 def setUp(self):
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400407 super(LogfileUploadTest, self).setUp()
Dirk Vogt67eb1482016-10-13 12:42:56 +0200408
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100409 url = reverse(self.LIST_CREATE_URL)
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400410 for uuid in [self.uuid, self.other_uuid]:
411 data = Dummy.crashreport_data(uuid=uuid)
412 for _ in range(2):
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100413 self.user.post(url, data)
Dirk Vogt36635692016-10-17 12:19:10 +0200414
Dirk Vogt67eb1482016-10-13 12:42:56 +0200415 def test_Logfile_upload_as_admin(self):
Dirk Vogt36635692016-10-17 12:19:10 +0200416 f = tempfile.NamedTemporaryFile('w+', suffix=".log", delete=True)
417 f.write(u"blihblahblub")
Borjan Tchakaloffec814a72018-02-28 11:16:53 +0400418 request = self.admin.post(
Franz-Xaver Geiger67504d02018-03-19 15:04:48 +0100419 reverse(self.PUT_LOGFILE_URL, args=[
420 self.uuid, 1, os.path.basename(f.name)
421 ]),
Dirk Vogt36635692016-10-17 12:19:10 +0200422 {'file': f}, format="multipart")
423 self.assertEqual(status.HTTP_201_CREATED, request.status_code)