Commits

b7w committed 5577dd4

Write test for proxy storage, fix some bugs

Comments (0)

Files changed (4)

bviewer/core/files/path.py

         self.is_image = False
         self.is_dir = True
 
+    def __lt__(self, other):
+        return self.name < other.name
+
 
 class ImagePath(BasePath, ImagePathCacheMixin):
     """

bviewer/core/files/proxy.py

 
 
 class ProxyImageStorage(BaseImageStorage):
-    def __init__(self, gallery, root_path=None, cache_path=None, archive_cache=False):
+    def __init__(self, gallery, root_path=None, cache_path=None, archive_cache=False, provider=ImageStorage):
         """
         :param root_path: place where image files stored, default settings.VIEWER_STORAGE_PATH
         :param cache_path: place where cache stored, default settings.VIEWER_CACHE_PATH
         :param archive_cache: set 'archives' sub cache folder instead of 'images'
-        :type gallery: bviewer.core.models.Gallery
+        :type gallery: bviewer.core.files.utils.GalleryConfig or bviewer.core.models.Gallery
         """
         self.gallery = gallery
-        self.mounts = gallery.home.split(';')
+        self.mounts = sorted(set(gallery.home.split(';')))
         self.configs = [GalleryConfig(gallery, i) for i in self.mounts]
         self._storages = {}
         for conf in self.configs:
-            storage = ImageStorage(conf, root_path=root_path, cache_path=cache_path, archive_cache=archive_cache)
+            storage = provider(conf, root_path=root_path, cache_path=cache_path, archive_cache=archive_cache)
             self._storages[conf.home] = storage
 
     def _get_storage(self, path):
                 return self._storages[mount], path.replace(_mount, '')
         raise FileError('No storage mount found')
 
+    def _get_master_storage(self):
+        return self._storages[self.mounts[0]]
+
     def list(self, path=None, saved_images=None):
         if not path:
             return sorted(MountPath(i) for i in self.mounts)
         storage, path = self._get_storage(path)
-        return storage.list(path=path, saved_images=saved_images)
+        return storage.list(path, saved_images=saved_images)
 
     def get_path(self, path, options=None):
         storage, path = self._get_storage(path)
         return storage.get_path(path, options=options)
 
     def get_url(self, url, options=None):
-        storage = list(self._storages.values())[0]
-        return storage.get_path(url, options=options)
+        storage = self._get_master_storage()
+        return storage.get_url(url, options=options)
 
     def get_archive(self, options=None):
-        storage = list(self._storages.values())[0]
+        storage = self._get_master_storage()
         return storage.get_archive(options=options)
 
     def clear_cache(self, full=False):
-        for storage in self._storages:
+        for storage in self._storages.values():
             storage.clear_cache(full=full)
 
     def cache_size(self):

bviewer/core/files/storage.py

         :param root_path: place where image files stored, default settings.VIEWER_STORAGE_PATH
         :param cache_path: place where cache stored, default settings.VIEWER_CACHE_PATH
         :param archive_cache: set 'archives' sub cache folder instead of 'images'
-        :type gallery: bviewer.core.models.Gallery
+        :type gallery: bviewer.core.files.utils.GalleryConfig or bviewer.core.models.Gallery
         """
         self.gallery = gallery
         self.root = root_path or settings.VIEWER_STORAGE_PATH

bviewer/core/tests/test_files.py

 
 from bviewer.core.exceptions import FileError
 from bviewer.core.files.path import ImagePath
+from bviewer.core.files.proxy import ProxyImageStorage
 from bviewer.core.files.storage import ImageStorage
 from bviewer.core.files.utils import ImageFolder
 from bviewer.core.tests.base import BaseImageStorageTestCase
                 self.assertEqual(func(image_path, for_cache=True), for_cache)
 
         gallery = Mock(home='home', url='url', cache_size=0)
