From 4be7db0e45deb4abf82f8bb1fee0bb47fd3e10cb Mon Sep 17 00:00:00 2001
From: Todd Dembrey <todd.dembrey@torchbox.com>
Date: Thu, 21 Jun 2018 18:54:41 +0100
Subject: [PATCH] Correctly display the draft revision on the users detail view

---
 .../migrations/0034_create_revisions_model.py |  4 +-
 opentech/apply/funds/models.py                |  4 +-
 .../apply/funds/tests/factories/models.py     | 48 +++++++++++++++----
 opentech/apply/funds/tests/test_views.py      | 13 ++++-
 opentech/apply/funds/views.py                 |  5 ++
 5 files changed, 60 insertions(+), 14 deletions(-)

diff --git a/opentech/apply/funds/migrations/0034_create_revisions_model.py b/opentech/apply/funds/migrations/0034_create_revisions_model.py
index ef2825718..e75812d77 100644
--- a/opentech/apply/funds/migrations/0034_create_revisions_model.py
+++ b/opentech/apply/funds/migrations/0034_create_revisions_model.py
@@ -24,11 +24,11 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='applicationsubmission',
             name='draft_revision',
-            field=models.OneToOneField(editable=False, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='draft', to='funds.ApplicationRevision'),
+            field=models.OneToOneField(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='draft', to='funds.ApplicationRevision'),
         ),
         migrations.AddField(
             model_name='applicationsubmission',
             name='live_revision',
-            field=models.OneToOneField(editable=False, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='live', to='funds.ApplicationRevision'),
+            field=models.OneToOneField(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='live', to='funds.ApplicationRevision'),
         ),
     ]
