Browse Source

Invalidate theme cache when theme assets are edited

rafalp 6 years ago
parent
commit
cd6b501b5a

+ 3 - 0
misago/themes/admin/tasks.py

@@ -2,6 +2,7 @@ import requests
 from celery import shared_task
 from requests.exceptions import RequestException
 
+from ..cache import clear_theme_cache
 from ..models import Theme, Css
 from .css import get_theme_media_map, rebuild_css
 
@@ -39,6 +40,7 @@ def build_single_theme_css(pk):
     else:
         media_map = get_theme_media_map(css.theme)
         rebuild_css(media_map, css)
+        clear_theme_cache()
 
 
 @shared_task
@@ -51,3 +53,4 @@ def build_theme_css(pk):
         media_map = get_theme_media_map(theme)
         for css in theme.css.filter(source_needs_building=True):
             rebuild_css(media_map, css)
+        clear_theme_cache()

+ 2 - 2
misago/themes/admin/tests/conftest.py

@@ -30,7 +30,7 @@ TESTS_DIR = os.path.dirname(os.path.abspath(__file__))
 
 
 @pytest.fixture
-def css(admin_client, theme):
+def css(admin_client, theme, mock_build_theme_css):
     url = reverse("misago:admin:appearance:themes:upload-css", kwargs={"pk": theme.pk})
     with open(os.path.join(TESTS_DIR, "css", "test.css")) as fp:
         admin_client.post(url, {"assets": [fp]})
@@ -45,7 +45,7 @@ def css_link(admin_client, theme):
 
 
 @pytest.fixture
-def css_needing_build(admin_client, theme):
+def css_needing_build(admin_client, theme, mock_build_theme_css):
     url = reverse("misago:admin:appearance:themes:upload-css", kwargs={"pk": theme.pk})
     with open(os.path.join(TESTS_DIR, "css", "test.needs-build.css")) as fp:
         admin_client.post(url, {"assets": [fp]})

+ 14 - 0
misago/themes/admin/tests/test_css_files_building.py

@@ -1,5 +1,7 @@
 import pytest
 
+from ....cache.test import assert_invalidates_cache
+from ... import THEME_CACHE
 from ..css import change_css_source, get_theme_media_map, rebuild_css
 from ..tasks import build_single_theme_css, build_theme_css
 
