fix: validate input for default_{merge,update}_style (#7395)
- Add `binding:"In(...)"` to the `default_merge_style` and `default_update_style` fields to only accept recognized merge and update styles. - Resolves https://codeberg.org/forgejo/forgejo/issues/7389 - Added integration test for the API (`binding` works in the exact same way for the API and web routes). Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7395 Reviewed-by: 0ko <0ko@noreply.codeberg.org> Co-authored-by: Gusted <postmaster@gusted.xyz> Co-committed-by: Gusted <postmaster@gusted.xyz>
This commit is contained in:
		
					parent
					
						
							
								114cd6d4b6
							
						
					
				
			
			
				commit
				
					
						4b56c05e65
					
				
			
		
					 5 changed files with 248 additions and 216 deletions
				
			
		| 
						 | 
				
			
			@ -224,10 +224,10 @@ type EditRepoOption struct {
 | 
			
		|||
	AllowRebaseUpdate *bool `json:"allow_rebase_update,omitempty"`
 | 
			
		||||
	// set to `true` to delete pr branch after merge by default
 | 
			
		||||
	DefaultDeleteBranchAfterMerge *bool `json:"default_delete_branch_after_merge,omitempty"`
 | 
			
		||||
	// set to a merge style to be used by this repository: "merge", "rebase", "rebase-merge", "squash", or "fast-forward-only".
 | 
			
		||||
	DefaultMergeStyle *string `json:"default_merge_style,omitempty"`
 | 
			
		||||
	// set to a merge style to be used by this repository: "merge", "rebase", "rebase-merge", "squash", "fast-forward-only", "manually-merged", or "rebase-update-only".
 | 
			
		||||
	DefaultMergeStyle *string `json:"default_merge_style,omitempty" binding:"In(merge,rebase,rebase-merge,squash,fast-forward-only,manually-merged,rebase-update-only)"`
 | 
			
		||||
	// set to a update style to be used by this repository: "rebase" or "merge"
 | 
			
		||||
	DefaultUpdateStyle *string `json:"default_update_style,omitempty"`
 | 
			
		||||
	DefaultUpdateStyle *string `json:"default_update_style,omitempty" binding:"In(merge,rebase)"`
 | 
			
		||||
	// set to `true` to allow edits from maintainers by default
 | 
			
		||||
	DefaultAllowMaintainerEdit *bool `json:"default_allow_maintainer_edit,omitempty"`
 | 
			
		||||
	// set to `true` to archive this repository.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -105,6 +105,10 @@ func Units(ctx *context.Context) {
 | 
			
		|||
 | 
			
		||||
func UnitsPost(ctx *context.Context) {
 | 
			
		||||
	form := web.GetForm(ctx).(*forms.RepoUnitSettingForm)
 | 
			
		||||
	if ctx.HasError() {
 | 
			
		||||
		ctx.Redirect(ctx.Repo.Repository.Link() + "/settings/units")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	repo := ctx.Repo.Repository
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -188,8 +188,8 @@ type RepoUnitSettingForm struct {
 | 
			
		|||
	PullsAllowSquash                      bool
 | 
			
		||||
	PullsAllowFastForwardOnly             bool
 | 
			
		||||
	PullsAllowManualMerge                 bool
 | 
			
		||||
	PullsDefaultMergeStyle                string
 | 
			
		||||
	PullsDefaultUpdateStyle               string
 | 
			
		||||
	PullsDefaultMergeStyle                string `binding:"In(merge,rebase,rebase-merge,squash,fast-forward-only,manually-merged,rebase-update-only)"`
 | 
			
		||||
	PullsDefaultUpdateStyle               string `binding:"In(merge,rebase)"`
 | 
			
		||||
	EnableAutodetectManualMerge           bool
 | 
			
		||||
	PullsAllowRebaseUpdate                bool
 | 
			
		||||
	DefaultDeleteBranchAfterMerge         bool
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								templates/swagger/v1_json.tmpl
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								templates/swagger/v1_json.tmpl
									
										
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -23762,7 +23762,7 @@
 | 
			
		|||
          "x-go-name": "DefaultDeleteBranchAfterMerge"
 | 
			
		||||
        },
 | 
			
		||||
        "default_merge_style": {
 | 
			
		||||
          "description": "set to a merge style to be used by this repository: \"merge\", \"rebase\", \"rebase-merge\", \"squash\", or \"fast-forward-only\".",
 | 
			
		||||
          "description": "set to a merge style to be used by this repository: \"merge\", \"rebase\", \"rebase-merge\", \"squash\", \"fast-forward-only\", \"manually-merged\", or \"rebase-update-only\".",
 | 
			
		||||
          "type": "string",
 | 
			
		||||
          "x-go-name": "DefaultMergeStyle"
 | 
			
		||||
        },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,6 @@ package integration
 | 
			
		|||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	auth_model "forgejo.org/models/auth"
 | 
			
		||||
| 
						 | 
				
			
			@ -16,6 +15,7 @@ import (
 | 
			
		|||
	"forgejo.org/models/unittest"
 | 
			
		||||
	user_model "forgejo.org/models/user"
 | 
			
		||||
	api "forgejo.org/modules/structs"
 | 
			
		||||
	"forgejo.org/tests"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -137,232 +137,260 @@ func getNewRepoEditOption(opts *api.EditRepoOption) *api.EditRepoOption {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func TestAPIRepoEdit(t *testing.T) {
 | 
			
		||||
	onGiteaRun(t, func(t *testing.T, u *url.URL) {
 | 
			
		||||
		bFalse, bTrue := false, true
 | 
			
		||||
	defer tests.PrepareTestEnv(t)()
 | 
			
		||||
	bFalse, bTrue := false, true
 | 
			
		||||
 | 
			
		||||
		user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})         // owner of the repo1 & repo16
 | 
			
		||||
		org3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})          // owner of the repo3, is an org
 | 
			
		||||
		user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})         // owner of neither repos
 | 
			
		||||
		repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})   // public repo
 | 
			
		||||
		repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})   // public repo
 | 
			
		||||
		repo15 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15}) // empty repo
 | 
			
		||||
		repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo
 | 
			
		||||
	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})         // owner of the repo1 & repo16
 | 
			
		||||
	org3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})          // owner of the repo3, is an org
 | 
			
		||||
	user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})         // owner of neither repos
 | 
			
		||||
	repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})   // public repo
 | 
			
		||||
	repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})   // public repo
 | 
			
		||||
	repo15 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15}) // empty repo
 | 
			
		||||
	repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo
 | 
			
		||||
 | 
			
		||||
		// Get user2's token
 | 
			
		||||
		session := loginUser(t, user2.Name)
 | 
			
		||||
		token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
 | 
			
		||||
		// Get user4's token
 | 
			
		||||
		session = loginUser(t, user4.Name)
 | 
			
		||||
		token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
 | 
			
		||||
	// Get user2's token
 | 
			
		||||
	session := loginUser(t, user2.Name)
 | 
			
		||||
	token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
 | 
			
		||||
	// Get user4's token
 | 
			
		||||
	session = loginUser(t, user4.Name)
 | 
			
		||||
	token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
 | 
			
		||||
 | 
			
		||||
		// Test editing a repo1 which user2 owns, changing name and many properties
 | 
			
		||||
		origRepoEditOption := getRepoEditOptionFromRepo(repo1)
 | 
			
		||||
		repoEditOption := getNewRepoEditOption(origRepoEditOption)
 | 
			
		||||
		req := NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo1.Name), &repoEditOption).
 | 
			
		||||
			AddTokenAuth(token2)
 | 
			
		||||
		resp := MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
		var repo api.Repository
 | 
			
		||||
		DecodeJSON(t, resp, &repo)
 | 
			
		||||
		assert.NotNil(t, repo)
 | 
			
		||||
		// check response
 | 
			
		||||
		assert.Equal(t, *repoEditOption.Name, repo.Name)
 | 
			
		||||
		assert.Equal(t, *repoEditOption.Description, repo.Description)
 | 
			
		||||
		assert.Equal(t, *repoEditOption.Website, repo.Website)
 | 
			
		||||
		assert.Equal(t, *repoEditOption.Archived, repo.Archived)
 | 
			
		||||
		// check repo1 from database
 | 
			
		||||
		repo1edited := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 | 
			
		||||
		repo1editedOption := getRepoEditOptionFromRepo(repo1edited)
 | 
			
		||||
		assert.Equal(t, *repoEditOption.Name, *repo1editedOption.Name)
 | 
			
		||||
		assert.Equal(t, *repoEditOption.Description, *repo1editedOption.Description)
 | 
			
		||||
		assert.Equal(t, *repoEditOption.Website, *repo1editedOption.Website)
 | 
			
		||||
		assert.Equal(t, *repoEditOption.Archived, *repo1editedOption.Archived)
 | 
			
		||||
		assert.Equal(t, *repoEditOption.Private, *repo1editedOption.Private)
 | 
			
		||||
		assert.Equal(t, *repoEditOption.HasWiki, *repo1editedOption.HasWiki)
 | 
			
		||||
	// Test editing a repo1 which user2 owns, changing name and many properties
 | 
			
		||||
	origRepoEditOption := getRepoEditOptionFromRepo(repo1)
 | 
			
		||||
	repoEditOption := getNewRepoEditOption(origRepoEditOption)
 | 
			
		||||
	req := NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo1.Name), &repoEditOption).
 | 
			
		||||
		AddTokenAuth(token2)
 | 
			
		||||
	resp := MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
	var repo api.Repository
 | 
			
		||||
	DecodeJSON(t, resp, &repo)
 | 
			
		||||
	assert.NotNil(t, repo)
 | 
			
		||||
	// check response
 | 
			
		||||
	assert.Equal(t, *repoEditOption.Name, repo.Name)
 | 
			
		||||
	assert.Equal(t, *repoEditOption.Description, repo.Description)
 | 
			
		||||
	assert.Equal(t, *repoEditOption.Website, repo.Website)
 | 
			
		||||
	assert.Equal(t, *repoEditOption.Archived, repo.Archived)
 | 
			
		||||
	// check repo1 from database
 | 
			
		||||
	repo1edited := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 | 
			
		||||
	repo1editedOption := getRepoEditOptionFromRepo(repo1edited)
 | 
			
		||||
	assert.Equal(t, *repoEditOption.Name, *repo1editedOption.Name)
 | 
			
		||||
	assert.Equal(t, *repoEditOption.Description, *repo1editedOption.Description)
 | 
			
		||||
	assert.Equal(t, *repoEditOption.Website, *repo1editedOption.Website)
 | 
			
		||||
	assert.Equal(t, *repoEditOption.Archived, *repo1editedOption.Archived)
 | 
			
		||||
	assert.Equal(t, *repoEditOption.Private, *repo1editedOption.Private)
 | 
			
		||||
	assert.Equal(t, *repoEditOption.HasWiki, *repo1editedOption.HasWiki)
 | 
			
		||||
 | 
			
		||||
		// Test editing repo1 to use internal issue and wiki (default)
 | 
			
		||||
		*repoEditOption.HasIssues = true
 | 
			
		||||
		repoEditOption.ExternalTracker = nil
 | 
			
		||||
		repoEditOption.InternalTracker = &api.InternalTracker{
 | 
			
		||||
			EnableTimeTracker:                false,
 | 
			
		||||
			AllowOnlyContributorsToTrackTime: false,
 | 
			
		||||
			EnableIssueDependencies:          false,
 | 
			
		||||
		}
 | 
			
		||||
		*repoEditOption.HasWiki = true
 | 
			
		||||
		repoEditOption.ExternalWiki = nil
 | 
			
		||||
		url := fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, *repoEditOption.Name)
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
			AddTokenAuth(token2)
 | 
			
		||||
		resp = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
		DecodeJSON(t, resp, &repo)
 | 
			
		||||
		assert.NotNil(t, repo)
 | 
			
		||||
		// check repo1 was written to database
 | 
			
		||||
		repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 | 
			
		||||
		repo1editedOption = getRepoEditOptionFromRepo(repo1edited)
 | 
			
		||||
		assert.True(t, *repo1editedOption.HasIssues)
 | 
			
		||||
		assert.Nil(t, repo1editedOption.ExternalTracker)
 | 
			
		||||
		assert.Equal(t, *repo1editedOption.InternalTracker, *repoEditOption.InternalTracker)
 | 
			
		||||
		assert.True(t, *repo1editedOption.HasWiki)
 | 
			
		||||
		assert.Nil(t, repo1editedOption.ExternalWiki)
 | 
			
		||||
	// Test editing repo1 to use internal issue and wiki (default)
 | 
			
		||||
	*repoEditOption.HasIssues = true
 | 
			
		||||
	repoEditOption.ExternalTracker = nil
 | 
			
		||||
	repoEditOption.InternalTracker = &api.InternalTracker{
 | 
			
		||||
		EnableTimeTracker:                false,
 | 
			
		||||
		AllowOnlyContributorsToTrackTime: false,
 | 
			
		||||
		EnableIssueDependencies:          false,
 | 
			
		||||
	}
 | 
			
		||||
	*repoEditOption.HasWiki = true
 | 
			
		||||
	repoEditOption.ExternalWiki = nil
 | 
			
		||||
	url := fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, *repoEditOption.Name)
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
		AddTokenAuth(token2)
 | 
			
		||||
	resp = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
	DecodeJSON(t, resp, &repo)
 | 
			
		||||
	assert.NotNil(t, repo)
 | 
			
		||||
	// check repo1 was written to database
 | 
			
		||||
	repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 | 
			
		||||
	repo1editedOption = getRepoEditOptionFromRepo(repo1edited)
 | 
			
		||||
	assert.True(t, *repo1editedOption.HasIssues)
 | 
			
		||||
	assert.Nil(t, repo1editedOption.ExternalTracker)
 | 
			
		||||
	assert.Equal(t, *repo1editedOption.InternalTracker, *repoEditOption.InternalTracker)
 | 
			
		||||
	assert.True(t, *repo1editedOption.HasWiki)
 | 
			
		||||
	assert.Nil(t, repo1editedOption.ExternalWiki)
 | 
			
		||||
 | 
			
		||||
		// Test editing repo1 to use external issue and wiki
 | 
			
		||||
		repoEditOption.ExternalTracker = &api.ExternalTracker{
 | 
			
		||||
			ExternalTrackerURL:    "http://www.somewebsite.com",
 | 
			
		||||
			ExternalTrackerFormat: "http://www.somewebsite.com/{user}/{repo}?issue={index}",
 | 
			
		||||
			ExternalTrackerStyle:  "alphanumeric",
 | 
			
		||||
		}
 | 
			
		||||
		repoEditOption.ExternalWiki = &api.ExternalWiki{
 | 
			
		||||
			ExternalWikiURL: "http://www.somewebsite.com",
 | 
			
		||||
		}
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
			AddTokenAuth(token2)
 | 
			
		||||
		resp = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
		DecodeJSON(t, resp, &repo)
 | 
			
		||||
		assert.NotNil(t, repo)
 | 
			
		||||
		// check repo1 was written to database
 | 
			
		||||
		repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 | 
			
		||||
		repo1editedOption = getRepoEditOptionFromRepo(repo1edited)
 | 
			
		||||
		assert.True(t, *repo1editedOption.HasIssues)
 | 
			
		||||
		assert.Equal(t, *repo1editedOption.ExternalTracker, *repoEditOption.ExternalTracker)
 | 
			
		||||
		assert.True(t, *repo1editedOption.HasWiki)
 | 
			
		||||
		assert.Equal(t, *repo1editedOption.ExternalWiki, *repoEditOption.ExternalWiki)
 | 
			
		||||
	// Test editing repo1 to use external issue and wiki
 | 
			
		||||
	repoEditOption.ExternalTracker = &api.ExternalTracker{
 | 
			
		||||
		ExternalTrackerURL:    "http://www.somewebsite.com",
 | 
			
		||||
		ExternalTrackerFormat: "http://www.somewebsite.com/{user}/{repo}?issue={index}",
 | 
			
		||||
		ExternalTrackerStyle:  "alphanumeric",
 | 
			
		||||
	}
 | 
			
		||||
	repoEditOption.ExternalWiki = &api.ExternalWiki{
 | 
			
		||||
		ExternalWikiURL: "http://www.somewebsite.com",
 | 
			
		||||
	}
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
		AddTokenAuth(token2)
 | 
			
		||||
	resp = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
	DecodeJSON(t, resp, &repo)
 | 
			
		||||
	assert.NotNil(t, repo)
 | 
			
		||||
	// check repo1 was written to database
 | 
			
		||||
	repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 | 
			
		||||
	repo1editedOption = getRepoEditOptionFromRepo(repo1edited)
 | 
			
		||||
	assert.True(t, *repo1editedOption.HasIssues)
 | 
			
		||||
	assert.Equal(t, *repo1editedOption.ExternalTracker, *repoEditOption.ExternalTracker)
 | 
			
		||||
	assert.True(t, *repo1editedOption.HasWiki)
 | 
			
		||||
	assert.Equal(t, *repo1editedOption.ExternalWiki, *repoEditOption.ExternalWiki)
 | 
			
		||||
 | 
			
		||||
		repoEditOption.ExternalTracker.ExternalTrackerStyle = "regexp"
 | 
			
		||||
		repoEditOption.ExternalTracker.ExternalTrackerRegexpPattern = `(\d+)`
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
			AddTokenAuth(token2)
 | 
			
		||||
		resp = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
		DecodeJSON(t, resp, &repo)
 | 
			
		||||
		assert.NotNil(t, repo)
 | 
			
		||||
		repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 | 
			
		||||
		repo1editedOption = getRepoEditOptionFromRepo(repo1edited)
 | 
			
		||||
		assert.True(t, *repo1editedOption.HasIssues)
 | 
			
		||||
		assert.Equal(t, *repo1editedOption.ExternalTracker, *repoEditOption.ExternalTracker)
 | 
			
		||||
	repoEditOption.ExternalTracker.ExternalTrackerStyle = "regexp"
 | 
			
		||||
	repoEditOption.ExternalTracker.ExternalTrackerRegexpPattern = `(\d+)`
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
		AddTokenAuth(token2)
 | 
			
		||||
	resp = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
	DecodeJSON(t, resp, &repo)
 | 
			
		||||
	assert.NotNil(t, repo)
 | 
			
		||||
	repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 | 
			
		||||
	repo1editedOption = getRepoEditOptionFromRepo(repo1edited)
 | 
			
		||||
	assert.True(t, *repo1editedOption.HasIssues)
 | 
			
		||||
	assert.Equal(t, *repo1editedOption.ExternalTracker, *repoEditOption.ExternalTracker)
 | 
			
		||||
 | 
			
		||||
		// Do some tests with invalid URL for external tracker and wiki
 | 
			
		||||
		repoEditOption.ExternalTracker.ExternalTrackerURL = "htp://www.somewebsite.com"
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
			AddTokenAuth(token2)
 | 
			
		||||
		MakeRequest(t, req, http.StatusUnprocessableEntity)
 | 
			
		||||
		repoEditOption.ExternalTracker.ExternalTrackerURL = "http://www.somewebsite.com"
 | 
			
		||||
		repoEditOption.ExternalTracker.ExternalTrackerFormat = "http://www.somewebsite.com/{user/{repo}?issue={index}"
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
			AddTokenAuth(token2)
 | 
			
		||||
		MakeRequest(t, req, http.StatusUnprocessableEntity)
 | 
			
		||||
		repoEditOption.ExternalTracker.ExternalTrackerFormat = "http://www.somewebsite.com/{user}/{repo}?issue={index}"
 | 
			
		||||
		repoEditOption.ExternalWiki.ExternalWikiURL = "htp://www.somewebsite.com"
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
			AddTokenAuth(token2)
 | 
			
		||||
		MakeRequest(t, req, http.StatusUnprocessableEntity)
 | 
			
		||||
	// Do some tests with invalid URL for external tracker and wiki
 | 
			
		||||
	repoEditOption.ExternalTracker.ExternalTrackerURL = "htp://www.somewebsite.com"
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
		AddTokenAuth(token2)
 | 
			
		||||
	MakeRequest(t, req, http.StatusUnprocessableEntity)
 | 
			
		||||
	repoEditOption.ExternalTracker.ExternalTrackerURL = "http://www.somewebsite.com"
 | 
			
		||||
	repoEditOption.ExternalTracker.ExternalTrackerFormat = "http://www.somewebsite.com/{user/{repo}?issue={index}"
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
		AddTokenAuth(token2)
 | 
			
		||||
	MakeRequest(t, req, http.StatusUnprocessableEntity)
 | 
			
		||||
	repoEditOption.ExternalTracker.ExternalTrackerFormat = "http://www.somewebsite.com/{user}/{repo}?issue={index}"
 | 
			
		||||
	repoEditOption.ExternalWiki.ExternalWikiURL = "htp://www.somewebsite.com"
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
		AddTokenAuth(token2)
 | 
			
		||||
	MakeRequest(t, req, http.StatusUnprocessableEntity)
 | 
			
		||||
 | 
			
		||||
		// Test small repo change through API with issue and wiki option not set; They shall not be touched.
 | 
			
		||||
		*repoEditOption.Description = "small change"
 | 
			
		||||
		repoEditOption.HasIssues = nil
 | 
			
		||||
		repoEditOption.ExternalTracker = nil
 | 
			
		||||
		repoEditOption.HasWiki = nil
 | 
			
		||||
		repoEditOption.ExternalWiki = nil
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
			AddTokenAuth(token2)
 | 
			
		||||
		resp = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
		DecodeJSON(t, resp, &repo)
 | 
			
		||||
		assert.NotNil(t, repo)
 | 
			
		||||
		// check repo1 was written to database
 | 
			
		||||
		repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 | 
			
		||||
		repo1editedOption = getRepoEditOptionFromRepo(repo1edited)
 | 
			
		||||
		assert.Equal(t, *repo1editedOption.Description, *repoEditOption.Description)
 | 
			
		||||
		assert.True(t, *repo1editedOption.HasIssues)
 | 
			
		||||
		assert.NotNil(t, *repo1editedOption.ExternalTracker)
 | 
			
		||||
		assert.True(t, *repo1editedOption.HasWiki)
 | 
			
		||||
		assert.NotNil(t, *repo1editedOption.ExternalWiki)
 | 
			
		||||
	// Test small repo change through API with issue and wiki option not set; They shall not be touched.
 | 
			
		||||
	*repoEditOption.Description = "small change"
 | 
			
		||||
	repoEditOption.HasIssues = nil
 | 
			
		||||
	repoEditOption.ExternalTracker = nil
 | 
			
		||||
	repoEditOption.HasWiki = nil
 | 
			
		||||
	repoEditOption.ExternalWiki = nil
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
		AddTokenAuth(token2)
 | 
			
		||||
	resp = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
	DecodeJSON(t, resp, &repo)
 | 
			
		||||
	assert.NotNil(t, repo)
 | 
			
		||||
	// check repo1 was written to database
 | 
			
		||||
	repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 | 
			
		||||
	repo1editedOption = getRepoEditOptionFromRepo(repo1edited)
 | 
			
		||||
	assert.Equal(t, *repo1editedOption.Description, *repoEditOption.Description)
 | 
			
		||||
	assert.True(t, *repo1editedOption.HasIssues)
 | 
			
		||||
	assert.NotNil(t, *repo1editedOption.ExternalTracker)
 | 
			
		||||
	assert.True(t, *repo1editedOption.HasWiki)
 | 
			
		||||
	assert.NotNil(t, *repo1editedOption.ExternalWiki)
 | 
			
		||||
 | 
			
		||||
		// reset repo in db
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, *repoEditOption.Name), &origRepoEditOption).
 | 
			
		||||
			AddTokenAuth(token2)
 | 
			
		||||
		_ = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
	// reset repo in db
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, *repoEditOption.Name), &origRepoEditOption).
 | 
			
		||||
		AddTokenAuth(token2)
 | 
			
		||||
	_ = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
 | 
			
		||||
		// Test editing a non-existing repo
 | 
			
		||||
		name := "repodoesnotexist"
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, name), &api.EditRepoOption{Name: &name}).
 | 
			
		||||
			AddTokenAuth(token2)
 | 
			
		||||
		_ = MakeRequest(t, req, http.StatusNotFound)
 | 
			
		||||
	// Test editing a non-existing repo
 | 
			
		||||
	name := "repodoesnotexist"
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, name), &api.EditRepoOption{Name: &name}).
 | 
			
		||||
		AddTokenAuth(token2)
 | 
			
		||||
	_ = MakeRequest(t, req, http.StatusNotFound)
 | 
			
		||||
 | 
			
		||||
		// Test editing repo16 by user4 who does not have write access
 | 
			
		||||
		origRepoEditOption = getRepoEditOptionFromRepo(repo16)
 | 
			
		||||
		repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo16.Name), &repoEditOption).
 | 
			
		||||
			AddTokenAuth(token4)
 | 
			
		||||
		MakeRequest(t, req, http.StatusNotFound)
 | 
			
		||||
	// Test editing repo16 by user4 who does not have write access
 | 
			
		||||
	origRepoEditOption = getRepoEditOptionFromRepo(repo16)
 | 
			
		||||
	repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo16.Name), &repoEditOption).
 | 
			
		||||
		AddTokenAuth(token4)
 | 
			
		||||
	MakeRequest(t, req, http.StatusNotFound)
 | 
			
		||||
 | 
			
		||||
		// Tests a repo with no token given so will fail
 | 
			
		||||
		origRepoEditOption = getRepoEditOptionFromRepo(repo16)
 | 
			
		||||
		repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo16.Name), &repoEditOption)
 | 
			
		||||
		_ = MakeRequest(t, req, http.StatusNotFound)
 | 
			
		||||
	// Tests a repo with no token given so will fail
 | 
			
		||||
	origRepoEditOption = getRepoEditOptionFromRepo(repo16)
 | 
			
		||||
	repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo16.Name), &repoEditOption)
 | 
			
		||||
	_ = MakeRequest(t, req, http.StatusNotFound)
 | 
			
		||||
 | 
			
		||||
		// Test using access token for a private repo that the user of the token owns
 | 
			
		||||
		origRepoEditOption = getRepoEditOptionFromRepo(repo16)
 | 
			
		||||
		repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo16.Name), &repoEditOption).
 | 
			
		||||
			AddTokenAuth(token2)
 | 
			
		||||
		_ = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
		// reset repo in db
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, *repoEditOption.Name), &origRepoEditOption).
 | 
			
		||||
			AddTokenAuth(token2)
 | 
			
		||||
		_ = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
	// Test using access token for a private repo that the user of the token owns
 | 
			
		||||
	origRepoEditOption = getRepoEditOptionFromRepo(repo16)
 | 
			
		||||
	repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo16.Name), &repoEditOption).
 | 
			
		||||
		AddTokenAuth(token2)
 | 
			
		||||
	_ = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
	// reset repo in db
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, *repoEditOption.Name), &origRepoEditOption).
 | 
			
		||||
		AddTokenAuth(token2)
 | 
			
		||||
	_ = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
 | 
			
		||||
		// Test making a repo public that is private
 | 
			
		||||
		repo16 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16})
 | 
			
		||||
		assert.True(t, repo16.IsPrivate)
 | 
			
		||||
		repoEditOption = &api.EditRepoOption{
 | 
			
		||||
			Private: &bFalse,
 | 
			
		||||
		}
 | 
			
		||||
		url = fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo16.Name)
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
			AddTokenAuth(token2)
 | 
			
		||||
		_ = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
		repo16 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16})
 | 
			
		||||
		assert.False(t, repo16.IsPrivate)
 | 
			
		||||
		// Make it private again
 | 
			
		||||
		repoEditOption.Private = &bTrue
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
			AddTokenAuth(token2)
 | 
			
		||||
		_ = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
	// Test making a repo public that is private
 | 
			
		||||
	repo16 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16})
 | 
			
		||||
	assert.True(t, repo16.IsPrivate)
 | 
			
		||||
	repoEditOption = &api.EditRepoOption{
 | 
			
		||||
		Private: &bFalse,
 | 
			
		||||
	}
 | 
			
		||||
	url = fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo16.Name)
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
		AddTokenAuth(token2)
 | 
			
		||||
	_ = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
	repo16 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16})
 | 
			
		||||
	assert.False(t, repo16.IsPrivate)
 | 
			
		||||
	// Make it private again
 | 
			
		||||
	repoEditOption.Private = &bTrue
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption).
 | 
			
		||||
		AddTokenAuth(token2)
 | 
			
		||||
	_ = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
 | 
			
		||||
		// Test to change empty repo
 | 
			
		||||
		assert.False(t, repo15.IsArchived)
 | 
			
		||||
		url = fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo15.Name)
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", url, &api.EditRepoOption{
 | 
			
		||||
			Archived: &bTrue,
 | 
			
		||||
		}).AddTokenAuth(token2)
 | 
			
		||||
		_ = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
		repo15 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15})
 | 
			
		||||
		assert.True(t, repo15.IsArchived)
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", url, &api.EditRepoOption{
 | 
			
		||||
			Archived: &bFalse,
 | 
			
		||||
		}).AddTokenAuth(token2)
 | 
			
		||||
		_ = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
	// Test to change empty repo
 | 
			
		||||
	assert.False(t, repo15.IsArchived)
 | 
			
		||||
	url = fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo15.Name)
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", url, &api.EditRepoOption{
 | 
			
		||||
		Archived: &bTrue,
 | 
			
		||||
	}).AddTokenAuth(token2)
 | 
			
		||||
	_ = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
	repo15 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15})
 | 
			
		||||
	assert.True(t, repo15.IsArchived)
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", url, &api.EditRepoOption{
 | 
			
		||||
		Archived: &bFalse,
 | 
			
		||||
	}).AddTokenAuth(token2)
 | 
			
		||||
	_ = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
 | 
			
		||||
		// Test using org repo "org3/repo3" where user2 is a collaborator
 | 
			
		||||
		origRepoEditOption = getRepoEditOptionFromRepo(repo3)
 | 
			
		||||
		repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", org3.Name, repo3.Name), &repoEditOption).
 | 
			
		||||
			AddTokenAuth(token2)
 | 
			
		||||
		MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
		// reset repo in db
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", org3.Name, *repoEditOption.Name), &origRepoEditOption).
 | 
			
		||||
			AddTokenAuth(token2)
 | 
			
		||||
		_ = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
	// Test using org repo "org3/repo3" where user2 is a collaborator
 | 
			
		||||
	origRepoEditOption = getRepoEditOptionFromRepo(repo3)
 | 
			
		||||
	repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", org3.Name, repo3.Name), &repoEditOption).
 | 
			
		||||
		AddTokenAuth(token2)
 | 
			
		||||
	MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
	// reset repo in db
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", org3.Name, *repoEditOption.Name), &origRepoEditOption).
 | 
			
		||||
		AddTokenAuth(token2)
 | 
			
		||||
	_ = MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
 | 
			
		||||
		// Test using org repo "org3/repo3" with no user token
 | 
			
		||||
		origRepoEditOption = getRepoEditOptionFromRepo(repo3)
 | 
			
		||||
		repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", org3.Name, repo3.Name), &repoEditOption)
 | 
			
		||||
		MakeRequest(t, req, http.StatusNotFound)
 | 
			
		||||
	// Test using org repo "org3/repo3" with no user token
 | 
			
		||||
	origRepoEditOption = getRepoEditOptionFromRepo(repo3)
 | 
			
		||||
	repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", org3.Name, repo3.Name), &repoEditOption)
 | 
			
		||||
	MakeRequest(t, req, http.StatusNotFound)
 | 
			
		||||
 | 
			
		||||
		// Test using repo "user2/repo1" where user4 is a NOT collaborator
 | 
			
		||||
		origRepoEditOption = getRepoEditOptionFromRepo(repo1)
 | 
			
		||||
		repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
			
		||||
		req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo1.Name), &repoEditOption).
 | 
			
		||||
			AddTokenAuth(token4)
 | 
			
		||||
		MakeRequest(t, req, http.StatusForbidden)
 | 
			
		||||
	// Test using repo "user2/repo1" where user4 is a NOT collaborator
 | 
			
		||||
	origRepoEditOption = getRepoEditOptionFromRepo(repo1)
 | 
			
		||||
	repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
			
		||||
	req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo1.Name), &repoEditOption).
 | 
			
		||||
		AddTokenAuth(token4)
 | 
			
		||||
	MakeRequest(t, req, http.StatusForbidden)
 | 
			
		||||
 | 
			
		||||
	t.Run("Default merge style", func(t *testing.T) {
 | 
			
		||||
		defer tests.PrintCurrentTest(t)()
 | 
			
		||||
 | 
			
		||||
		updateStyle := "invalid"
 | 
			
		||||
		MakeRequest(t, NewRequestWithJSON(t, "PATCH", url, &api.EditRepoOption{
 | 
			
		||||
			DefaultUpdateStyle: &updateStyle,
 | 
			
		||||
		}).AddTokenAuth(token2), http.StatusUnprocessableEntity)
 | 
			
		||||
 | 
			
		||||
		MakeRequest(t, NewRequestWithJSON(t, "PATCH", url, &api.EditRepoOption{
 | 
			
		||||
			DefaultMergeStyle: &updateStyle,
 | 
			
		||||
		}).AddTokenAuth(token2), http.StatusUnprocessableEntity)
 | 
			
		||||
 | 
			
		||||
		var apiRepo api.Repository
 | 
			
		||||
		DecodeJSON(t, MakeRequest(t, NewRequest(t, "GET", url).AddTokenAuth(token2), http.StatusOK), &apiRepo)
 | 
			
		||||
		assert.Equal(t, "merge", apiRepo.DefaultMergeStyle)
 | 
			
		||||
		assert.Equal(t, "merge", apiRepo.DefaultUpdateStyle)
 | 
			
		||||
 | 
			
		||||
		updateStyle = "rebase"
 | 
			
		||||
		MakeRequest(t, NewRequestWithJSON(t, "PATCH", url, &api.EditRepoOption{
 | 
			
		||||
			DefaultMergeStyle:  &updateStyle,
 | 
			
		||||
			DefaultUpdateStyle: &updateStyle,
 | 
			
		||||
			HasPullRequests:    &bTrue,
 | 
			
		||||
		}).AddTokenAuth(token2), http.StatusOK)
 | 
			
		||||
 | 
			
		||||
		DecodeJSON(t, MakeRequest(t, NewRequest(t, "GET", url).AddTokenAuth(token2), http.StatusOK), &apiRepo)
 | 
			
		||||
		assert.Equal(t, "rebase", apiRepo.DefaultMergeStyle)
 | 
			
		||||
		assert.Equal(t, "rebase", apiRepo.DefaultUpdateStyle)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue