test: consolidate Go tests (#39962)

Consolidate all Go tests. Coverage is identical to before. Go tests are
around 5% faster while being 7% smaller. No non-test code is touched.
This commit is contained in:
silverwind authored and GitHub committed 2026-10-24 13:48:19 +00:00
1 parent ce7364e215
commit 8abda62312
388 files changed
+18410 -29561

No files matched your search

+12 -21
View File
@@ -21,27 +21,18 @@ func TestCamoHandleLink(t *testing.T) {
setting.Camo.ServerURL = "https://image.proxy"
setting.Camo.HMACKey = "geheim"
dataURL := "data:image/png;base64,i//V"
assert.Equal(t, dataURL, camoHandleLink(dataURL))
assert.Equal(t,
"https://gitea.com/img.jpg",
camoHandleLink("https://gitea.com/img.jpg"))
assert.Equal(t,
"https://testimages.org/img.jpg",
camoHandleLink("https://testimages.org/img.jpg"))
assert.Equal(t,
"https://image.proxy/eivin43gJwGVIjR9MiYYtFIk0mw/aHR0cDovL3Rlc3RpbWFnZXMub3JnL2ltZy5qcGc",
camoHandleLink("http://testimages.org/img.jpg"))
test := func(expectedHTTPS string) {
assert.Equal(t, dataURL, camoHandleLink(dataURL))
assert.Equal(t,
"https://gitea.com/img.jpg",
camoHandleLink("https://gitea.com/img.jpg"))
assert.Equal(t, expectedHTTPS, camoHandleLink("https://testimages.org/img.jpg"))
assert.Equal(t,
"https://image.proxy/eivin43gJwGVIjR9MiYYtFIk0mw/aHR0cDovL3Rlc3RpbWFnZXMub3JnL2ltZy5qcGc",
camoHandleLink("http://testimages.org/img.jpg"))
}
test("https://testimages.org/img.jpg")
setting.Camo.Always = true
assert.Equal(t, dataURL, camoHandleLink(dataURL))
assert.Equal(t,
"https://gitea.com/img.jpg",
camoHandleLink("https://gitea.com/img.jpg"))
assert.Equal(t,
"https://image.proxy/tkdlvmqpbIr7SjONfHNgEU622y0/aHR0cHM6Ly90ZXN0aW1hZ2VzLm9yZy9pbWcuanBn",
camoHandleLink("https://testimages.org/img.jpg"))
assert.Equal(t,
"https://image.proxy/eivin43gJwGVIjR9MiYYtFIk0mw/aHR0cDovL3Rlc3RpbWFnZXMub3JnL2ltZy5qcGc",
camoHandleLink("http://testimages.org/img.jpg"))
test("https://image.proxy/tkdlvmqpbIr7SjONfHNgEU622y0/aHR0cHM6Ly90ZXN0aW1hZ2VzLm9yZy9pbWcuanBn")
}
-10
View File
@@ -85,7 +85,6 @@ func TestRender_IssueIndexPattern(t *testing.T) {
test("#abcd")
test("test#1234")
test("#1234test")
test("#abcd")
test("test!1234")
test("!1234test")
test(" test !1234test")
@@ -257,16 +256,7 @@ func TestRender_IssueIndexPattern_NoShortPattern(t *testing.T) {
testRenderIssueIndexPattern(t, "#1", "#1", NewTestRenderContext(metas))
testRenderIssueIndexPattern(t, "#1312", "#1312", NewTestRenderContext(metas))
testRenderIssueIndexPattern(t, "!1", "!1", NewTestRenderContext(metas))
}
func TestRender_PostProcessIssueTitle(t *testing.T) {
setting.AppURL = TestAppURL
metas := map[string]string{
"format": "https://someurl.com/{user}/{repo}/{index}",
"user": "someUser",
"repo": "someRepo",
"style": IssueNameStyleNumeric,
}
actual := PostProcessIssueTitle(NewTestRenderContext(metas), "#1")
assert.Equal(t, template.HTML("#1"), actual)
}
+20 -35
View File
@@ -37,43 +37,24 @@ func TestRender_IssueList(t *testing.T) {
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(out)))
}
t.Run("NormalIssueRef", func(t *testing.T) {
test(
"#12345",
for _, tc := range []struct {
name, input, expected string
}{
{
"NormalIssueRef", "#12345",
`<p><a href="/test-user/test-repo/issues/12345" class="ref-issue" rel="nofollow">#12345</a></p>`,
)
})
t.Run("ListIssueRef", func(t *testing.T) {
test(
"* #12345",
`<ul>
},
{"ListIssueRef", "* #12345", `<ul>
<li><div>issue #12345</div></li>
</ul>`,
)
})
t.Run("ListIssueRefNormal", func(t *testing.T) {
test(
"* foo #12345 bar",
`<ul>
</ul>`},
{"ListIssueRefNormal", "* foo #12345 bar", `<ul>
<li>foo <a href="/test-user/test-repo/issues/12345" class="ref-issue" rel="nofollow">#12345</a> bar</li>
</ul>`,
)
})
t.Run("ListTodoIssueRef", func(t *testing.T) {
test(
"* [ ] #12345",
`<ul>
</ul>`},
{"ListTodoIssueRef", "* [ ] #12345", `<ul>
<li class="task-list-item"><input type="checkbox" disabled="" data-source-position="2"/><div>issue #12345</div></li>
</ul>`,
)
})
t.Run("IssueFootnote", func(t *testing.T) {
test(
"foo[^1][^2]\n\n[^1]: bar\n[^2]: baz",
</ul>`},
{
"IssueFootnote", "foo[^1][^2]\n\n[^1]: bar\n[^2]: baz",
`<p>foo<sup id="fnref:user-content-1-12345"><a href="#fn:user-content-1-12345" rel="nofollow">1 </a></sup><sup id="fnref:user-content-2-12345"><a href="#fn:user-content-2-12345" rel="nofollow">2 </a></sup></p>
<div>
<hr/>
@@ -86,6 +67,10 @@ func TestRender_IssueList(t *testing.T) {
</li>
</ol>
</div>`,
)
})
},
} {
t.Run(tc.name, func(_t *testing.T) {
test(tc.input, tc.expected)
})
}
}
+49 -64
View File
@@ -11,94 +11,79 @@ import (
)
func TestProcessNodeAttrID_HTMLHeadingWithoutID(t *testing.T) {
// Test that HTML headings without id get an auto-generated id from their text content
// when EnableHeadingIDGeneration is true (for repo files and wiki pages)
testCases := []struct {
name string
input string
expected string
name string
generateHeadingID bool
input, expected string
}{
// Test that HTML headings without id get an auto-generated id from their text content
// when EnableHeadingIDGeneration is true (for repo files and wiki pages)
{
name: "h1 without id",
input: `<h1>Heading without ID</h1>`,
expected: `<h1 id="user-content-heading-without-id">Heading without ID</h1>`,
"h1 without id", true,
`<h1>Heading without ID</h1>`,
`<h1 id="user-content-heading-without-id">Heading without ID</h1>`,
},
{
name: "h2 without id",
input: `<h2>Another Heading</h2>`,
expected: `<h2 id="user-content-another-heading">Another Heading</h2>`,
"h2 without id", true,
`<h2>Another Heading</h2>`,
`<h2 id="user-content-another-heading">Another Heading</h2>`,
},
{
name: "h3 without id",
input: `<h3>Third Level</h3>`,
expected: `<h3 id="user-content-third-level">Third Level</h3>`,
"h3 without id", true,
`<h3>Third Level</h3>`,
`<h3 id="user-content-third-level">Third Level</h3>`,
},
{
name: "h1 with existing id should keep it",
input: `<h1 id="my-custom-id">Heading with ID</h1>`,
expected: `<h1 id="user-content-my-custom-id">Heading with ID</h1>`,
"h1 with existing id should keep it", true,
`<h1 id="my-custom-id">Heading with ID</h1>`,
`<h1 id="user-content-my-custom-id">Heading with ID</h1>`,
},
{
name: "h1 with user-content prefix should not double prefix",
input: `<h1 id="user-content-already-prefixed">Already Prefixed</h1>`,
expected: `<h1 id="user-content-already-prefixed">Already Prefixed</h1>`,
"h1 with user-content prefix should not double prefix", true,
`<h1 id="user-content-already-prefixed">Already Prefixed</h1>`,
`<h1 id="user-content-already-prefixed">Already Prefixed</h1>`,
},
{
name: "heading with special characters",
input: `<h1>What is Wine Staging?</h1>`,
expected: `<h1 id="user-content-what-is-wine-staging">What is Wine Staging?</h1>`,
"heading with special characters", true,
`<h1>What is Wine Staging?</h1>`,
`<h1 id="user-content-what-is-wine-staging">What is Wine Staging?</h1>`,
},
{
name: "heading with nested elements",
input: `<h2><strong>Bold</strong> and <em>Italic</em></h2>`,
expected: `<h2 id="user-content-bold-and-italic"><strong>Bold</strong> and <em>Italic</em></h2>`,
"heading with nested elements", true,
`<h2><strong>Bold</strong> and <em>Italic</em></h2>`,
`<h2 id="user-content-bold-and-italic"><strong>Bold</strong> and <em>Italic</em></h2>`,
},
// Test that HTML headings in comment-like contexts (issue comments)
// do NOT get auto-generated IDs to avoid duplicate IDs on pages with multiple documents.
// This is controlled by EnableHeadingIDGeneration which defaults to false.
// Default context without EnableHeadingIDGeneration (simulates comment rendering)
{
"h1 without id in comment context", false,
`<h1>Heading without ID</h1>`,
`<h1>Heading without ID</h1>`,
},
{
"h2 without id in comment context", false,
`<h2>Another Heading</h2>`,
`<h2>Another Heading</h2>`,
},
{
"h1 with existing id should still be prefixed", false,
`<h1 id="my-custom-id">Heading with ID</h1>`,
`<h1 id="user-content-my-custom-id">Heading with ID</h1>`,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
var result strings.Builder
ctx := NewTestRenderContext().WithEnableHeadingIDGeneration(true)
ctx := NewTestRenderContext()
if tc.generateHeadingID {
ctx.WithEnableHeadingIDGeneration(true)
}
err := PostProcessDefault(ctx, strings.NewReader(tc.input), &result)
assert.NoError(t, err)
assert.Equal(t, tc.expected, strings.TrimSpace(result.String()))
})
}
}
func TestProcessNodeAttrID_SkipHeadingIDForComments(t *testing.T) {
// Test that HTML headings in comment-like contexts (issue comments)
// do NOT get auto-generated IDs to avoid duplicate IDs on pages with multiple documents.
// This is controlled by EnableHeadingIDGeneration which defaults to false.
testCases := []struct {
name string
input string
expected string
}{
{
name: "h1 without id in comment context",
input: `<h1>Heading without ID</h1>`,
expected: `<h1>Heading without ID</h1>`,
},
{
name: "h2 without id in comment context",
input: `<h2>Another Heading</h2>`,
expected: `<h2>Another Heading</h2>`,
},
{
name: "h1 with existing id should still be prefixed",
input: `<h1 id="my-custom-id">Heading with ID</h1>`,
expected: `<h1 id="user-content-my-custom-id">Heading with ID</h1>`,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
var result strings.Builder
// Default context without EnableHeadingIDGeneration (simulates comment rendering)
err := PostProcessDefault(NewTestRenderContext(), strings.NewReader(tc.input), &result)
assert.NoError(t, err)
assert.Equal(t, tc.expected, strings.TrimSpace(result.String()))
})
}
}
+120 -266
View File
@@ -145,90 +145,42 @@ func TestRender_links(t *testing.T) {
setting.Markdown.CustomURLSchemes = []string{"ftp", "magnet"}
common.InitLinkURLSchemes(setting.Markdown.CustomURLSchemes)
// Text that should be turned into URL
test(
"https://www.example.com",
`<p><a href="https://www.example.com" rel="nofollow">https://www.example.com</a></p>`)
test(
"http://www.example.com",
`<p><a href="http://www.example.com" rel="nofollow">http://www.example.com</a></p>`)
test(
"https://example.com",
`<p><a href="https://example.com" rel="nofollow">https://example.com</a></p>`)
test(
"http://example.com",
`<p><a href="http://example.com" rel="nofollow">http://example.com</a></p>`)
test(
"http://foo.com/blah_blah",
`<p><a href="http://foo.com/blah_blah" rel="nofollow">http://foo.com/blah_blah</a></p>`)
test(
"http://foo.com/blah_blah/",
`<p><a href="http://foo.com/blah_blah/" rel="nofollow">http://foo.com/blah_blah/</a></p>`)
test(
"http://www.example.com/wpstyle/?p=364",
`<p><a href="http://www.example.com/wpstyle/?p=364" rel="nofollow">http://www.example.com/wpstyle/?p=364</a></p>`)
test(
"https://www.example.com/foo/?bar=baz&inga=42&quux",
`<p><a href="https://www.example.com/foo/?bar=baz&amp;inga=42&amp;quux" rel="nofollow">https://www.example.com/foo/?bar=baz&amp;inga=42&amp;quux</a></p>`)
test(
"http://142.42.1.1/",
`<p><a href="http://142.42.1.1/" rel="nofollow">http://142.42.1.1/</a></p>`)
test(
"https://github.com/go-gitea/gitea/?p=aaa/bbb.html#ccc-ddd",
`<p><a href="https://github.com/go-gitea/gitea/?p=aaa/bbb.html#ccc-ddd" rel="nofollow">https://github.com/go-gitea/gitea/?p=aaa/bbb.html#ccc-ddd</a></p>`)
test(
"https://en.wikipedia.org/wiki/URL_(disambiguation)",
`<p><a href="https://en.wikipedia.org/wiki/URL_(disambiguation)" rel="nofollow">https://en.wikipedia.org/wiki/URL_(disambiguation)</a></p>`)
test(
"https://foo_bar.example.com/",
`<p><a href="https://foo_bar.example.com/" rel="nofollow">https://foo_bar.example.com/</a></p>`)
test(
"https://stackoverflow.com/questions/2896191/what-is-go-used-fore",
`<p><a href="https://stackoverflow.com/questions/2896191/what-is-go-used-fore" rel="nofollow">https://stackoverflow.com/questions/2896191/what-is-go-used-fore</a></p>`)
test(
"https://username:password@gitea.com",
`<p><a href="https://username:password@gitea.com" rel="nofollow">https://username:password@gitea.com</a></p>`)
test(
"ftp://gitea.com/file.txt",
`<p><a href="ftp://gitea.com/file.txt" rel="nofollow">ftp://gitea.com/file.txt</a></p>`)
test(
"magnet:?xt=urn:btih:5dee65101db281ac9c46344cd6b175cdcadabcde&dn=download",
`<p><a href="magnet:?xt=urn:btih:5dee65101db281ac9c46344cd6b175cdcadabcde&amp;dn=download" rel="nofollow">magnet:?xt=urn:btih:5dee65101db281ac9c46344cd6b175cdcadabcde&amp;dn=download</a></p>`)
test(
`[link](https://example.com)`,
`<p><a href="https://example.com" rel="nofollow">link</a></p>`)
test(
`[link](mailto:test@example.com)`,
`<p><a href="mailto:test@example.com" rel="nofollow">link</a></p>`)
test(
`[link](javascript:xss)`,
`<p>link</p>`)
for _, testCase := range []struct {
input, expected string
}{
// Text that should be turned into URL
{"https://www.example.com", `<p><a href="https://www.example.com" rel="nofollow">https://www.example.com</a></p>`},
{"http://www.example.com", `<p><a href="http://www.example.com" rel="nofollow">http://www.example.com</a></p>`},
{"https://example.com", `<p><a href="https://example.com" rel="nofollow">https://example.com</a></p>`},
{"http://example.com", `<p><a href="http://example.com" rel="nofollow">http://example.com</a></p>`},
{"http://foo.com/blah_blah", `<p><a href="http://foo.com/blah_blah" rel="nofollow">http://foo.com/blah_blah</a></p>`},
{"http://foo.com/blah_blah/", `<p><a href="http://foo.com/blah_blah/" rel="nofollow">http://foo.com/blah_blah/</a></p>`},
{"http://www.example.com/wpstyle/?p=364", `<p><a href="http://www.example.com/wpstyle/?p=364" rel="nofollow">http://www.example.com/wpstyle/?p=364</a></p>`},
{"https://www.example.com/foo/?bar=baz&inga=42&quux", `<p><a href="https://www.example.com/foo/?bar=baz&amp;inga=42&amp;quux" rel="nofollow">https://www.example.com/foo/?bar=baz&amp;inga=42&amp;quux</a></p>`},
{"http://142.42.1.1/", `<p><a href="http://142.42.1.1/" rel="nofollow">http://142.42.1.1/</a></p>`},
{"https://github.com/go-gitea/gitea/?p=aaa/bbb.html#ccc-ddd", `<p><a href="https://github.com/go-gitea/gitea/?p=aaa/bbb.html#ccc-ddd" rel="nofollow">https://github.com/go-gitea/gitea/?p=aaa/bbb.html#ccc-ddd</a></p>`},
{"https://en.wikipedia.org/wiki/URL_(disambiguation)", `<p><a href="https://en.wikipedia.org/wiki/URL_(disambiguation)" rel="nofollow">https://en.wikipedia.org/wiki/URL_(disambiguation)</a></p>`},
{"https://foo_bar.example.com/", `<p><a href="https://foo_bar.example.com/" rel="nofollow">https://foo_bar.example.com/</a></p>`},
{"https://stackoverflow.com/questions/2896191/what-is-go-used-fore", `<p><a href="https://stackoverflow.com/questions/2896191/what-is-go-used-fore" rel="nofollow">https://stackoverflow.com/questions/2896191/what-is-go-used-fore</a></p>`},
{"https://username:password@gitea.com", `<p><a href="https://username:password@gitea.com" rel="nofollow">https://username:password@gitea.com</a></p>`},
{"ftp://gitea.com/file.txt", `<p><a href="ftp://gitea.com/file.txt" rel="nofollow">ftp://gitea.com/file.txt</a></p>`},
{"magnet:?xt=urn:btih:5dee65101db281ac9c46344cd6b175cdcadabcde&dn=download", `<p><a href="magnet:?xt=urn:btih:5dee65101db281ac9c46344cd6b175cdcadabcde&amp;dn=download" rel="nofollow">magnet:?xt=urn:btih:5dee65101db281ac9c46344cd6b175cdcadabcde&amp;dn=download</a></p>`},
{`[link](https://example.com)`, `<p><a href="https://example.com" rel="nofollow">link</a></p>`},
{`[link](mailto:test@example.com)`, `<p><a href="mailto:test@example.com" rel="nofollow">link</a></p>`},
{`[link](javascript:xss)`, `<p>link</p>`},
// Test that should *not* be turned into URL
test(
"www.example.com",
`<p>www.example.com</p>`)
test(
"example.com",
`<p>example.com</p>`)
test(
"test.example.com",
`<p>test.example.com</p>`)
test(
"http://",
`<p>http://</p>`)
test(
"https://",
`<p>https://</p>`)
test(
"://",
`<p>://</p>`)
test(
"www",
`<p>www</p>`)
test(
"ftps://gitea.com",
`<p>ftps://gitea.com</p>`)
// Test that should *not* be turned into URL
{"www.example.com", `<p>www.example.com</p>`},
{"example.com", `<p>example.com</p>`},
{"test.example.com", `<p>test.example.com</p>`},
{"http://", `<p>http://</p>`},
{"https://", `<p>https://</p>`},
{"://", `<p>://</p>`},
{"www", `<p>www</p>`},
{"ftps://gitea.com", `<p>ftps://gitea.com</p>`},
} {
test(testCase.input, testCase.expected)
}
t.Run("LinkEllipsis", func(t *testing.T) {
input := util.EllipsisDisplayString("http://10.1.2.3", 12)
@@ -244,73 +196,41 @@ func TestRender_links(t *testing.T) {
func TestRender_email(t *testing.T) {
setting.AppURL = markup.TestAppURL
defer testModule.MockVariableValue(&markup.RenderBehaviorForTesting.DisableAdditionalAttributes, true)()
test := func(input, expected string) {
res, err := testRenderString(markup.NewTestRenderContext().WithRelativePath("a.md"), input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(res), "input: %s", input)
}
for _, testCase := range []struct {
input, expected string
}{
// Text that should be turned into email link
{"info@gitea.com", `<p><a href="mailto:info@gitea.com" rel="nofollow">info@gitea.com</a></p>`},
{"(info@gitea.com)", `<p>(<a href="mailto:info@gitea.com" rel="nofollow">info@gitea.com</a>)</p>`},
{"[info@gitea.com]", `<p>[<a href="mailto:info@gitea.com" rel="nofollow">info@gitea.com</a>]</p>`},
{"info@gitea.com.", `<p><a href="mailto:info@gitea.com" rel="nofollow">info@gitea.com</a>.</p>`},
{"firstname+lastname@gitea.com", `<p><a href="mailto:firstname+lastname@gitea.com" rel="nofollow">firstname+lastname@gitea.com</a></p>`},
{"send email to info@gitea.co.uk.", `<p>send email to <a href="mailto:info@gitea.co.uk" rel="nofollow">info@gitea.co.uk</a>.</p>`},
// Text that should be turned into email link
test(
"info@gitea.com",
`<p><a href="mailto:info@gitea.com" rel="nofollow">info@gitea.com</a></p>`)
test(
"(info@gitea.com)",
`<p>(<a href="mailto:info@gitea.com" rel="nofollow">info@gitea.com</a>)</p>`)
test(
"[info@gitea.com]",
`<p>[<a href="mailto:info@gitea.com" rel="nofollow">info@gitea.com</a>]</p>`)
test(
"info@gitea.com.",
`<p><a href="mailto:info@gitea.com" rel="nofollow">info@gitea.com</a>.</p>`)
test(
"firstname+lastname@gitea.com",
`<p><a href="mailto:firstname+lastname@gitea.com" rel="nofollow">firstname+lastname@gitea.com</a></p>`)
test(
"send email to info@gitea.co.uk.",
`<p>send email to <a href="mailto:info@gitea.co.uk" rel="nofollow">info@gitea.co.uk</a>.</p>`)
test(
`j.doe@example.com,
{`j.doe@example.com,
j.doe@example.com.
j.doe@example.com;
j.doe@example.com?
j.doe@example.com!`,
`<p><a href="mailto:j.doe@example.com" rel="nofollow">j.doe@example.com</a>,
j.doe@example.com!`, `<p><a href="mailto:j.doe@example.com" rel="nofollow">j.doe@example.com</a>,
<a href="mailto:j.doe@example.com" rel="nofollow">j.doe@example.com</a>.
<a href="mailto:j.doe@example.com" rel="nofollow">j.doe@example.com</a>;
<a href="mailto:j.doe@example.com" rel="nofollow">j.doe@example.com</a>?
<a href="mailto:j.doe@example.com" rel="nofollow">j.doe@example.com</a>!</p>`)
<a href="mailto:j.doe@example.com" rel="nofollow">j.doe@example.com</a>!</p>`},
// match GitHub behavior
test("email@domain@domain.com", `<p>email@<a href="mailto:domain@domain.com" rel="nofollow">domain@domain.com</a></p>`)
// match GitHub behavior
{"email@domain@domain.com", `<p>email@<a href="mailto:domain@domain.com" rel="nofollow">domain@domain.com</a></p>`},
// match GitHub behavior
test(`"info@gitea.com"`, `<p>&#34;<a href="mailto:info@gitea.com" rel="nofollow">info@gitea.com</a>&#34;</p>`)
// match GitHub behavior
{`"info@gitea.com"`, `<p>&#34;<a href="mailto:info@gitea.com" rel="nofollow">info@gitea.com</a>&#34;</p>`},
// Test that should *not* be turned into email links
test(
"/home/gitea/mailstore/info@gitea/com",
`<p>/home/gitea/mailstore/info@gitea/com</p>`)
test(
"git@try.gitea.io:go-gitea/gitea.git",
`<p>git@try.gitea.io:go-gitea/gitea.git</p>`)
test(
"https://foo:bar@gitea.io",
`<p><a href="https://foo:bar@gitea.io" rel="nofollow">https://foo:bar@gitea.io</a></p>`)
test(
"gitea@3",
`<p>gitea@3</p>`)
test(
"gitea@gmail.c",
`<p>gitea@gmail.c</p>`)
test(
"email@domain..com",
`<p>email@domain..com</p>`)
// Test that should *not* be turned into email links
{"/home/gitea/mailstore/info@gitea/com", `<p>/home/gitea/mailstore/info@gitea/com</p>`},
{"git@try.gitea.io:go-gitea/gitea.git", `<p>git@try.gitea.io:go-gitea/gitea.git</p>`},
{"https://foo:bar@gitea.io", `<p><a href="https://foo:bar@gitea.io" rel="nofollow">https://foo:bar@gitea.io</a></p>`},
{"gitea@3", `<p>gitea@3</p>`},
{"gitea@gmail.c", `<p>gitea@gmail.c</p>`},
{"email@domain..com", `<p>email@domain..com</p>`},
cases := []struct {
input, expected string
}{
// match GitHub behavior
{"?a@d.zz", `<p>?<a href="mailto:a@d.zz" rel="nofollow">a@d.zz</a></p>`},
{"*a@d.zz", `<p>*<a href="mailto:a@d.zz" rel="nofollow">a@d.zz</a></p>`},
@@ -320,9 +240,10 @@ func TestRender_email(t *testing.T) {
// maybe we should reduce the candidate characters for the "name" part in the future
{"a*a@d.zz", `<p><a href="mailto:a*a@d.zz" rel="nofollow">a*a@d.zz</a></p>`},
{"a~a@d.zz", `<p><a href="mailto:a~a@d.zz" rel="nofollow">a~a@d.zz</a></p>`},
}
for _, c := range cases {
test(c.input, c.expected)
} {
res, err := testRenderString(markup.NewTestRenderContext().WithRelativePath("a.md"), testCase.input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(testCase.expected), strings.TrimSpace(res), "input: %s", testCase.input)
}
}
@@ -394,12 +315,6 @@ func TestRender_ShortLinks(t *testing.T) {
setting.AppURL = markup.TestAppURL
tree := markup.TestRepoURL + "src/master"
test := func(input, expected string) {
buffer, err := markdown.RenderString(markup.NewTestRenderContext(tree), input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
}
url := tree + "/Link"
otherURL := tree + "/Other-Link"
encodedURL := tree + "/Link%3F"
@@ -410,88 +325,36 @@ func TestRender_ShortLinks(t *testing.T) {
renderableFileURL := tree + "/markdown_file.md"
unrenderableFileURL := tree + "/file.zip"
favicon := "http://google.com/favicon.ico"
test(
"[[Link]]",
`<p><a href="`+url+`" rel="nofollow">Link</a></p>`,
)
test(
"[[Link.-]]",
`<p><a href="http://localhost:3000/test-owner/test-repo/src/master/Link.-" rel="nofollow">Link.-</a></p>`,
)
test(
"[[Link.jpg]]",
`<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" title="Link.jpg" alt="Link.jpg"/></a></p>`,
)
test(
"[["+favicon+"]]",
`<p><a href="`+favicon+`" rel="nofollow"><img src="`+favicon+`" title="favicon.ico" alt="`+favicon+`"/></a></p>`,
)
test(
"[[Name|Link]]",
`<p><a href="`+url+`" rel="nofollow">Name</a></p>`,
)
test(
"[[Name|Link.jpg]]",
`<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" title="Name" alt="Name"/></a></p>`,
)
test(
"[[Name|Link.jpg|alt=AltName]]",
`<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" title="AltName" alt="AltName"/></a></p>`,
)
test(
"[[Name|Link.jpg|title=Title]]",
`<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" title="Title" alt="Title"/></a></p>`,
)
test(
"[[Name|Link.jpg|alt=AltName|title=Title]]",
`<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" title="Title" alt="AltName"/></a></p>`,
)
test(
"[[Name|Link.jpg|alt=\"AltName\"|title='Title']]",
`<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" title="Title" alt="AltName"/></a></p>`,
)
test(
"[[Name|Link Other.jpg|alt=\"AltName\"|title='Title']]",
`<p><a href="`+otherImgurl+`" rel="nofollow"><img src="`+otherImgurl+`" title="Title" alt="AltName"/></a></p>`,
)
test(
"[[Link]] [[Other Link]]",
`<p><a href="`+url+`" rel="nofollow">Link</a> <a href="`+otherURL+`" rel="nofollow">Other Link</a></p>`,
)
test(
"[[Link?]]",
`<p><a href="`+encodedURL+`" rel="nofollow">Link?</a></p>`,
)
test(
"[[Link]] [[Other Link]] [[Link?]]",
`<p><a href="`+url+`" rel="nofollow">Link</a> <a href="`+otherURL+`" rel="nofollow">Other Link</a> <a href="`+encodedURL+`" rel="nofollow">Link?</a></p>`,
)
test(
"[[markdown_file.md]]",
`<p><a href="`+renderableFileURL+`" rel="nofollow">markdown_file.md</a></p>`,
)
test(
"[[file.zip]]",
`<p><a href="`+unrenderableFileURL+`" rel="nofollow">file.zip</a></p>`,
)
test(
"[[Link #.jpg]]",
`<p><a href="`+encodedImgurl+`" rel="nofollow"><img src="`+encodedImgurl+`" title="Link #.jpg" alt="Link #.jpg"/></a></p>`,
)
test(
"[[Name|Link #.jpg|alt=\"AltName\"|title='Title']]",
`<p><a href="`+encodedImgurl+`" rel="nofollow"><img src="`+encodedImgurl+`" title="Title" alt="AltName"/></a></p>`,
)
// FIXME: it's unable to resolve: [[link?k=v]]
// FIXME: it is a wrong test case, it is not an image, but a link with anchor "#.jpg"
test(
"[[some/path/Link #.jpg]]",
`<p><a href="`+notencodedImgurl+`" rel="nofollow"><img src="`+notencodedImgurl+`" title="Link #.jpg" alt="some/path/Link #.jpg"/></a></p>`,
)
test(
"<p><a href=\"https://example.org\">[[foobar]]</a></p>",
`<p><a href="https://example.org" rel="nofollow">[[foobar]]</a></p>`,
)
for _, testCase := range []struct {
input, expected string
}{
{"[[Link]]", `<p><a href="` + url + `" rel="nofollow">Link</a></p>`},
{"[[Link.-]]", `<p><a href="http://localhost:3000/test-owner/test-repo/src/master/Link.-" rel="nofollow">Link.-</a></p>`},
{"[[Link.jpg]]", `<p><a href="` + imgurl + `" rel="nofollow"><img src="` + imgurl + `" title="Link.jpg" alt="Link.jpg"/></a></p>`},
{"[[" + favicon + "]]", `<p><a href="` + favicon + `" rel="nofollow"><img src="` + favicon + `" title="favicon.ico" alt="` + favicon + `"/></a></p>`},
{"[[Name|Link]]", `<p><a href="` + url + `" rel="nofollow">Name</a></p>`},
{"[[Name|Link.jpg]]", `<p><a href="` + imgurl + `" rel="nofollow"><img src="` + imgurl + `" title="Name" alt="Name"/></a></p>`},
{"[[Name|Link.jpg|alt=AltName]]", `<p><a href="` + imgurl + `" rel="nofollow"><img src="` + imgurl + `" title="AltName" alt="AltName"/></a></p>`},
{"[[Name|Link.jpg|title=Title]]", `<p><a href="` + imgurl + `" rel="nofollow"><img src="` + imgurl + `" title="Title" alt="Title"/></a></p>`},
{"[[Name|Link.jpg|alt=AltName|title=Title]]", `<p><a href="` + imgurl + `" rel="nofollow"><img src="` + imgurl + `" title="Title" alt="AltName"/></a></p>`},
{"[[Name|Link.jpg|alt=\"AltName\"|title='Title']]", `<p><a href="` + imgurl + `" rel="nofollow"><img src="` + imgurl + `" title="Title" alt="AltName"/></a></p>`},
{"[[Name|Link Other.jpg|alt=\"AltName\"|title='Title']]", `<p><a href="` + otherImgurl + `" rel="nofollow"><img src="` + otherImgurl + `" title="Title" alt="AltName"/></a></p>`},
{"[[Link]] [[Other Link]]", `<p><a href="` + url + `" rel="nofollow">Link</a> <a href="` + otherURL + `" rel="nofollow">Other Link</a></p>`},
{"[[Link?]]", `<p><a href="` + encodedURL + `" rel="nofollow">Link?</a></p>`},
{"[[Link]] [[Other Link]] [[Link?]]", `<p><a href="` + url + `" rel="nofollow">Link</a> <a href="` + otherURL + `" rel="nofollow">Other Link</a> <a href="` + encodedURL + `" rel="nofollow">Link?</a></p>`},
{"[[markdown_file.md]]", `<p><a href="` + renderableFileURL + `" rel="nofollow">markdown_file.md</a></p>`},
{"[[file.zip]]", `<p><a href="` + unrenderableFileURL + `" rel="nofollow">file.zip</a></p>`},
{"[[Link #.jpg]]", `<p><a href="` + encodedImgurl + `" rel="nofollow"><img src="` + encodedImgurl + `" title="Link #.jpg" alt="Link #.jpg"/></a></p>`},
{"[[Name|Link #.jpg|alt=\"AltName\"|title='Title']]", `<p><a href="` + encodedImgurl + `" rel="nofollow"><img src="` + encodedImgurl + `" title="Title" alt="AltName"/></a></p>`},
// FIXME: it's unable to resolve: [[link?k=v]]
// FIXME: it is a wrong test case, it is not an image, but a link with anchor "#.jpg"
{"[[some/path/Link #.jpg]]", `<p><a href="` + notencodedImgurl + `" rel="nofollow"><img src="` + notencodedImgurl + `" title="Link #.jpg" alt="some/path/Link #.jpg"/></a></p>`},
{"<p><a href=\"https://example.org\">[[foobar]]</a></p>", `<p><a href="https://example.org" rel="nofollow">[[foobar]]</a></p>`},
} {
buffer, err := markdown.RenderString(markup.NewTestRenderContext(tree), testCase.input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(testCase.expected), strings.TrimSpace(string(buffer)))
}
}
func Test_ParseClusterFuzz(t *testing.T) {
@@ -519,45 +382,36 @@ func TestPostProcess(t *testing.T) {
setting.StaticURLPrefix = strings.TrimSuffix(markup.TestAppURL, "/") // can't run standalone
defer testModule.MockVariableValue(&markup.RenderBehaviorForTesting.DisableAdditionalAttributes, true)()
test := func(input, expected string) {
for _, testCase := range []struct {
input, expected string
}{
// Issue index shouldn't be post-processing in a document.
{"#1", "#1"},
// But cross-referenced issue index should work.
{"go-gitea/gitea#12345", `<a href="/go-gitea/gitea/issues/12345" class="ref-issue">go-gitea/gitea#12345</a>`},
// Test that other post-processing still works.
{":gitea:", `<span class="emoji"><img alt=":gitea:" src="` + setting.StaticURLPrefix + `/assets/img/emoji/gitea.png"/></span>`},
{"Some text with 😄 in the middle", `Some text with <span class="emoji" data-alias="smile">😄</span> in the middle`},
{"http://localhost:3000/person/repo/issues/4#issuecomment-1234", `<a href="http://localhost:3000/person/repo/issues/4#issuecomment-1234" class="ref-issue">person/repo#4 (comment)</a>`},
{"<math><mtext>:gitea: go-gitea/gitea#12345</mtext></math>", "<math><mtext>:gitea: go-gitea/gitea#12345</mtext></math>"},
// special tags, GitHub's behavior, and for unclosed tags, output as text content as much as possible
{"<script>a", `&lt;script&gt;a`},
{"<script>a</script>", `&lt;script&gt;a&lt;/script&gt;`},
{"<STYLE>a", `&lt;STYLE&gt;a`},
{"<style>a</STYLE>", `&lt;style&gt;a&lt;/STYLE&gt;`},
// other special tags, our special behavior
{"<?php\nfoo", "&lt;?php\nfoo"},
{"<%asp\nfoo", "&lt;%asp\nfoo"},
} {
var res strings.Builder
err := markup.PostProcessDefault(markup.NewTestRenderContext(markup.TestAppURL, map[string]string{"user": "go-gitea", "repo": "gitea"}), strings.NewReader(input), &res)
err := markup.PostProcessDefault(markup.NewTestRenderContext(markup.TestAppURL, map[string]string{"user": "go-gitea", "repo": "gitea"}), strings.NewReader(testCase.input), &res)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(res.String()))
assert.Equal(t, strings.TrimSpace(testCase.expected), strings.TrimSpace(res.String()))
}
// Issue index shouldn't be post-processing in a document.
test(
"#1",
"#1")
// But cross-referenced issue index should work.
test(
"go-gitea/gitea#12345",
`<a href="/go-gitea/gitea/issues/12345" class="ref-issue">go-gitea/gitea#12345</a>`)
// Test that other post-processing still works.
test(
":gitea:",
`<span class="emoji"><img alt=":gitea:" src="`+setting.StaticURLPrefix+`/assets/img/emoji/gitea.png"/></span>`)
test(
"Some text with 😄 in the middle",
`Some text with <span class="emoji" data-alias="smile">😄</span> in the middle`)
test("http://localhost:3000/person/repo/issues/4#issuecomment-1234",
`<a href="http://localhost:3000/person/repo/issues/4#issuecomment-1234" class="ref-issue">person/repo#4 (comment)</a>`)
test(
"<math><mtext>:gitea: go-gitea/gitea#12345</mtext></math>",
"<math><mtext>:gitea: go-gitea/gitea#12345</mtext></math>")
// special tags, GitHub's behavior, and for unclosed tags, output as text content as much as possible
test("<script>a", `&lt;script&gt;a`)
test("<script>a</script>", `&lt;script&gt;a&lt;/script&gt;`)
test("<STYLE>a", `&lt;STYLE&gt;a`)
test("<style>a</STYLE>", `&lt;style&gt;a&lt;/STYLE&gt;`)
// other special tags, our special behavior
test("<?php\nfoo", "&lt;?php\nfoo")
test("<%asp\nfoo", "&lt;%asp\nfoo")
}
func TestIssue16020(t *testing.T) {
+16 -26
View File
@@ -61,30 +61,20 @@ func TestRenderInternalAttrs(t *testing.T) {
}
func TestRenderInternalExtraHead(t *testing.T) {
t.Run("HeadExists", func(t *testing.T) {
out := &bytes.Buffer{}
var r RenderInternal
in := r.init("sec", out, `<MY-TAG>`)
_, _ = io.WriteString(in, `<head>any</head>`)
_ = in.Close()
assert.Equal(t, `<head><MY-TAG>any</head>`, out.String())
})
t.Run("HeadNotExists", func(t *testing.T) {
out := &bytes.Buffer{}
var r RenderInternal
in := r.init("sec", out, `<MY-TAG>`)
_, _ = io.WriteString(in, `<div></div>`)
_ = in.Close()
assert.Equal(t, `<MY-TAG><div></div>`, out.String())
})
t.Run("NotHTML", func(t *testing.T) {
out := &bytes.Buffer{}
var r RenderInternal
in := r.init("sec", out, `<MY-TAG>`)
_, _ = io.WriteString(in, `<any>`)
_ = in.Close()
assert.Equal(t, `<any>`, out.String())
})
for _, test := range []struct {
name, input, expected string
}{
{"HeadExists", `<head>any</head>`, `<head><MY-TAG>any</head>`},
{"HeadNotExists", `<div></div>`, `<MY-TAG><div></div>`},
{"NotHTML", `<any>`, `<any>`},
} {
t.Run(test.name, func(t *testing.T) {
out := &bytes.Buffer{}
var r RenderInternal
in := r.init("sec", out, `<MY-TAG>`)
_, _ = io.WriteString(in, test.input)
_ = in.Close()
assert.Equal(t, test.expected, out.String())
})
}
}
+14 -42
View File
@@ -16,6 +16,12 @@ import (
func TestRender(t *testing.T) {
r := renderer{}
render := func(t *testing.T, ctx *markup.RenderContext, input string) string {
var output strings.Builder
err := r.Render(ctx, strings.NewReader(input), &output)
assert.NoError(t, err)
return output.String()
}
t.Run("Basic notebook", func(t *testing.T) {
input := `{
@@ -37,12 +43,7 @@ func TestRender(t *testing.T) {
"nbformat": 4
}`
var output strings.Builder
ctx := &markup.RenderContext{}
err := r.Render(ctx, strings.NewReader(input), &output)
assert.NoError(t, err)
result := output.String()
result := render(t, &markup.RenderContext{}, input)
assert.Contains(t, result, `<div class="jupyter-notebook">`)
assert.Contains(t, result, `<div class="notebook-cell cell-type-code">`)
assert.Contains(t, result, `In [1]:`)
@@ -68,12 +69,7 @@ func TestRender(t *testing.T) {
"nbformat": 4
}`
var output strings.Builder
ctx := markup.NewRenderContext(t.Context())
err := r.Render(ctx, strings.NewReader(input), &output)
assert.NoError(t, err)
result := output.String()
result := render(t, markup.NewRenderContext(t.Context()), input)
// Assert normal markup still renders correctly
assert.Contains(t, result, `<div class="notebook-cell cell-type-markdown">`)
@@ -94,12 +90,7 @@ func TestRender(t *testing.T) {
}
input := fmt.Sprintf(`{"cells": [%s], "metadata": {}, "nbformat": 4}`, strings.Join(cellBlocks, ","))
var output strings.Builder
ctx := markup.NewRenderContext(t.Context())
err := r.Render(ctx, strings.NewReader(input), &output)
assert.NoError(t, err)
result := output.String()
result := render(t, markup.NewRenderContext(t.Context()), input)
// Verify it halts rendering gracefully and shows the truncation warning
assert.Contains(t, result, "Output truncated.")
@@ -130,12 +121,7 @@ func TestRender(t *testing.T) {
"nbformat": 4
}`
var output strings.Builder
ctx := markup.NewRenderContext(t.Context())
err := r.Render(ctx, strings.NewReader(input), &output)
assert.NoError(t, err)
result := output.String()
result := render(t, markup.NewRenderContext(t.Context()), input)
assert.Contains(t, result, `<img src="data:image/png;base64,`)
assert.Contains(t, result, `iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==`)
})
@@ -161,12 +147,7 @@ func TestRender(t *testing.T) {
"nbformat": 4
}`
var output strings.Builder
ctx := markup.NewRenderContext(t.Context())
err := r.Render(ctx, strings.NewReader(input), &output)
assert.NoError(t, err)
result := output.String()
result := render(t, markup.NewRenderContext(t.Context()), input)
assert.NotContains(t, result, `<style scoped>`)
assert.Contains(t, result, `<table><tr><td>1</td></tr></table>`)
assert.Contains(t, result, `<td>1</td>`)
@@ -193,12 +174,7 @@ func TestRender(t *testing.T) {
"nbformat": 4
}`
var output strings.Builder
ctx := markup.NewRenderContext(t.Context())
err := r.Render(ctx, strings.NewReader(input), &output)
assert.NoError(t, err)
result := output.String()
result := render(t, markup.NewRenderContext(t.Context()), input)
assert.Contains(t, result, `ValueError: test error`)
assert.Contains(t, result, `cell-output-error`)
})
@@ -210,12 +186,8 @@ func TestRender(t *testing.T) {
"nbformat": 3
}`
var output strings.Builder
ctx := markup.NewRenderContext(t.Context())
err := r.Render(ctx, strings.NewReader(input), &output)
assert.NoError(t, err)
assert.Regexp(t, `<div class="file-not-rendered-prompt">This notebook uses an older format.*</div>`, output.String())
result := render(t, markup.NewRenderContext(t.Context()), input)
assert.Regexp(t, `<div class="file-not-rendered-prompt">This notebook uses an older format.*</div>`, result)
})
}
-11
View File
@@ -58,17 +58,6 @@ func TestRender_Images(t *testing.T) {
result := baseLink + "/.images/src/02/train.jpg" // resolved link should not go out of the base link
// hint: With Markdown v2.5.2, there is a new syntax: [link](URL){:target="_blank"} , but we do not support it now
render(
"!["+title+"]("+url+")",
`<p><a href="`+result+`" target="_blank" rel="nofollow noopener"><img src="`+result+`" alt="`+title+`"/></a></p>`)
render(
"[["+title+"|"+url+"]]",
`<p><a href="`+result+`" rel="nofollow"><img src="`+result+`" title="`+title+`" alt="`+title+`"/></a></p>`)
render(
"[!["+title+"]("+url+")]("+href+")",
`<p><a href="`+href+`" rel="nofollow"><img src="`+result+`" alt="`+title+`"/></a></p>`)
render(
"!["+title+"]("+url+")",
`<p><a href="`+result+`" target="_blank" rel="nofollow noopener"><img src="`+result+`" alt="`+title+`"/></a></p>`)
+36 -57
View File
@@ -26,67 +26,46 @@ func (it *IssueTemplate) Valid() bool {
}
func TestExtractMetadata(t *testing.T) {
t.Run("ValidFrontAndBody", func(t *testing.T) {
var meta IssueTemplate
body, err := ExtractMetadata(fmt.Sprintf("%s\n%s\n%s\n%s", sepTest, frontTest, sepTest, bodyTest), &meta)
assert.NoError(t, err)
assert.Equal(t, bodyTest, body)
assert.Equal(t, metaTest, meta)
assert.True(t, meta.Valid())
})
for _, mode := range []string{"String", "Bytes"} {
t.Run(mode, func(t *testing.T) {
extract := func(format string, args ...any) (string, IssueTemplate, error) {
var meta IssueTemplate
if mode == "String" {
body, err := ExtractMetadata(fmt.Sprintf(format, args...), &meta)
return body, meta, err
} else {
body, err := ExtractMetadataBytes(fmt.Appendf(nil, format, args...), &meta)
return string(body), meta, err
}
}
t.Run("NoFirstSeparator", func(t *testing.T) {
var meta IssueTemplate
_, err := ExtractMetadata(fmt.Sprintf("%s\n%s\n%s", frontTest, sepTest, bodyTest), &meta)
assert.Error(t, err)
})
t.Run("ValidFrontAndBody", func(t *testing.T) {
body, meta, err := extract("%s\n%s\n%s\n%s", sepTest, frontTest, sepTest, bodyTest)
assert.NoError(t, err)
assert.Equal(t, bodyTest, body)
assert.Equal(t, metaTest, meta)
assert.True(t, meta.Valid())
})
t.Run("NoLastSeparator", func(t *testing.T) {
var meta IssueTemplate
_, err := ExtractMetadata(fmt.Sprintf("%s\n%s\n%s", sepTest, frontTest, bodyTest), &meta)
assert.Error(t, err)
})
t.Run("NoFirstSeparator", func(t *testing.T) {
_, _, err := extract("%s\n%s\n%s", frontTest, sepTest, bodyTest)
assert.Error(t, err)
})
t.Run("NoBody", func(t *testing.T) {
var meta IssueTemplate
body, err := ExtractMetadata(fmt.Sprintf("%s\n%s\n%s", sepTest, frontTest, sepTest), &meta)
assert.NoError(t, err)
assert.Empty(t, body)
assert.Equal(t, metaTest, meta)
assert.True(t, meta.Valid())
})
}
t.Run("NoLastSeparator", func(t *testing.T) {
_, _, err := extract("%s\n%s\n%s", sepTest, frontTest, bodyTest)
assert.Error(t, err)
})
func TestExtractMetadataBytes(t *testing.T) {
t.Run("ValidFrontAndBody", func(t *testing.T) {
var meta IssueTemplate
body, err := ExtractMetadataBytes(fmt.Appendf(nil, "%s\n%s\n%s\n%s", sepTest, frontTest, sepTest, bodyTest), &meta)
assert.NoError(t, err)
assert.Equal(t, bodyTest, string(body))
assert.Equal(t, metaTest, meta)
assert.True(t, meta.Valid())
})
t.Run("NoFirstSeparator", func(t *testing.T) {
var meta IssueTemplate
_, err := ExtractMetadataBytes(fmt.Appendf(nil, "%s\n%s\n%s", frontTest, sepTest, bodyTest), &meta)
assert.Error(t, err)
})
t.Run("NoLastSeparator", func(t *testing.T) {
var meta IssueTemplate
_, err := ExtractMetadataBytes(fmt.Appendf(nil, "%s\n%s\n%s", sepTest, frontTest, bodyTest), &meta)
assert.Error(t, err)
})
t.Run("NoBody", func(t *testing.T) {
var meta IssueTemplate
body, err := ExtractMetadataBytes(fmt.Appendf(nil, "%s\n%s\n%s", sepTest, frontTest, sepTest), &meta)
assert.NoError(t, err)
assert.Empty(t, string(body))
assert.Equal(t, metaTest, meta)
assert.True(t, meta.Valid())
})
t.Run("NoBody", func(t *testing.T) {
body, meta, err := extract("%s\n%s\n%s", sepTest, frontTest, sepTest)
assert.NoError(t, err)
assert.Empty(t, body)
assert.Equal(t, metaTest, meta)
assert.True(t, meta.Valid())
})
})
}
}
var (
+3 -8
View File
@@ -12,17 +12,12 @@ import (
)
func TestRenderIFrame(t *testing.T) {
render := func(ctx *RenderContext, opts ExternalRendererOptions) string {
sb := &strings.Builder{}
require.NoError(t, RenderIFrame(ctx, &opts, sb))
return sb.String()
}
ctx := NewRenderContext(t.Context()).
WithRelativePath("tree-path").
WithMetas(map[string]string{"user": "test-owner", "repo": "test-repo", "RefTypeNameSubURL": "src/branch/master"})
// iframe doesn't need sandbox, the sandbox is set in render's response header
ret := render(ctx, ExternalRendererOptions{ContentSandbox: "any"})
assert.Equal(t, `<iframe data-src="/test-owner/test-repo/render/src/branch/master/tree-path" data-global-init="initExternalRenderIframe" class="external-render-iframe"></iframe>`, ret)
sb := &strings.Builder{}
require.NoError(t, RenderIFrame(ctx, &ExternalRendererOptions{ContentSandbox: "any"}, sb))
assert.Equal(t, `<iframe data-src="/test-owner/test-repo/render/src/branch/master/tree-path" data-global-init="initExternalRenderIframe" class="external-render-iframe"></iframe>`, sb.String())
}