Skip to content

Commit 7888997

Browse files
committed
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
1 parent 1efd287 commit 7888997

8 files changed

Lines changed: 83 additions & 19 deletions

File tree

PLAN

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@ Updated: $Date$
77
Planned work in rough order
88
===========================
99

10-
* Change the draft submission form so that an email address is required for
11-
each author in order to complete self-service draft submission. Missing
12-
email address(es) will lead to failure, and require submission via the
13-
secretariat (where email addresses for all will also be required).
14-
1510
* Simplify submission if submitter is logged into the datatracker, skipping the
1611
email verification step.
1712

ietf/submit/forms.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,6 @@ class AuthorForm(NameEmailForm):
403403

404404
def __init__(self, *args, **kwargs):
405405
super(AuthorForm, self).__init__(*args, **kwargs)
406-
self.fields["email"].required = False
407406

408407
class SubmitterForm(NameEmailForm):
409408
#Fields for secretariat only

ietf/submit/tests.py

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def submission_file(name, rev, group, format, templatename, author=None, email=N
5353
if author is None:
5454
author = PersonFactory()
5555
if email is None:
56-
email = author.email().address.lower()
56+
email = author.email().address.lower() if author.email() else None
5757
if title is None:
5858
title = "Test Document"
5959
if year is None:
@@ -754,7 +754,7 @@ def test_edit_submission_and_force_post(self):
754754
"authors-1-name": "Person 2",
755755
"authors-1-email": "person2@example.com",
756756
"authors-2-name": "Person 3",
757-
"authors-2-email": "",
757+
"authors-2-email": "person3@example.com",
758758
"authors-prefix": ["authors-", "authors-0", "authors-1", "authors-2"],
759759
})
760760
self.assertNoFormPostErrors(r, ".has-error,.alert-danger")
@@ -776,7 +776,7 @@ def test_edit_submission_and_force_post(self):
776776
self.assertEqual(authors[1]["name"], "Person 2")
777777
self.assertEqual(authors[1]["email"], "person2@example.com")
778778
self.assertEqual(authors[2]["name"], "Person 3")
779-
self.assertEqual(authors[2]["email"], "")
779+
self.assertEqual(authors[2]["email"], "person3@example.com")
780780

781781
self.assertEqual(len(outbox), mailbox_before + 1)
782782
self.assertTrue("Manual Post Requested" in outbox[-1]["Subject"])
@@ -1038,20 +1038,62 @@ def test_submit_nonascii_name(self):
10381038

10391039
self.assertIn('The idnits check returned 1 warning', m)
10401040

1041-
def test_submit_invalid_yang(self):
1042-
name = "draft-yang-testing-invalid"
1041+
def test_submit_missing_author_email(self):
1042+
name = "draft-authorname-testing-noemail"
10431043
rev = "00"
10441044
group = None
10451045

1046-
# get
1046+
author = PersonFactory()
1047+
for e in author.email_set.all():
1048+
e.delete()
1049+
1050+
files = {"txt": submission_file(name, rev, group, "txt", "test_submission.txt", author=author, ascii=False)[0] }
1051+
1052+
# submit
10471053
url = urlreverse('ietf.submit.views.upload_submission')
1048-
r = self.client.get(url)
1049-
self.assertEqual(r.status_code, 200)
1054+
r = self.client.post(url, files)
1055+
self.assertEqual(r.status_code, 302)
1056+
status_url = r["Location"]
1057+
r = self.client.get(status_url)
10501058
q = PyQuery(r.content)
1059+
m = q('p.text-danger').text()
1060+
1061+
self.assertIn('Author email error', m)
1062+
self.assertIn('Found no email address.', m)
1063+
1064+
def test_submit_bad_author_email(self):
1065+
name = "draft-authorname-testing-bademail"
1066+
rev = "00"
1067+
group = None
1068+
1069+
author = PersonFactory()
1070+
email = author.email_set.first()
1071+
email.address = '@bad.email'
1072+
email.save()
1073+
1074+
files = {"xml": submission_file(name, rev, group, "xml", "test_submission.xml", author=author, ascii=False)[0] }
10511075

