You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

245 lines
11 KiB

  1. package github
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "io/ioutil"
  7. "net/http"
  8. "net/http/httptest"
  9. "strings"
  10. "testing"
  11. "github.com/matrix-org/go-neb/database"
  12. "github.com/matrix-org/go-neb/testutils"
  13. "github.com/matrix-org/go-neb/types"
  14. "github.com/matrix-org/gomatrix"
  15. )
  16. var roomID = "!testroom:id"
  17. func TestGithubWebhook(t *testing.T) {
  18. database.SetServiceDB(&database.NopStorage{})
  19. // Intercept message sending to Matrix and mock responses
  20. msgs := []gomatrix.TextMessage{}
  21. matrixTrans := struct{ testutils.MockTransport }{}
  22. matrixTrans.RT = func(req *http.Request) (*http.Response, error) {
  23. if !strings.Contains(req.URL.String(), "/send/m.room.message") {
  24. return nil, fmt.Errorf("Unhandled URL: %s", req.URL.String())
  25. }
  26. var msg gomatrix.TextMessage
  27. if err := json.NewDecoder(req.Body).Decode(&msg); err != nil {
  28. return nil, fmt.Errorf("Failed to decode request JSON: %s", err)
  29. }
  30. msgs = append(msgs, msg)
  31. return &http.Response{
  32. StatusCode: 200,
  33. Body: ioutil.NopCloser(bytes.NewBufferString(`{"event_id":"$yup:event"}`)),
  34. }, nil
  35. }
  36. matrixCli, _ := gomatrix.NewClient("https://hyrule", "@ghwebhook:hyrule", "its_a_secret")
  37. matrixCli.Client = &http.Client{Transport: matrixTrans}
  38. // create the service
  39. ghwh := makeService(t)
  40. if ghwh == nil {
  41. t.Fatal("TestGithubWebhook Failed to create service")
  42. }
  43. // inject the webhook event request
  44. req, err := http.NewRequest(
  45. "POST", "https://neb.endpoint/gh-webhook-service", bytes.NewBufferString(`
  46. {
  47. "action": "closed",
  48. "issue": {
  49. "url": "https://api.github.com/repos/DummyAccount/reponame/issues/15",
  50. "repository_url": "https://api.github.com/repos/DummyAccount/reponame",
  51. "labels_url": "https://api.github.com/repos/DummyAccount/reponame/issues/15/labels{/name}",
  52. "comments_url": "https://api.github.com/repos/DummyAccount/reponame/issues/15/comments",
  53. "events_url": "https://api.github.com/repos/DummyAccount/reponame/issues/15/events",
  54. "html_url": "https://github.com/DummyAccount/reponame/issues/15",
  55. "id": 159196956,
  56. "number": 15,
  57. "title": "aaaaaa",
  58. "user": {
  59. "login": "DummyAccount",
  60. "id": 7190048,
  61. "avatar_url": "https://avatars.githubusercontent.com/u/7190048?v=3",
  62. "gravatar_id": "",
  63. "url": "https://api.github.com/users/DummyAccount",
  64. "html_url": "https://github.com/DummyAccount",
  65. "followers_url": "https://api.github.com/users/DummyAccount/followers",
  66. "following_url": "https://api.github.com/users/DummyAccount/following{/other_user}",
  67. "gists_url": "https://api.github.com/users/DummyAccount/gists{/gist_id}",
  68. "starred_url": "https://api.github.com/users/DummyAccount/starred{/owner}{/repo}",
  69. "subscriptions_url": "https://api.github.com/users/DummyAccount/subscriptions",
  70. "organizations_url": "https://api.github.com/users/DummyAccount/orgs",
  71. "repos_url": "https://api.github.com/users/DummyAccount/repos",
  72. "events_url": "https://api.github.com/users/DummyAccount/events{/privacy}",
  73. "received_events_url": "https://api.github.com/users/DummyAccount/received_events",
  74. "type": "User",
  75. "site_admin": false
  76. },
  77. "labels": [
  78. ],
  79. "state": "closed",
  80. "locked": false,
  81. "assignee": null,
  82. "milestone": null,
  83. "comments": 1,
  84. "created_at": "2016-06-08T15:40:44Z",
  85. "updated_at": "2016-06-08T15:41:36Z",
  86. "closed_at": "2016-06-08T15:41:36Z",
  87. "body": ""
  88. },
  89. "repository": {
  90. "id": 21138172,
  91. "name": "reponame",
  92. "full_name": "DummyAccount/reponame",
  93. "owner": {
  94. "login": "DummyAccount",
  95. "id": 7190048,
  96. "avatar_url": "https://avatars.githubusercontent.com/u/7190048?v=3",
  97. "gravatar_id": "",
  98. "url": "https://api.github.com/users/DummyAccount",
  99. "html_url": "https://github.com/DummyAccount",
  100. "followers_url": "https://api.github.com/users/DummyAccount/followers",
  101. "following_url": "https://api.github.com/users/DummyAccount/following{/other_user}",
  102. "gists_url": "https://api.github.com/users/DummyAccount/gists{/gist_id}",
  103. "starred_url": "https://api.github.com/users/DummyAccount/starred{/owner}{/repo}",
  104. "subscriptions_url": "https://api.github.com/users/DummyAccount/subscriptions",
  105. "organizations_url": "https://api.github.com/users/DummyAccount/orgs",
  106. "repos_url": "https://api.github.com/users/DummyAccount/repos",
  107. "events_url": "https://api.github.com/users/DummyAccount/events{/privacy}",
  108. "received_events_url": "https://api.github.com/users/DummyAccount/received_events",
  109. "type": "User",
  110. "site_admin": false
  111. },
  112. "private": false,
  113. "html_url": "https://github.com/DummyAccount/reponame",
  114. "description": "Android Development Device Monitor",
  115. "fork": false,
  116. "url": "https://api.github.com/repos/DummyAccount/reponame",
  117. "forks_url": "https://api.github.com/repos/DummyAccount/reponame/forks",
  118. "keys_url": "https://api.github.com/repos/DummyAccount/reponame/keys{/key_id}",
  119. "collaborators_url": "https://api.github.com/repos/DummyAccount/reponame/collaborators{/collaborator}",
  120. "teams_url": "https://api.github.com/repos/DummyAccount/reponame/teams",
  121. "hooks_url": "https://api.github.com/repos/DummyAccount/reponame/hooks",
  122. "issue_events_url": "https://api.github.com/repos/DummyAccount/reponame/issues/events{/number}",
  123. "events_url": "https://api.github.com/repos/DummyAccount/reponame/events",
  124. "assignees_url": "https://api.github.com/repos/DummyAccount/reponame/assignees{/user}",
  125. "branches_url": "https://api.github.com/repos/DummyAccount/reponame/branches{/branch}",
  126. "tags_url": "https://api.github.com/repos/DummyAccount/reponame/tags",
  127. "blobs_url": "https://api.github.com/repos/DummyAccount/reponame/git/blobs{/sha}",
  128. "git_tags_url": "https://api.github.com/repos/DummyAccount/reponame/git/tags{/sha}",
  129. "git_refs_url": "https://api.github.com/repos/DummyAccount/reponame/git/refs{/sha}",
  130. "trees_url": "https://api.github.com/repos/DummyAccount/reponame/git/trees{/sha}",
  131. "statuses_url": "https://api.github.com/repos/DummyAccount/reponame/statuses/{sha}",
  132. "languages_url": "https://api.github.com/repos/DummyAccount/reponame/languages",
  133. "stargazers_url": "https://api.github.com/repos/DummyAccount/reponame/stargazers",
  134. "contributors_url": "https://api.github.com/repos/DummyAccount/reponame/contributors",
  135. "subscribers_url": "https://api.github.com/repos/DummyAccount/reponame/subscribers",
  136. "subscription_url": "https://api.github.com/repos/DummyAccount/reponame/subscription",
  137. "commits_url": "https://api.github.com/repos/DummyAccount/reponame/commits{/sha}",
  138. "git_commits_url": "https://api.github.com/repos/DummyAccount/reponame/git/commits{/sha}",
  139. "comments_url": "https://api.github.com/repos/DummyAccount/reponame/comments{/number}",
  140. "issue_comment_url": "https://api.github.com/repos/DummyAccount/reponame/issues/comments{/number}",
  141. "contents_url": "https://api.github.com/repos/DummyAccount/reponame/contents/{+path}",
  142. "compare_url": "https://api.github.com/repos/DummyAccount/reponame/compare/{base}...{head}",
  143. "merges_url": "https://api.github.com/repos/DummyAccount/reponame/merges",
  144. "archive_url": "https://api.github.com/repos/DummyAccount/reponame/{archive_format}{/ref}",
  145. "downloads_url": "https://api.github.com/repos/DummyAccount/reponame/downloads",
  146. "issues_url": "https://api.github.com/repos/DummyAccount/reponame/issues{/number}",
  147. "pulls_url": "https://api.github.com/repos/DummyAccount/reponame/pulls{/number}",
  148. "milestones_url": "https://api.github.com/repos/DummyAccount/reponame/milestones{/number}",
  149. "notifications_url": "https://api.github.com/repos/DummyAccount/reponame/notifications{?since,all,participating}",
  150. "labels_url": "https://api.github.com/repos/DummyAccount/reponame/labels{/name}",
  151. "releases_url": "https://api.github.com/repos/DummyAccount/reponame/releases{/id}",
  152. "deployments_url": "https://api.github.com/repos/DummyAccount/reponame/deployments",
  153. "created_at": "2014-06-23T18:51:33Z",
  154. "updated_at": "2015-07-22T07:42:19Z",
  155. "pushed_at": "2015-07-22T07:42:19Z",
  156. "git_url": "git://github.com/DummyAccount/reponame.git",
  157. "ssh_url": "git@github.com:DummyAccount/reponame.git",
  158. "clone_url": "https://github.com/DummyAccount/reponame.git",
  159. "svn_url": "https://github.com/DummyAccount/reponame",
  160. "homepage": null,
  161. "size": 725,
  162. "stargazers_count": 0,
  163. "watchers_count": 0,
  164. "language": "Java",
  165. "has_issues": true,
  166. "has_downloads": true,
  167. "has_wiki": true,
  168. "has_pages": false,
  169. "forks_count": 1,
  170. "mirror_url": null,
  171. "open_issues_count": 0,
  172. "forks": 1,
  173. "open_issues": 0,
  174. "watchers": 0,
  175. "default_branch": "master"
  176. },
  177. "sender": {
  178. "login": "DummyAccount",
  179. "id": 7190048,
  180. "avatar_url": "https://avatars.githubusercontent.com/u/7190048?v=3",
  181. "gravatar_id": "",
  182. "url": "https://api.github.com/users/DummyAccount",
  183. "html_url": "https://github.com/DummyAccount",
  184. "followers_url": "https://api.github.com/users/DummyAccount/followers",
  185. "following_url": "https://api.github.com/users/DummyAccount/following{/other_user}",
  186. "gists_url": "https://api.github.com/users/DummyAccount/gists{/gist_id}",
  187. "starred_url": "https://api.github.com/users/DummyAccount/starred{/owner}{/repo}",
  188. "subscriptions_url": "https://api.github.com/users/DummyAccount/subscriptions",
  189. "organizations_url": "https://api.github.com/users/DummyAccount/orgs",
  190. "repos_url": "https://api.github.com/users/DummyAccount/repos",
  191. "events_url": "https://api.github.com/users/DummyAccount/events{/privacy}",
  192. "received_events_url": "https://api.github.com/users/DummyAccount/received_events",
  193. "type": "User",
  194. "site_admin": false
  195. }
  196. }
  197. `),
  198. )
  199. if err != nil {
  200. t.Fatalf("TestGithubWebhook Failed to create webhook request: %s", err)
  201. }
  202. req.Header.Set("X-GitHub-Event", "issues")
  203. req.Header.Set("Content-Type", "application/json")
  204. mockWriter := httptest.NewRecorder()
  205. ghwh.OnReceiveWebhook(mockWriter, req, matrixCli)
  206. // check response
  207. if mockWriter.Code != 200 {
  208. t.Fatalf("TestGithubWebhook Expected response 200 OK, got %d", mockWriter.Code)
  209. }
  210. if len(msgs) != 1 {
  211. t.Fatalf("TestGithubWebhook Expected sent 1 msg, sent %d", len(msgs))
  212. }
  213. }
  214. func makeService(t *testing.T) *WebhookService {
  215. srv, err := types.CreateService("id", WebhookServiceType, "@ghwebhook:hyrule", []byte(
  216. `{
  217. "ClientUserID": "@alice:hyrule",
  218. "RealmID": "ghrealm",
  219. "Rooms":{
  220. "`+roomID+`": {
  221. "Repos": {
  222. "DummyAccount/reponame": {
  223. "Events": ["issues"]
  224. }
  225. }
  226. }
  227. }
  228. }`,
  229. ))
  230. if err != nil {
  231. t.Error("Failed to create GH webhook service: ", err)
  232. return nil
  233. }
  234. return srv.(*WebhookService)
  235. }