From 78889979a14733dfbb071f100608746787372c39 Mon Sep 17 00:00:00 2001 From: Henrik Levkowetz Date: Mon, 23 Sep 2019 17:26:16 +0000 Subject: [PATCH] Changed the draft submission form and views so that an email address is required for each author in order to complete self-service draft submission. It is possible to add these as metadata updates, but this will lead to submission through the secretariat (and the email addresses will still be required). Also updated related templates to make the handling of form section headings more consistent. - Legacy-Id: 16745 --- PLAN | 5 -- ietf/submit/forms.py | 1 - ietf/submit/tests.py | 62 ++++++++++++++++---- ietf/submit/utils.py | 24 ++++++++ ietf/templates/submit/edit_submission.html | 1 - ietf/templates/submit/replaces_form.html | 1 + ietf/templates/submit/submission_status.html | 9 ++- ietf/templates/submit/submitter_form.html | 1 + 8 files changed, 84 insertions(+), 20 deletions(-) diff --git a/PLAN b/PLAN index d3fdd4944..241023449 100644 --- a/PLAN +++ b/PLAN @@ -7,11 +7,6 @@ Updated: $Date$ Planned work in rough order =========================== -* Change the draft submission form so that an email address is required for - each author in order to complete self-service draft submission. Missing - email address(es) will lead to failure, and require submission via the - secretariat (where email addresses for all will also be required). - * Simplify submission if submitter is logged into the datatracker, skipping the email verification step. diff --git a/ietf/submit/forms.py b/ietf/submit/forms.py index b7829958f..8c16bd3d8 100644 --- a/ietf/submit/forms.py +++ b/ietf/submit/forms.py @@ -403,7 +403,6 @@ class AuthorForm(NameEmailForm): def __init__(self, *args, **kwargs): super(AuthorForm, self).__init__(*args, **kwargs) - self.fields["email"].required = False class SubmitterForm(NameEmailForm): #Fields for secretariat only diff --git a/ietf/submit/tests.py b/ietf/submit/tests.py index 4a7e55eff..861777cf3 100644 --- a/ietf/submit/tests.py +++ b/ietf/submit/tests.py @@ -53,7 +53,7 @@ def submission_file(name, rev, group, format, templatename, author=None, email=N if author is None: author = PersonFactory() if email is None: - email = author.email().address.lower() + email = author.email().address.lower() if author.email() else None if title is None: title = "Test Document" if year is None: @@ -754,7 +754,7 @@ class SubmitTests(TestCase): "authors-1-name": "Person 2", "authors-1-email": "person2@example.com", "authors-2-name": "Person 3", - "authors-2-email": "", + "authors-2-email": "person3@example.com", "authors-prefix": ["authors-", "authors-0", "authors-1", "authors-2"], }) self.assertNoFormPostErrors(r, ".has-error,.alert-danger") @@ -776,7 +776,7 @@ class SubmitTests(TestCase): 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"], "") + self.assertEqual(authors[2]["email"], "person3@example.com") self.assertEqual(len(outbox), mailbox_before + 1) self.assertTrue("Manual Post Requested" in outbox[-1]["Subject"]) @@ -1038,20 +1038,62 @@ class SubmitTests(TestCase): self.assertIn('The idnits check returned 1 warning', m) + def test_submit_missing_author_email(self): + name = "draft-authorname-testing-noemail" + rev = "00" + group = None + + author = PersonFactory() + for e in author.email_set.all(): + e.delete() + + files = {"txt": submission_file(name, rev, group, "txt", "test_submission.txt", author=author, ascii=False)[0] } + + # submit + url = urlreverse('ietf.submit.views.upload_submission') + 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.text-danger').text() + + self.assertIn('Author email error', m) + self.assertIn('Found no email address.', m) + + def test_submit_bad_author_email(self): + name = "draft-authorname-testing-bademail" + rev = "00" + group = None + + author = PersonFactory() + email = author.email_set.first() + email.address = '@bad.email' + email.save() + + files = {"xml": submission_file(name, rev, group, "xml", "test_submission.xml", author=author, ascii=False)[0] } + + # submit + url = urlreverse('ietf.submit.views.upload_submission') + 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.text-danger').text() + + self.assertIn('Author email error', m) + self.assertIn('Invalid email address.', m) + def test_submit_invalid_yang(self): name = "draft-yang-testing-invalid" 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 - files = {"txt": submission_file(name, rev, group, "txt", "test_submission_invalid_yang.txt") } + files = {"txt": submission_file(name, rev, group, "txt", "test_submission_invalid_yang.txt")[0] } + url = urlreverse('ietf.submit.views.upload_submission') r = self.client.post(url, files) self.assertEqual(r.status_code, 302) status_url = r["Location"] diff --git a/ietf/submit/utils.py b/ietf/submit/utils.py index 1b92bff09..ed7f4c2bd 100644 --- a/ietf/submit/utils.py +++ b/ietf/submit/utils.py @@ -72,6 +72,30 @@ def validate_submission(submission): if error: errors['document_date'] = error + # author email addresses + author_error_count = 0 + seen = set() + for author in submission.authors: + email = author['email'] + author['errors'] = [] + if not email: + author['errors'].append("Found no email address. A valid email address is required.") + author_error_count += 1 + else: + try: + validate_email(email) + except ValidationError: + author['errors'].append("Invalid email address. A valid email address is required.") + author_error_count += 1 + if email in seen: + author['errors'].append("Duplicate email address. A unique email address is required.") + author_error_count += 1 + else: + seen.add(email) + + if author_error_count: + errors['authors'] = "Author email error (see below)" if author_error_count == 1 else "Author email errors (see below)" + return errors def has_been_replaced_by(name): diff --git a/ietf/templates/submit/edit_submission.html b/ietf/templates/submit/edit_submission.html index 0ff71abfd..11bc46ea7 100644 --- a/ietf/templates/submit/edit_submission.html +++ b/ietf/templates/submit/edit_submission.html @@ -70,7 +70,6 @@ {% bootstrap_form edit_form %} -

