API endpoint for testing webhook (#3550)

* API endpoint for testing webhook

* Empty commit to rerun CI
release/v1.15
Ethan Koenig 2018-04-28 23:21:33 -07:00 committed by Lunny Xiao
parent 5a62eb30df
commit 7ea4bfc561
7 changed files with 165 additions and 5 deletions

View File

@ -3,3 +3,4 @@
repo_id: 1 repo_id: 1
hook_id: 1 hook_id: 1
uuid: uuid1 uuid: uuid1
is_delivered: true

View File

@ -13,10 +13,11 @@ import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"net/http/httptest"
"github.com/go-macaron/session" "github.com/go-macaron/session"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gopkg.in/macaron.v1" "gopkg.in/macaron.v1"
"net/http/httptest"
) )
// MockContext mock context for unit tests // MockContext mock context for unit tests
@ -48,6 +49,16 @@ func LoadRepo(t *testing.T, ctx *context.Context, repoID int64) {
ctx.Repo.RepoLink = ctx.Repo.Repository.Link() ctx.Repo.RepoLink = ctx.Repo.Repository.Link()
} }
// LoadRepoCommit loads a repo's commit into a test context.
func LoadRepoCommit(t *testing.T, ctx *context.Context) {
gitRepo, err := git.OpenRepository(ctx.Repo.Repository.RepoPath())
assert.NoError(t, err)
branch, err := gitRepo.GetHEADBranch()
assert.NoError(t, err)
ctx.Repo.Commit, err = gitRepo.GetBranchCommit(branch.Name)
assert.NoError(t, err)
}
// LoadUser load a user into a test context. // LoadUser load a user into a test context.
func LoadUser(t *testing.T, ctx *context.Context, userID int64) { func LoadUser(t *testing.T, ctx *context.Context, userID int64) {
ctx.User = models.AssertExistsAndLoadBean(t, &models.User{ID: userID}).(*models.User) ctx.User = models.AssertExistsAndLoadBean(t, &models.User{ID: userID}).(*models.User)

View File

@ -1565,6 +1565,46 @@
} }
} }
}, },
"/repos/{owner}/{repo}/hooks/{id}/tests": {
"post": {
"produces": [
"application/json"
],
"tags": [
"repository"
],
"summary": "Test a push webhook",
"operationId": "repoTestHook",
"parameters": [
{
"type": "string",
"description": "owner of the repo",
"name": "owner",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the repo",
"name": "repo",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "id of the hook to test",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"204": {
"$ref": "#/responses/empty"
}
}
}
},
"/repos/{owner}/{repo}/issue/{index}/comments": { "/repos/{owner}/{repo}/issue/{index}/comments": {
"get": { "get": {
"produces": [ "produces": [

View File

@ -382,9 +382,12 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/hooks", func() { m.Group("/hooks", func() {
m.Combo("").Get(repo.ListHooks). m.Combo("").Get(repo.ListHooks).
Post(bind(api.CreateHookOption{}), repo.CreateHook) Post(bind(api.CreateHookOption{}), repo.CreateHook)
m.Combo("/:id").Get(repo.GetHook). m.Group("/:id", func() {
m.Combo("").Get(repo.GetHook).
Patch(bind(api.EditHookOption{}), repo.EditHook). Patch(bind(api.EditHookOption{}), repo.EditHook).
Delete(repo.DeleteHook) Delete(repo.DeleteHook)
m.Post("/tests", context.RepoRef(), repo.TestHook)
})
}, reqToken(), reqRepoWriter()) }, reqToken(), reqRepoWriter())
m.Group("/collaborators", func() { m.Group("/collaborators", func() {
m.Get("", repo.ListCollaborators) m.Get("", repo.ListCollaborators)

View File

@ -5,11 +5,11 @@
package repo package repo
import ( import (
"code.gitea.io/git"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/routers/api/v1/convert" "code.gitea.io/gitea/routers/api/v1/convert"
"code.gitea.io/gitea/routers/api/v1/utils" "code.gitea.io/gitea/routers/api/v1/utils"
api "code.gitea.io/sdk/gitea" api "code.gitea.io/sdk/gitea"
) )
@ -82,6 +82,62 @@ func GetHook(ctx *context.APIContext) {
ctx.JSON(200, convert.ToHook(repo.RepoLink, hook)) ctx.JSON(200, convert.ToHook(repo.RepoLink, hook))
} }
// TestHook tests a hook
func TestHook(ctx *context.APIContext) {
// swagger:operation POST /repos/{owner}/{repo}/hooks/{id}/tests repository repoTestHook
// ---
// summary: Test a push webhook
// produces:
// - application/json
// parameters:
// - name: owner
// in: path
// description: owner of the repo
// type: string
// required: true
// - name: repo
// in: path
// description: name of the repo
// type: string
// required: true
// - name: id
// in: path
// description: id of the hook to test
// type: integer
// required: true
// responses:
// "204":
// "$ref": "#/responses/empty"
if ctx.Repo.Commit == nil {
// if repo does not have any commits, then don't send a webhook
ctx.Status(204)
return
}
hookID := ctx.ParamsInt64(":id")
hook, err := utils.GetRepoHook(ctx, ctx.Repo.Repository.ID, hookID)
if err != nil {
return
}
if err := models.PrepareWebhook(hook, ctx.Repo.Repository, models.HookEventPush, &api.PushPayload{
Ref: git.BranchPrefix + ctx.Repo.Repository.DefaultBranch,
Before: ctx.Repo.Commit.ID.String(),
After: ctx.Repo.Commit.ID.String(),
Commits: []*api.PayloadCommit{
convert.ToCommit(ctx.Repo.Repository, ctx.Repo.Commit),
},
Repo: ctx.Repo.Repository.APIFormat(models.AccessModeNone),
Pusher: ctx.User.APIFormat(),
Sender: ctx.User.APIFormat(),
}); err != nil {
ctx.Error(500, "PrepareWebhook: ", err)
return
}
go models.HookQueue.Add(ctx.Repo.Repository.ID)
ctx.Status(204)
}
// CreateHook create a hook for a repository // CreateHook create a hook for a repository
func CreateHook(ctx *context.APIContext, form api.CreateHookOption) { func CreateHook(ctx *context.APIContext, form api.CreateHookOption) {
// swagger:operation POST /repos/{owner}/{repo}/hooks repository repoCreateHook // swagger:operation POST /repos/{owner}/{repo}/hooks repository repoCreateHook

View File

@ -0,0 +1,33 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package repo
import (
"net/http"
"testing"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
)
func TestTestHook(t *testing.T) {
models.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/wiki/_pages")
ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2)
TestHook(&context.APIContext{Context: ctx, Org: nil})
assert.EqualValues(t, http.StatusNoContent, ctx.Resp.Status())
models.AssertExistsAndLoadBean(t, &models.HookTask{
RepoID: 1,
HookID: 1,
}, models.Cond("is_delivered=?", false))
}

View File

@ -0,0 +1,16 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package repo
import (
"path/filepath"
"testing"
"code.gitea.io/gitea/models"
)
func TestMain(m *testing.M) {
models.MainTest(m, filepath.Join("..", "..", "..", ".."))
}