@@ -154,3 +156,15 @@ def test_css_file_with_multiple_different_urls_is_correctly_replaced(
 
     result = change_css_source(media_map, css)
     assert_snapshot_match(result)
+
+
+def test_building_single_theme_css_invalidates_theme_cache(
+    theme, image, css_needing_build
+):
+    with assert_invalidates_cache(THEME_CACHE):
+        build_single_theme_css(css_needing_build.pk)
+
+
+def test_building_theme_css_invalidates_theme_cache(theme):
+    with assert_invalidates_cache(THEME_CACHE):
+        build_theme_css(theme.pk)

+ 12 - 0
misago/themes/admin/tests/test_css_files_creation_and_edition.py

@@ -1,7 +1,9 @@
 import pytest
 from django.urls import reverse
 
+from ....cache.test import assert_invalidates_cache
 from ....test import assert_contains, assert_has_error_message
+from ... import THEME_CACHE
 
 
 @pytest.fixture
@@ -164,6 +166,11 @@ def test_css_file_is_created_with_correct_order(
     assert css.order == 1
 
 
+def test_creating_css_file_invalidates_theme_cache(admin_client, create_link, data):
+    with assert_invalidates_cache(THEME_CACHE):
+        admin_client.post(create_link, data)
+
+
 def test_error_message_is_set_if_user_attempts_to_create_css_in_default_theme(
     default_theme, admin_client
 ):
@@ -326,6 +333,11 @@ def test_css_order_stays_the_same_after_edit(admin_client, edit_link, css, data)
     assert css.order == original_order
 
 
+def test_editing_css_file_invalidates_theme_cache(admin_client, edit_link, css, data):
+    with assert_invalidates_cache(THEME_CACHE):
+        admin_client.post(edit_link, data)
+
+
 def test_css_edit_form_redirects_user_to_edition_after_saving(
     theme, admin_client, edit_link, css, data
 ):

+ 16 - 2
misago/themes/admin/tests/test_css_links_creation_and_deletion.py

@@ -1,7 +1,9 @@
 import pytest
 from django.urls import reverse
 
+from ....cache.test import assert_invalidates_cache
 from ....test import assert_contains, assert_has_error_message
+from ... import THEME_CACHE
 
 
 @pytest.fixture
@@ -98,13 +100,20 @@ def test_css_link_is_created_with_correct_order(
 
 
 def test_css_link_creation_queues_task_to_download_remote_css_size(
-    theme, admin_client, create_link, css, data, mock_update_remote_css_size
+    theme, admin_client, create_link, data, mock_update_remote_css_size
 ):
     admin_client.post(create_link, data)
     css_link = theme.css.last()
     mock_update_remote_css_size.assert_called_once_with(css_link.pk)
 
 
+def test_css_link_creation_invalidates_theme_cache(
+    theme, admin_client, create_link, data
+):
+    with assert_invalidates_cache(THEME_CACHE):
+        admin_client.post(create_link, data)
+
+
 def test_error_message_is_set_if_user_attempts_to_create_css_link_in_default_theme(
     default_theme, admin_client
 ):
@@ -167,7 +176,7 @@ def test_changing_css_link_url_queues_task_to_download_remote_css_size(
     mock_update_remote_css_size.assert_called_once_with(css_link.pk)
 
 
-def test_not_changing_css_link_url_queues_task_to_download_remote_css_size(
+def test_not_changing_css_link_url_doesnt_queue_task_to_download_remote_css_size(
     admin_client, edit_link, css_link, data, mock_update_remote_css_size
 ):
     admin_client.post(edit_link, data)
@@ -175,6 +184,11 @@ def test_not_changing_css_link_url_queues_task_to_download_remote_css_size(
     mock_update_remote_css_size.assert_not_called()
 
 
+def test_changing_css_link_invalidates_theme_cache(admin_client, edit_link, data):
+    with assert_invalidates_cache(THEME_CACHE):
+        admin_client.post(edit_link, data)
+
+
 def test_css_order_stays_the_same_after_edit(admin_client, edit_link, css_link, data):
     original_order = css_link.order
     data["name"] = "changed link"

+ 7 - 0
misago/themes/admin/tests/test_deleting_assets.py

@@ -1,7 +1,9 @@
 import pytest
 from django.urls import reverse
 
+from ....cache.test import assert_invalidates_cache
 from ....test import assert_has_success_message
+from ... import THEME_CACHE
 
 
 @pytest.fixture
@@ -116,3 +118,8 @@ def test_other_theme_css_is_not_deleted(delete_css, theme, other_theme, css):
 def test_other_theme_media_is_not_deleted(delete_media, theme, other_theme, media):
     delete_media(other_theme, [media])
     assert theme.media.exists()
+
+
+def test_deleting_css_invalidates_theme_cache(theme, delete_css, css):
+    with assert_invalidates_cache(THEME_CACHE):
+        delete_css(theme, [css])

+ 12 - 0
misago/themes/admin/tests/test_reordering_css.py

@@ -1,7 +1,9 @@
 import pytest
 from django.urls import reverse
 
+from ....cache.test import assert_invalidates_cache
 from ....test import assert_has_error_message
+from ... import THEME_CACHE
 from ..css import get_next_css_order
 
 FIRST = 0
@@ -197,3 +199,13 @@ def test_if_given_nonexisting_theme_id_move_up_action_sets_error_message(
 def test_next_new_css_order_is_larger_than_largest_existing_css_order(theme):
     theme.css.create(name="CSS", url="https://test.cdn/font.css", order=4)
     assert get_next_css_order(theme) == 5
+
+
+def test_moving_css_up_invalidates_theme_cache(move_up, theme, css_list):
+    with assert_invalidates_cache(THEME_CACHE):
+        move_up(theme, css_list[LAST])
+
+
+def test_moving_css_down_invalidates_theme_cache(move_down, theme, css_list):
+    with assert_invalidates_cache(THEME_CACHE):
+        move_down(theme, css_list[FIRST])

+ 13 - 0
misago/themes/admin/views.py

@@ -4,6 +4,7 @@ from django.shortcuts import redirect
 from django.utils.translation import gettext, gettext_lazy as _
 
 from ...admin.views import generic
+from ..cache import clear_theme_cache
 from ..models import Theme, Css
 from .css import move_css_down, move_css_up
 from .forms import CssEditorForm, CssLinkForm, ThemeForm, UploadCssForm, UploadMediaForm
@@ -64,6 +65,7 @@ class ActivateTheme(ThemeAdmin, generic.ButtonView):
 def set_theme_as_active(request, theme):
     Theme.objects.update(is_active=False)
     Theme.objects.filter(pk=theme.pk).update(is_active=True)
+    clear_theme_cache()
 
 
 class ThemeAssetsAdmin(ThemeAdmin):
@@ -160,6 +162,10 @@ class DeleteThemeCss(DeleteThemeAssets):
     message_submit = _("Selected CSS files have been deleted.")
     queryset_attr = "css"
 
+    def action(self, request, theme):
+        super().action(request, theme)
+        clear_theme_cache()
+
 
 class DeleteThemeMedia(DeleteThemeAssets):
     message_submit = _("Selected media have been deleted.")
@@ -207,6 +213,7 @@ class ThemeCssAdmin(ThemeAssetsAdmin, generic.TargetedView):
 class MoveThemeCssUp(ThemeCssAdmin):
     def real_dispatch(self, request, theme, css):
         if request.method == "POST" and move_css_up(theme, css):
+            clear_theme_cache()
             messages.success(request, gettext('"%s" was moved up.') % css)
 
         return self.redirect_to_theme_assets(theme)
@@ -215,6 +222,7 @@ class MoveThemeCssUp(ThemeCssAdmin):
 class MoveThemeCssDown(ThemeCssAdmin):
     def real_dispatch(self, request, theme, css):
         if request.method == "POST" and move_css_down(theme, css):
+            clear_theme_cache()
             messages.success(request, gettext('"%s" was moved down.') % css)
 
         return self.redirect_to_theme_assets(theme)
@@ -246,6 +254,8 @@ class ThemeCssFormAdmin(ThemeCssAdmin, generic.ModelFormView):
         form.save()
         if css.source_needs_building:
             build_single_theme_css.delay(css.pk)
+        else:
+            clear_theme_cache()
         messages.success(request, self.message_submit % {"name": css.name})
 
 
@@ -288,6 +298,8 @@ class EditThemeCss(NewThemeCss):
             form.save()
             if css.source_needs_building:
                 build_single_theme_css.delay(css.pk)
+            else:
+                clear_theme_cache()
             messages.success(request, self.message_submit % {"name": css.name})
         else:
             message = gettext('No changes have been made to "%(css)s".')
@@ -311,6 +323,7 @@ class NewThemeCssLink(ThemeCssFormAdmin):
         super().handle_form(form, *args)
         if form.has_changed():
             update_remote_css_size.delay(form.instance.pk)
+            clear_theme_cache()
 
     def redirect_to_edit_form(self, theme, css):
         return redirect("misago:admin:appearance:themes:new-css-link", pk=theme.pk)