blob: adcec7d65937e35a0a71628597411d1859944ff3 [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
6from django.conf import settings
7from django.urls import reverse
8
9from rest_framework import status
10
11from crashreport_stats.tests.utils import Dummy, HiccupStatsAPITestCase
12
13# pylint: disable=too-many-public-methods
14
15
16class ViewsTestCase(HiccupStatsAPITestCase):
17 """Test cases for the statistics views."""
18
19 home_url = reverse("device")
20 device_url = reverse("hiccup_stats_device")
21 versions_url = reverse("hiccup_stats_versions")
22 versions_all_url = reverse("hiccup_stats_versions_all")
23
24 @staticmethod
25 def _url_with_params(url, params):
26 # Encode params, but keep slashes because we want to accept URLs as
27 # parameter values.
28 encoded_params = urlencode(params, safe="/")
29 return "{}?{}".format(url, encoded_params)
30
31 def _get_with_params(self, url, params):
32 return self.fp_staff_client.get(self._url_with_params(url, params))
33
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020034 def test_home_view_as_fp_staff(self):
35 """Test that Fairphone staff users can access the home view."""
36 self._assert_get_as_fp_staff_succeeds(self.home_url)
37
38 def test_home_view_as_device_owner(self):
39 """Test that device owner users can not access the home view."""
40 # Assert that the response is a redirect (to the login page)
41 self._assert_get_as_device_owner_fails(
42 self.home_url, expected_status=status.HTTP_302_FOUND
43 )
44
45 def test_home_view_no_auth(self):
46 """Test that one can not access the home view without auth."""
47 # Assert that the response is a redirect (to the login page)
48 self._assert_get_without_authentication_fails(
49 self.home_url, expected_status=status.HTTP_302_FOUND
50 )
51
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020052 def test_device_view_as_fp_staff(self):
53 """Test that Fairphone staff users can access the device view."""
54 self._assert_get_as_fp_staff_succeeds(
55 self._url_with_params(
56 self.device_url, {"uuid": self.device_owner_device.uuid}
57 )
58 )
59
60 def test_device_view_as_device_owner(self):
61 """Test that device owner users can not access the device view."""
62 # Assert that the response is a redirect (to the login page)
63 self._assert_get_as_device_owner_fails(
64 self._url_with_params(
65 self.device_url, {"uuid": self.device_owner_device.uuid}
66 ),
67 expected_status=status.HTTP_302_FOUND,
68 )
69
70 def test_device_view_no_auth(self):
71 """Test that non-authenticated users can not access the device view."""
72 # Assert that the response is a redirect (to the login page)
73 self._assert_get_without_authentication_fails(
74 self._url_with_params(
75 self.device_url, {"uuid": self.device_owner_device.uuid}
76 ),
77 expected_status=status.HTTP_302_FOUND,
78 )
79
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020080 def test_versions_view_as_fp_staff(self):
81 """Test that Fairphone staff users can access the versions view."""
82 self._assert_get_as_fp_staff_succeeds(self.versions_url)
83
84 def test_versions_view_as_device_owner(self):
85 """Test that device owner users can not access the versions view."""
86 # Assert that the response is a redirect (to the login page)
87 self._assert_get_as_device_owner_fails(
88 self.versions_url, expected_status=status.HTTP_302_FOUND
89 )
90
91 def test_versions_view_no_auth(self):
92 """Test one can not access the versions view without auth."""
93 # Assert that the response is a redirect (to the login page)
94 self._assert_get_without_authentication_fails(
95 self.versions_url, expected_status=status.HTTP_302_FOUND
96 )
97
Mitja Nikolaus03e412b2018-09-18 17:50:15 +020098 def test_versions_all_view_as_fp_staff(self):
99 """Test that Fairphone staff users can access the versions all view."""
100 self._assert_get_as_fp_staff_succeeds(self.versions_all_url)
101
102 def test_versions_all_view_as_device_owner(self):
103 """Test that device owner users can not access the versions all view."""
104 # Assert that the response is a redirect (to the login page)
105 self._assert_get_as_device_owner_fails(
106 self.versions_all_url, expected_status=status.HTTP_302_FOUND
107 )
108
109 def test_versions_all_view_no_auth(self):
110 """Test that one can not access the versions all view without auth."""
111 # Assert that the response is a redirect (to the login page)
112 self._assert_get_without_authentication_fails(
113 self.versions_all_url, expected_status=status.HTTP_302_FOUND
114 )
115
Mitja Nikolaus03e412b2018-09-18 17:50:15 +0200116 def test_home_view_post_as_fp_staff(self):
117 """Test HTTP POST method to home view as Fairphone staff user."""
118 response = self.fp_staff_client.post(
119 self.home_url, data={"uuid": str(self.device_owner_device.uuid)}
120 )
121
122 # Assert that the response is a redirect to the device page
123 self.assertRedirects(
124 response,
125 self._url_with_params(
126 self.device_url, {"uuid": self.device_owner_device.uuid}
127 ),
128 )
129
130 def test_home_view_post_no_auth(self):
131 """Test HTTP POST method to home view without authentication."""
132 response = self.client.post(
133 self.home_url, data={"uuid": str(self.device_owner_device.uuid)}
134 )
135
136 # Assert that the response is a redirect to the login page
137 self.assertRedirects(
138 response,
139 self._url_with_params(
140 settings.ACCOUNT_LOGOUT_REDIRECT_URL,
141 {"next": settings.LOGIN_REDIRECT_URL},
142 ),
143 )
144
145 def test_home_view_post_as_device_owner(self):
146 """Test HTTP POST method to home view as device owner."""
147 response = self.device_owner_client.post(
148 self.home_url, data={"uuid": str(self.device_owner_device.uuid)}
149 )
150
151 # Assert that the response is a redirect to the login page
152
153 self.assertRedirects(
154 response,
155 self._url_with_params(
156 settings.ACCOUNT_LOGOUT_REDIRECT_URL,
157 {"next": settings.LOGIN_REDIRECT_URL},
158 ),
159 )
160
161 def test_get_home_view(self):
162 """Test getting the home view with device search form."""
163 response = self.fp_staff_client.get(self.home_url)
164 self.assertEqual(response.status_code, status.HTTP_200_OK)
165 self.assertTemplateUsed(
166 response, "crashreport_stats/home.html", count=1
167 )
168 self.assertEqual(response.context["devices"], None)
169
170 def test_home_view_filter_devices_by_uuid(self):
171 """Test filtering devices by UUID."""
172 # Create a device
173 device = Dummy.create_dummy_device(Dummy.create_dummy_user())
174
175 # Filter devices by UUID of the created device
176 response = self.fp_staff_client.post(
177 self.home_url, data={"uuid": str(device.uuid)}
178 )
179
180 # Assert that the the client is redirected to the device page
181 self.assertRedirects(
182 response,
183 self._url_with_params(self.device_url, {"uuid": device.uuid}),
184 )
185
186 def test_home_view_filter_devices_by_uuid_part(self):
187 """Test filtering devices by start of UUID."""
188 # Create a device
189 device = Dummy.create_dummy_device(Dummy.create_dummy_user())
190
191 # Filter devices with start of the created device's UUID
192 response = self.fp_staff_client.post(
193 self.home_url, data={"uuid": str(device.uuid)[:4]}
194 )
195
196 # Assert that the the client is redirected to the device page
197 self.assertRedirects(
198 response,
199 self._url_with_params(self.device_url, {"uuid": device.uuid}),
200 )
201
202 def test_home_view_filter_devices_by_uuid_part_ambiguous_result(self):
203 """Test filtering devices with common start of UUIDs."""
204 # Create two devices
205 device1 = Dummy.create_dummy_device(Dummy.create_dummy_user())
206 device2 = Dummy.create_dummy_device(
207 Dummy.create_dummy_user(username=Dummy.USERNAMES[1])
208 )
209
210 # Adapt the devices' UUID so that they start with the same characters
211 device1.uuid = "4060fd90-6de1-4b03-a380-4277c703e913"
212 device1.save()
213 device2.uuid = "4061c59b-823d-4ec6-a463-8ac0c1cea67d"
214 device2.save()
215
216 # Filter devices with first three (common) characters of the UUID
217 response = self.fp_staff_client.post(
218 self.home_url, data={"uuid": str(device1.uuid)[:3]}
219 )
220
221 # Assert that both devices are part of the result
222 self.assertEqual(response.status_code, status.HTTP_200_OK)
223 self.assertTemplateUsed(
224 response, "crashreport_stats/home.html", count=1
225 )
226 self.assertEqual(set(response.context["devices"]), {device1, device2})
227
228 def test_home_view_filter_devices_empty_database(self):
229 """Test filtering devices on an empty database."""
230 response = self.fp_staff_client.post(
231 self.home_url, data={"uuid": "TestUUID"}
232 )
233 self.assertEqual(response.status_code, status.HTTP_200_OK)
234 self.assertIsNotNone(response.content)
235
236 def test_home_view_filter_devices_no_uuid(self):
237 """Test filtering devices without specifying UUID."""
238 response = self.fp_staff_client.post(self.home_url)
239 self.assertEqual(response.status_code, status.HTTP_200_OK)
240 self.assertTemplateUsed(
241 response, "crashreport_stats/home.html", count=1
242 )
243 self.assertEqual(response.context["devices"], None)
244
245 def test_get_device_view_empty_database(self):
246 """Test getting device view on an empty database."""
247 response = self.fp_staff_client.get(self.device_url)
248 self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
249
250 def test_get_device_view(self):
251 """Test getting device view."""
252 # Create a device
253 device = Dummy.create_dummy_device(Dummy.create_dummy_user())
254
255 # Get the corresponding device view
256 response = self._get_with_params(self.device_url, {"uuid": device.uuid})
257
258 # Assert that the view is constructed from the correct templates and
259 # the response context contains the device UUID
260 self.assertEqual(response.status_code, status.HTTP_200_OK)
261 self.assertTemplateUsed(
262 response, "crashreport_stats/device.html", count=1
263 )
264 self.assertTemplateUsed(
265 response, "crashreport_stats/tags/device_overview.html", count=1
266 )
267 self.assertTemplateUsed(
268 response,
269 "crashreport_stats/tags/device_update_history.html",
270 count=1,
271 )
272 self.assertTemplateUsed(
273 response,
274 "crashreport_stats/tags/device_report_history.html",
275 count=1,
276 )
277 self.assertTemplateUsed(
278 response,
279 "crashreport_stats/tags/device_crashreport_table.html",
280 count=1,
281 )
282 self.assertEqual(response.context["uuid"], str(device.uuid))
283
284 def _assert_versions_view_templates_are_used(self, response):
285 self.assertTemplateUsed(
286 response, "crashreport_stats/versions.html", count=1
287 )
288 self.assertTemplateUsed(
289 response, "crashreport_stats/tags/versions_table.html", count=1
290 )
291 self.assertTemplateUsed(
292 response, "crashreport_stats/tags/versions_pie_chart.html", count=1
293 )
294 self.assertTemplateUsed(
295 response, "crashreport_stats/tags/versions_bar_chart.html", count=1
296 )
297 self.assertTemplateUsed(
298 response, "crashreport_stats/tags/versions_area_chart.html", count=1
299 )
300
301 @unittest.skip("Fails because of wrong boolean usage in views.py")
302 def test_get_versions_view_empty_database(self):
303 """Test getting versions view on an empty database."""
304 response = self.fp_staff_client.get(self.versions_url)
305
306 # Assert that the correct templates are used and the response context
307 # contains the correct value for is_official_release
308 self._assert_versions_view_templates_are_used(response)
309 self.assertEqual(response.context["is_official_release"], True)
310
311 @unittest.skip("Fails because of wrong boolean usage in views.py")
312 def test_get_versions_view(self):
313 """Test getting versions view."""
314 # Create a version
315 Dummy.create_dummy_version()
316
317 # Get the versions view
318 response = self.fp_staff_client.get(self.versions_url)
319
320 # Assert that the correct templates are used and the response context
321 # contains the correct value for is_official_release
322 self._assert_versions_view_templates_are_used(response)
323 self.assertEqual(response.context["is_official_release"], True)
324
325 @unittest.skip("Fails because of wrong boolean usage in views.py")
326 def test_get_versions_all_view_no_versions(self):
327 """Test getting versions all view on an empty database."""
328 response = self.fp_staff_client.get(self.versions_all_url)
329
330 # Assert that the correct templates are used and the response context
331 # contains an empty value for is_official_release
332 self._assert_versions_view_templates_are_used(response)
333 self.assertEqual(response.context.get("is_official_release", ""), "")
334
335 @unittest.skip("Fails because of wrong boolean usage in views.py")
336 def test_get_versions_all_view(self):
337 """Test getting versions view."""
338 # Create a version
339 Dummy.create_dummy_version()
340
341 # Get the versions view
342 response = self.fp_staff_client.get(self.versions_all_url)
343
344 # Assert that the correct templates are used and the response context
345 # contains the an empty value for is_official_release
346 self._assert_versions_view_templates_are_used(response)
347 self.assertEqual(response.context.get("is_official_release", ""), "")