Skip to content

Commit f7f65ca

Browse files
committed
REST: Add modifying patch labels to API
1 parent a800941 commit f7f65ca

5 files changed

Lines changed: 69 additions & 3 deletions

File tree

‎docs/api/schemas/latest/patchwork.yaml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2404,6 +2404,11 @@ components:
24042404
type: array
24052405
items:
24062406
type: integer
2407+
labels:
2408+
title: Labels
2409+
type: array
2410+
items:
2411+
type: string
24072412
Person:
24082413
type: object
24092414
title: Person

‎docs/api/schemas/patchwork.j2‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2495,6 +2495,13 @@ components:
24952495
type: array
24962496
items:
24972497
type: integer
2498+
{% endif %}
2499+
{% if version >= (1, 4) %}
2500+
labels:
2501+
title: Labels
2502+
type: array
2503+
items:
2504+
type: string
24982505
{% endif %}
24992506
Person:
25002507
type: object

‎docs/api/schemas/v1.4/patchwork.yaml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2404,6 +2404,11 @@ components:
24042404
type: array
24052405
items:
24062406
type: integer
2407+
labels:
2408+
title: Labels
2409+
type: array
2410+
items:
2411+
type: string
24072412
Person:
24082413
type: object
24092414
title: Person

‎patchwork/api/patch.py‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from rest_framework.reverse import reverse
1919
from rest_framework.serializers import SerializerMethodField
2020
from rest_framework import status
21-
from rest_framework.serializers import StringRelatedField
21+
from rest_framework.serializers import SlugRelatedField
2222

2323
from patchwork.api.base import BaseHyperlinkedModelSerializer
2424
from patchwork.api.base import LinkHeaderPagination
@@ -31,6 +31,7 @@
3131
from patchwork.api.filters import PatchFilterSet
3232
from patchwork.models import Patch
3333
from patchwork.models import PatchRelation
34+
from patchwork.models import Label
3435
from patchwork.models import State
3536
from patchwork.parser import clean_subject
3637

@@ -78,6 +79,12 @@ class PatchConflict(APIException):
7879
)
7980

8081

82+
class LabelsField(SlugRelatedField):
83+
def get_queryset(self):
84+
project = self.parent.parent.instance.project
85+
return Label.get_project_labels(project)
86+
87+
8188
class PatchListSerializer(BaseHyperlinkedModelSerializer):
8289
web_url = SerializerMethodField()
8390
project = ProjectSerializer(read_only=True)
@@ -96,7 +103,7 @@ class PatchListSerializer(BaseHyperlinkedModelSerializer):
96103
default=[],
97104
style={'base_template': 'input.html'},
98105
)
99-
labels = StringRelatedField(many=True)
106+
labels = LabelsField(many=True, slug_field='name')
100107

101108
def get_web_url(self, instance):
102109
request = self.context.get('request')
@@ -198,7 +205,6 @@ class Meta:
198205
'check',
199206
'checks',
200207
'tags',
201-
'labels',
202208
)
203209
versioned_fields = {
204210
'1.1': ('comments', 'web_url'),

‎patchwork/tests/unit/api/test_patch.py‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,49 @@ def test_update_maintainer_version_1_0(self):
529529
self.assertEqual(Patch.objects.get(id=patch.id).state, state)
530530
self.assertEqual(Patch.objects.get(id=patch.id).delegate, user)
531531

532+
def test_update_labels(self):
533+
"""Update labels as maintainer."""
534+
project = create_project()
535+
project2 = create_project()
536+
label1 = create_label(name='label', project=project)
537+
label2 = create_label(name='label2')
538+
label_p2 = create_label(name='label_p2', project=project2)
539+
label1_global = create_label(name='label', project=None)
540+
patch = create_patch(project=project, labels=[label1_global])
541+
user = create_maintainer(project)
542+
543+
# Test adding labels labels, make sure local labels are prioritized
544+
545+
self.client.authenticate(user=user)
546+
resp = self.client.patch(
547+
self.api_url(patch.id), {'labels': [label1.name, label2.name]}
548+
)
549+
self.assertEqual(status.HTTP_200_OK, resp.status_code, resp)
550+
self.assertEqual(
551+
sorted(
552+
Patch.objects.get(id=patch.id).labels.values_list(
553+
'id', flat=True
554+
)
555+
),
556+
sorted([label1.id, label2.id]),
557+
)
558+
559+
# Test removing labels
560+
561+
self.client.authenticate(user=user)
562+
resp = self.client.patch(self.api_url(patch.id), {'labels': []})
563+
self.assertEqual(status.HTTP_200_OK, resp.status_code, resp)
564+
self.assertEqual(Patch.objects.get(id=patch.id).labels.count(), 0)
565+
566+
# Make sure labels from other projects cannot be added
567+
568+
self.client.authenticate(user=user)
569+
resp = self.client.patch(
570+
self.api_url(patch.id), {'labels': [label1.name, label_p2.name]}
571+
)
572+
self.assertEqual(status.HTTP_400_BAD_REQUEST, resp.status_code, resp)
573+
self.assertEqual(Patch.objects.get(id=patch.id).labels.count(), 0)
574+
532575
@utils.store_samples('patch-update-error-bad-request')
533576
def test_update_invalid_state(self):
534577
"""Update patch with invalid fields.

0 commit comments

Comments
 (0)