new file mode 100644
@@ -0,0 +1,232 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2018 Red Hat
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from django.test import override_settings
+from django.urls import reverse
+from rest_framework import status
+
+from patchwork.models import Note
+from patchwork.tests.api import utils
+from patchwork.tests.utils import create_patch
+from patchwork.tests.utils import create_maintainer
+from patchwork.tests.utils import create_person
+from patchwork.tests.utils import create_project
+from patchwork.tests.utils import create_note
+from patchwork.tests.utils import create_user
+
+
+@override_settings(ENABLE_REST_API=True)
+class TestPatchNotes(utils.APITestCase):
+ def setUp(self):
+ super(TestPatchNotes, self).setUp()
+ self.project = create_project()
+ self.user = create_maintainer(self.project)
+ self.patch = create_patch(project=self.project)
+
+ def check_for_expected(self, instance, response_data):
+ self.assertEqual(instance.id, response_data['id'])
+ self.assertEqual(instance.patch.id, response_data['patch']['id'])
+ self.assertEqual(
+ instance.submitter.id, response_data['submitter']['id']
+ )
+
+ def test_create_note(self):
+ start_num = Note.objects.count()
+ url = reverse(
+ 'api-patch-note-list', kwargs={'patch_id': self.patch.id}
+ )
+ data = {'content': 'New note'}
+ self.client.authenticate(user=self.user)
+ resp = self.client.post(url, data=data)
+ end_num = Note.objects.count()
+
+ self.assertEqual(status.HTTP_201_CREATED, resp.status_code)
+ self.assertEqual(start_num + 1, end_num)
+
+ def test_get_note_as_maintainer(self):
+ """Retrieve patch note with an user that is a maintainer."""
+ person = create_person(user=self.user)
+ note = create_note(patch=self.patch, submitter=person)
+
+ self.client.authenticate(user=self.user)
+ url = reverse(
+ 'api-patch-note-detail',
+ kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+ )
+ resp = self.client.get(url)
+
+ self.assertEqual(status.HTTP_200_OK, resp.status_code)
+ self.check_for_expected(note, resp.data)
+
+ def test_get_note_as_non_maintainer(self):
+ """Retrieve patch note with an user that is not a maintainer."""
+ person = create_person()
+ note = create_note(patch=self.patch)
+
+ self.client.authenticate(user=person.user)
+ url = reverse(
+ 'api-patch-note-detail',
+ kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+ )
+ resp = self.client.get(url)
+
+ self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
+
+ def test_get_note_public(self):
+ """Retrieve public patch note with an user that is not a maintainer."""
+ person = create_person(user=self.user)
+ note = create_note(patch=self.patch, maintainer_only=False)
+
+ self.client.authenticate(user=person.user)
+ url = reverse(
+ 'api-patch-note-detail',
+ kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+ )
+ resp = self.client.get(url)
+
+ self.assertEqual(status.HTTP_200_OK, resp.status_code)
+ self.check_for_expected(note, resp.data)
+
+ def test_get_note_list_as_maintainer(self):
+ """Retrieve notes from a patch note with an user that is a maintainer."""
+ person = create_person(user=self.user)
+ create_note(patch=self.patch, submitter=person)
+ create_note(patch=self.patch, submitter=person, maintainer_only=False)
+
+ self.client.authenticate(user=self.user)
+ url = reverse(
+ 'api-patch-note-list', kwargs={'patch_id': self.patch.id}
+ )
+ resp = self.client.get(url)
+
+ self.assertEqual(status.HTTP_200_OK, resp.status_code)
+ self.assertEqual(len(resp.data), 2)
+
+ def test_get_note_list_as_non_maintainer(self):
+ """Retrieve notes from a patch note with an user that is not a maintainer."""
+ person = create_person(user=self.user)
+ create_note(patch=self.patch, submitter=person)
+ public_note = create_note(
+ patch=self.patch, submitter=person, maintainer_only=False
+ )
+ not_maintainer = create_user()
+
+ self.client.authenticate(user=not_maintainer)
+ url = reverse(
+ 'api-patch-note-list', kwargs={'patch_id': self.patch.id}
+ )
+ resp = self.client.get(url)
+
+ self.assertEqual(status.HTTP_200_OK, resp.status_code)
+ self.assertEqual(len(resp.data), 1)
+ self.assertEqual(resp.data[0]['id'], public_note.id)
+
+ def test_edit_note_as_maintainer(self):
+ """Edit patch note with an user that is a maintainer."""
+ person = create_person(user=self.user)
+ note = create_note(patch=self.patch, submitter=person)
+
+ url = reverse(
+ 'api-patch-note-detail',
+ kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+ )
+ data = {'content': 'New content'}
+ self.client.authenticate(user=person.user)
+ resp = self.client.patch(url, data=data)
+
+ self.assertEqual(status.HTTP_200_OK, resp.status_code)
+ self.check_for_expected(note, resp.data)
+ self.assertNotEqual(note.content, resp.data['content'])
+ self.assertNotEqual(note.last_modified, resp.data['last_modified'])
+
+ def test_edit_note_as_non_maintainer(self):
+ """Edit patch note with an user that is not a maintainer."""
+ person = create_person()
+ note = create_note(patch=self.patch)
+
+ url = reverse(
+ 'api-patch-note-detail',
+ kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+ )
+ data = {'content': 'New content'}
+ self.client.authenticate(user=person.user)
+ resp = self.client.patch(url, data=data)
+
+ self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
+
+ def test_edit_note_public(self):
+ """Edit public patch note with an user that is a maintainerwith an user that is not a maintainer."""
+ person = create_person()
+ note = create_note(patch=self.patch, maintainer_only=False)
+
+ url = reverse(
+ 'api-patch-note-detail',
+ kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+ )
+ data = {'content': 'New content'}
+ self.client.authenticate(user=person.user)
+ resp = self.client.patch(url, data=data)
+
+ self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
+
+ def test_delete_note_as_maintainer(self):
+ """Delete patch note with an user that is a maintainer."""
+ person = create_person(user=self.user)
+ note = create_note(patch=self.patch, submitter=person)
+ start_num = Note.objects.count()
+
+ url = reverse(
+ 'api-patch-note-detail',
+ kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+ )
+
+ self.client.authenticate(user=person.user)
+ resp = self.client.delete(url)
+ end_num = Note.objects.count()
+
+ self.assertEqual(status.HTTP_204_NO_CONTENT, resp.status_code)
+ self.assertEqual(start_num - 1, end_num)
+
+ def test_delete_note_as_non_maintainer(self):
+ """Delete patch note with an user that is not a maintainer."""
+ person = create_person()
+ note = create_note(patch=self.patch)
+
+ url = reverse(
+ 'api-patch-note-detail',
+ kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+ )
+
+ self.client.authenticate(user=person.user)
+ resp = self.client.delete(url)
+
+ self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
+
+ def test_delete_note_public(self):
+ """Delete public patch note with an user that is a maintainerwith an user that is not a maintainer."""
+ person = create_person()
+ note = create_note(patch=self.patch, maintainer_only=False)
+
+ url = reverse(
+ 'api-patch-note-detail',
+ kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+ )
+ self.client.authenticate(user=person.user)
+ resp = self.client.delete(url)
+
+ self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
+
+ def test_notes_in_patch(self):
+ url = reverse('api-patch-detail', kwargs={'pk': self.patch.id})
+ self.client.authenticate(user=self.user)
+ resp = self.client.get(url)
+
+ correct_path = reverse(
+ 'api-patch-note-list', kwargs={'patch_id': self.patch.id}
+ )
+ self.assertEqual(
+ resp.data.get('notes'),
+ f'http://example.com{correct_path}',
+ )
@@ -15,6 +15,7 @@ from patchwork.models import Bundle
from patchwork.models import Check
from patchwork.models import Cover
from patchwork.models import CoverComment
+from patchwork.models import Note
from patchwork.models import Patch
from patchwork.models import PatchComment
from patchwork.models import PatchRelation
@@ -270,6 +271,17 @@ def create_patch_comment(**kwargs):
return PatchComment.objects.create(**values)
+def create_note(**kwargs):
+ """Create 'Note' object."""
+ values = {
+ 'submitter': create_person() if 'submitter' not in kwargs else None,
+ 'content': 'Note content',
+ }
+ values.update(kwargs)
+
+ return Note.objects.create(**values)
+
+
def create_check(**kwargs):
"""Create 'Check' object."""
values = {
Signed-off-by: andrepapoti <andrepapoti@gmail.com> --- patchwork/tests/api/test_notes.py | 232 ++++++++++++++++++++++++++++++ patchwork/tests/utils.py | 12 ++ 2 files changed, 244 insertions(+) create mode 100644 patchwork/tests/api/test_notes.py