code.gitea.io/gitea@v1.21.7/tests/integration/api_releases_test.go (about) 1 // Copyright 2018 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package integration 5 6 import ( 7 "bytes" 8 "fmt" 9 "io" 10 "mime/multipart" 11 "net/http" 12 "net/url" 13 "strings" 14 "testing" 15 16 auth_model "code.gitea.io/gitea/models/auth" 17 repo_model "code.gitea.io/gitea/models/repo" 18 "code.gitea.io/gitea/models/unittest" 19 user_model "code.gitea.io/gitea/models/user" 20 "code.gitea.io/gitea/modules/git" 21 api "code.gitea.io/gitea/modules/structs" 22 "code.gitea.io/gitea/tests" 23 24 "github.com/stretchr/testify/assert" 25 ) 26 27 func TestAPIListReleases(t *testing.T) { 28 defer tests.PrepareTestEnv(t)() 29 30 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 31 user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) 32 token := getUserToken(t, user2.LowerName, auth_model.AccessTokenScopeReadRepository) 33 34 link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/releases", user2.Name, repo.Name)) 35 link.RawQuery = url.Values{"token": {token}}.Encode() 36 resp := MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK) 37 var apiReleases []*api.Release 38 DecodeJSON(t, resp, &apiReleases) 39 if assert.Len(t, apiReleases, 3) { 40 for _, release := range apiReleases { 41 switch release.ID { 42 case 1: 43 assert.False(t, release.IsDraft) 44 assert.False(t, release.IsPrerelease) 45 assert.True(t, strings.HasSuffix(release.UploadURL, "/api/v1/repos/user2/repo1/releases/1/assets"), release.UploadURL) 46 case 4: 47 assert.True(t, release.IsDraft) 48 assert.False(t, release.IsPrerelease) 49 assert.True(t, strings.HasSuffix(release.UploadURL, "/api/v1/repos/user2/repo1/releases/4/assets"), release.UploadURL) 50 case 5: 51 assert.False(t, release.IsDraft) 52 assert.True(t, release.IsPrerelease) 53 assert.True(t, strings.HasSuffix(release.UploadURL, "/api/v1/repos/user2/repo1/releases/5/assets"), release.UploadURL) 54 default: 55 assert.NoError(t, fmt.Errorf("unexpected release: %v", release)) 56 } 57 } 58 } 59 60 // test filter 61 testFilterByLen := func(auth bool, query url.Values, expectedLength int, msgAndArgs ...string) { 62 if auth { 63 query.Set("token", token) 64 } 65 link.RawQuery = query.Encode() 66 resp = MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK) 67 DecodeJSON(t, resp, &apiReleases) 68 assert.Len(t, apiReleases, expectedLength, msgAndArgs) 69 } 70 71 testFilterByLen(false, url.Values{"draft": {"true"}}, 0, "anon should not see drafts") 72 testFilterByLen(true, url.Values{"draft": {"true"}}, 1, "repo owner should see drafts") 73 testFilterByLen(true, url.Values{"draft": {"false"}}, 2, "exclude drafts") 74 testFilterByLen(true, url.Values{"draft": {"false"}, "pre-release": {"false"}}, 1, "exclude drafts and pre-releases") 75 testFilterByLen(true, url.Values{"pre-release": {"true"}}, 1, "only get pre-release") 76 testFilterByLen(true, url.Values{"draft": {"true"}, "pre-release": {"true"}}, 0, "there is no pre-release draft") 77 } 78 79 func createNewReleaseUsingAPI(t *testing.T, session *TestSession, token string, owner *user_model.User, repo *repo_model.Repository, name, target, title, desc string) *api.Release { 80 urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/releases?token=%s", 81 owner.Name, repo.Name, token) 82 req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateReleaseOption{ 83 TagName: name, 84 Title: title, 85 Note: desc, 86 IsDraft: false, 87 IsPrerelease: false, 88 Target: target, 89 }) 90 resp := MakeRequest(t, req, http.StatusCreated) 91 92 var newRelease api.Release 93 DecodeJSON(t, resp, &newRelease) 94 rel := &repo_model.Release{ 95 ID: newRelease.ID, 96 TagName: newRelease.TagName, 97 Title: newRelease.Title, 98 } 99 unittest.AssertExistsAndLoadBean(t, rel) 100 assert.EqualValues(t, newRelease.Note, rel.Note) 101 102 return &newRelease 103 } 104 105 func TestAPICreateAndUpdateRelease(t *testing.T) { 106 defer tests.PrepareTestEnv(t)() 107 108 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 109 owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 110 session := loginUser(t, owner.LowerName) 111 token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 112 113 gitRepo, err := git.OpenRepository(git.DefaultContext, repo.RepoPath()) 114 assert.NoError(t, err) 115 defer gitRepo.Close() 116 117 err = gitRepo.CreateTag("v0.0.1", "master") 118 assert.NoError(t, err) 119 120 target, err := gitRepo.GetTagCommitID("v0.0.1") 121 assert.NoError(t, err) 122 123 newRelease := createNewReleaseUsingAPI(t, session, token, owner, repo, "v0.0.1", target, "v0.0.1", "test") 124 125 urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/releases/%d?token=%s", 126 owner.Name, repo.Name, newRelease.ID, token) 127 req := NewRequest(t, "GET", urlStr) 128 resp := MakeRequest(t, req, http.StatusOK) 129 130 var release api.Release 131 DecodeJSON(t, resp, &release) 132 133 assert.Equal(t, newRelease.TagName, release.TagName) 134 assert.Equal(t, newRelease.Title, release.Title) 135 assert.Equal(t, newRelease.Note, release.Note) 136 137 req = NewRequestWithJSON(t, "PATCH", urlStr, &api.EditReleaseOption{ 138 TagName: release.TagName, 139 Title: release.Title, 140 Note: "updated", 141 IsDraft: &release.IsDraft, 142 IsPrerelease: &release.IsPrerelease, 143 Target: release.Target, 144 }) 145 resp = MakeRequest(t, req, http.StatusOK) 146 147 DecodeJSON(t, resp, &newRelease) 148 rel := &repo_model.Release{ 149 ID: newRelease.ID, 150 TagName: newRelease.TagName, 151 Title: newRelease.Title, 152 } 153 unittest.AssertExistsAndLoadBean(t, rel) 154 assert.EqualValues(t, rel.Note, newRelease.Note) 155 } 156 157 func TestAPICreateReleaseToDefaultBranch(t *testing.T) { 158 defer tests.PrepareTestEnv(t)() 159 160 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 161 owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 162 session := loginUser(t, owner.LowerName) 163 token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 164 165 createNewReleaseUsingAPI(t, session, token, owner, repo, "v0.0.1", "", "v0.0.1", "test") 166 } 167 168 func TestAPICreateReleaseToDefaultBranchOnExistingTag(t *testing.T) { 169 defer tests.PrepareTestEnv(t)() 170 171 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 172 owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 173 session := loginUser(t, owner.LowerName) 174 token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 175 176 gitRepo, err := git.OpenRepository(git.DefaultContext, repo.RepoPath()) 177 assert.NoError(t, err) 178 defer gitRepo.Close() 179 180 err = gitRepo.CreateTag("v0.0.1", "master") 181 assert.NoError(t, err) 182 183 createNewReleaseUsingAPI(t, session, token, owner, repo, "v0.0.1", "", "v0.0.1", "test") 184 } 185 186 func TestAPIGetLatestRelease(t *testing.T) { 187 defer tests.PrepareTestEnv(t)() 188 189 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 190 owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 191 192 urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/releases/latest", 193 owner.Name, repo.Name) 194 195 req := NewRequestf(t, "GET", urlStr) 196 resp := MakeRequest(t, req, http.StatusOK) 197 198 var release *api.Release 199 DecodeJSON(t, resp, &release) 200 201 assert.Equal(t, "testing-release", release.Title) 202 } 203 204 func TestAPIGetReleaseByTag(t *testing.T) { 205 defer tests.PrepareTestEnv(t)() 206 207 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 208 owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 209 210 tag := "v1.1" 211 212 urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", 213 owner.Name, repo.Name, tag) 214 215 req := NewRequestf(t, "GET", urlStr) 216 resp := MakeRequest(t, req, http.StatusOK) 217 218 var release *api.Release 219 DecodeJSON(t, resp, &release) 220 221 assert.Equal(t, "testing-release", release.Title) 222 223 nonexistingtag := "nonexistingtag" 224 225 urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", 226 owner.Name, repo.Name, nonexistingtag) 227 228 req = NewRequestf(t, "GET", urlStr) 229 resp = MakeRequest(t, req, http.StatusNotFound) 230 231 var err *api.APIError 232 DecodeJSON(t, resp, &err) 233 assert.NotEmpty(t, err.Message) 234 } 235 236 func TestAPIDeleteReleaseByTagName(t *testing.T) { 237 defer tests.PrepareTestEnv(t)() 238 239 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 240 owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 241 session := loginUser(t, owner.LowerName) 242 token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 243 244 createNewReleaseUsingAPI(t, session, token, owner, repo, "release-tag", "", "Release Tag", "test") 245 246 // delete release 247 req := NewRequestf(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/release-tag?token=%s", owner.Name, repo.Name, token)) 248 _ = MakeRequest(t, req, http.StatusNoContent) 249 250 // make sure release is deleted 251 req = NewRequestf(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/release-tag?token=%s", owner.Name, repo.Name, token)) 252 _ = MakeRequest(t, req, http.StatusNotFound) 253 254 // delete release tag too 255 req = NewRequestf(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/tags/release-tag?token=%s", owner.Name, repo.Name, token)) 256 _ = MakeRequest(t, req, http.StatusNoContent) 257 } 258 259 func TestAPIUploadAssetRelease(t *testing.T) { 260 defer tests.PrepareTestEnv(t)() 261 262 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 263 owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 264 session := loginUser(t, owner.LowerName) 265 token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 266 267 r := createNewReleaseUsingAPI(t, session, token, owner, repo, "release-tag", "", "Release Tag", "test") 268 269 filename := "image.png" 270 buff := generateImg() 271 body := &bytes.Buffer{} 272 273 writer := multipart.NewWriter(body) 274 part, err := writer.CreateFormFile("attachment", filename) 275 assert.NoError(t, err) 276 _, err = io.Copy(part, &buff) 277 assert.NoError(t, err) 278 err = writer.Close() 279 assert.NoError(t, err) 280 281 req := NewRequestWithBody(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/releases/%d/assets?name=test-asset&token=%s", owner.Name, repo.Name, r.ID, token), body) 282 req.Header.Add("Content-Type", writer.FormDataContentType()) 283 resp := MakeRequest(t, req, http.StatusCreated) 284 285 var attachment *api.Attachment 286 DecodeJSON(t, resp, &attachment) 287 288 assert.EqualValues(t, "test-asset", attachment.Name) 289 assert.EqualValues(t, 104, attachment.Size) 290 }