From 54daa10d2354e7f5519b608bef04a3eca95f221a Mon Sep 17 00:00:00 2001
From: Todd Dembrey <todd.dembrey@torchbox.com>
Date: Tue, 25 Sep 2018 15:48:23 +0100
Subject: [PATCH] Add tests for the enhanced field behaviour

---
 opentech/apply/stream_forms/fields.py |  2 +-
 opentech/apply/stream_forms/files.py  |  6 +-
 opentech/apply/stream_forms/tests.py  | 89 ++++++++++++++++++++++++++-
 3 files changed, 93 insertions(+), 4 deletions(-)

diff --git a/opentech/apply/stream_forms/fields.py b/opentech/apply/stream_forms/fields.py
index a6c46c969..6f542f221 100644
--- a/opentech/apply/stream_forms/fields.py
+++ b/opentech/apply/stream_forms/fields.py
@@ -22,7 +22,7 @@ class MultiFileInput(ClearableFileInput):
             is_initial(file) for file in value
         )
 
-    def render(self, name, value, attrs=None):
+    def render(self, name, value, attrs=dict()):
         if self.multiple:
             attrs['multiple'] = 'multiple'
 
diff --git a/opentech/apply/stream_forms/files.py b/opentech/apply/stream_forms/files.py
index 5ec7c84f2..1d5b8ce5d 100644
--- a/opentech/apply/stream_forms/files.py
+++ b/opentech/apply/stream_forms/files.py
@@ -26,7 +26,11 @@ class StreamFieldFile(File):
         return self.filename
 
     def __eq__(self, other):
-        return self.filename == other.filename and self.size == other.size
+        if isinstance(other, File):
+            return self.filename == other.filename and self.size == other.size
+        # Rely on the other object to know how to check equality
+        # Could cause infinite loop if the other object is unsure how to compare
+        return other.__eq__(self)
 
     def _get_file(self):
         if getattr(self, '_file', None) is None:
diff --git a/opentech/apply/stream_forms/tests.py b/opentech/apply/stream_forms/tests.py
index a79ca8be5..a80eb218a 100644
--- a/opentech/apply/stream_forms/tests.py
+++ b/opentech/apply/stream_forms/tests.py
@@ -1,3 +1,88 @@
-# from django.test import TestCase
+from django.core.files.uploadedfile import SimpleUploadedFile
+from django.test import TestCase
 
-# Create your tests here.
+from faker import Faker
+
+from .files import StreamFieldFile
+from .fields import MultiFileField, MultiFileInput
+
+fake = Faker()
+
+def make_files(number):
+    file_names = [f'{fake.word()}_{i}' for i in range(3)]
+    files = [
+        StreamFieldFile(SimpleUploadedFile(name, b'Some File Content'), filename=name)
+        for name in file_names
+    ]
+    return files
+
+
+class TestMultiFileInput(TestCase):
+    widget = MultiFileInput()
+
+    def test_renders_multiple_attr(self):
+        html = self.widget.render('', [])
+        self.assertIn('multiple', html)
+
+    def test_renders_multiple_files(self):
+        files = make_files(3)
+        html = self.widget.render('', files)
+        for file in files:
+            self.assertIn(file.filename, html)
+
+    def test_handles_files(self):
+        field_name = 'testing'
+        files = make_files(3)
+        files_data = {field_name: files}
+        data = self.widget.value_from_datadict({}, files_data, field_name)
+        self.assertEqual(data['files'], files)
+
+    def test_no_delete(self):
+        data = self.widget.value_from_datadict({}, {}, '')
+        self.assertFalse(data['cleared'])
+
+    def test_delete(self):
+        field_name = 'testing'
+        field_id = self.widget.clear_checkbox_name(field_name) + '-'
+        form_data = {
+            field_id + '0': 'on',
+            field_id + '4': 'on',
+        }
+        data = self.widget.value_from_datadict(form_data, {}, field_name)
+        self.assertEqual(data['cleared'], {0, 4})
+
+
+class TestMultiFileField(TestCase):
+    field = MultiFileField()
+
+    def multi_file_value(self, files=list(), cleared=set()):
+        return {
+            'files': files,
+            'cleared': cleared,
+        }
+
+    def test_returns_files_if_no_change(self):
+        files = make_files(3)
+        cleaned = self.field.clean(self.multi_file_value(), files)
+        self.assertEqual(files, cleaned)
+
+    def test_returns_new_files(self):
+        files = make_files(3)
+        cleaned = self.field.clean(self.multi_file_value(files=files), None)
+        self.assertEqual(files, cleaned)
+
+    def test_returns_inital_and_files(self):
+        initial_files = make_files(3)
+        new_files = make_files(3)
+        cleaned = self.field.clean(self.multi_file_value(files=new_files), initial_files)
+        self.assertEqual(initial_files + new_files, cleaned)
+
+    def test_returns_nothing_all_cleared(self):
+        initial_files = make_files(3)
+        cleaned = self.field.clean(self.multi_file_value(cleared=range(3)), initial_files)
+        self.assertEqual([], cleaned)
+
+    def test_returns_something_some_cleared(self):
+        initial_files = make_files(3)
+        cleaned = self.field.clean(self.multi_file_value(cleared=[0, 2]), initial_files)
+        self.assertEqual([initial_files[1]], cleaned)
-- 
GitLab