test_common.py 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. # coding: utf-8
  2. from __future__ import print_function
  3. from __future__ import absolute_import
  4. from __future__ import division
  5. from __future__ import unicode_literals
  6. from . import models as bmodels
  7. from . import const
  8. from django.core.urlresolvers import reverse
  9. from django.test import Client, override_settings
  10. from django.utils.timezone import now
  11. import datetime
  12. import re
  13. # Warning: do not write new tests using this infrastructure. See
  14. # backend.unittest for one that leads to faster and more readable tests.
  15. # This is here only until all the old tests get rewritten.
  16. class NMFactoryMixin(object):
  17. def setUp(self):
  18. super(NMFactoryMixin, self).setUp()
  19. self.users = {}
  20. def make_user(self, tag, status, alioth=False, **kw):
  21. if alioth:
  22. uid = tag + "-guest"
  23. username = uid + "@users.alioth.debian.org"
  24. else:
  25. uid = tag
  26. username = uid + "@debian.org"
  27. kw.setdefault("email", tag + "@example.org")
  28. kw.setdefault("cn", tag.capitalize())
  29. res = bmodels.Person.objects.create_user(username=username,
  30. uid=uid,
  31. status=status,
  32. audit_skip=True,
  33. **kw)
  34. self.users[tag] = res
  35. return res
  36. def make_process(self, applicant, applying_for, progress, applying_as=None, advocates=[], manager=None):
  37. """
  38. Create a process for the given applicant
  39. """
  40. if applying_as is None: applying_as = applicant.status
  41. proc = bmodels.Process(person=applicant,
  42. applying_as=applying_as,
  43. applying_for=applying_for,
  44. progress=progress,
  45. is_active=progress not in (const.PROGRESS_DONE, const.PROGRESS_CANCELLED))
  46. if manager:
  47. try:
  48. am = manager.am
  49. except bmodels.AM.DoesNotExist:
  50. am = bmodels.AM.objects.create(person=manager)
  51. proc.manager = am
  52. proc.save()
  53. for a in advocates:
  54. proc.advocates.add(a)
  55. return proc
  56. class NMBasicFixtureMixin(NMFactoryMixin):
  57. def setUp(self):
  58. super(NMBasicFixtureMixin, self).setUp()
  59. # anonymous
  60. # pending account
  61. self.make_user("pending", const.STATUS_DC, expires=now() + datetime.timedelta(days=1), pending="12345", alioth=True)
  62. # debian contributor
  63. self.make_user("dc", const.STATUS_DC, alioth=True)
  64. # debian contributor with guest account
  65. self.make_user("dc_ga", const.STATUS_DC_GA, alioth=True)
  66. # dm
  67. self.make_user("dm", const.STATUS_DM, alioth=True)
  68. # dm with guest account
  69. self.make_user("dm_ga", const.STATUS_DM_GA, alioth=True)
  70. # dd, nonuploading
  71. self.make_user("dd_nu", const.STATUS_DD_NU)
  72. # dd, uploading
  73. self.make_user("dd_u", const.STATUS_DD_U)
  74. # # non-dd applicant
  75. # app_dc = self.make_user("app_dc", const.STATUS_DC, alioth=True, fd_comment="FD_COMMENTS")
  76. # # non-dd applicant
  77. # app_dc_ga = self.make_user("app_dc_ga", const.STATUS_DC_GA, alioth=True, fd_comment="FD_COMMENTS")
  78. # # non-dd applicant
  79. # app_dm = self.make_user("app_dm", const.STATUS_DM, alioth=True, fd_comment="FD_COMMENTS")
  80. # # non-dd applicant
  81. # app_dm_ga = self.make_user("app_dm_ga", const.STATUS_DM_GA, alioth=True, fd_comment="FD_COMMENTS")
  82. # # dd advocate
  83. # adv = self.make_user("adv", const.STATUS_DD_NU)
  84. # # dd advocate of a past process
  85. # adv_past = self.make_user("adv_past", const.STATUS_DD_NU)
  86. # # am of applicant
  87. # am =self.make_user("am", const.STATUS_DD_NU)
  88. # am_am = bmodels.AM.objects.create(person=am, slots=1)
  89. # proc = bmodels.Process.objects.create(person=applicant,
  90. # applying_as=const.STATUS_DC_GA,
  91. # applying_for=const.STATUS_DD_NU,
  92. # progress=const.PROGRESS_AM,
  93. # manager=am_am,
  94. # is_active=True)
  95. # proc.advocates.add(adv)
  96. # # am not of applicant
  97. # am_other = self.make_user("am_other", const.STATUS_DD_NU)
  98. # bmodels.AM.objects.create(person=am_other, slots=1)
  99. # # am of a past process
  100. # am_past = self.make_user("am_past", const.STATUS_DD_NU)
  101. # am_am_past = bmodels.AM.objects.create(person=am_past, slots=1)
  102. # proc = bmodels.Process.objects.create(person=applicant,
  103. # applying_as=const.STATUS_DC,
  104. # applying_for=const.STATUS_DC_GA,
  105. # progress=const.PROGRESS_DONE,
  106. # manager=am_am_past,
  107. # is_active=False)
  108. # proc.advocates.add(adv_past)
  109. # fd
  110. fd = self.make_user("fd", const.STATUS_DD_NU)
  111. bmodels.AM.objects.create(person=fd, is_fd=True)
  112. # dam
  113. dam = self.make_user("dam", const.STATUS_DD_NU)
  114. bmodels.AM.objects.create(person=dam, is_fd=True, is_dam=True)
  115. # Inspired from http://blog.liw.fi/posts/yarn/
  116. class NMTestUtilsWhen(object):
  117. method = "get"
  118. url = None
  119. user = None
  120. data = None # Optional dict with GET or POST data
  121. data_content_type = None # Content type to use for POST request. See: http://stackoverflow.com/questions/11802299/django-testing-post-based-views-with-json-objects
  122. def __init__(self, method=None, url=None, user=None, data=None, data_content_type=None, **kw):
  123. """
  124. Set up the parameters used by assertVisit to make a request
  125. """
  126. # Override the class defaults with the constructor arguments
  127. if method is not None: self.method = method
  128. if self.url is None or url is not None: self.url = url
  129. if self.user is None or user is not None: self.user = user
  130. if self.data is None or data is not None: self.data = data
  131. if self.data_content_type is None or data_content_type is not None: self.data_content_type = data_content_type
  132. self.args = kw
  133. def setUp(self, fixture):
  134. """
  135. Normalise the parameters using data from the fixture
  136. """
  137. if isinstance(self.user, basestring):
  138. self.user = getattr(fixture, "user_{}".format(self.user))
  139. if self.data is None:
  140. self.data = {}
  141. def tearDown(self, fixture):
  142. pass
  143. def __unicode__(self): return "performing {} {}".format(self.method.upper(), self.url)
  144. class NMTestUtilsThen(object):
  145. def __call__(self, fixture, response, when, test_client):
  146. fixture.fail("test not implemented")
  147. def __unicode__(self):
  148. return "user {} visits {}".format(self.user, self.url)
  149. class ThenSuccess(NMTestUtilsThen):
  150. def __call__(self, fixture, response, when, test_client):
  151. if response.status_code != 200:
  152. fixture.fail("User {} got status code {} instead of a Success when {}".format(
  153. when.user, response.status_code, when))
  154. class ThenForbidden(NMTestUtilsThen):
  155. def __call__(self, fixture, response, when, test_client):
  156. if response.status_code != 403:
  157. fixture.fail("User {} got status code {} instead of a Forbidden when {}".format(
  158. when.user, response.status_code, when))
  159. class ThenBadMethod(NMTestUtilsThen):
  160. def __call__(self, fixture, response, when, test_client):
  161. if response.status_code != 400:
  162. fixture.fail("User {} got status code {} instead of a BadMethod when {}".format(
  163. when.user, response.status_code, when))
  164. class ThenMethodNotAllowed(NMTestUtilsThen):
  165. def __call__(self, fixture, response, when, test_client):
  166. if response.status_code != 405:
  167. fixture.fail("User {} got status code {} instead of a 405 'Method not allowed' when {}".format(
  168. when.user, response.status_code, when))
  169. class ThenNotFound(NMTestUtilsThen):
  170. def __call__(self, fixture, response, when, test_client):
  171. if response.status_code != 404:
  172. fixture.fail("User {} got status code {} instead of a NotFound when {}".format(
  173. when.user, response.status_code, when))
  174. class ThenRedirect(NMTestUtilsThen):
  175. target = None
  176. def __init__(self, target=None):
  177. self.target = target
  178. def __call__(self, fixture, response, when, test_client):
  179. if response.status_code != 302:
  180. fixture.fail("User {} got status code {} instead of a Redirect when {}".format(
  181. when.user, response.status_code, when))
  182. if self.target and not re.search(self.target, response["Location"]):
  183. fixture.fail("User {} got redirected to {} which does not match {}".format(
  184. when.user, response["Location"], self.target))
  185. class NMTestUtilsMixin(object):
  186. def assertVisit(self, when, then, test_client=None):
  187. if test_client is None:
  188. test_client = Client()
  189. when.setUp(self)
  190. meth = getattr(test_client, when.method)
  191. kw = { "data": when.data }
  192. if when.data_content_type: kw["content_type"] = when.data_content_type
  193. if when.user:
  194. with override_settings(TEST_USER=when.user.username):
  195. response = meth(when.url, **kw)
  196. else:
  197. with override_settings(TEST_USER=None):
  198. response = meth(when.url, **kw)
  199. try:
  200. then(self, response, when, test_client)
  201. finally:
  202. when.tearDown(self)