Skip to content

Commit 9c6fa92

Browse files
fix: update RPC publish API fields (ietf-tools#10308)
* fix: update purple publish API fields * fix: handle IntegrityError more cleanly * fix: don't import RFC fields from draft * test: update test * chore: remove unused var/import * fix: f-string -> string
1 parent f56bfcb commit 9c6fa92

3 files changed

Lines changed: 39 additions & 50 deletions

File tree

ietf/api/serializers_rpc.py

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
update_rfcauthors,
2828
)
2929
from ietf.group.models import Group
30-
from ietf.name.models import StreamName, StdLevelName, FormalLanguageName
30+
from ietf.name.models import StreamName, StdLevelName
3131
from ietf.person.models import Person
3232
from ietf.utils import log
3333

@@ -137,7 +137,6 @@ class Meta:
137137
"pages",
138138
"source_format",
139139
"authors",
140-
"shepherd",
141140
"intended_std_level",
142141
"consensus",
143142
"shepherd",
@@ -263,15 +262,6 @@ class RfcPubSerializer(serializers.ModelSerializer):
263262
stream = serializers.PrimaryKeyRelatedField(
264263
queryset=StreamName.objects.filter(used=True)
265264
)
266-
formal_languages = serializers.PrimaryKeyRelatedField(
267-
many=True,
268-
required=False,
269-
queryset=FormalLanguageName.objects.filter(used=True),
270-
help_text=(
271-
"formal languages used in RFC (defaults to those from draft, send empty"
272-
"list to override)"
273-
)
274-
)
275265
std_level = serializers.PrimaryKeyRelatedField(
276266
queryset=StdLevelName.objects.filter(used=True),
277267
)
@@ -315,11 +305,8 @@ class Meta:
315305
"stream",
316306
"abstract",
317307
"pages",
318-
"words",
319-
"formal_languages",
320308
"std_level",
321309
"ad",
322-
"note",
323310
"obsoletes",
324311
"updates",
325312
"subseries",
@@ -353,9 +340,6 @@ def create(self, validated_data):
353340
# If specified, retrieve draft and extract RFC default values from it
354341
if draft_name is None:
355342
draft = None
356-
defaults_from_draft = {
357-
"group": Group.objects.get(acronym="none", type_id="individ"),
358-
}
359343
else:
360344
# validation enforces that draft_name and draft_rev are both present
361345
draft = Document.objects.filter(
@@ -378,17 +362,11 @@ def create(self, validated_data):
378362
},
379363
code="already-published-draft",
380364
)
381-
defaults_from_draft = {
382-
"ad": draft.ad,
383-
"formal_languages": draft.formal_languages.all(),
384-
"group": draft.group,
385-
"note": draft.note,
386-
}
387365

