test_plugin.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. from datetime import timedelta
  2. from unittest.mock import Mock, patch
  3. import pytest
  4. from django.utils import timezone
  5. from sentry.exceptions import HookValidationError
  6. from sentry.models import (
  7. Commit,
  8. Deploy,
  9. Environment,
  10. ProjectOption,
  11. Release,
  12. ReleaseCommit,
  13. ReleaseHeadCommit,
  14. Repository,
  15. User,
  16. )
  17. from sentry.testutils import TestCase
  18. from sentry_plugins.heroku.plugin import HerokuReleaseHook
  19. class SetRefsTest(TestCase):
  20. """
  21. tests that when finish_release is called on a release hook,
  22. we try to get the previous commits based on the version ref
  23. and that we create `ReleaseHeadCommit`s for the version
  24. """
  25. @patch("sentry.tasks.commits.fetch_commits")
  26. def test_minimal(self, mock_fetch_commits):
  27. project = self.create_project()
  28. version = "bbee5b51f84611e4b14834363b8514c2"
  29. data_list = [
  30. {
  31. "id": "c7155651831549cf8a5e47889fce17eb",
  32. "message": "foo",
  33. "author_email": "jane@example.com",
  34. },
  35. {
  36. "id": "62de626b7c7cfb8e77efb4273b1a3df4123e6216",
  37. "message": "hello",
  38. "author_name": "Jess",
  39. },
  40. {
  41. "id": "58de626b7c7cfb8e77efb4273b1a3df4123e6345",
  42. "message": "bar",
  43. "author_name": "Joe^^",
  44. },
  45. {
  46. "id": "bbee5b51f84611e4b14834363b8514c2",
  47. "message": "blah",
  48. "author_email": "katie@example.com",
  49. },
  50. ]
  51. user = User.objects.create(email="stebe@sentry.io")
  52. repo = Repository.objects.create(
  53. organization_id=project.organization_id, name=project.name, provider="dummy"
  54. )
  55. ProjectOption.objects.set_value(key="heroku:repository", project=project, value=repo.name)
  56. for data in data_list:
  57. Commit.objects.create(
  58. key=data["id"], organization_id=self.project.organization_id, repository_id=repo.id
  59. )
  60. old_release = Release.objects.create(
  61. version="a" * 40,
  62. organization_id=project.organization_id,
  63. date_added=timezone.now() - timedelta(minutes=30),
  64. )
  65. old_release.add_project(project)
  66. ReleaseCommit.objects.create(
  67. organization_id=project.organization_id,
  68. project_id=project.id,
  69. release=old_release,
  70. commit=Commit.objects.get(key="c7155651831549cf8a5e47889fce17eb"),
  71. order=0,
  72. )
  73. ReleaseHeadCommit.objects.create(
  74. organization_id=project.organization_id,
  75. repository_id=repo.id,
  76. release=old_release,
  77. commit=Commit.objects.get(key="c7155651831549cf8a5e47889fce17eb"),
  78. )
  79. release_heads = ReleaseHeadCommit.objects.filter(
  80. organization_id=project.organization_id,
  81. repository_id=repo.id,
  82. commit=Commit.objects.get(key="bbee5b51f84611e4b14834363b8514c2"),
  83. )
  84. assert len(release_heads) == 0
  85. hook = HerokuReleaseHook(project)
  86. hook.finish_release(version=version, owner=user)
  87. release = Release.objects.get(projects=project, version=version)
  88. new_release_heads = ReleaseHeadCommit.objects.filter(
  89. organization_id=project.organization_id,
  90. repository_id=repo.id,
  91. release=release,
  92. commit=Commit.objects.get(key="bbee5b51f84611e4b14834363b8514c2"),
  93. )
  94. assert len(new_release_heads) == 1
  95. assert release.version == "bbee5b51f84611e4b14834363b8514c2"
  96. deploy = Deploy.objects.filter(
  97. organization_id=project.organization_id,
  98. release=release,
  99. environment_id=Environment.objects.get(
  100. organization_id=project.organization_id, name="production"
  101. ).id,
  102. )
  103. assert len(deploy) == 1
  104. mock_fetch_commits.apply_async.assert_called_with(
  105. kwargs={
  106. "release_id": release.id,
  107. "user_id": user.id,
  108. "refs": [{"commit": "bbee5b51f84611e4b14834363b8514c2", "repository": repo.name}],
  109. "prev_release_id": old_release.id,
  110. }
  111. )
  112. class HookHandleTest(TestCase):
  113. def test_user_success(self):
  114. user = self.create_user()
  115. organization = self.create_organization(owner=user)
  116. project = self.create_project(organization=organization)
  117. hook = HerokuReleaseHook(project)
  118. hook.set_refs = Mock()
  119. req = Mock()
  120. req.POST = {"head_long": "abcd123", "url": "http://example.com", "user": user.email}
  121. hook.handle(req)
  122. assert Release.objects.filter(version=req.POST["head_long"]).exists()
  123. assert hook.set_refs.call_count == 1
  124. def test_actor_email_success(self):
  125. user = self.create_user()
  126. organization = self.create_organization(owner=user)
  127. project = self.create_project(organization=organization)
  128. hook = HerokuReleaseHook(project)
  129. hook.set_refs = Mock()
  130. req = Mock()
  131. req.POST = {
  132. "head_long": "v999",
  133. "url": "http://example.com",
  134. "actor": {"email": user.email},
  135. }
  136. hook.handle(req)
  137. assert Release.objects.filter(version=req.POST["head_long"]).exists()
  138. assert hook.set_refs.call_count == 1
  139. def test_email_mismatch(self):
  140. user = self.create_user()
  141. organization = self.create_organization(owner=user)
  142. project = self.create_project(organization=organization)
  143. hook = HerokuReleaseHook(project)
  144. req = Mock()
  145. req.POST = {"head_long": "v999", "url": "http://example.com", "user": "wrong@example.com"}
  146. hook.handle(req)
  147. assert Release.objects.filter(version=req.POST["head_long"]).exists()
  148. def test_bad_version(self):
  149. project = self.create_project()
  150. user = self.create_user()
  151. hook = HerokuReleaseHook(project)
  152. req = Mock()
  153. req.POST = {"head_long": "", "url": "http://example.com", "user": user.email}
  154. with pytest.raises(HookValidationError):
  155. hook.handle(req)