1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-22 18:28:37 +00:00

Refactor markup render system (#32612)

This PR removes (almost) all path tricks, and introduces "renderhelper"
package.

Now we can clearly see the rendering behaviors for comment/file/wiki,
more details are in "renderhelper" tests.

Fix #31411 , fix #18592, fix #25632 and maybe more problems. (ps: fix
#32608 by the way)
This commit is contained in:
wxiaoguang
2024-11-24 16:18:57 +08:00
committed by GitHub
parent fa175c1694
commit 633785a5f3
65 changed files with 1096 additions and 1194 deletions

View File

@@ -200,7 +200,7 @@ func (a *Action) LoadActUser(ctx context.Context) {
}
}
func (a *Action) loadRepo(ctx context.Context) {
func (a *Action) LoadRepo(ctx context.Context) {
if a.Repo != nil {
return
}
@@ -250,7 +250,7 @@ func (a *Action) GetActDisplayNameTitle(ctx context.Context) string {
// GetRepoUserName returns the name of the action repository owner.
func (a *Action) GetRepoUserName(ctx context.Context) string {
a.loadRepo(ctx)
a.LoadRepo(ctx)
if a.Repo == nil {
return "(non-existing-repo)"
}
@@ -265,7 +265,7 @@ func (a *Action) ShortRepoUserName(ctx context.Context) string {
// GetRepoName returns the name of the action repository.
func (a *Action) GetRepoName(ctx context.Context) string {
a.loadRepo(ctx)
a.LoadRepo(ctx)
if a.Repo == nil {
return "(non-existing-repo)"
}
@@ -644,7 +644,7 @@ func NotifyWatchers(ctx context.Context, actions ...*Action) error {
}
if repoChanged {
act.loadRepo(ctx)
act.LoadRepo(ctx)
repo = act.Repo
// check repo owner exist.

View File

@@ -7,8 +7,8 @@ import (
"context"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/renderhelper"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
"xorm.io/builder"
@@ -112,12 +112,8 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu
}
var err error
rctx := markup.NewRenderContext(ctx).
WithRepoFacade(issue.Repo).
WithLinks(markup.Links{Base: issue.Repo.Link()}).
WithMetas(issue.Repo.ComposeMetas(ctx))
if comment.RenderedContent, err = markdown.RenderString(rctx,
comment.Content); err != nil {
rctx := renderhelper.NewRenderContextRepoComment(ctx, issue.Repo)
if comment.RenderedContent, err = markdown.RenderString(rctx, comment.Content); err != nil {
return nil, err
}
}

View File

@@ -0,0 +1,53 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package renderhelper
import (
"context"
"io"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
)
type commitChecker struct {
ctx context.Context
commitCache map[string]bool
gitRepoFacade gitrepo.Repository
gitRepo *git.Repository
gitRepoCloser io.Closer
}
func newCommitChecker(ctx context.Context, gitRepo gitrepo.Repository) *commitChecker {
return &commitChecker{ctx: ctx, commitCache: make(map[string]bool), gitRepoFacade: gitRepo}
}
func (c *commitChecker) Close() error {
if c != nil && c.gitRepoCloser != nil {
return c.gitRepoCloser.Close()
}
return nil
}
func (c *commitChecker) IsCommitIDExisting(commitID string) bool {
exist, inCache := c.commitCache[commitID]
if inCache {
return exist
}
if c.gitRepo == nil {
r, closer, err := gitrepo.RepositoryFromContextOrOpen(c.ctx, c.gitRepoFacade)
if err != nil {
log.Error("unable to open repository: %s Error: %v", gitrepo.RepoGitURL(c.gitRepoFacade), err)
return false
}
c.gitRepo, c.gitRepoCloser = r, closer
}
exist = c.gitRepo.IsReferenceExist(commitID) // Don't use IsObjectExist since it doesn't support short hashs with gogit edition.
c.commitCache[commitID] = exist
return exist
}

View File

@@ -0,0 +1,27 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package renderhelper
import (
"context"
"testing"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/markup"
)
func TestMain(m *testing.M) {
unittest.MainTest(m, &unittest.TestOptions{
FixtureFiles: []string{"repository.yml", "user.yml"},
SetUp: func() error {
markup.RenderBehaviorForTesting.DisableAdditionalAttributes = true
markup.Init(&markup.RenderHelperFuncs{
IsUsernameMentionable: func(ctx context.Context, username string) bool {
return username == "user2"
},
})
return nil
},
})
}

View File

@@ -0,0 +1,73 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package renderhelper
import (
"context"
"fmt"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/util"
)
type RepoComment struct {
ctx *markup.RenderContext
opts RepoCommentOptions
commitChecker *commitChecker
repoLink string
}
func (r *RepoComment) CleanUp() {
_ = r.commitChecker.Close()
}
func (r *RepoComment) IsCommitIDExisting(commitID string) bool {
return r.commitChecker.IsCommitIDExisting(commitID)
}
func (r *RepoComment) ResolveLink(link string, likeType markup.LinkType) (finalLink string) {
switch likeType {
case markup.LinkTypeApp:
finalLink = r.ctx.ResolveLinkApp(link)
default:
finalLink = r.ctx.ResolveLinkRelative(r.repoLink, r.opts.CurrentRefPath, link)
}
return finalLink
}
var _ markup.RenderHelper = (*RepoComment)(nil)
type RepoCommentOptions struct {
DeprecatedRepoName string // it is only a patch for the non-standard "markup" api
DeprecatedOwnerName string // it is only a patch for the non-standard "markup" api
CurrentRefPath string // eg: "branch/main" or "commit/11223344"
}
func NewRenderContextRepoComment(ctx context.Context, repo *repo_model.Repository, opts ...RepoCommentOptions) *markup.RenderContext {
helper := &RepoComment{
repoLink: repo.Link(),
opts: util.OptionalArg(opts),
}
rctx := markup.NewRenderContext(ctx)
helper.ctx = rctx
if repo != nil {
helper.repoLink = repo.Link()
helper.commitChecker = newCommitChecker(ctx, repo)
rctx = rctx.WithMetas(repo.ComposeMetas(ctx))
} else {
// this is almost dead code, only to pass the incorrect tests
helper.repoLink = fmt.Sprintf("%s/%s", helper.opts.DeprecatedOwnerName, helper.opts.DeprecatedRepoName)
rctx = rctx.WithMetas(map[string]string{
"user": helper.opts.DeprecatedOwnerName,
"repo": helper.opts.DeprecatedRepoName,
"markdownLineBreakStyle": "comment",
"markupAllowShortIssuePattern": "true",
})
}
rctx = rctx.WithHelper(helper)
return rctx
}

View File

@@ -0,0 +1,76 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package renderhelper
import (
"context"
"testing"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
"github.com/stretchr/testify/assert"
)
func TestRepoComment(t *testing.T) {
unittest.PrepareTestEnv(t)
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
t.Run("AutoLink", func(t *testing.T) {
rctx := NewRenderContextRepoComment(context.Background(), repo1).WithMarkupType(markdown.MarkupName)
rendered, err := markup.RenderString(rctx, `
65f1bf27bc3bf70f64657658635e66094edbcb4d
#1
@user2
`)
assert.NoError(t, err)
assert.Equal(t,
`<p><a href="/user2/repo1/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d" rel="nofollow"><code>65f1bf27bc</code></a><br/>
<a href="/user2/repo1/issues/1" class="ref-issue" rel="nofollow">#1</a><br/>
<a href="/user2" rel="nofollow">@user2</a></p>
`, rendered)
})
t.Run("AbsoluteAndRelative", func(t *testing.T) {
rctx := NewRenderContextRepoComment(context.Background(), repo1).WithMarkupType(markdown.MarkupName)
// It is Gitea's old behavior, the relative path is resolved to the repo path
// It is different from GitHub, GitHub resolves relative links to current page's path
rendered, err := markup.RenderString(rctx, `
[/test](/test)
[./test](./test)
![/image](/image)
![./image](./image)
`)
assert.NoError(t, err)
assert.Equal(t,
`<p><a href="/user2/repo1/test" rel="nofollow">/test</a><br/>
<a href="/user2/repo1/test" rel="nofollow">./test</a><br/>
<a href="/user2/repo1/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/image" alt="/image"/></a><br/>
<a href="/user2/repo1/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/image" alt="./image"/></a></p>
`, rendered)
})
t.Run("WithCurrentRefPath", func(t *testing.T) {
rctx := NewRenderContextRepoComment(context.Background(), repo1, RepoCommentOptions{CurrentRefPath: "/commit/1234"}).
WithMarkupType(markdown.MarkupName)
// the ref path is only used to render commit message: a commit message is rendered at the commit page with its commit ID path
rendered, err := markup.RenderString(rctx, `
[/test](/test)
[./test](./test)
![/image](/image)
![./image](./image)
`)
assert.NoError(t, err)
assert.Equal(t, `<p><a href="/user2/repo1/test" rel="nofollow">/test</a><br/>
<a href="/user2/repo1/commit/1234/test" rel="nofollow">./test</a><br/>
<a href="/user2/repo1/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/image" alt="/image"/></a><br/>
<a href="/user2/repo1/commit/1234/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/commit/1234/image" alt="./image"/></a></p>
`, rendered)
})
}

View File

@@ -0,0 +1,77 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package renderhelper
import (
"context"
"fmt"
"path"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/util"
)
type RepoFile struct {
ctx *markup.RenderContext
opts RepoFileOptions
commitChecker *commitChecker
repoLink string
}
func (r *RepoFile) CleanUp() {
_ = r.commitChecker.Close()
}
func (r *RepoFile) IsCommitIDExisting(commitID string) bool {
return r.commitChecker.IsCommitIDExisting(commitID)
}
func (r *RepoFile) ResolveLink(link string, likeType markup.LinkType) string {
finalLink := link
switch likeType {
case markup.LinkTypeApp:
finalLink = r.ctx.ResolveLinkApp(link)
case markup.LinkTypeDefault:
finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "src", r.opts.CurrentRefPath), r.opts.CurrentTreePath, link)
case markup.LinkTypeRaw:
finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "raw", r.opts.CurrentRefPath), r.opts.CurrentTreePath, link)
case markup.LinkTypeMedia:
finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "media", r.opts.CurrentRefPath), r.opts.CurrentTreePath, link)
}
return finalLink
}
var _ markup.RenderHelper = (*RepoFile)(nil)
type RepoFileOptions struct {
DeprecatedRepoName string // it is only a patch for the non-standard "markup" api
DeprecatedOwnerName string // it is only a patch for the non-standard "markup" api
CurrentRefPath string // eg: "branch/main"
CurrentTreePath string // eg: "path/to/file" in the repo
}
func NewRenderContextRepoFile(ctx context.Context, repo *repo_model.Repository, opts ...RepoFileOptions) *markup.RenderContext {
helper := &RepoFile{opts: util.OptionalArg(opts)}
rctx := markup.NewRenderContext(ctx)
helper.ctx = rctx
if repo != nil {
helper.repoLink = repo.Link()
helper.commitChecker = newCommitChecker(ctx, repo)
rctx = rctx.WithMetas(repo.ComposeDocumentMetas(ctx))
} else {
// this is almost dead code, only to pass the incorrect tests
helper.repoLink = fmt.Sprintf("%s/%s", helper.opts.DeprecatedOwnerName, helper.opts.DeprecatedRepoName)
rctx = rctx.WithMetas(map[string]string{
"user": helper.opts.DeprecatedOwnerName,
"repo": helper.opts.DeprecatedRepoName,
"markdownLineBreakStyle": "document",
})
}
rctx = rctx.WithHelper(helper)
return rctx
}

View File

@@ -0,0 +1,83 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package renderhelper
import (
"context"
"testing"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
"github.com/stretchr/testify/assert"
)
func TestRepoFile(t *testing.T) {
unittest.PrepareTestEnv(t)
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
t.Run("AutoLink", func(t *testing.T) {
rctx := NewRenderContextRepoFile(context.Background(), repo1).WithMarkupType(markdown.MarkupName)
rendered, err := markup.RenderString(rctx, `
65f1bf27bc3bf70f64657658635e66094edbcb4d
#1
@user2
`)
assert.NoError(t, err)
assert.Equal(t,
`<p><a href="/user2/repo1/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d" rel="nofollow"><code>65f1bf27bc</code></a>
#1
<a href="/user2" rel="nofollow">@user2</a></p>
`, rendered)
})
t.Run("AbsoluteAndRelative", func(t *testing.T) {
rctx := NewRenderContextRepoFile(context.Background(), repo1, RepoFileOptions{CurrentRefPath: "branch/main"}).
WithMarkupType(markdown.MarkupName)
rendered, err := markup.RenderString(rctx, `
[/test](/test)
[./test](./test)
![/image](/image)
![./image](./image)
`)
assert.NoError(t, err)
assert.Equal(t,
`<p><a href="/user2/repo1/src/branch/main/test" rel="nofollow">/test</a>
<a href="/user2/repo1/src/branch/main/test" rel="nofollow">./test</a>
<a href="/user2/repo1/media/branch/main/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/media/branch/main/image" alt="/image"/></a>
<a href="/user2/repo1/media/branch/main/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/media/branch/main/image" alt="./image"/></a></p>
`, rendered)
})
t.Run("WithCurrentRefPath", func(t *testing.T) {
rctx := NewRenderContextRepoFile(context.Background(), repo1, RepoFileOptions{CurrentRefPath: "/commit/1234"}).
WithMarkupType(markdown.MarkupName)
rendered, err := markup.RenderString(rctx, `
[/test](/test)
![/image](/image)
`)
assert.NoError(t, err)
assert.Equal(t, `<p><a href="/user2/repo1/src/commit/1234/test" rel="nofollow">/test</a>
<a href="/user2/repo1/media/commit/1234/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/media/commit/1234/image" alt="/image"/></a></p>
`, rendered)
})
t.Run("WithCurrentRefPathByTag", func(t *testing.T) {
rctx := NewRenderContextRepoFile(context.Background(), repo1, RepoFileOptions{
CurrentRefPath: "/commit/1234",
CurrentTreePath: "my-dir",
}).
WithMarkupType(markdown.MarkupName)
rendered, err := markup.RenderString(rctx, `
<img src="LINK">
<video src="LINK">
`)
assert.NoError(t, err)
assert.Equal(t, `<a href="/user2/repo1/media/commit/1234/my-dir/LINK" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/media/commit/1234/my-dir/LINK"/></a>
<video src="/user2/repo1/media/commit/1234/my-dir/LINK">
</video>`, rendered)
})
}

View File

@@ -0,0 +1,80 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package renderhelper
import (
"context"
"fmt"
"path"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/util"
)
type RepoWiki struct {
ctx *markup.RenderContext
opts RepoWikiOptions
commitChecker *commitChecker
repoLink string
}
func (r *RepoWiki) CleanUp() {
_ = r.commitChecker.Close()
}
func (r *RepoWiki) IsCommitIDExisting(commitID string) bool {
return r.commitChecker.IsCommitIDExisting(commitID)
}
func (r *RepoWiki) ResolveLink(link string, likeType markup.LinkType) string {
finalLink := link
switch likeType {
case markup.LinkTypeApp:
finalLink = r.ctx.ResolveLinkApp(link)
case markup.LinkTypeDefault:
finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "wiki", r.opts.currentRefPath), r.opts.currentTreePath, link)
case markup.LinkTypeMedia:
finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "wiki/raw", r.opts.currentRefPath), r.opts.currentTreePath, link)
case markup.LinkTypeRaw: // wiki doesn't use it
}
return finalLink
}
var _ markup.RenderHelper = (*RepoWiki)(nil)
type RepoWikiOptions struct {
DeprecatedRepoName string // it is only a patch for the non-standard "markup" api
DeprecatedOwnerName string // it is only a patch for the non-standard "markup" api
// these options are not used at the moment because Wiki doesn't support sub-path, nor branch
currentRefPath string // eg: "branch/main"
currentTreePath string // eg: "path/to/file" in the repo
}
func NewRenderContextRepoWiki(ctx context.Context, repo *repo_model.Repository, opts ...RepoWikiOptions) *markup.RenderContext {
helper := &RepoWiki{opts: util.OptionalArg(opts)}
rctx := markup.NewRenderContext(ctx).WithMarkupType(markdown.MarkupName)
if repo != nil {
helper.repoLink = repo.Link()
helper.commitChecker = newCommitChecker(ctx, repo)
rctx = rctx.WithMetas(repo.ComposeWikiMetas(ctx))
} else {
// this is almost dead code, only to pass the incorrect tests
helper.repoLink = fmt.Sprintf("%s/%s", helper.opts.DeprecatedOwnerName, helper.opts.DeprecatedRepoName)
rctx = rctx.WithMetas(map[string]string{
"user": helper.opts.DeprecatedOwnerName,
"repo": helper.opts.DeprecatedRepoName,
"markdownLineBreakStyle": "document",
"markupAllowShortIssuePattern": "true",
})
}
rctx = rctx.WithHelper(helper)
helper.ctx = rctx
return rctx
}

