Skip to content

Commit 98fab6c

Browse files
committed
Merged in [17562] from jennifer@painless-security.com:
Add tooltips with doc name to 'updates' and 'obsoletes' links. Fixes ietf-tools#2866; - Legacy-Id: 17569 Note: SVN reference [17562] has been migrated to Git commit 2d6179c
2 parents 8b2dd1f + 2d6179c commit 98fab6c

4 files changed

Lines changed: 139 additions & 23 deletions

File tree

ietf/doc/templatetags/ietf_filters.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919
from django.utils.html import strip_tags
2020
from django.utils.encoding import force_text
2121
from django.utils.encoding import force_str # pyflakes:ignore force_str is used in the doctests
22+
from django.urls import reverse as urlreverse
2223

2324
import debug # pyflakes:ignore
2425

2526
from ietf.doc.models import ConsensusDocEvent
27+
from ietf.doc.utils import prettify_std_name
2628
from ietf.utils.text import wordwrap, fill, wrap_text_if_unwrapped
2729
from ietf.utils.html import sanitize_fragment
2830
from ietf.doc.models import BallotDocEvent
@@ -229,6 +231,24 @@ def urlize_ietf_docs(string, autoescape=None):
229231
return mark_safe(string)
230232
urlize_ietf_docs = stringfilter(urlize_ietf_docs)
231233

