mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-31 03:18:24 +00:00 
			
		
		
		
	API endpoint for testing webhook (#3550)
* API endpoint for testing webhook * Empty commit to rerun CI
This commit is contained in:
		| @@ -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) | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								public/swagger.v1.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								public/swagger.v1.json
									
									
									
									
										vendored
									
									
								
							| @@ -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). | 					m.Group("/:id", func() { | ||||||
| 						Patch(bind(api.EditHookOption{}), repo.EditHook). | 						m.Combo("").Get(repo.GetHook). | ||||||
| 						Delete(repo.DeleteHook) | 							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 | ||||||
|   | |||||||
							
								
								
									
										33
									
								
								routers/api/v1/repo/hook_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								routers/api/v1/repo/hook_test.go
									
									
									
									
									
										Normal 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)) | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								routers/api/v1/repo/main_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								routers/api/v1/repo/main_test.go
									
									
									
									
									
										Normal 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("..", "..", "..", "..")) | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user