diff --git a/opentech/apply/funds/models.py b/opentech/apply/funds/models.py
index 271547a3a..77b005925 100644
--- a/opentech/apply/funds/models.py
+++ b/opentech/apply/funds/models.py
@@ -624,14 +624,14 @@ class ApplicationSubmission(WorkflowHelpers, BaseStreamForm, AbstractFormSubmiss
 
     live_revision = models.OneToOneField(
         'ApplicationRevision',
-        on_delete=models.PROTECT,
+        on_delete=models.CASCADE,
         related_name='live',
         null=True,
         editable=False,
     )
     draft_revision = models.OneToOneField(
         'ApplicationRevision',
-        on_delete=models.PROTECT,
+        on_delete=models.CASCADE,
         related_name='draft',
         null=True,
         editable=False,
diff --git a/opentech/apply/funds/tests/factories/models.py b/opentech/apply/funds/tests/factories/models.py
index dd93ca97e..5b4bf8599 100644
--- a/opentech/apply/funds/tests/factories/models.py
+++ b/opentech/apply/funds/tests/factories/models.py
@@ -1,13 +1,15 @@
 from collections import defaultdict
 import datetime
+import json
 
 import factory
 import wagtail_factories
 
 from opentech.apply.funds.models import (
     AbstractRelatedForm,
-    ApplicationSubmission,
     ApplicationForm,
+    ApplicationSubmission,
+    ApplicationRevision,
     FundType,
     FundForm,
     LabForm,
@@ -24,6 +26,7 @@ __all__ = [
     'FundTypeFactory',
     'FundFormFactory',
     'ApplicationFormFactory',
+    'ApplicationRevisionFactory',
     'ApplicationSubmissionFactory',
     'RoundFactory',
     'RoundFormFactory',
@@ -99,8 +102,8 @@ class RoundFactory(wagtail_factories.PageFactory):
         model = Round
 
     title = factory.Sequence('Round {}'.format)
-    start_date = factory.LazyFunction(datetime.date.today)
-    end_date = factory.LazyFunction(lambda: datetime.date.today() + datetime.timedelta(days=7))
+    start_date = factory.Sequence(lambda n: datetime.date.today() + datetime.timedelta(days=n-1))
+    end_date = factory.Sequence(lambda n: datetime.date.today() + datetime.timedelta(days=n))
     lead = factory.SubFactory(StaffFactory)
 
     @factory.post_generation
@@ -168,18 +171,43 @@ class Metaclass(factory.base.FactoryMetaClass):
 
 
 class FormDataFactory(factory.Factory, metaclass=Metaclass):
-    def _create(self, *args, form_fields='{}', **kwargs):
-        form_fields = {
-            f.block_type: f.id
-            for f in ApplicationSubmission.form_fields.field.to_python(form_fields)
-        }
+    def _create(self, *args, form_fields={}, clean=False, **kwargs):
+        if form_fields and isinstance(form_fields, str):
+            form_fields = json.loads(form_fields)
+            form_definition = {
+                field['type']: field['id']
+                for field in form_fields
+            }
+        else:
+            form_definition =  {
+                f.block_type: f.id
+                for f in form_fields or ApplicationSubmission.form_fields.field.to_python(form_fields)
+            }
+
         form_data = {}
         for name, answer in kwargs.items():
-            form_data[form_fields[name]] = answer
+            form_data[form_definition[name]] = answer
+
+        if clean:
+            application = ApplicationSubmissionFactory()
+            application.form_fields = form_fields
+            application.form_data = form_data
+            application.save()
+            form_data = application.form_data.copy()
+            application.delete()
+            return application.form_data
 
         return form_data
 
 
+class ApplicationRevisionFactory(factory.DjangoModelFactory):
+    class Meta:
+        model = ApplicationRevision
+
+    submission = factory.SubFactory('opentech.apply.funds.tests.factories.ApplicationSubmissionFactory')
+    form_data = factory.SubFactory(FormDataFactory, form_fields=factory.SelfAttribute('..submission.form_fields'), clean=True)
+
+
 class ApplicationSubmissionFactory(factory.DjangoModelFactory):
     class Meta:
         model = ApplicationSubmission
@@ -198,6 +226,8 @@ class ApplicationSubmissionFactory(factory.DjangoModelFactory):
     round = factory.SubFactory(RoundFactory, workflow_name=factory.SelfAttribute('..workflow_name'), lead=factory.SelfAttribute('..lead'))
     user = factory.SubFactory(UserFactory)
     lead = factory.SubFactory(StaffFactory)
+    live_revision = None
+    draft_revision = None
 
     @classmethod
     def _generate(cls, strat, params):
diff --git a/opentech/apply/funds/tests/test_views.py b/opentech/apply/funds/tests/test_views.py
index cc3a95be3..fe985c434 100644
--- a/opentech/apply/funds/tests/test_views.py
+++ b/opentech/apply/funds/tests/test_views.py
@@ -1,4 +1,4 @@
-from opentech.apply.funds.tests.factories import ApplicationSubmissionFactory
+from opentech.apply.funds.tests.factories import ApplicationSubmissionFactory, ApplicationRevisionFactory
 from opentech.apply.users.tests.factories import UserFactory, StaffFactory
 from opentech.apply.utils.tests import BaseViewTestCase
 
@@ -54,6 +54,17 @@ class TestApplicantSubmissionView(BaseSubmissionViewTestCase):
         response = self.get_page(submission)
         self.assertContains(response, submission.title)
 
+    def test_sees_latest_draft_if_it_exists(self):
+        submission = ApplicationSubmissionFactory(user=self.user)
+        draft_revision = ApplicationRevisionFactory(submission=submission)
+        submission.draft_revision = draft_revision
+        submission.save()
+
+        draft_submission = submission.from_draft()
+        response = self.get_page(submission)
+
+        self.assertContains(response, draft_submission.title)
+
     def test_cant_view_others_submission(self):
         submission = ApplicationSubmissionFactory()
         response = self.get_page(submission)
diff --git a/opentech/apply/funds/views.py b/opentech/apply/funds/views.py
index 074049c9d..088725775 100644
--- a/opentech/apply/funds/views.py
+++ b/opentech/apply/funds/views.py
@@ -167,6 +167,11 @@ class ApplicantSubmissionDetailView(ActivityContextMixin, DelegateableView):
     model = ApplicationSubmission
     form_views = [CommentFormView]
 
+    def get_object(self):
+        object = super().get_object()
+        object = object.from_draft()
+        return object
+
     def dispatch(self, request, *args, **kwargs):
         if self.get_object().user != request.user:
             raise PermissionDenied
-- 
GitLab