10521076
# submit
1053-
files = {"txt": submission_file(name, rev, group, "txt", "test_submission_invalid_yang.txt") }
1077+
url = urlreverse('ietf.submit.views.upload_submission')
1078+
r = self.client.post(url, files)
1079+
self.assertEqual(r.status_code, 302)
1080+
status_url = r["Location"]
1081+
r = self.client.get(status_url)
1082+
q = PyQuery(r.content)
1083+
m = q('p.text-danger').text()
1084+
1085+
self.assertIn('Author email error', m)
1086+
self.assertIn('Invalid email address.', m)
10541087

1088+
def test_submit_invalid_yang(self):
1089+
name = "draft-yang-testing-invalid"
1090+
rev = "00"
1091+
group = None
1092+
1093+
# submit
1094+
files = {"txt": submission_file(name, rev, group, "txt", "test_submission_invalid_yang.txt")[0] }
1095+
1096+
url = urlreverse('ietf.submit.views.upload_submission')
10551097
r = self.client.post(url, files)
10561098
self.assertEqual(r.status_code, 302)
10571099
status_url = r["Location"]

ietf/submit/utils.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,30 @@ def validate_submission(submission):
7272
if error:
7373
errors['document_date'] = error
7474

75+
# author email addresses
76+
author_error_count = 0
77+
seen = set()
78+
for author in submission.authors:
79+
email = author['email']
80+
author['errors'] = []
81+
if not email:
82+
author['errors'].append("Found no email address. A valid email address is required.")
83+
author_error_count += 1
84+
else:
85+
try:
86+
validate_email(email)
87+
except ValidationError:
88+
author['errors'].append("Invalid email address. A valid email address is required.")
89+
author_error_count += 1
90+
if email in seen:
91+
author['errors'].append("Duplicate email address. A unique email address is required.")
92+
author_error_count += 1
93+
else:
94+
seen.add(email)
95+
96+
if author_error_count:
97+
errors['authors'] = "Author email error (see below)" if author_error_count == 1 else "Author email errors (see below)"
98+
7599
return errors
76100

77101
def has_been_replaced_by(name):

ietf/templates/submit/edit_submission.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ <h3>Adjust meta-data</h3>
7070

7171
{% bootstrap_form edit_form %}
7272

73-
<h3>Submitter</h3>
7473
{% include "submit/submitter_form.html" %}
7574
{% include "submit/replaces_form.html" %}
7675

ietf/templates/submit/replaces_form.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{% for field in replaces_form %}
2+
<h3>Replacement information</h3>
23
<tr{% if field.errors %} class="error"{% endif %}>
34
<th>{{ field.label_tag }}</th>
45
<td>

ietf/templates/submit/submission_status.html

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,9 @@ <h2>Meta-data from the submission</h2>
235235
<br>
236236
<b class="text-warning">Unrecognized country: "{{ author.country }}"</b>: See <a href="{% url "ietf.stats.views.known_countries_list" %}">recognized country names</a>.
237237
{% endif %}
238-
238+
{% for auth_err in author.errors %}
239+
<p class="text-danger bg-danger"><b>{{ auth_err }}</b></p>
240+
{% endfor %}
239241
</td>
240242
</tr>
241243
{% endfor %}
@@ -279,14 +281,15 @@ <h2>Meta-data from the submission</h2>
279281
</form>
280282
<p>Leads to manual post by the secretariat.</p>
281283

282-
{% if passes_checks and not errors %}
284+
{% if passes_checks and not errors and not submission.errors %}
283285
<h2>Please edit the following meta-data before posting:</h2>
284286

285287
<form class="idsubmit" method="post">
286288
{% csrf_token %}
287289
{% include "submit/submitter_form.html" %}
288290
{% include "submit/replaces_form.html" %}
289291
<input type="hidden" name="action" value="autopost">
292+
<h3>Post submission</h3>
290293
<button class="btn btn-primary" type="submit">Post submission</button>
291294
</form>
292295

@@ -320,7 +323,7 @@ <h3>Replaced documents</h3>
320323
{% endif %}
321324

322325
{% if can_cancel %}
323-
<h2>Cancel submission</h2>
326+
<h3>Cancel submission</h3>
324327
<form id="cancel-submission" method="post">
325328
{% csrf_token %}
326329
<input type="hidden" name="action" value="cancel">

ietf/templates/submit/submitter_form.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{# Copyright The IETF Trust 2015, All Rights Reserved #}{% load origin %}{% origin %}
22
{% load bootstrap3 %}
33

4+
<h3>Submitter</h3>
45
<p>
56
If you are one of the authors, please click the button below
67
with your name on it to automatically fill in the

0 commit comments

Comments
 (0)