Fixes #29404 Use relative links for - commits - mentions - issues --------- Co-authored-by: silverwind <me@silverwind.io>tags/v1.22.0-rc0
@@ -609,7 +609,7 @@ func mentionProcessor(ctx *RenderContext, node *html.Node) { | |||
if ok && strings.Contains(mention, "/") { | |||
mentionOrgAndTeam := strings.Split(mention, "/") | |||
if mentionOrgAndTeam[0][1:] == ctx.Metas["org"] && strings.Contains(teams, ","+strings.ToLower(mentionOrgAndTeam[1])+",") { | |||
replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(setting.AppURL, "org", ctx.Metas["org"], "teams", mentionOrgAndTeam[1]), mention, "mention")) | |||
replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(ctx.Links.Prefix(), "org", ctx.Metas["org"], "teams", mentionOrgAndTeam[1]), mention, "mention")) | |||
node = node.NextSibling.NextSibling | |||
start = 0 | |||
continue | |||
@@ -620,7 +620,7 @@ func mentionProcessor(ctx *RenderContext, node *html.Node) { | |||
mentionedUsername := mention[1:] | |||
if DefaultProcessorHelper.IsUsernameMentionable != nil && DefaultProcessorHelper.IsUsernameMentionable(ctx.Ctx, mentionedUsername) { | |||
replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(setting.AppURL, mentionedUsername), mention, "mention")) | |||
replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(ctx.Links.Prefix(), mentionedUsername), mention, "mention")) | |||
node = node.NextSibling.NextSibling | |||
} else { | |||
node = node.NextSibling | |||
@@ -898,9 +898,9 @@ func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) { | |||
path = "pulls" | |||
} | |||
if ref.Owner == "" { | |||
link = createLink(util.URLJoin(setting.AppURL, ctx.Metas["user"], ctx.Metas["repo"], path, ref.Issue), reftext, "ref-issue") | |||
link = createLink(util.URLJoin(ctx.Links.Prefix(), ctx.Metas["user"], ctx.Metas["repo"], path, ref.Issue), reftext, "ref-issue") | |||
} else { | |||
link = createLink(util.URLJoin(setting.AppURL, ref.Owner, ref.Name, path, ref.Issue), reftext, "ref-issue") | |||
link = createLink(util.URLJoin(ctx.Links.Prefix(), ref.Owner, ref.Name, path, ref.Issue), reftext, "ref-issue") | |||
} | |||
} | |||
@@ -939,7 +939,7 @@ func commitCrossReferencePatternProcessor(ctx *RenderContext, node *html.Node) { | |||
} | |||
reftext := ref.Owner + "/" + ref.Name + "@" + base.ShortSha(ref.CommitSha) | |||
link := createLink(util.URLJoin(setting.AppSubURL, ref.Owner, ref.Name, "commit", ref.CommitSha), reftext, "commit") | |||
link := createLink(util.URLJoin(ctx.Links.Prefix(), ref.Owner, ref.Name, "commit", ref.CommitSha), reftext, "commit") | |||
replaceContent(node, ref.RefLocation.Start, ref.RefLocation.End, link) | |||
node = node.NextSibling.NextSibling | |||
@@ -1166,7 +1166,7 @@ func hashCurrentPatternProcessor(ctx *RenderContext, node *html.Node) { | |||
continue | |||
} | |||
link := util.URLJoin(setting.AppURL, ctx.Metas["user"], ctx.Metas["repo"], "commit", hash) | |||
link := util.URLJoin(ctx.Links.Prefix(), ctx.Metas["user"], ctx.Metas["repo"], "commit", hash) | |||
replaceContent(node, m[2], m[3], createCodeLink(link, base.ShortSha(hash), "commit")) | |||
start = 0 | |||
node = node.NextSibling.NextSibling |
@@ -287,6 +287,7 @@ func TestRender_IssueIndexPattern_Document(t *testing.T) { | |||
} | |||
func testRenderIssueIndexPattern(t *testing.T, input, expected string, ctx *RenderContext) { | |||
ctx.Links.AbsolutePrefix = true | |||
if ctx.Links.Base == "" { | |||
ctx.Links.Base = TestRepoURL | |||
} |
@@ -43,7 +43,8 @@ func TestRender_Commits(t *testing.T) { | |||
Ctx: git.DefaultContext, | |||
RelativePath: ".md", | |||
Links: markup.Links{ | |||
Base: markup.TestRepoURL, | |||
AbsolutePrefix: true, | |||
Base: markup.TestRepoURL, | |||
}, | |||
Metas: localMetas, | |||
}, input) | |||
@@ -96,7 +97,8 @@ func TestRender_CrossReferences(t *testing.T) { | |||
Ctx: git.DefaultContext, | |||
RelativePath: "a.md", | |||
Links: markup.Links{ | |||
Base: setting.AppSubURL, | |||
AbsolutePrefix: true, | |||
Base: setting.AppSubURL, | |||
}, | |||
Metas: localMetas, | |||
}, input) | |||
@@ -588,7 +590,8 @@ func TestPostProcess_RenderDocument(t *testing.T) { | |||
err := markup.PostProcess(&markup.RenderContext{ | |||
Ctx: git.DefaultContext, | |||
Links: markup.Links{ | |||
Base: "https://example.com", | |||
AbsolutePrefix: true, | |||
Base: "https://example.com", | |||
}, | |||
Metas: localMetas, | |||
}, strings.NewReader(input), &res) |
@@ -130,11 +130,11 @@ func testAnswers(baseURLContent, baseURLImages string) []string { | |||
<li><a href="` + baseURLContent + `/Links" rel="nofollow">Links, Language bindings, Engine bindings</a></li> | |||
<li><a href="` + baseURLContent + `/Tips" rel="nofollow">Tips</a></li> | |||
</ul> | |||
<p>See commit <a href="http://localhost:3000/gogits/gogs/commit/65f1bf27bc" rel="nofollow"><code>65f1bf27bc</code></a></p> | |||
<p>See commit <a href="/gogits/gogs/commit/65f1bf27bc" rel="nofollow"><code>65f1bf27bc</code></a></p> | |||
<p>Ideas and codes</p> | |||
<ul> | |||
<li>Bezier widget (by <a href="` + AppURL + `r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="http://localhost:3000/ocornut/imgui/issues/786" class="ref-issue" rel="nofollow">ocornut/imgui#786</a></li> | |||
<li>Bezier widget (by <a href="` + AppURL + `r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="http://localhost:3000/gogits/gogs/issues/786" class="ref-issue" rel="nofollow">#786</a></li> | |||
<li>Bezier widget (by <a href="/r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="http://localhost:3000/ocornut/imgui/issues/786" class="ref-issue" rel="nofollow">ocornut/imgui#786</a></li> | |||
<li>Bezier widget (by <a href="/r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="http://localhost:3000/gogits/gogs/issues/786" class="ref-issue" rel="nofollow">#786</a></li> | |||
<li>Node graph editors <a href="https://github.com/ocornut/imgui/issues/306" rel="nofollow">https://github.com/ocornut/imgui/issues/306</a></li> | |||
<li><a href="` + baseURLContent + `/memory_editor_example" rel="nofollow">Memory Editor</a></li> | |||
<li><a href="` + baseURLContent + `/plot_var_example" rel="nofollow">Plot var helper</a></li> |
@@ -82,9 +82,17 @@ type RenderContext struct { | |||
} | |||
type Links struct { | |||
Base string | |||
BranchPath string | |||
TreePath string | |||
AbsolutePrefix bool | |||
Base string | |||
BranchPath string | |||
TreePath string | |||
} | |||
func (l *Links) Prefix() string { | |||
if l.AbsolutePrefix { | |||
return setting.AppURL | |||
} | |||
return setting.AppSubURL | |||
} | |||
func (l *Links) HasBranchInfo() bool { |
@@ -117,21 +117,21 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a582 | |||
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit | |||
<span class="emoji" aria-label="thumbs up">👍</span> | |||
<a href="mailto:mail@domain.com" class="mailto">mail@domain.com</a> | |||
<a href="http://localhost:3000/mention-user" class="mention">@mention-user</a> test | |||
<a href="http://localhost:3000/user13/repo11/issues/123" class="ref-issue">#123</a> | |||
<a href="/mention-user" class="mention">@mention-user</a> test | |||
<a href="/user13/repo11/issues/123" class="ref-issue">#123</a> | |||
space` | |||
assert.EqualValues(t, expected, RenderCommitBody(context.Background(), testInput, testMetas)) | |||
} | |||
func TestRenderCommitMessage(t *testing.T) { | |||
expected := `space <a href="http://localhost:3000/mention-user" class="mention">@mention-user</a> ` | |||
expected := `space <a href="/mention-user" class="mention">@mention-user</a> ` | |||
assert.EqualValues(t, expected, RenderCommitMessage(context.Background(), testInput, testMetas)) | |||
} | |||
func TestRenderCommitMessageLinkSubject(t *testing.T) { | |||
expected := `<a href="https://example.com/link" class="default-link muted">space </a><a href="http://localhost:3000/mention-user" class="mention">@mention-user</a>` | |||
expected := `<a href="https://example.com/link" class="default-link muted">space </a><a href="/mention-user" class="mention">@mention-user</a>` | |||
assert.EqualValues(t, expected, RenderCommitMessageLinkSubject(context.Background(), testInput, "https://example.com/link", testMetas)) | |||
} | |||
@@ -155,14 +155,14 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit | |||
<span class="emoji" aria-label="thumbs up">👍</span> | |||
mail@domain.com | |||
@mention-user test | |||
<a href="http://localhost:3000/user13/repo11/issues/123" class="ref-issue">#123</a> | |||
<a href="/user13/repo11/issues/123" class="ref-issue">#123</a> | |||
space | |||
` | |||
assert.EqualValues(t, expected, RenderIssueTitle(context.Background(), testInput, testMetas)) | |||
} | |||
func TestRenderMarkdownToHtml(t *testing.T) { | |||
expected := `<p>space <a href="http://localhost:3000/mention-user" rel="nofollow">@mention-user</a><br/> | |||
expected := `<p>space <a href="/mention-user" rel="nofollow">@mention-user</a><br/> | |||
/just/a/path.bin | |||
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a> | |||
<a href="/file.bin" rel="nofollow">local link</a> | |||
@@ -179,7 +179,7 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a582 | |||
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit | |||
<span class="emoji" aria-label="thumbs up">👍</span> | |||
<a href="mailto:mail@domain.com" rel="nofollow">mail@domain.com</a> | |||
<a href="http://localhost:3000/mention-user" rel="nofollow">@mention-user</a> test | |||
<a href="/mention-user" rel="nofollow">@mention-user</a> test | |||
#123 | |||
space</p> | |||
` |
@@ -34,7 +34,8 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPr | |||
if err := markdown.RenderRaw(&markup.RenderContext{ | |||
Ctx: ctx, | |||
Links: markup.Links{ | |||
Base: urlPrefix, | |||
AbsolutePrefix: true, | |||
Base: urlPrefix, | |||
}, | |||
}, strings.NewReader(text), ctx.Resp); err != nil { | |||
ctx.Error(http.StatusInternalServerError, err.Error()) | |||
@@ -79,7 +80,8 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPr | |||
if err := markup.Render(&markup.RenderContext{ | |||
Ctx: ctx, | |||
Links: markup.Links{ | |||
Base: urlPrefix, | |||
AbsolutePrefix: true, | |||
Base: urlPrefix, | |||
}, | |||
Metas: meta, | |||
IsWiki: wiki, |
@@ -222,7 +222,8 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient | |||
body, err := markdown.RenderString(&markup.RenderContext{ | |||
Ctx: ctx, | |||
Links: markup.Links{ | |||
Base: ctx.Issue.Repo.HTMLURL(), | |||
AbsolutePrefix: true, | |||
Base: ctx.Issue.Repo.HTMLURL(), | |||
}, | |||
Metas: ctx.Issue.Repo.ComposeMetas(ctx), | |||
}, ctx.Content) |
@@ -8,6 +8,8 @@ import ( | |||
"context" | |||
"fmt" | |||
"html/template" | |||
"io" | |||
"mime/quotedprintable" | |||
"regexp" | |||
"strings" | |||
"testing" | |||
@@ -19,6 +21,7 @@ import ( | |||
repo_model "code.gitea.io/gitea/models/repo" | |||
"code.gitea.io/gitea/models/unittest" | |||
user_model "code.gitea.io/gitea/models/user" | |||
"code.gitea.io/gitea/modules/markup" | |||
"code.gitea.io/gitea/modules/setting" | |||
"github.com/stretchr/testify/assert" | |||
@@ -67,6 +70,12 @@ func prepareMailerTest(t *testing.T) (doer *user_model.User, repo *repo_model.Re | |||
func TestComposeIssueCommentMessage(t *testing.T) { | |||
doer, _, issue, comment := prepareMailerTest(t) | |||
markup.Init(&markup.ProcessorHelper{ | |||
IsUsernameMentionable: func(ctx context.Context, username string) bool { | |||
return username == doer.Name | |||
}, | |||
}) | |||
setting.IncomingEmail.Enabled = true | |||
defer func() { setting.IncomingEmail.Enabled = false }() | |||
@@ -77,7 +86,8 @@ func TestComposeIssueCommentMessage(t *testing.T) { | |||
msgs, err := composeIssueCommentMessages(&mailCommentContext{ | |||
Context: context.TODO(), // TODO: use a correct context | |||
Issue: issue, Doer: doer, ActionType: activities_model.ActionCommentIssue, | |||
Content: "test body", Comment: comment, | |||
Content: fmt.Sprintf("test @%s %s#%d body", doer.Name, issue.Repo.FullName(), issue.Index), | |||
Comment: comment, | |||
}, "en-US", recipients, false, "issue comment") | |||
assert.NoError(t, err) | |||
assert.Len(t, msgs, 2) | |||
@@ -96,6 +106,20 @@ func TestComposeIssueCommentMessage(t *testing.T) { | |||
assert.Equal(t, "<user2/repo1/issues/1/comment/2@localhost>", gomailMsg.GetHeader("Message-ID")[0], "Message-ID header doesn't match") | |||
assert.Equal(t, "<mailto:"+replyTo+">", gomailMsg.GetHeader("List-Post")[0]) | |||
assert.Len(t, gomailMsg.GetHeader("List-Unsubscribe"), 2) // url + mailto | |||
var buf bytes.Buffer | |||
gomailMsg.WriteTo(&buf) | |||
b, err := io.ReadAll(quotedprintable.NewReader(&buf)) | |||
assert.NoError(t, err) | |||
// text/plain | |||
assert.Contains(t, string(b), fmt.Sprintf(`( %s )`, doer.HTMLURL())) | |||
assert.Contains(t, string(b), fmt.Sprintf(`( %s )`, issue.HTMLURL())) | |||
// text/html | |||
assert.Contains(t, string(b), fmt.Sprintf(`href="%s"`, doer.HTMLURL())) | |||
assert.Contains(t, string(b), fmt.Sprintf(`href="%s"`, issue.HTMLURL())) | |||
} | |||
func TestComposeIssueMessage(t *testing.T) { |