__init__.py 7.5KB

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