diff --git a/ietf/idindex/tests.py b/ietf/idindex/tests.py index ac0d68298..5f7ff9d9c 100644 --- a/ietf/idindex/tests.py +++ b/ietf/idindex/tests.py @@ -101,7 +101,7 @@ class IndexTests(TestCase): author = draft.documentauthor_set.order_by("order").get() self.assertEqual(t[14], u"%s <%s>" % (author.author.person.name, author.author.address)) self.assertEqual(t[15], u"%s <%s>" % (draft.shepherd.person.name, draft.shepherd.address)) - self.assertEqual(t[16], u"%s <%s>" % (draft.ad, draft.ad.email_address())) + self.assertEqual(t[16], u"%s <%s>" % (draft.ad.plain_ascii(), draft.ad.email_address())) # test RFC diff --git a/ietf/submit/models.py b/ietf/submit/models.py index bdffda06c..9bb3fed18 100644 --- a/ietf/submit/models.py +++ b/ietf/submit/models.py @@ -54,7 +54,7 @@ class Submission(models.Model): return u"%s-%s" % (self.name, self.rev) def authors_parsed(self): - if not hasattr(self._meta, '_cached_authors_parsed'): + if not hasattr(self, '_cached_authors_parsed'): from ietf.submit.utils import ensure_person_email_info_exists res = [] for line in self.authors.replace("\r", "").split("\n"): @@ -64,8 +64,8 @@ class Submission(models.Model): if not parsed["email"]: parsed["email"] = ensure_person_email_info_exists(**parsed).address res.append(parsed) - self._meta._cached_authors_parsed = res - return self._meta._cached_authors_parsed + self._cached_authors_parsed = res + return self._cached_authors_parsed def submitter_parsed(self): return parse_email_line(self.submitter) diff --git a/ietf/submit/test_submission.nonascii b/ietf/submit/test_submission.nonascii new file mode 100644 index 000000000..3e481b4e9 --- /dev/null +++ b/ietf/submit/test_submission.nonascii @@ -0,0 +1,212 @@ + + + + +Network Working Group %(initials)s %(surname)s +Internet-Draft Test Centre Inc. +Intended status: Informational %(month)s %(year)s +Expires: %(expiration)s + + + Testing Tests + %(name)s + +Abstract + + This document describes how to test tests. + +Status of This Memo + + This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF). Note that other groups may also distribute + working documents as Internet-Drafts. The list of current Internet- + Drafts is at http://datatracker.ietf.org/drafts/current/. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress." + + This Internet-Draft will expire on %(expiration)s. + +Copyright Notice + + Copyright (c) %(year)s IETF Trust and the persons identified as the + document authors. All rights reserved. + + This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (http://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with respect + to this document. Code Components extracted from this document must + include Simplified BSD License text as described in Section 4.e of + the Trust Legal Provisions and are provided without warranty as + described in the Simplified BSD License. + + + + + + + +%(surname)s Expires %(expiration)s [Page 1] + +Internet-Draft Testing Tests %(month)s %(year)s + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 + 2. Security Considerations . . . . . . . . . . . . . . . . . . . 2 + 3. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 2 + Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 2 + +1. Introduction + + This document describes a protocol for testing tests. + +2. Yang + + file "ietf-mpls@2015-10-16.yang" + + module ietf-mpls { + + namespace "urn:ietf:params:xml:ns:yang:ietf-mpls"; + + prefix "mpls"; + + import ietf-routing { + prefix "rt"; + } + + import ietf-interfaces { + prefix "if"; + } + + organization "TBD"; + + contact "TBD"; + + description + "This YANG module defines the essential components for the + management of the MPLS subsystem."; + + revision "2015-10-16" { + description + "Initial revision"; + reference "RFC 3031: A YANG Data Model for base MPLS"; + } + + typedef mpls-label { + type uint32 { + range "0..1048575"; + } + description + "The MPLS label range"; + } + + typedef percent { + type uint16 { + range "0 .. 100"; + } + description "Percentage"; + } + + grouping interface-mpls { + description "MPLS interface properties grouping"; + leaf enabled { + type boolean; + description + "'true' if mpls encapsulation is enabled on the + interface. 'false' if mpls encapsulation is enabled + on the interface."; + } + } + + augment "/rt:routing/rt:routing-instance" { + description "MPLS augmentation."; + container mpls { + description + "MPLS container, to be used as an augmentation target node + other MPLS sub-features config, e.g. MPLS static LSP, MPLS + LDP LSPs, and Trafic Engineering MPLS LSP Tunnels, etc."; + + list interface { + key "name"; + description "List of MPLS interfaces"; + leaf name { + type if:interface-ref; + description + "The name of a configured MPLS interface"; + } + container config { + description "Holds intended configuration"; + uses interface-mpls; + } + container state { + config false; + description "Holds inuse configuration"; + uses interface-mpls; + } + } + } + } + + augment "/rt:routing-state/rt:routing-instance" { + description "MPLS augmentation."; + container mpls { + config false; + description + "MPLS container, to be used as an augmentation target node + other MPLS sub-features state"; + } + } + } + + + +3. Security Considerations + + There are none. + +4. IANA Considerations + + No new registrations for IANA. + +Author's Address + + %(author)s + Test Centre Inc. + 42 Some Road + Some Where 12345 + UK + + Email: author@example.com + + + + + + + + + + + + + + + + + + + + + + + +%(surname)s Expires %(expiration)s [Page 2] diff --git a/ietf/submit/tests.py b/ietf/submit/tests.py index 1698703e3..a03852029 100644 --- a/ietf/submit/tests.py +++ b/ietf/submit/tests.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import datetime import os import shutil @@ -18,6 +19,7 @@ from ietf.group.utils import setup_default_community_list_for_group from ietf.meeting.models import Meeting from ietf.message.models import Message from ietf.person.models import Person, Email +from ietf.person.factories import UserFactory, PersonFactory from ietf.submit.models import Submission, Preapproval from ietf.submit.mail import add_submission_email, process_response_email from ietf.utils.mail import outbox, empty_outbox @@ -25,12 +27,15 @@ from ietf.utils.test_data import make_test_data from ietf.utils.test_utils import login_testing_unauthorized, unicontent, TestCase -def submission_file(name, rev, group, format, templatename): +def submission_file(name, rev, group, format, templatename, author=None): # construct appropriate text draft f = open(os.path.join(settings.BASE_DIR, "submit", templatename)) template = f.read() f.close() + if not author: + author = PersonFactory() + submission_text = template % dict( date=datetime.date.today().strftime("%d %B %Y"), expiration=(datetime.date.today() + datetime.timedelta(days=100)).strftime("%d %B, %Y"), @@ -38,9 +43,13 @@ def submission_file(name, rev, group, format, templatename): month=datetime.date.today().strftime("%B"), name="%s-%s" % (name, rev), group=group or "", + author=author.name, + initials=author.initials(), + surname=author.last_name(), + email=author.email().address.lower(), ) - file = StringIO(str(submission_text)) + file = StringIO(submission_text) file.name = "%s-%s.%s" % (name, rev, format) return file @@ -618,7 +627,10 @@ class SubmitTests(TestCase): "authors-0-email": "person1@example.com", "authors-1-name": "Person 2", "authors-1-email": "person2@example.com", - "authors-prefix": ["authors-", "authors-0", "authors-1"], + "authors-2-name": "Person 3", + "authors-2-email": "", + + "authors-prefix": ["authors-", "authors-0", "authors-1", "authors-2"], }) self.assertEqual(r.status_code, 302) @@ -633,11 +645,13 @@ class SubmitTests(TestCase): self.assertEqual(submission.state_id, "manual") authors = submission.authors_parsed() - self.assertEqual(len(authors), 2) + self.assertEqual(len(authors), 3) self.assertEqual(authors[0]["name"], "Person 1") self.assertEqual(authors[0]["email"], "person1@example.com") self.assertEqual(authors[1]["name"], "Person 2") self.assertEqual(authors[1]["email"], "person2@example.com") + self.assertEqual(authors[2]["name"], "Person 3") + self.assertEqual(authors[2]["email"], "unknown-email-Person-3") self.assertEqual(len(outbox), mailbox_before + 1) self.assertTrue("Manual Post Requested" in outbox[-1]["Subject"]) @@ -873,6 +887,36 @@ class SubmitTests(TestCase): self.assertIn('Expected the PS file to have extension ".ps"', m) self.assertIn('Expected an PS file of type "application/postscript"', m) + def test_submit_nonascii_name(self): + make_test_data() + + name = "draft-authorname-testing-nonascii" + rev = "00" + group = None + + # get + url = urlreverse('ietf.submit.views.upload_submission') + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + + # submit + #author = PersonFactory(name=u"Jörgen Nilsson".encode('latin1')) + user = UserFactory(first_name=u"Jörgen", last_name=u"Nilsson") + author = PersonFactory(user=user) + files = {"txt": submission_file(name, rev, group, "txt", "test_submission.nonascii", author=author) } + + r = self.client.post(url, files) + + self.assertEqual(r.status_code, 302) + status_url = r["Location"] + r = self.client.get(status_url) + q = PyQuery(r.content) + m = q('p.alert-warning').text() + + self.assertIn('The idnits check returned 1 error', m) + + class ApprovalsTestCase(TestCase): def test_approvals(self): make_test_data() diff --git a/ietf/submit/views.py b/ietf/submit/views.py index 3fe6552bb..ec09f56fc 100644 --- a/ietf/submit/views.py +++ b/ietf/submit/views.py @@ -464,6 +464,8 @@ def edit_submission(request, submission_id, access_token=None): replaces = replaces_form.cleaned_data.get("replaces", []) submission.replaces = ",".join(o.name for o in replaces) submission.authors = "\n".join(f.cleaned_line() for f in author_forms) + if hasattr(submission, '_cached_authors_parsed'): + del submission._cached_authors_parsed edit_form.save(commit=False) # transfer changes if submission.rev != prev_submission.rev: