* API endpoint for testing webhook * Empty commit to rerun CImaster
@@ -3,3 +3,4 @@ | |||||
repo_id: 1 | repo_id: 1 | ||||
hook_id: 1 | hook_id: 1 | ||||
uuid: uuid1 | uuid: uuid1 | ||||
is_delivered: true |
@@ -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) | ||||
@@ -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": [ | ||||
@@ -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). | |||||
Patch(bind(api.EditHookOption{}), repo.EditHook). | |||||
Delete(repo.DeleteHook) | |||||
m.Group("/:id", func() { | |||||
m.Combo("").Get(repo.GetHook). | |||||
Patch(bind(api.EditHookOption{}), repo.EditHook). | |||||
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) | ||||
@@ -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 | ||||
@@ -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)) | |||||
} |
@@ -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("..", "..", "..", "..")) | |||||
} |