diff options
Diffstat (limited to '')
-rw-r--r-- | tests/integration/release_test.go | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/tests/integration/release_test.go b/tests/integration/release_test.go new file mode 100644 index 00000000..48c2b37c --- /dev/null +++ b/tests/integration/release_test.go @@ -0,0 +1,353 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// Copyright 2024 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package integration + +import ( + "fmt" + "net/http" + "strconv" + "testing" + "time" + + auth_model "code.gitea.io/gitea/models/auth" + "code.gitea.io/gitea/models/db" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unittest" + "code.gitea.io/gitea/modules/setting" + api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/test" + "code.gitea.io/gitea/modules/translation" + "code.gitea.io/gitea/tests" + + "github.com/PuerkitoBio/goquery" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func createNewRelease(t *testing.T, session *TestSession, repoURL, tag, title string, preRelease, draft bool) { + createNewReleaseTarget(t, session, repoURL, tag, title, "master", preRelease, draft) +} + +func createNewReleaseTarget(t *testing.T, session *TestSession, repoURL, tag, title, target string, preRelease, draft bool) { + req := NewRequest(t, "GET", repoURL+"/releases/new") + resp := session.MakeRequest(t, req, http.StatusOK) + htmlDoc := NewHTMLParser(t, resp.Body) + + link, exists := htmlDoc.doc.Find("form.ui.form").Attr("action") + assert.True(t, exists, "The template has changed") + + postData := map[string]string{ + "_csrf": htmlDoc.GetCSRF(), + "tag_name": tag, + "tag_target": target, + "title": title, + "content": "", + } + if preRelease { + postData["prerelease"] = "on" + } + if draft { + postData["draft"] = "Save Draft" + } + req = NewRequestWithValues(t, "POST", link, postData) + + resp = session.MakeRequest(t, req, http.StatusSeeOther) + + test.RedirectURL(resp) // check that redirect URL exists +} + +func checkLatestReleaseAndCount(t *testing.T, session *TestSession, repoURL, version, label string, count int) { + req := NewRequest(t, "GET", repoURL+"/releases") + resp := session.MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, resp.Body) + labelText := htmlDoc.doc.Find("#release-list > li .detail .label").First().Text() + assert.EqualValues(t, label, labelText) + titleText := htmlDoc.doc.Find("#release-list > li .detail h4 a").First().Text() + assert.EqualValues(t, version, titleText) + + // Check release count in the counter on the Release/Tag switch, as well as that the tab is highlighted + if count < 10 { // Only check values less than 10, should be enough attempts before this test cracks + // 10 is the pagination limit, but the counter can have more than that + releaseTab := htmlDoc.doc.Find(".repository.releases .ui.compact.menu a.active.item[href$='/releases']") + assert.Contains(t, releaseTab.Text(), strconv.Itoa(count)+" release") // Could be "1 release" or "4 releases" + } + + releaseList := htmlDoc.doc.Find("#release-list > li") + assert.EqualValues(t, count, releaseList.Length()) +} + +func TestViewReleases(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + session := loginUser(t, "user2") + req := NewRequest(t, "GET", "/user2/repo1/releases") + session.MakeRequest(t, req, http.StatusOK) + + // if CI is too slow this test fail, so lets wait a bit + time.Sleep(time.Millisecond * 100) +} + +func TestViewReleasesNoLogin(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + req := NewRequest(t, "GET", "/user2/repo1/releases") + MakeRequest(t, req, http.StatusOK) +} + +func TestCreateRelease(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + session := loginUser(t, "user2") + createNewRelease(t, session, "/user2/repo1", "v0.0.1", "v0.0.1", false, false) + + checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.1", translation.NewLocale("en-US").TrString("repo.release.stable"), 4) +} + +func TestDeleteRelease(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 57, OwnerName: "user2", LowerName: "repo-release"}) + release := unittest.AssertExistsAndLoadBean(t, &repo_model.Release{TagName: "v2.0"}) + assert.False(t, release.IsTag) + + // Using the ID of a comment that does not belong to the repository must fail + session5 := loginUser(t, "user5") + otherRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user5", LowerName: "repo4"}) + + req := NewRequestWithValues(t, "POST", fmt.Sprintf("%s/releases/delete?id=%d", otherRepo.Link(), release.ID), map[string]string{ + "_csrf": GetCSRF(t, session5, otherRepo.Link()), + }) + session5.MakeRequest(t, req, http.StatusNotFound) + + session := loginUser(t, "user2") + req = NewRequestWithValues(t, "POST", fmt.Sprintf("%s/releases/delete?id=%d", repo.Link(), release.ID), map[string]string{ + "_csrf": GetCSRF(t, session, repo.Link()), + }) + session.MakeRequest(t, req, http.StatusOK) + release = unittest.AssertExistsAndLoadBean(t, &repo_model.Release{ID: release.ID}) + + if assert.True(t, release.IsTag) { + req = NewRequestWithValues(t, "POST", fmt.Sprintf("%s/tags/delete?id=%d", otherRepo.Link(), release.ID), map[string]string{ + "_csrf": GetCSRF(t, session5, otherRepo.Link()), + }) + session5.MakeRequest(t, req, http.StatusNotFound) + + req = NewRequestWithValues(t, "POST", fmt.Sprintf("%s/tags/delete?id=%d", repo.Link(), release.ID), map[string]string{ + "_csrf": GetCSRF(t, session, repo.Link()), + }) + session.MakeRequest(t, req, http.StatusOK) + + unittest.AssertNotExistsBean(t, &repo_model.Release{ID: release.ID}) + } +} + +func TestCreateReleasePreRelease(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + session := loginUser(t, "user2") + createNewRelease(t, session, "/user2/repo1", "v0.0.1", "v0.0.1", true, false) + + checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.1", translation.NewLocale("en-US").TrString("repo.release.prerelease"), 4) +} + +func TestCreateReleaseDraft(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + session := loginUser(t, "user2") + createNewRelease(t, session, "/user2/repo1", "v0.0.1", "v0.0.1", false, true) + + checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.1", translation.NewLocale("en-US").TrString("repo.release.draft"), 4) +} + +func TestCreateReleasePaging(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + oldAPIDefaultNum := setting.API.DefaultPagingNum + defer func() { + setting.API.DefaultPagingNum = oldAPIDefaultNum + }() + setting.API.DefaultPagingNum = 10 + + session := loginUser(t, "user2") + // Create enough releases to have paging + for i := 0; i < 12; i++ { + version := fmt.Sprintf("v0.0.%d", i) + createNewRelease(t, session, "/user2/repo1", version, version, false, false) + } + createNewRelease(t, session, "/user2/repo1", "v0.0.12", "v0.0.12", false, true) + + checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.12", translation.NewLocale("en-US").TrString("repo.release.draft"), 10) + + // Check that user4 does not see draft and still see 10 latest releases + session2 := loginUser(t, "user4") + checkLatestReleaseAndCount(t, session2, "/user2/repo1", "v0.0.11", translation.NewLocale("en-US").TrString("repo.release.stable"), 10) +} + +func TestViewReleaseListNoLogin(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 57, OwnerName: "user2", LowerName: "repo-release"}) + + link := repo.Link() + "/releases" + + req := NewRequest(t, "GET", link) + rsp := MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, rsp.Body) + releases := htmlDoc.Find("#release-list li.ui.grid") + assert.Equal(t, 5, releases.Length()) + + links := make([]string, 0, 5) + commitsToMain := make([]string, 0, 5) + releases.Each(func(i int, s *goquery.Selection) { + link, exist := s.Find(".release-list-title a").Attr("href") + if !exist { + return + } + links = append(links, link) + + commitsToMain = append(commitsToMain, s.Find(".ahead > a").Text()) + }) + + assert.EqualValues(t, []string{ + "/user2/repo-release/releases/tag/empty-target-branch", + "/user2/repo-release/releases/tag/non-existing-target-branch", + "/user2/repo-release/releases/tag/v2.0", + "/user2/repo-release/releases/tag/v1.1", + "/user2/repo-release/releases/tag/v1.0", + }, links) + assert.EqualValues(t, []string{ + "1 commits", // like v1.1 + "1 commits", // like v1.1 + "0 commits", + "1 commits", // should be 3 commits ahead and 2 commits behind, but not implemented yet + "3 commits", + }, commitsToMain) +} + +func TestViewSingleReleaseNoLogin(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + req := NewRequest(t, "GET", "/user2/repo-release/releases/tag/v1.0") + resp := MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, resp.Body) + // check the "number of commits to main since this release" + releaseList := htmlDoc.doc.Find("#release-list .ahead > a") + assert.EqualValues(t, 1, releaseList.Length()) + assert.EqualValues(t, "3 commits", releaseList.First().Text()) +} + +func TestViewReleaseListLogin(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + + link := repo.Link() + "/releases" + + session := loginUser(t, "user1") + req := NewRequest(t, "GET", link) + rsp := session.MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, rsp.Body) + releases := htmlDoc.Find("#release-list li.ui.grid") + assert.Equal(t, 3, releases.Length()) + + links := make([]string, 0, 5) + releases.Each(func(i int, s *goquery.Selection) { + link, exist := s.Find(".release-list-title a").Attr("href") + if !exist { + return + } + links = append(links, link) + }) + + assert.EqualValues(t, []string{ + "/user2/repo1/releases/tag/draft-release", + "/user2/repo1/releases/tag/v1.0", + "/user2/repo1/releases/tag/v1.1", + }, links) +} + +func TestReleaseOnCommit(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + session := loginUser(t, "user2") + createNewReleaseTarget(t, session, "/user2/repo1", "v0.0.1", "v0.0.1", "65f1bf27bc3bf70f64657658635e66094edbcb4d", false, false) + + checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.1", translation.NewLocale("en-US").TrString("repo.release.stable"), 4) +} + +func TestViewTagsList(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + + link := repo.Link() + "/tags" + + session := loginUser(t, "user1") + req := NewRequest(t, "GET", link) + rsp := session.MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, rsp.Body) + tags := htmlDoc.Find(".tag-list tr") + assert.Equal(t, 3, tags.Length()) + + tagNames := make([]string, 0, 5) + tags.Each(func(i int, s *goquery.Selection) { + tagNames = append(tagNames, s.Find(".tag a.tw-flex.tw-items-center").Text()) + }) + + assert.EqualValues(t, []string{"v1.0", "delete-tag", "v1.1"}, tagNames) +} + +func TestDownloadReleaseAttachment(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + tests.PrepareAttachmentsStorage(t) + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) + + url := repo.Link() + "/releases/download/v1.1/README.md" + + req := NewRequest(t, "GET", url) + MakeRequest(t, req, http.StatusNotFound) + + req = NewRequest(t, "GET", url) + session := loginUser(t, "user2") + session.MakeRequest(t, req, http.StatusOK) +} + +func TestReleaseHideArchiveLinksUI(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + release := unittest.AssertExistsAndLoadBean(t, &repo_model.Release{TagName: "v2.0"}) + + require.NoError(t, release.LoadAttributes(db.DefaultContext)) + + session := loginUser(t, release.Repo.OwnerName) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + + zipURL := fmt.Sprintf("%s/archive/%s.zip", release.Repo.Link(), release.TagName) + tarGzURL := fmt.Sprintf("%s/archive/%s.tar.gz", release.Repo.Link(), release.TagName) + + resp := session.MakeRequest(t, NewRequest(t, "GET", release.HTMLURL()), http.StatusOK) + body := resp.Body.String() + assert.Contains(t, body, zipURL) + assert.Contains(t, body, tarGzURL) + + hideArchiveLinks := true + + req := NewRequestWithJSON(t, "PATCH", release.APIURL(), &api.EditReleaseOption{ + HideArchiveLinks: &hideArchiveLinks, + }).AddTokenAuth(token) + MakeRequest(t, req, http.StatusOK) + + resp = session.MakeRequest(t, NewRequest(t, "GET", release.HTMLURL()), http.StatusOK) + body = resp.Body.String() + assert.NotContains(t, body, zipURL) + assert.NotContains(t, body, tarGzURL) +} |