Source code for timApp.tests.server.test_caching

"""Server tests for document caching."""
import re
from unittest.mock import patch, Mock

from timApp.auth.accesstype import AccessType
from timApp.document.caching import clear_doc_cache
from timApp.document.docentry import DocEntry
from timApp.item import routes
from timApp.item.routes import render_doc_view
from timApp.tests.server.timroutetest import TimRouteTest, get_note_id_from_json
from timApp.timdb.sqa import db
from timApp.user.usergroup import UserGroup
from timApp.user.userutils import grant_access


[docs]class CachingTest(TimRouteTest):
[docs] def test_cache(self): self.login_test1() d = self.create_doc(initial_par="#- {plugin=textfield #t}") self.test_user_2.grant_access(d, AccessType.view) self.test_user_3.grant_access(d, AccessType.view) db.session.commit() clear_doc_cache(d, None) self.login_test3() self.check_not_cached(d) self.check_not_cached(d) # cache is disabled by default d.document.set_settings({"cache": True}) self.check_not_cached(d) # was not in cache, added to cache def normalize(s: str) -> str: # Remove modified date as it can be slightly different depending on CI speed return re.sub(r'"modified": "[^"]+"', r'"modified": "X"', s) last = normalize(self.last_get) self.check_is_cached(d) # was in cache, fetched from cache # Cached result should be the same as not cached. self.assertEqual(last, normalize(self.last_get)) self.check_is_cached(d) # still in cache self.check_is_cached( d, {"unlock": True} ) # value of unlock shouldn't affect caching self.check_not_cached(d, {"nocache": True}) # nocache should clear the cache self.check_not_cached(d, {"nocache": True}) # make sure nocache is not cached self.check_is_cached(d) self.post_answer("textfield", f"{d.id}.t", user_input={"c": "x"}) self.check_not_cached_and_then_cached(d) par = d.document.get_paragraphs()[0] self.mark_as_read(d, par.get_id()) self.check_not_cached_and_then_cached(d) self.login_test2() self.check_not_cached_and_then_cached(d) self.login_test3() c = self.post_comment(par, public=False, text="test") nid = get_note_id_from_json(c) self.check_not_cached_and_then_cached(d) self.login_test2() self.check_is_cached(d) self.login_test3() self.edit_comment(nid, par, True, "test2") self.check_not_cached_and_then_cached(d) self.login_test2() self.check_not_cached_and_then_cached(d) self.login_test3() self.edit_comment(nid, par, False, "test2") self.check_not_cached_and_then_cached(d) self.login_test2() self.check_not_cached_and_then_cached(d)
[docs] def check_not_cached_and_then_cached(self, d, query=None): self.check_not_cached(d, query) self.check_is_cached(d, query)
[docs] def check_is_cached(self, d, query=None): self.get_with_patch(d, query).assert_not_called()
[docs] def check_not_cached(self, d, query=None): self.get_with_patch(d, query).assert_called_once()
[docs] def get_with_patch(self, d, query=None): with patch.object( routes, render_doc_view.__name__, wraps=render_doc_view ) as m: # type: Mock self.last_get = self.get(d.url, query_string=query) return m
[docs] def test_cache_pregenerate(self): self.login_test1() d = self.create_doc(initial_par="test") self.test_user_2.grant_access(d, AccessType.view) db.session.commit() clear_doc_cache(d, None) self.get( f"/generateCache/{d.path}", expect_status=400, expect_content="Document does not have caching enabled.", ) d.document.set_settings({"cache": True}) self.get( f"/generateCache/{d.path}", expect_content=""" 1/2 testuser1: ok 2/2 testuser2: ok """.strip() + "\n", ) self.get( f"/generateCache/{d.path}", expect_content=""" 1/2 testuser1: already cached 2/2 testuser2: already cached """.strip() + "\n", ) self.check_is_cached(d) self.get( f"/generateCache/{d.path}", # TODO enable this test. We need two users with only view right. # testuser1 and 2 have different rights so there will be differences in the HTML. # query_string={'print_diffs': True}, expect_content=""" 1/2 testuser1: already cached 2/2 testuser2: already cached """.strip() + "\n", ) ug = UserGroup.create("testgroup1") self.test_user_3.add_to_group(ug, added_by=None) grant_access(ug, d, AccessType.view) db.session.commit() d = DocEntry.find_by_id(d.id) db.session.refresh(d) self.get( f"/generateCache/{d.path}", expect_status=403, expect_content="No access for group testgroup1", ) # When running all server tests in IDE (PyCharm), the tests start failing in test_clipboard with # sqlalchemy.orm.exc.FlushError in initialize_database. Refreshing the test client prevents it. # The line self.test_user_3.add_to_group seems to trigger the error. self.refresh_client()
[docs] def test_cache_generate_exam_mode(self): self.login_test1() d = self.create_doc(settings={"exam_mode": "view", "cache": True}) # The nocache is just for making sure there's no previous doc cache when rerunning this same test from IDE. # The doc id is always the same because the DB starts fresh. self.get(d.url, query_string={"nocache": True}) self.test_user_2.grant_access(d, AccessType.view) db.session.commit() self.get( f"/generateCache/{d.path}", ) self.login_test2() r = self.get(d.url, as_tree=True) self.assert_js_variable(r, "exam_mode", True) rights = self.get_js_variable(r, "curr_item")["rights"] self.assertEqual( { "browse_own_answers": True, "can_comment": True, "can_mark_as_read": True, "copy": False, "editable": False, "manage": False, "owner": False, "see_answers": False, "teacher": False, }, rights, ) rights = self.get_js_variable(r, "translations")[0]["rights"] self.assertEqual( { "browse_own_answers": True, "can_comment": True, "can_mark_as_read": True, "copy": False, "editable": False, "manage": False, "owner": False, "see_answers": False, "teacher": False, }, rights, )