Badge API tests
This commit is contained in:
parent
e033a1a4a5
commit
0e53778d22
3 changed files with 146 additions and 103 deletions
|
@ -1,115 +1,144 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"encoding/xml"
|
||||||
"net"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/url"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/drone/drone/common"
|
"github.com/drone/drone/common"
|
||||||
|
"github.com/drone/drone/common/ccmenu"
|
||||||
|
"github.com/drone/drone/datastore"
|
||||||
"github.com/drone/drone/mocks"
|
"github.com/drone/drone/mocks"
|
||||||
. "github.com/franela/goblin"
|
. "github.com/franela/goblin"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RecorderImpl struct {
|
|
||||||
recorder *httptest.ResponseRecorder
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ri RecorderImpl) Header() http.Header {
|
|
||||||
return ri.recorder.Header()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ri RecorderImpl) Write(buf []byte) (int, error) {
|
|
||||||
return ri.recorder.Write(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ri RecorderImpl) WriteHeader(code int) {
|
|
||||||
ri.recorder.WriteHeader(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ri RecorderImpl) CloseNotify() <-chan bool {
|
|
||||||
return http.ResponseWriter(ri.recorder).(http.CloseNotifier).CloseNotify()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ri RecorderImpl) Flush() {
|
|
||||||
ri.recorder.Flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ri RecorderImpl) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
|
||||||
return http.ResponseWriter(ri.recorder).(http.Hijacker).Hijack()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ri RecorderImpl) Size() int {
|
|
||||||
return ri.recorder.Body.Len()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ri RecorderImpl) Status() int {
|
|
||||||
return ri.recorder.Code
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ri RecorderImpl) WriteHeaderNow() {
|
|
||||||
// no-op?
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ri RecorderImpl) Written() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBadage(t *testing.T) {
|
func TestBadage(t *testing.T) {
|
||||||
g := Goblin(t)
|
g := Goblin(t)
|
||||||
g.Describe("Badge", func() {
|
g.Describe("Badge", func() {
|
||||||
// token := common.Token{
|
|
||||||
// Kind: "github",
|
|
||||||
// Login: "Freya",
|
|
||||||
// Label: "github",
|
|
||||||
// Repos: []string{"Freya/Hello-World"},
|
|
||||||
// Scopes: []string{},
|
|
||||||
// Expiry: 0,
|
|
||||||
// Issued: 0,
|
|
||||||
// }
|
|
||||||
|
|
||||||
var ds *mocks.Datastore
|
|
||||||
var ctx gin.Context
|
var ctx gin.Context
|
||||||
|
owner := "Freya"
|
||||||
|
name := "Hello-World"
|
||||||
|
fullName := owner + "/" + name
|
||||||
|
repo := &common.Repo{Owner: owner, Name: name, FullName: fullName}
|
||||||
g.BeforeEach(func() {
|
g.BeforeEach(func() {
|
||||||
router := gin.New()
|
ctx = gin.Context{Engine: gin.Default()}
|
||||||
ds = new(mocks.Datastore)
|
url, _ := url.Parse("http://drone.local/badges/" + fullName)
|
||||||
ctx = gin.Context{Engine: router}
|
ctx.Request = &http.Request{URL: url}
|
||||||
ctx.Set("datastore", ds)
|
ctx.Set("repo", repo)
|
||||||
})
|
})
|
||||||
|
|
||||||
g.AfterEach(func() {
|
g.AfterEach(func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
g.It("should provide SVG response", func() {
|
cycleStateTester := func(expector gin.HandlerFunc, handle gin.HandlerFunc, validator func(state string, w *ResponseRecorder)) {
|
||||||
w := new(RecorderImpl)
|
for idx, state := range []string{"", common.StateError, common.StateFailure, common.StateKilled, common.StatePending, common.StateRunning, common.StateSuccess} {
|
||||||
w.recorder = httptest.NewRecorder()
|
w := NewResponseRecorder()
|
||||||
ctx.Writer = w
|
ctx.Writer = w
|
||||||
|
|
||||||
repo := &common.Repo{Owner: "Freya", Name: "Hello-World"}
|
repo.Last = &common.Build{
|
||||||
ctx.Set("repo", repo)
|
Started: time.Now().UTC().Unix(),
|
||||||
|
Finished: time.Now().UTC().Unix(),
|
||||||
// TODO(benschumacher) expand this a lot.
|
Number: idx,
|
||||||
GetBadge(&ctx)
|
State: state,
|
||||||
g.Assert(w.Status()).Equal(200)
|
}
|
||||||
|
|
||||||
// Check the variety of states
|
|
||||||
for _, state := range []string{common.StateError, common.StateFailure, common.StateKilled, common.StatePending, common.StateRunning, common.StateSuccess} {
|
|
||||||
repo.Last = &common.Build{State: state}
|
|
||||||
ctx.Set("repo", repo)
|
ctx.Set("repo", repo)
|
||||||
|
|
||||||
GetBadge(&ctx)
|
if expector != nil {
|
||||||
g.Assert(w.Status()).Equal(200)
|
expector(&ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
handle(&ctx)
|
||||||
|
|
||||||
|
validator(state, w)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g.It("should provide SVG response", func() {
|
||||||
|
{
|
||||||
|
// 1. verify no "last" build
|
||||||
|
w := NewResponseRecorder()
|
||||||
|
ctx.Writer = w
|
||||||
|
ctx.Request.URL.Path += "/status.svg"
|
||||||
|
|
||||||
|
GetBadge(&ctx)
|
||||||
|
|
||||||
|
g.Assert(w.Status()).Equal(200)
|
||||||
|
g.Assert(w.HeaderMap.Get("content-type")).Equal("image/svg+xml")
|
||||||
|
g.Assert(strings.Contains(w.Body.String(), ">none")).IsTrue()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. verify a variety of "last" build states
|
||||||
|
cycleStateTester(nil, GetBadge, func(state string, w *ResponseRecorder) {
|
||||||
|
g.Assert(w.Status()).Equal(200)
|
||||||
|
g.Assert(w.HeaderMap.Get("content-type")).Equal("image/svg+xml")
|
||||||
|
|
||||||
|
// this may be excessive, but does effectively verify behavior
|
||||||
|
switch state {
|
||||||
|
case common.StateSuccess:
|
||||||
|
g.Assert(strings.Contains(w.Body.String(), ">success")).IsTrue()
|
||||||
|
case common.StatePending, common.StateRunning:
|
||||||
|
g.Assert(strings.Contains(w.Body.String(), ">started")).IsTrue()
|
||||||
|
case common.StateError, common.StateKilled:
|
||||||
|
g.Assert(strings.Contains(w.Body.String(), ">error")).IsTrue()
|
||||||
|
case common.StateFailure:
|
||||||
|
g.Assert(strings.Contains(w.Body.String(), ">failure")).IsTrue()
|
||||||
|
default:
|
||||||
|
g.Assert(strings.Contains(w.Body.String(), ">none")).IsTrue()
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
g.It("should provide CCTray response") /*, func() {
|
|
||||||
w := httptest.NewRecorder()
|
|
||||||
ctx.Writer = w
|
|
||||||
|
|
||||||
repo := &common.Repo{Owner: "Freya", Name: "Hello-World"}
|
g.It("should provide CCTray response", func() {
|
||||||
ctx.Set("repo", repo)
|
{
|
||||||
|
// 1. verify no "last" build
|
||||||
|
w := NewResponseRecorder()
|
||||||
|
ctx.Writer = w
|
||||||
|
ctx.Request.URL.Path += "/cc.xml"
|
||||||
|
|
||||||
}*/
|
ds := new(mocks.Datastore)
|
||||||
|
ctx.Set("datastore", ds)
|
||||||
|
|
||||||
|
ds.On("BuildLast", fullName).Return(nil, datastore.ErrKeyNotFound).Once()
|
||||||
|
GetCC(&ctx)
|
||||||
|
|
||||||
|
g.Assert(w.Status()).Equal(404)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. verify a variety of "last" build states
|
||||||
|
cycleStateTester(func(c *gin.Context) {
|
||||||
|
repo := ToRepo(c)
|
||||||
|
ds := new(mocks.Datastore)
|
||||||
|
ctx.Set("datastore", ds)
|
||||||
|
ds.On("BuildLast", fullName).Return(repo.Last, nil).Once()
|
||||||
|
},
|
||||||
|
GetCC,
|
||||||
|
func(state string, w *ResponseRecorder) {
|
||||||
|
g.Assert(w.Status()).Equal(200)
|
||||||
|
|
||||||
|
v := ccmenu.CCProjects{}
|
||||||
|
xml.Unmarshal(w.Body.Bytes(), &v)
|
||||||
|
switch state {
|
||||||
|
case common.StateSuccess:
|
||||||
|
g.Assert(v.Project.Activity).Equal("Sleeping")
|
||||||
|
g.Assert(v.Project.LastBuildStatus).Equal("Success")
|
||||||
|
case common.StatePending, common.StateRunning:
|
||||||
|
g.Assert(v.Project.Activity).Equal("Building")
|
||||||
|
g.Assert(v.Project.LastBuildStatus).Equal("Unknown")
|
||||||
|
case common.StateError, common.StateKilled:
|
||||||
|
g.Assert(v.Project.Activity).Equal("Sleeping")
|
||||||
|
g.Assert(v.Project.LastBuildStatus).Equal("Exception")
|
||||||
|
case common.StateFailure:
|
||||||
|
g.Assert(v.Project.Activity).Equal("Sleeping")
|
||||||
|
g.Assert(v.Project.LastBuildStatus).Equal("Failure")
|
||||||
|
default:
|
||||||
|
g.Assert(v.Project.Activity).Equal("Sleeping")
|
||||||
|
g.Assert(v.Project.LastBuildStatus).Equal("Unknown")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/drone/drone/common"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MockSession struct {
|
|
||||||
Token *common.Token
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s MockSession) GenerateToken(*common.Token) (string, error) {
|
|
||||||
return "session", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s MockSession) GetLogin(*http.Request) *common.Token {
|
|
||||||
return s.Token
|
|
||||||
}
|
|
33
server/responserecorder_test.go
Normal file
33
server/responserecorder_test.go
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ResponseRecorder struct {
|
||||||
|
*httptest.ResponseRecorder
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewResponseRecorder() *ResponseRecorder {
|
||||||
|
return &ResponseRecorder{httptest.NewRecorder()}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr *ResponseRecorder) reset() {
|
||||||
|
rr.ResponseRecorder = httptest.NewRecorder()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr *ResponseRecorder) CloseNotify() <-chan bool {
|
||||||
|
return http.ResponseWriter(rr).(http.CloseNotifier).CloseNotify()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr *ResponseRecorder) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||||
|
return http.ResponseWriter(rr).(http.Hijacker).Hijack()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr *ResponseRecorder) Size() int { return rr.Body.Len() }
|
||||||
|
func (rr *ResponseRecorder) Status() int { return rr.Code }
|
||||||
|
func (rr *ResponseRecorder) WriteHeaderNow() {}
|
||||||
|
func (rr *ResponseRecorder) Written() bool { return rr.Code != 0 }
|
Loading…
Reference in a new issue