// Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT package templates import ( "context" "html/template" "testing" "forgejo.org/models/db" issues_model "forgejo.org/models/issues" "forgejo.org/models/unittest" user_model "forgejo.org/models/user" "forgejo.org/modules/setting" "forgejo.org/modules/test" "forgejo.org/modules/translation" "github.com/stretchr/testify/assert" ) const testInput = ` space @mention-user /just/a/path.bin https://example.com/file.bin [local link](file.bin) [remote link](https://example.com) [[local link|file.bin]] [[remote link|https://example.com]] ![local image](image.jpg) ![remote image](https://example.com/image.jpg) [[local image|image.jpg]] [[remote link|https://example.com/image.jpg]] https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit :+1: mail@domain.com @mention-user test #123 space ` + "`code :+1: #123 code`\n" var testMetas = map[string]string{ "user": "user13", "repo": "repo11", "repoPath": "../../tests/gitea-repositories-meta/user13/repo11.git/", "mode": "comment", } func TestApostrophesInMentions(t *testing.T) { rendered := RenderMarkdownToHtml(t.Context(), "@mention-user's comment") assert.Equal(t, template.HTML("

@mention-user's comment

\n"), rendered) } func TestNonExistantUserMention(t *testing.T) { rendered := RenderMarkdownToHtml(t.Context(), "@ThisUserDoesNotExist @mention-user") assert.Equal(t, template.HTML("

@ThisUserDoesNotExist @mention-user

\n"), rendered) } func TestRenderCommitBody(t *testing.T) { type args struct { ctx context.Context msg string metas map[string]string } tests := []struct { name string args args want template.HTML }{ { name: "multiple lines", args: args{ ctx: t.Context(), msg: "first line\nsecond line", }, want: "second line", }, { name: "multiple lines with leading newlines", args: args{ ctx: t.Context(), msg: "\n\n\n\nfirst line\nsecond line", }, want: "second line", }, { name: "multiple lines with trailing newlines", args: args{ ctx: t.Context(), msg: "first line\nsecond line\n\n\n", }, want: "second line", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { assert.Equalf(t, tt.want, RenderCommitBody(tt.args.ctx, tt.args.msg, tt.args.metas), "RenderCommitBody(%v, %v, %v)", tt.args.ctx, tt.args.msg, tt.args.metas) }) } expected := `/just/a/path.bin https://example.com/file.bin [local link](file.bin) [remote link](https://example.com) [[local link|file.bin]] [[remote link|https://example.com]] ![local image](image.jpg) ![remote image](https://example.com/image.jpg) [[local image|image.jpg]] [[remote link|https://example.com/image.jpg]] 88fc37a3c0...12fc37a3c0 (hash) com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare 88fc37a3c0 com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit 👍 mail@domain.com @mention-user test #123 space ` + "`code 👍 #123 code`" assert.EqualValues(t, expected, RenderCommitBody(t.Context(), testInput, testMetas)) } func TestRenderCommitMessage(t *testing.T) { expected := `space @mention-user ` assert.EqualValues(t, expected, RenderCommitMessage(t.Context(), testInput, testMetas)) } func TestRenderCommitMessageLinkSubject(t *testing.T) { expected := `space @mention-user` assert.EqualValues(t, expected, RenderCommitMessageLinkSubject(t.Context(), testInput, "https://example.com/link", testMetas)) } func TestRenderIssueTitle(t *testing.T) { expected := ` space @mention-user /just/a/path.bin https://example.com/file.bin [local link](file.bin) [remote link](https://example.com) [[local link|file.bin]] [[remote link|https://example.com]] ![local image](image.jpg) ![remote image](https://example.com/image.jpg) [[local image|image.jpg]] [[remote link|https://example.com/image.jpg]] https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit 👍 mail@domain.com @mention-user test #123 space code :+1: #123 code ` assert.EqualValues(t, expected, RenderIssueTitle(t.Context(), testInput, testMetas)) } func TestRenderRefIssueTitle(t *testing.T) { expected := ` space @mention-user /just/a/path.bin https://example.com/file.bin [local link](file.bin) [remote link](https://example.com) [[local link|file.bin]] [[remote link|https://example.com]] ![local image](image.jpg) ![remote image](https://example.com/image.jpg) [[local image|image.jpg]] [[remote link|https://example.com/image.jpg]] https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit 👍 mail@domain.com @mention-user test #123 space code :+1: #123 code ` assert.EqualValues(t, expected, RenderRefIssueTitle(t.Context(), testInput)) } func TestRenderMarkdownToHtml(t *testing.T) { expected := `

space @mention-user
/just/a/path.bin https://example.com/file.bin local link remote link local link remote link local image remote image 88fc37a3c0...12fc37a3c0 (hash) com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare 88fc37a3c0 com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit 👍 mail@domain.com @mention-user test #123 space code :+1: #123 code

` assert.EqualValues(t, expected, RenderMarkdownToHtml(t.Context(), testInput)) } func TestRenderLabels(t *testing.T) { unittest.PrepareTestEnv(t) tr := &translation.MockLocale{} label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}) labelScoped := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 7}) labelMalicious := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 11}) labelArchived := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 12}) rendered := RenderLabels(db.DefaultContext, tr, []*issues_model.Label{label}, "user2/repo1", false) assert.Contains(t, rendered, "user2/repo1/issues?labels=1") assert.Contains(t, rendered, ">label1<") assert.Contains(t, rendered, "title='First label'") rendered = RenderLabels(db.DefaultContext, tr, []*issues_model.Label{label}, "user2/repo1", true) assert.Contains(t, rendered, "user2/repo1/pulls?labels=1") assert.Contains(t, rendered, ">label1<") rendered = RenderLabels(db.DefaultContext, tr, []*issues_model.Label{labelScoped}, "user2/repo1", false) assert.Contains(t, rendered, "user2/repo1/issues?labels=7") assert.Contains(t, rendered, ">scope<") assert.Contains(t, rendered, ">label1<") rendered = RenderLabels(db.DefaultContext, tr, []*issues_model.Label{labelMalicious}, "user2/repo1", false) assert.Contains(t, rendered, "user2/repo1/issues?labels=11") assert.Contains(t, rendered, "> <script>malicious</script> <") assert.Contains(t, rendered, ">'?&<") assert.Contains(t, rendered, "title='Malicious label ' <script>malicious</script>'") rendered = RenderLabels(db.DefaultContext, tr, []*issues_model.Label{labelArchived}, "user2/repo1", false) assert.Contains(t, rendered, "user2/repo1/issues?labels=12") assert.Contains(t, rendered, ">archived label<><") assert.Contains(t, rendered, "title='repo.issues.archived_label_description'") } func TestRenderUser(t *testing.T) { unittest.PrepareTestEnv(t) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) ghost := user_model.NewGhostUser() assert.Contains(t, RenderUser(db.DefaultContext, *user), "user2") assert.Contains(t, RenderUser(db.DefaultContext, *org), "org3") assert.Contains(t, RenderUser(db.DefaultContext, *ghost), "Ghost") defer test.MockVariableValue(&setting.UI.DefaultShowFullName, true)() assert.Contains(t, RenderUser(db.DefaultContext, *user), "< U<se>r Tw<o > ><") assert.Contains(t, RenderUser(db.DefaultContext, *org), "<<<< >> >> > >> > >>> >>") assert.Contains(t, RenderUser(db.DefaultContext, *ghost), "Ghost") }