PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/trac/wiki/tests/web_ui.py

https://github.com/edgewall/trac
Python | 222 lines | 180 code | 25 blank | 17 comment | 6 complexity | c18a6462268fc46aff9989ad4ea915de MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. #
  3. # Copyright (C) 2016-2022 Edgewall Software
  4. # All rights reserved.
  5. #
  6. # This software is licensed as described in the file COPYING, which
  7. # you should have received as part of this distribution. The terms
  8. # are also available at https://trac.edgewall.org/wiki/TracLicense.
  9. #
  10. # This software consists of voluntary contributions made by many
  11. # individuals. For the exact contribution history, see the revision
  12. # history and logs, available at https://trac.edgewall.org/log/.
  13. import re
  14. import unittest
  15. from trac.perm import DefaultPermissionStore, PermissionCache
  16. from trac.test import EnvironmentStub, MockRequest
  17. from trac.web.api import HTTPBadRequest, RequestDone
  18. from trac.web.chrome import Chrome
  19. from trac.wiki.model import WikiPage
  20. from trac.wiki.web_ui import DefaultWikiPolicy, WikiModule
  21. class DefaultWikiPolicyTestCase(unittest.TestCase):
  22. def setUp(self):
  23. self.env = \
  24. EnvironmentStub(enable=['trac.attachment.LegacyAttachmentPolicy',
  25. 'trac.perm.*',
  26. 'trac.wiki.web_ui.*'])
  27. self.env.config.set('trac', 'permission_policies',
  28. 'DefaultWikiPolicy,DefaultPermissionPolicy')
  29. self.policy = DefaultWikiPolicy(self.env)
  30. store = DefaultPermissionStore(self.env)
  31. store.grant_permission('user1', 'WIKI_ADMIN')
  32. store.grant_permission('user2', 'WIKI_DELETE')
  33. store.grant_permission('user2', 'WIKI_MODIFY')
  34. store.grant_permission('user2', 'WIKI_RENAME')
  35. self.page = WikiPage(self.env, 'SomePage')
  36. self.page.text = 'This is a readonly page.'
  37. self.page.readonly = 1
  38. self.page.save('user', 'readonly page added')
  39. def test_user_with_wiki_admin_can_modify_readonly_page(self):
  40. """User with WIKI_ADMIN cannot modify a readonly page."""
  41. perm_cache = PermissionCache(self.env, 'user1', self.page.resource)
  42. self.assertIn('WIKI_ADMIN', perm_cache)
  43. for perm in ('WIKI_DELETE', 'WIKI_MODIFY', 'WIKI_RENAME'):
  44. self.assertIn(perm, perm_cache)
  45. self.assertIsNone(
  46. self.policy.check_permission(perm, perm_cache.username,
  47. self.page.resource, perm_cache))
  48. def test_user_without_wiki_admin_cannot_modify_readonly_page(self):
  49. """User without WIKI_ADMIN cannot modify a readonly page."""
  50. perm_cache = PermissionCache(self.env, 'user2', self.page.resource)
  51. self.assertNotIn('WIKI_ADMIN', perm_cache)
  52. for perm in ('WIKI_DELETE', 'WIKI_MODIFY', 'WIKI_RENAME'):
  53. self.assertNotIn(perm, perm_cache)
  54. self.assertFalse(
  55. self.policy.check_permission(perm, perm_cache.username,
  56. self.page.resource, perm_cache))
  57. class WikiModuleTestCase(unittest.TestCase):
  58. def setUp(self):
  59. self.env = EnvironmentStub()
  60. def _insert_templates(self):
  61. page = WikiPage(self.env)
  62. page.name = 'PageTemplates/TheTemplate'
  63. page.text = 'The template below /PageTemplates'
  64. page.save('trac', 'create page')
  65. page = WikiPage(self.env)
  66. page.name = 'TheTemplate'
  67. page.text = 'The template below /'
  68. page.save('trac', 'create page')
  69. def tearDown(self):
  70. self.env.reset_db()
  71. def test_invalid_post_request_raises_exception(self):
  72. req = MockRequest(self.env, method='POST', action=None)
  73. self.assertRaises(HTTPBadRequest,
  74. WikiModule(self.env).process_request, req)
  75. def test_invalid_get_request_raises_exception(self):
  76. req = MockRequest(self.env, method='GET', action=None,
  77. args=dict(version='a', old_version='1'))
  78. with self.assertRaises(HTTPBadRequest) as cm:
  79. WikiModule(self.env).process_request(req)
  80. self.assertEqual("400 Bad Request (Invalid value for request argument "
  81. "<em>version</em>.)", str(cm.exception))
  82. req = MockRequest(self.env, method='GET', action=None,
  83. args=dict(version='2', old_version='a'))
  84. with self.assertRaises(HTTPBadRequest) as cm:
  85. WikiModule(self.env).process_request(req)
  86. self.assertEqual("400 Bad Request (Invalid value for request argument "
  87. "<em>old_version</em>.)", str(cm.exception))
  88. def test_wiki_template_relative_path(self):
  89. self._insert_templates()
  90. req = MockRequest(self.env, path_info='/wiki/NewPage', method='GET',
  91. args={'action': 'edit', 'page': 'NewPage',
  92. 'template': 'TheTemplate'})
  93. resp = WikiModule(self.env).process_request(req)
  94. self.assertEqual('The template below /PageTemplates',
  95. resp[1]['page'].text)
  96. def test_wiki_template_absolute_path(self):
  97. self._insert_templates()
  98. req = MockRequest(self.env, path_info='/wiki/NewPage', method='GET',
  99. args={'action': 'edit', 'page': 'NewPage',
  100. 'template': '/TheTemplate'})
  101. resp = WikiModule(self.env).process_request(req)
  102. self.assertEqual('The template below /', resp[1]['page'].text)
  103. def test_edit_action_with_empty_verion(self):
  104. """Universal edit button requires request with parameters string
  105. ?action=edit&version= and ?action=view&version= (#12937)
  106. """
  107. req = MockRequest(self.env, path_info='/wiki/NewPage', method='GET',
  108. args={'action': 'view', 'version': '',
  109. 'page': 'NewPage'})
  110. resp = WikiModule(self.env).process_request(req)
  111. self.assertEqual('wiki_view.html', resp[0])
  112. self.assertIsNone(resp[1]['version'])
  113. self.assertEqual('NewPage', resp[1]['page'].name)
  114. req = MockRequest(self.env, path_info='/wiki/NewPage', method='GET',
  115. args={'action': 'edit', 'version': '',
  116. 'page': 'NewPage'})
  117. resp = WikiModule(self.env).process_request(req)
  118. self.assertEqual('wiki_edit.html', resp[0])
  119. self.assertNotIn('version', resp[1])
  120. self.assertEqual('NewPage', resp[1]['page'].name)
  121. def test_wiki_page_path(self):
  122. for name in ('WikiStart', 'Page', 'Page/SubPage'):
  123. page = WikiPage(self.env)
  124. page.name = name
  125. page.text = 'Contents for %s\n' % name
  126. page.save('trac', 'create page')
  127. def get_pagepath(path_info):
  128. content = self._render_wiki_page(path_info)
  129. match = re.search(r'<div\s+id="pagepath"[^>]*>.*?</div>', content,
  130. re.DOTALL)
  131. return match and match.group(0)
  132. pagepath = get_pagepath('/wiki')
  133. self.assertIn(' href="/trac.cgi/wiki">wiki:</a>', pagepath)
  134. self.assertIn(' href="/trac.cgi/wiki/WikiStart"', pagepath)
  135. pagepath = get_pagepath('/wiki/Page')
  136. self.assertIn(' href="/trac.cgi/wiki">wiki:</a>', pagepath)
  137. self.assertIn(' href="/trac.cgi/wiki/Page"', pagepath)
  138. pagepath = get_pagepath('/wiki/Page/SubPage')
  139. self.assertIn(' href="/trac.cgi/wiki">wiki:</a>', pagepath)
  140. self.assertIn(' href="/trac.cgi/wiki/Page"', pagepath)
  141. self.assertIn(' href="/trac.cgi/wiki/Page/SubPage"', pagepath)
  142. def test_delete_page(self):
  143. page = WikiPage(self.env)
  144. page.name = 'SandBox'
  145. page.text = 'Contents for SandBox'
  146. page.save('trac', 'create page')
  147. mod = WikiModule(self.env)
  148. req = MockRequest(self.env, path_info='/wiki/SandBox', method='GET',
  149. args={'action': 'delete', 'version': '1'})
  150. self.assertTrue(mod.match_request(req))
  151. resp = mod.process_request(req)
  152. self.assertEqual(2, len(resp))
  153. self.assertIn('Are you sure you want to completely delete this page?',
  154. self._render_template(req, resp[0], resp[1]))
  155. req = MockRequest(self.env, path_info='/wiki/SandBox', method='POST',
  156. args={'action': 'delete'})
  157. self.assertTrue(mod.match_request(req))
  158. self.assertRaises(RequestDone, mod.process_request, req)
  159. self.assertIn('The page SandBox has been deleted.',
  160. req.chrome.get('notices'))
  161. self.assertEqual(False, WikiPage(self.env, 'SandBox').exists)
  162. def _render_template(self, req, template, data):
  163. content = Chrome(self.env).render_template(req, template, data,
  164. {'iterable': False,
  165. 'fragment': False})
  166. return content.decode('utf-8')
  167. def _render_wiki_page(self, path_info):
  168. req = MockRequest(self.env, path_info=path_info, method='GET')
  169. mod = WikiModule(self.env)
  170. self.assertTrue(mod.match_request(req))
  171. resp = mod.process_request(req)
  172. self.assertEqual(2, len(resp))
  173. return self._render_template(req, resp[0], resp[1])
  174. def test_suite():
  175. suite = unittest.TestSuite()
  176. suite.addTest(unittest.makeSuite(DefaultWikiPolicyTestCase))
  177. suite.addTest(unittest.makeSuite(WikiModuleTestCase))
  178. return suite
  179. if __name__ == '__main__':
  180. unittest.main(defaultTest='test_suite')