mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-06 20:56:05 +00:00
9dc04289aa
before: gitrepo vs git packages after: git package fully handle all git operations by the way, use `WithRepo(repo)` instead of `WithDir(repo.Path)` to hide path details. benefits: 1. remove all unnecessary wrappers, developers no need to struggle with "which package should be used" 2. simplify code, RepositoryFacade can (will) be used everywhere, all "path" details are (will be) hidden
281 lines
9.3 KiB
Go
281 lines
9.3 KiB
Go
// Copyright 2017 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package repo
|
|
|
|
import (
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"testing"
|
|
|
|
repo_model "gitea.dev/models/repo"
|
|
"gitea.dev/models/unittest"
|
|
"gitea.dev/modules/git"
|
|
"gitea.dev/modules/web"
|
|
"gitea.dev/services/contexttest"
|
|
"gitea.dev/services/forms"
|
|
repo_service "gitea.dev/services/repository"
|
|
wiki_service "gitea.dev/services/wiki"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
const (
|
|
content = "Wiki contents for unit tests"
|
|
message = "Wiki commit message for unit tests"
|
|
)
|
|
|
|
func wikiEntry(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.WebPath) (*git.Repository, *git.TreeEntry) {
|
|
wikiRepo, err := git.OpenRepository(repo.WikiStorageRepo())
|
|
assert.NoError(t, err)
|
|
t.Cleanup(func() {
|
|
defer wikiRepo.Close()
|
|
})
|
|
commit, err := wikiRepo.GetBranchCommit(t.Context(), "master")
|
|
assert.NoError(t, err)
|
|
entries, err := commit.Tree().ListEntries(t.Context(), wikiRepo)
|
|
assert.NoError(t, err)
|
|
for _, entry := range entries {
|
|
if entry.Name() == wiki_service.WebPathToGitPath(wikiName) {
|
|
return wikiRepo, entry
|
|
}
|
|
}
|
|
return wikiRepo, nil
|
|
}
|
|
|
|
func wikiContent(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.WebPath) string {
|
|
wikiRepo, entry := wikiEntry(t, repo, wikiName)
|
|
if !assert.NotNil(t, entry) {
|
|
return ""
|
|
}
|
|
reader, err := entry.Blob(wikiRepo).DataAsync(t.Context())
|
|
assert.NoError(t, err)
|
|
defer reader.Close()
|
|
bytes, err := io.ReadAll(reader)
|
|
assert.NoError(t, err)
|
|
return string(bytes)
|
|
}
|
|
|
|
func assertWikiExists(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.WebPath) {
|
|
_, entry := wikiEntry(t, repo, wikiName)
|
|
assert.NotNil(t, entry)
|
|
}
|
|
|
|
func assertWikiNotExists(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.WebPath) {
|
|
_, entry := wikiEntry(t, repo, wikiName)
|
|
assert.Nil(t, entry)
|
|
}
|
|
|
|
func assertPagesMetas(t *testing.T, expectedNames []string, metas any) {
|
|
pageMetas, ok := metas.([]PageMeta)
|
|
require.True(t, ok)
|
|
require.Len(t, pageMetas, len(expectedNames))
|
|
|
|
for i, pageMeta := range pageMetas {
|
|
assert.Equal(t, expectedNames[i], pageMeta.Name)
|
|
}
|
|
}
|
|
|
|
func TestWiki(t *testing.T) {
|
|
unittest.PrepareTestEnv(t)
|
|
|
|
ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki")
|
|
ctx.SetPathParam("*", "Home")
|
|
contexttest.LoadRepo(t, ctx, 1)
|
|
Wiki(ctx)
|
|
assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus())
|
|
assert.EqualValues(t, "Home", ctx.Data["Title"])
|
|
assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name", "Unescaped File"}, ctx.Data["Pages"])
|
|
|
|
ctx, _ = contexttest.MockContext(t, "user2/repo1/jpeg.jpg")
|
|
ctx.SetPathParam("*", "jpeg.jpg")
|
|
contexttest.LoadRepo(t, ctx, 1)
|
|
Wiki(ctx)
|
|
assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus())
|
|
assert.Equal(t, "/user2/repo1/wiki/raw/jpeg.jpg", ctx.Resp.Header().Get("Location"))
|
|
}
|
|
|
|
func TestWikiPages(t *testing.T) {
|
|
unittest.PrepareTestEnv(t)
|
|
|
|
ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/?action=_pages")
|
|
contexttest.LoadRepo(t, ctx, 1)
|
|
WikiPages(ctx)
|
|
assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus())
|
|
assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name", "Unescaped File"}, ctx.Data["Pages"])
|
|
}
|
|
|
|
func TestNewWiki(t *testing.T) {
|
|
unittest.PrepareTestEnv(t)
|
|
|
|
ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/?action=_new")
|
|
contexttest.LoadUser(t, ctx, 2)
|
|
contexttest.LoadRepo(t, ctx, 1)
|
|
NewWiki(ctx)
|
|
assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus())
|
|
assert.EqualValues(t, ctx.Tr("repo.wiki.new_page"), ctx.Data["Title"])
|
|
}
|
|
|
|
func TestNewWikiPost(t *testing.T) {
|
|
for _, title := range []string{
|
|
"New page",
|
|
"&&&&",
|
|
} {
|
|
unittest.PrepareTestEnv(t)
|
|
|
|
ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/?action=_new")
|
|
contexttest.LoadUser(t, ctx, 2)
|
|
contexttest.LoadRepo(t, ctx, 1)
|
|
web.SetForm(ctx, &forms.NewWikiForm{
|
|
Title: title,
|
|
Content: content,
|
|
Message: message,
|
|
})
|
|
NewWikiPost(ctx)
|
|
assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus())
|
|
assertWikiExists(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title))
|
|
assert.Equal(t, content, wikiContent(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title)))
|
|
}
|
|
}
|
|
|
|
func TestNewWikiPost_ReservedName(t *testing.T) {
|
|
unittest.PrepareTestEnv(t)
|
|
|
|
ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/?action=_new")
|
|
contexttest.LoadUser(t, ctx, 2)
|
|
contexttest.LoadRepo(t, ctx, 1)
|
|
web.SetForm(ctx, &forms.NewWikiForm{
|
|
Title: "_edit",
|
|
Content: content,
|
|
Message: message,
|
|
})
|
|
NewWikiPost(ctx)
|
|
assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus())
|
|
assert.EqualValues(t, ctx.Tr("repo.wiki.reserved_page", "_edit"), ctx.Flash.ErrorMsg)
|
|
assertWikiNotExists(t, ctx.Repo.Repository, "_edit")
|
|
}
|
|
|
|
func TestEditWiki(t *testing.T) {
|
|
unittest.PrepareTestEnv(t)
|
|
|
|
ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/Home?action=_edit")
|
|
ctx.SetPathParam("*", "Home")
|
|
contexttest.LoadUser(t, ctx, 2)
|
|
contexttest.LoadRepo(t, ctx, 1)
|
|
EditWiki(ctx)
|
|
assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus())
|
|
assert.EqualValues(t, "Home", ctx.Data["Title"])
|
|
assert.Equal(t, wikiContent(t, ctx.Repo.Repository, "Home"), ctx.Data["WikiEditContent"])
|
|
|
|
ctx, _ = contexttest.MockContext(t, "user2/repo1/wiki/jpeg.jpg?action=_edit")
|
|
ctx.SetPathParam("*", "jpeg.jpg")
|
|
contexttest.LoadUser(t, ctx, 2)
|
|
contexttest.LoadRepo(t, ctx, 1)
|
|
EditWiki(ctx)
|
|
assert.Equal(t, http.StatusForbidden, ctx.Resp.WrittenStatus())
|
|
}
|
|
|
|
func TestEditWikiPost(t *testing.T) {
|
|
for _, title := range []string{
|
|
"Home",
|
|
"New/<page>",
|
|
} {
|
|
unittest.PrepareTestEnv(t)
|
|
ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/Home?action=_new")
|
|
ctx.SetPathParam("*", "Home")
|
|
contexttest.LoadUser(t, ctx, 2)
|
|
contexttest.LoadRepo(t, ctx, 1)
|
|
web.SetForm(ctx, &forms.NewWikiForm{
|
|
Title: title,
|
|
Content: content,
|
|
Message: message,
|
|
})
|
|
EditWikiPost(ctx)
|
|
assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus())
|
|
assertWikiExists(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title))
|
|
assert.Equal(t, content, wikiContent(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title)))
|
|
if title != "Home" {
|
|
assertWikiNotExists(t, ctx.Repo.Repository, "Home")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDeleteWikiPagePost(t *testing.T) {
|
|
unittest.PrepareTestEnv(t)
|
|
|
|
ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/Home?action=_delete")
|
|
contexttest.LoadUser(t, ctx, 2)
|
|
contexttest.LoadRepo(t, ctx, 1)
|
|
DeleteWikiPagePost(ctx)
|
|
assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus())
|
|
assertWikiNotExists(t, ctx.Repo.Repository, "Home")
|
|
}
|
|
|
|
func TestWikiRaw(t *testing.T) {
|
|
for filepath, filetype := range map[string]string{
|
|
"jpeg.jpg": "image/jpeg",
|
|
"images/jpeg.jpg": "image/jpeg",
|
|
"files/Non-Renderable-File.zip": "application/octet-stream",
|
|
"Page With Spaced Name": "text/plain; charset=utf-8",
|
|
"Page-With-Spaced-Name": "text/plain; charset=utf-8",
|
|
"Page With Spaced Name.md": "", // there is no "Page With Spaced Name.md" in repo
|
|
"Page-With-Spaced-Name.md": "text/plain; charset=utf-8",
|
|
} {
|
|
unittest.PrepareTestEnv(t)
|
|
|
|
ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/raw/"+url.PathEscape(filepath))
|
|
ctx.SetPathParam("*", filepath)
|
|
contexttest.LoadUser(t, ctx, 2)
|
|
contexttest.LoadRepo(t, ctx, 1)
|
|
WikiRaw(ctx)
|
|
if filetype == "" {
|
|
assert.Equal(t, http.StatusNotFound, ctx.Resp.WrittenStatus(), "filepath: %s", filepath)
|
|
} else {
|
|
assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus(), "filepath: %s", filepath)
|
|
assert.Equal(t, filetype, ctx.Resp.Header().Get("Content-Type"), "filepath: %s", filepath)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDefaultWikiBranch(t *testing.T) {
|
|
unittest.PrepareTestEnv(t)
|
|
|
|
// repo with no wiki
|
|
repoWithNoWiki := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
|
|
assert.False(t, repo_service.HasWiki(t.Context(), repoWithNoWiki))
|
|
assert.NoError(t, wiki_service.ChangeDefaultWikiBranch(t.Context(), repoWithNoWiki, "main"))
|
|
|
|
// repo with wiki
|
|
assert.NoError(t, repo_model.UpdateRepositoryColsNoAutoTime(
|
|
t.Context(),
|
|
&repo_model.Repository{ID: 1, DefaultWikiBranch: "wrong-branch"},
|
|
"default_wiki_branch",
|
|
),
|
|
)
|
|
|
|
ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki")
|
|
ctx.SetPathParam("*", "Home")
|
|
contexttest.LoadRepo(t, ctx, 1)
|
|
assert.Equal(t, "wrong-branch", ctx.Repo.Repository.DefaultWikiBranch)
|
|
Wiki(ctx) // after the visiting, the out-of-sync database record will update the branch name to "master"
|
|
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
|
assert.Equal(t, "master", ctx.Repo.Repository.DefaultWikiBranch)
|
|
|
|
// invalid branch name should fail
|
|
assert.Error(t, wiki_service.ChangeDefaultWikiBranch(t.Context(), repo, "the bad name"))
|
|
repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
|
assert.Equal(t, "master", repo.DefaultWikiBranch)
|
|
|
|
// the same branch name, should succeed (actually a no-op)
|
|
assert.NoError(t, wiki_service.ChangeDefaultWikiBranch(t.Context(), repo, "master"))
|
|
repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
|
assert.Equal(t, "master", repo.DefaultWikiBranch)
|
|
|
|
// change to another name
|
|
assert.NoError(t, wiki_service.ChangeDefaultWikiBranch(t.Context(), repo, "main"))
|
|
repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
|
assert.Equal(t, "main", repo.DefaultWikiBranch)
|
|
}
|