-        storage = ImageStorage(gallery, root_path='root', cache_path='cache')
+        # storage try to create cache folder on init, mock it
+        with patch('os.makedirs'):
+            storage = ImageStorage(gallery, root_path='root', cache_path='cache')
 
         assert_method_for_cache('os.path.getctime', storage.ctime, side_effect=str)
         assert_method_for_cache('os.path.exists', storage.exists, side_effect=str)
         open_module = 'builtins.open' if six.PY3 else '__builtin__.open'
-        assert_method_for_cache(open_module, storage.open, side_effect=lambda path, mode: str(path))
+        assert_method_for_cache(open_module, storage.open, side_effect=lambda path, mode: str(path))
+
+
+class ProxyImageStorageTestCase(BaseImageStorageTestCase):
+    VALUE = Mock()
+    VALUE2 = Mock()
+
+    def setUp(self):
+        self.gallery = Mock(home='home;home2', url='gallery_url', cache_size=0)
+        self.backend = Mock(
+            list=Mock(return_value=self.VALUE),
+            get_path=Mock(return_value=self.VALUE),
+            get_url=Mock(return_value=self.VALUE),
+            get_archive=Mock(return_value=self.VALUE),
+            clear_cache=Mock(return_value=self.VALUE),
+            cache_size=Mock(return_value=10),
+        )
+        self.backend2 = Mock(
+            list=Mock(return_value=self.VALUE2),
+            get_path=Mock(return_value=self.VALUE2),
+            clear_cache=Mock(return_value=self.VALUE2),
+            cache_size=Mock(return_value=100),
+        )
+        self.storage = self._build_storage(self.backend, self.backend2)
+        self.options = Mock()
+
+    def _build_storage(self, backend, backend2):
+        def _provider(conf, *args, **kwargs):
+            if conf.home == 'home':
+                return backend
+            if conf.home == 'home2':
+                return backend2
+            raise AssertionError('Wrong home')
+
+        return ProxyImageStorage(self.gallery, provider=_provider)
+
+    def test_list(self):
+        out = self.storage.list(saved_images=self.options)
+        self.assertEqual([i.full_path for i in out if i.is_dir], ['home', 'home2'])
+
+        self.assertEqual(self.storage.list('home', saved_images=self.options), self.VALUE)
+        self.backend.list.assert_called_with('', saved_images=self.options)
+        self.assertEqual(self.storage.list('home/path', saved_images=self.options), self.VALUE)
+        self.backend.list.assert_called_with('path', saved_images=self.options)
+
+        self.assertEqual(self.storage.list('home2', saved_images=self.options), self.VALUE2)
+        self.backend2.list.assert_called_with('', saved_images=self.options)
+        self.assertEqual(self.storage.list('home2/path2', saved_images=self.options), self.VALUE2)
+        self.backend2.list.assert_called_with('path2', saved_images=self.options)
+
+    def test_get_path(self):
+        out = self.storage.get_path('home/file', options=self.options)
+        self.assertEqual(out, self.VALUE)
+        self.backend.get_path.assert_called_with('file', options=self.options)
+
+        out = self.storage.get_path('home2/file2', options=self.options)
+        self.assertEqual(out, self.VALUE2)
+        self.backend2.get_path.assert_called_with('file2', options=self.options)
+
+    def test_get_url(self):
+        out = self.storage.get_url('url', options=self.options)
+        self.assertEqual(out, self.VALUE)
+        self.backend.get_url.assert_called_with('url', options=self.options)
+
+    def test_get_archive(self):
+        out = self.storage.get_archive(options=self.options)
+        self.assertEqual(out, self.VALUE)
+        self.backend.get_archive.assert_called_with(options=self.options)
+
+    def test_clear_cache(self):
+        self.storage.clear_cache(full=True)
+        self.backend.clear_cache.assert_called_with(full=True)
+        self.backend2.clear_cache.assert_called_with(full=True)
+
+    def test_cache_size(self):
+        out = self.storage.cache_size()
+        self.assertEqual(out, 110)
+        self.backend.cache_size.assert_called_with()
+        self.backend2.cache_size.assert_called_with()