From 2d817427fc34a5e2586baa39aea79407f1026f91 Mon Sep 17 00:00:00 2001
From: Henrik Levkowetz <henrik@levkowetz.com>
Date: Wed, 27 Sep 2017 14:18:12 +0000
Subject: [PATCH] Added a cancel button to the submission confirmation page. 
 Fixes issue #2379.  - Legacy-Id: 14170

---
 ietf/submit/tests.py                          | 32 +++++++++++---
 ietf/submit/views.py                          | 42 ++++++++++++-------
 ietf/templates/submit/confirm_submission.html |  8 +++-
 3 files changed, 60 insertions(+), 22 deletions(-)

diff --git a/ietf/submit/tests.py b/ietf/submit/tests.py
index d936bed06..b9c015544 100644
--- a/ietf/submit/tests.py
+++ b/ietf/submit/tests.py
@@ -141,9 +141,6 @@ class SubmitTests(TestCase):
             self.assertTrue(os.path.exists(os.path.join(self.staging_dir, u"%s-%s.%s" % (name, rev, format))))
         self.assertEqual(Submission.objects.filter(name=name).count(), 1)
         submission = Submission.objects.get(name=name)
-        if len(submission.authors) != 1:
-            debug.show('submission')
-            debug.pprint('submission.__dict__')
         self.assertEqual(len(submission.authors), 1)
         a = submission.authors[0]
         self.assertEqual(a["name"], author.ascii)
@@ -397,7 +394,7 @@ class SubmitTests(TestCase):
 
         # confirm
         mailbox_before = len(outbox)
-        r = self.client.post(confirm_url)
+        r = self.client.post(confirm_url, {'action':'confirm'})
         self.assertEqual(r.status_code, 302)
 
         # check we have document events 
@@ -526,7 +523,7 @@ class SubmitTests(TestCase):
 
         # confirm
         mailbox_before = len(outbox)
-        r = self.client.post(confirm_url)
+        r = self.client.post(confirm_url, {'action':'confirm'})
         self.assertEqual(r.status_code, 302)
 
         draft = Document.objects.get(docalias__name=name)
@@ -574,12 +571,35 @@ class SubmitTests(TestCase):
         confirm_url = self.extract_confirm_url(outbox[-1])
         self.assertFalse("chairs have been copied" in unicode(outbox[-1]))
         mailbox_before = len(outbox)
-        r = self.client.post(confirm_url)
+        r = self.client.post(confirm_url, {'action':'confirm'})
         self.assertEqual(r.status_code, 302)
+        self.assertEqual(len(outbox), mailbox_before+3)
         draft = Document.objects.get(docalias__name=name)
         self.assertEqual(draft.rev, rev)
         self.assertEqual(draft.relateddocument_set.filter(relationship_id='replaces').count(), replaces_count)
 
+    def test_submit_cancel_confirmation(self):
+        draft = make_test_data()
+        draft.group = None
+        draft.save_with_history([DocEvent.objects.create(doc=draft, rev=draft.rev, type="added_comment", by=Person.objects.get(user__username="secretary"), desc="Test")])
+        name = draft.name
+        old_rev = draft.rev
+        rev = '%02d'%(int(draft.rev)+1)
+        status_url, author = self.do_submission(name, rev)
+        mailbox_before = len(outbox)
+        r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces='')
+        self.assertEqual(r.status_code, 302)
+        status_url = r["Location"]
+        r = self.client.get(status_url)
+        self.assertEqual(len(outbox), mailbox_before + 1)
+        confirm_url = self.extract_confirm_url(outbox[-1])
+        mailbox_before = len(outbox)
+        r = self.client.post(confirm_url, {'action':'cancel'})
+        self.assertEqual(r.status_code, 302)
+        self.assertEqual(len(outbox), mailbox_before)
+        draft = Document.objects.get(docalias__name=name)
+        self.assertEqual(draft.rev, old_rev)
+
     def test_submit_new_wg_with_dash(self):
         make_test_data()
 
diff --git a/ietf/submit/views.py b/ietf/submit/views.py
index abc1e9629..c58a02b2a 100644
--- a/ietf/submit/views.py
+++ b/ietf/submit/views.py
@@ -33,7 +33,6 @@ from ietf.utils.accesstoken import generate_access_token
 from ietf.utils.log import log
 from ietf.utils.mail import send_mail_message
 
-
 def upload_submission(request):
     if request.method == 'POST':
         try:
@@ -438,20 +437,35 @@ def confirm_submission(request, submission_id, auth_token):
     if not key_matched: key_matched = auth_token == submission.auth_key # backwards-compat
 
     if request.method == 'POST' and submission.state_id in ("auth", "aut-appr") and key_matched:
-        submitter_parsed = submission.submitter_parsed()
-        if submitter_parsed["name"] and submitter_parsed["email"]:
-            # We know who approved it
-            desc = "New version approved"
-        elif submission.state_id == "auth":
-            desc = "New version approved by author"
+        action = request.POST.get('action')
+        if action == 'confirm':
+            submitter_parsed = submission.submitter_parsed()
+            if submitter_parsed["name"] and submitter_parsed["email"]:
+                # We know who approved it
+                desc = "New version approved"
+            elif submission.state_id == "auth":
+                desc = "New version approved by author"
+            else:
+                desc = "New version approved by previous author"
+
+            post_submission(request, submission, desc)
+
+            create_submission_event(request, submission, "Confirmed and posted submission")
+
+            return redirect("ietf.doc.views_doc.document_main", name=submission.name)
+
+        elif action == "cancel":
+            if  submission.state.next_states.filter(slug="cancel"):
+                cancel_submission(submission)
+                create_submission_event(request, submission, "Cancelled submission")
+                messages.success(request, 'The submission was cancelled.')
+            else:
+                messages.error(request, 'The submission is not in a state where it can be cancelled.')
+
+            return redirect("ietf.submit.views.submission_status", submission_id=submission_id)
+            
         else:
-            desc = "New version approved by previous author"
-
-        post_submission(request, submission, desc)
-
-        create_submission_event(request, submission, "Confirmed and posted submission")
-
-        return redirect("ietf.doc.views_doc.document_main", name=submission.name)
+            raise RuntimeError("Unexpected state in confirm_submission()")
 
     return render(request, 'submit/confirm_submission.html', {
         'submission': submission,
diff --git a/ietf/templates/submit/confirm_submission.html b/ietf/templates/submit/confirm_submission.html
index b1385092c..561e08a04 100644
--- a/ietf/templates/submit/confirm_submission.html
+++ b/ietf/templates/submit/confirm_submission.html
@@ -35,9 +35,13 @@
       <p>Please press the button below to finish posting of
         <b>{{ submission.name }}-{{ submission.rev }}</b>.</p>
 
-      <form class="confirm-submission" method="post">{% csrf_token %}
-        <button class="btn btn-primary" type="submit">Confirm submission & post draft</button>
+      
+      <form id="confirm-submission" method="post">
+	{% csrf_token %}
+        <button class="btn btn-primary" type="submit" name="action" value="confirm">Confirm submission & post draft</button>
+	<button class="btn btn-danger"  type="submit" name="action" value="cancel" >Cancel submission</button>
       </form>
+
     {% endif %}
 
   {% endif %}