From 833916ba9210c246299d59e66e2d5b6cc913f164 Mon Sep 17 00:00:00 2001
From: Todd Dembrey <todd.dembrey@torchbox.com>
Date: Fri, 31 Aug 2018 16:37:01 +0100
Subject: [PATCH] Refactor to make sure we can save the files in the submission
 folder

---
 opentech/apply/funds/models/submissions.py | 22 +++++++++++++++++-----
 opentech/apply/funds/tests/test_models.py  | 14 ++++++++++++--
 2 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/opentech/apply/funds/models/submissions.py b/opentech/apply/funds/models/submissions.py
index 96772bc12..707d8409f 100644
--- a/opentech/apply/funds/models/submissions.py
+++ b/opentech/apply/funds/models/submissions.py
@@ -474,7 +474,7 @@ class ApplicationSubmission(
     def clean_submission(self):
         self.process_form_data()
         self.ensure_user_has_account()
-        self.process_file_data()
+        self.process_file_data(self.form_data)
 
     def process_form_data(self):
         for field_name, field_id in self.must_include.items():
@@ -482,31 +482,43 @@ class ApplicationSubmission(
             if response:
                 self.form_data[field_name] = response
 
-    def process_file_data(self):
+    def extract_files(self):
+        files = {}
         for field in self.form_fields:
             if isinstance(field.block, UploadableMediaBlock):
-                file = self.form_data.get(field.id, {})
+                files[field.id] = self.form_data.pop(field.id, {})
+        return files
+
+    def process_file_data(self, data):
+        for field in self.form_fields:
+            if isinstance(field.block, UploadableMediaBlock):
+                file = data.get(field.id, {})
                 self.form_data[field.id] = handle_files(file, os.path.join('submission', str(self.id), field.id))
 
     def save(self, *args, **kwargs):
         if self.is_draft:
             raise ValueError('Cannot save with draft data')
 
-        self.clean_submission()
-
         creating = not self.id
+
         if creating:
             # We are creating the object default to first stage
             self.workflow_name = self.get_from_parent('workflow_name')
             # Copy extra relevant information to the child
             self.lead = self.get_from_parent('lead')
 
+            # We need the submission id to correctly save the files
+            files = self.extract_files()
+
+        self.clean_submission()
+
         # add a denormed version of the answer for searching
         self.search_data = ' '.join(self.prepare_search_values())
 
         super().save(*args, **kwargs)
 
         if creating:
+            self.process_file_data(files)
             self.reviewers.set(self.get_from_parent('reviewers').all())
             first_revision = ApplicationRevision.objects.create(
                 submission=self,
diff --git a/opentech/apply/funds/tests/test_models.py b/opentech/apply/funds/tests/test_models.py
index 28842606b..2992c93d4 100644
--- a/opentech/apply/funds/tests/test_models.py
+++ b/opentech/apply/funds/tests/test_models.py
@@ -10,6 +10,7 @@ from django.core.exceptions import ValidationError
 from django.test import TestCase, override_settings
 
 from opentech.apply.funds.models import ApplicationSubmission
+from opentech.apply.funds.models.submissions import save_path
 from opentech.apply.funds.blocks import EmailBlock, FullNameBlock
 from opentech.apply.funds.workflow import Request
 from opentech.apply.utils.testing import make_request
@@ -371,8 +372,17 @@ class TestApplicationSubmission(TestCase):
     def test_file_gets_uploaded(self):
         filename = 'file_name.png'
         submission = self.make_submission(form_data__image__filename=filename)
-        save_path = os.path.join(settings.MEDIA_ROOT, submission.save_path(filename))
-        self.assertTrue(os.path.isfile(save_path))
+        path = os.path.join(settings.MEDIA_ROOT, 'submission', str(submission.id))
+
+        # Check we created the top level folder
+        self.assertTrue(os.path.isdir(path))
+
+        found_files = []
+        for _, _, files in os.walk(path):
+            found_files.extend(files)
+
+        # Check we saved the file somewhere beneath it
+        self.assertIn(filename, found_files)
 
     def test_create_revision_on_create(self):
         submission = ApplicationSubmissionFactory()
-- 
GitLab