/tests/sentry/plugins/mail/activity/test_release.py

https://github.com/pombredanne/django-sentry · Python · 328 lines · 261 code · 53 blank · 14 comment · 6 complexity · bc2f81d6b3227e0a22c8016f0956230e MD5 · raw file

  1. # -*- coding: utf-8 -*-
  2. from __future__ import absolute_import
  3. from django.core import mail
  4. from django.utils import timezone
  5. from sentry.models import (
  6. Activity,
  7. Commit,
  8. CommitAuthor,
  9. Deploy,
  10. Environment,
  11. GroupSubscriptionReason,
  12. Release,
  13. ReleaseCommit,
  14. Repository,
  15. UserEmail,
  16. UserOption,
  17. UserOptionValue,
  18. )
  19. from sentry.plugins.sentry_mail.activity.release import ReleaseActivityEmail
  20. from sentry.testutils import TestCase
  21. class ReleaseTestCase(TestCase):
  22. def setUp(self):
  23. super(ReleaseTestCase, self).setUp()
  24. self.user = self.create_user("foo@example.com")
  25. assert UserEmail.objects.filter(user=self.user, email=self.user.email).update(
  26. is_verified=True
  27. )
  28. self.user2 = self.create_user("bar@example.com")
  29. assert UserEmail.objects.filter(user=self.user2, email=self.user2.email).update(
  30. is_verified=True
  31. )
  32. self.user3 = self.create_user("baz@example.com")
  33. assert UserEmail.objects.filter(user=self.user3, email=self.user3.email).update(
  34. is_verified=True
  35. )
  36. self.user4 = self.create_user("floop@example.com")
  37. assert UserEmail.objects.filter(user=self.user4, email=self.user4.email).update(
  38. is_verified=True
  39. )
  40. self.user5 = self.create_user("companyemail@example.com")
  41. user5_alt_email = "privateEmail@gmail.com"
  42. UserEmail.objects.create(email=user5_alt_email, user=self.user5)
  43. assert UserEmail.objects.filter(user=self.user5, email=self.user5.email).update(
  44. is_verified=True
  45. )
  46. assert UserEmail.objects.filter(user=self.user5, email=user5_alt_email).update(
  47. is_verified=True
  48. )
  49. self.org = self.create_organization(owner=None)
  50. self.org.flags.allow_joinleave = False
  51. self.org.save()
  52. self.team = self.create_team(organization=self.org)
  53. self.team2 = self.create_team(organization=self.org)
  54. self.create_member(user=self.user, organization=self.org, teams=[self.team])
  55. self.create_member(user=self.user2, organization=self.org)
  56. self.create_member(user=self.user3, organization=self.org, teams=[self.team])
  57. self.create_member(user=self.user4, organization=self.org, teams=[self.team])
  58. self.create_member(user=self.user5, organization=self.org, teams=[self.team])
  59. self.project = self.create_project(organization=self.org, teams=[self.team])
  60. self.project2 = self.create_project(organization=self.org, teams=[self.team2])
  61. self.release = Release.objects.create(
  62. version="a" * 40,
  63. organization_id=self.project.organization_id,
  64. date_released=timezone.now(),
  65. )
  66. self.release.add_project(self.project)
  67. self.release.add_project(self.project2)
  68. self.environment = Environment.objects.create(
  69. name="production", organization_id=self.org.id
  70. )
  71. self.deploy = Deploy.objects.create(
  72. release=self.release, organization_id=self.org.id, environment_id=self.environment.id
  73. )
  74. repository = Repository.objects.create(organization_id=self.org.id, name=self.project.name)
  75. self.commit = Commit.objects.create(
  76. key="a" * 40,
  77. repository_id=repository.id,
  78. organization_id=self.org.id,
  79. author=CommitAuthor.objects.create(
  80. organization_id=self.org.id, name=self.user.name, email=self.user.email
  81. ),
  82. )
  83. self.commit2 = Commit.objects.create(
  84. key="b" * 40,
  85. repository_id=repository.id,
  86. organization_id=self.org.id,
  87. author=CommitAuthor.objects.create(
  88. organization_id=self.org.id, name=self.user2.name, email=self.user2.email
  89. ),
  90. )
  91. self.commit3 = Commit.objects.create(
  92. key="c" * 40,
  93. repository_id=repository.id,
  94. organization_id=self.org.id,
  95. author=CommitAuthor.objects.create(
  96. organization_id=self.org.id, name=self.user4.name, email=self.user4.email
  97. ),
  98. )
  99. self.commit4 = Commit.objects.create(
  100. key="e" * 40,
  101. repository_id=repository.id,
  102. organization_id=self.org.id,
  103. author=CommitAuthor.objects.create(
  104. organization_id=self.org.id, name=self.user5.name, email=user5_alt_email
  105. ),
  106. )
  107. ReleaseCommit.objects.create(
  108. organization_id=self.project.organization_id,
  109. release=self.release,
  110. commit=self.commit,
  111. order=0,
  112. )
  113. ReleaseCommit.objects.create(
  114. organization_id=self.project.organization_id,
  115. release=self.release,
  116. commit=self.commit2,
  117. order=1,
  118. )
  119. ReleaseCommit.objects.create(
  120. organization_id=self.project.organization_id,
  121. release=self.release,
  122. commit=self.commit3,
  123. order=2,
  124. )
  125. ReleaseCommit.objects.create(
  126. organization_id=self.project.organization_id,
  127. release=self.release,
  128. commit=self.commit4,
  129. order=3,
  130. )
  131. UserOption.objects.set_value(
  132. user=self.user3,
  133. organization=self.org,
  134. key="deploy-emails",
  135. value=UserOptionValue.all_deploys,
  136. )
  137. UserOption.objects.set_value(
  138. user=self.user4,
  139. organization=self.org,
  140. key="deploy-emails",
  141. value=UserOptionValue.no_deploys,
  142. )
  143. # added to make sure org default above takes precedent
  144. UserOption.objects.set_value(
  145. user=self.user4,
  146. organization=None,
  147. key="deploy-emails",
  148. value=UserOptionValue.all_deploys,
  149. )
  150. def test_simple(self):
  151. email = ReleaseActivityEmail(
  152. Activity(
  153. project=self.project,
  154. user=self.user,
  155. type=Activity.RELEASE,
  156. data={"version": self.release.version, "deploy_id": self.deploy.id},
  157. )
  158. )
  159. # user is included because they committed
  160. # user2 committed but isn't in a team associated with the project.
  161. # user3 is included because they oped into all deploy emails
  162. # user4 committed but isn't included because they opted out of all deploy emails
  163. # for that org -- also tests to make sure org overrides default preference
  164. # user5 committed with another email address and is still included.
  165. assert len(email.get_participants()) == 3
  166. assert email.get_participants() == {
  167. self.user: GroupSubscriptionReason.committed,
  168. self.user3: GroupSubscriptionReason.deploy_setting,
  169. self.user5: GroupSubscriptionReason.committed,
  170. }
  171. context = email.get_context()
  172. assert context["environment"] == "production"
  173. assert context["repos"][0]["commits"] == [
  174. (self.commit, self.user),
  175. (self.commit2, self.user2),
  176. (self.commit3, self.user4),
  177. (self.commit4, self.user5),
  178. ]
  179. user_context = email.get_user_context(self.user)
  180. # make sure this only includes projects user has access to
  181. assert len(user_context["projects"]) == 1
  182. assert user_context["projects"][0][0] == self.project
  183. with self.tasks():
  184. email.send()
  185. assert len(mail.outbox) == 3
  186. sent_email_addresses = {msg.to[0] for msg in mail.outbox}
  187. assert sent_email_addresses == {self.user.email, self.user3.email, self.user5.email}
  188. def test_doesnt_generate_on_no_release(self):
  189. email = ReleaseActivityEmail(
  190. Activity(
  191. project=self.project,
  192. user=self.user,
  193. type=Activity.RELEASE,
  194. data={"version": "a", "deploy_id": 5},
  195. )
  196. )
  197. assert email.release is None
  198. assert not email.should_email()
  199. def test_no_committers(self):
  200. release = Release.objects.create(
  201. version="b" * 40,
  202. organization_id=self.project.organization_id,
  203. date_released=timezone.now(),
  204. )
  205. release.add_project(self.project)
  206. release.add_project(self.project2)
  207. deploy = Deploy.objects.create(
  208. release=release, organization_id=self.org.id, environment_id=self.environment.id
  209. )
  210. email = ReleaseActivityEmail(
  211. Activity(
  212. project=self.project,
  213. user=self.user,
  214. type=Activity.RELEASE,
  215. data={"version": release.version, "deploy_id": deploy.id},
  216. )
  217. )
  218. # only user3 is included because they oped into all deploy emails
  219. assert len(email.get_participants()) == 1
  220. assert email.get_participants() == {self.user3: GroupSubscriptionReason.deploy_setting}
  221. context = email.get_context()
  222. assert context["environment"] == "production"
  223. assert context["repos"] == []
  224. user_context = email.get_user_context(self.user)
  225. # make sure this only includes projects user has access to
  226. assert len(user_context["projects"]) == 1
  227. assert user_context["projects"][0][0] == self.project
  228. with self.tasks():
  229. email.send()
  230. assert len(mail.outbox) == 1
  231. sent_email_addresses = {msg.to[0] for msg in mail.outbox}
  232. assert sent_email_addresses == {self.user3.email}
  233. def test_uses_default(self):
  234. user6 = self.create_user()
  235. self.create_member(user=user6, organization=self.org, teams=[self.team])
  236. UserOption.objects.set_value(
  237. user=user6, organization=None, key="deploy-emails", value=UserOptionValue.all_deploys
  238. )
  239. release = Release.objects.create(
  240. version="b" * 40,
  241. organization_id=self.project.organization_id,
  242. date_released=timezone.now(),
  243. )
  244. release.add_project(self.project)
  245. release.add_project(self.project2)
  246. deploy = Deploy.objects.create(
  247. release=release, organization_id=self.org.id, environment_id=self.environment.id
  248. )
  249. email = ReleaseActivityEmail(
  250. Activity(
  251. project=self.project,
  252. user=self.user,
  253. type=Activity.RELEASE,
  254. data={"version": release.version, "deploy_id": deploy.id},
  255. )
  256. )
  257. # user3 and user 6 are included because they oped into all deploy emails
  258. # (one on an org level, one as their default)
  259. assert len(email.get_participants()) == 2
  260. assert email.get_participants() == {
  261. user6: GroupSubscriptionReason.deploy_setting,
  262. self.user3: GroupSubscriptionReason.deploy_setting,
  263. }
  264. context = email.get_context()
  265. assert context["environment"] == "production"
  266. assert context["repos"] == []
  267. user_context = email.get_user_context(user6)
  268. # make sure this only includes projects user has access to
  269. assert len(user_context["projects"]) == 1
  270. assert user_context["projects"][0][0] == self.project
  271. with self.tasks():
  272. email.send()
  273. assert len(mail.outbox) == 2
  274. sent_email_addresses = {msg.to[0] for msg in mail.outbox}
  275. assert sent_email_addresses == {self.user3.email, user6.email}