Coverage for apis_core/generic/tests/test_generic.py: 36%
101 statements
« prev ^ index » next coverage.py v7.5.3, created at 2025-09-03 06:15 +0000
« prev ^ index » next coverage.py v7.5.3, created at 2025-09-03 06:15 +0000
1import pytest
2from django.contrib.auth.models import Permission, User
3from django.contrib.contenttypes.models import ContentType
4from faker import Faker
6from apis_core.generic.tests.models import Dummy, Person
7from apis_core.generic.tests.tables import DummyTable
8from apis_core.generic.views import List
10fake = Faker()
12# tuple of route, permission, and expected status_code
13routes = [
14 ("/generic_tests.person/", "view_person", 200),
15 ("/generic_tests.person/1", "view_person", 200),
16 ("/generic_tests.person/create", "add_person", 200),
17 ("/generic_tests.person/delete/1", "delete_person", 200),
18 ("/generic_tests.person/update/1", "change_person", 200),
19 ("/generic_tests.person/duplicate/1", "add_person", 302),
20 ("/generic_tests.person/autocomplete", "view_person", 200),
21 ("/generic_tests.person/import", "add_person", 200),
22 ("/generic_tests.person/selectmergeorenrich/1", "add_person", 200),
23 ("/generic_tests.person/merge/1/2", "change_person", 200),
24 (
25 "/generic_tests.person/enrich/1?uri=https://d-nb.info/gnd/119252880",
26 "change_person",
27 200,
28 ),
29]
30route_parameters = "route,permission,status_code"
32unique_first_name = "SomeUniqueFirstName"
33unique_last_name = "SomeUniqueLastName"
36@pytest.mark.django_db
37class TestGeneric(object):
38 @pytest.fixture
39 def setup(self):
40 # Create an admin user
41 self.admin = User.objects.create_superuser(
42 "admin", fake.email(), fake.password()
43 )
44 # Create a normal user
45 self.user = User.objects.create_user(
46 fake.user_name(), fake.email(), fake.password()
47 )
48 # Create a couple of person objects
49 for _ in range(0, fake.random_int(5, 20)):
50 Person.objects.create(
51 first_name=fake.first_name(), last_name=fake.last_name()
52 )
53 self.unique = Person.objects.create(
54 first_name=unique_first_name, last_name=unique_last_name
55 )
56 self.person_count = Person.objects.count()
58 def test_person_count(self, setup):
59 """Check if the correct number of persons was created"""
60 assert Person.objects.count() == self.person_count
62 # Initial tests for checking the permissions of the views
64 @pytest.mark.parametrize(route_parameters, routes)
65 def test_anon_person_views(self, setup, route, permission, status_code, client):
66 """Anon user should not be able to access the person views"""
67 response = client.get(route)
68 assert response.status_code == 302
70 @pytest.mark.parametrize(route_parameters, routes)
71 def test_admin_person_views(
72 self, setup, route, permission, status_code, admin_client
73 ):
74 """Admin user should be able to access the person list"""
75 response = admin_client.get(route)
76 assert response.status_code == status_code
78 @pytest.mark.parametrize(route_parameters, routes)
79 def test_person_user_views(self, setup, route, permission, status_code, client):
80 """Normal user should not be able to access the person list"""
81 client.force_login(self.user)
82 response = client.get(route)
83 assert response.status_code == 403
85 @pytest.mark.parametrize(route_parameters, routes)
86 def test_person_user_with_access(
87 self, setup, route, permission, status_code, client
88 ):
89 """Normal user should be able to access the person views after bein granted permission"""
90 content_type = ContentType.objects.get_for_model(Person)
91 p = Permission.objects.get(codename=permission, content_type=content_type)
92 self.user.user_permissions.add(p)
93 client.force_login(self.user)
94 response = client.get(route)
95 assert response.status_code == status_code
97 # More detailed tests checking the content of the responses and sending actual data
99 def test_person_list(self, setup, admin_client):
100 """Check if the first_name of some person object is listed in the person list"""
101 p = Person.objects.order_by("?").first()
102 response = admin_client.get("/generic_tests.person/")
103 assert p.first_name in response.content.decode()
105 def test_person_detail(self, setup, admin_client):
106 """Check if the details page of a person lists its details"""
107 p = Person.objects.order_by("?").first()
108 response = admin_client.get(f"/generic_tests.person/{p.pk}")
109 assert p.first_name in response.content.decode()
110 assert p.last_name in response.content.decode()
112 def test_person_create(self, setup, admin_client):
113 """Check if we can create a person using the create route"""
114 data = {
115 "first_name": fake.first_name(),
116 "last_name": fake.last_name(),
117 }
118 response = admin_client.post("/generic_tests.person/create", data, follow=True)
119 assert response.status_code == 200
120 assert data["first_name"] in response.content.decode()
121 assert data["last_name"] in response.content.decode()
122 assert Person.objects.count() == self.person_count + 1
124 def test_person_delete(self, setup, admin_client):
125 """Check if we can delete a person using the delete route"""
126 p = Person.objects.order_by("?").first()
127 response = admin_client.get(f"/generic_tests.person/delete/{p.pk}")
128 assert response.status_code == 200
129 assert "Confirm deletion of:" in response.content.decode()
130 assert str(p) in response.content.decode()
132 def test_person_delete_confirmation(self, setup, admin_client):
133 """Check if we can delete a person using the delete route"""
134 p = self.unique
135 response = admin_client.post(
136 f"/generic_tests.person/delete/{p.pk}", follow=True
137 )
138 assert response.status_code == 200
139 assert p.first_name not in response.content.decode()
140 assert p.last_name not in response.content.decode()
141 assert Person.objects.count() == self.person_count - 1
143 def test_person_delete_redirect(self, setup, admin_client):
144 """Check if we can delete a person using the delete route"""
145 p = self.unique
146 response = admin_client.post(
147 f"/generic_tests.person/delete/{p.pk}?redirect=/generic_tests.person/create"
148 )
149 assert response.status_code == 302
150 assert response.headers["Location"] == "/generic_tests.person/create"
152 def test_person_update(self, setup, admin_client):
153 """Check if we can update a person"""
154 p = Person.objects.order_by("?").first()
155 data = {
156 "first_name": fake.first_name(),
157 "last_name": fake.last_name(),
158 }
159 response = admin_client.post(
160 f"/generic_tests.person/update/{p.pk}", data, follow=True
161 )
162 assert response.status_code == 200
163 assert Person.objects.get(pk=p.pk).last_name == data["last_name"]
164 assert Person.objects.get(pk=p.pk).first_name == data["first_name"]
166 def test_person_autocomplete(self, setup, admin_client):
167 """Check if we find a person using autocomplete"""
168 p = self.unique
169 response = admin_client.get(
170 f"/generic_tests.person/autocomplete?q={p.first_name}"
171 )
172 assert response.status_code == 200
173 expected = {
174 "results": [{"id": str(p.pk), "selected_text": str(p), "text": str(p)}],
175 "pagination": {"more": False},
176 }
177 assert response.json() == expected
179 def test_person_table_export_filename(self, rf, admin_user):
180 """Check if the person table provides the correct export filename"""
181 view = List(model=Person)
182 assert view.get_export_filename("ext") == "table.ext"
184 def test_dummy_table_export_filename(self, rf, admin_user):
185 """Check if the dummy table provides the correct export filename"""
186 view = List(model=Dummy)
187 assert view.get_export_filename("ext") == "dummytable.ext"
189 def test_dummy_table_class(self, admin_client):
190 request = admin_client.get("/generic_tests.dummy/")
191 assert isinstance(request.context["table"], DummyTable)