388366
# Transaction to clean up if something fails
389367
with transaction.atomic():
390368
# create rfc, letting validated request data override draft defaults
391-
rfc = self._create_rfc(defaults_from_draft | validated_data)
369+
rfc = self._create_rfc(validated_data)
392370
DocEvent.objects.create(
393371
doc=rfc,
394372
rev=rfc.rev,
@@ -523,14 +501,11 @@ def create(self, validated_data):
523501

524502
def _create_rfc(self, validated_data):
525503
authors_data = validated_data.pop("authors")
526-
formal_languages = validated_data.pop("formal_languages", [])
527-
# todo ad field
528504
rfc = Document.objects.create(
529505
type_id="rfc",
530506
name=f"rfc{validated_data['rfc_number']}",
531507
**validated_data,
532508
)
533-
rfc.formal_languages.set(formal_languages) # list of PKs is ok
534509
for order, author_data in enumerate(authors_data):
535510
rfc.rfcauthor_set.create(
536511
order=order,

ietf/api/tests_views_rpc.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,15 @@ def test_draftviewset_references(self):
8080
def test_notify_rfc_published(self):
8181
url = urlreverse("ietf.api.purple_api.notify_rfc_published")
8282
area = GroupFactory(type_id="area")
83+
rfc_group = GroupFactory(type_id="wg")
8384
draft_ad = RoleFactory(group=area, name_id="ad").person
84-
authors = PersonFactory.create_batch(2)
85-
draft = WgDraftFactory(group__parent=area, authors=authors)
85+
rfc_ad = PersonFactory()
86+
draft_authors = PersonFactory.create_batch(2)
87+
rfc_authors = PersonFactory.create_batch(3)
88+
draft = WgDraftFactory(
89+
group__parent=area, authors=draft_authors, ad=draft_ad, stream_id="ietf"
90+
)
91+
rfc_stream_id = "ise"
8692
assert isinstance(draft, Document), "WgDraftFactory should generate a Document"
8793
unused_rfc_number = (
8894
Document.objects.filter(rfc_number__isnull=False).aggregate(
@@ -96,7 +102,7 @@ def test_notify_rfc_published(self):
96102
"draft_name": draft.name,
97103
"draft_rev": draft.rev,
98104
"rfc_number": unused_rfc_number,
99-
"title": draft.title,
105+
"title": "RFC " + draft.title,
100106
"authors": [
101107
{
102108
"titlepage_name": f"titlepage {author.name}",
@@ -106,17 +112,14 @@ def test_notify_rfc_published(self):
106112
"affiliation": "Some Affiliation",
107113
"country": "CA",
108114
}
109-
for author in authors
115+
for author in rfc_authors
110116
],
111-
"group": draft.group.acronym,
112-
"stream": draft.stream_id,
113-
"abstract": draft.abstract,
114-
"pages": draft.pages,
115-
"words": draft.pages * 250,
116-
"formal_languages": [],
117+
"group": rfc_group.acronym,
118+
"stream": rfc_stream_id,
119+
"abstract": "RFC version of " + draft.abstract,
120+
"pages": draft.pages + 10,
117121
"std_level": "ps",
118-
"ad": draft_ad.pk,
119-
"note": "noted",
122+
"ad": rfc_ad.pk,
120123
"obsoletes": [],
121124
"updates": [],
122125
"subseries": [],
@@ -137,7 +140,7 @@ def test_notify_rfc_published(self):
137140
).count(),
138141
1,
139142
)
140-
self.assertEqual(rfc.title, draft.title)
143+
self.assertEqual(rfc.title, "RFC " + draft.title)
141144
self.assertEqual(rfc.documentauthor_set.count(), 0)
142145
self.assertEqual(
143146
list(
@@ -159,18 +162,15 @@ def test_notify_rfc_published(self):
159162
"affiliation": "Some Affiliation",
160163
"country": "CA",
161164
}
162-
for author in authors
165+
for author in rfc_authors
163166
],
164167
)
165-
self.assertEqual(rfc.group, draft.group)
166-
self.assertEqual(rfc.stream, draft.stream)
167-
self.assertEqual(rfc.abstract, draft.abstract)
168-
self.assertEqual(rfc.pages, draft.pages)
169-
self.assertEqual(rfc.words, draft.pages * 250)
170-
self.assertEqual(rfc.formal_languages.count(), 0)
168+
self.assertEqual(rfc.group, rfc_group)
169+
self.assertEqual(rfc.stream_id, rfc_stream_id)
170+
self.assertEqual(rfc.abstract, "RFC version of " + draft.abstract)
171+
self.assertEqual(rfc.pages, draft.pages + 10)
171172
self.assertEqual(rfc.std_level_id, "ps")
172-
self.assertEqual(rfc.ad, draft_ad)
173-
self.assertEqual(rfc.note, "noted")
173+
self.assertEqual(rfc.ad, rfc_ad)
174174
self.assertEqual(rfc.related_that_doc("obs"), [])
175175
self.assertEqual(rfc.related_that_doc("updates"), [])
176176
self.assertEqual(rfc.part_of(), [])

ietf/api/views_rpc.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from tempfile import TemporaryDirectory
66

77
from django.conf import settings
8+
from django.db import IntegrityError
89
from drf_spectacular.utils import OpenApiParameter
910
from rest_framework import mixins, parsers, serializers, viewsets, status
1011
from rest_framework.decorators import action
@@ -360,7 +361,20 @@ def post(self, request):
360361
serializer = RfcPubSerializer(data=request.data)
361362
serializer.is_valid(raise_exception=True)
362363
# Create RFC
363-
serializer.save()
364+
try:
365+
serializer.save()
366+
except IntegrityError as err:
367+
if Document.objects.filter(
368+
rfc_number=serializer.validated_data["rfc_number"]
369+
):
370+
raise serializers.ValidationError(
371+
"RFC with that number already exists",
372+
code="rfc-number-in-use",
373+
)
374+
raise serializers.ValidationError(
375+
f"Unable to publish: {err}",
376+
code="unknown-integrity-error",
377+
)
364378
return Response(NotificationAckSerializer().data)
365379

366380

0 commit comments

Comments
 (0)