Browse Source

Wrap tests for uploading assets

rafalp 6 years ago
parent
commit
ee913809d1

+ 2 - 4
misago/admin/tests/test_logout_from_admin.py

@@ -1,7 +1,6 @@
-from django.contrib.messages import get_messages
 from django.urls import reverse
 
-from ...test import assert_contains
+from ...test import assert_contains, assert_has_message
 from ..auth import is_admin_authorized
 
 admin_logout_link = reverse("misago:admin:logout")
@@ -23,8 +22,7 @@ def test_admin_is_redirected_to_site_on_logout(admin_client, superuser):
 
 def test_admin_is_displayed_a_message_after_logout(admin_client, superuser):
     response = admin_client.post(admin_logout_link)
-    message = list(get_messages(response.wsgi_request))[0]
-    assert str(message) == "Your admin session has been closed."
+    assert_has_message(response, "Your admin session has been closed.")
 
 
 def test_admin_can_logout_from_entire_site(admin_client):

+ 5 - 0
misago/admin/themes/tests/conftest.py

@@ -11,3 +11,8 @@ def default_theme(db):
 @pytest.fixture
 def theme(db):
     return Theme.objects.create(name="Custom theme")
+
+
+@pytest.fixture
+def nonexisting_theme(mocker, default_theme):
+    return mocker.Mock(pk=default_theme.pk + 1)

+ 50 - 25
misago/admin/themes/tests/test_uploading_css.py

@@ -3,6 +3,8 @@ import os
 import pytest
 from django.urls import reverse
 
+from ....test import assert_has_error_message
+
 TESTS_DIR = os.path.dirname(os.path.abspath(__file__))
 
 
@@ -22,13 +24,8 @@ def hashed_css_file():
 
 
 @pytest.fixture
-def incorrectly_hashed_css_file():
-    return os.path.join(TESTS_DIR, "css", "test.0046cb3b.css")
-
-
-@pytest.fixture
 def upload(admin_client):
-    def post_upload(theme, asset_files):
+    def post_upload(theme, asset_files=None):
         url = reverse(
             "misago:admin:appearance:themes:upload-css", kwargs={"pk": theme.pk}
         )
