__init__.py 7.1KB

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