mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-27 04:11:03 +00:00
table-driven tests for badge permutations
This commit is contained in:
parent
acc6bb76ee
commit
9c882c1a9e
2 changed files with 60 additions and 113 deletions
|
@ -4,9 +4,7 @@ import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"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/common/ccmenu"
|
||||||
|
@ -17,129 +15,78 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBadge(t *testing.T) {
|
var badgeTests = []struct {
|
||||||
|
badge []byte
|
||||||
|
state string
|
||||||
|
activity string
|
||||||
|
status string
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
{badgeSuccess, common.StateSuccess, "Sleeping", "Success", nil},
|
||||||
|
{badgeStarted, common.StateRunning, "Building", "Unknown", nil},
|
||||||
|
{badgeError, common.StateError, "Sleeping", "Exception", nil},
|
||||||
|
{badgeError, common.StateKilled, "Sleeping", "Exception", nil},
|
||||||
|
{badgeFailure, common.StateFailure, "Sleeping", "Failure", nil},
|
||||||
|
{badgeNone, "", "", "", datastore.ErrKeyNotFound},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBadges(t *testing.T) {
|
||||||
|
store := new(mocks.Datastore)
|
||||||
|
url_, _ := url.Parse("http://localhost:8080")
|
||||||
|
|
||||||
g := Goblin(t)
|
g := Goblin(t)
|
||||||
g.Describe("Badge", func() {
|
g.Describe("Badges", func() {
|
||||||
var ctx gin.Context
|
|
||||||
owner := "Freya"
|
|
||||||
name := "Hello-World"
|
|
||||||
fullName := owner + "/" + name
|
|
||||||
repo := &common.Repo{Owner: owner, Name: name, FullName: fullName}
|
|
||||||
g.BeforeEach(func() {
|
|
||||||
ctx = gin.Context{Engine: gin.Default()}
|
|
||||||
url, _ := url.Parse("http://drone.local/badges/" + fullName)
|
|
||||||
ctx.Request = &http.Request{URL: url}
|
|
||||||
ctx.Set("repo", repo)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.AfterEach(func() {
|
g.It("should svg badges", func() {
|
||||||
})
|
for _, test := range badgeTests {
|
||||||
|
rw := recorder.New()
|
||||||
|
ctx := &gin.Context{Engine: gin.Default(), Writer: rw}
|
||||||
|
|
||||||
cycleStateTester := func(expector gin.HandlerFunc, handle gin.HandlerFunc, validator func(state string, w *recorder.ResponseRecorder)) {
|
repo := &common.Repo{FullName: "foo/bar"}
|
||||||
for idx, state := range []string{"", common.StateError, common.StateFailure, common.StateKilled, common.StatePending, common.StateRunning, common.StateSuccess} {
|
if len(test.state) != 0 {
|
||||||
w := recorder.NewResponseRecorder()
|
repo.Last = &common.Build{State: test.state}
|
||||||
ctx.Writer = w
|
|
||||||
|
|
||||||
repo.Last = &common.Build{
|
|
||||||
Started: time.Now().UTC().Unix(),
|
|
||||||
Finished: time.Now().UTC().Unix(),
|
|
||||||
Number: idx,
|
|
||||||
State: state,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx.Set("datastore", store)
|
||||||
ctx.Set("repo", repo)
|
ctx.Set("repo", repo)
|
||||||
|
|
||||||
if expector != nil {
|
GetBadge(ctx)
|
||||||
expector(&ctx)
|
g.Assert(rw.Code).Equal(200)
|
||||||
}
|
g.Assert(rw.Body.Bytes()).Equal(test.badge)
|
||||||
|
g.Assert(rw.HeaderMap.Get("Content-Type")).Equal("image/svg+xml")
|
||||||
handle(&ctx)
|
|
||||||
|
|
||||||
validator(state, w)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
g.It("should provide SVG response", func() {
|
|
||||||
{
|
|
||||||
// 1. verify no "last" build
|
|
||||||
w := recorder.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 *recorder.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() {
|
g.It("should serve ccmenu xml", func() {
|
||||||
{
|
|
||||||
// 1. verify no "last" build
|
|
||||||
w := recorder.NewResponseRecorder()
|
|
||||||
ctx.Writer = w
|
|
||||||
ctx.Request.URL.Path += "/cc.xml"
|
|
||||||
|
|
||||||
ds := new(mocks.Datastore)
|
for _, test := range badgeTests {
|
||||||
ctx.Set("datastore", ds)
|
rw := recorder.New()
|
||||||
|
ctx := &gin.Context{Engine: gin.Default(), Writer: rw}
|
||||||
|
ctx.Request = &http.Request{URL: url_}
|
||||||
|
|
||||||
ds.On("BuildLast", fullName).Return(nil, datastore.ErrKeyNotFound).Once()
|
repo := &common.Repo{FullName: "foo/bar"}
|
||||||
GetCC(&ctx)
|
ctx.Set("datastore", store)
|
||||||
|
ctx.Set("repo", repo)
|
||||||
|
|
||||||
g.Assert(w.Status()).Equal(404)
|
build := &common.Build{State: test.state}
|
||||||
|
store.On("BuildLast", repo.FullName).Return(build, test.err).Once()
|
||||||
|
GetCC(ctx)
|
||||||
|
|
||||||
|
// in an error scenario (ie no build exists) we should
|
||||||
|
// return a 404 not found error.
|
||||||
|
if test.err != nil {
|
||||||
|
g.Assert(rw.Status()).Equal(404)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// else parse the CCMenu xml output and verify
|
||||||
|
// it matches the expected values.
|
||||||
|
cc := &ccmenu.CCProjects{}
|
||||||
|
xml.Unmarshal(rw.Body.Bytes(), cc)
|
||||||
|
g.Assert(cc.Project.Activity).Equal(test.activity)
|
||||||
|
g.Assert(cc.Project.LastBuildStatus).Equal(test.status)
|
||||||
|
g.Assert(rw.HeaderMap.Get("Content-Type")).Equal("application/xml; charset=utf-8")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 *recorder.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")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ type ResponseRecorder struct {
|
||||||
*httptest.ResponseRecorder
|
*httptest.ResponseRecorder
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewResponseRecorder() *ResponseRecorder {
|
func New() *ResponseRecorder {
|
||||||
return &ResponseRecorder{httptest.NewRecorder()}
|
return &ResponseRecorder{httptest.NewRecorder()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue