Merge pull request '[v7.0/forgejo] [BUG] webhook: fix admin-hooks and add more tests' (#3131) from bp-v7.0/forgejo-9a94019-e0b5f2d-c1f7c49-7d95cf6 into v7.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3131 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
This commit is contained in:
		
						commit
						c63b347a0b
					
				
					 5 changed files with 165 additions and 106 deletions
				
			
		| 
						 | 
				
			
			@ -8,15 +8,11 @@ import (
 | 
			
		|||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/models/db"
 | 
			
		||||
	"code.gitea.io/gitea/modules/optional"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GetDefaultWebhooks returns all admin-default webhooks.
 | 
			
		||||
func GetDefaultWebhooks(ctx context.Context) ([]*Webhook, error) {
 | 
			
		||||
	webhooks := make([]*Webhook, 0, 5)
 | 
			
		||||
	return webhooks, db.GetEngine(ctx).
 | 
			
		||||
		Where("repo_id=? AND owner_id=? AND is_system_webhook=?", 0, 0, false).
 | 
			
		||||
		Find(&webhooks)
 | 
			
		||||
	return getAdminWebhooks(ctx, false)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetSystemOrDefaultWebhook returns admin system or default webhook by given ID.
 | 
			
		||||
| 
						 | 
				
			
			@ -34,15 +30,21 @@ func GetSystemOrDefaultWebhook(ctx context.Context, id int64) (*Webhook, error)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// GetSystemWebhooks returns all admin system webhooks.
 | 
			
		||||
func GetSystemWebhooks(ctx context.Context, isActive optional.Option[bool]) ([]*Webhook, error) {
 | 
			
		||||
func GetSystemWebhooks(ctx context.Context, onlyActive bool) ([]*Webhook, error) {
 | 
			
		||||
	return getAdminWebhooks(ctx, true, onlyActive)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getAdminWebhooks(ctx context.Context, systemWebhooks bool, onlyActive ...bool) ([]*Webhook, error) {
 | 
			
		||||
	webhooks := make([]*Webhook, 0, 5)
 | 
			
		||||
	if !isActive.Has() {
 | 
			
		||||
	if len(onlyActive) > 0 && onlyActive[0] {
 | 
			
		||||
		return webhooks, db.GetEngine(ctx).
 | 
			
		||||
			Where("repo_id=? AND owner_id=? AND is_system_webhook=?", 0, 0, true).
 | 
			
		||||
			Where("repo_id=? AND owner_id=? AND is_system_webhook=? AND is_active = ?", 0, 0, systemWebhooks, true).
 | 
			
		||||
			OrderBy("id").
 | 
			
		||||
			Find(&webhooks)
 | 
			
		||||
	}
 | 
			
		||||
	return webhooks, db.GetEngine(ctx).
 | 
			
		||||
		Where("repo_id=? AND owner_id=? AND is_system_webhook=? AND is_active = ?", 0, 0, true, isActive.Value()).
 | 
			
		||||
		Where("repo_id=? AND owner_id=? AND is_system_webhook=?", 0, 0, systemWebhooks).
 | 
			
		||||
		OrderBy("id").
 | 
			
		||||
		Find(&webhooks)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,6 @@ import (
 | 
			
		|||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/models/webhook"
 | 
			
		||||
	"code.gitea.io/gitea/modules/optional"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	api "code.gitea.io/gitea/modules/structs"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +37,7 @@ func ListHooks(ctx *context.APIContext) {
 | 
			
		|||
	//   "200":
 | 
			
		||||
	//     "$ref": "#/responses/HookList"
 | 
			
		||||
 | 
			
		||||
	sysHooks, err := webhook.GetSystemWebhooks(ctx, optional.None[bool]())
 | 
			
		||||
	sysHooks, err := webhook.GetSystemWebhooks(ctx, false)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.Error(http.StatusInternalServerError, "GetSystemWebhooks", err)
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,9 +8,9 @@ import (
 | 
			
		|||
 | 
			
		||||
	"code.gitea.io/gitea/models/webhook"
 | 
			
		||||
	"code.gitea.io/gitea/modules/base"
 | 
			
		||||
	"code.gitea.io/gitea/modules/optional"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/services/context"
 | 
			
		||||
	webhook_service "code.gitea.io/gitea/services/webhook"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
| 
						 | 
				
			
			@ -35,9 +35,10 @@ func DefaultOrSystemWebhooks(ctx *context.Context) {
 | 
			
		|||
 | 
			
		||||
	sys["Title"] = ctx.Tr("admin.systemhooks")
 | 
			
		||||
	sys["Description"] = ctx.Tr("admin.systemhooks.desc")
 | 
			
		||||
	sys["Webhooks"], err = webhook.GetSystemWebhooks(ctx, optional.None[bool]())
 | 
			
		||||
	sys["Webhooks"], err = webhook.GetSystemWebhooks(ctx, false)
 | 
			
		||||
	sys["BaseLink"] = setting.AppSubURL + "/admin/hooks"
 | 
			
		||||
	sys["BaseLinkNew"] = setting.AppSubURL + "/admin/system-hooks"
 | 
			
		||||
	sys["WebhookList"] = webhook_service.List()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.ServerError("GetWebhooksAdmin", err)
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			@ -48,6 +49,7 @@ func DefaultOrSystemWebhooks(ctx *context.Context) {
 | 
			
		|||
	def["Webhooks"], err = webhook.GetDefaultWebhooks(ctx)
 | 
			
		||||
	def["BaseLink"] = setting.AppSubURL + "/admin/hooks"
 | 
			
		||||
	def["BaseLinkNew"] = setting.AppSubURL + "/admin/default-hooks"
 | 
			
		||||
	def["WebhookList"] = webhook_service.List()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.ServerError("GetWebhooksAdmin", err)
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -243,7 +243,7 @@ func PrepareWebhooks(ctx context.Context, source EventSource, event webhook_modu
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// Add any admin-defined system webhooks
 | 
			
		||||
	systemHooks, err := webhook_model.GetSystemWebhooks(ctx, optional.Some(true))
 | 
			
		||||
	systemHooks, err := webhook_model.GetSystemWebhooks(ctx, true)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("GetSystemWebhooks: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,6 @@ import (
 | 
			
		|||
	"net/http"
 | 
			
		||||
	"net/http/httptest"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	gitea_context "code.gitea.io/gitea/services/context"
 | 
			
		||||
| 
						 | 
				
			
			@ -37,30 +36,58 @@ func TestNewWebHookLink(t *testing.T) {
 | 
			
		|||
	for _, url := range tests {
 | 
			
		||||
		resp := session.MakeRequest(t, NewRequest(t, "GET", url), http.StatusOK)
 | 
			
		||||
		htmlDoc := NewHTMLParser(t, resp.Body)
 | 
			
		||||
		menus := htmlDoc.doc.Find(".ui.top.attached.header .ui.dropdown .menu a")
 | 
			
		||||
		menus.Each(func(i int, menu *goquery.Selection) {
 | 
			
		||||
			url, exist := menu.Attr("href")
 | 
			
		||||
			assert.True(t, exist)
 | 
			
		||||
			assert.True(t, strings.HasPrefix(url, baseurl))
 | 
			
		||||
		})
 | 
			
		||||
		assert.Equal(t, webhooksLen, htmlDoc.Find(`a[href^="`+baseurl+`/"][href$="/new"]`).Length(), "not all webhooks are listed in the 'new' dropdown")
 | 
			
		||||
		assert.Equal(t,
 | 
			
		||||
			webhooksLen,
 | 
			
		||||
			htmlDoc.Find(`a[href^="`+baseurl+`/"][href$="/new"]`).Length(),
 | 
			
		||||
			"not all webhooks are listed in the 'new' dropdown")
 | 
			
		||||
 | 
			
		||||
		csrfToken = htmlDoc.GetCSRF()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// ensure that the "failure" pages has the full dropdown as well
 | 
			
		||||
	resp := session.MakeRequest(t, NewRequestWithValues(t, "POST", baseurl+"/gitea/new", map[string]string{"_csrf": csrfToken}), http.StatusUnprocessableEntity)
 | 
			
		||||
	htmlDoc := NewHTMLParser(t, resp.Body)
 | 
			
		||||
	assert.Equal(t, webhooksLen, htmlDoc.Find(`a[href^="`+baseurl+`/"][href$="/new"]`).Length(), "not all webhooks are listed in the 'new' dropdown on failure")
 | 
			
		||||
	assert.Equal(t,
 | 
			
		||||
		webhooksLen,
 | 
			
		||||
		htmlDoc.Find(`a[href^="`+baseurl+`/"][href$="/new"]`).Length(),
 | 
			
		||||
		"not all webhooks are listed in the 'new' dropdown on failure")
 | 
			
		||||
 | 
			
		||||
	resp = session.MakeRequest(t, NewRequestWithValues(t, "POST", baseurl+"/1", map[string]string{"_csrf": csrfToken}), http.StatusUnprocessableEntity)
 | 
			
		||||
	htmlDoc = NewHTMLParser(t, resp.Body)
 | 
			
		||||
	assert.Equal(t, webhooksLen, htmlDoc.Find(`a[href^="`+baseurl+`/"][href$="/new"]`).Length(), "not all webhooks are listed in the 'new' dropdown on failure")
 | 
			
		||||
	assert.Equal(t,
 | 
			
		||||
		webhooksLen,
 | 
			
		||||
		htmlDoc.Find(`a[href^="`+baseurl+`/"][href$="/new"]`).Length(),
 | 
			
		||||
		"not all webhooks are listed in the 'new' dropdown on failure")
 | 
			
		||||
 | 
			
		||||
	adminSession := loginUser(t, "user1")
 | 
			
		||||
	t.Run("org3", func(t *testing.T) {
 | 
			
		||||
		baseurl := "/org/org3/settings/hooks"
 | 
			
		||||
		resp := adminSession.MakeRequest(t, NewRequest(t, "GET", baseurl), http.StatusOK)
 | 
			
		||||
		htmlDoc := NewHTMLParser(t, resp.Body)
 | 
			
		||||
		assert.Equal(t,
 | 
			
		||||
			webhooksLen,
 | 
			
		||||
			htmlDoc.Find(`a[href^="`+baseurl+`/"][href$="/new"]`).Length(),
 | 
			
		||||
			"not all webhooks are listed in the 'new' dropdown")
 | 
			
		||||
	})
 | 
			
		||||
	t.Run("admin", func(t *testing.T) {
 | 
			
		||||
		baseurl := "/admin/hooks"
 | 
			
		||||
		resp := adminSession.MakeRequest(t, NewRequest(t, "GET", baseurl), http.StatusOK)
 | 
			
		||||
		htmlDoc := NewHTMLParser(t, resp.Body)
 | 
			
		||||
		assert.Equal(t,
 | 
			
		||||
			webhooksLen,
 | 
			
		||||
			htmlDoc.Find(`a[href^="/admin/default-hooks/"][href$="/new"]`).Length(),
 | 
			
		||||
			"not all webhooks are listed in the 'new' dropdown for default-hooks")
 | 
			
		||||
		assert.Equal(t,
 | 
			
		||||
			webhooksLen,
 | 
			
		||||
			htmlDoc.Find(`a[href^="/admin/system-hooks/"][href$="/new"]`).Length(),
 | 
			
		||||
			"not all webhooks are listed in the 'new' dropdown for system-hooks")
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestWebhookForms(t *testing.T) {
 | 
			
		||||
	defer tests.PrepareTestEnv(t)()
 | 
			
		||||
 | 
			
		||||
	session := loginUser(t, "user2")
 | 
			
		||||
	session := loginUser(t, "user1")
 | 
			
		||||
 | 
			
		||||
	t.Run("forgejo/required", testWebhookForms("forgejo", session, map[string]string{
 | 
			
		||||
		"payload_url":  "https://forgejo.example.com",
 | 
			
		||||
| 
						 | 
				
			
			@ -272,7 +299,9 @@ func assertInput(t testing.TB, form *goquery.Selection, name string) string {
 | 
			
		|||
	t.Helper()
 | 
			
		||||
	input := form.Find(`input[name="` + name + `"]`)
 | 
			
		||||
	if input.Length() != 1 {
 | 
			
		||||
		t.Log(form.Html())
 | 
			
		||||
		form.Find("input").Each(func(i int, s *goquery.Selection) {
 | 
			
		||||
			t.Logf("found <input name=%q />", s.AttrOr("name", ""))
 | 
			
		||||
		})
 | 
			
		||||
		t.Errorf("field <input name=%q /> found %d times, expected once", name, input.Length())
 | 
			
		||||
	}
 | 
			
		||||
	switch input.AttrOr("type", "") {
 | 
			
		||||
| 
						 | 
				
			
			@ -288,99 +317,126 @@ func assertInput(t testing.TB, form *goquery.Selection, name string) string {
 | 
			
		|||
 | 
			
		||||
func testWebhookForms(name string, session *TestSession, validFields map[string]string, invalidPatches ...map[string]string) func(t *testing.T) {
 | 
			
		||||
	return func(t *testing.T) {
 | 
			
		||||
		// new webhook form
 | 
			
		||||
		resp := session.MakeRequest(t, NewRequest(t, "GET", "/user2/repo1/settings/hooks/"+name+"/new"), http.StatusOK)
 | 
			
		||||
		htmlForm := NewHTMLParser(t, resp.Body).Find(`form[action^="/user2/repo1/settings/hooks/"]`)
 | 
			
		||||
		t.Run("repo1", func(t *testing.T) {
 | 
			
		||||
			testWebhookFormsShared(t, "/user2/repo1/settings/hooks", name, session, validFields, invalidPatches...)
 | 
			
		||||
		})
 | 
			
		||||
		t.Run("org3", func(t *testing.T) {
 | 
			
		||||
			testWebhookFormsShared(t, "/org/org3/settings/hooks", name, session, validFields, invalidPatches...)
 | 
			
		||||
		})
 | 
			
		||||
		t.Run("system", func(t *testing.T) {
 | 
			
		||||
			testWebhookFormsShared(t, "/admin/system-hooks", name, session, validFields, invalidPatches...)
 | 
			
		||||
		})
 | 
			
		||||
		t.Run("default", func(t *testing.T) {
 | 
			
		||||
			testWebhookFormsShared(t, "/admin/default-hooks", name, session, validFields, invalidPatches...)
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		// fill the form
 | 
			
		||||
		payload := map[string]string{
 | 
			
		||||
			"_csrf":  htmlForm.Find(`input[name="_csrf"]`).AttrOr("value", ""),
 | 
			
		||||
			"events": "send_everything",
 | 
			
		||||
		}
 | 
			
		||||
		for k, v := range validFields {
 | 
			
		||||
			assertInput(t, htmlForm, k)
 | 
			
		||||
			payload[k] = v
 | 
			
		||||
		}
 | 
			
		||||
		if t.Failed() {
 | 
			
		||||
			t.FailNow() // prevent further execution if the form could not be filled properly
 | 
			
		||||
		}
 | 
			
		||||
func testWebhookFormsShared(t *testing.T, endpoint, name string, session *TestSession, validFields map[string]string, invalidPatches ...map[string]string) {
 | 
			
		||||
	// new webhook form
 | 
			
		||||
	resp := session.MakeRequest(t, NewRequest(t, "GET", endpoint+"/"+name+"/new"), http.StatusOK)
 | 
			
		||||
	htmlForm := NewHTMLParser(t, resp.Body).Find(`form[action^="` + endpoint + `/"]`)
 | 
			
		||||
 | 
			
		||||
		// create the webhook (this redirects back to the hook list)
 | 
			
		||||
		resp = session.MakeRequest(t, NewRequestWithValues(t, "POST", "/user2/repo1/settings/hooks/"+name+"/new", payload), http.StatusSeeOther)
 | 
			
		||||
		assertHasFlashMessages(t, resp, "success")
 | 
			
		||||
	// fill the form
 | 
			
		||||
	payload := map[string]string{
 | 
			
		||||
		"_csrf":  htmlForm.Find(`input[name="_csrf"]`).AttrOr("value", ""),
 | 
			
		||||
		"events": "send_everything",
 | 
			
		||||
	}
 | 
			
		||||
	for k, v := range validFields {
 | 
			
		||||
		assertInput(t, htmlForm, k)
 | 
			
		||||
		payload[k] = v
 | 
			
		||||
	}
 | 
			
		||||
	if t.Failed() {
 | 
			
		||||
		t.FailNow() // prevent further execution if the form could not be filled properly
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		// find last created hook in the hook list
 | 
			
		||||
		// (a bit hacky, but the list should be sorted)
 | 
			
		||||
		resp = session.MakeRequest(t, NewRequest(t, "GET", "/user2/repo1/settings/hooks"), http.StatusOK)
 | 
			
		||||
		htmlDoc := NewHTMLParser(t, resp.Body)
 | 
			
		||||
		editFormURL := htmlDoc.Find(`a[href^="/user2/repo1/settings/hooks/"]`).Last().AttrOr("href", "")
 | 
			
		||||
		assert.NotEmpty(t, editFormURL)
 | 
			
		||||
	// create the webhook (this redirects back to the hook list)
 | 
			
		||||
	resp = session.MakeRequest(t, NewRequestWithValues(t, "POST", endpoint+"/"+name+"/new", payload), http.StatusSeeOther)
 | 
			
		||||
	assertHasFlashMessages(t, resp, "success")
 | 
			
		||||
	listEndpoint := resp.Header().Get("Location")
 | 
			
		||||
	updateEndpoint := endpoint + "/"
 | 
			
		||||
	if endpoint == "/admin/system-hooks" || endpoint == "/admin/default-hooks" {
 | 
			
		||||
		updateEndpoint = "/admin/hooks/"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		// edit webhook form
 | 
			
		||||
		resp = session.MakeRequest(t, NewRequest(t, "GET", editFormURL), http.StatusOK)
 | 
			
		||||
		htmlForm = NewHTMLParser(t, resp.Body).Find(`form[action^="/user2/repo1/settings/hooks/"]`)
 | 
			
		||||
		editPostURL := htmlForm.AttrOr("action", "")
 | 
			
		||||
		assert.NotEmpty(t, editPostURL)
 | 
			
		||||
	// find last created hook in the hook list
 | 
			
		||||
	// (a bit hacky, but the list should be sorted)
 | 
			
		||||
	resp = session.MakeRequest(t, NewRequest(t, "GET", listEndpoint), http.StatusOK)
 | 
			
		||||
	htmlDoc := NewHTMLParser(t, resp.Body)
 | 
			
		||||
	selector := `a[href^="` + updateEndpoint + `"]`
 | 
			
		||||
	if endpoint == "/admin/system-hooks" {
 | 
			
		||||
		// system-hooks and default-hooks are listed on the same page
 | 
			
		||||
		// add a specifier to select the latest system-hooks
 | 
			
		||||
		// (the default-hooks are at the end, so no further specifier needed)
 | 
			
		||||
		selector = `.admin-setting-content > div:first-of-type ` + selector
 | 
			
		||||
	}
 | 
			
		||||
	editFormURL := htmlDoc.Find(selector).Last().AttrOr("href", "")
 | 
			
		||||
	assert.NotEmpty(t, editFormURL)
 | 
			
		||||
 | 
			
		||||
		// fill the form
 | 
			
		||||
		payload = map[string]string{
 | 
			
		||||
			"_csrf":  htmlForm.Find(`input[name="_csrf"]`).AttrOr("value", ""),
 | 
			
		||||
			"events": "push_only",
 | 
			
		||||
		}
 | 
			
		||||
		for k, v := range validFields {
 | 
			
		||||
			assert.Equal(t, v, assertInput(t, htmlForm, k), "input %q did not contain value %q", k, v)
 | 
			
		||||
			payload[k] = v
 | 
			
		||||
		}
 | 
			
		||||
	// edit webhook form
 | 
			
		||||
	resp = session.MakeRequest(t, NewRequest(t, "GET", editFormURL), http.StatusOK)
 | 
			
		||||
	htmlForm = NewHTMLParser(t, resp.Body).Find(`form[action^="` + updateEndpoint + `"]`)
 | 
			
		||||
	editPostURL := htmlForm.AttrOr("action", "")
 | 
			
		||||
	assert.NotEmpty(t, editPostURL)
 | 
			
		||||
 | 
			
		||||
		// update the webhook
 | 
			
		||||
		resp = session.MakeRequest(t, NewRequestWithValues(t, "POST", editPostURL, payload), http.StatusSeeOther)
 | 
			
		||||
		assertHasFlashMessages(t, resp, "success")
 | 
			
		||||
	// fill the form
 | 
			
		||||
	payload = map[string]string{
 | 
			
		||||
		"_csrf":  htmlForm.Find(`input[name="_csrf"]`).AttrOr("value", ""),
 | 
			
		||||
		"events": "push_only",
 | 
			
		||||
	}
 | 
			
		||||
	for k, v := range validFields {
 | 
			
		||||
		assert.Equal(t, v, assertInput(t, htmlForm, k), "input %q did not contain value %q", k, v)
 | 
			
		||||
		payload[k] = v
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		// check the updated webhook
 | 
			
		||||
		resp = session.MakeRequest(t, NewRequest(t, "GET", editFormURL), http.StatusOK)
 | 
			
		||||
		htmlForm = NewHTMLParser(t, resp.Body).Find(`form[action^="/user2/repo1/settings/hooks/"]`)
 | 
			
		||||
		for k, v := range validFields {
 | 
			
		||||
			assert.Equal(t, v, assertInput(t, htmlForm, k), "input %q did not contain value %q", k, v)
 | 
			
		||||
		}
 | 
			
		||||
	// update the webhook
 | 
			
		||||
	resp = session.MakeRequest(t, NewRequestWithValues(t, "POST", editPostURL, payload), http.StatusSeeOther)
 | 
			
		||||
	assertHasFlashMessages(t, resp, "success")
 | 
			
		||||
 | 
			
		||||
		if len(invalidPatches) > 0 {
 | 
			
		||||
			// check that invalid fields are rejected
 | 
			
		||||
			resp := session.MakeRequest(t, NewRequest(t, "GET", "/user2/repo1/settings/hooks/"+name+"/new"), http.StatusOK)
 | 
			
		||||
			htmlForm := NewHTMLParser(t, resp.Body).Find(`form[action^="/user2/repo1/settings/hooks/"]`)
 | 
			
		||||
	// check the updated webhook
 | 
			
		||||
	resp = session.MakeRequest(t, NewRequest(t, "GET", editFormURL), http.StatusOK)
 | 
			
		||||
	htmlForm = NewHTMLParser(t, resp.Body).Find(`form[action^="` + updateEndpoint + `"]`)
 | 
			
		||||
	for k, v := range validFields {
 | 
			
		||||
		assert.Equal(t, v, assertInput(t, htmlForm, k), "input %q did not contain value %q", k, v)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
			for _, invalidPatch := range invalidPatches {
 | 
			
		||||
				t.Run("invalid", func(t *testing.T) {
 | 
			
		||||
					// fill the form
 | 
			
		||||
					payload := map[string]string{
 | 
			
		||||
						"_csrf":  htmlForm.Find(`input[name="_csrf"]`).AttrOr("value", ""),
 | 
			
		||||
						"events": "send_everything",
 | 
			
		||||
					}
 | 
			
		||||
					for k, v := range validFields {
 | 
			
		||||
	if len(invalidPatches) > 0 {
 | 
			
		||||
		// check that invalid fields are rejected
 | 
			
		||||
		resp := session.MakeRequest(t, NewRequest(t, "GET", endpoint+"/"+name+"/new"), http.StatusOK)
 | 
			
		||||
		htmlForm := NewHTMLParser(t, resp.Body).Find(`form[action^="` + endpoint + `/"]`)
 | 
			
		||||
 | 
			
		||||
		for _, invalidPatch := range invalidPatches {
 | 
			
		||||
			t.Run("invalid", func(t *testing.T) {
 | 
			
		||||
				// fill the form
 | 
			
		||||
				payload := map[string]string{
 | 
			
		||||
					"_csrf":  htmlForm.Find(`input[name="_csrf"]`).AttrOr("value", ""),
 | 
			
		||||
					"events": "send_everything",
 | 
			
		||||
				}
 | 
			
		||||
				for k, v := range validFields {
 | 
			
		||||
					payload[k] = v
 | 
			
		||||
				}
 | 
			
		||||
				for k, v := range invalidPatch {
 | 
			
		||||
					if v == "" {
 | 
			
		||||
						delete(payload, k)
 | 
			
		||||
					} else {
 | 
			
		||||
						payload[k] = v
 | 
			
		||||
					}
 | 
			
		||||
					for k, v := range invalidPatch {
 | 
			
		||||
						if v == "" {
 | 
			
		||||
							delete(payload, k)
 | 
			
		||||
						} else {
 | 
			
		||||
							payload[k] = v
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
					resp := session.MakeRequest(t, NewRequestWithValues(t, "POST", "/user2/repo1/settings/hooks/"+name+"/new", payload), http.StatusUnprocessableEntity)
 | 
			
		||||
					// check that the invalid form is pre-filled
 | 
			
		||||
					htmlForm = NewHTMLParser(t, resp.Body).Find(`form[action^="/user2/repo1/settings/hooks/"]`)
 | 
			
		||||
					for k, v := range payload {
 | 
			
		||||
						if k == "_csrf" || k == "events" || v == "" {
 | 
			
		||||
							// the 'events' is a radio input, which is buggy below
 | 
			
		||||
							continue
 | 
			
		||||
						}
 | 
			
		||||
						assert.Equal(t, v, assertInput(t, htmlForm, k), "input %q did not contain value %q", k, v)
 | 
			
		||||
				resp := session.MakeRequest(t, NewRequestWithValues(t, "POST", endpoint+"/"+name+"/new", payload), http.StatusUnprocessableEntity)
 | 
			
		||||
				// check that the invalid form is pre-filled
 | 
			
		||||
				htmlForm = NewHTMLParser(t, resp.Body).Find(`form[action^="` + endpoint + `/"]`)
 | 
			
		||||
				for k, v := range payload {
 | 
			
		||||
					if k == "_csrf" || k == "events" || v == "" {
 | 
			
		||||
						// the 'events' is a radio input, which is buggy below
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
					if t.Failed() {
 | 
			
		||||
						t.Log(invalidPatch)
 | 
			
		||||
					}
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
					assert.Equal(t, v, assertInput(t, htmlForm, k), "input %q did not contain value %q", k, v)
 | 
			
		||||
				}
 | 
			
		||||
				if t.Failed() {
 | 
			
		||||
					t.Log(invalidPatch)
 | 
			
		||||
				}
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue