From fb2aa92b586e37cfaff484fd7acd1593a2f292ff Mon Sep 17 00:00:00 2001
From: Todd Dembrey <todd.dembrey@torchbox.com>
Date: Tue, 7 May 2019 15:33:47 +0100
Subject: [PATCH] GH-1130: Redirect back to origin on batch determine

---
 .../apply/determinations/tests/test_views.py  | 44 +++++++++++++++++++
 opentech/apply/determinations/views.py        | 11 ++++-
 2 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/opentech/apply/determinations/tests/test_views.py b/opentech/apply/determinations/tests/test_views.py
index 0f7f418d9..f3e71f999 100644
--- a/opentech/apply/determinations/tests/test_views.py
+++ b/opentech/apply/determinations/tests/test_views.py
@@ -1,6 +1,15 @@
+import urllib
+
+from django.contrib.messages.storage.fallback import FallbackStorage
+from django.contrib.sessions.middleware import SessionMiddleware
+from django.test import RequestFactory
+from django.urls import reverse_lazy
+
 from opentech.apply.activity.models import Activity
 from opentech.apply.determinations.models import ACCEPTED, REJECTED
+from opentech.apply.determinations.views import BatchDeterminationCreateView
 from opentech.apply.users.tests.factories import StaffFactory, UserFactory
+from opentech.apply.funds.models import ApplicationSubmission
 from opentech.apply.funds.tests.factories import ApplicationSubmissionFactory
 from opentech.apply.utils.testing import BaseViewTestCase
 
@@ -123,6 +132,15 @@ class BatchDeterminationTestCase(BaseViewTestCase):
     url_name = 'funds:submissions:determinations:{}'
     base_view_name = 'batch'
 
+    def dummy_request(self, path):
+        request = RequestFactory().get(path)
+        middleware = SessionMiddleware()
+        middleware.process_request(request)
+        request.session.save()
+        request.user = StaffFactory()
+        request._messages = FallbackStorage(request)
+        return request
+
     def test_cant_access_without_submissions(self):
         url = self.url(None) + '?action=rejected'
         response = self.client.get(url, follow=True, secure=True)
@@ -157,6 +175,32 @@ class BatchDeterminationTestCase(BaseViewTestCase):
 
         self.assertRedirects(response, self.url_from_pattern('apply:submissions:list'))
 
+    def test_sets_next_on_redirect(self):
+        test_path = '/a/path/?with=query&a=sting'
+        request = RequestFactory().get('', PATH_INFO=test_path)
+        redirect = BatchDeterminationCreateView.should_redirect(
+            request,
+            ApplicationSubmission.objects.none(),
+            ['rejected'],
+        )
+        url = urllib.parse.urlparse(redirect.url)
+        query = urllib.parse.parse_qs(url.query)
+        next_path = urllib.parse.unquote_plus(query['next'][0])
+        self.assertEqual(next_path, test_path)
+
+    def test_success_redirects_if_exists(self):
+        test_path = '/a/path/?with=query&a=sting'
+        view = BatchDeterminationCreateView()
+        view.request = self.dummy_request('?next=' + urllib.parse.quote_plus(test_path))
+        redirect_url = view.get_success_url()
+        self.assertEqual(redirect_url, test_path)
+
+    def test_success_if_no_next(self):
+        view = BatchDeterminationCreateView()
+        view.request = self.dummy_request('')
+        redirect_url = view.get_success_url()
+        self.assertEqual(redirect_url, reverse_lazy('apply:submissions:list'))
+
     def test_message_created_if_determination_exists(self):
         submissions = ApplicationSubmissionFactory.create_batch(2)
 
diff --git a/opentech/apply/determinations/views.py b/opentech/apply/determinations/views.py
index ea1e37af5..0adae9a6f 100644
--- a/opentech/apply/determinations/views.py
+++ b/opentech/apply/determinations/views.py
@@ -1,3 +1,5 @@
+from urllib import parse
+
 from django.contrib import messages
 from django.contrib.auth.decorators import login_required
 from django.core.exceptions import PermissionDenied
@@ -61,6 +63,7 @@ class BatchDeterminationCreateView(CreateView):
         if not self.get_action() or not self.get_submissions():
             messages.warning(self.request, 'Improperly configured request, please try again.')
             return HttpResponseRedirect(self.get_success_url())
+
         return super().dispatch(*args, **kwargs)
 
     def get_action(self):
@@ -162,13 +165,17 @@ class BatchDeterminationCreateView(CreateView):
             return HttpResponseRedirect(
                 reverse_lazy('apply:submissions:determinations:batch') +
                 "?action=" + action +
-                "&submissions=" + ','.join([str(submission.id) for submission in submissions])
+                "&submissions=" + ','.join([str(submission.id) for submission in submissions]) +
+                "&next=" + parse.quote_plus(request.get_full_path()),
             )
         elif set(actions) != non_determine_states:
             raise ValueError('Inconsistent states provided - please talk to an admin')
 
     def get_success_url(self):
-        return reverse_lazy('apply:submissions:list')
+        try:
+            return self.request.GET['next']
+        except KeyError:
+            return reverse_lazy('apply:submissions:list')
 
 
 @method_decorator(staff_required, name='dispatch')
-- 
GitLab