You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

232 lines
6.9 KiB

  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package integrations
  5. import (
  6. "encoding/json"
  7. "fmt"
  8. "io/ioutil"
  9. "net/http"
  10. "testing"
  11. "code.gitea.io/gitea/models"
  12. "code.gitea.io/gitea/modules/auth"
  13. api "code.gitea.io/gitea/modules/structs"
  14. "github.com/stretchr/testify/assert"
  15. )
  16. type APITestContext struct {
  17. Reponame string
  18. Session *TestSession
  19. Token string
  20. Username string
  21. ExpectedCode int
  22. }
  23. func NewAPITestContext(t *testing.T, username, reponame string) APITestContext {
  24. session := loginUser(t, username)
  25. token := getTokenForLoggedInUser(t, session)
  26. return APITestContext{
  27. Session: session,
  28. Token: token,
  29. Username: username,
  30. Reponame: reponame,
  31. }
  32. }
  33. func (ctx APITestContext) GitPath() string {
  34. return fmt.Sprintf("%s/%s.git", ctx.Username, ctx.Reponame)
  35. }
  36. func doAPICreateRepository(ctx APITestContext, empty bool, callback ...func(*testing.T, api.Repository)) func(*testing.T) {
  37. return func(t *testing.T) {
  38. createRepoOption := &api.CreateRepoOption{
  39. AutoInit: !empty,
  40. Description: "Temporary repo",
  41. Name: ctx.Reponame,
  42. Private: true,
  43. Gitignores: "",
  44. License: "WTFPL",
  45. Readme: "Default",
  46. }
  47. req := NewRequestWithJSON(t, "POST", "/api/v1/user/repos?token="+ctx.Token, createRepoOption)
  48. if ctx.ExpectedCode != 0 {
  49. ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)
  50. return
  51. }
  52. resp := ctx.Session.MakeRequest(t, req, http.StatusCreated)
  53. var repository api.Repository
  54. DecodeJSON(t, resp, &repository)
  55. if len(callback) > 0 {
  56. callback[0](t, repository)
  57. }
  58. }
  59. }
  60. func doAPIAddCollaborator(ctx APITestContext, username string, mode models.AccessMode) func(*testing.T) {
  61. return func(t *testing.T) {
  62. permission := "read"
  63. if mode == models.AccessModeAdmin {
  64. permission = "admin"
  65. } else if mode > models.AccessModeRead {
  66. permission = "write"
  67. }
  68. addCollaboratorOption := &api.AddCollaboratorOption{
  69. Permission: &permission,
  70. }
  71. req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/collaborators/%s?token=%s", ctx.Username, ctx.Reponame, username, ctx.Token), addCollaboratorOption)
  72. if ctx.ExpectedCode != 0 {
  73. ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)
  74. return
  75. }
  76. ctx.Session.MakeRequest(t, req, http.StatusNoContent)
  77. }
  78. }
  79. func doAPIForkRepository(ctx APITestContext, username string, callback ...func(*testing.T, api.Repository)) func(*testing.T) {
  80. return func(t *testing.T) {
  81. createForkOption := &api.CreateForkOption{}
  82. req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/forks?token=%s", username, ctx.Reponame, ctx.Token), createForkOption)
  83. if ctx.ExpectedCode != 0 {
  84. ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)
  85. return
  86. }
  87. resp := ctx.Session.MakeRequest(t, req, http.StatusAccepted)
  88. var repository api.Repository
  89. DecodeJSON(t, resp, &repository)
  90. if len(callback) > 0 {
  91. callback[0](t, repository)
  92. }
  93. }
  94. }
  95. func doAPIGetRepository(ctx APITestContext, callback ...func(*testing.T, api.Repository)) func(*testing.T) {
  96. return func(t *testing.T) {
  97. urlStr := fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", ctx.Username, ctx.Reponame, ctx.Token)
  98. req := NewRequest(t, "GET", urlStr)
  99. if ctx.ExpectedCode != 0 {
  100. ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)
  101. return
  102. }
  103. resp := ctx.Session.MakeRequest(t, req, http.StatusOK)
  104. var repository api.Repository
  105. DecodeJSON(t, resp, &repository)
  106. if len(callback) > 0 {
  107. callback[0](t, repository)
  108. }
  109. }
  110. }
  111. func doAPIDeleteRepository(ctx APITestContext) func(*testing.T) {
  112. return func(t *testing.T) {
  113. urlStr := fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", ctx.Username, ctx.Reponame, ctx.Token)
  114. req := NewRequest(t, "DELETE", urlStr)
  115. if ctx.ExpectedCode != 0 {
  116. ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)
  117. return
  118. }
  119. ctx.Session.MakeRequest(t, req, http.StatusNoContent)
  120. }
  121. }
  122. func doAPICreateUserKey(ctx APITestContext, keyname, keyFile string, callback ...func(*testing.T, api.PublicKey)) func(*testing.T) {
  123. return func(t *testing.T) {
  124. urlStr := fmt.Sprintf("/api/v1/user/keys?token=%s", ctx.Token)
  125. dataPubKey, err := ioutil.ReadFile(keyFile + ".pub")
  126. assert.NoError(t, err)
  127. req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateKeyOption{
  128. Title: keyname,
  129. Key: string(dataPubKey),
  130. })
  131. if ctx.ExpectedCode != 0 {
  132. ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)
  133. return
  134. }
  135. resp := ctx.Session.MakeRequest(t, req, http.StatusCreated)
  136. var publicKey api.PublicKey
  137. DecodeJSON(t, resp, &publicKey)
  138. if len(callback) > 0 {
  139. callback[0](t, publicKey)
  140. }
  141. }
  142. }
  143. func doAPIDeleteUserKey(ctx APITestContext, keyID int64) func(*testing.T) {
  144. return func(t *testing.T) {
  145. urlStr := fmt.Sprintf("/api/v1/user/keys/%d?token=%s", keyID, ctx.Token)
  146. req := NewRequest(t, "DELETE", urlStr)
  147. if ctx.ExpectedCode != 0 {
  148. ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)
  149. return
  150. }
  151. ctx.Session.MakeRequest(t, req, http.StatusNoContent)
  152. }
  153. }
  154. func doAPICreateDeployKey(ctx APITestContext, keyname, keyFile string, readOnly bool) func(*testing.T) {
  155. return func(t *testing.T) {
  156. urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/keys?token=%s", ctx.Username, ctx.Reponame, ctx.Token)
  157. dataPubKey, err := ioutil.ReadFile(keyFile + ".pub")
  158. assert.NoError(t, err)
  159. req := NewRequestWithJSON(t, "POST", urlStr, api.CreateKeyOption{
  160. Title: keyname,
  161. Key: string(dataPubKey),
  162. ReadOnly: readOnly,
  163. })
  164. if ctx.ExpectedCode != 0 {
  165. ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)
  166. return
  167. }
  168. ctx.Session.MakeRequest(t, req, http.StatusCreated)
  169. }
  170. }
  171. func doAPICreatePullRequest(ctx APITestContext, owner, repo, baseBranch, headBranch string) func(*testing.T) (api.PullRequest, error) {
  172. return func(t *testing.T) (api.PullRequest, error) {
  173. urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls?token=%s",
  174. owner, repo, ctx.Token)
  175. req := NewRequestWithJSON(t, http.MethodPost, urlStr, &api.CreatePullRequestOption{
  176. Head: headBranch,
  177. Base: baseBranch,
  178. Title: fmt.Sprintf("create a pr from %s to %s", headBranch, baseBranch),
  179. })
  180. expected := 201
  181. if ctx.ExpectedCode != 0 {
  182. expected = ctx.ExpectedCode
  183. }
  184. resp := ctx.Session.MakeRequest(t, req, expected)
  185. decoder := json.NewDecoder(resp.Body)
  186. pr := api.PullRequest{}
  187. err := decoder.Decode(&pr)
  188. return pr, err
  189. }
  190. }
  191. func doAPIMergePullRequest(ctx APITestContext, owner, repo string, index int64) func(*testing.T) {
  192. return func(t *testing.T) {
  193. urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge?token=%s",
  194. owner, repo, index, ctx.Token)
  195. req := NewRequestWithJSON(t, http.MethodPost, urlStr, &auth.MergePullRequestForm{
  196. MergeMessageField: "doAPIMergePullRequest Merge",
  197. Do: string(models.MergeStyleMerge),
  198. })
  199. if ctx.ExpectedCode != 0 {
  200. ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)
  201. return
  202. }
  203. ctx.Session.MakeRequest(t, req, 200)
  204. }
  205. }