Forráskód Böngészése

added tests for getting files and getting resized images

Dimitri Korsch 3 éve
szülő
commit
be5632ea9f

+ 1 - 0
pycs/frontend/endpoints/data/GetResizedFile.py

@@ -37,4 +37,5 @@ class GetResizedFile(View):
                                                   max_width, max_height)
 
         # send to client
+        print(file_name)
         return send_from_directory(file_directory, file_name)

+ 6 - 6
pycs/util/FileOperations.py

@@ -79,10 +79,10 @@ def resize_file(file: File,
                                    project_root,
                                    'temp',
                                    f'{file.uuid}_{max_width}_{max_height}.jpg')
-    result = resize_image(abs_file_path, abs_target_path, max_width, max_height)
+    resized = resize_image(abs_file_path, abs_target_path, max_width, max_height)
 
     # return path
-    if result is not None:
+    if resized:
         return os.path.split(abs_target_path)
 
     return os.path.split(abs_file_path)
@@ -118,9 +118,9 @@ def crop_file(file: File, project_root: str, box: BoundingBox,
                                    project_root,
                                    'temp',
                                    f'{file.uuid}_{bounding_box_suffix}.jpg')
-    result = crop_image(abs_file_path, abs_target_path, box)
+    cropped = crop_image(abs_file_path, abs_target_path, box)
 
-    if result:
+    if cropped:
         abs_file_path = abs_target_path
 
     # resize image
@@ -129,9 +129,9 @@ def crop_file(file: File, project_root: str, box: BoundingBox,
                                    project_root,
                                    'temp',
                                    target_file_name)
-    result = resize_image(abs_file_path, abs_target_path, max_width, max_height)
+    resized = resize_image(abs_file_path, abs_target_path, max_width, max_height)
 
-    if result:
+    if resized:
         abs_file_path = abs_target_path
 
     # return image

+ 6 - 1
tests/base.py

@@ -67,7 +67,12 @@ class BaseTestCase(unittest.TestCase):
 
     def _do_request(self, request_func, *args,  status_code=200, **kwargs):
         response = request_func(*args, follow_redirects=True, **kwargs)
