mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-26 09:50:41 +00:00
Populate URL field of API commits (#3546)
* Populate URL field of API commits * fix orgmode_test
This commit is contained in:
parent
7b297808ce
commit
7b104f0cd0
11 changed files with 126 additions and 98 deletions
|
@ -15,8 +15,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/base"
|
"code.gitea.io/gitea/modules/base"
|
||||||
"code.gitea.io/gitea/modules/log"
|
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"github.com/Unknwon/com"
|
"github.com/Unknwon/com"
|
||||||
"golang.org/x/net/html"
|
"golang.org/x/net/html"
|
||||||
|
@ -112,20 +112,6 @@ func cutoutVerbosePrefix(prefix string) string {
|
||||||
return prefix
|
return prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
// URLJoin joins url components, like path.Join, but preserving contents
|
|
||||||
func URLJoin(base string, elems ...string) string {
|
|
||||||
u, err := url.Parse(base)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(4, "URLJoin: Invalid base URL %s", base)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
joinArgs := make([]string, 0, len(elems)+1)
|
|
||||||
joinArgs = append(joinArgs, u.Path)
|
|
||||||
joinArgs = append(joinArgs, elems...)
|
|
||||||
u.Path = path.Join(joinArgs...)
|
|
||||||
return u.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// RenderIssueIndexPatternOptions options for RenderIssueIndexPattern function
|
// RenderIssueIndexPatternOptions options for RenderIssueIndexPattern function
|
||||||
type RenderIssueIndexPatternOptions struct {
|
type RenderIssueIndexPatternOptions struct {
|
||||||
// url to which non-special formatting should be linked. If empty,
|
// url to which non-special formatting should be linked. If empty,
|
||||||
|
@ -177,7 +163,7 @@ func RenderIssueIndexPattern(rawBytes []byte, opts RenderIssueIndexPatternOption
|
||||||
}
|
}
|
||||||
if opts.Metas == nil {
|
if opts.Metas == nil {
|
||||||
buf.WriteString(`<a href="`)
|
buf.WriteString(`<a href="`)
|
||||||
buf.WriteString(URLJoin(
|
buf.WriteString(util.URLJoin(
|
||||||
opts.URLPrefix, "issues", string(remainder[startIndex+1:endIndex])))
|
opts.URLPrefix, "issues", string(remainder[startIndex+1:endIndex])))
|
||||||
buf.WriteString(`">`)
|
buf.WriteString(`">`)
|
||||||
buf.Write(remainder[startIndex:endIndex])
|
buf.Write(remainder[startIndex:endIndex])
|
||||||
|
@ -228,7 +214,7 @@ func renderFullSha1Pattern(rawBytes []byte, urlPrefix string) []byte {
|
||||||
path := protocol + "://" + paths
|
path := protocol + "://" + paths
|
||||||
author := string(m[3])
|
author := string(m[3])
|
||||||
repoName := string(m[4])
|
repoName := string(m[4])
|
||||||
path = URLJoin(path, author, repoName)
|
path = util.URLJoin(path, author, repoName)
|
||||||
ltype := "src"
|
ltype := "src"
|
||||||
itemType := m[5]
|
itemType := m[5]
|
||||||
if IsSameDomain(paths) {
|
if IsSameDomain(paths) {
|
||||||
|
@ -260,7 +246,7 @@ func renderFullSha1Pattern(rawBytes []byte, urlPrefix string) []byte {
|
||||||
text += ")"
|
text += ")"
|
||||||
}
|
}
|
||||||
rawBytes = bytes.Replace(rawBytes, all, []byte(fmt.Sprintf(
|
rawBytes = bytes.Replace(rawBytes, all, []byte(fmt.Sprintf(
|
||||||
`<a href="%s">%s</a>`, URLJoin(path, ltype, string(sha))+urlSuffix, text)), -1)
|
`<a href="%s">%s</a>`, util.URLJoin(path, ltype, string(sha))+urlSuffix, text)), -1)
|
||||||
}
|
}
|
||||||
return rawBytes
|
return rawBytes
|
||||||
}
|
}
|
||||||
|
@ -399,9 +385,9 @@ func RenderShortLinks(rawBytes []byte, urlPrefix string, noLink bool, isWikiMark
|
||||||
urlPrefix = strings.Replace(urlPrefix, "/src/", "/raw/", 1)
|
urlPrefix = strings.Replace(urlPrefix, "/src/", "/raw/", 1)
|
||||||
}
|
}
|
||||||
if isWikiMarkdown {
|
if isWikiMarkdown {
|
||||||
link = URLJoin("wiki", "raw", link)
|
link = util.URLJoin("wiki", "raw", link)
|
||||||
}
|
}
|
||||||
link = URLJoin(urlPrefix, link)
|
link = util.URLJoin(urlPrefix, link)
|
||||||
}
|
}
|
||||||
title := props["title"]
|
title := props["title"]
|
||||||
if title == "" {
|
if title == "" {
|
||||||
|
@ -420,9 +406,9 @@ func RenderShortLinks(rawBytes []byte, urlPrefix string, noLink bool, isWikiMark
|
||||||
name = fmt.Sprintf(`<img src="%s" %s title="%s" />`, link, alt, title)
|
name = fmt.Sprintf(`<img src="%s" %s title="%s" />`, link, alt, title)
|
||||||
} else if !absoluteLink {
|
} else if !absoluteLink {
|
||||||
if isWikiMarkdown {
|
if isWikiMarkdown {
|
||||||
link = URLJoin("wiki", link)
|
link = util.URLJoin("wiki", link)
|
||||||
}
|
}
|
||||||
link = URLJoin(urlPrefix, link)
|
link = util.URLJoin(urlPrefix, link)
|
||||||
}
|
}
|
||||||
if noLink {
|
if noLink {
|
||||||
rawBytes = bytes.Replace(rawBytes, orig, []byte(name), -1)
|
rawBytes = bytes.Replace(rawBytes, orig, []byte(name), -1)
|
||||||
|
@ -445,7 +431,7 @@ func RenderCrossReferenceIssueIndexPattern(rawBytes []byte, urlPrefix string, me
|
||||||
repo := string(bytes.Split(m, []byte("#"))[0])
|
repo := string(bytes.Split(m, []byte("#"))[0])
|
||||||
issue := string(bytes.Split(m, []byte("#"))[1])
|
issue := string(bytes.Split(m, []byte("#"))[1])
|
||||||
|
|
||||||
link := fmt.Sprintf(`<a href="%s">%s</a>`, URLJoin(setting.AppURL, repo, "issues", issue), m)
|
link := fmt.Sprintf(`<a href="%s">%s</a>`, util.URLJoin(setting.AppURL, repo, "issues", issue), m)
|
||||||
rawBytes = bytes.Replace(rawBytes, m, []byte(link), 1)
|
rawBytes = bytes.Replace(rawBytes, m, []byte(link), 1)
|
||||||
}
|
}
|
||||||
return rawBytes
|
return rawBytes
|
||||||
|
@ -463,7 +449,7 @@ func renderSha1CurrentPattern(rawBytes []byte, urlPrefix string) []byte {
|
||||||
// Although unlikely, deadbeef and 1234567 are valid short forms of SHA1 hash
|
// Although unlikely, deadbeef and 1234567 are valid short forms of SHA1 hash
|
||||||
// as used by git and github for linking and thus we have to do similar.
|
// as used by git and github for linking and thus we have to do similar.
|
||||||
rawBytes = bytes.Replace(rawBytes, hash, []byte(fmt.Sprintf(
|
rawBytes = bytes.Replace(rawBytes, hash, []byte(fmt.Sprintf(
|
||||||
`<a href="%s">%s</a>`, URLJoin(urlPrefix, "commit", string(hash)), base.ShortSha(string(hash)))), -1)
|
`<a href="%s">%s</a>`, util.URLJoin(urlPrefix, "commit", string(hash)), base.ShortSha(string(hash)))), -1)
|
||||||
}
|
}
|
||||||
return rawBytes
|
return rawBytes
|
||||||
}
|
}
|
||||||
|
@ -474,7 +460,7 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string, metas map[string]strin
|
||||||
for _, m := range ms {
|
for _, m := range ms {
|
||||||
m = m[bytes.Index(m, []byte("@")):]
|
m = m[bytes.Index(m, []byte("@")):]
|
||||||
rawBytes = bytes.Replace(rawBytes, m,
|
rawBytes = bytes.Replace(rawBytes, m,
|
||||||
[]byte(fmt.Sprintf(`<a href="%s">%s</a>`, URLJoin(setting.AppURL, string(m[1:])), m)), -1)
|
[]byte(fmt.Sprintf(`<a href="%s">%s</a>`, util.URLJoin(setting.AppURL, string(m[1:])), m)), -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
rawBytes = RenderFullIssuePattern(rawBytes)
|
rawBytes = RenderFullIssuePattern(rawBytes)
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
. "code.gitea.io/gitea/modules/markup"
|
. "code.gitea.io/gitea/modules/markup"
|
||||||
_ "code.gitea.io/gitea/modules/markup/markdown"
|
_ "code.gitea.io/gitea/modules/markup/markdown"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
@ -37,12 +38,12 @@ var alphanumericMetas = map[string]string{
|
||||||
|
|
||||||
// numericLink an HTML to a numeric-style issue
|
// numericLink an HTML to a numeric-style issue
|
||||||
func numericIssueLink(baseURL string, index int) string {
|
func numericIssueLink(baseURL string, index int) string {
|
||||||
return link(URLJoin(baseURL, strconv.Itoa(index)), fmt.Sprintf("#%d", index))
|
return link(util.URLJoin(baseURL, strconv.Itoa(index)), fmt.Sprintf("#%d", index))
|
||||||
}
|
}
|
||||||
|
|
||||||
// alphanumLink an HTML link to an alphanumeric-style issue
|
// alphanumLink an HTML link to an alphanumeric-style issue
|
||||||
func alphanumIssueLink(baseURL string, name string) string {
|
func alphanumIssueLink(baseURL string, name string) string {
|
||||||
return link(URLJoin(baseURL, name), name)
|
return link(util.URLJoin(baseURL, name), name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// urlContentsLink an HTML link whose contents is the target URL
|
// urlContentsLink an HTML link whose contents is the target URL
|
||||||
|
@ -63,31 +64,6 @@ func testRenderIssueIndexPattern(t *testing.T, input, expected string, opts Rend
|
||||||
assert.Equal(t, expected, actual)
|
assert.Equal(t, expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestURLJoin(t *testing.T) {
|
|
||||||
type test struct {
|
|
||||||
Expected string
|
|
||||||
Base string
|
|
||||||
Elements []string
|
|
||||||
}
|
|
||||||
newTest := func(expected, base string, elements ...string) test {
|
|
||||||
return test{Expected: expected, Base: base, Elements: elements}
|
|
||||||
}
|
|
||||||
for _, test := range []test{
|
|
||||||
newTest("https://try.gitea.io/a/b/c",
|
|
||||||
"https://try.gitea.io", "a/b", "c"),
|
|
||||||
newTest("https://try.gitea.io/a/b/c",
|
|
||||||
"https://try.gitea.io/", "/a/b/", "/c/"),
|
|
||||||
newTest("https://try.gitea.io/a/c",
|
|
||||||
"https://try.gitea.io/", "/a/./b/", "../c/"),
|
|
||||||
newTest("a/b/c",
|
|
||||||
"a", "b/c/"),
|
|
||||||
newTest("a/b/d",
|
|
||||||
"a/", "b/c/", "/../d/"),
|
|
||||||
} {
|
|
||||||
assert.Equal(t, test.Expected, URLJoin(test.Base, test.Elements...))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRender_IssueIndexPattern(t *testing.T) {
|
func TestRender_IssueIndexPattern(t *testing.T) {
|
||||||
// numeric: render inputs without valid mentions
|
// numeric: render inputs without valid mentions
|
||||||
test := func(s string) {
|
test := func(s string) {
|
||||||
|
@ -123,7 +99,7 @@ func TestRender_IssueIndexPattern2(t *testing.T) {
|
||||||
test := func(s, expectedFmt string, indices ...int) {
|
test := func(s, expectedFmt string, indices ...int) {
|
||||||
links := make([]interface{}, len(indices))
|
links := make([]interface{}, len(indices))
|
||||||
for i, index := range indices {
|
for i, index := range indices {
|
||||||
links[i] = numericIssueLink(URLJoin(setting.AppSubURL, "issues"), index)
|
links[i] = numericIssueLink(util.URLJoin(setting.AppSubURL, "issues"), index)
|
||||||
}
|
}
|
||||||
expectedNil := fmt.Sprintf(expectedFmt, links...)
|
expectedNil := fmt.Sprintf(expectedFmt, links...)
|
||||||
testRenderIssueIndexPattern(t, s, expectedNil, RenderIssueIndexPatternOptions{})
|
testRenderIssueIndexPattern(t, s, expectedNil, RenderIssueIndexPatternOptions{})
|
||||||
|
@ -228,8 +204,8 @@ func TestRender_AutoLink(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// render valid issue URLs
|
// render valid issue URLs
|
||||||
test(URLJoin(setting.AppSubURL, "issues", "3333"),
|
test(util.URLJoin(setting.AppSubURL, "issues", "3333"),
|
||||||
numericIssueLink(URLJoin(setting.AppSubURL, "issues"), 3333))
|
numericIssueLink(util.URLJoin(setting.AppSubURL, "issues"), 3333))
|
||||||
|
|
||||||
// render external issue URLs
|
// render external issue URLs
|
||||||
for _, externalURL := range []string{
|
for _, externalURL := range []string{
|
||||||
|
@ -240,7 +216,7 @@ func TestRender_AutoLink(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// render valid commit URLs
|
// render valid commit URLs
|
||||||
tmp := URLJoin(AppSubURL, "commit", "d8a994ef243349f321568f9e36d5c3f444b99cae")
|
tmp := util.URLJoin(AppSubURL, "commit", "d8a994ef243349f321568f9e36d5c3f444b99cae")
|
||||||
test(tmp, "<a href=\""+tmp+"\">d8a994ef24</a>")
|
test(tmp, "<a href=\""+tmp+"\">d8a994ef24</a>")
|
||||||
tmp += "#diff-2"
|
tmp += "#diff-2"
|
||||||
test(tmp, "<a href=\""+tmp+"\">d8a994ef24 (diff-2)</a>")
|
test(tmp, "<a href=\""+tmp+"\">d8a994ef24 (diff-2)</a>")
|
||||||
|
@ -260,8 +236,8 @@ func TestRender_Commits(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var sha = "b6dd6210eaebc915fd5be5579c58cce4da2e2579"
|
var sha = "b6dd6210eaebc915fd5be5579c58cce4da2e2579"
|
||||||
var commit = URLJoin(AppSubURL, "commit", sha)
|
var commit = util.URLJoin(AppSubURL, "commit", sha)
|
||||||
var subtree = URLJoin(commit, "src")
|
var subtree = util.URLJoin(commit, "src")
|
||||||
var tree = strings.Replace(subtree, "/commit/", "/tree/", -1)
|
var tree = strings.Replace(subtree, "/commit/", "/tree/", -1)
|
||||||
var src = strings.Replace(subtree, "/commit/", "/src/", -1)
|
var src = strings.Replace(subtree, "/commit/", "/src/", -1)
|
||||||
|
|
||||||
|
@ -284,10 +260,10 @@ func TestRender_CrossReferences(t *testing.T) {
|
||||||
|
|
||||||
test(
|
test(
|
||||||
"gogits/gogs#12345",
|
"gogits/gogs#12345",
|
||||||
`<p><a href="`+URLJoin(AppURL, "gogits", "gogs", "issues", "12345")+`" rel="nofollow">gogits/gogs#12345</a></p>`)
|
`<p><a href="`+util.URLJoin(AppURL, "gogits", "gogs", "issues", "12345")+`" rel="nofollow">gogits/gogs#12345</a></p>`)
|
||||||
test(
|
test(
|
||||||
"go-gitea/gitea#12345",
|
"go-gitea/gitea#12345",
|
||||||
`<p><a href="`+URLJoin(AppURL, "go-gitea", "gitea", "issues", "12345")+`" rel="nofollow">go-gitea/gitea#12345</a></p>`)
|
`<p><a href="`+util.URLJoin(AppURL, "go-gitea", "gitea", "issues", "12345")+`" rel="nofollow">go-gitea/gitea#12345</a></p>`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRender_FullIssueURLs(t *testing.T) {
|
func TestRender_FullIssueURLs(t *testing.T) {
|
||||||
|
@ -482,7 +458,7 @@ func TestMisc_IsSameDomain(t *testing.T) {
|
||||||
setting.AppSubURL = AppSubURL
|
setting.AppSubURL = AppSubURL
|
||||||
|
|
||||||
var sha = "b6dd6210eaebc915fd5be5579c58cce4da2e2579"
|
var sha = "b6dd6210eaebc915fd5be5579c58cce4da2e2579"
|
||||||
var commit = URLJoin(AppSubURL, "commit", sha)
|
var commit = util.URLJoin(AppSubURL, "commit", sha)
|
||||||
|
|
||||||
assert.True(t, IsSameDomain(commit))
|
assert.True(t, IsSameDomain(commit))
|
||||||
assert.False(t, IsSameDomain("http://google.com/ncr"))
|
assert.False(t, IsSameDomain("http://google.com/ncr"))
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/markup"
|
"code.gitea.io/gitea/modules/markup"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"github.com/russross/blackfriday"
|
"github.com/russross/blackfriday"
|
||||||
)
|
)
|
||||||
|
@ -27,9 +28,9 @@ func (r *Renderer) Link(out *bytes.Buffer, link []byte, title []byte, content []
|
||||||
if link[0] != '#' {
|
if link[0] != '#' {
|
||||||
lnk := string(link)
|
lnk := string(link)
|
||||||
if r.IsWiki {
|
if r.IsWiki {
|
||||||
lnk = markup.URLJoin("wiki", lnk)
|
lnk = util.URLJoin("wiki", lnk)
|
||||||
}
|
}
|
||||||
mLink := markup.URLJoin(r.URLPrefix, lnk)
|
mLink := util.URLJoin(r.URLPrefix, lnk)
|
||||||
link = []byte(mLink)
|
link = []byte(mLink)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +98,7 @@ var (
|
||||||
func (r *Renderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
|
func (r *Renderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
|
||||||
prefix := r.URLPrefix
|
prefix := r.URLPrefix
|
||||||
if r.IsWiki {
|
if r.IsWiki {
|
||||||
prefix = markup.URLJoin(prefix, "wiki", "src")
|
prefix = util.URLJoin(prefix, "wiki", "src")
|
||||||
}
|
}
|
||||||
prefix = strings.Replace(prefix, "/src/", "/raw/", 1)
|
prefix = strings.Replace(prefix, "/src/", "/raw/", 1)
|
||||||
if len(link) > 0 {
|
if len(link) > 0 {
|
||||||
|
@ -110,7 +111,7 @@ func (r *Renderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byt
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
lnk := string(link)
|
lnk := string(link)
|
||||||
lnk = markup.URLJoin(prefix, lnk)
|
lnk = util.URLJoin(prefix, lnk)
|
||||||
lnk = strings.Replace(lnk, " ", "+", -1)
|
lnk = strings.Replace(lnk, " ", "+", -1)
|
||||||
link = []byte(lnk)
|
link = []byte(lnk)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"code.gitea.io/gitea/modules/markup"
|
"code.gitea.io/gitea/modules/markup"
|
||||||
. "code.gitea.io/gitea/modules/markup/markdown"
|
. "code.gitea.io/gitea/modules/markup/markdown"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
@ -33,8 +34,8 @@ func TestRender_StandardLinks(t *testing.T) {
|
||||||
googleRendered := `<p><a href="https://google.com/" rel="nofollow">https://google.com/</a></p>`
|
googleRendered := `<p><a href="https://google.com/" rel="nofollow">https://google.com/</a></p>`
|
||||||
test("<https://google.com/>", googleRendered, googleRendered)
|
test("<https://google.com/>", googleRendered, googleRendered)
|
||||||
|
|
||||||
lnk := markup.URLJoin(AppSubURL, "WikiPage")
|
lnk := util.URLJoin(AppSubURL, "WikiPage")
|
||||||
lnkWiki := markup.URLJoin(AppSubURL, "wiki", "WikiPage")
|
lnkWiki := util.URLJoin(AppSubURL, "wiki", "WikiPage")
|
||||||
test("[WikiPage](WikiPage)",
|
test("[WikiPage](WikiPage)",
|
||||||
`<p><a href="`+lnk+`" rel="nofollow">WikiPage</a></p>`,
|
`<p><a href="`+lnk+`" rel="nofollow">WikiPage</a></p>`,
|
||||||
`<p><a href="`+lnkWiki+`" rel="nofollow">WikiPage</a></p>`)
|
`<p><a href="`+lnkWiki+`" rel="nofollow">WikiPage</a></p>`)
|
||||||
|
@ -43,7 +44,7 @@ func TestRender_StandardLinks(t *testing.T) {
|
||||||
func TestRender_ShortLinks(t *testing.T) {
|
func TestRender_ShortLinks(t *testing.T) {
|
||||||
setting.AppURL = AppURL
|
setting.AppURL = AppURL
|
||||||
setting.AppSubURL = AppSubURL
|
setting.AppSubURL = AppSubURL
|
||||||
tree := markup.URLJoin(AppSubURL, "src", "master")
|
tree := util.URLJoin(AppSubURL, "src", "master")
|
||||||
|
|
||||||
test := func(input, expected, expectedWiki string) {
|
test := func(input, expected, expectedWiki string) {
|
||||||
buffer := RenderString(input, tree, nil)
|
buffer := RenderString(input, tree, nil)
|
||||||
|
@ -52,13 +53,13 @@ func TestRender_ShortLinks(t *testing.T) {
|
||||||
assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(string(buffer)))
|
assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(string(buffer)))
|
||||||
}
|
}
|
||||||
|
|
||||||
rawtree := markup.URLJoin(AppSubURL, "raw", "master")
|
rawtree := util.URLJoin(AppSubURL, "raw", "master")
|
||||||
url := markup.URLJoin(tree, "Link")
|
url := util.URLJoin(tree, "Link")
|
||||||
otherUrl := markup.URLJoin(tree, "OtherLink")
|
otherUrl := util.URLJoin(tree, "OtherLink")
|
||||||
imgurl := markup.URLJoin(rawtree, "Link.jpg")
|
imgurl := util.URLJoin(rawtree, "Link.jpg")
|
||||||
urlWiki := markup.URLJoin(AppSubURL, "wiki", "Link")
|
urlWiki := util.URLJoin(AppSubURL, "wiki", "Link")
|
||||||
otherUrlWiki := markup.URLJoin(AppSubURL, "wiki", "OtherLink")
|
otherUrlWiki := util.URLJoin(AppSubURL, "wiki", "OtherLink")
|
||||||
imgurlWiki := markup.URLJoin(AppSubURL, "wiki", "raw", "Link.jpg")
|
imgurlWiki := util.URLJoin(AppSubURL, "wiki", "raw", "Link.jpg")
|
||||||
favicon := "http://google.com/favicon.ico"
|
favicon := "http://google.com/favicon.ico"
|
||||||
|
|
||||||
test(
|
test(
|
||||||
|
@ -136,7 +137,7 @@ func TestRender_Images(t *testing.T) {
|
||||||
|
|
||||||
url := "../../.images/src/02/train.jpg"
|
url := "../../.images/src/02/train.jpg"
|
||||||
title := "Train"
|
title := "Train"
|
||||||
result := markup.URLJoin(AppSubURL, url)
|
result := util.URLJoin(AppSubURL, url)
|
||||||
|
|
||||||
test(
|
test(
|
||||||
"!["+title+"]("+url+")",
|
"!["+title+"]("+url+")",
|
||||||
|
@ -259,7 +260,7 @@ Here are some links to the most important topics. You can find the full list of
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTotal_RenderWiki(t *testing.T) {
|
func TestTotal_RenderWiki(t *testing.T) {
|
||||||
answers := testAnswers(markup.URLJoin(AppSubURL, "wiki/"), markup.URLJoin(AppSubURL, "wiki", "raw/"))
|
answers := testAnswers(util.URLJoin(AppSubURL, "wiki/"), util.URLJoin(AppSubURL, "wiki", "raw/"))
|
||||||
|
|
||||||
for i := 0; i < len(sameCases); i++ {
|
for i := 0; i < len(sameCases); i++ {
|
||||||
line := RenderWiki([]byte(sameCases[i]), AppSubURL, nil)
|
line := RenderWiki([]byte(sameCases[i]), AppSubURL, nil)
|
||||||
|
@ -286,10 +287,10 @@ func TestTotal_RenderWiki(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTotal_RenderString(t *testing.T) {
|
func TestTotal_RenderString(t *testing.T) {
|
||||||
answers := testAnswers(markup.URLJoin(AppSubURL, "src", "master/"), markup.URLJoin(AppSubURL, "raw", "master/"))
|
answers := testAnswers(util.URLJoin(AppSubURL, "src", "master/"), util.URLJoin(AppSubURL, "raw", "master/"))
|
||||||
|
|
||||||
for i := 0; i < len(sameCases); i++ {
|
for i := 0; i < len(sameCases); i++ {
|
||||||
line := RenderString(sameCases[i], markup.URLJoin(AppSubURL, "src", "master/"), nil)
|
line := RenderString(sameCases[i], util.URLJoin(AppSubURL, "src", "master/"), nil)
|
||||||
assert.Equal(t, answers[i], line)
|
assert.Equal(t, answers[i], line)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/markup"
|
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
@ -30,7 +30,7 @@ func TestRender_StandardLinks(t *testing.T) {
|
||||||
googleRendered := `<p><a href="https://google.com/" title="https://google.com/">https://google.com/</a></p>`
|
googleRendered := `<p><a href="https://google.com/" title="https://google.com/">https://google.com/</a></p>`
|
||||||
test("[[https://google.com/]]", googleRendered)
|
test("[[https://google.com/]]", googleRendered)
|
||||||
|
|
||||||
lnk := markup.URLJoin(AppSubURL, "WikiPage")
|
lnk := util.URLJoin(AppSubURL, "WikiPage")
|
||||||
test("[[WikiPage][WikiPage]]",
|
test("[[WikiPage][WikiPage]]",
|
||||||
`<p><a href="`+lnk+`" title="WikiPage">WikiPage</a></p>`)
|
`<p><a href="`+lnk+`" title="WikiPage">WikiPage</a></p>`)
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ func TestRender_Images(t *testing.T) {
|
||||||
|
|
||||||
url := "../../.images/src/02/train.jpg"
|
url := "../../.images/src/02/train.jpg"
|
||||||
title := "Train"
|
title := "Train"
|
||||||
result := markup.URLJoin(AppSubURL, url)
|
result := util.URLJoin(AppSubURL, url)
|
||||||
|
|
||||||
test(
|
test(
|
||||||
"[[file:"+url+"]["+title+"]]",
|
"[[file:"+url+"]["+title+"]]",
|
||||||
|
|
|
@ -4,6 +4,13 @@
|
||||||
|
|
||||||
package util
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
)
|
||||||
|
|
||||||
// OptionalBool a boolean that can be "null"
|
// OptionalBool a boolean that can be "null"
|
||||||
type OptionalBool byte
|
type OptionalBool byte
|
||||||
|
|
||||||
|
@ -47,6 +54,20 @@ func Max(a, b int) int {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// URLJoin joins url components, like path.Join, but preserving contents
|
||||||
|
func URLJoin(base string, elems ...string) string {
|
||||||
|
u, err := url.Parse(base)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(4, "URLJoin: Invalid base URL %s", base)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
joinArgs := make([]string, 0, len(elems)+1)
|
||||||
|
joinArgs = append(joinArgs, u.Path)
|
||||||
|
joinArgs = append(joinArgs, elems...)
|
||||||
|
u.Path = path.Join(joinArgs...)
|
||||||
|
return u.String()
|
||||||
|
}
|
||||||
|
|
||||||
// Min min of two ints
|
// Min min of two ints
|
||||||
func Min(a, b int) int {
|
func Min(a, b int) int {
|
||||||
if a > b {
|
if a > b {
|
||||||
|
|
36
modules/util/util_test.go
Normal file
36
modules/util/util_test.go
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestURLJoin(t *testing.T) {
|
||||||
|
type test struct {
|
||||||
|
Expected string
|
||||||
|
Base string
|
||||||
|
Elements []string
|
||||||
|
}
|
||||||
|
newTest := func(expected, base string, elements ...string) test {
|
||||||
|
return test{Expected: expected, Base: base, Elements: elements}
|
||||||
|
}
|
||||||
|
for _, test := range []test{
|
||||||
|
newTest("https://try.gitea.io/a/b/c",
|
||||||
|
"https://try.gitea.io", "a/b", "c"),
|
||||||
|
newTest("https://try.gitea.io/a/b/c",
|
||||||
|
"https://try.gitea.io/", "/a/b/", "/c/"),
|
||||||
|
newTest("https://try.gitea.io/a/c",
|
||||||
|
"https://try.gitea.io/", "/a/./b/", "../c/"),
|
||||||
|
newTest("a/b/c",
|
||||||
|
"a", "b/c/"),
|
||||||
|
newTest("a/b/d",
|
||||||
|
"a/", "b/c/", "/../d/"),
|
||||||
|
} {
|
||||||
|
assert.Equal(t, test.Expected, URLJoin(test.Base, test.Elements...))
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,8 @@ import (
|
||||||
|
|
||||||
"code.gitea.io/git"
|
"code.gitea.io/git"
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ToEmail convert models.EmailAddress to api.Email
|
// ToEmail convert models.EmailAddress to api.Email
|
||||||
|
@ -25,35 +27,40 @@ func ToEmail(email *models.EmailAddress) *api.Email {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToBranch convert a commit and branch to an api.Branch
|
// ToBranch convert a commit and branch to an api.Branch
|
||||||
func ToBranch(b *models.Branch, c *git.Commit) *api.Branch {
|
func ToBranch(repo *models.Repository, b *models.Branch, c *git.Commit) *api.Branch {
|
||||||
return &api.Branch{
|
return &api.Branch{
|
||||||
Name: b.Name,
|
Name: b.Name,
|
||||||
Commit: ToCommit(c),
|
Commit: ToCommit(repo, c),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToCommit convert a commit to api.PayloadCommit
|
// ToCommit convert a commit to api.PayloadCommit
|
||||||
func ToCommit(c *git.Commit) *api.PayloadCommit {
|
func ToCommit(repo *models.Repository, c *git.Commit) *api.PayloadCommit {
|
||||||
authorUsername := ""
|
authorUsername := ""
|
||||||
author, err := models.GetUserByEmail(c.Author.Email)
|
if author, err := models.GetUserByEmail(c.Author.Email); err == nil {
|
||||||
if err == nil {
|
|
||||||
authorUsername = author.Name
|
authorUsername = author.Name
|
||||||
|
} else if !models.IsErrUserNotExist(err) {
|
||||||
|
log.Error(4, "GetUserByEmail: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
committerUsername := ""
|
committerUsername := ""
|
||||||
committer, err := models.GetUserByEmail(c.Committer.Email)
|
if committer, err := models.GetUserByEmail(c.Committer.Email); err == nil {
|
||||||
if err == nil {
|
|
||||||
committerUsername = committer.Name
|
committerUsername = committer.Name
|
||||||
|
} else if !models.IsErrUserNotExist(err) {
|
||||||
|
log.Error(4, "GetUserByEmail: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
verif := models.ParseCommitWithSignature(c)
|
verif := models.ParseCommitWithSignature(c)
|
||||||
var signature, payload string
|
var signature, payload string
|
||||||
if c.Signature != nil {
|
if c.Signature != nil {
|
||||||
signature = c.Signature.Signature
|
signature = c.Signature.Signature
|
||||||
payload = c.Signature.Payload
|
payload = c.Signature.Payload
|
||||||
}
|
}
|
||||||
|
|
||||||
return &api.PayloadCommit{
|
return &api.PayloadCommit{
|
||||||
ID: c.ID.String(),
|
ID: c.ID.String(),
|
||||||
Message: c.Message(),
|
Message: c.Message(),
|
||||||
URL: "Not implemented",
|
URL: util.URLJoin(repo.Link(), "commit", c.ID.String()),
|
||||||
Author: &api.PayloadUser{
|
Author: &api.PayloadUser{
|
||||||
Name: c.Author.Name,
|
Name: c.Author.Name,
|
||||||
Email: c.Author.Email,
|
Email: c.Author.Email,
|
||||||
|
|
|
@ -8,9 +8,9 @@ import (
|
||||||
api "code.gitea.io/sdk/gitea"
|
api "code.gitea.io/sdk/gitea"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
"code.gitea.io/gitea/modules/markup"
|
|
||||||
"code.gitea.io/gitea/modules/markup/markdown"
|
"code.gitea.io/gitea/modules/markup/markdown"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Markdown render markdown document to HTML
|
// Markdown render markdown document to HTML
|
||||||
|
@ -45,7 +45,7 @@ func Markdown(ctx *context.APIContext, form api.MarkdownOption) {
|
||||||
switch form.Mode {
|
switch form.Mode {
|
||||||
case "gfm":
|
case "gfm":
|
||||||
md := []byte(form.Text)
|
md := []byte(form.Text)
|
||||||
context := markup.URLJoin(setting.AppURL, form.Context)
|
context := util.URLJoin(setting.AppURL, form.Context)
|
||||||
if form.Wiki {
|
if form.Wiki {
|
||||||
ctx.Write([]byte(markdown.RenderWiki(md, context, nil)))
|
ctx.Write([]byte(markdown.RenderWiki(md, context, nil)))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -9,8 +9,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
"code.gitea.io/gitea/modules/markup"
|
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
api "code.gitea.io/sdk/gitea"
|
api "code.gitea.io/sdk/gitea"
|
||||||
|
|
||||||
"github.com/go-macaron/inject"
|
"github.com/go-macaron/inject"
|
||||||
|
@ -53,7 +53,7 @@ func TestAPI_RenderGFM(t *testing.T) {
|
||||||
Context: Repo,
|
Context: Repo,
|
||||||
Wiki: true,
|
Wiki: true,
|
||||||
}
|
}
|
||||||
requrl, _ := url.Parse(markup.URLJoin(AppURL, "api", "v1", "markdown"))
|
requrl, _ := url.Parse(util.URLJoin(AppURL, "api", "v1", "markdown"))
|
||||||
req := &http.Request{
|
req := &http.Request{
|
||||||
Method: "POST",
|
Method: "POST",
|
||||||
URL: requrl,
|
URL: requrl,
|
||||||
|
@ -147,7 +147,7 @@ func TestAPI_RenderSimple(t *testing.T) {
|
||||||
Text: "",
|
Text: "",
|
||||||
Context: Repo,
|
Context: Repo,
|
||||||
}
|
}
|
||||||
requrl, _ := url.Parse(markup.URLJoin(AppURL, "api", "v1", "markdown"))
|
requrl, _ := url.Parse(util.URLJoin(AppURL, "api", "v1", "markdown"))
|
||||||
req := &http.Request{
|
req := &http.Request{
|
||||||
Method: "POST",
|
Method: "POST",
|
||||||
URL: requrl,
|
URL: requrl,
|
||||||
|
@ -166,7 +166,7 @@ func TestAPI_RenderSimple(t *testing.T) {
|
||||||
func TestAPI_RenderRaw(t *testing.T) {
|
func TestAPI_RenderRaw(t *testing.T) {
|
||||||
setting.AppURL = AppURL
|
setting.AppURL = AppURL
|
||||||
|
|
||||||
requrl, _ := url.Parse(markup.URLJoin(AppURL, "api", "v1", "markdown"))
|
requrl, _ := url.Parse(util.URLJoin(AppURL, "api", "v1", "markdown"))
|
||||||
req := &http.Request{
|
req := &http.Request{
|
||||||
Method: "POST",
|
Method: "POST",
|
||||||
URL: requrl,
|
URL: requrl,
|
||||||
|
|
|
@ -61,7 +61,7 @@ func GetBranch(ctx *context.APIContext) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.JSON(200, convert.ToBranch(branch, c))
|
ctx.JSON(200, convert.ToBranch(ctx.Repo.Repository, branch, c))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListBranches list all the branches of a repository
|
// ListBranches list all the branches of a repository
|
||||||
|
@ -98,7 +98,7 @@ func ListBranches(ctx *context.APIContext) {
|
||||||
ctx.Error(500, "GetCommit", err)
|
ctx.Error(500, "GetCommit", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
apiBranches[i] = convert.ToBranch(branches[i], c)
|
apiBranches[i] = convert.ToBranch(ctx.Repo.Repository, branches[i], c)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.JSON(200, &apiBranches)
|
ctx.JSON(200, &apiBranches)
|
||||||
|
|
Loading…
Reference in a new issue