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
This commit is contained in:
Henrik Levkowetz 2019-09-23 17:26:16 +00:00
parent 1efd28752c
commit 78889979a1
8 changed files with 84 additions and 20 deletions

5
PLAN
View file

@ -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.

View file

@ -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

View file

@ -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"]

View file

@ -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):

View file

@ -70,7 +70,6 @@
{% bootstrap_form edit_form %}
<h3>Submitter</h3>
{% include "submit/submitter_form.html" %}
{% include "submit/replaces_form.html" %}

View file

@ -1,4 +1,5 @@
{% for field in replaces_form %}
<h3>Replacement information</h3>
<tr{% if field.errors %} class="error"{% endif %}>
<th>{{ field.label_tag }}</th>
<td>

View file

@ -235,7 +235,9 @@
<br>
<b class="text-warning">Unrecognized country: "{{ author.country }}"</b>: See <a href="{% url "ietf.stats.views.known_countries_list" %}">recognized country names</a>.
{% endif %}
{% for auth_err in author.errors %}
<p class="text-danger bg-danger"><b>{{ auth_err }}</b></p>
{% endfor %}
</td>
</tr>
{% endfor %}
@ -279,7 +281,7 @@
</form>
<p>Leads to manual post by the secretariat.</p>
{% if passes_checks and not errors %}
{% if passes_checks and not errors and not submission.errors %}
<h2>Please edit the following meta-data before posting:</h2>
<form class="idsubmit" method="post">
@ -287,6 +289,7 @@
{% include "submit/submitter_form.html" %}
{% include "submit/replaces_form.html" %}
<input type="hidden" name="action" value="autopost">
<h3>Post submission</h3>
<button class="btn btn-primary" type="submit">Post submission</button>
</form>
@ -320,7 +323,7 @@
{% endif %}
{% if can_cancel %}
<h2>Cancel submission</h2>
<h3>Cancel submission</h3>
<form id="cancel-submission" method="post">
{% csrf_token %}
<input type="hidden" name="action" value="cancel">

View file

@ -1,6 +1,7 @@
{# Copyright The IETF Trust 2015, All Rights Reserved #}{% load origin %}{% origin %}
{% load bootstrap3 %}
<h3>Submitter</h3>
<p>
If you are one of the authors, please click the button below
with your name on it to automatically fill in the