@@ -63,7 +60,13 @@ def test_uploaded_file_is_rejected_if_its_not_css_file(upload, theme, other_file
         assert not theme.css.exists()
 
 
-def test_if_some_of_uploaded_files_are_incorrect_only_correct_files_are_added_to_theme(
+def test_error_message_is_set_if_uploaded_file_is_not_css(upload, theme, other_file):
+    with open(other_file, "rb") as fp:
+        response = upload(theme, fp)
+        assert_has_error_message(response)
+
+
+def test_if_some_of_uploaded_files_are_incorrect_only_css_files_are_added_to_theme(
     upload, theme, css_file, other_file
 ):
     with open(css_file) as fp1:
@@ -72,44 +75,46 @@ def test_if_some_of_uploaded_files_are_incorrect_only_correct_files_are_added_to
             assert theme.css.exists()
             assert theme.css.count() == 1
 
-    css_asset = theme.css.last()
+    css = theme.css.last()
     expected_filename = str(css_file).split("/")[-1]
-    assert css_asset.name == expected_filename
+    assert css.name == expected_filename
 
 
 def test_css_file_is_uploaded_to_theme_directory(upload, theme, css_file):
     with open(css_file) as fp:
         upload(theme, fp)
 
-    css_asset = theme.css.last()
-    assert theme.dirname in str(css_asset.source_file)
+    css = theme.css.last()
+    assert theme.dirname in str(css.source_file)
 
 
 def test_css_file_name_is_set_as_asset_name(upload, theme, css_file):
     with open(css_file) as fp:
         upload(theme, fp)
 
-    css_asset = theme.css.last()
+    css = theme.css.last()
     expected_filename = str(css_file).split("/")[-1]
-    assert css_asset.name == expected_filename
+    assert css.name == expected_filename
 
 
-def test_hash_is_added_to_uploaded_file_name(upload, theme, css_file, hashed_css_file):
+def test_hash_is_added_to_uploaded_css_file_name(
+    upload, theme, css_file, hashed_css_file
+):
     with open(css_file) as fp:
         upload(theme, fp)
 
-    css_asset = theme.css.last()
-    filename = str(css_asset.source_file.path).split("/")[-1]
+    css = theme.css.last()
+    filename = str(css.source_file.path).split("/")[-1]
     expected_filename = str(hashed_css_file).split("/")[-1]
     assert filename == expected_filename
 
 
-def test_hash_is_set_on_asset(upload, theme, css_file, hashed_css_file):
+def test_hash_is_set_on_css_source_asset(upload, theme, css_file):
     with open(css_file) as fp:
         upload(theme, fp)
 
-    css_asset = theme.css.last()
-    assert css_asset.source_hash
+    css = theme.css.last()
+    assert css.source_hash
 
 
 def test_css_file_name_is_preserved_if_it_already_contains_correct_hash(
@@ -118,18 +123,38 @@ def test_css_file_name_is_preserved_if_it_already_contains_correct_hash(
     with open(hashed_css_file) as fp:
         upload(theme, fp)
 
-    css_asset = theme.css.last()
-    filename = str(css_asset.source_file.path).split("/")[-1]
+    css = theme.css.last()
+    filename = str(css.source_file.path).split("/")[-1]
     expected_filename = str(hashed_css_file).split("/")[-1]
     assert filename == expected_filename
 
 
 def test_new_hash_is_added_to_css_file_name_if_it_contains_incorrect_hash(
-    upload, theme, incorrectly_hashed_css_file
+    upload, theme
 ):
+    incorrectly_hashed_css_file = os.path.join(TESTS_DIR, "css", "test.0046cb3b.css")
     with open(incorrectly_hashed_css_file) as fp:
         upload(theme, fp)
 
-    css_asset = theme.css.last()
-    filename = str(css_asset.source_file.path).split("/")[-1]
-    assert css_asset.source_hash in filename
+    css = theme.css.last()
+    filename = str(css.source_file.path).split("/")[-1]
+    assert css.source_hash in filename
+
+
+def test_error_message_is_set_if_no_css_file_was_uploaded(upload, theme):
+    response = upload(theme)
+    assert_has_error_message(response)
+
+
+def test_error_message_is_set_if_user_attempts_to_upload_css_file_to_default_theme(
+    upload, default_theme
+):
+    response = upload(default_theme)
+    assert_has_error_message(response)
+
+
+def test_error_message_is_set_if_user_attempts_to_upload_css_file_to_nonexisting_theme(
+    upload, nonexisting_theme
+):
+    response = upload(nonexisting_theme)
+    assert_has_error_message(response)

+ 117 - 13
misago/admin/themes/tests/test_uploading_media.py

@@ -3,32 +3,34 @@ import os
 import pytest
 from django.urls import reverse
 
+from ....test import assert_has_error_message
+
 TESTS_DIR = os.path.dirname(os.path.abspath(__file__))
 
 
 @pytest.fixture
-def font_file():
-    return os.path.join(TESTS_DIR, "font", "Lato.ttf")
+def png_file():
+    return os.path.join(TESTS_DIR, "images", "test.png")
 
 
 @pytest.fixture
-def text_file():
-    return os.path.join(TESTS_DIR, "font", "OFL.txt")
+def svg_file():
+    return os.path.join(TESTS_DIR, "images", "test.svg")
 
 
 @pytest.fixture
-def png_file():
-    return os.path.join(TESTS_DIR, "images", "test.png")
+def hashable_file():
+    return os.path.join(TESTS_DIR, "css", "test.css")
 
 
 @pytest.fixture
-def svg_file():
-    return os.path.join(TESTS_DIR, "images", "test.svg")
+def hashed_file():
+    return os.path.join(TESTS_DIR, "css", "test.4846cb3b.css")
 
 
 @pytest.fixture
 def upload(admin_client):
-    def post_upload(theme, asset_files):
+    def post_upload(theme, asset_files=None):
         url = reverse(
             "misago:admin:appearance:themes:upload-media", kwargs={"pk": theme.pk}
         )
@@ -41,25 +43,127 @@ def upload(admin_client):
     return post_upload
 
 
-def test_font_file_can_be_uploaded(upload, theme, font_file):
+def test_font_file_can_be_uploaded(upload, theme):
+    font_file = os.path.join(TESTS_DIR, "font", "Lato.ttf")
     with open(font_file, "rb") as fp:
         upload(theme, fp)
         assert theme.media.exists()
 
 
-def test_text_file_can_be_uploaded(upload, theme, text_file):
+def test_text_file_can_be_uploaded(upload, theme):
+    text_file = os.path.join(TESTS_DIR, "font", "OFL.txt")
     with open(text_file) as fp:
         upload(theme, fp)
         assert theme.media.exists()
 
 
+def test_svg_file_can_be_uploaded(upload, theme):
+    svg_file = os.path.join(TESTS_DIR, "images", "test.svg")
+    with open(svg_file) as fp:
+        upload(theme, fp)
+        assert theme.media.exists()
+
+
 def test_png_file_can_be_uploaded(upload, theme, png_file):
     with open(png_file, "rb") as fp:
         upload(theme, fp)
         assert theme.media.exists()
 
 
-def test_svg_file_can_be_uploaded(upload, theme, svg_file):
+def test_media_file_name_is_set_as_asset_name(upload, theme, svg_file):
     with open(svg_file) as fp:
         upload(theme, fp)
-        assert theme.media.exists()
+
+    media = theme.media.last()
+    expected_filename = str(svg_file).split("/")[-1]
+    assert media.name == expected_filename
+
+
+def test_media_file_is_uploaded_to_theme_directory(upload, theme, svg_file):
+    with open(svg_file) as fp:
+        upload(theme, fp)
+
+    media = theme.media.last()
+    assert theme.dirname in str(media.file)
+
+
+def test_hash_is_added_to_uploaded_media_file_name(
+    upload, theme, hashable_file, hashed_file
+):
+    with open(hashable_file) as fp:
+        upload(theme, fp)
+
+    media = theme.media.last()
+    filename = str(media.file.path).split("/")[-1]
+    expected_filename = str(hashed_file).split("/")[-1]
+    assert filename == expected_filename
+
+
+def test_hash_is_set_on_media_asset(upload, theme, hashed_file):
+    with open(hashed_file) as fp:
+        upload(theme, fp)
+
+    media = theme.media.last()
+    assert media.hash
+
+
+def test_media_file_name_is_preserved_if_it_already_contains_correct_hash(
+    upload, theme, hashed_file
+):
+    with open(hashed_file) as fp:
+        upload(theme, fp)
+
+    media = theme.media.last()
+    filename = str(media.file.path).split("/")[-1]
+    expected_filename = str(hashed_file).split("/")[-1]
+    assert filename == expected_filename
+
+
+def test_new_hash_is_added_to_media_file_name_if_it_contains_incorrect_hash(
+    upload, theme
+):
+    incorrectly_hashed_file = os.path.join(TESTS_DIR, "css", "test.0046cb3b.css")
+    with open(incorrectly_hashed_file) as fp:
+        upload(theme, fp)
+
+    media = theme.media.last()
+    filename = str(media.file.path).split("/")[-1]
+    assert media.hash in filename
+
+
+def test_image_dimensions_are_set_for_uploaded_image_file(upload, theme, png_file):
+    with open(png_file, "rb") as fp:
+        upload(theme, fp)
+
+    media = theme.media.last()
+    assert media.width
+    assert media.height
+
+
+def test_thumbnail_is_generated_in_theme_directory_for_uploaded_image_file(
+    upload, theme, png_file
+):
+    with open(png_file, "rb") as fp:
+        upload(theme, fp)
+
+    media = theme.media.last()
+    assert theme.dirname in str(media.thumbnail)
+
+
+def test_error_message_is_set_if_no_media_was_uploaded(upload, theme):
+    response = upload(theme)
+    assert_has_error_message(response)
+
+
+def test_error_message_is_set_if_user_attempts_to_upload_file_to_default_theme(
+    upload, default_theme
+):
+    response = upload(default_theme)
+    assert_has_error_message(response)
+
+
+def test_error_message_is_set_if_user_attempts_to_upload_file_to_nonexisting_theme(
+    upload, nonexisting_theme
+):
+    response = upload(nonexisting_theme)
+    assert_has_error_message(response)

+ 2 - 2
misago/admin/themes/views.py

@@ -108,12 +108,12 @@ class UploadThemeAssets(ThemeAssetsActionAdmin, generic.TargetedView):
         form = self.form(request.POST, request.FILES, instance=theme)
 
         if not form.is_valid():
-            if form.cleaned_data["assets"]:
+            if form.cleaned_data.get("assets"):
                 messages.info(request, self.message_partial_success)
             for error in form.errors["assets"]:
                 messages.error(request, error)
 
-        if form.cleaned_data["assets"]:
+        if form.cleaned_data.get("assets"):
             form.save()
             messages.success(request, self.message_success)
 

+ 47 - 0
misago/test.py

@@ -1,3 +1,7 @@
+from django.contrib.messages.api import get_messages
+from django.contrib.messages.constants import ERROR, INFO, SUCCESS
+
+
 def assert_contains(response, string, status_code=200):
     assert response.status_code == status_code
     fail_message = f'"{string}" not found in response.content'
@@ -8,3 +12,46 @@ def assert_not_contains(response, string, status_code=200):
     assert response.status_code == status_code
     fail_message = f'"{string}" was found in response.content'
     assert string not in response.content.decode("utf-8"), fail_message
+
+
+def assert_has_error_message(response):
+    messages = get_messages(response.wsgi_request)
+    levels = [i.level for i in messages]
+
+    assert levels, "No messages were set during the request"
+    assert ERROR in levels, "No error messages were set during the request"
+
+
+def assert_has_info_message(response):
+    messages = get_messages(response.wsgi_request)
+    levels = [i.level for i in messages]
+
+    assert levels, "No messages were set during the request"
+    assert INFO in levels, "No info messages were set during the request"
+
+
+def assert_has_success_message(response):
+    messages = get_messages(response.wsgi_request)
+    levels = [i.level for i in messages]
+
+    assert levels, "No messages were set during the request"
+    assert SUCCESS in levels, "No success messages were set during the request"
+
+
+def assert_has_message(response, message, level=None):
+    messages = get_messages(response.wsgi_request)
+    found = False
+    for msg in messages:
+        if message in str(msg):
+            if level and level != msg.level:
+                error = (
+                    'Message containing "%s" was set '
+                    "but didn't have level %s (it had %s)"
+                )
+                raise AssertionError(error % (message, level, message.level))
+            found = True
+
+    if not found:
+        raise AssertionError(
+            'Message containing "%s" was not set during the request' % message
+        )