gitlab.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. from time import time
  2. from sentry.models import Identity, IdentityProvider, Integration, Repository
  3. from sentry.testutils import APITestCase
  4. EXTERNAL_ID = "example.gitlab.com:group-x"
  5. WEBHOOK_SECRET = "secret-token-value"
  6. WEBHOOK_TOKEN = f"{EXTERNAL_ID}:{WEBHOOK_SECRET}"
  7. class GitLabTestCase(APITestCase):
  8. provider = "gitlab"
  9. def setUp(self):
  10. self.login_as(self.user)
  11. self.integration = Integration.objects.create(
  12. provider=self.provider,
  13. name="Example Gitlab",
  14. external_id=EXTERNAL_ID,
  15. metadata={
  16. "instance": "example.gitlab.com",
  17. "base_url": "https://example.gitlab.com",
  18. "domain_name": "example.gitlab.com/group-x",
  19. "verify_ssl": False,
  20. "webhook_secret": WEBHOOK_SECRET,
  21. "group_id": 1,
  22. },
  23. )
  24. identity = Identity.objects.create(
  25. idp=IdentityProvider.objects.create(type=self.provider, config={}),
  26. user=self.user,
  27. external_id="gitlab123",
  28. data={"access_token": "123456789", "created_at": time(), "refresh_token": "0987654321"},
  29. )
  30. self.integration.add_organization(self.organization, self.user, identity.id)
  31. self.installation = self.integration.get_installation(self.organization.id)
  32. def create_repo(self, name, external_id=15, url=None, organization_id=None):
  33. instance = self.integration.metadata["instance"]
  34. organization_id = organization_id or self.organization.id
  35. return Repository.objects.create(
  36. organization_id=organization_id,
  37. name=name,
  38. external_id=f"{instance}:{external_id}",
  39. url=url,
  40. config={"project_id": external_id, "path": "example-repo"},
  41. provider="integrations:gitlab",
  42. integration_id=self.integration.id,
  43. )
  44. MERGE_REQUEST_OPENED_EVENT = b"""{
  45. "object_kind": "merge_request",
  46. "user": {
  47. "name": "Administrator",
  48. "username": "root",
  49. "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"
  50. },
  51. "project": {
  52. "id": 15,
  53. "name": "Sentry",
  54. "description": "",
  55. "web_url": "http://example.com/cool-group/sentry",
  56. "avatar_url": null,
  57. "git_ssh_url": "git@example.com:cool-group/sentry.git",
  58. "git_http_url": "http://example.com/cool-group/sentry.git",
  59. "namespace": "cool-group",
  60. "visibility_level": 0,
  61. "path_with_namespace": "cool-group/sentry",
  62. "default_branch": "master",
  63. "ci_config_path": "",
  64. "homepage": "http://example.com/cool-group/sentry",
  65. "url": "git@example.com:cool-group/sentry.git",
  66. "ssh_url": "git@example.com:cool-group/sentry.git",
  67. "http_url": "http://example.com/cool-group/sentry.git"
  68. },
  69. "object_attributes": {
  70. "id": 90,
  71. "target_branch": "master",
  72. "source_branch": "ms-viewport",
  73. "source_project_id": 14,
  74. "author_id": 51,
  75. "assignee_id": 6,
  76. "title": "Create a new Viewport",
  77. "created_at": "2017-09-20T08:31:45.944Z",
  78. "updated_at": "2017-09-28T12:23:42.365Z",
  79. "milestone_id": null,
  80. "state": "opened",
  81. "merge_status": "unchecked",
  82. "target_project_id": 14,
  83. "iid": 1,
  84. "description": "Create a viewport for things Fixes BAR-9",
  85. "updated_by_id": 1,
  86. "merge_error": null,
  87. "merge_params": {
  88. "force_remove_source_branch": "0"
  89. },
  90. "merge_when_pipeline_succeeds": false,
  91. "merge_user_id": null,
  92. "merge_commit_sha": null,
  93. "deleted_at": null,
  94. "in_progress_merge_commit_sha": null,
  95. "lock_version": 5,
  96. "time_estimate": 0,
  97. "last_edited_at": "2017-09-27T12:43:37.558Z",
  98. "last_edited_by_id": 1,
  99. "head_pipeline_id": 61,
  100. "ref_fetched": true,
  101. "merge_jid": null,
  102. "source": {
  103. "name": "Awesome Project",
  104. "description": "",
  105. "web_url": "http://example.com/awesome_space/awesome_project",
  106. "avatar_url": null,
  107. "git_ssh_url": "git@example.com:awesome_space/awesome_project.git",
  108. "git_http_url": "http://example.com/awesome_space/awesome_project.git",
  109. "namespace": "root",
  110. "visibility_level": 0,
  111. "path_with_namespace": "awesome_space/awesome_project",
  112. "default_branch": "master",
  113. "ci_config_path": "",
  114. "homepage": "http://example.com/awesome_space/awesome_project",
  115. "url": "http://example.com/awesome_space/awesome_project.git",
  116. "ssh_url": "git@example.com:awesome_space/awesome_project.git",
  117. "http_url": "http://example.com/awesome_space/awesome_project.git"
  118. },
  119. "target": {
  120. "name": "Awesome Project",
  121. "description": "Aut reprehenderit ut est.",
  122. "web_url": "http://example.com/awesome_space/awesome_project",
  123. "avatar_url": null,
  124. "git_ssh_url": "git@example.com:awesome_space/awesome_project.git",
  125. "git_http_url": "http://example.com/awesome_space/awesome_project.git",
  126. "namespace": "Awesome Space",
  127. "visibility_level": 0,
  128. "path_with_namespace": "awesome_space/awesome_project",
  129. "default_branch": "master",
  130. "ci_config_path": "",
  131. "homepage": "http://example.com/awesome_space/awesome_project",
  132. "url": "http://example.com/awesome_space/awesome_project.git",
  133. "ssh_url": "git@example.com:awesome_space/awesome_project.git",
  134. "http_url": "http://example.com/awesome_space/awesome_project.git"
  135. },
  136. "last_commit": {
  137. "id": "ba3e0d8ff79c80d5b0bbb4f3e2e343e0aaa662b7",
  138. "message": "fixed readme",
  139. "timestamp": "2017-09-26T16:12:57Z",
  140. "url": "http://example.com/awesome_space/awesome_project/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
  141. "author": {
  142. "name": "GitLab dev user",
  143. "email": "gitlabdev@dv6700.(none)"
  144. }
  145. },
  146. "work_in_progress": false,
  147. "total_time_spent": 0,
  148. "human_total_time_spent": null,
  149. "human_time_estimate": null
  150. },
  151. "labels": null,
  152. "repository": {
  153. "name": "git-gpg-test",
  154. "url": "git@example.com:awesome_space/awesome_project.git",
  155. "description": "",
  156. "homepage": "http://example.com/awesome_space/awesome_project"
  157. }
  158. }"""
  159. PUSH_EVENT = b"""
  160. {
  161. "object_kind": "push",
  162. "before": "95790bf891e76fee5e1747ab589903a6a1f80f22",
  163. "after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
  164. "ref": "refs/heads/master",
  165. "checkout_sha": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
  166. "user_id": 4,
  167. "user_name": "John Smith",
  168. "user_username": "jsmith",
  169. "user_email": "john@example.com",
  170. "user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80",
  171. "project_id": 15,
  172. "project":{
  173. "id": 15,
  174. "name":"Sentry",
  175. "description":"",
  176. "web_url":"http://example.com/cool-group/sentry",
  177. "avatar_url":null,
  178. "git_ssh_url":"git@example.com:cool-group/sentry.git",
  179. "git_http_url":"http://example.com/cool-group/sentry.git",
  180. "namespace":"Cool Group",
  181. "visibility_level":0,
  182. "path_with_namespace":"cool-group/sentry",
  183. "default_branch":"master",
  184. "homepage":"http://example.com/cool-group/sentry",
  185. "url":"git@example.com:cool-group/sentry.git",
  186. "ssh_url":"git@example.com:cool-group/sentry.git",
  187. "http_url":"http://example.com/cool-group/sentry.git"
  188. },
  189. "repository":{
  190. "name": "Sentry",
  191. "url": "git@example.com:cool-group/sentry.git",
  192. "description": "",
  193. "homepage": "http://example.com/cool-group/sentry",
  194. "git_http_url":"http://example.com/cool-group/sentry.git",
  195. "git_ssh_url":"git@example.com:cool-group/sentry.git",
  196. "visibility_level":0
  197. },
  198. "commits": [
  199. {
  200. "id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
  201. "message": "Update Catalan translation to e38cb41.",
  202. "timestamp": "2011-12-12T14:27:31+02:00",
  203. "url": "http://example.com/cool-group/sentry/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
  204. "author": {
  205. "name": "Jordi",
  206. "email": "jordi@example.org"
  207. },
  208. "added": ["CHANGELOG"],
  209. "modified": ["app/controller/application.rb"],
  210. "removed": []
  211. },
  212. {
  213. "id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
  214. "message": "fixed readme",
  215. "timestamp": "2012-01-03T23:36:29+02:00",
  216. "url": "http://example.com/cool-group/sentry/commit/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
  217. "author": {
  218. "name": "GitLab dev user",
  219. "email": "gitlabdev@example.org"
  220. },
  221. "added": ["CHANGELOG"],
  222. "modified": ["app/controller/application.rb"],
  223. "removed": []
  224. }
  225. ],
  226. "total_commits_count": 2
  227. }
  228. """
  229. PUSH_EVENT_IGNORED_COMMIT = b"""
  230. {
  231. "object_kind": "push",
  232. "before": "95790bf891e76fee5e1747ab589903a6a1f80f22",
  233. "after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
  234. "ref": "refs/heads/master",
  235. "checkout_sha": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
  236. "user_id": 4,
  237. "user_name": "John Smith",
  238. "user_username": "jsmith",
  239. "user_email": "john@example.com",
  240. "user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80",
  241. "project_id": 15,
  242. "project":{
  243. "id": 15,
  244. "name":"Sentry",
  245. "description":"",
  246. "web_url":"http://example.com/cool-group/sentry",
  247. "avatar_url":null,
  248. "git_ssh_url":"git@example.com:cool-group/sentry.git",
  249. "git_http_url":"http://example.com/cool-group/sentry.git",
  250. "namespace":"cool-group",
  251. "visibility_level":0,
  252. "path_with_namespace":"cool-group/sentry",
  253. "default_branch":"master",
  254. "homepage":"http://example.com/cool-group/sentry",
  255. "url":"git@example.com:cool-group/sentry.git",
  256. "ssh_url":"git@example.com:cool-group/sentry.git",
  257. "http_url":"http://example.com/cool-group/sentry.git"
  258. },
  259. "repository":{
  260. "name": "Sentry",
  261. "url": "git@example.com:cool-group/sentry.git",
  262. "description": "",
  263. "homepage": "http://example.com/cool-group/sentry",
  264. "git_http_url":"http://example.com/cool-group/sentry.git",
  265. "git_ssh_url":"git@example.com:cool-group/sentry.git",
  266. "visibility_level":0
  267. },
  268. "commits": [
  269. {
  270. "id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
  271. "message": "Update things #skipsentry",
  272. "timestamp": "2011-12-12T14:27:31+02:00",
  273. "url": "http://example.com/cool-group/sentry/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
  274. "author": {
  275. "name": "Jordi",
  276. "email": "jordi@example.org"
  277. },
  278. "added": ["CHANGELOG"],
  279. "modified": ["app/controller/application.rb"],
  280. "removed": []
  281. }
  282. ],
  283. "total_commits_count": 1
  284. }
  285. """
  286. COMPARE_RESPONSE = r"""
  287. {
  288. "commit": {
  289. "id": "12d65c8dd2b2676fa3ac47d955accc085a37a9c1",
  290. "short_id": "12d65c8dd2b",
  291. "title": "JS fix",
  292. "author_name": "Dmitriy",
  293. "author_email": "dmitriy@example.com",
  294. "created_at": "2014-02-27T10:27:00+02:00"
  295. },
  296. "commits": [{
  297. "id": "12d65c8dd2b2676fa3ac47d955accc085a37a9c1",
  298. "short_id": "12d65c8dd2b",
  299. "title": "JS fix",
  300. "author_name": "Dmitriy",
  301. "author_email": "dmitriy@example.com",
  302. "created_at": "2014-02-27T10:27:00+02:00"
  303. },
  304. {
  305. "id": "8b090c1b79a14f2bd9e8a738f717824ff53aebad",
  306. "short_id": "8b090c1b",
  307. "title": "Fix dmitriy mistake",
  308. "author_name": "Sally",
  309. "author_email": "sally@example.com",
  310. "created_at": "2014-02-27T10:27:00+02:00"
  311. }],
  312. "diffs": [{
  313. "old_path": "files/js/application.js",
  314. "new_path": "files/js/application.js",
  315. "a_mode": null,
  316. "b_mode": "100644",
  317. "diff": "--- a/files/js/application.js\n+++ b/files/js/application.js\n@@ -24,8 +24,10 @@\n //= require g.raphael-min\n //= require g.bar-min\n //= require branch-graph\n-//= require highlightjs.min\n-//= require ace/ace\n //= require_tree .\n //= require d3\n //= require underscore\n+\n+function fix() { \n+ alert(\"Fixed\")\n+}",
  318. "new_file": false,
  319. "renamed_file": false,
  320. "deleted_file": false
  321. }],
  322. "compare_timeout": false,
  323. "compare_same_ref": false
  324. }
  325. """
  326. COMMIT_LIST_RESPONSE = r"""
  327. [
  328. {
  329. "id": "ed899a2f4b50b4370feeea94676502b42383c746",
  330. "short_id": "ed899a2f4b5",
  331. "title": "Replace sanitize with escape once",
  332. "author_name": "Dmitriy",
  333. "author_email": "dmitriy@example.com",
  334. "authored_date": "2018-09-20T11:50:22+03:00",
  335. "committer_name": "Administrator",
  336. "committer_email": "admin@example.com",
  337. "committed_date": "2018-09-20T11:50:22+03:00",
  338. "created_at": "2018-09-20T11:50:22+03:00",
  339. "message": "Replace sanitize with escape once",
  340. "parent_ids": [
  341. "6104942438c14ec7bd21c6cd5bd995272b3faff6"
  342. ]
  343. },
  344. {
  345. "id": "6104942438c14ec7bd21c6cd5bd995272b3faff6",
  346. "short_id": "6104942438c",
  347. "title": "Sanitize for network graph",
  348. "author_name": "randx",
  349. "author_email": "dmitriy@example.com",
  350. "committer_name": "Dmitriy",
  351. "committer_email": "dmitriy@example.com",
  352. "created_at": "2018-09-20T09:06:12+03:00",
  353. "message": "Sanitize for network graph",
  354. "parent_ids": [
  355. "ae1d9fb46aa2b07ee9836d49862ec4e2c46fbbba"
  356. ]
  357. }
  358. ]
  359. """
  360. COMMIT_DIFF_RESPONSE = r"""
  361. [
  362. {
  363. "old_path": "files/js/application.js",
  364. "new_path": "files/js/application.js",
  365. "a_mode": null,
  366. "b_mode": "100644",
  367. "diff": "--- a/files/js/application.js\n+++ b/files/js/application.js\n@@ -24,8 +24,10 @@\n //= require g.raphael-min\n //= require g.bar-min\n //= require branch-graph\n-//= require highlightjs.min\n-//= require ace/ace\n //= require_tree .\n //= require d3\n //= require underscore\n+\n+function fix() { \n+ alert(\"Fixed\")\n+}",
  368. "new_file": false,
  369. "renamed_file": false,
  370. "deleted_file": false
  371. },
  372. {
  373. "a_mode": "100644",
  374. "b_mode": "100644",
  375. "deleted_file": false,
  376. "diff": "@@ -1 +1,3 @@\n OH HAI\n+OH HAI\n+OH HAI\n",
  377. "new_file": false,
  378. "new_path": "README.txt",
  379. "old_path": "README.txt",
  380. "renamed_file": false
  381. }
  382. ]
  383. """
  384. # Example taken from https://docs.gitlab.com/ee/api/commits.html#get-a-single-commit
  385. GET_COMMIT_RESPONSE = """
  386. {
  387. "id": "6104942438c14ec7bd21c6cd5bd995272b3faff6",
  388. "short_id": "6104942438c",
  389. "title": "Sanitize for network graph",
  390. "author_name": "randx",
  391. "author_email": "user@example.com",
  392. "committer_name": "Dmitriy",
  393. "committer_email": "user@example.com",
  394. "created_at": "2021-09-20T09:06:12.300+03:00",
  395. "message": "Sanitize for network graph",
  396. "committed_date": "2021-09-20T09:06:12.300+03:00",
  397. "authored_date": "2021-09-20T09:06:12.420+03:00",
  398. "parent_ids": [
  399. "ae1d9fb46aa2b07ee9836d49862ec4e2c46fbbba"
  400. ],
  401. "last_pipeline" : {
  402. "id": 8,
  403. "ref": "master",
  404. "sha": "2dc6aa325a317eda67812f05600bdf0fcdc70ab0",
  405. "status": "created"
  406. },
  407. "stats": {
  408. "additions": 15,
  409. "deletions": 10,
  410. "total": 25
  411. },
  412. "status": "running",
  413. "web_url": "https://gitlab.example.com/thedude/gitlab-foss/-/commit/6104942438c14ec7bd21c6cd5bd995272b3faff6"
  414. }"""