test_provider.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. from functools import cached_property
  2. from unittest.mock import patch
  3. import responses
  4. from sentry.models import Integration, OrganizationIntegration, Repository
  5. from sentry.testutils import TestCase
  6. from sentry.utils import json
  7. from sentry_plugins.github.client import GitHubAppsClient, GitHubClient
  8. from sentry_plugins.github.plugin import GitHubAppsRepositoryProvider, GitHubRepositoryProvider
  9. from sentry_plugins.github.testutils import (
  10. COMPARE_COMMITS_EXAMPLE,
  11. GET_LAST_COMMITS_EXAMPLE,
  12. INTSTALLATION_REPOSITORIES_API_RESPONSE,
  13. LIST_INSTALLATION_API_RESPONSE,
  14. )
  15. from social_auth.models import UserSocialAuth
  16. class GitHubPluginTest(TestCase):
  17. @cached_property
  18. def provider(self):
  19. return GitHubRepositoryProvider("github")
  20. def test_compare_commits(self):
  21. repo = Repository.objects.create(provider="github", name="example", organization_id=1)
  22. res = self.provider._format_commits(repo, json.loads(COMPARE_COMMITS_EXAMPLE)["commits"])
  23. assert res == [
  24. {
  25. "author_email": "support@github.com",
  26. "author_name": "Monalisa Octocat",
  27. "message": "Fix all the bugs",
  28. "id": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
  29. "repository": "example",
  30. }
  31. ]
  32. def test_get_last_commits(self):
  33. repo = Repository.objects.create(provider="github", name="example", organization_id=1)
  34. res = self.provider._format_commits(repo, json.loads(GET_LAST_COMMITS_EXAMPLE)[:10])
  35. assert res == [
  36. {
  37. "author_email": "support@github.com",
  38. "author_name": "Monalisa Octocat",
  39. "message": "Fix all the bugs",
  40. "id": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
  41. "repository": "example",
  42. }
  43. ]
  44. @responses.activate
  45. def test_create_repository(self):
  46. responses.add(
  47. responses.POST,
  48. "https://api.github.com/repos/getsentry/example-repo/hooks",
  49. json={"id": "123456", "events": ["push", "pull_request"]},
  50. )
  51. user = self.create_user()
  52. organization = self.create_organization()
  53. UserSocialAuth.objects.create(
  54. user=user, provider="github", extra_data={"access_token": "abcdefg"}
  55. )
  56. data = {"name": "getsentry/example-repo", "external_id": "654321"}
  57. data = self.provider.create_repository(organization, data, user)
  58. assert data == {
  59. "config": {
  60. "name": "getsentry/example-repo",
  61. "webhook_id": "123456",
  62. "webhook_events": ["push", "pull_request"],
  63. },
  64. "external_id": "654321",
  65. "name": "getsentry/example-repo",
  66. "url": "https://github.com/getsentry/example-repo",
  67. }
  68. request = responses.calls[-1].request
  69. req_json = json.loads(request.body)
  70. assert req_json == {
  71. "active": True,
  72. "config": {
  73. "url": f"http://testserver/plugins/github/organizations/{organization.id}/webhook/",
  74. "secret": self.provider.get_webhook_secret(organization),
  75. "content_type": "json",
  76. },
  77. "name": "web",
  78. "events": ["push", "pull_request"],
  79. }
  80. @responses.activate
  81. def test_delete_repository(self):
  82. responses.add(
  83. responses.DELETE,
  84. "https://api.github.com/repos/getsentry/example-repo/hooks/123456",
  85. json={},
  86. )
  87. user = self.create_user()
  88. organization = self.create_organization()
  89. UserSocialAuth.objects.create(
  90. user=user, provider="github", extra_data={"access_token": "abcdefg"}
  91. )
  92. repo = Repository.objects.create(
  93. provider="github",
  94. name="example-repo",
  95. organization_id=organization.id,
  96. config={
  97. "name": "getsentry/example-repo",
  98. "external_id": "654321",
  99. "webhook_id": "123456",
  100. },
  101. )
  102. self.provider.delete_repository(repo, user)
  103. @responses.activate
  104. def test_update_repository_without_webhook(self):
  105. responses.add(
  106. responses.POST,
  107. "https://api.github.com/repos/getsentry/example-repo/hooks",
  108. json={"id": "123456", "events": ["push", "pull_request"]},
  109. )
  110. user = self.create_user()
  111. organization = self.create_organization()
  112. UserSocialAuth.objects.create(
  113. user=user, provider="github", extra_data={"access_token": "abcdefg"}
  114. )
  115. repo = Repository.objects.create(
  116. provider="github",
  117. name="example-repo",
  118. organization_id=organization.id,
  119. config={"name": "getsentry/example-repo", "external_id": "654321"},
  120. )
  121. self.provider.update_repository(repo, user)
  122. assert repo.config["webhook_id"] == "123456"
  123. assert repo.config["webhook_events"] == ["push", "pull_request"]
  124. @responses.activate
  125. def test_update_repository_with_webhook(self):
  126. responses.add(
  127. responses.PATCH,
  128. "https://api.github.com/repos/getsentry/example-repo/hooks/123456",
  129. json={"id": "123456", "events": ["push", "pull_request"]},
  130. )
  131. user = self.create_user()
  132. organization = self.create_organization()
  133. UserSocialAuth.objects.create(
  134. user=user, provider="github", extra_data={"access_token": "abcdefg"}
  135. )
  136. repo = Repository.objects.create(
  137. provider="github",
  138. name="example-repo",
  139. organization_id=organization.id,
  140. config={
  141. "name": "getsentry/example-repo",
  142. "external_id": "654321",
  143. "webhook_id": "123456",
  144. },
  145. )
  146. self.provider.update_repository(repo, user)
  147. assert repo.config["webhook_id"] == "123456"
  148. assert repo.config["webhook_events"] == ["push", "pull_request"]
  149. class GitHubAppsProviderTest(TestCase):
  150. @cached_property
  151. def provider(self):
  152. return GitHubAppsRepositoryProvider("github_apps")
  153. @patch.object(
  154. GitHubAppsClient,
  155. "get_repositories",
  156. return_value=json.loads(INTSTALLATION_REPOSITORIES_API_RESPONSE),
  157. )
  158. @patch.object(
  159. GitHubClient, "get_installations", return_value=json.loads(LIST_INSTALLATION_API_RESPONSE)
  160. )
  161. def test_link_auth(self, *args):
  162. user = self.create_user()
  163. organization = self.create_organization()
  164. UserSocialAuth.objects.create(
  165. user=user, provider="github_apps", extra_data={"access_token": "abcdefg"}
  166. )
  167. integration = Integration.objects.create(provider="github_apps", external_id="1")
  168. self.provider.link_auth(user, organization, {"integration_id": integration.id})
  169. assert OrganizationIntegration.objects.filter(
  170. organization=organization, integration=integration
  171. ).exists()
  172. def test_delete_repository(self):
  173. user = self.create_user()
  174. organization = self.create_organization()
  175. integration = Integration.objects.create(provider="github_apps", external_id="1")
  176. repo = Repository.objects.create(
  177. name="example-repo",
  178. provider="github_apps",
  179. organization_id=organization.id,
  180. integration_id=integration.id,
  181. )
  182. # just check that it doesn't throw / try to delete a webhook
  183. assert self.provider.delete_repository(repo=repo, actor=user) is None
  184. @patch.object(GitHubAppsClient, "get_last_commits", return_value=[])
  185. def test_compare_commits_no_start(self, mock_get_last_commits):
  186. organization = self.create_organization()
  187. integration = Integration.objects.create(provider="github_apps", external_id="1")
  188. repo = Repository.objects.create(
  189. name="example-repo",
  190. provider="github_apps",
  191. organization_id=organization.id,
  192. integration_id=integration.id,
  193. config={"name": "example-repo"},
  194. )
  195. self.provider.compare_commits(repo, None, "a" * 40)
  196. assert mock_get_last_commits.called
  197. @patch.object(GitHubAppsClient, "compare_commits", return_value={"commits": []})
  198. def test_compare_commits(self, mock_compare_commits):
  199. organization = self.create_organization()
  200. integration = Integration.objects.create(provider="github_apps", external_id="1")
  201. repo = Repository.objects.create(
  202. name="example-repo",
  203. provider="github_apps",
  204. organization_id=organization.id,
  205. integration_id=integration.id,
  206. config={"name": "example-repo"},
  207. )
  208. self.provider.compare_commits(repo, "b" * 40, "a" * 40)
  209. assert mock_compare_commits.called