Skip to content

Commit a87fd13

Browse files
andrepapotivictor-accarini
authored andcommitted
tests: Add tests for Note related endpoints
Signed-off-by: andrepapoti <[email protected]>
1 parent 13f5fd5 commit a87fd13

File tree

2 files changed

+368
-0
lines changed

2 files changed

+368
-0
lines changed

patchwork/tests/api/test_notes.py

Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
# Patchwork - automated patch tracking system
2+
# Copyright (C) 2024 Collabora
3+
#
4+
# SPDX-License-Identifier: GPL-2.0-or-later
5+
6+
from django.test import override_settings
7+
from django.urls import reverse
8+
from rest_framework import status
9+
10+
from patchwork.models import Note
11+
from patchwork.tests.api import utils
12+
from patchwork.tests.utils import create_patch
13+
from patchwork.tests.utils import create_maintainer
14+
from patchwork.tests.utils import create_person
15+
from patchwork.tests.utils import create_project
16+
from patchwork.tests.utils import create_note
17+
from patchwork.tests.utils import create_user
18+
from patchwork.tests.utils import create_superuser
19+
20+
21+
@override_settings(ENABLE_REST_API=True)
22+
class TestPatchNotes(utils.APITestCase):
23+
def setUp(self):
24+
super().setUp()
25+
self.project = create_project()
26+
self.superuser = create_superuser()
27+
self.user = create_maintainer(self.project)
28+
self.patch = create_patch(project=self.project)
29+
30+
def check_for_expected(self, instance, response_data):
31+
self.assertEqual(instance.id, response_data['id'])
32+
self.assertEqual(instance.patch.id, response_data['patch']['id'])
33+
self.assertEqual(
34+
instance.submitter.id, response_data['submitter']['id']
35+
)
36+
37+
def test_create_note(self):
38+
start_num = Note.objects.count()
39+
url = reverse(
40+
'api-patch-note-list', kwargs={'patch_id': self.patch.id}
41+
)
42+
data = {'content': 'New note'}
43+
self.client.authenticate(user=self.user)
44+
resp = self.client.post(url, data=data)
45+
end_num = Note.objects.count()
46+
47+
self.assertEqual(status.HTTP_201_CREATED, resp.status_code)
48+
self.assertEqual(start_num + 1, end_num)
49+
50+
def test_create_public_note(self):
51+
start_num = Note.objects.count()
52+
url = reverse(
53+
'api-patch-note-list', kwargs={'patch_id': self.patch.id}
54+
)
55+
data = {
56+
'content': 'New note',
57+
'maintainer_only': False,
58+
}
59+
self.client.authenticate(user=self.user)
60+
resp = self.client.post(url, data=data)
61+
end_num = Note.objects.count()
62+
63+
self.assertEqual(status.HTTP_201_CREATED, resp.status_code)
64+
self.assertEqual(start_num + 1, end_num)
65+
66+
def test_get_note_as_super_user(self):
67+
"""Retrieve patch note with an superuser."""
68+
note = create_note(patch=self.patch)
69+
70+
url = reverse(
71+
'api-patch-note-detail',
72+
kwargs={'patch_id': self.patch.id, 'note_id': note.id},
73+
)
74+
self.client.authenticate(user=self.superuser)
75+
resp = self.client.get(url)
76+
77+
self.assertEqual(status.HTTP_200_OK, resp.status_code)
78+
self.check_for_expected(note, resp.data)
79+
80+
def test_get_note_as_anon_user(self):
81+
"""Retrieve patch note with an anonymous user."""
82+
note = create_note()
83+
84+
url = reverse(
85+
'api-patch-note-detail',
86+
kwargs={'patch_id': self.patch.id, 'note_id': note.id},
87+
)
88+
resp = self.client.get(url)
89+
90+
self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
91+
92+
def test_get_public_note_as_anon_user(self):
93+
"""Retrieve public patch note with an anon user."""
94+
note = create_note(patch=self.patch, maintainer_only=False)
95+
96+
url = reverse(
97+
'api-patch-note-detail',
98+
kwargs={'patch_id': self.patch.id, 'note_id': note.id},
99+
)
100+
resp = self.client.get(url)
101+
102+
self.assertEqual(status.HTTP_200_OK, resp.status_code)
103+
self.check_for_expected(note, resp.data)
104+
105+
def test_get_note_as_maintainer(self):
106+
"""Retrieve patch note with an user that is a maintainer."""
107+
note = create_note(patch=self.patch, submitter=self.user)
108+
109+
self.client.authenticate(user=self.user)
110+
url = reverse(
111+
'api-patch-note-detail',
112+
kwargs={'patch_id': self.patch.id, 'note_id': note.id},
113+
)
114+
resp = self.client.get(url)
115+
116+
self.assertEqual(status.HTTP_200_OK, resp.status_code)
117+
self.check_for_expected(note, resp.data)
118+
119+
def test_get_note_as_non_maintainer(self):
120+
"""Retrieve patch note with an user that is not a maintainer."""
121+
note = create_note()
122+
123+
self.client.authenticate(user=self.user)
124+
url = reverse(
125+
'api-patch-note-detail',
126+
kwargs={'patch_id': self.patch.id, 'note_id': note.id},
127+
)
128+
resp = self.client.get(url)
129+
130+
self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
131+
132+
def test_get_note_public(self):
133+
"""Retrieve public patch note with an user that is not a maintainer."""
134+
person = create_person(user=self.user)
135+
note = create_note(patch=self.patch, maintainer_only=False)
136+
137+
self.client.authenticate(user=person.user)
138+
url = reverse(
139+
'api-patch-note-detail',
140+
kwargs={'patch_id': self.patch.id, 'note_id': note.id},
141+
)
142+
resp = self.client.get(url)
143+
144+
self.assertEqual(status.HTTP_200_OK, resp.status_code)
145+
self.check_for_expected(note, resp.data)
146+
147+
def test_get_public_note_list_as_anon_user(self):
148+
"""Retrieve public patch note without authentication."""
149+
note = create_note(patch=self.patch, maintainer_only=False)
150+
151+
url = reverse(
152+
'api-patch-note-detail',
153+
kwargs={'patch_id': self.patch.id, 'note_id': note.id},
154+
)
155+
resp = self.client.get(url)
156+
157+
self.assertEqual(status.HTTP_200_OK, resp.status_code)
158+
self.check_for_expected(note, resp.data)
159+
160+
def test_get_note_list_as_super_user(self):
161+
"""Retrieve notes from a patch note without an user."""
162+
create_note(patch=self.patch, submitter=self.user)
163+
create_note(
164+
patch=self.patch, submitter=self.user, maintainer_only=False
165+
)
166+
167+
url = reverse(
168+
'api-patch-note-list', kwargs={'patch_id': self.patch.id}
169+
)
170+
self.client.authenticate(user=self.superuser)
171+
resp = self.client.get(url)
172+
173+
self.assertEqual(status.HTTP_200_OK, resp.status_code)
174+
self.assertEqual(len(resp.data), 2)
175+
176+
def test_get_note_list_as_anon_user(self):
177+
"""Retrieve notes from a patch note without an user."""
178+
create_note(patch=self.patch, submitter=self.user)
179+
public_note = create_note(
180+
patch=self.patch, submitter=self.user, maintainer_only=False
181+
)
182+
183+
url = reverse(
184+
'api-patch-note-list', kwargs={'patch_id': self.patch.id}
185+
)
186+
resp = self.client.get(url)
187+
188+
self.assertEqual(status.HTTP_200_OK, resp.status_code)
189+
self.assertEqual(len(resp.data), 1)
190+
self.check_for_expected(public_note, resp.data[0])
191+
192+
def test_get_note_list_as_maintainer(self):
193+
"""Retrieve notes from a patch note with an user that is a maintainer."""
194+
create_note(patch=self.patch, submitter=self.user)
195+
create_note(
196+
patch=self.patch, submitter=self.user, maintainer_only=False
197+
)
198+
199+
self.client.authenticate(user=self.user)
200+
url = reverse(
201+
'api-patch-note-list', kwargs={'patch_id': self.patch.id}
202+
)
203+
resp = self.client.get(url)
204+
205+
self.assertEqual(status.HTTP_200_OK, resp.status_code)
206+
self.assertEqual(len(resp.data), 2)
207+
208+
def test_get_note_list_as_non_maintainer(self):
209+
"""Retrieve notes from a patch note with an user that is not a maintainer."""
210+
create_note(patch=self.patch, submitter=self.user)
211+
public_note = create_note(
212+
patch=self.patch, submitter=self.user, maintainer_only=False
213+
)
214+
not_maintainer = create_user()
215+
216+
self.client.authenticate(user=not_maintainer)
217+
url = reverse(
218+
'api-patch-note-list', kwargs={'patch_id': self.patch.id}
219+
)
220+
resp = self.client.get(url)
221+
222+
self.assertEqual(status.HTTP_200_OK, resp.status_code)
223+
self.assertEqual(len(resp.data), 1)
224+
self.assertEqual(resp.data[0]['id'], public_note.id)
225+
226+
def test_edit_note_as_maintainer(self):
227+
"""Edit patch note with an user that is a maintainer."""
228+
note = create_note(patch=self.patch, submitter=self.user)
229+
230+
url = reverse(
231+
'api-patch-note-detail',
232+
kwargs={'patch_id': self.patch.id, 'note_id': note.id},
233+
)
234+
data = {'content': 'New content'}
235+
self.client.authenticate(user=self.user)
236+
resp = self.client.patch(url, data=data)
237+
238+
self.assertEqual(status.HTTP_200_OK, resp.status_code)
239+
self.check_for_expected(note, resp.data)
240+
self.assertNotEqual(note.content, resp.data['content'])
241+
self.assertNotEqual(note.updated_at, resp.data['updated_at'])
242+
243+
def test_edit_note_as_non_maintainer(self):
244+
"""Edit patch note with an user that is not a maintainer."""
245+
note = create_note()
246+
247+
url = reverse(
248+
'api-patch-note-detail',
249+
kwargs={'patch_id': self.patch.id, 'note_id': note.id},
250+
)
251+
data = {'content': 'New content'}
252+
self.client.authenticate(user=self.user)
253+
resp = self.client.patch(url, data=data)
254+
255+
self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
256+
257+
def test_edit_note_public_as_non_maintainer(self):
258+
"""
259+
Edit public patch note with an user that is not a maintainer.
260+
"""
261+
note = create_note(patch=self.patch, maintainer_only=False)
262+
263+
url = reverse(
264+
'api-patch-note-detail',
265+
kwargs={'patch_id': self.patch.id, 'note_id': note.id},
266+
)
267+
data = {'content': 'New content'}
268+
self.client.authenticate(user=create_user())
269+
resp = self.client.patch(url, data=data)
270+
271+
self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
272+
273+
def test_delete_note_as_maintainer(self):
274+
"""Delete patch note with an user that is a maintainer."""
275+
note = create_note(patch=self.patch, submitter=self.user)
276+
start_num = Note.objects.count()
277+
278+
url = reverse(
279+
'api-patch-note-detail',
280+
kwargs={'patch_id': self.patch.id, 'note_id': note.id},
281+
)
282+
283+
self.client.authenticate(user=self.user)
284+
resp = self.client.delete(url)
285+
end_num = Note.objects.count()
286+
287+
self.assertEqual(status.HTTP_204_NO_CONTENT, resp.status_code)
288+
self.assertEqual(start_num - 1, end_num)
289+
290+
def test_delete_note_as_non_maintainer(self):
291+
"""Delete patch note with an user that is not a maintainer."""
292+
note = create_note()
293+
294+
url = reverse(
295+
'api-patch-note-detail',
296+
kwargs={'patch_id': self.patch.id, 'note_id': note.id},
297+
)
298+
299+
self.client.authenticate(user=self.user)
300+
resp = self.client.delete(url)
301+
302+
self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
303+
304+
def test_delete_note_public(self):
305+
"""
306+
Delete public patch note with an user that is a maintainer with
307+
an user that is not a maintainer.
308+
"""
309+
person = create_person()
310+
note = create_note(patch=self.patch, maintainer_only=False)
311+
312+
url = reverse(
313+
'api-patch-note-detail',
314+
kwargs={'patch_id': self.patch.id, 'note_id': note.id},
315+
)
316+
self.client.authenticate(user=person.user)
317+
resp = self.client.delete(url)
318+
319+
self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
320+
321+
def test_notes_in_patch(self):
322+
url = reverse('api-patch-detail', kwargs={'pk': self.patch.id})
323+
self.client.authenticate(user=self.user)
324+
resp = self.client.get(url)
325+
326+
correct_path = reverse(
327+
'api-patch-note-list', kwargs={'patch_id': self.patch.id}
328+
)
329+
self.assertEqual(
330+
resp.data.get('notes'),
331+
f'http://example.com{correct_path}',
332+
)