View File

@@ -0,0 +1,65 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package renderhelper
import (
"context"
"testing"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
"github.com/stretchr/testify/assert"
)
func TestRepoWiki(t *testing.T) {
unittest.PrepareTestEnv(t)
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
t.Run("AutoLink", func(t *testing.T) {
rctx := NewRenderContextRepoWiki(context.Background(), repo1).WithMarkupType(markdown.MarkupName)
rendered, err := markup.RenderString(rctx, `
65f1bf27bc3bf70f64657658635e66094edbcb4d
#1
@user2
`)
assert.NoError(t, err)
assert.Equal(t,
`<p><a href="/user2/repo1/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d" rel="nofollow"><code>65f1bf27bc</code></a>
<a href="/user2/repo1/issues/1" class="ref-issue" rel="nofollow">#1</a>
<a href="/user2" rel="nofollow">@user2</a></p>
`, rendered)
})
t.Run("AbsoluteAndRelative", func(t *testing.T) {
rctx := NewRenderContextRepoWiki(context.Background(), repo1).WithMarkupType(markdown.MarkupName)
rendered, err := markup.RenderString(rctx, `
[/test](/test)
[./test](./test)
![/image](/image)
![./image](./image)
`)
assert.NoError(t, err)
assert.Equal(t,
`<p><a href="/user2/repo1/wiki/test" rel="nofollow">/test</a>
<a href="/user2/repo1/wiki/test" rel="nofollow">./test</a>
<a href="/user2/repo1/wiki/raw/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/wiki/raw/image" alt="/image"/></a>
<a href="/user2/repo1/wiki/raw/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/wiki/raw/image" alt="./image"/></a></p>
`, rendered)
})
t.Run("PathInTag", func(t *testing.T) {
rctx := NewRenderContextRepoWiki(context.Background(), repo1).WithMarkupType(markdown.MarkupName)
rendered, err := markup.RenderString(rctx, `
<img src="LINK">
<video src="LINK">
`)
assert.NoError(t, err)
assert.Equal(t, `<a href="/user2/repo1/wiki/raw/LINK" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/wiki/raw/LINK"/></a>
<video src="/user2/repo1/wiki/raw/LINK">
</video>`, rendered)
})
}