234+
@register.filter(name='urlize_doc_list', is_safe=True, needs_autoescape=True)
235+
def urlize_doc_list(docs, autoescape=None):
236+
"""Convert a list of DocAliases into list of links using canonical name"""
237+
links = []
238+
for doc in docs:
239+
name=doc.document.canonical_name()
240+
title = doc.document.title
241+
url = urlreverse('ietf.doc.views_doc.document_main', kwargs=dict(name=name))
242+
if autoescape:
243+
name = escape(name)
244+
title = escape(title)
245+
links.append(mark_safe(
246+
'<a href="%(url)s" title="%(title)s">%(name)s</a>' % dict(name=prettify_std_name(name),
247+
title=title,
248+
url=url)
249+
))
250+
return links
251+
232252
@register.filter(name='dashify')
233253
def dashify(string):
234254
"""

ietf/doc/tests.py

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

44

@@ -516,8 +516,19 @@ def tearDown(self):
516516
def test_document_draft(self):
517517
draft = WgDraftFactory(name='draft-ietf-mars-test',rev='01')
518518
HolderIprDisclosureFactory(docs=[draft])
519+
520+
# Docs for testing relationships. Does not test 'possibly-replaces'. The 'replaced_by' direction
521+
# is tested separately below.
519522
replaced = IndividualDraftFactory()
520523
draft.relateddocument_set.create(relationship_id='replaces',source=draft,target=replaced.docalias.first())
524+
obsoleted = IndividualDraftFactory()
525+
draft.relateddocument_set.create(relationship_id='obs',source=draft,target=obsoleted.docalias.first())
526+
obsoleted_by = IndividualDraftFactory()
527+
obsoleted_by.relateddocument_set.create(relationship_id='obs',source=obsoleted_by,target=draft.docalias.first())
528+
updated = IndividualDraftFactory()
529+
draft.relateddocument_set.create(relationship_id='updates',source=draft,target=updated.docalias.first())
530+
updated_by = IndividualDraftFactory()
531+
updated_by.relateddocument_set.create(relationship_id='updates',source=obsoleted_by,target=draft.docalias.first())
521532

522533
# these tests aren't testing all attributes yet, feel free to
523534
# expand them
@@ -527,45 +538,122 @@ def test_document_draft(self):
527538
self.assertContains(r, "Active Internet-Draft")
528539
self.assertContains(r, "Show full document text")
529540
self.assertNotContains(r, "Deimos street")
541+
self.assertContains(r, replaced.canonical_name())
542+
self.assertContains(r, replaced.title)
543+
# obs/updates not included until draft is RFC
544+
self.assertNotContains(r, obsoleted.canonical_name())
545+
self.assertNotContains(r, obsoleted.title)
546+
self.assertNotContains(r, obsoleted_by.canonical_name())
547+
self.assertNotContains(r, obsoleted_by.title)
548+
self.assertNotContains(r, updated.canonical_name())
549+
self.assertNotContains(r, updated.title)
550+
self.assertNotContains(r, updated_by.canonical_name())
551+
self.assertNotContains(r, updated_by.title)
530552

531553
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)) + "?include_text=0")
532554
self.assertEqual(r.status_code, 200)
533555
self.assertContains(r, "Active Internet-Draft")
534556
self.assertNotContains(r, "Show full document text")
535557
self.assertContains(r, "Deimos street")
558+
self.assertContains(r, replaced.canonical_name())
559+
self.assertContains(r, replaced.title)
560+
# obs/updates not included until draft is RFC
561+
self.assertNotContains(r, obsoleted.canonical_name())
562+
self.assertNotContains(r, obsoleted.title)
563+
self.assertNotContains(r, obsoleted_by.canonical_name())
564+
self.assertNotContains(r, obsoleted_by.title)
565+
self.assertNotContains(r, updated.canonical_name())
566+
self.assertNotContains(r, updated.title)
567+
self.assertNotContains(r, updated_by.canonical_name())
568+
self.assertNotContains(r, updated_by.title)
536569

537570
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)) + "?include_text=foo")
538571
self.assertEqual(r.status_code, 200)
539572
self.assertContains(r, "Active Internet-Draft")
540573
self.assertNotContains(r, "Show full document text")
541574
self.assertContains(r, "Deimos street")
575+
self.assertContains(r, replaced.canonical_name())
576+
self.assertContains(r, replaced.title)
577+
# obs/updates not included until draft is RFC
578+
self.assertNotContains(r, obsoleted.canonical_name())
579+
self.assertNotContains(r, obsoleted.title)
580+
self.assertNotContains(r, obsoleted_by.canonical_name())
581+
self.assertNotContains(r, obsoleted_by.title)
582+
self.assertNotContains(r, updated.canonical_name())
583+
self.assertNotContains(r, updated.title)
584+
self.assertNotContains(r, updated_by.canonical_name())
585+
self.assertNotContains(r, updated_by.title)
542586

543587
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)) + "?include_text=1")
544588
self.assertEqual(r.status_code, 200)
545589
self.assertContains(r, "Active Internet-Draft")
546590
self.assertNotContains(r, "Show full document text")
547591
self.assertContains(r, "Deimos street")
592+
self.assertContains(r, replaced.canonical_name())
593+
self.assertContains(r, replaced.title)
594+
# obs/updates not included until draft is RFC
595+
self.assertNotContains(r, obsoleted.canonical_name())
596+
self.assertNotContains(r, obsoleted.title)
597+
self.assertNotContains(r, obsoleted_by.canonical_name())
598+
self.assertNotContains(r, obsoleted_by.title)
599+
self.assertNotContains(r, updated.canonical_name())
600+
self.assertNotContains(r, updated.title)
601+
self.assertNotContains(r, updated_by.canonical_name())
602+
self.assertNotContains(r, updated_by.title)
548603

549604
self.client.cookies = SimpleCookie({str('full_draft'): str('on')})
550605
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)))
551606
self.assertEqual(r.status_code, 200)
552607
self.assertContains(r, "Active Internet-Draft")
553608
self.assertNotContains(r, "Show full document text")
554609
self.assertContains(r, "Deimos street")
610+
self.assertContains(r, replaced.canonical_name())
611+
self.assertContains(r, replaced.title)
612+
# obs/updates not included until draft is RFC
613+
self.assertNotContains(r, obsoleted.canonical_name())
614+
self.assertNotContains(r, obsoleted.title)
615+
self.assertNotContains(r, obsoleted_by.canonical_name())
616+
self.assertNotContains(r, obsoleted_by.title)
617+
self.assertNotContains(r, updated.canonical_name())
618+
self.assertNotContains(r, updated.title)
619+
self.assertNotContains(r, updated_by.canonical_name())
620+
self.assertNotContains(r, updated_by.title)
555621

556622
self.client.cookies = SimpleCookie({str('full_draft'): str('off')})
557623
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)))
558624
self.assertEqual(r.status_code, 200)
559625
self.assertContains(r, "Active Internet-Draft")
560626
self.assertContains(r, "Show full document text")
561627
self.assertNotContains(r, "Deimos street")
628+
self.assertContains(r, replaced.canonical_name())
629+
self.assertContains(r, replaced.title)
630+
# obs/updates not included until draft is RFC
631+
self.assertNotContains(r, obsoleted.canonical_name())
632+
self.assertNotContains(r, obsoleted.title)
633+
self.assertNotContains(r, obsoleted_by.canonical_name())
634+
self.assertNotContains(r, obsoleted_by.title)
635+
self.assertNotContains(r, updated.canonical_name())
636+
self.assertNotContains(r, updated.title)
637+
self.assertNotContains(r, updated_by.canonical_name())
638+
self.assertNotContains(r, updated_by.title)
562639

563640
self.client.cookies = SimpleCookie({str('full_draft'): str('foo')})
564641
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)))
565642
self.assertEqual(r.status_code, 200)
566643
self.assertContains(r, "Active Internet-Draft")
567644
self.assertContains(r, "Show full document text")
568645
self.assertNotContains(r, "Deimos street")
646+
self.assertContains(r, replaced.canonical_name())
647+
self.assertContains(r, replaced.title)
648+
# obs/updates not included until draft is RFC
649+
self.assertNotContains(r, obsoleted.canonical_name())
650+
self.assertNotContains(r, obsoleted.title)
651+
self.assertNotContains(r, obsoleted_by.canonical_name())
652+
self.assertNotContains(r, obsoleted_by.title)
653+
self.assertNotContains(r, updated.canonical_name())
654+
self.assertNotContains(r, updated.title)
655+
self.assertNotContains(r, updated_by.canonical_name())
656+
self.assertNotContains(r, updated_by.title)
569657

570658
r = self.client.get(urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=draft.name)))
571659
self.assertEqual(r.status_code, 200)
@@ -604,7 +692,8 @@ def test_document_draft(self):
604692
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)))
605693
self.assertEqual(r.status_code, 200)
606694
self.assertContains(r, "Replaced Internet-Draft")
607-
self.assertContains(r, replacement.name)
695+
self.assertContains(r, replacement.canonical_name())
696+
self.assertContains(r, replacement.title)
608697
rel.delete()
609698

610699
# draft published as RFC
@@ -627,6 +716,17 @@ def test_document_draft(self):
627716
self.assertEqual(r.status_code, 200)
628717
self.assertContains(r, "RFC 123456")
629718
self.assertContains(r, draft.name)
719+
self.assertContains(r, replaced.canonical_name())
720+
self.assertContains(r, replaced.title)
721+
# obs/updates included with RFC
722+
self.assertContains(r, obsoleted.canonical_name())
723+
self.assertContains(r, obsoleted.title)
724+
self.assertContains(r, obsoleted_by.canonical_name())
725+
self.assertContains(r, obsoleted_by.title)
726+
self.assertContains(r, updated.canonical_name())
727+
self.assertContains(r, updated.title)
728+
self.assertContains(r, updated_by.canonical_name())
729+
self.assertContains(r, updated_by.title)
630730

631731
# naked RFC - also wierd that we test a PS from the ISE
632732
rfc = IndividualDraftFactory(

ietf/doc/views_doc.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -412,10 +412,6 @@ def document_main(request, name, rev=None):
412412

413413
augment_docs_and_user_with_user_info([doc], request.user)
414414

415-
replaces = [d.name for d in doc.related_that_doc("replaces")]
416-
replaced_by = [d.name for d in doc.related_that("replaces")]
417-
possibly_replaces = [d.name for d in doc.related_that_doc("possibly-replaces")]
418-
possibly_replaced_by = [d.name for d in doc.related_that("possibly-replaces")]
419415
published = doc.latest_event(type="published_rfc")
420416
started_iesg_process = doc.latest_event(type="started_iesg_process")
421417

@@ -459,14 +455,14 @@ def document_main(request, name, rev=None):
459455
submission=submission,
460456
resurrected_by=resurrected_by,
461457

462-
replaces=replaces,
463-
replaced_by=replaced_by,
464-
possibly_replaces=possibly_replaces,
465-
possibly_replaced_by=possibly_replaced_by,
466-
updates=[prettify_std_name(d.name) for d in doc.related_that_doc("updates")],
467-
updated_by=[prettify_std_name(d.document.canonical_name()) for d in doc.related_that("updates")],
468-
obsoletes=[prettify_std_name(d.name) for d in doc.related_that_doc("obs")],
469-
obsoleted_by=[prettify_std_name(d.document.canonical_name()) for d in doc.related_that("obs")],
458+
replaces=doc.related_that_doc("replaces"),
459+
replaced_by=doc.related_that("replaces"),
460+
possibly_replaces=doc.related_that_doc("possibly_replaces"),
461+
possibly_replaced_by=doc.related_that("possibly_replaces"),
462+
updates=doc.related_that_doc("updates"),
463+
updated_by=doc.related_that("updates"),
464+
obsoletes=doc.related_that_doc("obs"),
465+
obsoleted_by=doc.related_that("obs"),
470466
conflict_reviews=conflict_reviews,
471467
status_changes=status_changes,
472468
proposed_status_changes=proposed_status_changes,

ietf/templates/doc/document_draft.html

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{% extends "base.html" %}
2-
{# Copyright The IETF Trust 2016, All Rights Reserved #}
2+
{# Copyright The IETF Trust 2016-2020, All Rights Reserved #}
33
{% load origin %}
44
{% load staticfiles %}
55
{% load ietf_filters %}
@@ -52,10 +52,10 @@
5252
RFC - {{ doc.std_level }}
5353
({% if published %}{{ published.time|date:"F Y" }}{% else %}publication date unknown{% endif %}{% if has_errata %}; <a href="https://www.rfc-editor.org/errata_search.php?rfc={{ rfc_number }}" rel="nofollow">Errata</a>{% else %}; No errata{% endif %})
5454

55-
{% if obsoleted_by %}<div>Obsoleted by {{ obsoleted_by|join:", "|urlize_ietf_docs }}</div>{% endif %}
56-
{% if updated_by %}<div>Updated by {{ updated_by|join:", "|urlize_ietf_docs }}</div>{% endif %}
57-
{% if obsoletes %}<div>Obsoletes {{ obsoletes|join:", "|urlize_ietf_docs }}</div>{% endif %}
58-
{% if updates %}<div>Updates {{ updates|join:", "|urlize_ietf_docs }}</div>{% endif %}
55+
{% if obsoleted_by %}<div>Obsoleted by {{ obsoleted_by|urlize_doc_list|join:", " }}</div>{% endif %}
56+
{% if updated_by %}<div>Updated by {{ updated_by|urlize_doc_list|join:", " }}</div>{% endif %}
57+
{% if obsoletes %}<div>Obsoletes {{ obsoletes|urlize_doc_list|join:", " }}</div>{% endif %}
58+
{% if updates %}<div> Updates {{ updates|urlize_doc_list|join:", " }}</div>{% endif %}
5959
{% if status_changes %}<div>Status changed by {{ status_changes|join:", "|urlize_ietf_docs }}</div>{% endif %}
6060
{% if proposed_status_changes %}<div>Proposed status changed by {{ proposed_status_changes|join:", "|urlize_ietf_docs }}</div>{% endif %}
6161
{% if rfc_aliases %}<div>Also known as {{ rfc_aliases|join:", "|urlize_ietf_docs }}</div>{% endif %}
@@ -89,7 +89,7 @@
8989
{% endif %}
9090
</td>
9191
<td>
92-
{{ replaces|join:", "|urlize_ietf_docs|default:"(None)" }}
92+
{{ replaces|urlize_doc_list|join:", "|default:"(None)" }}
9393
</td>
9494
</tr>
9595
{% endif %}
@@ -100,7 +100,7 @@
100100
<th>Replaced by</th>
101101
<td class="edit"></td>
102102
<td>
103-
{{ replaced_by|join:", "|urlize_ietf_docs }}
103+
{{ replaced_by|urlize_doc_list|join:", " }}
104104
</td>
105105
</tr>
106106
{% endif %}
@@ -116,7 +116,7 @@
116116
{% endif %}
117117
</td>
118118
<td>
119-
{{ possibly_replaces|join:", "|urlize_ietf_docs }}
119+
{{ possibly_replaces|urlize_doc_list|join:", " }}
120120
</td>
121121
</tr>
122122
{% endif %}
@@ -131,7 +131,7 @@
131131
{% endif %}
132132
</td>
133133
<td>
134-
{{ possibly_replaced_by|join:", "|urlize_ietf_docs }}
134+
{{ possibly_replaced_by|urlize_doc_list|join:", " }}
135135
</td>
136136
</tr>
137137
{% endif %}

0 commit comments

Comments
 (0)