blob: ed41cbd60cfa2738547e284cb11c6d02b960c6d3 [file] [log] [blame]
Mitja Nikolaus03e412b2018-09-18 17:50:15 +02001"""Tests for the views module."""
2
3import unittest
4from urllib.parse import urlencode
5
Mitja Nikolaus03e412b2018-09-18 17:50:15 +02006from django.urls import reverse
7
8from rest_framework import status
9
10from crashreport_stats.tests.utils import Dummy, HiccupStatsAPITestCase
11
12# pylint: disable=too-many-public-methods
13
14
15class ViewsTestCase(HiccupStatsAPITestCase):
16 """Test cases for the statistics views."""
17
18 home_url = reverse("device")
19 device_url = reverse("hiccup_stats_device")
20 versions_url = reverse("hiccup_stats_versions")
21 versions_all_url = reverse("hiccup_stats_versions_all")
22
23 @staticmethod
24 def _url_with_params(url, params):
25 # Encode params, but keep slashes because we want to accept URLs as
26 # parameter values.
27 encoded_params = urlencode(params, safe="/")
28 return "{}?{}".format(url, encoded_params)
29
30 def _get_with_params(self, url, params):
31 return self.fp_staff_client.get(self._url_with_params(url, params))
32
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020033 def test_home_view_as_fp_staff(self):
34 """Test that Fairphone staff users can access the home view."""
35 self._assert_get_as_fp_staff_succeeds(self.home_url)
36
37 def test_home_view_as_device_owner(self):
38 """Test that device owner users can not access the home view."""
Mitja Nikolausa9017982018-11-21 12:14:45 +010039 # Assert that the permission is denied.
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020040 self._assert_get_as_device_owner_fails(
Mitja Nikolausa9017982018-11-21 12:14:45 +010041 self.home_url, expected_status=status.HTTP_403_FORBIDDEN
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020042 )
43
44 def test_home_view_no_auth(self):
45 """Test that one can not access the home view without auth."""
Mitja Nikolausa9017982018-11-21 12:14:45 +010046 # Assert that the permission is denied
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020047 self._assert_get_without_authentication_fails(
Mitja Nikolausa9017982018-11-21 12:14:45 +010048 self.home_url, expected_status=status.HTTP_403_FORBIDDEN
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020049 )
50
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020051 def test_device_view_as_fp_staff(self):
52 """Test that Fairphone staff users can access the device view."""
53 self._assert_get_as_fp_staff_succeeds(
54 self._url_with_params(
55 self.device_url, {"uuid": self.device_owner_device.uuid}
56 )
57 )
58
59 def test_device_view_as_device_owner(self):
60 """Test that device owner users can not access the device view."""
Mitja Nikolausa9017982018-11-21 12:14:45 +010061 # Assert that the the permission is denied.
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020062 self._assert_get_as_device_owner_fails(
63 self._url_with_params(
64 self.device_url, {"uuid": self.device_owner_device.uuid}
Mitja Nikolausa9017982018-11-21 12:14:45 +010065 )
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020066 )
67
68 def test_device_view_no_auth(self):
69 """Test that non-authenticated users can not access the device view."""
Mitja Nikolausa9017982018-11-21 12:14:45 +010070 # Assert that the permission is denied.
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020071 self._assert_get_without_authentication_fails(
72 self._url_with_params(
73 self.device_url, {"uuid": self.device_owner_device.uuid}
74 ),
Mitja Nikolausa9017982018-11-21 12:14:45 +010075 expected_status=status.HTTP_403_FORBIDDEN,
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020076 )
77
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020078 def test_versions_view_as_fp_staff(self):
79 """Test that Fairphone staff users can access the versions view."""
80 self._assert_get_as_fp_staff_succeeds(self.versions_url)
81
82 def test_versions_view_as_device_owner(self):
83 """Test that device owner users can not access the versions view."""
Mitja Nikolausa9017982018-11-21 12:14:45 +010084 # Assert that the permission is denied
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020085 self._assert_get_as_device_owner_fails(
Mitja Nikolausa9017982018-11-21 12:14:45 +010086 self.versions_url, expected_status=status.HTTP_403_FORBIDDEN
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020087 )
88
89 def test_versions_view_no_auth(self):
90 """Test one can not access the versions view without auth."""
Mitja Nikolausa9017982018-11-21 12:14:45 +010091 # Assert that the permission is denied
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020092 self._assert_get_without_authentication_fails(
Mitja Nikolausa9017982018-11-21 12:14:45 +010093 self.versions_url, expected_status=status.HTTP_403_FORBIDDEN
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020094 )
95
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020096 def test_versions_all_view_as_fp_staff(self):
97 """Test that Fairphone staff users can access the versions all view."""
98 self._assert_get_as_fp_staff_succeeds(self.versions_all_url)
99
100 def test_versions_all_view_as_device_owner(self):
101 """Test that device owner users can not access the versions all view."""
Mitja Nikolausa9017982018-11-21 12:14:45 +0100102 # Assert that the permission is denied
Mitja Nikolaus03e412b2018-09-18 17:50:15 +0200103 self._assert_get_as_device_owner_fails(
Mitja Nikolausa9017982018-11-21 12:14:45 +0100104 self.versions_all_url, expected_status=status.HTTP_403_FORBIDDEN
Mitja Nikolaus03e412b2018-09-18 17:50:15 +0200105 )
106
107 def test_versions_all_view_no_auth(self):
108 """Test that one can not access the versions all view without auth."""
Mitja Nikolausa9017982018-11-21 12:14:45 +0100109 # Assert that the permission is denied
Mitja Nikolaus03e412b2018-09-18 17:50:15 +0200110 self._assert_get_without_authentication_fails(
Mitja Nikolausa9017982018-11-21 12:14:45 +0100111 self.versions_all_url, expected_status=status.HTTP_403_FORBIDDEN
Mitja Nikolaus03e412b2018-09-18 17:50:15 +0200112 )
113
Mitja Nikolaus03e412b2018-09-18 17:50:15 +0200114 def test_home_view_post_as_fp_staff(self):
115 """Test HTTP POST method to home view as Fairphone staff user."""
116 response = self.fp_staff_client.post(
117 self.home_url, data={"uuid": str(self.device_owner_device.uuid)}
118 )
119
120 # Assert that the response is a redirect to the device page
121 self.assertRedirects(
122 response,
123 self._url_with_params(
124 self.device_url, {"uuid": self.device_owner_device.uuid}
125 ),
126 )
127
128 def test_home_view_post_no_auth(self):
129 """Test HTTP POST method to home view without authentication."""
130 response = self.client.post(
131 self.home_url, data={"uuid": str(self.device_owner_device.uuid)}
132 )
133
Mitja Nikolausa9017982018-11-21 12:14:45 +0100134 # Assert that the permission is denied
135 self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
Mitja Nikolaus03e412b2018-09-18 17:50:15 +0200136
137 def test_home_view_post_as_device_owner(self):
138 """Test HTTP POST method to home view as device owner."""
139 response = self.device_owner_client.post(
140 self.home_url, data={"uuid": str(self.device_owner_device.uuid)}
141 )
142
Mitja Nikolausa9017982018-11-21 12:14:45 +0100143 # Assert that the permission is denied
144 self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
Mitja Nikolaus03e412b2018-09-18 17:50:15 +0200145
146 def test_get_home_view(self):
147 """Test getting the home view with device search form."""
148 response = self.fp_staff_client.get(self.home_url)
149 self.assertEqual(response.status_code, status.HTTP_200_OK)
150 self.assertTemplateUsed(
151 response, "crashreport_stats/home.html", count=1
152 )
153 self.assertEqual(response.context["devices"], None)
154
155 def test_home_view_filter_devices_by_uuid(self):
156 """Test filtering devices by UUID."""
157 # Create a device
Mitja Nikolaus77dd5652018-12-06 11:27:01 +0100158 device = Dummy.create_device(Dummy.create_user())
Mitja Nikolaus03e412b2018-09-18 17:50:15 +0200159
160 # Filter devices by UUID of the created device
161 response = self.fp_staff_client.post(
162 self.home_url, data={"uuid": str(device.uuid)}
163 )
164
165 # Assert that the the client is redirected to the device page
166 self.assertRedirects(
167 response,
168 self._url_with_params(self.device_url, {"uuid": device.uuid}),
169 )
170
171 def test_home_view_filter_devices_by_uuid_part(self):
172 """Test filtering devices by start of UUID."""
173 # Create a device
Mitja Nikolaus77dd5652018-12-06 11:27:01 +0100174 device = Dummy.create_device(Dummy.create_user())
Mitja Nikolaus03e412b2018-09-18 17:50:15 +0200175
176 # Filter devices with start of the created device's UUID
177 response = self.fp_staff_client.post(
178 self.home_url, data={"uuid": str(device.uuid)[:4]}
179 )
180
181 # Assert that the the client is redirected to the device page
182 self.assertRedirects(
183 response,
184 self._url_with_params(self.device_url, {"uuid": device.uuid}),
185 )
186
187 def test_home_view_filter_devices_by_uuid_part_ambiguous_result(self):
188 """Test filtering devices with common start of UUIDs."""
189 # Create two devices
Mitja Nikolaus77dd5652018-12-06 11:27:01 +0100190 device1 = Dummy.create_device(Dummy.create_user())
191 device2 = Dummy.create_device(
192 Dummy.create_user(username=Dummy.USERNAMES[1])
Mitja Nikolaus03e412b2018-09-18 17:50:15 +0200193 )
194
195 # Adapt the devices' UUID so that they start with the same characters
196 device1.uuid = "4060fd90-6de1-4b03-a380-4277c703e913"
197 device1.save()
198 device2.uuid = "4061c59b-823d-4ec6-a463-8ac0c1cea67d"
199 device2.save()
200
201 # Filter devices with first three (common) characters of the UUID
202 response = self.fp_staff_client.post(
203 self.home_url, data={"uuid": str(device1.uuid)[:3]}
204 )
205
206 # Assert that both devices are part of the result
207 self.assertEqual(response.status_code, status.HTTP_200_OK)
208 self.assertTemplateUsed(
209 response, "crashreport_stats/home.html", count=1
210 )
211 self.assertEqual(set(response.context["devices"]), {device1, device2})
212
213 def test_home_view_filter_devices_empty_database(self):
214 """Test filtering devices on an empty database."""
215 response = self.fp_staff_client.post(
216 self.home_url, data={"uuid": "TestUUID"}
217 )
218 self.assertEqual(response.status_code, status.HTTP_200_OK)
219 self.assertIsNotNone(response.content)
220
221 def test_home_view_filter_devices_no_uuid(self):
222 """Test filtering devices without specifying UUID."""
223 response = self.fp_staff_client.post(self.home_url)
224 self.assertEqual(response.status_code, status.HTTP_200_OK)
225 self.assertTemplateUsed(
226 response, "crashreport_stats/home.html", count=1
227 )
228 self.assertEqual(response.context["devices"], None)
229
230 def test_get_device_view_empty_database(self):
231 """Test getting device view on an empty database."""
232 response = self.fp_staff_client.get(self.device_url)
233 self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
234
235 def test_get_device_view(self):
236 """Test getting device view."""
237 # Create a device
Mitja Nikolaus77dd5652018-12-06 11:27:01 +0100238 device = Dummy.create_device(Dummy.create_user())
Mitja Nikolaus03e412b2018-09-18 17:50:15 +0200239
240 # Get the corresponding device view
241 response = self._get_with_params(self.device_url, {"uuid": device.uuid})
242
243 # Assert that the view is constructed from the correct templates and
244 # the response context contains the device UUID
245 self.assertEqual(response.status_code, status.HTTP_200_OK)
246 self.assertTemplateUsed(
247 response, "crashreport_stats/device.html", count=1
248 )
249 self.assertTemplateUsed(
250 response, "crashreport_stats/tags/device_overview.html", count=1
251 )
252 self.assertTemplateUsed(
253 response,
254 "crashreport_stats/tags/device_update_history.html",
255 count=1,
256 )
257 self.assertTemplateUsed(
258 response,
259 "crashreport_stats/tags/device_report_history.html",
260 count=1,
261 )
262 self.assertTemplateUsed(
263 response,
264 "crashreport_stats/tags/device_crashreport_table.html",
265 count=1,
266 )
267 self.assertEqual(response.context["uuid"], str(device.uuid))
268
269 def _assert_versions_view_templates_are_used(self, response):
270 self.assertTemplateUsed(
271 response, "crashreport_stats/versions.html", count=1
272 )
273 self.assertTemplateUsed(
274 response, "crashreport_stats/tags/versions_table.html", count=1
275 )
276 self.assertTemplateUsed(
277 response, "crashreport_stats/tags/versions_pie_chart.html", count=1
278 )
279 self.assertTemplateUsed(
280 response, "crashreport_stats/tags/versions_bar_chart.html", count=1
281 )
282 self.assertTemplateUsed(
283 response, "crashreport_stats/tags/versions_area_chart.html", count=1
284 )
285
286 @unittest.skip("Fails because of wrong boolean usage in views.py")
287 def test_get_versions_view_empty_database(self):
288 """Test getting versions view on an empty database."""
289 response = self.fp_staff_client.get(self.versions_url)
290
291 # Assert that the correct templates are used and the response context
292 # contains the correct value for is_official_release
293 self._assert_versions_view_templates_are_used(response)
294 self.assertEqual(response.context["is_official_release"], True)
295
296 @unittest.skip("Fails because of wrong boolean usage in views.py")
297 def test_get_versions_view(self):
298 """Test getting versions view."""
299 # Create a version
Mitja Nikolaus77dd5652018-12-06 11:27:01 +0100300 Dummy.create_version()
Mitja Nikolaus03e412b2018-09-18 17:50:15 +0200301
302 # Get the versions view
303 response = self.fp_staff_client.get(self.versions_url)
304
305 # Assert that the correct templates are used and the response context
306 # contains the correct value for is_official_release
307 self._assert_versions_view_templates_are_used(response)
308 self.assertEqual(response.context["is_official_release"], True)
309
310 @unittest.skip("Fails because of wrong boolean usage in views.py")
311 def test_get_versions_all_view_no_versions(self):
312 """Test getting versions all view on an empty database."""
313 response = self.fp_staff_client.get(self.versions_all_url)
314
315 # Assert that the correct templates are used and the response context
316 # contains an empty value for is_official_release
317 self._assert_versions_view_templates_are_used(response)
318 self.assertEqual(response.context.get("is_official_release", ""), "")
319
320 @unittest.skip("Fails because of wrong boolean usage in views.py")
321 def test_get_versions_all_view(self):
322 """Test getting versions view."""
323 # Create a version
Mitja Nikolaus77dd5652018-12-06 11:27:01 +0100324 Dummy.create_version()
Mitja Nikolaus03e412b2018-09-18 17:50:15 +0200325
326 # Get the versions view
327 response = self.fp_staff_client.get(self.versions_all_url)
328
329 # Assert that the correct templates are used and the response context
330 # contains the an empty value for is_official_release
331 self._assert_versions_view_templates_are_used(response)
332 self.assertEqual(response.context.get("is_official_release", ""), "")