View File

@@ -0,0 +1,29 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package renderhelper
import (
"context"
"code.gitea.io/gitea/modules/markup"
)
type SimpleDocument struct {
*markup.SimpleRenderHelper
ctx *markup.RenderContext
baseLink string
}
func (r *SimpleDocument) ResolveLink(link string, likeType markup.LinkType) string {
return r.ctx.ResolveLinkRelative(r.baseLink, "", link)
}
var _ markup.RenderHelper = (*SimpleDocument)(nil)
func NewRenderContextSimpleDocument(ctx context.Context, baseLink string) *markup.RenderContext {
helper := &SimpleDocument{baseLink: baseLink}
rctx := markup.NewRenderContext(ctx).WithHelper(helper).WithMetas(markup.ComposeSimpleDocumentMetas())
helper.ctx = rctx
return rctx
}

View File

@@ -0,0 +1,40 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package renderhelper
import (
"context"
"testing"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
"github.com/stretchr/testify/assert"
)
func TestSimpleDocument(t *testing.T) {
unittest.PrepareTestEnv(t)
rctx := NewRenderContextSimpleDocument(context.Background(), "/base").WithMarkupType(markdown.MarkupName)
rendered, err := markup.RenderString(rctx, `
65f1bf27bc3bf70f64657658635e66094edbcb4d
#1
@user2
[/test](/test)
[./test](./test)
![/image](/image)
![./image](./image)
`)
assert.NoError(t, err)
assert.Equal(t,
`<p>65f1bf27bc3bf70f64657658635e66094edbcb4d
#1
<a href="/base/user2" rel="nofollow">@user2</a></p>
<p><a href="/base/test" rel="nofollow">/test</a>
<a href="/base/test" rel="nofollow">./test</a>
<a href="/base/image" target="_blank" rel="nofollow noopener"><img src="/base/image" alt="/image"/></a>
<a href="/base/image" target="_blank" rel="nofollow noopener"><img src="/base/image" alt="./image"/></a></p>
`, rendered)
}

View File

@@ -9,6 +9,7 @@ import (
"code.gitea.io/gitea/models/db"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"xorm.io/builder"
)
@@ -64,10 +65,10 @@ func BeanExists(t assert.TestingT, bean any, conditions ...any) bool {
}
// AssertExistsAndLoadBean assert that a bean exists and load it from the test database
func AssertExistsAndLoadBean[T any](t assert.TestingT, bean T, conditions ...any) T {
func AssertExistsAndLoadBean[T any](t require.TestingT, bean T, conditions ...any) T {
exists, err := LoadBeanIfExists(bean, conditions...)
assert.NoError(t, err)
assert.True(t, exists,
require.NoError(t, err)
require.True(t, exists,
"Expected to find %+v (of type %T, with conditions %+v), but did not",
bean, bean, conditions)
return bean