code.gitea.io/gitea@v1.21.7/tests/integration/api_branch_test.go (about)

     1  // Copyright 2017 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package integration
     5  
     6  import (
     7  	"net/http"
     8  	"net/url"
     9  	"testing"
    10  
    11  	auth_model "code.gitea.io/gitea/models/auth"
    12  	"code.gitea.io/gitea/models/db"
    13  	git_model "code.gitea.io/gitea/models/git"
    14  	api "code.gitea.io/gitea/modules/structs"
    15  	"code.gitea.io/gitea/tests"
    16  
    17  	"github.com/stretchr/testify/assert"
    18  )
    19  
    20  func testAPIGetBranch(t *testing.T, branchName string, exists bool) {
    21  	token := getUserToken(t, "user2", auth_model.AccessTokenScopeReadRepository)
    22  	req := NewRequestf(t, "GET", "/api/v1/repos/user2/repo1/branches/%s?token=%s", branchName, token)
    23  	resp := MakeRequest(t, req, NoExpectedStatus)
    24  	if !exists {
    25  		assert.EqualValues(t, http.StatusNotFound, resp.Code)
    26  		return
    27  	}
    28  	assert.EqualValues(t, http.StatusOK, resp.Code)
    29  	var branch api.Branch
    30  	DecodeJSON(t, resp, &branch)
    31  	assert.EqualValues(t, branchName, branch.Name)
    32  	assert.True(t, branch.UserCanPush)
    33  	assert.True(t, branch.UserCanMerge)
    34  }
    35  
    36  func testAPIGetBranchProtection(t *testing.T, branchName string, expectedHTTPStatus int) *api.BranchProtection {
    37  	token := getUserToken(t, "user2", auth_model.AccessTokenScopeReadRepository)
    38  	req := NewRequestf(t, "GET", "/api/v1/repos/user2/repo1/branch_protections/%s?token=%s", branchName, token)
    39  	resp := MakeRequest(t, req, expectedHTTPStatus)
    40  
    41  	if resp.Code == http.StatusOK {
    42  		var branchProtection api.BranchProtection
    43  		DecodeJSON(t, resp, &branchProtection)
    44  		assert.EqualValues(t, branchName, branchProtection.RuleName)
    45  		return &branchProtection
    46  	}
    47  	return nil
    48  }
    49  
    50  func testAPICreateBranchProtection(t *testing.T, branchName string, expectedHTTPStatus int) {
    51  	token := getUserToken(t, "user2", auth_model.AccessTokenScopeWriteRepository)
    52  	req := NewRequestWithJSON(t, "POST", "/api/v1/repos/user2/repo1/branch_protections?token="+token, &api.BranchProtection{
    53  		RuleName: branchName,
    54  	})
    55  	resp := MakeRequest(t, req, expectedHTTPStatus)
    56  
    57  	if resp.Code == http.StatusCreated {
    58  		var branchProtection api.BranchProtection
    59  		DecodeJSON(t, resp, &branchProtection)
    60  		assert.EqualValues(t, branchName, branchProtection.RuleName)
    61  	}
    62  }
    63  
    64  func testAPIEditBranchProtection(t *testing.T, branchName string, body *api.BranchProtection, expectedHTTPStatus int) {
    65  	token := getUserToken(t, "user2", auth_model.AccessTokenScopeWriteRepository)
    66  	req := NewRequestWithJSON(t, "PATCH", "/api/v1/repos/user2/repo1/branch_protections/"+branchName+"?token="+token, body)
    67  	resp := MakeRequest(t, req, expectedHTTPStatus)
    68  
    69  	if resp.Code == http.StatusOK {
    70  		var branchProtection api.BranchProtection
    71  		DecodeJSON(t, resp, &branchProtection)
    72  		assert.EqualValues(t, branchName, branchProtection.RuleName)
    73  	}
    74  }
    75  
    76  func testAPIDeleteBranchProtection(t *testing.T, branchName string, expectedHTTPStatus int) {
    77  	token := getUserToken(t, "user2", auth_model.AccessTokenScopeWriteRepository)
    78  	req := NewRequestf(t, "DELETE", "/api/v1/repos/user2/repo1/branch_protections/%s?token=%s", branchName, token)
    79  	MakeRequest(t, req, expectedHTTPStatus)
    80  }
    81  
    82  func testAPIDeleteBranch(t *testing.T, branchName string, expectedHTTPStatus int) {
    83  	token := getUserToken(t, "user2", auth_model.AccessTokenScopeWriteRepository)
    84  	req := NewRequestf(t, "DELETE", "/api/v1/repos/user2/repo1/branches/%s?token=%s", branchName, token)
    85  	MakeRequest(t, req, expectedHTTPStatus)
    86  }
    87  
    88  func TestAPIGetBranch(t *testing.T) {
    89  	defer tests.PrepareTestEnv(t)()
    90  	for _, test := range []struct {
    91  		BranchName string
    92  		Exists     bool
    93  	}{
    94  		{"master", true},
    95  		{"master/doesnotexist", false},
    96  		{"feature/1", true},
    97  		{"feature/1/doesnotexist", false},
    98  	} {
    99  		testAPIGetBranch(t, test.BranchName, test.Exists)
   100  	}
   101  }
   102  
   103  func TestAPICreateBranch(t *testing.T) {
   104  	onGiteaRun(t, testAPICreateBranches)
   105  }
   106  
   107  func testAPICreateBranches(t *testing.T, giteaURL *url.URL) {
   108  	username := "user2"
   109  	ctx := NewAPITestContext(t, username, "my-noo-repo", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
   110  	giteaURL.Path = ctx.GitPath()
   111  
   112  	t.Run("CreateRepo", doAPICreateRepository(ctx, false))
   113  	testCases := []struct {
   114  		OldBranch          string
   115  		NewBranch          string
   116  		ExpectedHTTPStatus int
   117  	}{
   118  		// Creating branch from default branch
   119  		{
   120  			OldBranch:          "",
   121  			NewBranch:          "new_branch_from_default_branch",
   122  			ExpectedHTTPStatus: http.StatusCreated,
   123  		},
   124  		// Creating branch from master
   125  		{
   126  			OldBranch:          "master",
   127  			NewBranch:          "new_branch_from_master_1",
   128  			ExpectedHTTPStatus: http.StatusCreated,
   129  		},
   130  		// Trying to create from master but already exists
   131  		{
   132  			OldBranch:          "master",
   133  			NewBranch:          "new_branch_from_master_1",
   134  			ExpectedHTTPStatus: http.StatusConflict,
   135  		},
   136  		// Trying to create from other branch (not default branch)
   137  		{
   138  			OldBranch:          "new_branch_from_master_1",
   139  			NewBranch:          "branch_2",
   140  			ExpectedHTTPStatus: http.StatusCreated,
   141  		},
   142  		// Trying to create from a branch which does not exist
   143  		{
   144  			OldBranch:          "does_not_exist",
   145  			NewBranch:          "new_branch_from_non_existent",
   146  			ExpectedHTTPStatus: http.StatusNotFound,
   147  		},
   148  	}
   149  	for _, test := range testCases {
   150  		session := ctx.Session
   151  		testAPICreateBranch(t, session, "user2", "my-noo-repo", test.OldBranch, test.NewBranch, test.ExpectedHTTPStatus)
   152  	}
   153  }
   154  
   155  func testAPICreateBranch(t testing.TB, session *TestSession, user, repo, oldBranch, newBranch string, status int) bool {
   156  	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
   157  	req := NewRequestWithJSON(t, "POST", "/api/v1/repos/"+user+"/"+repo+"/branches?token="+token, &api.CreateBranchRepoOption{
   158  		BranchName:    newBranch,
   159  		OldBranchName: oldBranch,
   160  	})
   161  	resp := MakeRequest(t, req, status)
   162  
   163  	var branch api.Branch
   164  	DecodeJSON(t, resp, &branch)
   165  
   166  	if status == http.StatusCreated {
   167  		assert.EqualValues(t, newBranch, branch.Name)
   168  	}
   169  
   170  	return resp.Result().StatusCode == status
   171  }
   172  
   173  func TestAPIBranchProtection(t *testing.T) {
   174  	defer tests.PrepareTestEnv(t)()
   175  
   176  	// Branch protection  on branch that not exist
   177  	testAPICreateBranchProtection(t, "master/doesnotexist", http.StatusCreated)
   178  	// Get branch protection on branch that exist but not branch protection
   179  	testAPIGetBranchProtection(t, "master", http.StatusNotFound)
   180  
   181  	testAPICreateBranchProtection(t, "master", http.StatusCreated)
   182  	// Can only create once
   183  	testAPICreateBranchProtection(t, "master", http.StatusForbidden)
   184  
   185  	// Can't delete a protected branch
   186  	testAPIDeleteBranch(t, "master", http.StatusForbidden)
   187  
   188  	testAPIGetBranchProtection(t, "master", http.StatusOK)
   189  	testAPIEditBranchProtection(t, "master", &api.BranchProtection{
   190  		EnablePush: true,
   191  	}, http.StatusOK)
   192  
   193  	// enable status checks, require the "test1" check to pass
   194  	testAPIEditBranchProtection(t, "master", &api.BranchProtection{
   195  		EnableStatusCheck:   true,
   196  		StatusCheckContexts: []string{"test1"},
   197  	}, http.StatusOK)
   198  	bp := testAPIGetBranchProtection(t, "master", http.StatusOK)
   199  	assert.Equal(t, true, bp.EnableStatusCheck)
   200  	assert.Equal(t, []string{"test1"}, bp.StatusCheckContexts)
   201  
   202  	// disable status checks, clear the list of required checks
   203  	testAPIEditBranchProtection(t, "master", &api.BranchProtection{
   204  		EnableStatusCheck:   false,
   205  		StatusCheckContexts: []string{},
   206  	}, http.StatusOK)
   207  	bp = testAPIGetBranchProtection(t, "master", http.StatusOK)
   208  	assert.Equal(t, false, bp.EnableStatusCheck)
   209  	assert.Equal(t, []string{}, bp.StatusCheckContexts)
   210  
   211  	testAPIDeleteBranchProtection(t, "master", http.StatusNoContent)
   212  
   213  	// Test branch deletion
   214  	testAPIDeleteBranch(t, "master", http.StatusForbidden)
   215  	testAPIDeleteBranch(t, "branch2", http.StatusNoContent)
   216  }
   217  
   218  func TestAPICreateBranchWithSyncBranches(t *testing.T) {
   219  	defer tests.PrepareTestEnv(t)()
   220  
   221  	branches, err := git_model.FindBranches(db.DefaultContext, git_model.FindBranchOptions{
   222  		RepoID: 1,
   223  	})
   224  	assert.NoError(t, err)
   225  	assert.Len(t, branches, 4)
   226  
   227  	// make a broke repository with no branch on database
   228  	_, err = db.DeleteByBean(db.DefaultContext, git_model.Branch{RepoID: 1})
   229  	assert.NoError(t, err)
   230  
   231  	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
   232  		ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
   233  		giteaURL.Path = ctx.GitPath()
   234  
   235  		testAPICreateBranch(t, ctx.Session, "user2", "repo1", "", "new_branch", http.StatusCreated)
   236  	})
   237  
   238  	branches, err = git_model.FindBranches(db.DefaultContext, git_model.FindBranchOptions{
   239  		RepoID: 1,
   240  	})
   241  	assert.NoError(t, err)
   242  	assert.Len(t, branches, 5)
   243  
   244  	branches, err = git_model.FindBranches(db.DefaultContext, git_model.FindBranchOptions{
   245  		RepoID:  1,
   246  		Keyword: "new_branch",
   247  	})
   248  	assert.NoError(t, err)
   249  	assert.Len(t, branches, 1)
   250  }