package github import ( "bytes" "encoding/json" "fmt" "io/ioutil" "net/http" "net/http/httptest" "strings" "testing" "github.com/matrix-org/go-neb/database" "github.com/matrix-org/go-neb/testutils" "github.com/matrix-org/go-neb/types" "maunium.net/go/mautrix" mevt "maunium.net/go/mautrix/event" ) var roomID = "!testroom:id" func TestGithubWebhook(t *testing.T) { database.SetServiceDB(&database.NopStorage{}) // Intercept message sending to Matrix and mock responses msgs := []mevt.MessageEventContent{} matrixTrans := struct{ testutils.MockTransport }{} matrixTrans.RT = func(req *http.Request) (*http.Response, error) { if !strings.Contains(req.URL.String(), "/send/m.room.message") { return nil, fmt.Errorf("Unhandled URL: %s", req.URL.String()) } var msg mevt.MessageEventContent if err := json.NewDecoder(req.Body).Decode(&msg); err != nil { return nil, fmt.Errorf("Failed to decode request JSON: %s", err) } msgs = append(msgs, msg) return &http.Response{ StatusCode: 200, Body: ioutil.NopCloser(bytes.NewBufferString(`{"event_id":"$yup:event"}`)), }, nil } matrixCli, _ := mautrix.NewClient("https://hyrule", "@ghwebhook:hyrule", "its_a_secret") matrixCli.Client = &http.Client{Transport: matrixTrans} // create the service ghwh := makeService(t) if ghwh == nil { t.Fatal("TestGithubWebhook Failed to create service") } // inject the webhook event request req, err := http.NewRequest( "POST", "https://neb.endpoint/gh-webhook-service", bytes.NewBufferString(` { "action": "closed", "issue": { "url": "https://api.github.com/repos/DummyAccount/reponame/issues/15", "repository_url": "https://api.github.com/repos/DummyAccount/reponame", "labels_url": "https://api.github.com/repos/DummyAccount/reponame/issues/15/labels{/name}", "comments_url": "https://api.github.com/repos/DummyAccount/reponame/issues/15/comments", "events_url": "https://api.github.com/repos/DummyAccount/reponame/issues/15/events", "html_url": "https://github.com/DummyAccount/reponame/issues/15", "id": 159196956, "number": 15, "title": "aaaaaa", "user": { "login": "DummyAccount", "id": 7190048, "avatar_url": "https://avatars.githubusercontent.com/u/7190048?v=3", "gravatar_id": "", "url": "https://api.github.com/users/DummyAccount", "html_url": "https://github.com/DummyAccount", "followers_url": "https://api.github.com/users/DummyAccount/followers", "following_url": "https://api.github.com/users/DummyAccount/following{/other_user}", "gists_url": "https://api.github.com/users/DummyAccount/gists{/gist_id}", "starred_url": "https://api.github.com/users/DummyAccount/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/DummyAccount/subscriptions", "organizations_url": "https://api.github.com/users/DummyAccount/orgs", "repos_url": "https://api.github.com/users/DummyAccount/repos", "events_url": "https://api.github.com/users/DummyAccount/events{/privacy}", "received_events_url": "https://api.github.com/users/DummyAccount/received_events", "type": "User", "site_admin": false }, "labels": [ ], "state": "closed", "locked": false, "assignee": null, "milestone": null, "comments": 1, "created_at": "2016-06-08T15:40:44Z", "updated_at": "2016-06-08T15:41:36Z", "closed_at": "2016-06-08T15:41:36Z", "body": "" }, "repository": { "id": 21138172, "name": "reponame", "full_name": "DummyAccount/reponame", "owner": { "login": "DummyAccount", "id": 7190048, "avatar_url": "https://avatars.githubusercontent.com/u/7190048?v=3", "gravatar_id": "", "url": "https://api.github.com/users/DummyAccount", "html_url": "https://github.com/DummyAccount", "followers_url": "https://api.github.com/users/DummyAccount/followers", "following_url": "https://api.github.com/users/DummyAccount/following{/other_user}", "gists_url": "https://api.github.com/users/DummyAccount/gists{/gist_id}", "starred_url": "https://api.github.com/users/DummyAccount/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/DummyAccount/subscriptions", "organizations_url": "https://api.github.com/users/DummyAccount/orgs", "repos_url": "https://api.github.com/users/DummyAccount/repos", "events_url": "https://api.github.com/users/DummyAccount/events{/privacy}", "received_events_url": "https://api.github.com/users/DummyAccount/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/DummyAccount/reponame", "description": "Android Development Device Monitor", "fork": false, "url": "https://api.github.com/repos/DummyAccount/reponame", "forks_url": "https://api.github.com/repos/DummyAccount/reponame/forks", "keys_url": "https://api.github.com/repos/DummyAccount/reponame/keys{/key_id}", "collaborators_url": "https://api.github.com/repos/DummyAccount/reponame/collaborators{/collaborator}", "teams_url": "https://api.github.com/repos/DummyAccount/reponame/teams", "hooks_url": "https://api.github.com/repos/DummyAccount/reponame/hooks", "issue_events_url": "https://api.github.com/repos/DummyAccount/reponame/issues/events{/number}", "events_url": "https://api.github.com/repos/DummyAccount/reponame/events", "assignees_url": "https://api.github.com/repos/DummyAccount/reponame/assignees{/user}", "branches_url": "https://api.github.com/repos/DummyAccount/reponame/branches{/branch}", "tags_url": "https://api.github.com/repos/DummyAccount/reponame/tags", "blobs_url": "https://api.github.com/repos/DummyAccount/reponame/git/blobs{/sha}", "git_tags_url": "https://api.github.com/repos/DummyAccount/reponame/git/tags{/sha}", "git_refs_url": "https://api.github.com/repos/DummyAccount/reponame/git/refs{/sha}", "trees_url": "https://api.github.com/repos/DummyAccount/reponame/git/trees{/sha}", "statuses_url": "https://api.github.com/repos/DummyAccount/reponame/statuses/{sha}", "languages_url": "https://api.github.com/repos/DummyAccount/reponame/languages", "stargazers_url": "https://api.github.com/repos/DummyAccount/reponame/stargazers", "contributors_url": "https://api.github.com/repos/DummyAccount/reponame/contributors", "subscribers_url": "https://api.github.com/repos/DummyAccount/reponame/subscribers", "subscription_url": "https://api.github.com/repos/DummyAccount/reponame/subscription", "commits_url": "https://api.github.com/repos/DummyAccount/reponame/commits{/sha}", "git_commits_url": "https://api.github.com/repos/DummyAccount/reponame/git/commits{/sha}", "comments_url": "https://api.github.com/repos/DummyAccount/reponame/comments{/number}", "issue_comment_url": "https://api.github.com/repos/DummyAccount/reponame/issues/comments{/number}", "contents_url": "https://api.github.com/repos/DummyAccount/reponame/contents/{+path}", "compare_url": "https://api.github.com/repos/DummyAccount/reponame/compare/{base}...{head}", "merges_url": "https://api.github.com/repos/DummyAccount/reponame/merges", "archive_url": "https://api.github.com/repos/DummyAccount/reponame/{archive_format}{/ref}", "downloads_url": "https://api.github.com/repos/DummyAccount/reponame/downloads", "issues_url": "https://api.github.com/repos/DummyAccount/reponame/issues{/number}", "pulls_url": "https://api.github.com/repos/DummyAccount/reponame/pulls{/number}", "milestones_url": "https://api.github.com/repos/DummyAccount/reponame/milestones{/number}", "notifications_url": "https://api.github.com/repos/DummyAccount/reponame/notifications{?since,all,participating}", "labels_url": "https://api.github.com/repos/DummyAccount/reponame/labels{/name}", "releases_url": "https://api.github.com/repos/DummyAccount/reponame/releases{/id}", "deployments_url": "https://api.github.com/repos/DummyAccount/reponame/deployments", "created_at": "2014-06-23T18:51:33Z", "updated_at": "2015-07-22T07:42:19Z", "pushed_at": "2015-07-22T07:42:19Z", "git_url": "git://github.com/DummyAccount/reponame.git", "ssh_url": "git@github.com:DummyAccount/reponame.git", "clone_url": "https://github.com/DummyAccount/reponame.git", "svn_url": "https://github.com/DummyAccount/reponame", "homepage": null, "size": 725, "stargazers_count": 0, "watchers_count": 0, "language": "Java", "has_issues": true, "has_downloads": true, "has_wiki": true, "has_pages": false, "forks_count": 1, "mirror_url": null, "open_issues_count": 0, "forks": 1, "open_issues": 0, "watchers": 0, "default_branch": "master" }, "sender": { "login": "DummyAccount", "id": 7190048, "avatar_url": "https://avatars.githubusercontent.com/u/7190048?v=3", "gravatar_id": "", "url": "https://api.github.com/users/DummyAccount", "html_url": "https://github.com/DummyAccount", "followers_url": "https://api.github.com/users/DummyAccount/followers", "following_url": "https://api.github.com/users/DummyAccount/following{/other_user}", "gists_url": "https://api.github.com/users/DummyAccount/gists{/gist_id}", "starred_url": "https://api.github.com/users/DummyAccount/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/DummyAccount/subscriptions", "organizations_url": "https://api.github.com/users/DummyAccount/orgs", "repos_url": "https://api.github.com/users/DummyAccount/repos", "events_url": "https://api.github.com/users/DummyAccount/events{/privacy}", "received_events_url": "https://api.github.com/users/DummyAccount/received_events", "type": "User", "site_admin": false } } `), ) if err != nil { t.Fatalf("TestGithubWebhook Failed to create webhook request: %s", err) } req.Header.Set("X-GitHub-Event", "issues") req.Header.Set("Content-Type", "application/json") mockWriter := httptest.NewRecorder() ghwh.OnReceiveWebhook(mockWriter, req, matrixCli) // check response if mockWriter.Code != 200 { t.Fatalf("TestGithubWebhook Expected response 200 OK, got %d", mockWriter.Code) } if len(msgs) != 1 { t.Fatalf("TestGithubWebhook Expected sent 1 msg, sent %d", len(msgs)) } } func makeService(t *testing.T) *WebhookService { srv, err := types.CreateService("id", WebhookServiceType, "@ghwebhook:hyrule", []byte( `{ "ClientUserID": "@alice:hyrule", "RealmID": "ghrealm", "Rooms":{ "`+roomID+`": { "Repos": { "DummyAccount/reponame": { "Events": ["issues"] } } } } }`, )) if err != nil { t.Error("Failed to create GH webhook service: ", err) return nil } return srv.(*WebhookService) }