gitea源码

api_repo_file_delete_test.go 6.8KB

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