/askbot/tests/utils.py

https://github.com/rtnpro/askbot-devel · Python · 254 lines · 244 code · 1 blank · 9 comment · 0 complexity · b7206f1a4dfc438f6c49d59649b53c4c MD5 · raw file

  1. """utility functions used by Askbot test cases
  2. """
  3. from django.test import TestCase
  4. from functools import wraps
  5. from askbot import models
  6. def create_user(
  7. username = None,
  8. email = None,
  9. notification_schedule = None,
  10. date_joined = None,
  11. status = 'a',
  12. reputation = 1
  13. ):
  14. """Creates a user and sets default update subscription
  15. settings
  16. ``notification_schedule`` is a dictionary with keys
  17. the same as in keys in
  18. :attr:`~askbot.models.EmailFeedSetting.FEED_TYPES`:
  19. * 'q_ask' - questions that user asks
  20. * 'q_all' - enture forum, tag filtered
  21. * 'q_ans' - questions that user answers
  22. * 'q_sel' - questions that user decides to follow
  23. * 'm_and_c' - comments and mentions of user anywhere
  24. and values as keys in
  25. :attr:`~askbot.models.EmailFeedSetting.FEED_TYPES`:
  26. * 'i' - instantly
  27. * 'd' - daily
  28. * 'w' - weekly
  29. * 'n' - never
  30. """
  31. user = models.User.objects.create_user(username, email)
  32. user.reputation = reputation
  33. if date_joined is not None:
  34. user.date_joined = date_joined
  35. user.save()
  36. user.set_status(status)
  37. if notification_schedule == None:
  38. notification_schedule = models.EmailFeedSetting.NO_EMAIL_SCHEDULE
  39. #a hack, we need to delete these, that will be created automatically
  40. #because just below we will be replacing them with the new values
  41. user.notification_subscriptions.all().delete()
  42. for feed_type, frequency in notification_schedule.items():
  43. feed = models.EmailFeedSetting(
  44. feed_type = feed_type,
  45. frequency = frequency,
  46. subscriber = user
  47. )
  48. feed.save()
  49. return user
  50. class AskbotTestCase(TestCase):
  51. """adds some askbot-specific methods
  52. to django TestCase class
  53. """
  54. def create_user(
  55. self,
  56. username = 'user',
  57. email = None,
  58. notification_schedule = None,
  59. date_joined = None,
  60. status = 'a'
  61. ):
  62. """creates user with username, etc and
  63. makes the result accessible as
  64. self.<username>
  65. newly created user object is also returned
  66. """
  67. assert(username is not None)
  68. assert(not hasattr(self, username))
  69. if email is None:
  70. email = username + '@example.com'
  71. user_object = create_user(
  72. username = username,
  73. email = email,
  74. notification_schedule = notification_schedule,
  75. date_joined = date_joined,
  76. status = status
  77. )
  78. setattr(self, username, user_object)
  79. return user_object
  80. def assertRaisesRegexp(self, *args, **kwargs):
  81. """a shim for python < 2.7"""
  82. try:
  83. #run assertRaisesRegex, if available
  84. super(AskbotTestCase, self).assertRaisesRegexp(*args, **kwargs)
  85. except AttributeError:
  86. #in this case lose testing for the error text
  87. #second argument is the regex that is supposed
  88. #to match the error text
  89. args_list = list(args)#conv tuple to list
  90. args_list.pop(1)#so we can remove an item
  91. self.assertRaises(*args_list, **kwargs)
  92. def post_question(
  93. self,
  94. user = None,
  95. title = 'test question title',
  96. body_text = 'test question body text',
  97. tags = 'test',
  98. by_email = False,
  99. wiki = False,
  100. is_anonymous = False,
  101. follow = False,
  102. timestamp = None,
  103. ):
  104. """posts and returns question on behalf
  105. of user. If user is not given, it will be self.user
  106. ``tags`` is a string with tagnames
  107. if follow is True, question is followed by the poster
  108. """
  109. if user is None:
  110. user = self.user
  111. question = user.post_question(
  112. title = title,
  113. body_text = body_text,
  114. tags = tags,
  115. by_email = by_email,
  116. wiki = wiki,
  117. is_anonymous = is_anonymous,
  118. timestamp = timestamp
  119. )
  120. if follow:
  121. user.follow_question(question)
  122. return question
  123. def reload_object(self, obj):
  124. """reloads model object from the database
  125. """
  126. return obj.__class__.objects.get(id = obj.id)
  127. def post_answer(
  128. self,
  129. user = None,
  130. question = None,
  131. body_text = 'test answer text',
  132. by_email = False,
  133. follow = False,
  134. wiki = False,
  135. timestamp = None
  136. ):
  137. if user is None:
  138. user = self.user
  139. return user.post_answer(
  140. question = question,
  141. body_text = body_text,
  142. by_email = by_email,
  143. follow = follow,
  144. wiki = wiki,
  145. timestamp = timestamp
  146. )
  147. def create_tag(self, tag_name, user = None):
  148. """creates a user, b/c it is necessary"""
  149. if user is None:
  150. try:
  151. user = models.User.objects.get(username = 'tag_creator')
  152. except models.User.DoesNotExist:
  153. user = self.create_user('tag_creator')
  154. tag = models.Tag(created_by = user, name = tag_name)
  155. tag.save()
  156. return tag
  157. def post_comment(
  158. self,
  159. user = None,
  160. parent_post = None,
  161. body_text = 'test comment text',
  162. by_email = False,
  163. timestamp = None
  164. ):
  165. """posts and returns a comment to parent post, uses
  166. now timestamp if not given, dummy body_text
  167. author is required
  168. """
  169. if user is None:
  170. user = self.user
  171. comment = user.post_comment(
  172. parent_post = parent_post,
  173. body_text = body_text,
  174. by_email = by_email,
  175. timestamp = timestamp,
  176. )
  177. return comment
  178. """
  179. Some test decorators, taken from Django-1.3
  180. """
  181. class SkipTest(Exception):
  182. """
  183. Raise this exception in a test to skip it.
  184. Usually you can use TestResult.skip() or one of the skipping decorators
  185. instead of raising this directly.
  186. """
  187. def _id(obj):
  188. return obj
  189. def skip(reason):
  190. """
  191. Unconditionally skip a test.
  192. """
  193. def decorator(test_item):
  194. if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
  195. @wraps(test_item)
  196. def skip_wrapper(*args, **kwargs):
  197. raise SkipTest(reason)
  198. test_item = skip_wrapper
  199. test_item.__unittest_skip__ = True
  200. test_item.__unittest_skip_why__ = reason
  201. return test_item
  202. return decorator
  203. def skipIf(condition, reason):
  204. """
  205. Skip a test if the condition is true.
  206. """
  207. if condition:
  208. return skip(reason)
  209. return _id