diff --git a/integrations/api_helper_for_declarative_test.go b/integrations/api_helper_for_declarative_test.go index 943981ead..85f0ab621 100644 --- a/integrations/api_helper_for_declarative_test.go +++ b/integrations/api_helper_for_declarative_test.go @@ -5,11 +5,14 @@ package integrations import ( + "encoding/json" "fmt" "io/ioutil" "net/http" "testing" + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/auth" api "code.gitea.io/gitea/modules/structs" "github.com/stretchr/testify/assert" ) @@ -150,3 +153,42 @@ func doAPICreateDeployKey(ctx APITestContext, keyname, keyFile string, readOnly ctx.Session.MakeRequest(t, req, http.StatusCreated) } } + +func doAPICreatePullRequest(ctx APITestContext, owner, repo, baseBranch, headBranch string) func(*testing.T) (api.PullRequest, error) { + return func(t *testing.T) (api.PullRequest, error) { + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls?token=%s", + owner, repo, ctx.Token) + req := NewRequestWithJSON(t, http.MethodPost, urlStr, &api.CreatePullRequestOption{ + Head: headBranch, + Base: baseBranch, + Title: fmt.Sprintf("create a pr from %s to %s", headBranch, baseBranch), + }) + + expected := 201 + if ctx.ExpectedCode != 0 { + expected = ctx.ExpectedCode + } + resp := ctx.Session.MakeRequest(t, req, expected) + decoder := json.NewDecoder(resp.Body) + pr := api.PullRequest{} + err := decoder.Decode(&pr) + return pr, err + } +} + +func doAPIMergePullRequest(ctx APITestContext, owner, repo string, index int64) func(*testing.T) { + return func(t *testing.T) { + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge?token=%s", + owner, repo, index, ctx.Token) + req := NewRequestWithJSON(t, http.MethodPost, urlStr, &auth.MergePullRequestForm{ + MergeMessageField: "doAPIMergePullRequest Merge", + Do: string(models.MergeStyleMerge), + }) + + if ctx.ExpectedCode != 0 { + ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) + return + } + ctx.Session.MakeRequest(t, req, 200) + } +} diff --git a/integrations/git_helper_for_declarative_test.go b/integrations/git_helper_for_declarative_test.go index b4fead662..235f4b4a9 100644 --- a/integrations/git_helper_for_declarative_test.go +++ b/integrations/git_helper_for_declarative_test.go @@ -112,16 +112,44 @@ func doGitAddRemote(dstPath, remoteName string, u *url.URL) func(*testing.T) { } } -func doGitPushTestRepository(dstPath, remoteName, branch string) func(*testing.T) { +func doGitPushTestRepository(dstPath string, args ...string) func(*testing.T) { return func(t *testing.T) { - _, err := git.NewCommand("push", "-u", remoteName, branch).RunInDir(dstPath) + _, err := git.NewCommand(append([]string{"push", "-u"}, args...)...).RunInDir(dstPath) assert.NoError(t, err) } } -func doGitPushTestRepositoryFail(dstPath, remoteName, branch string) func(*testing.T) { +func doGitPushTestRepositoryFail(dstPath string, args ...string) func(*testing.T) { return func(t *testing.T) { - _, err := git.NewCommand("push", "-u", remoteName, branch).RunInDir(dstPath) + _, err := git.NewCommand(append([]string{"push"}, args...)...).RunInDir(dstPath) assert.Error(t, err) } } + +func doGitCreateBranch(dstPath, branch string) func(*testing.T) { + return func(t *testing.T) { + _, err := git.NewCommand("checkout", "-b", branch).RunInDir(dstPath) + assert.NoError(t, err) + } +} + +func doGitCheckoutBranch(dstPath string, args ...string) func(*testing.T) { + return func(t *testing.T) { + _, err := git.NewCommand(append([]string{"checkout"}, args...)...).RunInDir(dstPath) + assert.NoError(t, err) + } +} + +func doGitMerge(dstPath string, args ...string) func(*testing.T) { + return func(t *testing.T) { + _, err := git.NewCommand(append([]string{"merge"}, args...)...).RunInDir(dstPath) + assert.NoError(t, err) + } +} + +func doGitPull(dstPath string, args ...string) func(*testing.T) { + return func(t *testing.T) { + _, err := git.NewCommand(append([]string{"pull"}, args...)...).RunInDir(dstPath) + assert.NoError(t, err) + } +} diff --git a/integrations/git_test.go b/integrations/git_test.go index 0554f9a5a..ce5aee493 100644 --- a/integrations/git_test.go +++ b/integrations/git_test.go @@ -13,11 +13,13 @@ import ( "os" "path" "path/filepath" + "strconv" "testing" "time" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/git" + api "code.gitea.io/gitea/modules/structs" "github.com/stretchr/testify/assert" ) @@ -43,119 +45,23 @@ func testGit(t *testing.T, u *url.URL) { httpContext.Reponame = "repo-tmp-17" dstPath, err := ioutil.TempDir("", httpContext.Reponame) - var little, big, littleLFS, bigLFS string - assert.NoError(t, err) defer os.RemoveAll(dstPath) - t.Run("Standard", func(t *testing.T) { - PrintCurrentTest(t) - ensureAnonymousClone(t, u) - - t.Run("CreateRepo", doAPICreateRepository(httpContext, false)) - - u.Path = httpContext.GitPath() - u.User = url.UserPassword(username, userPassword) - - t.Run("Clone", doGitClone(dstPath, u)) - - t.Run("PushCommit", func(t *testing.T) { - PrintCurrentTest(t) - t.Run("Little", func(t *testing.T) { - PrintCurrentTest(t) - little = commitAndPush(t, littleSize, dstPath) - }) - t.Run("Big", func(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - return - } - PrintCurrentTest(t) - big = commitAndPush(t, bigSize, dstPath) - }) - }) - }) - t.Run("LFS", func(t *testing.T) { - PrintCurrentTest(t) - t.Run("PushCommit", func(t *testing.T) { - PrintCurrentTest(t) - //Setup git LFS - _, err = git.NewCommand("lfs").AddArguments("install").RunInDir(dstPath) - assert.NoError(t, err) - _, err = git.NewCommand("lfs").AddArguments("track", "data-file-*").RunInDir(dstPath) - assert.NoError(t, err) - err = git.AddChanges(dstPath, false, ".gitattributes") - assert.NoError(t, err) - - t.Run("Little", func(t *testing.T) { - PrintCurrentTest(t) - littleLFS = commitAndPush(t, littleSize, dstPath) - lockFileTest(t, littleLFS, dstPath) - }) - t.Run("Big", func(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - return - } - PrintCurrentTest(t) - bigLFS = commitAndPush(t, bigSize, dstPath) - lockFileTest(t, bigLFS, dstPath) - }) - }) - t.Run("Locks", func(t *testing.T) { - PrintCurrentTest(t) - lockTest(t, u.String(), dstPath) - }) - }) - t.Run("Raw", func(t *testing.T) { - PrintCurrentTest(t) - session := loginUser(t, "user2") - - // Request raw paths - req := NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", little)) - resp := session.MakeRequest(t, req, http.StatusOK) - assert.Equal(t, littleSize, resp.Body.Len()) - - req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", littleLFS)) - resp = session.MakeRequest(t, req, http.StatusOK) - assert.NotEqual(t, littleSize, resp.Body.Len()) - assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier) - - if !testing.Short() { - req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", big)) - nilResp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) - assert.Equal(t, bigSize, nilResp.Length) - - req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", bigLFS)) - resp = session.MakeRequest(t, req, http.StatusOK) - assert.NotEqual(t, bigSize, resp.Body.Len()) - assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier) - } - - }) - t.Run("Media", func(t *testing.T) { - PrintCurrentTest(t) - session := loginUser(t, "user2") - // Request media paths - req := NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", little)) - resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) - assert.Equal(t, littleSize, resp.Length) + t.Run("CreateRepo", doAPICreateRepository(httpContext, false)) + ensureAnonymousClone(t, u) - req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", littleLFS)) - resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) - assert.Equal(t, littleSize, resp.Length) + u.Path = httpContext.GitPath() + u.User = url.UserPassword(username, userPassword) - if !testing.Short() { - req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", big)) - resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) - assert.Equal(t, bigSize, resp.Length) + t.Run("Clone", doGitClone(dstPath, u)) - req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", bigLFS)) - resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) - assert.Equal(t, bigSize, resp.Length) - } - }) + little, big := standardCommitAndPushTest(t, dstPath) + littleLFS, bigLFS := lfsCommitAndPushTest(t, dstPath) + rawTest(t, &httpContext, little, big, littleLFS, bigLFS) + mediaTest(t, &httpContext, little, big, littleLFS, bigLFS) + t.Run("BranchProtectMerge", doBranchProtectPRMerge(&httpContext, dstPath)) }) t.Run("SSH", func(t *testing.T) { PrintCurrentTest(t) @@ -165,123 +71,26 @@ func testGit(t *testing.T, u *url.URL) { //Setup key the user ssh key withKeyFile(t, keyname, func(keyFile string) { t.Run("CreateUserKey", doAPICreateUserKey(sshContext, "test-key", keyFile)) - PrintCurrentTest(t) //Setup remote link + //TODO: get url from api sshURL := createSSHUrl(sshContext.GitPath(), u) //Setup clone folder dstPath, err := ioutil.TempDir("", sshContext.Reponame) assert.NoError(t, err) defer os.RemoveAll(dstPath) - var little, big, littleLFS, bigLFS string - - t.Run("Standard", func(t *testing.T) { - PrintCurrentTest(t) - t.Run("CreateRepo", doAPICreateRepository(sshContext, false)) - - //TODO get url from api - t.Run("Clone", doGitClone(dstPath, sshURL)) - - //time.Sleep(5 * time.Minute) - t.Run("PushCommit", func(t *testing.T) { - PrintCurrentTest(t) - t.Run("Little", func(t *testing.T) { - PrintCurrentTest(t) - little = commitAndPush(t, littleSize, dstPath) - }) - t.Run("Big", func(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - return - } - PrintCurrentTest(t) - big = commitAndPush(t, bigSize, dstPath) - }) - }) - }) - t.Run("LFS", func(t *testing.T) { - PrintCurrentTest(t) - t.Run("PushCommit", func(t *testing.T) { - PrintCurrentTest(t) - //Setup git LFS - _, err = git.NewCommand("lfs").AddArguments("install").RunInDir(dstPath) - assert.NoError(t, err) - _, err = git.NewCommand("lfs").AddArguments("track", "data-file-*").RunInDir(dstPath) - assert.NoError(t, err) - err = git.AddChanges(dstPath, false, ".gitattributes") - assert.NoError(t, err) - - t.Run("Little", func(t *testing.T) { - PrintCurrentTest(t) - littleLFS = commitAndPush(t, littleSize, dstPath) - lockFileTest(t, littleLFS, dstPath) - - }) - t.Run("Big", func(t *testing.T) { - if testing.Short() { - return - } - PrintCurrentTest(t) - bigLFS = commitAndPush(t, bigSize, dstPath) - lockFileTest(t, bigLFS, dstPath) - - }) - }) - t.Run("Locks", func(t *testing.T) { - PrintCurrentTest(t) - lockTest(t, u.String(), dstPath) - }) - }) - t.Run("Raw", func(t *testing.T) { - PrintCurrentTest(t) - session := loginUser(t, "user2") - - // Request raw paths - req := NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", little)) - resp := session.MakeRequest(t, req, http.StatusOK) - assert.Equal(t, littleSize, resp.Body.Len()) - - req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", littleLFS)) - resp = session.MakeRequest(t, req, http.StatusOK) - assert.NotEqual(t, littleSize, resp.Body.Len()) - assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier) - - if !testing.Short() { - req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", big)) - resp = session.MakeRequest(t, req, http.StatusOK) - assert.Equal(t, bigSize, resp.Body.Len()) - - req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", bigLFS)) - resp = session.MakeRequest(t, req, http.StatusOK) - assert.NotEqual(t, bigSize, resp.Body.Len()) - assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier) - } - }) - t.Run("Media", func(t *testing.T) { - PrintCurrentTest(t) - session := loginUser(t, "user2") - - // Request media paths - req := NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", little)) - resp := session.MakeRequest(t, req, http.StatusOK) - assert.Equal(t, littleSize, resp.Body.Len()) - - req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", littleLFS)) - resp = session.MakeRequest(t, req, http.StatusOK) - assert.Equal(t, littleSize, resp.Body.Len()) - - if !testing.Short() { - req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", big)) - resp = session.MakeRequest(t, req, http.StatusOK) - assert.Equal(t, bigSize, resp.Body.Len()) - - req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", bigLFS)) - resp = session.MakeRequest(t, req, http.StatusOK) - assert.Equal(t, bigSize, resp.Body.Len()) - } - }) + t.Run("CreateRepo", doAPICreateRepository(sshContext, false)) + + t.Run("Clone", doGitClone(dstPath, sshURL)) + + little, big := standardCommitAndPushTest(t, dstPath) + littleLFS, bigLFS := lfsCommitAndPushTest(t, dstPath) + rawTest(t, &sshContext, little, big, littleLFS, bigLFS) + mediaTest(t, &sshContext, little, big, littleLFS, bigLFS) + + t.Run("BranchProtectMerge", doBranchProtectPRMerge(&sshContext, dstPath)) }) }) @@ -295,7 +104,116 @@ func ensureAnonymousClone(t *testing.T, u *url.URL) { } -func lockTest(t *testing.T, remote, repoPath string) { +func standardCommitAndPushTest(t *testing.T, dstPath string) (little, big string) { + t.Run("Standard", func(t *testing.T) { + PrintCurrentTest(t) + little, big = commitAndPushTest(t, dstPath, "data-file-") + }) + return +} + +func lfsCommitAndPushTest(t *testing.T, dstPath string) (littleLFS, bigLFS string) { + t.Run("LFS", func(t *testing.T) { + PrintCurrentTest(t) + prefix := "lfs-data-file-" + _, err := git.NewCommand("lfs").AddArguments("install").RunInDir(dstPath) + assert.NoError(t, err) + _, err = git.NewCommand("lfs").AddArguments("track", prefix+"*").RunInDir(dstPath) + assert.NoError(t, err) + err = git.AddChanges(dstPath, false, ".gitattributes") + assert.NoError(t, err) + + littleLFS, bigLFS = commitAndPushTest(t, dstPath, prefix) + + t.Run("Locks", func(t *testing.T) { + PrintCurrentTest(t) + lockTest(t, dstPath) + }) + }) + return +} + +func commitAndPushTest(t *testing.T, dstPath, prefix string) (little, big string) { + t.Run("PushCommit", func(t *testing.T) { + PrintCurrentTest(t) + t.Run("Little", func(t *testing.T) { + PrintCurrentTest(t) + little = doCommitAndPush(t, littleSize, dstPath, prefix) + }) + t.Run("Big", func(t *testing.T) { + if testing.Short() { + t.Skip("Skipping test in short mode.") + return + } + PrintCurrentTest(t) + big = doCommitAndPush(t, bigSize, dstPath, prefix) + }) + }) + return +} + +func rawTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS string) { + t.Run("Raw", func(t *testing.T) { + PrintCurrentTest(t) + username := ctx.Username + reponame := ctx.Reponame + + session := loginUser(t, username) + + // Request raw paths + req := NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", little)) + resp := session.MakeRequest(t, req, http.StatusOK) + assert.Equal(t, littleSize, resp.Body.Len()) + + req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", littleLFS)) + resp = session.MakeRequest(t, req, http.StatusOK) + assert.NotEqual(t, littleSize, resp.Body.Len()) + assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier) + + if !testing.Short() { + req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", big)) + resp = session.MakeRequest(t, req, http.StatusOK) + assert.Equal(t, bigSize, resp.Body.Len()) + + req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", bigLFS)) + resp = session.MakeRequest(t, req, http.StatusOK) + assert.NotEqual(t, bigSize, resp.Body.Len()) + assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier) + } + }) +} + +func mediaTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS string) { + t.Run("Media", func(t *testing.T) { + PrintCurrentTest(t) + + username := ctx.Username + reponame := ctx.Reponame + + session := loginUser(t, username) + + // Request media paths + req := NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", little)) + resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) + assert.Equal(t, littleSize, resp.Length) + + req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", littleLFS)) + resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) + assert.Equal(t, littleSize, resp.Length) + + if !testing.Short() { + req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", big)) + resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) + assert.Equal(t, bigSize, resp.Length) + + req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", bigLFS)) + resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) + assert.Equal(t, bigSize, resp.Length) + } + }) +} + +func lockTest(t *testing.T, repoPath string) { lockFileTest(t, "README.md", repoPath) } @@ -310,22 +228,22 @@ func lockFileTest(t *testing.T, filename, repoPath string) { assert.NoError(t, err) } -func commitAndPush(t *testing.T, size int, repoPath string) string { - name, err := generateCommitWithNewData(size, repoPath, "user2@example.com", "User Two") +func doCommitAndPush(t *testing.T, size int, repoPath, prefix string) string { + name, err := generateCommitWithNewData(size, repoPath, "user2@example.com", "User Two", prefix) assert.NoError(t, err) - _, err = git.NewCommand("push").RunInDir(repoPath) //Push + _, err = git.NewCommand("push", "origin", "master").RunInDir(repoPath) //Push assert.NoError(t, err) return name } -func generateCommitWithNewData(size int, repoPath, email, fullName string) (string, error) { +func generateCommitWithNewData(size int, repoPath, email, fullName, prefix string) (string, error) { //Generate random file data := make([]byte, size) _, err := rand.Read(data) if err != nil { return "", err } - tmpFile, err := ioutil.TempFile(repoPath, "data-file-") + tmpFile, err := ioutil.TempFile(repoPath, prefix) if err != nil { return "", err } @@ -355,3 +273,71 @@ func generateCommitWithNewData(size int, repoPath, email, fullName string) (stri }) return filepath.Base(tmpFile.Name()), err } + +func doBranchProtectPRMerge(baseCtx *APITestContext, dstPath string) func(t *testing.T) { + return func(t *testing.T) { + PrintCurrentTest(t) + t.Run("CreateBranchProtected", doGitCreateBranch(dstPath, "protected")) + t.Run("PushProtectedBranch", doGitPushTestRepository(dstPath, "origin", "protected")) + + ctx := NewAPITestContext(t, baseCtx.Username, baseCtx.Reponame) + t.Run("ProtectProtectedBranchNoWhitelist", doProtectBranch(ctx, "protected", "")) + t.Run("GenerateCommit", func(t *testing.T) { + _, err := generateCommitWithNewData(littleSize, dstPath, "user2@example.com", "User Two", "branch-data-file-") + assert.NoError(t, err) + }) + t.Run("FailToPushToProtectedBranch", doGitPushTestRepositoryFail(dstPath, "origin", "protected")) + t.Run("PushToUnprotectedBranch", doGitPushTestRepository(dstPath, "origin", "protected:unprotected")) + var pr api.PullRequest + var err error + t.Run("CreatePullRequest", func(t *testing.T) { + pr, err = doAPICreatePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, "protected", "unprotected")(t) + assert.NoError(t, err) + }) + t.Run("MergePR", doAPIMergePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index)) + t.Run("PullProtected", doGitPull(dstPath, "origin", "protected")) + t.Run("ProtectProtectedBranchWhitelist", doProtectBranch(ctx, "protected", baseCtx.Username)) + + t.Run("CheckoutMaster", doGitCheckoutBranch(dstPath, "master")) + t.Run("CreateBranchForced", doGitCreateBranch(dstPath, "toforce")) + t.Run("GenerateCommit", func(t *testing.T) { + _, err := generateCommitWithNewData(littleSize, dstPath, "user2@example.com", "User Two", "branch-data-file-") + assert.NoError(t, err) + }) + t.Run("FailToForcePushToProtectedBranch", doGitPushTestRepositoryFail(dstPath, "-f", "origin", "toforce:protected")) + t.Run("MergeProtectedToToforce", doGitMerge(dstPath, "protected")) + t.Run("PushToProtectedBranch", doGitPushTestRepository(dstPath, "origin", "toforce:protected")) + t.Run("CheckoutMasterAgain", doGitCheckoutBranch(dstPath, "master")) + } +} + +func doProtectBranch(ctx APITestContext, branch string, userToWhitelist string) func(t *testing.T) { + // We are going to just use the owner to set the protection. + return func(t *testing.T) { + csrf := GetCSRF(t, ctx.Session, fmt.Sprintf("/%s/%s/settings/branches", url.PathEscape(ctx.Username), url.PathEscape(ctx.Reponame))) + + if userToWhitelist == "" { + // Change branch to protected + req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/settings/branches/%s", url.PathEscape(ctx.Username), url.PathEscape(ctx.Reponame), url.PathEscape(branch)), map[string]string{ + "_csrf": csrf, + "protected": "on", + }) + ctx.Session.MakeRequest(t, req, http.StatusFound) + } else { + user, err := models.GetUserByName(userToWhitelist) + assert.NoError(t, err) + // Change branch to protected + req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/settings/branches/%s", url.PathEscape(ctx.Username), url.PathEscape(ctx.Reponame), url.PathEscape(branch)), map[string]string{ + "_csrf": csrf, + "protected": "on", + "enable_whitelist": "on", + "whitelist_users": strconv.FormatInt(user.ID, 10), + }) + ctx.Session.MakeRequest(t, req, http.StatusFound) + } + // Check if master branch has been locked successfully + flashCookie := ctx.Session.GetCookie("macaron_flash") + assert.NotNil(t, flashCookie) + assert.EqualValues(t, "success%3DBranch%2Bprotection%2Bfor%2Bbranch%2B%2527"+url.QueryEscape(branch)+"%2527%2Bhas%2Bbeen%2Bupdated.", flashCookie.Value) + } +}