Browse Source

Add working test and implement template parsing

kegan/travis
Kegan Dougal 8 years ago
parent
commit
3a8b4a6aca
  1. 74
      src/github.com/matrix-org/go-neb/services/travisci/travisci.go
  2. 24
      src/github.com/matrix-org/go-neb/services/travisci/travisci_test.go

74
src/github.com/matrix-org/go-neb/services/travisci/travisci.go

@ -106,44 +106,26 @@ type webhookNotification struct {
} `json:"repository"` } `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_message: commit message of build
// commit_subject: first line of the commit message // commit_subject: first line of the commit message
t.CommitMessage = n.Message
t["commit_message"] = n.Message
subjAndMsg := strings.SplitN(n.Message, "\n", 2) subjAndMsg := strings.SplitN(n.Message, "\n", 2)
t.CommitSubject = subjAndMsg[0]
t["commit_subject"] = subjAndMsg[0]
if n.Status != nil { 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 { if n.StartedAt != nil && n.FinishedAt != nil {
// duration: total duration of all builds in the matrix -- TODO // duration: total duration of all builds in the matrix -- TODO
@ -157,18 +139,22 @@ func notifToTemplate(n webhookNotification) (t notificationTemplate) {
"finished_at": *n.FinishedAt, "finished_at": *n.FinishedAt,
}).Warn("Failed to parse Travis-CI start/finish times.") }).Warn("Failed to parse Travis-CI start/finish times.")
} else { } 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. // 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 return
} }
whForRepo := notif.Repository.OwnerName + "/" + notif.Repository.Name whForRepo := notif.Repository.OwnerName + "/" + notif.Repository.Name
// TODO tmplData := notifToTemplate(notif)
tmplData := notifToTemplate(notif)
logger := log.WithFields(log.Fields{ logger := log.WithFields(log.Fields{
"repo": whForRepo, "repo": whForRepo,
@ -226,8 +212,10 @@ func (s *Service) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli
if ownerRepo != whForRepo { if ownerRepo != whForRepo {
continue continue
} }
tmpl := travisToGoTemplate(repoData.Template)
msg := tmpl // TODO
msg := matrix.TextMessage{
Body: outputForTemplate(repoData.Template, tmplData),
MsgType: "m.notice",
}
logger.WithFields(log.Fields{ logger.WithFields(log.Fields{
"msg": msg, "msg": msg,

24
src/github.com/matrix-org/go-neb/services/travisci/travisci_test.go

@ -4,15 +4,16 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/matrix-org/go-neb/database"
"github.com/matrix-org/go-neb/matrix"
"github.com/matrix-org/go-neb/types"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
"strings" "strings"
"testing" "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----- const travisOrgPEMPublicKey = (`-----BEGIN PUBLIC KEY-----
@ -70,7 +71,7 @@ var travisTests = []struct {
{ {
exampleSignature, true, exampleBody, exampleSignature, true, exampleBody,
"%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message}", "%{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} httpClient = &http.Client{Transport: travisTransport}
// Intercept message sending to Matrix and mock responses // Intercept message sending to Matrix and mock responses
msgs := []matrix.HTMLMessage{}
msgs := []matrix.TextMessage{}
matrixTrans := struct{ MockTransport }{} matrixTrans := struct{ MockTransport }{}
matrixTrans.roundTrip = func(req *http.Request) (*http.Response, error) { matrixTrans.roundTrip = func(req *http.Request) (*http.Response, error) {
if !strings.Contains(req.URL.String(), "/send/m.room.message") { if !strings.Contains(req.URL.String(), "/send/m.room.message") {
return nil, fmt.Errorf("Unhandled URL: %s", req.URL.String()) 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 { 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) msgs = append(msgs, msg)
return &http.Response{ return &http.Response{
@ -128,7 +129,7 @@ func TestTravisCI(t *testing.T) {
// BEGIN running the Travis-CI table tests // BEGIN running the Travis-CI table tests
// --------------------------------------- // ---------------------------------------
for _, test := range travisTests { for _, test := range travisTests {
msgs = []matrix.HTMLMessage{} // reset sent messages
msgs = []matrix.TextMessage{} // reset sent messages
mockWriter := httptest.NewRecorder() mockWriter := httptest.NewRecorder()
travis := makeService(t, test.Template) travis := makeService(t, test.Template)
if travis == nil { if travis == nil {
@ -153,6 +154,13 @@ func TestTravisCI(t *testing.T) {
if mockWriter.Code != 200 { if mockWriter.Code != 200 {
t.Errorf("TestTravisCI OnReceiveWebhook want code %d, got %d", 200, mockWriter.Code) 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)
}
} }
} }

Loading…
Cancel
Save