Add tests for stats endpoints authorization
Add tests that ensure all stats endpoints URLs are only accessible
for admin users and Fairphone staff.
Further move attributes from _VersionTestCase to a level where they are
actually used, i.e. VersionTestCase and VersionDailyTestCase.
Issue: HIC-205
Change-Id: Iad0dc2acd7d8eb5d33c6681e07b6bbbbdcb28d94
diff --git a/crashreport_stats/tests.py b/crashreport_stats/tests.py
index e99674b..f69ff0c 100644
--- a/crashreport_stats/tests.py
+++ b/crashreport_stats/tests.py
@@ -7,17 +7,19 @@
import operator
import os
import unittest
+from urllib.parse import urlencode
import zipfile
import pytz
+from django.conf import settings
from django.contrib.auth.models import Group
from django.core.management import call_command
from django.test import TestCase
from django.urls import reverse
-from django.utils.http import urlencode
from rest_framework import status
+from rest_framework.authtoken.models import Token
from rest_framework.test import APITestCase, APIClient
from crashreport_stats.models import (
@@ -330,17 +332,18 @@
return entity
-class _HiccupAPITestCase(APITestCase):
- """Abstract class for Hiccup REST API test cases to inherit from."""
+class _HiccupStatsAPITestCase(APITestCase):
+ """Abstract class for Hiccup stats REST API test cases to inherit from."""
@classmethod
def setUpTestData(cls): # noqa: N802
- """Create an admin and client user for accessing the API.
+ """Create an admin and two client users for accessing the API.
The APIClient that can be used to make authenticated requests as
- admin user is stored in self.admin. Another client (which is
- related to a user that is part of the Fairphone software team group)
- is stored in self.fp_staff_client.
+ admin user is stored in self.admin. A client which is related to a
+ user that is part of the Fairphone staff group is stored in
+ self.fp_staff_client. A client which is related to a device owner
+ user is stored in self.device_owner_client.
"""
admin_user = User.objects.create_superuser(
"somebody", "somebody@example.com", "thepassword"
@@ -348,17 +351,53 @@
cls.admin = APIClient()
cls.admin.force_authenticate(admin_user)
- fp_software_team_group = Group(name=FP_STAFF_GROUP_NAME)
- fp_software_team_group.save()
- fp_software_team_user = User.objects.create_user(
+ fp_staff_group = Group(name=FP_STAFF_GROUP_NAME)
+ fp_staff_group.save()
+ fp_staff_user = User.objects.create_user(
"fp_staff", "somebody@fairphone.com", "thepassword"
)
- fp_software_team_user.groups.add(fp_software_team_group)
+ fp_staff_user.groups.add(fp_staff_group)
cls.fp_staff_client = APIClient()
- cls.fp_staff_client.login(username="fp_staff", password="thepassword")
+ cls.fp_staff_client.force_login(fp_staff_user)
+
+ cls.device_owner_user = User.objects.create_user(
+ "device_owner", "somebody@somemail.com", "thepassword"
+ )
+ Token.objects.create(user=cls.device_owner_user)
+ cls.device_owner_device = Dummy.create_dummy_device(
+ user=cls.device_owner_user
+ )
+ cls.device_owner_client = APIClient()
+ cls.device_owner_client.credentials(
+ HTTP_AUTHORIZATION="Token " + cls.device_owner_user.auth_token.key
+ )
+
+ def _assert_get_as_admin_user_succeeds(
+ self, url, expected_status=status.HTTP_200_OK
+ ):
+ response = self.admin.get(url)
+ self.assertEqual(response.status_code, expected_status)
+
+ def _assert_get_as_fp_staff_succeeds(
+ self, url, expected_status=status.HTTP_200_OK
+ ):
+ response = self.fp_staff_client.get(url)
+ self.assertEqual(response.status_code, expected_status)
+
+ def _assert_get_without_authentication_fails(
+ self, url, expected_status=status.HTTP_401_UNAUTHORIZED
+ ):
+ response = self.client.get(url)
+ self.assertEqual(response.status_code, expected_status)
+
+ def _assert_get_as_device_owner_fails(
+ self, url, expected_status=status.HTTP_403_FORBIDDEN
+ ):
+ response = self.device_owner_client.get(url)
+ self.assertEqual(response.status_code, expected_status)
-class StatusTestCase(_HiccupAPITestCase):
+class StatusTestCase(_HiccupStatsAPITestCase):
"""Test the status endpoint."""
status_url = reverse("hiccup_stats_api_v1_status")
@@ -374,10 +413,29 @@
self.assertEqual(response.data["crashreports"], num_crashreports)
self.assertEqual(response.data["heartbeats"], num_heartbeats)
+ def test_status_url_as_admin(self):
+ """Test that admin users can access the status URL."""
+ self._assert_get_as_admin_user_succeeds(self.status_url)
+
+ def test_status_url_as_fp_staff(self):
+ """Test that Fairphone staff users can access the status URL."""
+ self._assert_get_as_fp_staff_succeeds(self.status_url)
+
+ def test_status_url_as_device_owner(self):
+ """Test that device owner users can not access the status URL."""
+ self._assert_get_as_device_owner_fails(self.status_url)
+
+ def test_status_url_no_auth(self):
+ """Test that non-authenticated users can not access the status URL."""
+ self._assert_get_without_authentication_fails(self.status_url)
+
def test_get_status_empty_database(self):
"""Get the status when the database is empty."""
response = self.fp_staff_client.get(self.status_url)
- self._assert_status_response_is(response, 0, 0, 0)
+
+ # Assert that only the device that was created by the setUpTestData()
+ # method is found.
+ self._assert_status_response_is(response, 1, 0, 0)
def test_get_status(self):
"""Get the status after some reports have been created."""
@@ -391,24 +449,17 @@
Dummy.create_dummy_user(username=Dummy.USERNAMES[1])
)
- # Assert that the status includes the appropriate numbers
+ # Assert that the status includes the appropriate numbers (a third
+ # device was created by the setUpTestData() method)
response = self.fp_staff_client.get(self.status_url)
self._assert_status_response_is(
- response, num_devices=2, num_crashreports=1, num_heartbeats=1
+ response, num_devices=3, num_crashreports=1, num_heartbeats=1
)
-class _VersionTestCase(_HiccupAPITestCase):
+class _VersionTestCase(_HiccupStatsAPITestCase):
"""Abstract class for version-related test cases to inherit from."""
- # The attribute name characterising the unicity of a stats entry (the
- # named identifier)
- unique_entry_name = "build_fingerprint"
- # The collection of unique entries to post
- unique_entries = Dummy.BUILD_FINGERPRINTS
- # The URL to retrieve the stats entries from
- endpoint_url = reverse("hiccup_stats_api_v1_versions")
-
@staticmethod
def _create_dummy_version(**kwargs):
return Dummy.create_dummy_version(**kwargs)
@@ -423,28 +474,17 @@
self.assertEqual(response.data["count"], count)
self.assertEqual(len(response.data["results"]), count)
- def _assert_device_owner_has_no_get_access(self, entries_url):
- # Create a user and device
- user = Dummy.create_dummy_user()
- device = Dummy.create_dummy_device(user=user)
-
- # Create authenticated client
- user = APIClient()
- user.credentials(HTTP_AUTHORIZATION="Token " + device.token)
-
- # Try getting entries using the client
- response = user.get(entries_url)
- self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
-
- def _assert_filter_result_matches(self, filter_params, expected_result):
+ def _assert_filter_result_matches(
+ self, endpoint_url, unique_entry_name, filter_params, expected_result
+ ):
# List entities with filter
- response = self._get_with_params(self.endpoint_url, filter_params)
+ response = self._get_with_params(endpoint_url, filter_params)
# Expect only the single matching result to be returned
self._assert_result_length_is(response, 1)
self.assertEqual(
- response.data["results"][0][self.unique_entry_name],
- getattr(expected_result, self.unique_entry_name),
+ response.data["results"][0][unique_entry_name],
+ getattr(expected_result, unique_entry_name),
)
@@ -453,6 +493,14 @@
# pylint: disable=too-many-ancestors
+ # The attribute name characterising the unicity of a stats entry (the
+ # named identifier)
+ unique_entry_name = "build_fingerprint"
+ # The collection of unique entries to post
+ unique_entries = Dummy.BUILD_FINGERPRINTS
+ # The URL to retrieve the stats entries from
+ endpoint_url = reverse("hiccup_stats_api_v1_versions")
+
def _create_version_entities(self):
versions = [
self._create_dummy_version(**{self.unique_entry_name: unique_entry})
@@ -460,14 +508,21 @@
]
return versions
- def test_list_versions_without_authentication(self):
- """Test listing of versions without authentication."""
- response = self.client.get(self.endpoint_url)
- self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
+ def test_endpoint_url_as_admin(self):
+ """Test that admin users can access the endpoint URL."""
+ self._assert_get_as_admin_user_succeeds(self.endpoint_url)
- def test_list_versions_as_device_owner(self):
- """Test listing of versions as device owner."""
- self._assert_device_owner_has_no_get_access(self.endpoint_url)
+ def test_endpoint_url_as_fp_staff(self):
+ """Test that Fairphone staff users can access the endpoint URL."""
+ self._assert_get_as_fp_staff_succeeds(self.endpoint_url)
+
+ def test_endpoint_url_as_device_owner(self):
+ """Test that device owner users can not access the endpoint URL."""
+ self._assert_get_as_device_owner_fails(self.endpoint_url)
+
+ def test_endpoint_url_no_auth(self):
+ """Test that non-authenticated users can not access the endpoint URL."""
+ self._assert_get_without_authentication_fails(self.endpoint_url)
def test_list_versions_empty_database(self):
"""Test listing of versions on an empty database."""
@@ -493,7 +548,10 @@
self.unique_entry_name: getattr(versions[0], self.unique_entry_name)
}
self._assert_filter_result_matches(
- filter_params, expected_result=versions[0]
+ self.endpoint_url,
+ self.unique_entry_name,
+ filter_params,
+ expected_result=versions[0],
)
def test_filter_versions_by_release_type(self):
@@ -525,7 +583,10 @@
"is_beta_release": version.is_beta_release,
}
self._assert_filter_result_matches(
- filter_params, expected_result=version
+ self.endpoint_url,
+ self.unique_entry_name,
+ filter_params,
+ expected_result=version,
)
def test_filter_versions_by_first_seen_date(self):
@@ -543,7 +604,10 @@
# Expect the single matching result to be returned
filter_params = {"first_seen_after": Dummy.DATES[2]}
self._assert_filter_result_matches(
- filter_params, expected_result=versions[0]
+ self.endpoint_url,
+ self.unique_entry_name,
+ filter_params,
+ expected_result=versions[0],
)
@@ -563,6 +627,8 @@
class VersionDailyTestCase(_VersionTestCase):
"""Test the VersionDaily REST endpoint."""
+ unique_entry_name = "build_fingerprint"
+ unique_entries = Dummy.BUILD_FINGERPRINTS
endpoint_url = reverse("hiccup_stats_api_v1_version_daily")
@staticmethod
@@ -580,14 +646,21 @@
]
return versions_daily
- def test_list_daily_versions_without_authentication(self):
- """Test listing of daily versions without authentication."""
- response = self.client.get(self.endpoint_url)
- self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
+ def test_endpoint_url_as_admin(self):
+ """Test that admin users can access the endpoint URL."""
+ self._assert_get_as_admin_user_succeeds(self.endpoint_url)
- def test_list_daily_versions_as_device_owner(self):
- """Test listing of daily versions as device owner."""
- self._assert_device_owner_has_no_get_access(self.endpoint_url)
+ def test_endpoint_url_as_fp_staff(self):
+ """Test that Fairphone staff users can access the endpoint URL."""
+ self._assert_get_as_fp_staff_succeeds(self.endpoint_url)
+
+ def test_endpoint_url_as_device_owner(self):
+ """Test that device owner users can not access the endpoint URL."""
+ self._assert_get_as_device_owner_fails(self.endpoint_url)
+
+ def test_endpoint_url_no_auth(self):
+ """Test that non-authenticated users can not access the endpoint URL."""
+ self._assert_get_without_authentication_fails(self.endpoint_url)
def test_list_daily_versions_empty_database(self):
"""Test listing of daily versions on an empty database."""
@@ -615,7 +688,10 @@
param_name: getattr(versions[0].version, self.unique_entry_name)
}
self._assert_filter_result_matches(
- filter_params, expected_result=versions[0].version
+ self.endpoint_url,
+ self.unique_entry_name,
+ filter_params,
+ expected_result=versions[0].version,
)
def test_filter_daily_versions_by_date(self):
@@ -634,7 +710,10 @@
# Expect the single matching result to be returned
filter_params = {"date": versions[0].date}
self._assert_filter_result_matches(
- filter_params, expected_result=versions[0].version
+ self.endpoint_url,
+ self.unique_entry_name,
+ filter_params,
+ expected_result=versions[0].version,
)
@@ -1239,9 +1318,14 @@
)
-class DeviceStatsTestCase(_HiccupAPITestCase):
+class DeviceStatsTestCase(_HiccupStatsAPITestCase):
"""Test the single device stats REST endpoints."""
+ device_overview_url = "hiccup_stats_api_v1_device_overview"
+ device_report_history_url = "hiccup_stats_api_v1_device_report_history"
+ device_update_history_url = "hiccup_stats_api_v1_device_update_history"
+ device_logfile_download_url = "hiccup_stats_api_v1_logfile_download"
+
def _get_with_params(self, url, params):
url = reverse(url, kwargs=params)
return self.fp_staff_client.get(url)
@@ -1283,6 +1367,176 @@
"Fails because there is no fallback for the last_active "
"date for devices without heartbeats."
)
+ def test_device_overview_url_as_admin(self):
+ """Test that admin users can access the URL."""
+ self._assert_get_as_admin_user_succeeds(
+ reverse(
+ self.device_overview_url,
+ kwargs={"uuid": self.device_owner_device.uuid},
+ )
+ )
+
+ @unittest.skip(
+ "Fails because there is no fallback for the last_active "
+ "date for devices without heartbeats."
+ )
+ def test_device_overview_url_as_fp_staff(self):
+ """Test that Fairphone staff users can access the URL."""
+ self._assert_get_as_fp_staff_succeeds(
+ reverse(
+ self.device_overview_url,
+ kwargs={"uuid": self.device_owner_device.uuid},
+ )
+ )
+
+ def test_device_overview_url_as_device_owner(self):
+ """Test that device owner users can not access the URL."""
+ self._assert_get_as_device_owner_fails(
+ reverse(
+ self.device_overview_url,
+ kwargs={"uuid": self.device_owner_device.uuid},
+ )
+ )
+
+ def test_device_overview_url_no_auth(self):
+ """Test that non-authenticated users can not access the URL."""
+ self._assert_get_without_authentication_fails(
+ reverse(
+ self.device_overview_url,
+ kwargs={"uuid": self.device_owner_device.uuid},
+ )
+ )
+
+ def test_device_report_history_url_as_admin(self):
+ """Test that admin users can access device report history URL."""
+ self._assert_get_as_admin_user_succeeds(
+ reverse(
+ self.device_report_history_url,
+ kwargs={"uuid": self.device_owner_device.uuid},
+ )
+ )
+
+ def test_device_report_history_url_as_fp_staff(self):
+ """Test that FP staff can access device report history URL."""
+ self._assert_get_as_fp_staff_succeeds(
+ reverse(
+ self.device_report_history_url,
+ kwargs={"uuid": self.device_owner_device.uuid},
+ )
+ )
+
+ def test_device_report_history_url_as_device_owner(self):
+ """Test that device owners can't access device report history URL."""
+ self._assert_get_as_device_owner_fails(
+ reverse(
+ self.device_report_history_url,
+ kwargs={"uuid": self.device_owner_device.uuid},
+ )
+ )
+
+ def test_device_report_history_url_no_auth(self):
+ """Test that device report history is not accessible without auth."""
+ self._assert_get_without_authentication_fails(
+ reverse(
+ self.device_report_history_url,
+ kwargs={"uuid": self.device_owner_device.uuid},
+ )
+ )
+
+ def test_device_update_history_url_as_admin(self):
+ """Test that admin users can access device update history URL."""
+ self._assert_get_as_admin_user_succeeds(
+ reverse(
+ self.device_update_history_url,
+ kwargs={"uuid": self.device_owner_device.uuid},
+ )
+ )
+
+ def test_device_update_history_url_as_fp_staff(self):
+ """Test that FP staff can access device update history URL."""
+ self._assert_get_as_fp_staff_succeeds(
+ reverse(
+ self.device_update_history_url,
+ kwargs={"uuid": self.device_owner_device.uuid},
+ )
+ )
+
+ def test_device_update_history_url_as_device_owner(self):
+ """Test that device owners can't access device update history URL."""
+ self._assert_get_as_device_owner_fails(
+ reverse(
+ self.device_update_history_url,
+ kwargs={"uuid": self.device_owner_device.uuid},
+ )
+ )
+
+ def test_device_update_history_url_no_auth(self):
+ """Test that device update history is not accessible without auth."""
+ self._assert_get_without_authentication_fails(
+ reverse(
+ self.device_update_history_url,
+ kwargs={"uuid": self.device_owner_device.uuid},
+ )
+ )
+
+ def test_logfile_download_url_as_admin(self):
+ """Test that admin users can access the logfile download URL."""
+ non_existent_logfile_id = 0
+ self.assertFalse(
+ LogFile.objects.filter(id=non_existent_logfile_id).exists()
+ )
+ self._assert_get_as_admin_user_succeeds(
+ reverse(
+ self.device_logfile_download_url,
+ kwargs={"id_logfile": non_existent_logfile_id},
+ ),
+ expected_status=status.HTTP_404_NOT_FOUND,
+ )
+
+ def tes_logfile_download_url_as_fp_staff(self):
+ """Test that FP staff can access the logfile download URL."""
+ non_existent_logfile_id = 0
+ self.assertFalse(
+ LogFile.objects.filter(id=non_existent_logfile_id).exists()
+ )
+ self._assert_get_as_fp_staff_succeeds(
+ reverse(
+ self.device_logfile_download_url,
+ kwargs={"id_logfile": non_existent_logfile_id},
+ ),
+ expected_status=status.HTTP_404_NOT_FOUND,
+ )
+
+ def test_logfile_download_url_as_device_owner(self):
+ """Test that device owners can't access the logfile download URL."""
+ non_existent_logfile_id = 0
+ self.assertFalse(
+ LogFile.objects.filter(id=non_existent_logfile_id).exists()
+ )
+ self._assert_get_as_device_owner_fails(
+ reverse(
+ self.device_logfile_download_url,
+ kwargs={"id_logfile": non_existent_logfile_id},
+ )
+ )
+
+ def test_logfile_download_url_no_auth(self):
+ """Test that the logfile download URL is not accessible without auth."""
+ non_existent_logfile_id = 0
+ self.assertFalse(
+ LogFile.objects.filter(id=non_existent_logfile_id).exists()
+ )
+ self._assert_get_without_authentication_fails(
+ reverse(
+ self.device_logfile_download_url,
+ kwargs={"id_logfile": non_existent_logfile_id},
+ )
+ )
+
+ @unittest.skip(
+ "Fails because there is no fallback for the last_active "
+ "date for devices without heartbeats."
+ )
def test_get_device_stats_no_reports(self):
"""Test getting device stats for a device without reports."""
# Create a device
@@ -1290,7 +1544,7 @@
# Get the device statistics
response = self._get_with_params(
- "hiccup_stats_api_v1_device_overview", {"uuid": device.uuid}
+ self.device_overview_url, {"uuid": device.uuid}
)
# Assert that the statistics match
@@ -1314,7 +1568,7 @@
# Get the device statistics
response = self._get_with_params(
- "hiccup_stats_api_v1_device_overview", {"uuid": device.uuid}
+ self.device_overview_url, {"uuid": device.uuid}
)
# Assert that the statistics match
@@ -1342,7 +1596,7 @@
# Get the device statistics
response = self._get_with_params(
- "hiccup_stats_api_v1_device_overview", {"uuid": device.uuid}
+ self.device_overview_url, {"uuid": device.uuid}
)
# Assert that the statistics match
@@ -1374,7 +1628,7 @@
# Get the device statistics
response = self._get_with_params(
- "hiccup_stats_api_v1_device_overview", {"uuid": device.uuid}
+ self.device_overview_url, {"uuid": device.uuid}
)
# Assert that the statistics match
@@ -1410,7 +1664,7 @@
# Get the device statistics
response = self._get_with_params(
- "hiccup_stats_api_v1_device_overview", {"uuid": device.uuid}
+ self.device_overview_url, {"uuid": device.uuid}
)
# Assert that the statistics match
@@ -1443,7 +1697,7 @@
# Get the device statistics
response = self._get_with_params(
- "hiccup_stats_api_v1_device_overview", {"uuid": device.uuid}
+ self.device_overview_url, {"uuid": device.uuid}
)
# Assert that the statistics match
@@ -1485,7 +1739,7 @@
# Get the device statistics
response = self._get_with_params(
- "hiccup_stats_api_v1_device_overview", {"uuid": device.uuid}
+ self.device_overview_url, {"uuid": device.uuid}
)
# Assert that the statistics match
@@ -1508,7 +1762,7 @@
# Get the device report history statistics
response = self._get_with_params(
- "hiccup_stats_api_v1_device_report_history", {"uuid": device.uuid}
+ self.device_report_history_url, {"uuid": device.uuid}
)
# Assert that the report history is empty
@@ -1531,7 +1785,7 @@
# Get the device report history statistics
response = self._get_with_params(
- "hiccup_stats_api_v1_device_report_history", {"uuid": device.uuid}
+ self.device_report_history_url, {"uuid": device.uuid}
)
# Assert that the statistics match
@@ -1553,7 +1807,7 @@
# Get the device report history statistics
response = self._get_with_params(
- "hiccup_stats_api_v1_device_update_history", {"uuid": device.uuid}
+ self.device_update_history_url, {"uuid": device.uuid}
)
# Assert that the update history is empty
@@ -1574,7 +1828,7 @@
# Get the device update history statistics
response = self._get_with_params(
- "hiccup_stats_api_v1_device_update_history", {"uuid": device.uuid}
+ self.device_update_history_url, {"uuid": device.uuid}
)
# Assert that the statistics match
@@ -1631,7 +1885,7 @@
# Get the device update history statistics and sort it
response = self._get_with_params(
- "hiccup_stats_api_v1_device_update_history", {"uuid": device.uuid}
+ self.device_update_history_url, {"uuid": device.uuid}
)
response.data.sort(key=operator.itemgetter("build_fingerprint"))
@@ -1642,7 +1896,7 @@
"""Test download of a non existing log file."""
# Try to get a log file
response = self._get_with_params(
- "hiccup_stats_api_v1_logfile_download", {"id_logfile": 0}
+ self.device_logfile_download_url, {"id_logfile": 0}
)
# Assert that the log file was not found
@@ -1657,7 +1911,7 @@
# Get the log file
response = self._get_with_params(
- "hiccup_stats_api_v1_logfile_download", {"id_logfile": logfile.id}
+ self.device_logfile_download_url, {"id_logfile": logfile.id}
)
# Assert that the log file contents are in the response data
@@ -1672,7 +1926,7 @@
)
-class ViewsTestCase(_HiccupAPITestCase):
+class ViewsTestCase(_HiccupStatsAPITestCase):
"""Test cases for the statistics views."""
home_url = reverse("device")
@@ -1682,11 +1936,190 @@
@staticmethod
def _url_with_params(url, params):
- return "{}?{}".format(url, urlencode(params))
+ # Encode params, but keep slashes because we want to accept URLs as
+ # parameter values.
+ encoded_params = urlencode(params, safe="/")
+ return "{}?{}".format(url, encoded_params)
def _get_with_params(self, url, params):
return self.fp_staff_client.get(self._url_with_params(url, params))
+ @unittest.skip(
+ "Fails because the view is currently not accessible for admin users."
+ )
+ def test_home_view_as_admin(self):
+ """Test that admin users can access the home view."""
+ self._assert_get_as_admin_user_succeeds(self.home_url)
+
+ def test_home_view_as_fp_staff(self):
+ """Test that Fairphone staff users can access the home view."""
+ self._assert_get_as_fp_staff_succeeds(self.home_url)
+
+ def test_home_view_as_device_owner(self):
+ """Test that device owner users can not access the home view."""
+ # Assert that the response is a redirect (to the login page)
+ self._assert_get_as_device_owner_fails(
+ self.home_url, expected_status=status.HTTP_302_FOUND
+ )
+
+ def test_home_view_no_auth(self):
+ """Test that one can not access the home view without auth."""
+ # Assert that the response is a redirect (to the login page)
+ self._assert_get_without_authentication_fails(
+ self.home_url, expected_status=status.HTTP_302_FOUND
+ )
+
+ @unittest.skip(
+ "Fails because the view is currently not accessible for admin users."
+ )
+ def test_device_view_as_admin(self):
+ """Test that admin users can access the device view."""
+ self._assert_get_as_admin_user_succeeds(
+ self._url_with_params(
+ self.device_url, {"uuid": self.device_owner_device.uuid}
+ )
+ )
+
+ def test_device_view_as_fp_staff(self):
+ """Test that Fairphone staff users can access the device view."""
+ self._assert_get_as_fp_staff_succeeds(
+ self._url_with_params(
+ self.device_url, {"uuid": self.device_owner_device.uuid}
+ )
+ )
+
+ def test_device_view_as_device_owner(self):
+ """Test that device owner users can not access the device view."""
+ # Assert that the response is a redirect (to the login page)
+ self._assert_get_as_device_owner_fails(
+ self._url_with_params(
+ self.device_url, {"uuid": self.device_owner_device.uuid}
+ ),
+ expected_status=status.HTTP_302_FOUND,
+ )
+
+ def test_device_view_no_auth(self):
+ """Test that non-authenticated users can not access the device view."""
+ # Assert that the response is a redirect (to the login page)
+ self._assert_get_without_authentication_fails(
+ self._url_with_params(
+ self.device_url, {"uuid": self.device_owner_device.uuid}
+ ),
+ expected_status=status.HTTP_302_FOUND,
+ )
+
+ @unittest.skip(
+ "Fails because the view is currently not accessible for admin users."
+ )
+ def test_versions_view_as_admin(self):
+ """Test that admin users can access the versions view."""
+ self._assert_get_as_admin_user_succeeds(self.versions_url)
+
+ def test_versions_view_as_fp_staff(self):
+ """Test that Fairphone staff users can access the versions view."""
+ self._assert_get_as_fp_staff_succeeds(self.versions_url)
+
+ def test_versions_view_as_device_owner(self):
+ """Test that device owner users can not access the versions view."""
+ # Assert that the response is a redirect (to the login page)
+ self._assert_get_as_device_owner_fails(
+ self.versions_url, expected_status=status.HTTP_302_FOUND
+ )
+
+ def test_versions_view_no_auth(self):
+ """Test one can not access the versions view without auth."""
+ # Assert that the response is a redirect (to the login page)
+ self._assert_get_without_authentication_fails(
+ self.versions_url, expected_status=status.HTTP_302_FOUND
+ )
+
+ @unittest.skip(
+ "Fails because the view is currently not accessible for admin users."
+ )
+ def test_versions_all_view_as_admin(self):
+ """Test that admin users can access the versions all view."""
+ self._assert_get_as_admin_user_succeeds(self.versions_all_url)
+
+ def test_versions_all_view_as_fp_staff(self):
+ """Test that Fairphone staff users can access the versions all view."""
+ self._assert_get_as_fp_staff_succeeds(self.versions_all_url)
+
+ def test_versions_all_view_as_device_owner(self):
+ """Test that device owner users can not access the versions all view."""
+ # Assert that the response is a redirect (to the login page)
+ self._assert_get_as_device_owner_fails(
+ self.versions_all_url, expected_status=status.HTTP_302_FOUND
+ )
+
+ def test_versions_all_view_no_auth(self):
+ """Test that one can not access the versions all view without auth."""
+ # Assert that the response is a redirect (to the login page)
+ self._assert_get_without_authentication_fails(
+ self.versions_all_url, expected_status=status.HTTP_302_FOUND
+ )
+
+ @unittest.skip(
+ "Fails because the view is currently not accessible for admin users."
+ )
+ def test_home_view_post_as_admin_user(self):
+ """Test HTTP POST method to home view as admin user."""
+ response = self.admin.post(
+ self.home_url, data={"uuid": str(self.device_owner_device.uuid)}
+ )
+
+ # Assert that the response is a redirect to the device page
+ self.assertRedirects(
+ response,
+ self._url_with_params(
+ self.device_url, {"uuid": self.device_owner_device.uuid}
+ ),
+ )
+
+ def test_home_view_post_as_fp_staff(self):
+ """Test HTTP POST method to home view as Fairphone staff user."""
+ response = self.fp_staff_client.post(
+ self.home_url, data={"uuid": str(self.device_owner_device.uuid)}
+ )
+
+ # Assert that the response is a redirect to the device page
+ self.assertRedirects(
+ response,
+ self._url_with_params(
+ self.device_url, {"uuid": self.device_owner_device.uuid}
+ ),
+ )
+
+ def test_home_view_post_no_auth(self):
+ """Test HTTP POST method to home view without authentication."""
+ response = self.client.post(
+ self.home_url, data={"uuid": str(self.device_owner_device.uuid)}
+ )
+
+ # Assert that the response is a redirect to the login page
+ self.assertRedirects(
+ response,
+ self._url_with_params(
+ settings.ACCOUNT_LOGOUT_REDIRECT_URL,
+ {"next": settings.LOGIN_REDIRECT_URL},
+ ),
+ )
+
+ def test_home_view_post_as_device_owner(self):
+ """Test HTTP POST method to home view as device owner."""
+ response = self.device_owner_client.post(
+ self.home_url, data={"uuid": str(self.device_owner_device.uuid)}
+ )
+
+ # Assert that the response is a redirect to the login page
+
+ self.assertRedirects(
+ response,
+ self._url_with_params(
+ settings.ACCOUNT_LOGOUT_REDIRECT_URL,
+ {"next": settings.LOGIN_REDIRECT_URL},
+ ),
+ )
+
def test_get_home_view(self):
"""Test getting the home view with device search form."""
response = self.fp_staff_client.get(self.home_url)