This commit is contained in:
@@ -14,18 +14,18 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/indexer/issues"
|
||||
"code.gitea.io/gitea/modules/references"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
"code.gitea.io/gitea/tests"
|
||||
"gitea.dev/models/db"
|
||||
issues_model "gitea.dev/models/issues"
|
||||
repo_model "gitea.dev/models/repo"
|
||||
"gitea.dev/models/unit"
|
||||
"gitea.dev/models/unittest"
|
||||
user_model "gitea.dev/models/user"
|
||||
"gitea.dev/modules/indexer/issues"
|
||||
"gitea.dev/modules/references"
|
||||
"gitea.dev/modules/setting"
|
||||
api "gitea.dev/modules/structs"
|
||||
"gitea.dev/modules/test"
|
||||
"gitea.dev/tests"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -34,7 +34,7 @@ import (
|
||||
func getIssuesSelection(t testing.TB, htmlDoc *HTMLDoc) *goquery.Selection {
|
||||
issueList := htmlDoc.doc.Find("#issue-list")
|
||||
assert.Equal(t, 1, issueList.Length())
|
||||
return issueList.Find(".flex-item").Find(".issue-title")
|
||||
return issueList.Find(".item").Find(".list-item-large-title")
|
||||
}
|
||||
|
||||
func getIssue(t *testing.T, repoID int64, issueSelection *goquery.Selection) *issues_model.Issue {
|
||||
@@ -123,7 +123,7 @@ func TestNoLoginViewIssue(t *testing.T) {
|
||||
}
|
||||
|
||||
func testNewIssue(t *testing.T, session *TestSession, user, repo, title, content string) string {
|
||||
req := NewRequest(t, "GET", path.Join(user, repo, "issues", "new"))
|
||||
req := NewRequest(t, "GET", "/"+path.Join(user, repo, "issues", "new"))
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
@@ -493,8 +493,7 @@ func TestSearchIssues(t *testing.T) {
|
||||
link, _ := url.Parse("/issues/search")
|
||||
req := NewRequest(t, "GET", link.String())
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
var apiIssues []*api.Issue
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
apiIssues := DecodeJSON(t, resp, []*api.Issue{})
|
||||
assert.Len(t, apiIssues, expectedIssueCount)
|
||||
|
||||
since := "2000-01-01T00:50:01+00:00" // 946687801
|
||||
@@ -505,7 +504,7 @@ func TestSearchIssues(t *testing.T) {
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
apiIssues = DecodeJSON(t, resp, []*api.Issue{})
|
||||
assert.Len(t, apiIssues, 11)
|
||||
query.Del("since")
|
||||
query.Del("before")
|
||||
@@ -514,14 +513,14 @@ func TestSearchIssues(t *testing.T) {
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
apiIssues = DecodeJSON(t, resp, []*api.Issue{})
|
||||
assert.Len(t, apiIssues, 2)
|
||||
|
||||
query.Set("state", "all")
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
apiIssues = DecodeJSON(t, resp, []*api.Issue{})
|
||||
assert.Equal(t, "22", resp.Header().Get("X-Total-Count"))
|
||||
assert.Len(t, apiIssues, 20)
|
||||
|
||||
@@ -529,7 +528,7 @@ func TestSearchIssues(t *testing.T) {
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
apiIssues = DecodeJSON(t, resp, []*api.Issue{})
|
||||
assert.Equal(t, "22", resp.Header().Get("X-Total-Count"))
|
||||
assert.Len(t, apiIssues, 5)
|
||||
|
||||
@@ -537,42 +536,42 @@ func TestSearchIssues(t *testing.T) {
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
apiIssues = DecodeJSON(t, resp, []*api.Issue{})
|
||||
assert.Len(t, apiIssues, 2)
|
||||
|
||||
query = url.Values{"milestones": {"milestone1"}, "state": {"all"}}
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
apiIssues = DecodeJSON(t, resp, []*api.Issue{})
|
||||
assert.Len(t, apiIssues, 1)
|
||||
|
||||
query = url.Values{"milestones": {"milestone1,milestone3"}, "state": {"all"}}
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
apiIssues = DecodeJSON(t, resp, []*api.Issue{})
|
||||
assert.Len(t, apiIssues, 2)
|
||||
|
||||
query = url.Values{"owner": {"user2"}} // user
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
apiIssues = DecodeJSON(t, resp, []*api.Issue{})
|
||||
assert.Len(t, apiIssues, 8)
|
||||
|
||||
query = url.Values{"owner": {"org3"}} // organization
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
apiIssues = DecodeJSON(t, resp, []*api.Issue{})
|
||||
assert.Len(t, apiIssues, 5)
|
||||
|
||||
query = url.Values{"owner": {"org3"}, "team": {"team1"}} // organization + team
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
apiIssues = DecodeJSON(t, resp, []*api.Issue{})
|
||||
assert.Len(t, apiIssues, 2)
|
||||
}
|
||||
|
||||
@@ -589,14 +588,14 @@ func TestSearchIssuesWithLabels(t *testing.T) {
|
||||
link.RawQuery = query.Encode()
|
||||
req := NewRequest(t, "GET", link.String())
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
apiIssues = DecodeJSON(t, resp, []*api.Issue{})
|
||||
assert.Len(t, apiIssues, expectedIssueCount)
|
||||
|
||||
query.Add("labels", "label1")
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
apiIssues = DecodeJSON(t, resp, []*api.Issue{})
|
||||
assert.Len(t, apiIssues, 2)
|
||||
|
||||
// multiple labels
|
||||
@@ -604,7 +603,7 @@ func TestSearchIssuesWithLabels(t *testing.T) {
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
apiIssues = DecodeJSON(t, resp, []*api.Issue{})
|
||||
assert.Len(t, apiIssues, 2)
|
||||
|
||||
// an org label
|
||||
@@ -612,7 +611,7 @@ func TestSearchIssuesWithLabels(t *testing.T) {
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
apiIssues = DecodeJSON(t, resp, []*api.Issue{})
|
||||
assert.Len(t, apiIssues, 1)
|
||||
|
||||
// org and repo label
|
||||
@@ -621,7 +620,7 @@ func TestSearchIssuesWithLabels(t *testing.T) {
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
apiIssues = DecodeJSON(t, resp, []*api.Issue{})
|
||||
assert.Len(t, apiIssues, 2)
|
||||
|
||||
// org and repo label which share the same issue
|
||||
@@ -629,7 +628,7 @@ func TestSearchIssuesWithLabels(t *testing.T) {
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
apiIssues = DecodeJSON(t, resp, []*api.Issue{})
|
||||
assert.Len(t, apiIssues, 2)
|
||||
}
|
||||
|
||||
@@ -648,11 +647,10 @@ func TestGetIssueInfo(t *testing.T) {
|
||||
urlStr := fmt.Sprintf("/%s/%s/issues/%d/info", owner.Name, repo.Name, issue.Index)
|
||||
req := NewRequest(t, "GET", urlStr)
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
var respStruct struct {
|
||||
respStruct := DecodeJSON(t, resp, &struct {
|
||||
ConvertedIssue api.Issue
|
||||
RenderedLabels template.HTML
|
||||
}
|
||||
DecodeJSON(t, resp, &respStruct)
|
||||
}{})
|
||||
|
||||
assert.Equal(t, issue.ID, respStruct.ConvertedIssue.ID)
|
||||
assert.Contains(t, string(respStruct.RenderedLabels), `"labels-list"`)
|
||||
@@ -669,7 +667,7 @@ func TestUpdateIssueDeadline(t *testing.T) {
|
||||
assert.Equal(t, api.StateOpen, issueBefore.State())
|
||||
|
||||
session := loginUser(t, owner.Name)
|
||||
urlStr := fmt.Sprintf("%s/%s/issues/%d/deadline", owner.Name, repoBefore.Name, issueBefore.Index)
|
||||
urlStr := fmt.Sprintf("/%s/%s/issues/%d/deadline", owner.Name, repoBefore.Name, issueBefore.Index)
|
||||
|
||||
req := NewRequestWithValues(t, "POST", urlStr, map[string]string{"deadline": "2022-04-06"})
|
||||
session.MakeRequest(t, req, http.StatusOK)
|
||||
@@ -682,6 +680,59 @@ func TestUpdateIssueDeadline(t *testing.T) {
|
||||
assert.True(t, issueAfter.DeadlineUnix.IsZero())
|
||||
}
|
||||
|
||||
func TestUpdateIssueRefByPoster(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
// user4 is a non-admin, non-collaborator on user2/repo1.
|
||||
// They create an issue, making them the poster.
|
||||
posterSession := loginUser(t, "user4")
|
||||
issueURL := testNewIssue(t, posterSession, "user2", "repo1", "Poster ref test", "body")
|
||||
refURL := issueURL + "/ref"
|
||||
|
||||
// The poster (non-collaborator) must be able to update the ref.
|
||||
req := NewRequestWithValues(t, "POST", refURL, map[string]string{"ref": "refs/heads/main"})
|
||||
posterSession.MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
// A different non-collaborator non-poster must be forbidden.
|
||||
otherSession := loginUser(t, "user5")
|
||||
req = NewRequestWithValues(t, "POST", refURL, map[string]string{"ref": "refs/heads/main"})
|
||||
otherSession.MakeRequest(t, req, http.StatusForbidden)
|
||||
}
|
||||
|
||||
func TestIssueRefSelectorEnabledForPoster(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
// user4 creates an issue in user2/repo1 (user4 has no write permission there).
|
||||
posterSession := loginUser(t, "user4")
|
||||
issueURL := testNewIssue(t, posterSession, "user2", "repo1", "Ref selector test", "body")
|
||||
|
||||
resp := posterSession.MakeRequest(t, NewRequest(t, "GET", issueURL), http.StatusOK)
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
|
||||
// The branch selector must not carry the "disabled" CSS class for the poster.
|
||||
sel := htmlDoc.Find(".branch-selector-dropdown")
|
||||
assert.Equal(t, 1, sel.Length())
|
||||
assert.False(t, sel.HasClass("disabled"), "branch selector should be enabled for the issue poster")
|
||||
// The update-ref URL must be present so JS can send the POST request.
|
||||
_, hasURL := sel.Attr("data-url-update-issueref")
|
||||
assert.True(t, hasURL, "data-url-update-issueref must be set for the issue poster")
|
||||
}
|
||||
|
||||
func TestIssueRefSelectorEnabledForNewIssue(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
// user4 (non-collaborator on user2/repo1) must see an enabled ref selector
|
||||
// when creating a new issue.
|
||||
session := loginUser(t, "user4")
|
||||
req := NewRequest(t, "GET", "/user2/repo1/issues/new")
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
|
||||
sel := htmlDoc.Find(".branch-selector-dropdown")
|
||||
assert.Equal(t, 1, sel.Length())
|
||||
assert.False(t, sel.HasClass("disabled"), "branch selector should be enabled on the new issue form")
|
||||
}
|
||||
|
||||
func TestIssueReferenceURL(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
session := loginUser(t, "user2")
|
||||
@@ -689,14 +740,13 @@ func TestIssueReferenceURL(t *testing.T) {
|
||||
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
|
||||
|
||||
req := NewRequest(t, "GET", fmt.Sprintf("%s/issues/%d", repo.FullName(), issue.Index))
|
||||
req := NewRequest(t, "GET", fmt.Sprintf("%s/issues/%d", repo.Link(), issue.Index))
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
|
||||
// the "reference" uses relative URLs, then JS code will convert them to absolute URLs for current origin, in case users are using multiple domains
|
||||
ref, _ := htmlDoc.Find(`.timeline-item.comment.first .reference-issue`).Attr("data-reference")
|
||||
assert.Equal(t, "/user2/repo1/issues/1#issue-1", ref)
|
||||
ref, _ := htmlDoc.Find(`.timeline-item.comment.issue-content-comment .reference-issue`).Attr("data-reference")
|
||||
assert.Equal(t, setting.AppURL+"user2/repo1/issues/1#issue-1", ref)
|
||||
|
||||
ref, _ = htmlDoc.Find(`.timeline-item.comment:not(.first) .reference-issue`).Attr("data-reference")
|
||||
assert.Equal(t, "/user2/repo1/issues/1#issuecomment-2", ref)
|
||||
ref, _ = htmlDoc.Find(`.timeline-item.comment:not(.issue-content-comment) .reference-issue`).Attr("data-reference")
|
||||
assert.Equal(t, setting.AppURL+"user2/repo1/issues/1#issuecomment-2", ref)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user