From 3a8b4a6aca4de0361e5bc301cc4afd6300d616f1 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Wed, 16 Nov 2016 11:51:58 +0000 Subject: [PATCH] Add working test and implement template parsing --- .../go-neb/services/travisci/travisci.go | 74 ++++++++----------- .../go-neb/services/travisci/travisci_test.go | 24 ++++-- 2 files changed, 47 insertions(+), 51 deletions(-) diff --git a/src/github.com/matrix-org/go-neb/services/travisci/travisci.go b/src/github.com/matrix-org/go-neb/services/travisci/travisci.go index fa82a5a..7391268 100644 --- a/src/github.com/matrix-org/go-neb/services/travisci/travisci.go +++ b/src/github.com/matrix-org/go-neb/services/travisci/travisci.go @@ -106,44 +106,26 @@ type webhookNotification struct { } `json:"repository"` } -// The template variables a user can use in their messages -type notificationTemplate struct { - RepositorySlug string - Repository string // Deprecated: alias for RepositorySlug - RepositoryName string - BuildNumber string - BuildID string - Branch string - Commit string - Author string - CommitMessage string - CommitSubject string - Result string - Message string - Duration string - ElapsedTime string - CompareURL string - BuildURL string -} - -func notifToTemplate(n webhookNotification) (t notificationTemplate) { - t.RepositorySlug = n.Repository.OwnerName + "/" + n.Repository.Name - t.Repository = t.RepositorySlug - t.RepositoryName = n.Repository.Name - t.BuildNumber = n.Number - t.BuildID = strconv.Itoa(n.ID) - t.Branch = n.Branch - t.Commit = n.Commit - t.Author = n.CommitterName // author: commit author name +// Converts a webhook notification into a map of template var name to value +func notifToTemplate(n webhookNotification) map[string]string { + t := make(map[string]string) + t["repository_slug"] = n.Repository.OwnerName + "/" + n.Repository.Name + t["repository"] = t["repository_slug"] // Deprecated form but still used everywhere in people's templates + t["repository_name"] = n.Repository.Name + t["build_number"] = n.Number + t["build_id"] = strconv.Itoa(n.ID) + t["branch"] = n.Branch + t["commit"] = n.Commit + t["author"] = n.CommitterName // author: commit author name // commit_message: commit message of build // commit_subject: first line of the commit message - t.CommitMessage = n.Message + t["commit_message"] = n.Message subjAndMsg := strings.SplitN(n.Message, "\n", 2) - t.CommitSubject = subjAndMsg[0] + t["commit_subject"] = subjAndMsg[0] if n.Status != nil { - t.Result = strconv.Itoa(*n.Status) + t["result"] = strconv.Itoa(*n.Status) } - t.Message = n.StatusMessage + t["message"] = n.StatusMessage if n.StartedAt != nil && n.FinishedAt != nil { // duration: total duration of all builds in the matrix -- TODO @@ -157,18 +139,22 @@ func notifToTemplate(n webhookNotification) (t notificationTemplate) { "finished_at": *n.FinishedAt, }).Warn("Failed to parse Travis-CI start/finish times.") } else { - t.Duration = finish.Sub(start).String() - t.ElapsedTime = t.Duration + t["duration"] = finish.Sub(start).String() + t["elapsed_time"] = t["duration"] } } - t.CompareURL = n.CompareURL - t.BuildURL = n.BuildURL - return + t["compare_url"] = n.CompareURL + t["build_url"] = n.BuildURL + return t } -func travisToGoTemplate(travisTmpl string) (goTmpl string) { - return +func outputForTemplate(travisTmpl string, tmpl map[string]string) (out string) { + out = travisTmpl + for tmplVar, tmplValue := range tmpl { + out = strings.Replace(out, "%{"+tmplVar+"}", tmplValue, -1) + } + return out } // OnReceiveWebhook receives requests from Travis-CI and possibly sends requests to Matrix as a result. @@ -215,7 +201,7 @@ func (s *Service) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli return } whForRepo := notif.Repository.OwnerName + "/" + notif.Repository.Name - // TODO tmplData := notifToTemplate(notif) + tmplData := notifToTemplate(notif) logger := log.WithFields(log.Fields{ "repo": whForRepo, @@ -226,8 +212,10 @@ func (s *Service) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli if ownerRepo != whForRepo { continue } - tmpl := travisToGoTemplate(repoData.Template) - msg := tmpl // TODO + msg := matrix.TextMessage{ + Body: outputForTemplate(repoData.Template, tmplData), + MsgType: "m.notice", + } logger.WithFields(log.Fields{ "msg": msg, diff --git a/src/github.com/matrix-org/go-neb/services/travisci/travisci_test.go b/src/github.com/matrix-org/go-neb/services/travisci/travisci_test.go index 1848a81..0affa2f 100644 --- a/src/github.com/matrix-org/go-neb/services/travisci/travisci_test.go +++ b/src/github.com/matrix-org/go-neb/services/travisci/travisci_test.go @@ -4,15 +4,16 @@ import ( "bytes" "encoding/json" "fmt" - "github.com/matrix-org/go-neb/database" - "github.com/matrix-org/go-neb/matrix" - "github.com/matrix-org/go-neb/types" "io/ioutil" "net/http" "net/http/httptest" "net/url" "strings" "testing" + + "github.com/matrix-org/go-neb/database" + "github.com/matrix-org/go-neb/matrix" + "github.com/matrix-org/go-neb/types" ) const travisOrgPEMPublicKey = (`-----BEGIN PUBLIC KEY----- @@ -70,7 +71,7 @@ var travisTests = []struct { { exampleSignature, true, exampleBody, "%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message}", - "Kegsay/flow-jsdoc#22 master - 3a092c3a6032ebb50384c99b445f947e9ce86e2a : Kegan Dougal: Test Travis webhook support", + "Kegsay/flow-jsdoc#18 (master - 3a092c3a6032ebb50384c99b445f947e9ce86e2a : Kegan Dougal): Passed", }, } @@ -106,15 +107,15 @@ func TestTravisCI(t *testing.T) { httpClient = &http.Client{Transport: travisTransport} // Intercept message sending to Matrix and mock responses - msgs := []matrix.HTMLMessage{} + msgs := []matrix.TextMessage{} matrixTrans := struct{ MockTransport }{} matrixTrans.roundTrip = 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 matrix.HTMLMessage + var msg matrix.TextMessage if err := json.NewDecoder(req.Body).Decode(&msg); err != nil { - return nil, err + return nil, fmt.Errorf("Failed to decode request JSON: %s", err) } msgs = append(msgs, msg) return &http.Response{ @@ -128,7 +129,7 @@ func TestTravisCI(t *testing.T) { // BEGIN running the Travis-CI table tests // --------------------------------------- for _, test := range travisTests { - msgs = []matrix.HTMLMessage{} // reset sent messages + msgs = []matrix.TextMessage{} // reset sent messages mockWriter := httptest.NewRecorder() travis := makeService(t, test.Template) if travis == nil { @@ -153,6 +154,13 @@ func TestTravisCI(t *testing.T) { if mockWriter.Code != 200 { t.Errorf("TestTravisCI OnReceiveWebhook want code %d, got %d", 200, mockWriter.Code) } + if len(msgs) != 1 { + t.Errorf("TestTravisCI want sent messages %d, got %d ", 1, len(msgs)) + continue + } + if msgs[0].Body != test.ExpectedOutput { + t.Errorf("TestTravisCI want matrix body '%s', got '%s'", test.ExpectedOutput, msgs[0].Body) + } } }