Source code for timApp.tests.server.test_macros

"""Server tests for macros."""
from timApp.auth.accesstype import AccessType
from timApp.document.specialnames import (
    TEMPLATE_FOLDER_NAME,
    PREAMBLE_FOLDER_NAME,
    DEFAULT_PREAMBLE_DOC,
)
from timApp.document.usercontext import UserContext
from timApp.document.viewcontext import default_view_ctx
from timApp.markdown.markdownconverter import md_to_html
from timApp.plugin.plugin import Plugin
from timApp.tests.db.timdbtest import TEST_USER_1_ID, TEST_USER_2_ID
from timApp.tests.server.timroutetest import TimRouteTest, get_content
from timApp.tim_app import app
from timApp.timdb.sqa import db
from timApp.user.user import User, UserInfo
from timApp.util.utils import decode_csplugin


[docs]class MacroTest(TimRouteTest):
[docs] def test_macro_doc(self): self.login_test1() doc = self.create_doc( settings={"macro_delimiter": "%%", "macros": {"rivi": "kerros"}} ).document table_text = """ {% set sarakeleveys = 50 %} {% set sarakkeet = ['eka', 'toka', 'kolmas', 'neljäs'] %} {% set rivit = ['eka', 'toka', 'kolmas', 'neljäs', 'viides'] %} {% for x in sarakkeet %} %%'-'*sarakeleveys%% {% endfor %} {% for r in rivit %} {% for s in sarakkeet %}%%('{} {}, {} sarake').format(r,rivi,s).rjust(sarakeleveys)%% {% endfor %} {% endfor %} {% for x in sarakkeet %} %%'-'*sarakeleveys%% {% endfor %} """ table_html = md_to_html(table_text, sanitize=True, macros={"rivi": "kerros"}) self.new_par(doc, table_text, json_key="texts", expect_contains=table_html) self.get(f"/view/{doc.doc_id}", expect_contains=table_html)
[docs] def test_user_macros(self): self.login_test1() d = self.create_doc( initial_par=r""" Username is %%username%% and real name is %%realname%% and email is %%useremail%% and logged name is %%loggedUsername%% and id is %%userid%% #- Percents: \%\% #- Broken: %% ``` {#test plugin="csPlugin"} type: cs header: %%username%% and %%realname%% ``` """ ) self.test_user_2.grant_access(d, AccessType.view) db.session.commit() pars = self.get(d.url, as_tree=True).cssselect(".parContent") self.assertEqual( f"Username is {self.test_user_1.name} and real name is {self.test_user_1.real_name} and email is {self.test_user_1.email} and logged name is {self.test_user_1.name} and id is {self.test_user_1.id}", pars[0].text_content().strip(), ) self.assertEqual("Percents: %%", pars[1].text_content().strip()) self.assertEqual( "Syntax error in macro template: unexpected 'end of template'", pars[2].text_content().strip(), ) p, _ = Plugin.from_task_id( f"{d.id}.test", UserContext.from_one_user(User.query.get(TEST_USER_1_ID)), default_view_ctx, ) self.assertEqual("testuser1 and Test user 1", p.values["header"]) self.login_test2() self.assertEqual( f"Username is {self.test_user_2.name} and real name is {self.test_user_2.real_name} and email is {self.test_user_2.email} and logged name is {self.test_user_2.name} and id is {self.test_user_2.id}", self.get(f"/view/{d.id}", as_tree=True) .cssselect(".parContent")[0] .text_content() .strip(), ) p, _ = Plugin.from_task_id( f"{d.id}.test", UserContext.from_one_user(User.query.get(TEST_USER_2_ID)), default_view_ctx, ) self.assertEqual("testuser2 and Test user 2", p.values["header"])
[docs] def test_user_nocache(self): self.login_test1() d = self.create_doc( initial_par=""" #- {nocache=true} I am %%username%%. """ ) self.assert_content(self.get(d.url, as_tree=True), ["I am testuser1."])
[docs] def test_macro_only_delimiter(self): self.login_test1() doc = self.create_doc(settings={"macro_delimiter": "%%"}).document self.new_par( doc, "{% set a = 123456+1 %}%%a%%", json_key="texts", expect_contains="123457", )
[docs] def test_null_macros(self): self.login_test1() d = self.create_doc( initial_par=""" ``` {plugin=showVideo} ``` """ ) d.document.set_settings({"macros": None}) r = self.get(d.url, as_tree=True).cssselect(".parContent tim-video") self.assertTrue(r)
[docs] def test_invalid_macros(self): self.login_test1() d = self.create_doc( initial_par=""" ``` {plugin=showVideo} ``` """ ) d.document.set_settings({"macros": "invalid"}) self.get(d.url) d.document.set_settings({"macros": {"a": {"b": "c"}}}) self.get(d.url)
[docs] def test_doc_macros(self): self.login_test1() d = self.create_doc() d.document.add_paragraph("%%docid%% %%docpath%%") e = self.get(d.url, as_tree=True) self.assert_content(e, [f"{d.id} {d.path}"])
[docs] def test_host_macros(self): self.login_test1() d = self.create_doc(initial_par="%%host%%") e = self.get(d.url, as_tree=True) self.assert_content(e, [app.config["TIM_HOST"]])
[docs] def test_globalmacros_with_reference(self): self.login_test1() pp = self.current_user.get_personal_folder().path d = self.create_doc( f"{pp}/a/b/d1", initial_par=""" this is a %%x()%% #- {plugin=csPlugin} type: cs stem: this is a %%x()%% """, settings={ "globalmacros": {"ADDFOREVERY": "{% macro x() %}cat{% endmacro %}"} }, ) self.create_doc( f"{pp}/a/{TEMPLATE_FOLDER_NAME}/{PREAMBLE_FOLDER_NAME}/{DEFAULT_PREAMBLE_DOC}", settings={ "globalmacros": {"ADDFOREVERY": "{% macro x() %}law{% endmacro %}"} }, ) d2 = self.create_doc(f"{pp}/a/c/d2", initial_par="""this is the %%x()%%""") p = d2.document.get_paragraphs()[0].create_reference(d.document) d.document.add_paragraph_obj(p) d.document.clear_mem_cache() tree = self.get(d.url, as_tree=True) pars = get_content(tree) self.assertEqual( pars[:-2] + pars[-1::], ["", "this is a cat", "this is the law"] ) plugins = tree.cssselect("cs-runner") self.assertEqual("this is a cat", decode_csplugin(plugins[0])["stem"])
[docs] def test_usermacro_in_plugin(self): """User-specific macros in plugins.""" self.login_test1() d = self.create_doc( initial_par=""" #- {plugin=csPlugin} type: cs stem: Hi, %%username%%! """ ) tree = self.get(d.url, as_tree=True) plugins = tree.cssselect("cs-runner") self.assertEqual("Hi, testuser1!", decode_csplugin(plugins[0])["stem"])
[docs] def test_addforevery_only_settings(self): self.login_test1() x = self.create_doc(self.get_personal_item_path("x/y")) d = self.create_preamble_for(x) d.document.add_text( """ #- {settings=""} #{% globalmacros: ADDFOREVERY: hi """ ) r = self.get(d.url, as_tree=True) self.assert_content(r, ["#{%\nglobalmacros:\n ADDFOREVERY: hi"])
[docs] def test_usermacros_no_xss(self): script = '<script>alert("hi")</script>' u, _ = User.create_with_group( UserInfo( username=script, full_name=script, email=script, ) ) db.session.commit() self.login(username=script) d = self.create_doc( initial_par="macros: %%username%% %%realname%% %%useremail%% %%doctitle%%", title=script, ) r = self.get(d.url) self.assertNotIn(script, r)