__init__.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2014 The Distro Tracker Developers
  3. # See the COPYRIGHT file at the top-level directory of this distribution and
  4. # at http://deb.li/DTAuthors
  5. #
  6. # This file is part of Distro Tracker. It is subject to the license terms
  7. # in the LICENSE file found in the top-level directory of this
  8. # distribution and at http://deb.li/DTLicense. No part of Distro Tracker,
  9. # including this file, may be copied, modified, propagated, or distributed
  10. # except according to the terms contained in the LICENSE file.
  11. """
  12. Distro Tracker test infrastructure.
  13. """
  14. import shutil
  15. import tempfile
  16. import os
  17. import os.path
  18. import inspect
  19. from django.conf import settings
  20. from django.contrib.staticfiles.testing import StaticLiveServerTestCase
  21. import django.test
  22. from django.test.signals import setting_changed
  23. from bs4 import BeautifulSoup as soup
  24. class TempDirsMixin(object):
  25. """
  26. Diverts all distro-tracker path settings to make them point
  27. to temporary directories while testing.
  28. """
  29. DISTRO_TRACKER_PATH_SETTINGS = {
  30. 'STATIC_ROOT': 'static',
  31. 'MEDIA_ROOT': 'media',
  32. 'DISTRO_TRACKER_CACHE_DIRECTORY': 'cache',
  33. 'DISTRO_TRACKER_KEYRING_DIRECTORY': 'keyring',
  34. 'DISTRO_TRACKER_TEMPLATE_DIRECTORY': 'templates',
  35. 'DISTRO_TRACKER_LOG_DIRECTORY': 'logs',
  36. 'DISTRO_TRACKER_MAILDIR_DIRECTORY': 'maildir',
  37. }
  38. def _backup_settings(self, name):
  39. self._settings_copy[name] = getattr(settings, name)
  40. def _restore_settings(self):
  41. for key, value in self._settings_copy.items():
  42. setattr(settings, key, value)
  43. def __call__(self, result=None):
  44. """
  45. Wrapper around __call__ to perform temporary directories setup.
  46. This means that user-defined Test Cases aren't required to
  47. include a call to super().setUp().
  48. """
  49. self._settings_copy = {}
  50. self.addCleanup(self._restore_settings)
  51. self._backup_settings('DISTRO_TRACKER_DATA_PATH')
  52. tempdir = tempfile.mkdtemp(prefix='distro-tracker-tests-')
  53. self.addCleanup(shutil.rmtree, tempdir)
  54. setattr(settings, 'DISTRO_TRACKER_DATA_PATH', tempdir)
  55. for name, dirname in self.DISTRO_TRACKER_PATH_SETTINGS.items():
  56. self._backup_settings(name)
  57. dirname = os.path.join(tempdir, dirname)
  58. setattr(settings, name, dirname)
  59. os.mkdir(dirname)
  60. return super(TempDirsMixin, self).__call__(result)
  61. class TestCaseHelpersMixin(object):
  62. """
  63. Helpers method injected into distro_tracker's *TestCase objects.
  64. """
  65. def get_test_data_path(self, name):
  66. """
  67. Returns an absolute path name of file within the tests-data
  68. subdirectory in the calling TestCase.
  69. """
  70. return os.path.join(os.path.dirname(inspect.getabsfile(self.__class__)),
  71. 'tests-data', name)
  72. def add_test_template_dir(self, name='tests-templates'):
  73. template_dir = self.get_test_data_path(name)
  74. settings.TEMPLATES[0]['DIRS'].append(template_dir)
  75. setting_changed.send(sender=self.__class__, setting='TEMPLATES',
  76. value=settings.TEMPLATES, enter=True)
  77. def cleanup_test_template_dir():
  78. settings.TEMPLATES[0]['DIRS'].remove(template_dir)
  79. setting_changed.send(sender=self.__class__, setting='TEMPLATES',
  80. value=settings.TEMPLATES, enter=False)
  81. self.addCleanup(cleanup_test_template_dir)
  82. def import_key_into_keyring(self, filename):
  83. """
  84. Imports a key from an ascii armored file located in tests-data/keys/
  85. into Distro Tracker's keyrings/.
  86. """
  87. import gpgme
  88. old = os.environ.get('GNUPGHOME', None)
  89. os.environ['GNUPGHOME'] = settings.DISTRO_TRACKER_KEYRING_DIRECTORY
  90. ctx = gpgme.Context()
  91. file_path = self.get_test_data_path('keys/' + filename)
  92. with open(file_path, 'rb') as key_file:
  93. ctx.import_(key_file)
  94. if old:
  95. os.environ['GNUPGHOME'] = old
  96. class SimpleTestCase(TempDirsMixin, TestCaseHelpersMixin,
  97. django.test.SimpleTestCase):
  98. pass
  99. class TestCase(TempDirsMixin, TestCaseHelpersMixin,
  100. django.test.TestCase):
  101. pass
  102. class TransactionTestCase(TempDirsMixin, TestCaseHelpersMixin,
  103. django.test.TransactionTestCase):
  104. pass
  105. class LiveServerTestCase(TempDirsMixin, TestCaseHelpersMixin,
  106. StaticLiveServerTestCase):
  107. pass
  108. class TemplateTestsMixin(object):
  109. """Helper methods to tests templates"""
  110. @staticmethod
  111. def html_contains_link(text, link):
  112. html = soup(text, 'html.parser')
  113. for a_tag in html.findAll('a', {'href': True}):
  114. if a_tag['href'] == link:
  115. return True
  116. return False
  117. def assertLinkIsInResponse(self, response, link):
  118. self.assertTrue(self.html_contains_link(response.content, link))
  119. def assertLinkIsNotInResponse(self, response, link):
  120. self.assertFalse(self.html_contains_link(response.content, link))