Add tooltips with doc name to "updates" and "obsoletes" links. Fixes #2866; Commit ready for merge.

- Legacy-Id: 17562
This commit is contained in:
Jennifer Richards 2020-03-30 20:22:05 +00:00
parent 5e47b3afa8
commit 2d6179c1a5
4 changed files with 139 additions and 23 deletions

View file

@ -19,10 +19,12 @@ from django.utils.safestring import mark_safe, SafeData
from django.utils.html import strip_tags
from django.utils.encoding import force_text
from django.utils.encoding import force_str # pyflakes:ignore force_str is used in the doctests
from django.urls import reverse as urlreverse
import debug # pyflakes:ignore
from ietf.doc.models import ConsensusDocEvent
from ietf.doc.utils import prettify_std_name
from ietf.utils.text import wordwrap, fill, wrap_text_if_unwrapped
from ietf.utils.html import sanitize_fragment
from ietf.doc.models import BallotDocEvent
@ -229,6 +231,24 @@ def urlize_ietf_docs(string, autoescape=None):
return mark_safe(string)
urlize_ietf_docs = stringfilter(urlize_ietf_docs)
@register.filter(name='urlize_doc_list', is_safe=True, needs_autoescape=True)
def urlize_doc_list(docs, autoescape=None):
"""Convert a list of DocAliases into list of links using canonical name"""
links = []
for doc in docs:
name=doc.document.canonical_name()
title = doc.document.title
url = urlreverse('ietf.doc.views_doc.document_main', kwargs=dict(name=name))
if autoescape:
name = escape(name)
title = escape(title)
links.append(mark_safe(
'<a href="%(url)s" title="%(title)s">%(name)s</a>' % dict(name=prettify_std_name(name),
title=title,
url=url)
))
return links
@register.filter(name='dashify')
def dashify(string):
"""

View file

@ -1,4 +1,4 @@
# Copyright The IETF Trust 2012-2019, All Rights Reserved
# Copyright The IETF Trust 2012-2020, All Rights Reserved
# -*- coding: utf-8 -*-
@ -516,8 +516,19 @@ Man Expires September 22, 2015 [Page 3]
def test_document_draft(self):
draft = WgDraftFactory(name='draft-ietf-mars-test',rev='01')
HolderIprDisclosureFactory(docs=[draft])
# Docs for testing relationships. Does not test 'possibly-replaces'. The 'replaced_by' direction
# is tested separately below.
replaced = IndividualDraftFactory()
draft.relateddocument_set.create(relationship_id='replaces',source=draft,target=replaced.docalias.first())
obsoleted = IndividualDraftFactory()
draft.relateddocument_set.create(relationship_id='obs',source=draft,target=obsoleted.docalias.first())
obsoleted_by = IndividualDraftFactory()
obsoleted_by.relateddocument_set.create(relationship_id='obs',source=obsoleted_by,target=draft.docalias.first())
updated = IndividualDraftFactory()
draft.relateddocument_set.create(relationship_id='updates',source=draft,target=updated.docalias.first())
updated_by = IndividualDraftFactory()
updated_by.relateddocument_set.create(relationship_id='updates',source=obsoleted_by,target=draft.docalias.first())
# these tests aren't testing all attributes yet, feel free to
# expand them
@ -527,24 +538,68 @@ Man Expires September 22, 2015 [Page 3]
self.assertContains(r, "Active Internet-Draft")
self.assertContains(r, "Show full document text")
self.assertNotContains(r, "Deimos street")
self.assertContains(r, replaced.canonical_name())
self.assertContains(r, replaced.title)
# obs/updates not included until draft is RFC
self.assertNotContains(r, obsoleted.canonical_name())
self.assertNotContains(r, obsoleted.title)
self.assertNotContains(r, obsoleted_by.canonical_name())
self.assertNotContains(r, obsoleted_by.title)
self.assertNotContains(r, updated.canonical_name())
self.assertNotContains(r, updated.title)
self.assertNotContains(r, updated_by.canonical_name())
self.assertNotContains(r, updated_by.title)
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)) + "?include_text=0")
self.assertEqual(r.status_code, 200)
self.assertContains(r, "Active Internet-Draft")
self.assertNotContains(r, "Show full document text")
self.assertContains(r, "Deimos street")
self.assertContains(r, replaced.canonical_name())
self.assertContains(r, replaced.title)
# obs/updates not included until draft is RFC
self.assertNotContains(r, obsoleted.canonical_name())
self.assertNotContains(r, obsoleted.title)
self.assertNotContains(r, obsoleted_by.canonical_name())
self.assertNotContains(r, obsoleted_by.title)
self.assertNotContains(r, updated.canonical_name())
self.assertNotContains(r, updated.title)
self.assertNotContains(r, updated_by.canonical_name())
self.assertNotContains(r, updated_by.title)
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)) + "?include_text=foo")
self.assertEqual(r.status_code, 200)
self.assertContains(r, "Active Internet-Draft")
self.assertNotContains(r, "Show full document text")
self.assertContains(r, "Deimos street")
self.assertContains(r, replaced.canonical_name())
self.assertContains(r, replaced.title)
# obs/updates not included until draft is RFC
self.assertNotContains(r, obsoleted.canonical_name())
self.assertNotContains(r, obsoleted.title)
self.assertNotContains(r, obsoleted_by.canonical_name())
self.assertNotContains(r, obsoleted_by.title)
self.assertNotContains(r, updated.canonical_name())
self.assertNotContains(r, updated.title)
self.assertNotContains(r, updated_by.canonical_name())
self.assertNotContains(r, updated_by.title)
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)) + "?include_text=1")
self.assertEqual(r.status_code, 200)
self.assertContains(r, "Active Internet-Draft")
self.assertNotContains(r, "Show full document text")
self.assertContains(r, "Deimos street")
self.assertContains(r, replaced.canonical_name())
self.assertContains(r, replaced.title)
# obs/updates not included until draft is RFC
self.assertNotContains(r, obsoleted.canonical_name())
self.assertNotContains(r, obsoleted.title)
self.assertNotContains(r, obsoleted_by.canonical_name())
self.assertNotContains(r, obsoleted_by.title)
self.assertNotContains(r, updated.canonical_name())
self.assertNotContains(r, updated.title)
self.assertNotContains(r, updated_by.canonical_name())
self.assertNotContains(r, updated_by.title)
self.client.cookies = SimpleCookie({str('full_draft'): str('on')})
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)))
@ -552,6 +607,17 @@ Man Expires September 22, 2015 [Page 3]
self.assertContains(r, "Active Internet-Draft")
self.assertNotContains(r, "Show full document text")
self.assertContains(r, "Deimos street")
self.assertContains(r, replaced.canonical_name())
self.assertContains(r, replaced.title)
# obs/updates not included until draft is RFC
self.assertNotContains(r, obsoleted.canonical_name())
self.assertNotContains(r, obsoleted.title)
self.assertNotContains(r, obsoleted_by.canonical_name())
self.assertNotContains(r, obsoleted_by.title)
self.assertNotContains(r, updated.canonical_name())
self.assertNotContains(r, updated.title)
self.assertNotContains(r, updated_by.canonical_name())
self.assertNotContains(r, updated_by.title)
self.client.cookies = SimpleCookie({str('full_draft'): str('off')})
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)))
@ -559,6 +625,17 @@ Man Expires September 22, 2015 [Page 3]
self.assertContains(r, "Active Internet-Draft")
self.assertContains(r, "Show full document text")
self.assertNotContains(r, "Deimos street")
self.assertContains(r, replaced.canonical_name())
self.assertContains(r, replaced.title)
# obs/updates not included until draft is RFC
self.assertNotContains(r, obsoleted.canonical_name())
self.assertNotContains(r, obsoleted.title)
self.assertNotContains(r, obsoleted_by.canonical_name())
self.assertNotContains(r, obsoleted_by.title)
self.assertNotContains(r, updated.canonical_name())
self.assertNotContains(r, updated.title)
self.assertNotContains(r, updated_by.canonical_name())
self.assertNotContains(r, updated_by.title)
self.client.cookies = SimpleCookie({str('full_draft'): str('foo')})
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)))
@ -566,6 +643,17 @@ Man Expires September 22, 2015 [Page 3]
self.assertContains(r, "Active Internet-Draft")
self.assertContains(r, "Show full document text")
self.assertNotContains(r, "Deimos street")
self.assertContains(r, replaced.canonical_name())
self.assertContains(r, replaced.title)
# obs/updates not included until draft is RFC
self.assertNotContains(r, obsoleted.canonical_name())
self.assertNotContains(r, obsoleted.title)
self.assertNotContains(r, obsoleted_by.canonical_name())
self.assertNotContains(r, obsoleted_by.title)
self.assertNotContains(r, updated.canonical_name())
self.assertNotContains(r, updated.title)
self.assertNotContains(r, updated_by.canonical_name())
self.assertNotContains(r, updated_by.title)
r = self.client.get(urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=draft.name)))
self.assertEqual(r.status_code, 200)
@ -604,7 +692,8 @@ Man Expires September 22, 2015 [Page 3]
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)))
self.assertEqual(r.status_code, 200)
self.assertContains(r, "Replaced Internet-Draft")
self.assertContains(r, replacement.name)
self.assertContains(r, replacement.canonical_name())
self.assertContains(r, replacement.title)
rel.delete()
# draft published as RFC
@ -627,6 +716,17 @@ Man Expires September 22, 2015 [Page 3]
self.assertEqual(r.status_code, 200)
self.assertContains(r, "RFC 123456")
self.assertContains(r, draft.name)
self.assertContains(r, replaced.canonical_name())
self.assertContains(r, replaced.title)
# obs/updates included with RFC
self.assertContains(r, obsoleted.canonical_name())
self.assertContains(r, obsoleted.title)
self.assertContains(r, obsoleted_by.canonical_name())
self.assertContains(r, obsoleted_by.title)
self.assertContains(r, updated.canonical_name())
self.assertContains(r, updated.title)
self.assertContains(r, updated_by.canonical_name())
self.assertContains(r, updated_by.title)
# naked RFC - also wierd that we test a PS from the ISE
rfc = IndividualDraftFactory(

View file

@ -413,10 +413,6 @@ def document_main(request, name, rev=None):
augment_docs_and_user_with_user_info([doc], request.user)
replaces = [d.name for d in doc.related_that_doc("replaces")]
replaced_by = [d.name for d in doc.related_that("replaces")]
possibly_replaces = [d.name for d in doc.related_that_doc("possibly-replaces")]
possibly_replaced_by = [d.name for d in doc.related_that("possibly-replaces")]
published = doc.latest_event(type="published_rfc")
started_iesg_process = doc.latest_event(type="started_iesg_process")
@ -460,14 +456,14 @@ def document_main(request, name, rev=None):
submission=submission,
resurrected_by=resurrected_by,
replaces=replaces,
replaced_by=replaced_by,
possibly_replaces=possibly_replaces,
possibly_replaced_by=possibly_replaced_by,
updates=[prettify_std_name(d.name) for d in doc.related_that_doc("updates")],
updated_by=[prettify_std_name(d.document.canonical_name()) for d in doc.related_that("updates")],
obsoletes=[prettify_std_name(d.name) for d in doc.related_that_doc("obs")],
obsoleted_by=[prettify_std_name(d.document.canonical_name()) for d in doc.related_that("obs")],
replaces=doc.related_that_doc("replaces"),
replaced_by=doc.related_that("replaces"),
possibly_replaces=doc.related_that_doc("possibly_replaces"),
possibly_replaced_by=doc.related_that("possibly_replaces"),
updates=doc.related_that_doc("updates"),
updated_by=doc.related_that("updates"),
obsoletes=doc.related_that_doc("obs"),
obsoleted_by=doc.related_that("obs"),
conflict_reviews=conflict_reviews,
status_changes=status_changes,
proposed_status_changes=proposed_status_changes,

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2016, All Rights Reserved #}
{# Copyright The IETF Trust 2016-2020, All Rights Reserved #}
{% load origin %}
{% load staticfiles %}
{% load ietf_filters %}
@ -52,10 +52,10 @@
RFC - {{ doc.std_level }}
({% 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 %})
{% if obsoleted_by %}<div>Obsoleted by {{ obsoleted_by|join:", "|urlize_ietf_docs }}</div>{% endif %}
{% if updated_by %}<div>Updated by {{ updated_by|join:", "|urlize_ietf_docs }}</div>{% endif %}
{% if obsoletes %}<div>Obsoletes {{ obsoletes|join:", "|urlize_ietf_docs }}</div>{% endif %}
{% if updates %}<div>Updates {{ updates|join:", "|urlize_ietf_docs }}</div>{% endif %}
{% if obsoleted_by %}<div>Obsoleted by {{ obsoleted_by|urlize_doc_list|join:", " }}</div>{% endif %}
{% if updated_by %}<div>Updated by {{ updated_by|urlize_doc_list|join:", " }}</div>{% endif %}
{% if obsoletes %}<div>Obsoletes {{ obsoletes|urlize_doc_list|join:", " }}</div>{% endif %}
{% if updates %}<div> Updates {{ updates|urlize_doc_list|join:", " }}</div>{% endif %}
{% if status_changes %}<div>Status changed by {{ status_changes|join:", "|urlize_ietf_docs }}</div>{% endif %}
{% if proposed_status_changes %}<div>Proposed status changed by {{ proposed_status_changes|join:", "|urlize_ietf_docs }}</div>{% endif %}
{% if rfc_aliases %}<div>Also known as {{ rfc_aliases|join:", "|urlize_ietf_docs }}</div>{% endif %}
@ -89,7 +89,7 @@
{% endif %}
</td>
<td>
{{ replaces|join:", "|urlize_ietf_docs|default:"(None)" }}
{{ replaces|urlize_doc_list|join:", "|default:"(None)" }}
</td>
</tr>
{% endif %}
@ -100,7 +100,7 @@
<th>Replaced by</th>
<td class="edit"></td>
<td>
{{ replaced_by|join:", "|urlize_ietf_docs }}
{{ replaced_by|urlize_doc_list|join:", " }}
</td>
</tr>
{% endif %}
@ -116,7 +116,7 @@
{% endif %}
</td>
<td>
{{ possibly_replaces|join:", "|urlize_ietf_docs }}
{{ possibly_replaces|urlize_doc_list|join:", " }}
</td>
</tr>
{% endif %}
@ -131,7 +131,7 @@
{% endif %}
</td>
<td>
{{ possibly_replaced_by|join:", "|urlize_ietf_docs }}
{{ possibly_replaced_by|urlize_doc_list|join:", " }}
</td>
</tr>
{% endif %}