-        self.assertEqual(response.status_code, status_code, response.get_data().decode())
+        try:
+            content = response.get_data().decode()
+        except UnicodeDecodeError:
+            content = response.get_data()
+
+        self.assertEqual(response.status_code, status_code, content)
         return response
 
     def post(self,

+ 195 - 0
tests/client/file_tests.py

@@ -1,7 +1,10 @@
+import cv2
 import io
+import numpy as np
 import os
 import uuid
 
+from PIL import Image
 from flask import url_for
 from pathlib import Path
 from pycs.database.File import File
@@ -125,3 +128,195 @@ class FileDeletionTests(_BaseFileTests):
         self.assertEqual(1, self.project.files.count())
         self.post(url, json=dict(remove=True), status_code=400)
         self.assertEqual(1, self.project.files.count())
+
+
+class FileGettingTests(_BaseFileTests):
+
+
+    def test_get_file_getting(self):
+
+        file_uuid = str(uuid.uuid1())
+        file, is_new = self.project.add_file(
+            uuid=file_uuid,
+            file_type="image",
+            name=f"name",
+            filename=f"image",
+            extension=".jpg",
+            size=32*1024,
+        )
+
+        self.assertTrue(is_new)
+        self.assertEqual(1, self.project.files.count())
+
+        url = url_for("get_file", file_id=file.id)
+
+        # without an actual file, this GET request returns 404
+        self.get(url, status_code=404)
+
+        content = b"some text"
+        with open(file.absolute_path, "wb") as f:
+            f.write(content)
+
+        response = self.get(url)
+
+        self.assertFalse(response.is_json)
+        self.assertEqual(content, response.data)
+
+    def test_get_prev_next_file(self):
+
+        for i in range(1, 6):
+            file_uuid = str(uuid.uuid1())
+            file, is_new = self.project.add_file(
+                uuid=file_uuid,
+                file_type="image",
+                name=f"name_{i}",
+                filename=f"image_{i}",
+                extension=".jpg",
+                size=32*1024,
+            )
+
+            self.assertTrue(is_new)
+            with open(file.absolute_path, "wb") as f:
+                f.write(b"some content")
+
+        self.assertEqual(5, self.project.files.count())
+        files = self.project.files.all()
+
+        url = url_for("get_previous_and_next_file", file_id=4542)
+        self.get(url, status_code=404)
+
+        for i, file in enumerate(files):
+            p_file, n_file = None, None
+
+            if i != 0:
+                p_file = files[i-1].serialize()
+
+            if i < len(files)-1:
+                n_file = files[i+1].serialize()
+
+
+            url = url_for("get_previous_and_next_file", file_id=file.id)
+
+            response = self.get(url)
+            self.assertTrue(response.is_json)
+
+            content_should = dict(
+                next=n_file,
+                nextInCollection=n_file,
+                previous=p_file,
+                previousInCollection=p_file,
+            )
+
+            self.assertDictEqual(content_should, response.json)
+
+        files[1].delete()
+        file = files[2]
+        p_file, n_file = files[0], files[3]
+        url = url_for("get_previous_and_next_file", file_id=file.id)
+
+        response = self.get(url)
+        self.assertTrue(response.is_json)
+
+        content_should = dict(
+            next=n_file.serialize(),
+            nextInCollection=n_file.serialize(),
+            previous=p_file.serialize(),
+            previousInCollection=p_file.serialize(),
+        )
+
+        self.assertDictEqual(content_should, response.json)
+
+        files[3].delete()
+        file = files[2]
+        p_file, n_file = files[0], files[4]
+        url = url_for("get_previous_and_next_file", file_id=file.id)
+
+        response = self.get(url)
+        self.assertTrue(response.is_json)
+
+        content_should = dict(
+            next=n_file.serialize(),
+            nextInCollection=n_file.serialize(),
+            previous=p_file.serialize(),
+            previousInCollection=p_file.serialize(),
+        )
+
+        self.assertDictEqual(content_should, response.json)
+
+
+
+class FileResizingTests(_BaseFileTests):
+
+    def _add_image(self, shape, file: File):
+        image = np.random.randint(0, 256, shape).astype(np.uint8)
+
+        im = Image.fromarray(image)
+
+        im.save(file.absolute_path)
+        self.assertTrue(os.path.exists(file.absolute_path))
+        return image
+
+    def _compare_images(self, im0, im1, threshold=1e-3):
+        im0, im1 = im0 / 255, im1 / 255
+        mse = np.mean((im0 - im1)**2)
+        self.assertLess(mse, threshold)
+
+    @pаtch_tpool_execute
+    def test_resize_image(self, mocked_execute):
+
+        self.get(url_for("get_resized_file", file_id=4242, resolution=300), status_code=404)
+
+        file_uuid = str(uuid.uuid1())
+        file, is_new = self.project.add_file(
+            uuid=file_uuid,
+            file_type="image",
+            name=f"name",
+            filename=f"image",
+            extension=".png",
+            size=32*1024,
+        )
+
+        self.assertTrue(is_new)
+
+        image = self._add_image((300, 300), file)
+
+        for upscale in [300, 1200, 500, 320]:
+            url = url_for("get_resized_file", file_id=file.id, resolution=upscale)
+            response = self.get(url)
+
+            self.assertFalse(response.is_json)
+
+            returned_im = np.asarray(Image.open(io.BytesIO(response.data)))
+
+            self.assertEqual(image.shape, returned_im.shape)
+            self._compare_images(image, returned_im)
+
+
+        # repeat the last scale two times to get the cached resized image
+        for downscale in [299, 200, 150, 32, 32]:
+            sm_image = np.asarray(Image.fromarray(image).resize((downscale, downscale)))
+
+            url = url_for("get_resized_file", file_id=file.id, resolution=downscale)
+            response = self.get(url)
+
+            self.assertFalse(response.is_json)
+
+            returned_im = np.asarray(Image.open(io.BytesIO(response.data)))
+
+            self.assertEqual(sm_image.shape, returned_im.shape)
+            self._compare_images(sm_image, returned_im)
+
+            del sm_image
+
+
+        save = file.path
+        file.path = "/some/nonexisting/path"
+        file.commit()
+        url = url_for("get_resized_file", file_id=file.id, resolution=upscale)
+        response = self.get(url, status_code=404)
+
+        file.path = save
+        file.commit()
+
+
+