patchwork/tests/utils.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from patchwork.models import Check
1616
from patchwork.models import Cover
1717
from patchwork.models import CoverComment
18+
from patchwork.models import Note
1819
from patchwork.models import Patch
1920
from patchwork.models import PatchComment
2021
from patchwork.models import PatchRelation
@@ -119,6 +120,28 @@ def create_user(link_person=True, **kwargs):
119120
return user
120121

121122

123+
def create_superuser(**kwargs):
124+
"""Create a 'User' and set him as admin."""
125+
values = {
126+
'username': 'test_user_super',
127+
'email': '[email protected]',
128+
'first_name': 'Super',
129+
'last_name': 'User',
130+
}
131+
user = User.objects.create_superuser(
132+
values['username'],
133+
values['email'],
134+
values['username'],
135+
first_name=values['first_name'],
136+
last_name=values['last_name'],
137+
)
138+
139+
profile = user.profile
140+
profile.save()
141+
142+
return user
143+
144+
122145
def create_maintainer(project=None, **kwargs):
123146
"""Create a 'User' and set as maintainer for provided project."""
124147
if not project:
@@ -270,6 +293,19 @@ def create_patch_comment(**kwargs):
270293
return PatchComment.objects.create(**values)
271294

272295

296+
def create_note(**kwargs):
297+
"""Create 'Note' object."""
298+
values = {
299+
'patch': create_patch() if 'patch' not in kwargs else None,
300+
'submitter': create_user() if 'submitter' not in kwargs else None,
301+
'content': 'Note content',
302+
'maintainer_only': kwargs.get('maintainer_only', True)
303+
}
304+
values.update(kwargs)
305+
306+
return Note.objects.create(**values)
307+
308+
273309
def create_check(**kwargs):
274310
"""Create 'Check' object."""
275311
values = {

0 commit comments

Comments
 (0)