diff --git a/.gitignore b/.gitignore index 3dcacda..b26376d 100644 --- a/.gitignore +++ b/.gitignore @@ -33,14 +33,7 @@ docs/_build* .tox -tests/* !tests/__init__.py !tests/config.py !tests/test_cloudy.py - -tests/data/* -!tests/data/hello.txt -!tests/data/hello.js - -tests/container_1/* -!tests/container_1/empty +!tests/testconf.py diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..d8f4608 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,69 @@ +"""Defines fixtures available to all tests.""" + +import pytest +from tempfile import TemporaryDirectory, NamedTemporaryFile +import os +from flask import Flask +from flask_cloudy import Storage +from tests.config import LocalConfig +import random + + +@pytest.yield_fixture(scope='function') +def temp_dir(): + """A temporary directory for each test.""" + with TemporaryDirectory() as temp_dir: + yield temp_dir + +@pytest.yield_fixture(scope='function') +def temp_container(): + """A temporary container directory for each test.""" + with TemporaryDirectory() as temp_dir: + yield temp_dir + +@pytest.yield_fixture(scope='function') +def temp_txt_file(): + """A temporary txt file with random contents for each test.""" + with NamedTemporaryFile(mode="w+", suffix=".txt") as temp_file: + temp_file.write('%s' % random.random()) + temp_file.file.seek(0) + yield temp_file + + +@pytest.yield_fixture(scope='function') +def temp_png_file(): + """A temporary txt file with random contents for each test.""" + with NamedTemporaryFile(suffix=".png") as temp_file: + yield temp_file + + +@pytest.yield_fixture(scope='function') +def temp_js_file(): + """A temporary js file with random contents for each test.""" + with NamedTemporaryFile(mode="w+", suffix=".js") as temp_file: + temp_file.write('%s' % random.random()) + temp_file.file.seek(0) + yield temp_file + + +@pytest.yield_fixture(scope='function') +def app(temp_container): + """An application for the tests.""" + app = Flask(__name__) + LocalConfig.STORAGE_CONTAINER = temp_container + app.config.from_object(LocalConfig) + + ctx = app.test_request_context() + ctx.push() + + yield app + + ctx.pop() + + +@pytest.fixture(scope='function') +def storage(app): + """A flask-cloudy storage instance for tests.""" + storage = Storage(app=app) + storage.app = app + return storage diff --git a/tests/container_1/empty b/tests/container_1/empty deleted file mode 100644 index e69de29..0000000 diff --git a/tests/data/hello.js b/tests/data/hello.js deleted file mode 100644 index 575a91b..0000000 --- a/tests/data/hello.js +++ /dev/null @@ -1 +0,0 @@ -// This is the javascript file diff --git a/tests/data/hello.txt b/tests/data/hello.txt deleted file mode 100644 index e69de29..0000000 diff --git a/tests/test_cloudy.py b/tests/test_cloudy.py index 17a740a..a2162d9 100644 --- a/tests/test_cloudy.py +++ b/tests/test_cloudy.py @@ -1,16 +1,17 @@ - import os +from os.path import join, dirname import pytest from tests.config import LocalConfig as config - from flask_cloudy import (InvalidExtensionError, Object, get_driver_class, get_file_extension, get_file_extension_type, get_file_name, get_provider_name) from libcloud.storage.base import Container, StorageDriver -CWD = os.path.dirname(__file__) +CWD = dirname(__file__) -CONTAINER = "%s/%s" % (CWD, config.STORAGE_CONTAINER) if config.STORAGE_PROVIDER == "LOCAL" else config.STORAGE_CONTAINER +CONTAINER = "%s/%s" % ( + CWD, config.STORAGE_CONTAINER +) if config.STORAGE_PROVIDER == "LOCAL" else config.STORAGE_CONTAINER class TestUtilities: @@ -31,6 +32,7 @@ class TestUtilities: def test_get_provider_name(self): class GoogleStorageDriver(object): pass + driver = GoogleStorageDriver() assert get_provider_name(driver) == "google_storage" @@ -64,6 +66,22 @@ class TestLocalStorage: o = storage.create(object_name) assert isinstance(o, Object) + def test_empty_storage_object_evaluates_false(self, storage): + """Check that storage object eval false if they are empty.""" + object_name = "hello.txt" + o = storage.create(object_name) + if o: + raise ValueError("Object evaluated to false") + + def test_storage_object_evaluates_true(self, storage, temp_txt_file): + """Check that storage object eval true if they are not empty.""" + o = storage.upload(temp_txt_file.name) + o1 = storage.get(o.name) + if not o: + raise ValueError("Storage upload object evaluated to false") + if not o1: + raise ValueError("Storage get object evaluated to false") + def test_object_type_extension(self, storage): object_name = "hello.jpg" o = storage.create(object_name) @@ -81,20 +99,43 @@ class TestLocalStorage: p = "%s/%s" % (o.container.name, o.name) assert o.path.endswith(p) - def test_storage_upload_invalid(self, storage): + def test_storage_upload_invalid(self, storage, temp_js_file): + """Check .js extensions are not allowed by default.""" object_name = "my-js/hello.js" with pytest.raises(InvalidExtensionError): - storage.upload(CWD + "/data/hello.js", name=object_name) + storage.upload(temp_js_file.name, name=object_name) - def test_storage_upload_ovewrite(self, storage): - object_name = "my-txt-hello.txt" - o = storage.upload(CWD + "/data/hello.txt", name=object_name, overwrite=True) - assert isinstance(o, Object) - assert o.name == object_name + def test_storage_upload_overwrite(self, storage, temp_txt_file, + temp_js_file): + object_name = "hello.txt" + o = storage.upload(temp_js_file.name, + name=object_name, + overwrite=True, + allowed_extensions=["js"]) + o_ow = storage.upload(temp_txt_file.name, + name=object_name, + overwrite=True) + assert isinstance(o_ow, Object) + assert o_ow.name == o.name + assert o_ow.name == object_name - def test_storage_get(self, storage): - object_name = "my-txt-helloIII.txt" - o = storage.upload(CWD + "/data/hello.txt", name=object_name, overwrite=True) + def test_storage_upload_no_overwrite(self, storage, temp_txt_file, + temp_js_file): + object_name = "hello.txt" + o = storage.upload(temp_js_file.name, + overwrite=True, + allowed_extensions=["js"]) + o_no_ow = storage.upload(temp_txt_file.name, + name=object_name, + overwrite=False) + assert isinstance(o_no_ow, Object) + assert o.name != o_no_ow.name + + def test_storage_get(self, storage, temp_txt_file): + object_name = "test_storage_get.txt" + o = storage.upload(temp_txt_file.name, + name=object_name, + overwrite=True) o2 = storage.get(o.name) assert isinstance(o2, Object) @@ -102,58 +143,68 @@ class TestLocalStorage: o2 = storage.get("idonexist") assert o2 is None - def test_storage_upload(self, storage): - object_name = "my-txt-hello2.txt" - storage.upload(CWD + "/data/hello.txt", name=object_name) - o = storage.upload(CWD + "/data/hello.txt", name=object_name) + def test_storage_upload(self, storage, temp_txt_file): + object_name = "test_storage_upload.txt" + storage.upload(temp_txt_file.name, name=object_name) + o = storage.upload(temp_txt_file.name, name=object_name) assert isinstance(o, Object) assert o.name != object_name - def test_storage_upload_use_filename_name(self, storage): - object_name = "hello.js" - o = storage.upload(CWD + "/data/hello.js", overwrite=True, allowed_extensions=["js"]) + def test_storage_upload_use_filename_name(self, storage, temp_js_file): + """Check that uploaded files retain thier name.""" + object_name = os.path.basename(temp_js_file.name) + o = storage.upload(temp_js_file.name, + overwrite=True, + allowed_extensions=["js"]) assert o.name == object_name - def test_storage_upload_append_extension(self, storage): - object_name = "my-txt-hello-hello" - o = storage.upload(CWD + "/data/hello.txt", object_name, overwrite=True) + def test_storage_upload_append_extension(self, storage, temp_txt_file): + """Check that uploaded names get an appended extension.""" + object_name = "test_storage_upload_append_extension" + o = storage.upload(temp_txt_file.name, object_name, overwrite=True) assert get_file_extension(o.name) == "txt" - def test_storage_upload_with_prefix(self, storage): - object_name = "my-txt-hello-hello" + def test_storage_upload_with_prefix(self, storage, temp_txt_file): + object_name = os.path.splitext(os.path.basename(temp_txt_file.name))[0] prefix = "dir1/dir2/dir3/" full_name = "%s%s.%s" % (prefix, object_name, "txt") - o = storage.upload(CWD + "/data/hello.txt", name=object_name, prefix=prefix, overwrite=True) + o = storage.upload(temp_txt_file.name, + name=object_name, + prefix=prefix, + overwrite=True) assert full_name in storage assert o.name == full_name - def test_save_to(self, storage): - object_name = "my-txt-hello-to-save.txt" - o = storage.upload(CWD + "/data/hello.txt", name=object_name) - file = o.save_to(CWD + "/data", overwrite=True) - file2 = o.save_to(CWD + "/data", name="my_new_file", overwrite=True) + def test_save_to(self, storage, temp_dir, temp_txt_file): + object_name = "test_save_to.txt" + o = storage.upload(temp_txt_file.name, name=object_name) + file = o.save_to(temp_dir, overwrite=True) + file2 = o.save_to( + temp_dir, + name="my_new_file", + overwrite=True) + print(o, o.name, file, temp_dir, file2) assert os.path.isfile(file) - assert file2 == CWD + "/data/my_new_file.txt" + assert file2 == join(temp_dir, "my_new_file.txt") - def test_werkzeug_upload(self, storage): + def test_local_server(self, storage, temp_txt_file): + """Test the local server function.""" + object_name = "test_local_server.txt" + storage.upload(temp_txt_file.name, name=object_name, overwrite=True) + print(storage.app.view_functions) + file_server = storage.app.view_functions['FLASK_CLOUDY_SERVER'] + response = file_server(object_name) + assert response.status_code == 200 + + @pytest.mark.timeout(30) + def test_werkzeug_upload(self, storage, temp_png_file): try: import werkzeug except ImportError: return - object_name = "my-txt-hello.txt" - filepath = CWD + "/data/hello.txt" - file = None - with open(filepath, 'rb') as fp: - file = werkzeug.datastructures.FileStorage(fp) - file.filename = object_name - o = storage.upload(file, overwrite=True) - assert isinstance(o, Object) - assert o.name == object_name - - def test_local_server(self, storage): - """Test the local server function.""" - object_name = "test_local_server.txt" - storage.upload(CWD + "/data/hello.txt", name=object_name, overwrite=True) - file_server = storage.app.view_functions['FLASK_CLOUDY_SERVER'] - response = file_server(object_name) - assert response.status_code == 200 + object_name = "test-werkzeug-upload.txt" + file = werkzeug.datastructures.FileStorage(temp_png_file) + file.filename = object_name + o = storage.upload(file, overwrite=True) + assert isinstance(o, Object) + assert o.name == object_name