Skip to content

Commit 24101bb

Browse files
authored
feat: json snapshots of ipr statements (#9684)
1 parent 8fbbc55 commit 24101bb

File tree

4 files changed

+86
-3
lines changed

4 files changed

+86
-3
lines changed

ietf/ipr/tests.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44

55
import datetime
6+
import json
67
from unittest import mock
78
import re
89

@@ -15,6 +16,8 @@
1516
from django.urls import reverse as urlreverse
1617
from django.utils import timezone
1718

19+
from django.db.models import Max
20+
1821
import debug # pyflakes:ignore
1922

2023
from ietf.api.views import EmailIngestionError
@@ -45,6 +48,7 @@
4548
from ietf.mailtrigger.utils import gather_address_lists
4649
from ietf.message.factories import MessageFactory
4750
from ietf.message.models import Message
51+
from ietf.person.factories import PersonFactory
4852
from ietf.utils.mail import outbox, empty_outbox, get_payload_text
4953
from ietf.utils.test_utils import TestCase, login_testing_unauthorized
5054
from ietf.utils.text import text_to_dict
@@ -1113,3 +1117,56 @@ def test_patent_details_required_unless_blanket(self):
11131117
val = self.data.pop(pf)
11141118
self.assertTrue(HolderIprDisclosureForm(data=self.data).is_valid())
11151119
self.data[pf] = val
1120+
1121+
class JsonSnapshotTests(TestCase):
1122+
def test_json_snapshot(self):
1123+
h = HolderIprDisclosureFactory()
1124+
url = urlreverse("ietf.ipr.views.json_snapshot", kwargs=dict(id=h.id))
1125+
login_testing_unauthorized(self, "secretary", url)
1126+
r = self.client.get(url)
1127+
self.assertEqual(r.status_code, 200)
1128+
dump = json.loads(r.content)
1129+
self.assertCountEqual(
1130+
[o["model"] for o in dump],
1131+
["ipr.holderiprdisclosure", "ipr.iprdisclosurebase", "person.person"],
1132+
)
1133+
h.docs.add(WgRfcFactory())
1134+
r = self.client.get(url)
1135+
self.assertEqual(r.status_code, 200)
1136+
dump = json.loads(r.content)
1137+
self.assertCountEqual(
1138+
[o["model"] for o in dump],
1139+
[
1140+
"ipr.holderiprdisclosure",
1141+
"ipr.iprdisclosurebase",
1142+
"ipr.iprdocrel",
1143+
"person.person",
1144+
],
1145+
)
1146+
IprEventFactory(
1147+
disclosure=h,
1148+
message=MessageFactory(by=PersonFactory()),
1149+
in_reply_to=MessageFactory(),
1150+
)
1151+
r = self.client.get(url)
1152+
self.assertEqual(r.status_code, 200)
1153+
dump = json.loads(r.content)
1154+
self.assertCountEqual(
1155+
[o["model"] for o in dump],
1156+
[
1157+
"ipr.holderiprdisclosure",
1158+
"ipr.iprdisclosurebase",
1159+
"ipr.iprdocrel",
1160+
"ipr.iprevent",
1161+
"message.message",
1162+
"message.message",
1163+
"person.person",
1164+
"person.person",
1165+
"person.person",
1166+
"person.person",
1167+
],
1168+
)
1169+
no_such_ipr_id = IprDisclosureBase.objects.aggregate(Max("id"))["id__max"] + 1
1170+
url = urlreverse("ietf.ipr.views.json_snapshot", kwargs=dict(id=no_such_ipr_id))
1171+
r = self.client.get(url)
1172+
self.assertEqual(r.status_code, 404)

ietf/ipr/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
url(r'^(?P<id>\d+)/notify/(?P<type>update|posted)/$', views.notify),
2222
url(r'^(?P<id>\d+)/post/$', views.post),
2323
url(r'^(?P<id>\d+)/state/$', views.state),
24+
url(r'^(?P<id>\d+)/json-snapshot/$', views.json_snapshot),
2425
url(r'^update/$', RedirectView.as_view(url=reverse_lazy('ietf.ipr.views.showlist'), permanent=True)),
2526
url(r'^update/(?P<id>\d+)/$', views.update),
2627
url(r'^new-(?P<_type>(specific|generic|general|third-party))/$', views.new),

ietf/ipr/utils.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
# Copyright The IETF Trust 2014-2020, All Rights Reserved
1+
# Copyright The IETF Trust 2014-2025, All Rights Reserved
22
# -*- coding: utf-8 -*-
33

4+
import json
5+
import debug # pyflakes:ignore
6+
47
from textwrap import dedent
58

9+
from django.core import serializers
10+
611
from ietf.ipr.mail import process_response_email, UndeliverableIprResponseError
712

8-
import debug # pyflakes:ignore
13+
from ietf.ipr.models import IprDocRel
914

1015
def get_genitive(name):
1116
"""Return the genitive form of name"""
@@ -85,3 +90,18 @@ def ingest_response_email(message: bytes):
8590
email_original_message=message,
8691
email_attach_traceback=True,
8792
) from err
93+
94+
def json_dump_disclosure(disclosure):
95+
objs = set()
96+
objs.add(disclosure)
97+
objs.add(disclosure.iprdisclosurebase_ptr)
98+
objs.add(disclosure.by)
99+
objs.update(IprDocRel.objects.filter(disclosure=disclosure))
100+
objs.update(disclosure.iprevent_set.all())
101+
objs.update([i.by for i in disclosure.iprevent_set.all()])
102+
objs.update([i.message for i in disclosure.iprevent_set.all() if i.message ])
103+
objs.update([i.message.by for i in disclosure.iprevent_set.all() if i.message ])
104+
objs.update([i.in_reply_to for i in disclosure.iprevent_set.all() if i.in_reply_to ])
105+
objs.update([i.in_reply_to.by for i in disclosure.iprevent_set.all() if i.in_reply_to ])
106+
objs = sorted(list(objs),key=lambda o:o.__class__.__name__)
107+
return json.dumps(json.loads(serializers.serialize("json",objs)),indent=4)

ietf/ipr/views.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
NonDocSpecificIprDisclosure, IprDocRel,
3333
RelatedIpr,IprEvent)
3434
from ietf.ipr.utils import (get_genitive, get_ipr_summary,
35-
iprs_from_docs, related_docs)
35+
iprs_from_docs, json_dump_disclosure, related_docs)
3636
from ietf.mailtrigger.utils import gather_address_lists
3737
from ietf.message.models import Message
3838
from ietf.message.utils import infer_message
@@ -901,3 +901,8 @@ def update(request, id):
901901
child = ipr.get_child()
902902
type = class_to_type[child.__class__.__name__]
903903
return new(request, type, updates=id)
904+
905+
@role_required("Secretariat")
906+
def json_snapshot(request, id):
907+
obj = get_object_or_404(IprDisclosureBase,id=id).get_child()
908+
return HttpResponse(json_dump_disclosure(obj),content_type="application/json")

0 commit comments

Comments
 (0)