code.gitea.io/gitea@v1.22.3/tests/integration/api_repo_file_delete_test.go (about)

     1  // Copyright 2019 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package integration
     5  
     6  import (
     7  	"fmt"
     8  	"net/http"
     9  	"net/url"
    10  	"testing"
    11  
    12  	auth_model "code.gitea.io/gitea/models/auth"
    13  	repo_model "code.gitea.io/gitea/models/repo"
    14  	"code.gitea.io/gitea/models/unittest"
    15  	user_model "code.gitea.io/gitea/models/user"
    16  	api "code.gitea.io/gitea/modules/structs"
    17  
    18  	"github.com/stretchr/testify/assert"
    19  )
    20  
    21  func getDeleteFileOptions() *api.DeleteFileOptions {
    22  	return &api.DeleteFileOptions{
    23  		FileOptions: api.FileOptions{
    24  			BranchName:    "master",
    25  			NewBranchName: "master",
    26  			Message:       "Removing the file new/file.txt",
    27  			Author: api.Identity{
    28  				Name:  "John Doe",
    29  				Email: "johndoe@example.com",
    30  			},
    31  			Committer: api.Identity{
    32  				Name:  "Jane Doe",
    33  				Email: "janedoe@example.com",
    34  			},
    35  		},
    36  		SHA: "103ff9234cefeee5ec5361d22b49fbb04d385885",
    37  	}
    38  }
    39  
    40  func TestAPIDeleteFile(t *testing.T) {
    41  	onGiteaRun(t, func(t *testing.T, u *url.URL) {
    42  		user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})         // owner of the repo1 & repo16
    43  		org3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})          // owner of the repo3, is an org
    44  		user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})         // owner of neither repos
    45  		repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})   // public repo
    46  		repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})   // public repo
    47  		repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo
    48  		fileID := 0
    49  
    50  		// Get user2's token
    51  		session := loginUser(t, user2.Name)
    52  		token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
    53  		// Get user4's token
    54  		session = loginUser(t, user4.Name)
    55  		token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
    56  
    57  		// Test deleting a file in repo1 which user2 owns, try both with branch and empty branch
    58  		for _, branch := range [...]string{
    59  			"master", // Branch
    60  			"",       // Empty branch
    61  		} {
    62  			fileID++
    63  			treePath := fmt.Sprintf("delete/file%d.txt", fileID)
    64  			createFile(user2, repo1, treePath)
    65  			deleteFileOptions := getDeleteFileOptions()
    66  			deleteFileOptions.BranchName = branch
    67  			req := NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &deleteFileOptions).
    68  				AddTokenAuth(token2)
    69  			resp := MakeRequest(t, req, http.StatusOK)
    70  			var fileResponse api.FileResponse
    71  			DecodeJSON(t, resp, &fileResponse)
    72  			assert.NotNil(t, fileResponse)
    73  			assert.Nil(t, fileResponse.Content)
    74  		}
    75  
    76  		// Test deleting file and making the delete in a new branch
    77  		fileID++
    78  		treePath := fmt.Sprintf("delete/file%d.txt", fileID)
    79  		createFile(user2, repo1, treePath)
    80  		deleteFileOptions := getDeleteFileOptions()
    81  		deleteFileOptions.BranchName = repo1.DefaultBranch
    82  		deleteFileOptions.NewBranchName = "new_branch"
    83  		req := NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &deleteFileOptions).
    84  			AddTokenAuth(token2)
    85  		resp := MakeRequest(t, req, http.StatusOK)
    86  		var fileResponse api.FileResponse
    87  		DecodeJSON(t, resp, &fileResponse)
    88  		assert.NotNil(t, fileResponse)
    89  		assert.Nil(t, fileResponse.Content)
    90  		assert.EqualValues(t, deleteFileOptions.Message+"\n", fileResponse.Commit.Message)
    91  
    92  		// Test deleting file without a message
    93  		fileID++
    94  		treePath = fmt.Sprintf("delete/file%d.txt", fileID)
    95  		createFile(user2, repo1, treePath)
    96  		deleteFileOptions = getDeleteFileOptions()
    97  		deleteFileOptions.Message = ""
    98  		req = NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &deleteFileOptions).
    99  			AddTokenAuth(token2)
   100  		resp = MakeRequest(t, req, http.StatusOK)
   101  		DecodeJSON(t, resp, &fileResponse)
   102  		expectedMessage := "Delete " + treePath + "\n"
   103  		assert.EqualValues(t, expectedMessage, fileResponse.Commit.Message)
   104  
   105  		// Test deleting a file with the wrong SHA
   106  		fileID++
   107  		treePath = fmt.Sprintf("delete/file%d.txt", fileID)
   108  		createFile(user2, repo1, treePath)
   109  		deleteFileOptions = getDeleteFileOptions()
   110  		deleteFileOptions.SHA = "badsha"
   111  		req = NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &deleteFileOptions).
   112  			AddTokenAuth(token2)
   113  		MakeRequest(t, req, http.StatusBadRequest)
   114  
   115  		// Test creating a file in repo16 by user4 who does not have write access
   116  		fileID++
   117  		treePath = fmt.Sprintf("delete/file%d.txt", fileID)
   118  		createFile(user2, repo16, treePath)
   119  		deleteFileOptions = getDeleteFileOptions()
   120  		req = NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath), &deleteFileOptions).
   121  			AddTokenAuth(token4)
   122  		MakeRequest(t, req, http.StatusNotFound)
   123  
   124  		// Tests a repo with no token given so will fail
   125  		fileID++
   126  		treePath = fmt.Sprintf("delete/file%d.txt", fileID)
   127  		createFile(user2, repo16, treePath)
   128  		deleteFileOptions = getDeleteFileOptions()
   129  		req = NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath), &deleteFileOptions)
   130  		MakeRequest(t, req, http.StatusNotFound)
   131  
   132  		// Test using access token for a private repo that the user of the token owns
   133  		fileID++
   134  		treePath = fmt.Sprintf("delete/file%d.txt", fileID)
   135  		createFile(user2, repo16, treePath)
   136  		deleteFileOptions = getDeleteFileOptions()
   137  		req = NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath), &deleteFileOptions).
   138  			AddTokenAuth(token2)
   139  		MakeRequest(t, req, http.StatusOK)
   140  
   141  		// Test using org repo "org3/repo3" where user2 is a collaborator
   142  		fileID++
   143  		treePath = fmt.Sprintf("delete/file%d.txt", fileID)
   144  		createFile(org3, repo3, treePath)
   145  		deleteFileOptions = getDeleteFileOptions()
   146  		req = NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", org3.Name, repo3.Name, treePath), &deleteFileOptions).
   147  			AddTokenAuth(token2)
   148  		MakeRequest(t, req, http.StatusOK)
   149  
   150  		// Test using org repo "org3/repo3" with no user token
   151  		fileID++
   152  		treePath = fmt.Sprintf("delete/file%d.txt", fileID)
   153  		createFile(org3, repo3, treePath)
   154  		deleteFileOptions = getDeleteFileOptions()
   155  		req = NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", org3.Name, repo3.Name, treePath), &deleteFileOptions)
   156  		MakeRequest(t, req, http.StatusNotFound)
   157  
   158  		// Test using repo "user2/repo1" where user4 is a NOT collaborator
   159  		fileID++
   160  		treePath = fmt.Sprintf("delete/file%d.txt", fileID)
   161  		createFile(user2, repo1, treePath)
   162  		deleteFileOptions = getDeleteFileOptions()
   163  		req = NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &deleteFileOptions).
   164  			AddTokenAuth(token4)
   165  		MakeRequest(t, req, http.StatusForbidden)
   166  	})
   167  }