Submitter

{% include "submit/submitter_form.html" %} {% include "submit/replaces_form.html" %} diff --git a/ietf/templates/submit/replaces_form.html b/ietf/templates/submit/replaces_form.html index 0f5eae31f..311aec768 100644 --- a/ietf/templates/submit/replaces_form.html +++ b/ietf/templates/submit/replaces_form.html @@ -1,4 +1,5 @@ {% for field in replaces_form %} +

Replacement information

{{ field.label_tag }} diff --git a/ietf/templates/submit/submission_status.html b/ietf/templates/submit/submission_status.html index 981de304c..bcd8eb9c1 100644 --- a/ietf/templates/submit/submission_status.html +++ b/ietf/templates/submit/submission_status.html @@ -235,7 +235,9 @@
Unrecognized country: "{{ author.country }}": See recognized country names. {% endif %} - + {% for auth_err in author.errors %} +

{{ auth_err }}

+ {% endfor %} {% endfor %} @@ -279,7 +281,7 @@

Leads to manual post by the secretariat.

- {% if passes_checks and not errors %} + {% if passes_checks and not errors and not submission.errors %}

Please edit the following meta-data before posting:

@@ -287,6 +289,7 @@ {% include "submit/submitter_form.html" %} {% include "submit/replaces_form.html" %} +

Post submission

@@ -320,7 +323,7 @@ {% endif %} {% if can_cancel %} -

Cancel submission

+

Cancel submission

{% csrf_token %} diff --git a/ietf/templates/submit/submitter_form.html b/ietf/templates/submit/submitter_form.html index 1564dd3e5..3a341c7c4 100644 --- a/ietf/templates/submit/submitter_form.html +++ b/ietf/templates/submit/submitter_form.html @@ -1,6 +1,7 @@ {# Copyright The IETF Trust 2015, All Rights Reserved #}{% load origin %}{% origin %} {% load bootstrap3 %} +

Submitter

If you are one of the authors, please click the button below with your name on it to automatically fill in the