mirror of
https://codeberg.org/forgejo/forgejo
synced 2024-11-26 19:56:11 +01:00
a448744b7b
- Currently the confirmation for dangerous actions such as transferring the repository or deleting it only requires the user to ~~copy paste~~ type the repository name. - This can be problematic when the user has a fork or another repository with the same name as an organization's repository, and the confirmation doesn't make clear that it could be deleting the wrong repository. While it's mentioned in the dialog, it's better to be on the safe side and also add the owner's name to be an element that has to be typed for these dangerous actions. - Added integration tests. (cherry picked from commitbf679b24dd
) (cherry picked from commit1963085dd9
) (cherry picked from commitfb94095d19
) (cherry picked from commite1d1e46afe
) (cherry picked from commit64e38b3363
) (cherry picked from commit0c2a78fa48
) (cherry picked from commite8aa66f1dd
) (cherry picked from commit55b5aa0239
)
589 lines
22 KiB
Go
589 lines
22 KiB
Go
// Copyright 2017 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package integration
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"path"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
gitea_context "code.gitea.io/gitea/modules/context"
|
|
"code.gitea.io/gitea/modules/setting"
|
|
"code.gitea.io/gitea/modules/translation"
|
|
"code.gitea.io/gitea/tests"
|
|
|
|
"github.com/PuerkitoBio/goquery"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestViewRepo(t *testing.T) {
|
|
defer tests.PrepareTestEnv(t)()
|
|
|
|
session := loginUser(t, "user2")
|
|
|
|
req := NewRequest(t, "GET", "/user2/repo1")
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
noDescription := htmlDoc.doc.Find("#repo-desc").Children()
|
|
repoTopics := htmlDoc.doc.Find("#repo-topics").Children()
|
|
repoSummary := htmlDoc.doc.Find(".repository-summary").Children()
|
|
|
|
assert.True(t, noDescription.HasClass("no-description"))
|
|
assert.True(t, repoTopics.HasClass("repo-topic"))
|
|
assert.True(t, repoSummary.HasClass("repository-menu"))
|
|
|
|
req = NewRequest(t, "GET", "/org3/repo3")
|
|
MakeRequest(t, req, http.StatusNotFound)
|
|
|
|
session = loginUser(t, "user1")
|
|
session.MakeRequest(t, req, http.StatusNotFound)
|
|
}
|
|
|
|
func testViewRepo(t *testing.T) {
|
|
defer tests.PrepareTestEnv(t)()
|
|
|
|
req := NewRequest(t, "GET", "/org3/repo3")
|
|
session := loginUser(t, "user2")
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
files := htmlDoc.doc.Find("#repo-files-table > TBODY > TR")
|
|
|
|
type file struct {
|
|
fileName string
|
|
commitID string
|
|
commitMsg string
|
|
commitTime string
|
|
}
|
|
|
|
var items []file
|
|
|
|
files.Each(func(i int, s *goquery.Selection) {
|
|
tds := s.Find("td")
|
|
var f file
|
|
tds.Each(func(i int, s *goquery.Selection) {
|
|
if i == 0 {
|
|
f.fileName = strings.TrimSpace(s.Text())
|
|
} else if i == 1 {
|
|
a := s.Find("a")
|
|
f.commitMsg = strings.TrimSpace(a.Text())
|
|
l, _ := a.Attr("href")
|
|
f.commitID = path.Base(l)
|
|
}
|
|
})
|
|
|
|
// convert "2017-06-14 21:54:21 +0800" to "Wed, 14 Jun 2017 13:54:21 UTC"
|
|
htmlTimeString, _ := s.Find("relative-time.time-since").Attr("datetime")
|
|
htmlTime, _ := time.Parse(time.RFC3339, htmlTimeString)
|
|
f.commitTime = htmlTime.In(time.Local).Format(time.RFC1123)
|
|
items = append(items, f)
|
|
})
|
|
|
|
commitT := time.Date(2017, time.June, 14, 13, 54, 21, 0, time.UTC).In(time.Local).Format(time.RFC1123)
|
|
assert.EqualValues(t, []file{
|
|
{
|
|
fileName: "doc",
|
|
commitID: "2a47ca4b614a9f5a43abbd5ad851a54a616ffee6",
|
|
commitMsg: "init project",
|
|
commitTime: commitT,
|
|
},
|
|
{
|
|
fileName: "README.md",
|
|
commitID: "2a47ca4b614a9f5a43abbd5ad851a54a616ffee6",
|
|
commitMsg: "init project",
|
|
commitTime: commitT,
|
|
},
|
|
}, items)
|
|
}
|
|
|
|
func TestViewRepo2(t *testing.T) {
|
|
// no last commit cache
|
|
testViewRepo(t)
|
|
|
|
// enable last commit cache for all repositories
|
|
oldCommitsCount := setting.CacheService.LastCommit.CommitsCount
|
|
setting.CacheService.LastCommit.CommitsCount = 0
|
|
// first view will not hit the cache
|
|
testViewRepo(t)
|
|
// second view will hit the cache
|
|
testViewRepo(t)
|
|
setting.CacheService.LastCommit.CommitsCount = oldCommitsCount
|
|
}
|
|
|
|
func TestViewRepo3(t *testing.T) {
|
|
defer tests.PrepareTestEnv(t)()
|
|
|
|
req := NewRequest(t, "GET", "/org3/repo3")
|
|
session := loginUser(t, "user4")
|
|
session.MakeRequest(t, req, http.StatusOK)
|
|
}
|
|
|
|
func TestViewRepo1CloneLinkAnonymous(t *testing.T) {
|
|
defer tests.PrepareTestEnv(t)()
|
|
|
|
req := NewRequest(t, "GET", "/user2/repo1")
|
|
resp := MakeRequest(t, req, http.StatusOK)
|
|
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
link, exists := htmlDoc.doc.Find("#repo-clone-https").Attr("data-link")
|
|
assert.True(t, exists, "The template has changed")
|
|
assert.Equal(t, setting.AppURL+"user2/repo1.git", link)
|
|
_, exists = htmlDoc.doc.Find("#repo-clone-ssh").Attr("data-link")
|
|
assert.False(t, exists)
|
|
}
|
|
|
|
func TestViewRepo1CloneLinkAuthorized(t *testing.T) {
|
|
defer tests.PrepareTestEnv(t)()
|
|
|
|
session := loginUser(t, "user2")
|
|
|
|
req := NewRequest(t, "GET", "/user2/repo1")
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
link, exists := htmlDoc.doc.Find("#repo-clone-https").Attr("data-link")
|
|
assert.True(t, exists, "The template has changed")
|
|
assert.Equal(t, setting.AppURL+"user2/repo1.git", link)
|
|
link, exists = htmlDoc.doc.Find("#repo-clone-ssh").Attr("data-link")
|
|
assert.True(t, exists, "The template has changed")
|
|
sshURL := fmt.Sprintf("ssh://%s@%s:%d/user2/repo1.git", setting.SSH.User, setting.SSH.Domain, setting.SSH.Port)
|
|
assert.Equal(t, sshURL, link)
|
|
}
|
|
|
|
func TestViewRepoWithSymlinks(t *testing.T) {
|
|
defer tests.PrepareTestEnv(t)()
|
|
|
|
session := loginUser(t, "user2")
|
|
|
|
req := NewRequest(t, "GET", "/user2/repo20.git")
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
files := htmlDoc.doc.Find("#repo-files-table > TBODY > TR > TD.name > SPAN.truncate")
|
|
items := files.Map(func(i int, s *goquery.Selection) string {
|
|
cls, _ := s.Find("SVG").Attr("class")
|
|
file := strings.Trim(s.Find("A").Text(), " \t\n")
|
|
return fmt.Sprintf("%s: %s", file, cls)
|
|
})
|
|
assert.Len(t, items, 5)
|
|
assert.Equal(t, "a: svg octicon-file-directory-fill", items[0])
|
|
assert.Equal(t, "link_b: svg octicon-file-directory-symlink", items[1])
|
|
assert.Equal(t, "link_d: svg octicon-file-symlink-file", items[2])
|
|
assert.Equal(t, "link_hi: svg octicon-file-symlink-file", items[3])
|
|
assert.Equal(t, "link_link: svg octicon-file-symlink-file", items[4])
|
|
}
|
|
|
|
// TestViewAsRepoAdmin tests PR #2167
|
|
func TestViewAsRepoAdmin(t *testing.T) {
|
|
for user, expectedNoDescription := range map[string]bool{
|
|
"user2": true,
|
|
"user4": false,
|
|
} {
|
|
defer tests.PrepareTestEnv(t)()
|
|
|
|
session := loginUser(t, user)
|
|
|
|
req := NewRequest(t, "GET", "/user2/repo1.git")
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
noDescription := htmlDoc.doc.Find("#repo-desc").Children()
|
|
repoTopics := htmlDoc.doc.Find("#repo-topics").Children()
|
|
repoSummary := htmlDoc.doc.Find(".repository-summary").Children()
|
|
|
|
assert.Equal(t, expectedNoDescription, noDescription.HasClass("no-description"))
|
|
assert.True(t, repoTopics.HasClass("repo-topic"))
|
|
assert.True(t, repoSummary.HasClass("repository-menu"))
|
|
}
|
|
}
|
|
|
|
// TestViewFileInRepo repo description, topics and summary should not be displayed when viewing a file
|
|
func TestViewFileInRepo(t *testing.T) {
|
|
defer tests.PrepareTestEnv(t)()
|
|
|
|
session := loginUser(t, "user2")
|
|
|
|
req := NewRequest(t, "GET", "/user2/repo1/src/branch/master/README.md")
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
description := htmlDoc.doc.Find("#repo-desc")
|
|
repoTopics := htmlDoc.doc.Find("#repo-topics")
|
|
repoSummary := htmlDoc.doc.Find(".repository-summary")
|
|
|
|
assert.EqualValues(t, 0, description.Length())
|
|
assert.EqualValues(t, 0, repoTopics.Length())
|
|
assert.EqualValues(t, 0, repoSummary.Length())
|
|
}
|
|
|
|
// TestBlameFileInRepo repo description, topics and summary should not be displayed when running blame on a file
|
|
func TestBlameFileInRepo(t *testing.T) {
|
|
defer tests.PrepareTestEnv(t)()
|
|
|
|
session := loginUser(t, "user2")
|
|
|
|
req := NewRequest(t, "GET", "/user2/repo1/blame/branch/master/README.md")
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
description := htmlDoc.doc.Find("#repo-desc")
|
|
repoTopics := htmlDoc.doc.Find("#repo-topics")
|
|
repoSummary := htmlDoc.doc.Find(".repository-summary")
|
|
|
|
assert.EqualValues(t, 0, description.Length())
|
|
assert.EqualValues(t, 0, repoTopics.Length())
|
|
assert.EqualValues(t, 0, repoSummary.Length())
|
|
}
|
|
|
|
// TestViewRepoDirectory repo description, topics and summary should not be displayed when within a directory
|
|
func TestViewRepoDirectory(t *testing.T) {
|
|
defer tests.PrepareTestEnv(t)()
|
|
|
|
session := loginUser(t, "user2")
|
|
|
|
req := NewRequest(t, "GET", "/user2/repo20/src/branch/master/a")
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
description := htmlDoc.doc.Find("#repo-desc")
|
|
repoTopics := htmlDoc.doc.Find("#repo-topics")
|
|
repoSummary := htmlDoc.doc.Find(".repository-summary")
|
|
|
|
repoFilesTable := htmlDoc.doc.Find("#repo-files-table")
|
|
assert.NotZero(t, len(repoFilesTable.Nodes))
|
|
|
|
assert.Zero(t, description.Length())
|
|
assert.Zero(t, repoTopics.Length())
|
|
assert.Zero(t, repoSummary.Length())
|
|
}
|
|
|
|
// ensure that the all the different ways to find and render a README work
|
|
func TestViewRepoDirectoryReadme(t *testing.T) {
|
|
defer tests.PrepareTestEnv(t)()
|
|
|
|
// there are many combinations:
|
|
// - READMEs can be .md, .txt, or have no extension
|
|
// - READMEs can be tagged with a language and even a country code
|
|
// - READMEs can be stored in docs/, .gitea/, or .github/
|
|
// - READMEs can be symlinks to other files
|
|
// - READMEs can be broken symlinks which should not render
|
|
//
|
|
// this doesn't cover all possible cases, just the major branches of the code
|
|
|
|
session := loginUser(t, "user2")
|
|
|
|
check := func(name, url, expectedFilename, expectedReadmeType, expectedContent string) {
|
|
t.Run(name, func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
|
|
req := NewRequest(t, "GET", url)
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
readmeName := htmlDoc.doc.Find("h4.file-header")
|
|
readmeContent := htmlDoc.doc.Find(".file-view") // TODO: add a id="readme" to the output to make this test more precise
|
|
readmeType, _ := readmeContent.Attr("class")
|
|
|
|
assert.Equal(t, expectedFilename, strings.TrimSpace(readmeName.Text()))
|
|
assert.Contains(t, readmeType, expectedReadmeType)
|
|
assert.Contains(t, readmeContent.Text(), expectedContent)
|
|
})
|
|
}
|
|
|
|
// viewing the top level
|
|
check("Home", "/user2/readme-test/", "README.md", "markdown", "The cake is a lie.")
|
|
|
|
// viewing different file extensions
|
|
check("md", "/user2/readme-test/src/branch/master/", "README.md", "markdown", "The cake is a lie.")
|
|
check("txt", "/user2/readme-test/src/branch/txt/", "README.txt", "plain-text", "My spoon is too big.")
|
|
check("plain", "/user2/readme-test/src/branch/plain/", "README", "plain-text", "Birken my stocks gee howdy")
|
|
check("i18n", "/user2/readme-test/src/branch/i18n/", "README.zh.md", "markdown", "蛋糕是一个谎言")
|
|
|
|
// using HEAD ref
|
|
check("branch-HEAD", "/user2/readme-test/src/branch/HEAD/", "README.md", "markdown", "The cake is a lie.")
|
|
check("commit-HEAD", "/user2/readme-test/src/commit/HEAD/", "README.md", "markdown", "The cake is a lie.")
|
|
|
|
// viewing different subdirectories
|
|
check("subdir", "/user2/readme-test/src/branch/subdir/libcake", "README.md", "markdown", "Four pints of sugar.")
|
|
check("docs-direct", "/user2/readme-test/src/branch/special-subdir-docs/docs/", "README.md", "markdown", "This is in docs/")
|
|
check("docs", "/user2/readme-test/src/branch/special-subdir-docs/", "docs/README.md", "markdown", "This is in docs/")
|
|
check(".gitea", "/user2/readme-test/src/branch/special-subdir-.gitea/", ".gitea/README.md", "markdown", "This is in .gitea/")
|
|
check(".github", "/user2/readme-test/src/branch/special-subdir-.github/", ".github/README.md", "markdown", "This is in .github/")
|
|
|
|
// symlinks
|
|
// symlinks are subtle:
|
|
// - they should be able to handle going a reasonable number of times up and down in the tree
|
|
// - they shouldn't get stuck on link cycles
|
|
// - they should determine the filetype based on the name of the link, not the target
|
|
check("symlink", "/user2/readme-test/src/branch/symlink/", "README.md", "markdown", "This is in some/other/path")
|
|
check("symlink-multiple", "/user2/readme-test/src/branch/symlink/some/", "README.txt", "plain-text", "This is in some/other/path")
|
|
check("symlink-up-and-down", "/user2/readme-test/src/branch/symlink/up/back/down/down", "README.md", "markdown", "It's a me, mario")
|
|
|
|
// testing fallback rules
|
|
// READMEs are searched in this order:
|
|
// - [README.zh-cn.md, README.zh_cn.md, README.zh.md, README_zh.md, README.md, README.txt, README,
|
|
// docs/README.zh-cn.md, docs/README.zh_cn.md, docs/README.zh.md, docs/README_zh.md, docs/README.md, docs/README.txt, docs/README,
|
|
// .gitea/README.zh-cn.md, .gitea/README.zh_cn.md, .gitea/README.zh.md, .gitea/README_zh.md, .gitea/README.md, .gitea/README.txt, .gitea/README,
|
|
|
|
// .github/README.zh-cn.md, .github/README.zh_cn.md, .github/README.zh.md, .github/README_zh.md, .github/README.md, .github/README.txt, .github/README]
|
|
// and a broken/looped symlink counts as not existing at all and should be skipped.
|
|
// again, this doesn't cover all cases, but it covers a few
|
|
check("fallback/top", "/user2/readme-test/src/branch/fallbacks/", "README.en.md", "markdown", "This is README.en.md")
|
|
check("fallback/2", "/user2/readme-test/src/branch/fallbacks2/", "README.md", "markdown", "This is README.md")
|
|
check("fallback/3", "/user2/readme-test/src/branch/fallbacks3/", "README", "plain-text", "This is README")
|
|
check("fallback/4", "/user2/readme-test/src/branch/fallbacks4/", "docs/README.en.md", "markdown", "This is docs/README.en.md")
|
|
check("fallback/5", "/user2/readme-test/src/branch/fallbacks5/", "docs/README.md", "markdown", "This is docs/README.md")
|
|
check("fallback/6", "/user2/readme-test/src/branch/fallbacks6/", "docs/README", "plain-text", "This is docs/README")
|
|
check("fallback/7", "/user2/readme-test/src/branch/fallbacks7/", ".gitea/README.en.md", "markdown", "This is .gitea/README.en.md")
|
|
check("fallback/8", "/user2/readme-test/src/branch/fallbacks8/", ".gitea/README.md", "markdown", "This is .gitea/README.md")
|
|
check("fallback/9", "/user2/readme-test/src/branch/fallbacks9/", ".gitea/README", "plain-text", "This is .gitea/README")
|
|
|
|
// this case tests that broken symlinks count as missing files, instead of rendering their contents
|
|
check("fallbacks-broken-symlinks", "/user2/readme-test/src/branch/fallbacks-broken-symlinks/", "docs/README", "plain-text", "This is docs/README")
|
|
|
|
// some cases that should NOT render a README
|
|
// - /readme
|
|
// - /.github/docs/README.md
|
|
// - a symlink loop
|
|
|
|
missing := func(name, url string) {
|
|
t.Run("missing/"+name, func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
|
|
req := NewRequest(t, "GET", url)
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
_, exists := htmlDoc.doc.Find(".file-view").Attr("class")
|
|
|
|
assert.False(t, exists, "README should not have rendered")
|
|
})
|
|
}
|
|
missing("sp-ace", "/user2/readme-test/src/branch/sp-ace/")
|
|
missing("nested-special", "/user2/readme-test/src/branch/special-subdir-nested/subproject") // the special subdirs should only trigger on the repo root
|
|
missing("special-subdir-nested", "/user2/readme-test/src/branch/special-subdir-nested/")
|
|
missing("symlink-loop", "/user2/readme-test/src/branch/symlink-loop/")
|
|
}
|
|
|
|
func TestMarkDownReadmeImage(t *testing.T) {
|
|
defer tests.PrepareTestEnv(t)()
|
|
|
|
session := loginUser(t, "user2")
|
|
|
|
req := NewRequest(t, "GET", "/user2/repo1/src/branch/home-md-img-check")
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
src, exists := htmlDoc.doc.Find(`.markdown img`).Attr("src")
|
|
assert.True(t, exists, "Image not found in README")
|
|
assert.Equal(t, "/user2/repo1/media/branch/home-md-img-check/test-fake-img.jpg", src)
|
|
|
|
req = NewRequest(t, "GET", "/user2/repo1/src/branch/home-md-img-check/README.md")
|
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
htmlDoc = NewHTMLParser(t, resp.Body)
|
|
src, exists = htmlDoc.doc.Find(`.markdown img`).Attr("src")
|
|
assert.True(t, exists, "Image not found in markdown file")
|
|
assert.Equal(t, "/user2/repo1/media/branch/home-md-img-check/test-fake-img.jpg", src)
|
|
}
|
|
|
|
func TestMarkDownReadmeImageSubfolder(t *testing.T) {
|
|
defer tests.PrepareTestEnv(t)()
|
|
|
|
session := loginUser(t, "user2")
|
|
|
|
// this branch has the README in the special docs/README.md location
|
|
req := NewRequest(t, "GET", "/user2/repo1/src/branch/sub-home-md-img-check")
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
src, exists := htmlDoc.doc.Find(`.markdown img`).Attr("src")
|
|
assert.True(t, exists, "Image not found in README")
|
|
assert.Equal(t, "/user2/repo1/media/branch/sub-home-md-img-check/docs/test-fake-img.jpg", src)
|
|
|
|
req = NewRequest(t, "GET", "/user2/repo1/src/branch/sub-home-md-img-check/docs/README.md")
|
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
htmlDoc = NewHTMLParser(t, resp.Body)
|
|
src, exists = htmlDoc.doc.Find(`.markdown img`).Attr("src")
|
|
assert.True(t, exists, "Image not found in markdown file")
|
|
assert.Equal(t, "/user2/repo1/media/branch/sub-home-md-img-check/docs/test-fake-img.jpg", src)
|
|
}
|
|
|
|
func TestGeneratedSourceLink(t *testing.T) {
|
|
defer tests.PrepareTestEnv(t)()
|
|
|
|
t.Run("Rendered file", func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
req := NewRequest(t, "GET", "/user2/repo1/src/branch/master/README.md?display=source")
|
|
resp := MakeRequest(t, req, http.StatusOK)
|
|
doc := NewHTMLParser(t, resp.Body)
|
|
|
|
dataURL, exists := doc.doc.Find(".copy-line-permalink").Attr("data-url")
|
|
assert.True(t, exists)
|
|
assert.Equal(t, "/user2/repo1/src/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d/README.md?display=source", dataURL)
|
|
|
|
dataURL, exists = doc.doc.Find(".ref-in-new-issue").Attr("data-url-param-body-link")
|
|
assert.True(t, exists)
|
|
assert.Equal(t, "/user2/repo1/src/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d/README.md?display=source", dataURL)
|
|
})
|
|
|
|
t.Run("Non-Rendered file", func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
|
|
session := loginUser(t, "user27")
|
|
req := NewRequest(t, "GET", "/user27/repo49/src/branch/master/test/test.txt")
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
doc := NewHTMLParser(t, resp.Body)
|
|
|
|
dataURL, exists := doc.doc.Find(".copy-line-permalink").Attr("data-url")
|
|
assert.True(t, exists)
|
|
assert.Equal(t, "/user27/repo49/src/commit/aacbdfe9e1c4b47f60abe81849045fa4e96f1d75/test/test.txt", dataURL)
|
|
|
|
dataURL, exists = doc.doc.Find(".ref-in-new-issue").Attr("data-url-param-body-link")
|
|
assert.True(t, exists)
|
|
assert.Equal(t, "/user27/repo49/src/commit/aacbdfe9e1c4b47f60abe81849045fa4e96f1d75/test/test.txt", dataURL)
|
|
})
|
|
}
|
|
|
|
func TestDangerZoneConfirmation(t *testing.T) {
|
|
defer tests.PrepareTestEnv(t)()
|
|
mustInvalidRepoName := func(resp *httptest.ResponseRecorder) {
|
|
t.Helper()
|
|
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
assert.Contains(t,
|
|
htmlDoc.doc.Find(".ui.negative.message").Text(),
|
|
translation.NewLocale("en-US").Tr("form.enterred_invalid_repo_name"),
|
|
)
|
|
}
|
|
|
|
t.Run("Transfer ownership", func(t *testing.T) {
|
|
session := loginUser(t, "user2")
|
|
|
|
t.Run("Fail", func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
|
|
req := NewRequestWithValues(t, "POST", "/user2/repo1/settings", map[string]string{
|
|
"_csrf": GetCSRF(t, session, "/user2/repo1/settings"),
|
|
"action": "transfer",
|
|
"repo_name": "repo1",
|
|
"new_owner_name": "user1",
|
|
})
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
mustInvalidRepoName(resp)
|
|
})
|
|
t.Run("Pass", func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
|
|
req := NewRequestWithValues(t, "POST", "/user2/repo1/settings", map[string]string{
|
|
"_csrf": GetCSRF(t, session, "/user2/repo1/settings"),
|
|
"action": "transfer",
|
|
"repo_name": "user2/repo1",
|
|
"new_owner_name": "user1",
|
|
})
|
|
session.MakeRequest(t, req, http.StatusSeeOther)
|
|
|
|
flashCookie := session.GetCookie(gitea_context.CookieNameFlash)
|
|
assert.NotNil(t, flashCookie)
|
|
assert.EqualValues(t, flashCookie.Value, "success%3DThis%2Brepository%2Bhas%2Bbeen%2Bmarked%2Bfor%2Btransfer%2Band%2Bawaits%2Bconfirmation%2Bfrom%2B%2522User%2BOne%2522")
|
|
})
|
|
})
|
|
|
|
t.Run("Convert fork", func(t *testing.T) {
|
|
session := loginUser(t, "user20")
|
|
|
|
t.Run("Fail", func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
|
|
req := NewRequestWithValues(t, "POST", "/user20/big_test_public_fork_7/settings", map[string]string{
|
|
"_csrf": GetCSRF(t, session, "/user20/big_test_public_fork_7/settings"),
|
|
"action": "convert_fork",
|
|
"repo_name": "big_test_public_fork_7",
|
|
})
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
mustInvalidRepoName(resp)
|
|
})
|
|
t.Run("Pass", func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
|
|
req := NewRequestWithValues(t, "POST", "/user20/big_test_public_fork_7/settings", map[string]string{
|
|
"_csrf": GetCSRF(t, session, "/user20/big_test_public_fork_7/settings"),
|
|
"action": "convert_fork",
|
|
"repo_name": "user20/big_test_public_fork_7",
|
|
})
|
|
session.MakeRequest(t, req, http.StatusSeeOther)
|
|
|
|
flashCookie := session.GetCookie(gitea_context.CookieNameFlash)
|
|
assert.NotNil(t, flashCookie)
|
|
assert.EqualValues(t, flashCookie.Value, "success%3DThe%2Bfork%2Bhas%2Bbeen%2Bconverted%2Binto%2Ba%2Bregular%2Brepository.")
|
|
})
|
|
})
|
|
|
|
t.Run("Delete wiki", func(t *testing.T) {
|
|
session := loginUser(t, "user2")
|
|
|
|
t.Run("Fail", func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
|
|
req := NewRequestWithValues(t, "POST", "/user2/repo1/settings", map[string]string{
|
|
"_csrf": GetCSRF(t, session, "/user2/repo1/settings"),
|
|
"action": "delete-wiki",
|
|
"repo_name": "repo1",
|
|
})
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
mustInvalidRepoName(resp)
|
|
})
|
|
t.Run("Pass", func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
|
|
req := NewRequestWithValues(t, "POST", "/user2/repo1/settings", map[string]string{
|
|
"_csrf": GetCSRF(t, session, "/user2/repo1/settings"),
|
|
"action": "delete-wiki",
|
|
"repo_name": "user2/repo1",
|
|
})
|
|
session.MakeRequest(t, req, http.StatusSeeOther)
|
|
|
|
flashCookie := session.GetCookie(gitea_context.CookieNameFlash)
|
|
assert.NotNil(t, flashCookie)
|
|
assert.EqualValues(t, flashCookie.Value, "success%3DThe%2Brepository%2Bwiki%2Bdata%2Bhas%2Bbeen%2Bdeleted.")
|
|
})
|
|
})
|
|
|
|
t.Run("Delete", func(t *testing.T) {
|
|
session := loginUser(t, "user2")
|
|
|
|
t.Run("Fail", func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
|
|
req := NewRequestWithValues(t, "POST", "/user2/repo1/settings", map[string]string{
|
|
"_csrf": GetCSRF(t, session, "/user2/repo1/settings"),
|
|
"action": "delete",
|
|
"repo_name": "repo1",
|
|
})
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
mustInvalidRepoName(resp)
|
|
})
|
|
t.Run("Pass", func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
|
|
req := NewRequestWithValues(t, "POST", "/user2/repo1/settings", map[string]string{
|
|
"_csrf": GetCSRF(t, session, "/user2/repo1/settings"),
|
|
"action": "delete",
|
|
"repo_name": "user2/repo1",
|
|
})
|
|
session.MakeRequest(t, req, http.StatusSeeOther)
|
|
|
|
flashCookie := session.GetCookie(gitea_context.CookieNameFlash)
|
|
assert.NotNil(t, flashCookie)
|
|
assert.EqualValues(t, flashCookie.Value, "success%3DThe%2Brepository%2Bhas%2Bbeen%2Bdeleted.")
|
|
})
|
|
})
|
|
}
|