__init__.py 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. # -*- coding: utf-8 -*-
  2. import unittest
  3. import plaster
  4. import requests
  5. import transaction
  6. from depot.manager import DepotManager
  7. from pyramid import testing
  8. from sqlalchemy.exc import IntegrityError
  9. from tracim.lib.core.content import ContentApi
  10. from tracim.lib.core.workspace import WorkspaceApi
  11. from tracim.models import get_engine
  12. from tracim.models import DeclarativeBase
  13. from tracim.models import get_session_factory
  14. from tracim.models import get_tm_session
  15. from tracim.models.data import Workspace
  16. from tracim.models.data import ContentType
  17. from tracim.models.data import ContentRevisionRO
  18. from tracim.models.data import Content
  19. from tracim.lib.utils.logger import logger
  20. from tracim.fixtures import FixturesLoader
  21. from tracim.fixtures.users_and_groups import Base as BaseFixture
  22. from tracim.config import CFG
  23. from tracim.extensions import hapic
  24. from tracim import web
  25. from webtest import TestApp
  26. def eq_(a, b, msg=None):
  27. # TODO - G.M - 05-04-2018 - Remove this when all old nose code is removed
  28. assert a == b, msg or "%r != %r" % (a, b)
  29. # TODO - G.M - 2018-06-179 - Refactor slug change function
  30. # as a kind of pytest fixture ?
  31. def set_html_document_slug_to_legacy(session_factory) -> None:
  32. """
  33. Simple function to help some functional test. This modify "html-documents"
  34. type content in database to legacy "page" slug.
  35. :param session_factory: session factory of the test
  36. :return: Nothing.
  37. """
  38. dbsession = get_tm_session(
  39. session_factory,
  40. transaction.manager
  41. )
  42. content_query = dbsession.query(ContentRevisionRO).filter(ContentRevisionRO.type == 'page').filter(ContentRevisionRO.content_id == 6) # nopep8
  43. assert content_query.count() == 0
  44. html_documents_query = dbsession.query(ContentRevisionRO).filter(ContentRevisionRO.type == 'html-documents') # nopep8
  45. html_documents_query.update({ContentRevisionRO.type: 'page'})
  46. transaction.commit()
  47. assert content_query.count() > 0
  48. class FunctionalTest(unittest.TestCase):
  49. fixtures = [BaseFixture]
  50. sqlalchemy_url = 'sqlite:///tracim_test.sqlite'
  51. def setUp(self):
  52. logger._logger.setLevel('WARNING')
  53. DepotManager._clear()
  54. self.settings = {
  55. 'sqlalchemy.url': self.sqlalchemy_url,
  56. 'user.auth_token.validity': '604800',
  57. 'depot_storage_dir': '/tmp/test/depot',
  58. 'depot_storage_name': 'test',
  59. 'preview_cache_dir': '/tmp/test/preview_cache',
  60. 'email.notification.activated': 'false',
  61. }
  62. hapic.reset_context()
  63. self.engine = get_engine(self.settings)
  64. DeclarativeBase.metadata.create_all(self.engine)
  65. self.session_factory = get_session_factory(self.engine)
  66. self.app_config = CFG(self.settings)
  67. self.app_config.configure_filedepot()
  68. self.init_database(self.settings)
  69. DepotManager._clear()
  70. self.run_app()
  71. def run_app(self):
  72. app = web({}, **self.settings)
  73. self.testapp = TestApp(app)
  74. def init_database(self, settings):
  75. with transaction.manager:
  76. dbsession = get_tm_session(self.session_factory, transaction.manager)
  77. try:
  78. fixtures_loader = FixturesLoader(dbsession, self.app_config)
  79. fixtures_loader.loads(self.fixtures)
  80. transaction.commit()
  81. print("Database initialized.")
  82. except IntegrityError:
  83. print('Warning, there was a problem when adding default data'
  84. ', it may have already been added:')
  85. import traceback
  86. print(traceback.format_exc())
  87. transaction.abort()
  88. print('Database initialization failed')
  89. def tearDown(self):
  90. logger.debug(self, 'TearDown Test...')
  91. from tracim.models.meta import DeclarativeBase
  92. testing.tearDown()
  93. transaction.abort()
  94. DeclarativeBase.metadata.drop_all(self.engine)
  95. DepotManager._clear()
  96. class FunctionalTestEmptyDB(FunctionalTest):
  97. fixtures = []
  98. class FunctionalTestNoDB(FunctionalTest):
  99. sqlalchemy_url = 'sqlite://'
  100. def init_database(self, settings):
  101. self.engine = get_engine(settings)
  102. class CommandFunctionalTest(FunctionalTest):
  103. def run_app(self):
  104. self.session = get_tm_session(self.session_factory, transaction.manager)
  105. class BaseTest(unittest.TestCase):
  106. """
  107. Pyramid default test.
  108. """
  109. config_uri = 'tests_configs.ini'
  110. config_section = 'base_test'
  111. def setUp(self):
  112. logger._logger.setLevel('WARNING')
  113. logger.debug(self, 'Setup Test...')
  114. self.settings = plaster.get_settings(
  115. self.config_uri,
  116. self.config_section
  117. )
  118. self.config = testing.setUp(settings = self.settings)
  119. self.config.include('tracim.models')
  120. DepotManager._clear()
  121. DepotManager.configure(
  122. 'test', {'depot.backend': 'depot.io.memory.MemoryFileStorage'}
  123. )
  124. settings = self.config.get_settings()
  125. self.app_config = CFG(settings)
  126. from tracim.models import (
  127. get_engine,
  128. get_session_factory,
  129. get_tm_session,
  130. )
  131. self.engine = get_engine(settings)
  132. session_factory = get_session_factory(self.engine)
  133. self.session = get_tm_session(session_factory, transaction.manager)
  134. self.init_database()
  135. def init_database(self):
  136. logger.debug(self, 'Init Database Schema...')
  137. from tracim.models.meta import DeclarativeBase
  138. DeclarativeBase.metadata.create_all(self.engine)
  139. def tearDown(self):
  140. logger.debug(self, 'TearDown Test...')
  141. from tracim.models.meta import DeclarativeBase
  142. testing.tearDown()
  143. transaction.abort()
  144. DeclarativeBase.metadata.drop_all(self.engine)
  145. class StandardTest(BaseTest):
  146. """
  147. BaseTest with default fixtures
  148. """
  149. fixtures = [BaseFixture]
  150. def init_database(self):
  151. BaseTest.init_database(self)
  152. fixtures_loader = FixturesLoader(
  153. session=self.session,
  154. config=CFG(self.config.get_settings()))
  155. fixtures_loader.loads(self.fixtures)
  156. class DefaultTest(StandardTest):
  157. def _create_workspace_and_test(self, name, user) -> Workspace:
  158. """
  159. All extra parameters (*args, **kwargs) are for Workspace init
  160. :return: Created workspace instance
  161. """
  162. WorkspaceApi(
  163. current_user=user,
  164. session=self.session,
  165. config=self.app_config,
  166. ).create_workspace(name, save_now=True)
  167. eq_(
  168. 1,
  169. self.session.query(Workspace).filter(
  170. Workspace.label == name
  171. ).count()
  172. )
  173. return self.session.query(Workspace).filter(
  174. Workspace.label == name
  175. ).one()
  176. def _create_content_and_test(
  177. self,
  178. name,
  179. workspace,
  180. *args,
  181. **kwargs
  182. ) -> Content:
  183. """
  184. All extra parameters (*args, **kwargs) are for Content init
  185. :return: Created Content instance
  186. """
  187. content = Content(*args, **kwargs)
  188. content.label = name
  189. content.workspace = workspace
  190. self.session.add(content)
  191. self.session.flush()
  192. content_api = ContentApi(
  193. current_user=None,
  194. session=self.session,
  195. config=self.app_config,
  196. )
  197. eq_(
  198. 1,
  199. content_api.get_canonical_query().filter(
  200. Content.label == name
  201. ).count()
  202. )
  203. return content_api.get_canonical_query().filter(
  204. Content.label == name
  205. ).one()
  206. def _create_thread_and_test(self,
  207. user,
  208. workspace_name='workspace_1',
  209. folder_name='folder_1',
  210. thread_name='thread_1') -> Content:
  211. """
  212. :return: Thread
  213. """
  214. workspace = self._create_workspace_and_test(workspace_name, user)
  215. folder = self._create_content_and_test(
  216. folder_name, workspace,
  217. type=ContentType.Folder,
  218. owner=user
  219. )
  220. thread = self._create_content_and_test(
  221. thread_name,
  222. workspace,
  223. type=ContentType.Thread,
  224. parent=folder,
  225. owner=user
  226. )
  227. return thread
  228. class MailHogTest(DefaultTest):
  229. """
  230. Theses test need a working mailhog
  231. """
  232. config_section = 'mail_test'
  233. def tearDown(self):
  234. logger.debug(self, 'Cleanup MailHog list...')
  235. requests.delete('http://127.0.0.1:8025/api/v1/messages')