def test_theme_activation(): cache.init_cache() shop = get_default_shop() with override_provides("xtheme", [ "shuup_tests.xtheme.utils:FauxTheme", "shuup_tests.xtheme.utils:FauxTheme2" ]): set_current_theme(FauxTheme.identifier, shop) assert isinstance(get_current_theme(shop), FauxTheme) set_current_theme(FauxTheme2.identifier, shop) assert isinstance(get_current_theme(shop), FauxTheme2) with pytest.raises(ValueError): set_current_theme(printable_gibberish(), shop)
def test_theme_activation(): with override_current_theme_class(): with override_provides("xtheme", [ "shuup_tests.xtheme.utils:FauxTheme", "shuup_tests.xtheme.utils:FauxTheme2" ]): ThemeSettings.objects.all().delete() assert not get_current_theme() set_current_theme(FauxTheme.identifier) assert isinstance(get_current_theme(), FauxTheme) set_current_theme(FauxTheme2.identifier) assert isinstance(get_current_theme(), FauxTheme2) with pytest.raises(ValueError): set_current_theme(printable_gibberish())
def inject_global_snippet(context, content): if not valid_view(context): return from shuup.xtheme import get_current_theme from shuup.xtheme.models import Snippet, SnippetType shop = get_shop(context["request"]) cache_key = GLOBAL_SNIPPETS_CACHE_KEY.format(shop_id=shop.id) snippets = cache.get(cache_key) if snippets is None: snippets = Snippet.objects.filter(shop=shop) cache.set(cache_key, snippets) for snippet in snippets: if snippet.themes: current_theme = get_current_theme(shop) if current_theme and current_theme.identifier not in snippet.themes: continue content = snippet.snippet if snippet.snippet_type == SnippetType.InlineJS: content = InlineScriptResource(content) elif snippet.snippet_type == SnippetType.InlineCSS: content = InlineStyleResource(content) elif snippet.snippet_type == SnippetType.InlineHTMLMarkup: content = InlineMarkupResource(content) add_resource(context, snippet.location, content)
def process_request(self, request): shop = getattr(request, "shop", Shop.objects.first()) theme = get_current_theme(shop) if theme: theme.set_current() else: log.error((_("Shop '{}' has no active theme")).format(shop))
def inject_global_snippet(context, content): if not valid_view(context): return from shuup.xtheme import get_current_theme from shuup.xtheme.models import Snippet, SnippetType shop = get_shop(context["request"]) cache_key = GLOBAL_SNIPPETS_CACHE_KEY.format(shop_id=shop.id) snippets = cache.get(cache_key) if snippets is None: snippets = Snippet.objects.filter(shop=shop) cache.set(cache_key, snippets) for snippet in snippets: if snippet.themes: current_theme = get_current_theme(shop) if current_theme and current_theme.identifier not in snippet.themes: continue content = snippet.snippet if snippet.snippet_type == SnippetType.InlineJS: content = InlineScriptResource(content) elif snippet.snippet_type == SnippetType.InlineCSS: content = InlineStyleResource(content) elif snippet.snippet_type == SnippetType.InlineHTMLMarkup: content = InlineMarkupResource(content) elif snippet.snippet_type == SnippetType.InlineJinjaHTMLMarkup: context = dict(context.items()) # prevent recursive injection context["allow_resource_injection"] = False content = JinjaMarkupResource(content, context) add_resource(context, snippet.location, content)
def test_xtheme_snippet_injection(browser, admin_user, live_server, settings): shop = factories.get_default_shop() initialize_admin_browser_test(browser, live_server, settings) url = reverse("shuup_admin:xtheme_snippet.new") browser.visit("%s%s" % (live_server, url)) wait_until_condition(browser, lambda x: x.is_text_present("New Snippet")) browser.execute_script( "$(\"[name='location']\").val('body_end').trigger('change')") browser.execute_script( "$(\"[name='snippet_type']\").val('inline_js').trigger('change')") browser.execute_script( "window.CodeMirror.editors['id_snippet-snippet'].setValue('alert(\"works\")');" ) click_element(browser, "button[type='submit']") wait_until_appeared(browser, "div[class='message success']") url = reverse("shuup:index") browser.visit("%s%s" % (live_server, url)) def has_alert(browser): try: return browser.get_alert().text == "works" except: return False wait_until_condition(browser, has_alert) browser.get_alert().accept() theme = get_current_theme(shop) snippet = Snippet.objects.filter(shop=shop).first() snippet.themes = [theme.identifier] snippet.save() cache.clear() browser.visit("%s%s" % (live_server, url)) wait_until_condition(browser, has_alert) browser.get_alert().accept() snippet.themes = ["doesnt-exist"] snippet.save() cache.clear() browser.visit("%s%s" % (live_server, url)) wait_until_condition(browser, lambda x: x.is_text_present("Welcome to Default!")) with pytest.raises(Exception): browser.get_alert() # delete the snippet url = reverse("shuup_admin:xtheme_snippet.edit", kwargs=dict(pk=snippet.pk)) browser.visit("%s%s" % (live_server, url)) assert Snippet.objects.filter(shop=shop).exists() click_element(browser, ".shuup-toolbar button.btn.btn-danger") browser.get_alert().accept() wait_until_condition( browser, lambda x: not Snippet.objects.filter(shop=shop).exists())
def test_set_get_theme(rf): with override_provides("xtheme", [ "shuup_tests.xtheme.utils:FauxTheme", "shuup_tests.xtheme.utils:FauxTheme2" ]): shop1 = Shop.objects.create(identifier="shop1", domain="shop-1") shop2 = Shop.objects.create(identifier="shop2", domain="shop-test-2") assert get_current_theme(shop1) is None assert get_current_theme(shop2) is None set_current_theme(FauxTheme2.identifier, shop1) assert get_current_theme(shop1).identifier == FauxTheme2.identifier assert get_current_theme(shop1).settings_obj is not None set_current_theme(FauxTheme.identifier, shop2) assert get_current_theme(shop2).identifier == FauxTheme.identifier
def process_request(self, request): shop = getattr(request, "shop", get_shop(request)) theme = get_current_theme(shop) if theme: request.theme = theme theme.set_current() else: log.error((_("Shop '{}' has no active theme")).format(shop))
def test_theme_activation(): shop = get_default_shop() with override_current_theme_class(): with override_provides("xtheme", [ "shuup_tests.xtheme.utils:FauxTheme", "shuup_tests.xtheme.utils:FauxTheme2" ]): ThemeSettings.objects.all().delete() # ThemeSettings will be created on the fly theme = get_current_theme(shop) assert theme assert theme.settings_obj set_current_theme(FauxTheme.identifier, shop) assert isinstance(get_current_theme(shop), FauxTheme) set_current_theme(FauxTheme2.identifier, shop) assert isinstance(get_current_theme(shop), FauxTheme2) with pytest.raises(ValueError): set_current_theme(printable_gibberish(), shop)
def test_page_layout(): if "shuup.xtheme" not in settings.INSTALLED_APPS: pytest.skip("Need shuup.xtheme in INSTALLED_APPS") shop = factories.get_default_shop() theme = get_current_theme(shop) view_config = ViewConfig(theme=theme, shop=shop, view_name="PageView", draft=True) page1_content = printable_gibberish() page1 = create_page(available_from=datetime.date(1917, 12, 6), content=page1_content, shop=shop, url="test1") page2_content = printable_gibberish() page2 = create_page(available_from=datetime.date(1917, 12, 6), content=page2_content, shop=shop, url="test2") placeholder_name = "cms_page" context = {"page": page1} layout = view_config.get_placeholder_layout(PageLayout, placeholder_name, context=context) assert isinstance(layout, PageLayout) assert layout.get_help_text({}) == "" # Invalid context for help text assert page1.title in layout.get_help_text(context) # Make sure layout is empty serialized = layout.serialize() assert len(serialized["rows"]) == 0 assert serialized["name"] == placeholder_name # Add custom plugin to page layout.begin_column({"md": 8}) plugin_text = printable_gibberish() layout.add_plugin("text", {"text": plugin_text}) view_config.save_placeholder_layout( get_layout_data_key(placeholder_name, layout, context), layout) view_config.publish() c = SmartClient() soup = c.soup(reverse("shuup:cms_page", kwargs={"url": page1.url})) page_content = soup.find("div", {"class": "page-content"}) assert page1_content in page_content.text assert plugin_text in page_content.text c = SmartClient() soup = c.soup(reverse("shuup:cms_page", kwargs={"url": page2.url})) page_content = soup.find("div", {"class": "page-content"}) assert page2_content in page_content.text assert plugin_text not in page_content.text
def test_xtheme_snippet_injection(browser, admin_user, live_server, settings): shop = factories.get_default_shop() initialize_admin_browser_test(browser, live_server, settings) url = reverse("shuup_admin:xtheme_snippet.new") browser.visit("%s%s" % (live_server, url)) wait_until_condition(browser, lambda x: x.is_text_present("New Snippet")) browser.execute_script("$(\"[name='location']\").val('body_end').trigger('change')") browser.execute_script("$(\"[name='snippet_type']\").val('inline_js').trigger('change')") browser.execute_script("window.CodeMirror.editors['id_snippet-snippet'].setValue('alert(\"works\")');") click_element(browser, "button[type='submit']") wait_until_appeared(browser, "div[class='message success']") url = reverse("shuup:index") browser.visit("%s%s" % (live_server, url)) def has_alert(browser): try: return browser.get_alert().text == "works" except: return False wait_until_condition(browser, has_alert) browser.get_alert().accept() theme = get_current_theme(shop) snippet = Snippet.objects.filter(shop=shop).first() snippet.themes = [theme.identifier] snippet.save() cache.clear() browser.visit("%s%s" % (live_server, url)) wait_until_condition(browser, has_alert) browser.get_alert().accept() snippet.themes = ["doesnt-exist"] snippet.save() cache.clear() browser.visit("%s%s" % (live_server, url)) wait_until_condition(browser, lambda x: x.is_text_present("Welcome to Default!")) with pytest.raises(Exception): browser.get_alert() # delete the snippet url = reverse("shuup_admin:xtheme_snippet.edit", kwargs=dict(pk=snippet.pk)) browser.visit("%s%s" % (live_server, url)) assert Snippet.objects.filter(shop=shop).exists() click_element(browser, ".shuup-toolbar button.btn.btn-danger") browser.get_alert().accept() wait_until_condition(browser, lambda x: not Snippet.objects.filter(shop=shop).exists())
def inject_global_snippet(context, content): # noqa: C901 if not valid_view(context): return from shuup.xtheme import get_current_theme from shuup.xtheme.models import Snippet, SnippetType request = context["request"] shop = getattr(request, "shop", None) or get_shop(context["request"]) cache_key = GLOBAL_SNIPPETS_CACHE_KEY.format(shop_id=shop.id) snippets = cache.get(cache_key) if snippets is None: snippets = Snippet.objects.filter(shop=shop) cache.set(cache_key, snippets) for snippet in snippets: if snippet.themes: current_theme = getattr(request, "theme", None) or get_current_theme(shop) if current_theme and current_theme.identifier not in snippet.themes: continue snippet_blockers = get_provide_objects( "xtheme_snippet_blocker") # type: Iterable[SnippetBlocker] blocked = False for snippet_blocker in snippet_blockers: if snippet_blocker.should_block_global_snippet_injection( snippet, context): blocked = True break if blocked: continue content = snippet.snippet if snippet.snippet_type == SnippetType.InlineJS: content = InlineScriptResource(content) elif snippet.snippet_type == SnippetType.InlineCSS: content = InlineStyleResource(content) elif snippet.snippet_type == SnippetType.InlineHTMLMarkup: content = InlineMarkupResource(content) elif snippet.snippet_type == SnippetType.InlineJinjaHTMLMarkup: context = dict(context.items()) # prevent recursive injection context["allow_resource_injection"] = False content = JinjaMarkupResource(content, context) add_resource(context, snippet.location, content)
def test_page_layout(): if "shuup.xtheme" not in settings.INSTALLED_APPS: pytest.skip("Need shuup.xtheme in INSTALLED_APPS") shop = factories.get_default_shop() theme = get_current_theme(shop) view_config = ViewConfig(theme=theme, shop=shop, view_name="PageView", draft=True) page1_content = printable_gibberish() page1 = create_page(available_from=datetime.date(1917, 12, 6), content=page1_content, shop=shop, url="test1") page2_content = printable_gibberish() page2 = create_page(available_from=datetime.date(1917, 12, 6), content=page2_content, shop=shop, url="test2") placeholder_name = "cms_page" context = {"page": page1} layout = view_config.get_placeholder_layout(PageLayout, placeholder_name, context=context) assert isinstance(layout, PageLayout) assert layout.get_help_text({}) == "" # Invalid context for help text assert page1.title in layout.get_help_text(context) # Make sure layout is empty serialized = layout.serialize() assert len(serialized["rows"]) == 0 assert serialized["name"] == placeholder_name # Add custom plugin to page layout.begin_column({"md": 8}) plugin_text = printable_gibberish() layout.add_plugin("text", {"text": plugin_text}) view_config.save_placeholder_layout(get_layout_data_key(placeholder_name, layout, context), layout) view_config.publish() c = SmartClient() soup = c.soup(reverse("shuup:cms_page", kwargs={"url": page1.url})) page_content = soup.find("div", {"class": "page-content"}) assert page1_content in page_content.text assert plugin_text in page_content.text c = SmartClient() soup = c.soup(reverse("shuup:cms_page", kwargs={"url": page2.url})) page_content = soup.find("div", {"class": "page-content"}) assert page2_content in page_content.text assert plugin_text not in page_content.text
def test_plugin(): shop = factories.get_default_shop() set_current_theme(ClassicGrayTheme.identifier, shop) blog_page = Page.objects.create(shop=shop, title="Blog", url="blog", available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="") # create 10 blog pages for i in range(10): article = Page.objects.create( shop=shop, title="Article %d" % i, url="blog-%d" % i, available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="Content %d" % i, template_name="shuup_cms_blog/blog_page.jinja") BlogArticle.objects.create(page=article, is_blog_article=True, image=factories.get_random_filer_image(), small_description="description %d" % i) # create 3 non blog post pages for i in range(3): article = Page.objects.create( shop=shop, title="Nothing %d" % i, url="non-%d" % i, available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="content %i" % i) theme = get_current_theme(shop) view_config = ViewConfig(theme=theme, shop=shop, view_name="PageView", draft=True) placeholder_name = "cms_page" context = {"page": blog_page} layout = view_config.get_placeholder_layout(PageLayout, placeholder_name, context=context) assert isinstance(layout, PageLayout) assert layout.get_help_text({}) == "" assert blog_page.title in layout.get_help_text(context) serialized = layout.serialize() assert len(serialized["rows"]) == 0 assert serialized["name"] == placeholder_name layout.begin_column({"sm": 12}) layout.add_plugin(ShuupCMSBlogArticleListPlugin.identifier, {}) view_config.save_placeholder_layout( get_layout_data_key(placeholder_name, layout, context), layout) view_config.publish() client = SmartClient() response, soup = client.response_and_soup( reverse("shuup:cms_page", kwargs={"url": blog_page.url})) assert response.status_code == 200 assert len(soup.find_all("a", {"class": "article-card"})) == 10
def test_plugin(): shop = factories.get_default_shop() set_current_theme(ClassicGrayTheme.identifier, shop) blog_one_page = Page.objects.create( shop=shop, title="Blog One", url="blog_one", available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="") blog_two_page = Page.objects.create( shop=shop, title="Blog Two", url="blog_two", available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="") # create 10 blog pages for page in [blog_one_page, blog_two_page]: for i in range(10): article = Page.objects.create( shop=shop, title="Article %d %s" % (i, page.title), url="blog-%d-%s" % (i, page.url), available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="Content %d" % i, template_name="shuup_cms_blog/blog_page.jinja", parent=page) BlogArticle.objects.create( page=article, is_blog_article=True, image=factories.get_random_filer_image(), small_description="description %d" % i) # create 3 non blog post pages for i in range(3): article = Page.objects.create( shop=shop, title="Nothing %d" % i, url="non-%d" % i, available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="content %i" % i) theme = get_current_theme(shop) view_config = ViewConfig(theme=theme, shop=shop, view_name="PageView", draft=True) placeholder_name = "cms_page" context_one = {"page": blog_one_page} context_two = {"page": blog_two_page} layout_one = view_config.get_placeholder_layout(PageLayout, placeholder_name, context=context_one) layout_two = view_config.get_placeholder_layout(PageLayout, placeholder_name, context=context_two) assert isinstance(layout_one, PageLayout) assert isinstance(layout_two, PageLayout) assert layout_one.get_help_text({}) == "" assert layout_two.get_help_text({}) == "" assert blog_one_page.title in layout_two.get_help_text(context_one) assert blog_two_page.title in layout_two.get_help_text(context_two) serialized_one = layout_one.serialize() serialized_two = layout_two.serialize() assert len(serialized_one["rows"]) == 0 assert len(serialized_two["rows"]) == 0 assert serialized_one["name"] == placeholder_name assert serialized_two["name"] == placeholder_name layout_one.begin_column({"sm": 12}) layout_two.begin_column({"sm": 12}) layout_one.add_plugin(ShuupCMSBlogArticleListPlugin.identifier, {"blog_page": blog_one_page.pk}) layout_two.add_plugin(ShuupCMSBlogArticleListPlugin.identifier, {"blog_page": blog_two_page.pk}) view_config.save_placeholder_layout( get_layout_data_key(placeholder_name, layout_one, context_one), layout_one) view_config.save_placeholder_layout( get_layout_data_key(placeholder_name, layout_two, context_two), layout_two) view_config.publish() client = SmartClient() response, soup = client.response_and_soup( reverse("shuup:cms_page", kwargs={"url": blog_one_page.url})) assert response.status_code == 200 assert len(soup.find_all("a", {"class": "article-card"})) == 10 response, soup = client.response_and_soup( reverse("shuup:cms_page", kwargs={"url": blog_two_page.url})) assert response.status_code == 200 assert len(soup.find_all("a", {"class": "article-card"})) == 10 article_one = Page.objects.create( shop=shop, title="Article test", url="blog-test", available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="Content test", template_name= "shuup_cms_blog/blog_page.jinja", # Add an article without a parent ) BlogArticle.objects.create(page=article_one, is_blog_article=True, image=factories.get_random_filer_image(), small_description="description test") article_two = Page.objects.create( shop=shop, title="Article test 2", url="blog-test-2", available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="Content test 2", template_name= "shuup_cms_blog/blog_page.jinja", # Add an article without a parent ) BlogArticle.objects.create(page=article_two, is_blog_article=True, image=factories.get_random_filer_image(), small_description="description test 2") view_config = ViewConfig(theme=theme, shop=shop, view_name="PageView", draft=True) # No blog page set means that only articles with no parent will be shown layout_two.add_plugin(ShuupCMSBlogArticleListPlugin.identifier, {}) view_config.save_placeholder_layout( get_layout_data_key(placeholder_name, layout_two, context_two), layout_two) view_config.publish() response, soup = client.response_and_soup( reverse("shuup:cms_page", kwargs={"url": blog_two_page.url})) assert response.status_code == 200 assert len(soup.find_all("a", {"class": "article-card"})) == 2 response, soup = client.response_and_soup( reverse("shuup:cms_page", kwargs={"url": article_one.url})) assert response.status_code == 200 assert len(soup.find_all("a", {"class": "article-card"})) == 1 assert soup.find("div", { "class": "article-title" }).text == article_two.title article_one.soft_delete() # Delete the article that has no parent article_two.soft_delete() # Delete the article that has no parent response, soup = client.response_and_soup( reverse("shuup:cms_page", kwargs={"url": blog_two_page.url})) assert response.status_code == 200 assert len(soup.find_all("a", {"class": "article-card"})) == 0 article_with_parent = Page.objects.filter(parent=blog_one_page).first() response, soup = client.response_and_soup( reverse("shuup:cms_page", kwargs={"url": article_with_parent.url})) assert response.status_code == 200 assert len(soup.find_all( "a", {"class": "article-card"})) == 9 # Assert there are 9 articles shown article_card_titles = soup.find_all("div", {"class": "article-title"}) article_card_titles = [title.text for title in article_card_titles] # Assert that the current visited article (article_with_parent) is not visible in Related articles assert article_with_parent.title not in article_card_titles
def _get_basic_view_config(view_name="pow"): shop = factories.get_default_shop() theme = get_current_theme(shop) return ViewConfig(theme=theme, shop=shop, view_name=view_name, draft=True)