__init__.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. # -*- coding: utf-8 -*-
  2. #
  3. # This file is part of Radicale Server - Calendar Server
  4. # Copyright © 2012-2013 Guillaume Ayoub
  5. #
  6. # This library is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This library is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with Radicale. If not, see <http://www.gnu.org/licenses/>.
  18. """
  19. Tests for Radicale.
  20. """
  21. import base64
  22. import hashlib
  23. import os
  24. import shutil
  25. import sys
  26. import tempfile
  27. from dulwich.repo import Repo
  28. from io import BytesIO
  29. sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
  30. import radicale
  31. RADICALE_CONFIG = os.path.join(os.path.dirname(os.path.dirname(__file__)),
  32. "config")
  33. os.environ["RADICALE_CONFIG"] = RADICALE_CONFIG
  34. from radicale import config
  35. from radicale.auth import htpasswd
  36. from radicale.storage import filesystem, database
  37. from .helpers import get_file_content
  38. from sqlalchemy.orm import sessionmaker
  39. from sqlalchemy import create_engine
  40. class BaseTest(object):
  41. """Base class for tests."""
  42. def request(self, method, path, data=None, **args):
  43. """Send a request."""
  44. # Create a ConfigParser and configure it
  45. # This uses the default config file at the root of the
  46. # Radicale Project
  47. config.read(os.environ.get("RADICALE_CONFIG"))
  48. self._CONFIG_PARSER = config
  49. self.application._status = None
  50. self.application._headers = None
  51. self.application._answer = None
  52. for key in args:
  53. args[key.upper()] = args[key]
  54. args["REQUEST_METHOD"] = method.upper()
  55. args["PATH_INFO"] = path
  56. if data:
  57. args["wsgi.input"] = BytesIO(data)
  58. args["CONTENT_LENGTH"] = str(len(data))
  59. self.application._answer = self.application(args, self.start_response)
  60. return (
  61. int(self.application._status.split()[0]),
  62. dict(self.application._headers),
  63. self.application._answer[0].decode("utf-8")
  64. if self.application._answer else None)
  65. def start_response(self, status, headers):
  66. """Put the response values into the current application."""
  67. self.application._status = status
  68. self.application._headers = headers
  69. @property
  70. def config_instance(self):
  71. return self._CONFIG_PARSER
  72. class FileSystem(BaseTest):
  73. """Base class for filesystem tests."""
  74. storage_type = "filesystem"
  75. def setup(self):
  76. """Setup function for each test."""
  77. self.colpath = tempfile.mkdtemp()
  78. config.set("storage", "type", self.storage_type)
  79. filesystem.FOLDER = self.colpath
  80. filesystem.GIT_REPOSITORY = None
  81. self.application = radicale.Application()
  82. def teardown(self):
  83. """Teardown function for each test."""
  84. shutil.rmtree(self.colpath)
  85. class MultiFileSystem(FileSystem):
  86. """Base class for multifilesystem tests."""
  87. storage_type = "multifilesystem"
  88. class DataBaseSystem(BaseTest):
  89. """Base class for database tests"""
  90. def setup(self):
  91. config.set("storage", "type", "database")
  92. config.set("storage", "database_url", "sqlite://")
  93. database.Session = sessionmaker()
  94. database.Session.configure(bind=create_engine("sqlite://"))
  95. session = database.Session()
  96. # session.execute(get_file_content("schema.sql"))
  97. for st in get_file_content("schema.sql").split(";"):
  98. session.execute(st)
  99. session.commit()
  100. self.application = radicale.Application()
  101. class GitFileSystem(FileSystem):
  102. """Base class for filesystem tests using Git"""
  103. def setup(self):
  104. super(GitFileSystem, self).setup()
  105. Repo.init(self.colpath)
  106. filesystem.GIT_REPOSITORY = Repo(self.colpath)
  107. class GitMultiFileSystem(GitFileSystem, MultiFileSystem):
  108. """Base class for multifilesystem tests using Git"""
  109. class HtpasswdAuthSystem(BaseTest):
  110. """Base class to test Radicale with Htpasswd authentication"""
  111. def setup(self):
  112. self.colpath = tempfile.mkdtemp()
  113. htpasswd_file_path = os.path.join(self.colpath, ".htpasswd")
  114. with open(htpasswd_file_path, "w") as fd:
  115. fd.write('tmp:{SHA}' + base64.b64encode(
  116. hashlib.sha1("bépo").digest()))
  117. config.set("auth", "type", "htpasswd")
  118. self.userpass = base64.b64encode("tmp:bépo")
  119. self.application = radicale.Application()
  120. htpasswd.FILENAME = htpasswd_file_path
  121. htpasswd.ENCRYPTION = "sha1"
  122. def teardown(self):
  123. config.set("auth", "type", "None")
  124. radicale.auth.is_authenticated = lambda *_: True