mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2026-07-12 20:48:40 +00:00
tests: better factory with forgery package (#11356)
### Context Following the feedback in forgejo/discussions#170 (and my ambitious attempt in forgejo/forgejo#10985), it appears that having an easy-to-use factory package would greatly help get rid of the global fixtures. I think that the global fixtures are quite harmful (recent example: https://codeberg.org/forgejo/forgejo/pulls/9906#issuecomment-10826066): - hard to write (contributor must know where to add them) - hard to change (may break some unrelated tests) - hard to review (not located near the test code) - they require the tests to execute sequentially ### Proposed way forward The `forgery` package (the name represents faking/crafting and sounds good with Forgejo) is meant to replace global yaml fixtures with local go factories. The forgery can currently: - create users - create repos - create organisations This allowed me to drop `CreateDeclarativeRepoWithOptions` (and deprecate `CreateDeclarativeRepo`). I think that further changes should be delayed to other PRs (I have a local branch to create `Project`) ### Documentation - [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - [x] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change. - [x] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change. *The decision if the pull request will be shown in the release notes is up to the mergers / release team.* The content of the `release-notes/<pull request number>.md` file will serve as the basis for the release notes. If the file does not exist, the title of the pull request will be used instead. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/11356 Reviewed-by: limiting-factor <limiting-factor@noreply.codeberg.org>
This commit is contained in:
parent
0e577ed6c9
commit
88ba174119
27 changed files with 675 additions and 604 deletions
|
|
@ -25,7 +25,7 @@ func TestDebugserver(t *testing.T) {
|
|||
signal.Notify(done, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
onForgejoRun(t, func(*testing.T, *url.URL) {
|
||||
defer DeclareGitRepos(t)()
|
||||
DeclareGitRepos(t)
|
||||
fmt.Println(setting.AppURL)
|
||||
<-done
|
||||
})
|
||||
|
|
|
|||
|
|
@ -19,12 +19,11 @@ import (
|
|||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/git"
|
||||
"forgejo.org/modules/indexer/stats"
|
||||
"forgejo.org/modules/optional"
|
||||
"forgejo.org/modules/timeutil"
|
||||
issue_service "forgejo.org/services/issue"
|
||||
files_service "forgejo.org/services/repository/files"
|
||||
"forgejo.org/services/wiki"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -44,7 +43,7 @@ type SetupRepo func(*user_model.User, *repo_model.Repository)
|
|||
|
||||
// put your Git repo declarations in here
|
||||
// feel free to amend the helper function below or use the raw variant directly
|
||||
func DeclareGitRepos(t *testing.T) func() {
|
||||
func DeclareGitRepos(t *testing.T) {
|
||||
now := timeutil.TimeStampNow()
|
||||
postIssue := func(repo *repo_model.Repository, user *user_model.User, age int64, title, content string) {
|
||||
issue := &issues_model.Issue{
|
||||
|
|
@ -57,45 +56,45 @@ func DeclareGitRepos(t *testing.T) func() {
|
|||
require.NoError(t, issue_service.NewIssue(db.DefaultContext, repo, issue, nil, nil, nil))
|
||||
}
|
||||
|
||||
cleanupFunctions := []func(){
|
||||
newRepo(t, 2, "diff-test", nil, []FileChanges{{
|
||||
Filename: "testfile",
|
||||
Versions: []string{"hello", "hallo", "hola", "native", "ubuntu-latest", "- runs-on: ubuntu-latest", "- runs-on: debian-latest"},
|
||||
}}, nil),
|
||||
newRepo(t, 2, "language-stats-test", nil, []FileChanges{{
|
||||
Filename: "main.rs",
|
||||
Versions: []string{"fn main() {", "println!(\"Hello World!\");", "}"},
|
||||
}}, nil),
|
||||
newRepo(t, 2, "mentions-highlighted", nil, []FileChanges{
|
||||
{
|
||||
Filename: "history1.md",
|
||||
Versions: []string{""},
|
||||
CommitMsg: "A commit message which mentions @user2 in the title\nand has some additional text which mentions @user1",
|
||||
},
|
||||
{
|
||||
Filename: "history2.md",
|
||||
Versions: []string{""},
|
||||
CommitMsg: "Another commit which mentions @user1 in the title\nand @user2 in the text",
|
||||
},
|
||||
}, nil),
|
||||
newRepo(t, 2, "file-uploads", nil, []FileChanges{{
|
||||
Filename: "UPLOAD_TEST.md",
|
||||
Versions: []string{"# File upload test\nUse this repo to test various file upload features in new branches."},
|
||||
}}, nil),
|
||||
newRepo(t, 2, "unicode-escaping", &tests.DeclarativeRepoOptions{
|
||||
EnabledUnits: optional.Some([]unit_model.Type{unit_model.TypeCode, unit_model.TypeWiki}),
|
||||
}, []FileChanges{{
|
||||
Filename: "a-file",
|
||||
Versions: []string{"{a}{а}"},
|
||||
}}, func(user *user_model.User, repo *repo_model.Repository) {
|
||||
wiki.InitWiki(db.DefaultContext, repo)
|
||||
wiki.AddWikiPage(db.DefaultContext, user, repo, "Home", "{a}{а}", "{a}{а}")
|
||||
wiki.AddWikiPage(db.DefaultContext, user, repo, "_Sidebar", "{a}{а}", "{a}{а}")
|
||||
wiki.AddWikiPage(db.DefaultContext, user, repo, "_Footer", "{a}{а}", "{a}{а}")
|
||||
}),
|
||||
newRepo(t, 2, "multiple-combo-boxes", nil, []FileChanges{{
|
||||
Filename: ".forgejo/issue_template/multi-combo-boxes.yaml",
|
||||
Versions: []string{`
|
||||
newRepo(t, 2, "diff-test", nil, []FileChanges{{
|
||||
Filename: "testfile",
|
||||
Versions: []string{"hello", "hallo", "hola", "native", "ubuntu-latest", "- runs-on: ubuntu-latest", "- runs-on: debian-latest"},
|
||||
}}, nil)
|
||||
newRepo(t, 2, "language-stats-test", nil, []FileChanges{{
|
||||
Filename: "main.rs",
|
||||
Versions: []string{"fn main() {", "println!(\"Hello World!\");", "}"},
|
||||
}}, nil)
|
||||
newRepo(t, 2, "mentions-highlighted", nil, []FileChanges{
|
||||
{
|
||||
Filename: "history1.md",
|
||||
Versions: []string{""},
|
||||
CommitMsg: "A commit message which mentions @user2 in the title\nand has some additional text which mentions @user1",
|
||||
},
|
||||
{
|
||||
Filename: "history2.md",
|
||||
Versions: []string{""},
|
||||
CommitMsg: "Another commit which mentions @user1 in the title\nand @user2 in the text",
|
||||
},
|
||||
}, nil)
|
||||
newRepo(t, 2, "file-uploads", nil, []FileChanges{{
|
||||
Filename: "UPLOAD_TEST.md",
|
||||
Versions: []string{"# File upload test\nUse this repo to test various file upload features in new branches."},
|
||||
}}, nil)
|
||||
newRepo(t, 2, "unicode-escaping", map[unit_model.Type]convert.Conversion{
|
||||
unit_model.TypeCode: nil,
|
||||
unit_model.TypeWiki: nil,
|
||||
}, []FileChanges{{
|
||||
Filename: "a-file",
|
||||
Versions: []string{"{a}{а}"},
|
||||
}}, func(user *user_model.User, repo *repo_model.Repository) {
|
||||
wiki.InitWiki(db.DefaultContext, repo)
|
||||
wiki.AddWikiPage(db.DefaultContext, user, repo, "Home", "{a}{а}", "{a}{а}")
|
||||
wiki.AddWikiPage(db.DefaultContext, user, repo, "_Sidebar", "{a}{а}", "{a}{а}")
|
||||
wiki.AddWikiPage(db.DefaultContext, user, repo, "_Footer", "{a}{а}", "{a}{а}")
|
||||
})
|
||||
newRepo(t, 2, "multiple-combo-boxes", nil, []FileChanges{{
|
||||
Filename: ".forgejo/issue_template/multi-combo-boxes.yaml",
|
||||
Versions: []string{`
|
||||
name: "Multiple combo-boxes"
|
||||
description: "To show something"
|
||||
body:
|
||||
|
|
@ -108,79 +107,70 @@ body:
|
|||
attributes:
|
||||
label: two
|
||||
`},
|
||||
}}, nil),
|
||||
newRepo(t, 11, "dependency-test", &tests.DeclarativeRepoOptions{
|
||||
UnitConfig: optional.Some(map[unit_model.Type]convert.Conversion{
|
||||
unit_model.TypeIssues: &repo_model.IssuesConfig{
|
||||
EnableDependencies: true,
|
||||
},
|
||||
}),
|
||||
}, []FileChanges{}, func(user *user_model.User, repo *repo_model.Repository) {
|
||||
postIssue(repo, user, 500, "first issue here", "an issue created earlier")
|
||||
postIssue(repo, user, 400, "second issue here", "not the right issue, but in the right repo")
|
||||
postIssue(repo, user, 300, "third issue here", "depends on things")
|
||||
postIssue(repo, user, 200, "unrelated issue", "shrug emoji")
|
||||
postIssue(repo, user, 100, "newest issue", "very new")
|
||||
}),
|
||||
newRepo(t, 11, "dependency-test-2", &tests.DeclarativeRepoOptions{
|
||||
UnitConfig: optional.Some(map[unit_model.Type]convert.Conversion{
|
||||
unit_model.TypeIssues: &repo_model.IssuesConfig{
|
||||
EnableDependencies: true,
|
||||
},
|
||||
}),
|
||||
}, []FileChanges{}, func(user *user_model.User, repo *repo_model.Repository) {
|
||||
postIssue(repo, user, 450, "right issue", "an issue containing word right")
|
||||
postIssue(repo, user, 150, "left issue", "an issue containing word left")
|
||||
}),
|
||||
newRepo(t, 2, "long-diff-test", nil, []FileChanges{{
|
||||
Filename: "test-README.md",
|
||||
Versions: []string{
|
||||
readStringFile(t, "tests/e2e/declarative-repo/long-diff-test/0-README.md"),
|
||||
},
|
||||
}}, func(user *user_model.User, repo *repo_model.Repository) {
|
||||
commit1Sha := addCommitToBranch(t, user, repo, "main", "test-branch", "test-README.md", "",
|
||||
readStringFile(t, "tests/e2e/declarative-repo/long-diff-test/1-README.md"))
|
||||
commit2Sha := addCommitToBranch(t, user, repo, "test-branch", "test-branch", "test-README.md", commit1Sha,
|
||||
readStringFile(t, "tests/e2e/declarative-repo/long-diff-test/2-README.md"))
|
||||
addCommitToBranch(t, user, repo, "test-branch", "test-branch", "test-README.md", commit2Sha,
|
||||
readStringFile(t, "tests/e2e/declarative-repo/long-diff-test/3-README.md"))
|
||||
}),
|
||||
newRepo(t, 2, "huge-diff-test", nil, []FileChanges{{
|
||||
Filename: "glossary.po",
|
||||
Versions: []string{
|
||||
func() string {
|
||||
var sb strings.Builder
|
||||
sb.Write([]byte("0"))
|
||||
for i := 1; i < 2000; i++ {
|
||||
sb.WriteString(strconv.Itoa(i))
|
||||
sb.WriteByte('\n')
|
||||
}}, nil)
|
||||
newRepo(t, 11, "dependency-test", map[unit_model.Type]convert.Conversion{
|
||||
unit_model.TypeIssues: &repo_model.IssuesConfig{
|
||||
EnableDependencies: true,
|
||||
},
|
||||
unit_model.TypeCode: nil,
|
||||
}, []FileChanges{}, func(user *user_model.User, repo *repo_model.Repository) {
|
||||
postIssue(repo, user, 500, "first issue here", "an issue created earlier")
|
||||
postIssue(repo, user, 400, "second issue here", "not the right issue, but in the right repo")
|
||||
postIssue(repo, user, 300, "third issue here", "depends on things")
|
||||
postIssue(repo, user, 200, "unrelated issue", "shrug emoji")
|
||||
postIssue(repo, user, 100, "newest issue", "very new")
|
||||
})
|
||||
newRepo(t, 11, "dependency-test-2", map[unit_model.Type]convert.Conversion{
|
||||
unit_model.TypeIssues: &repo_model.IssuesConfig{
|
||||
EnableDependencies: true,
|
||||
},
|
||||
unit_model.TypeCode: nil,
|
||||
}, []FileChanges{}, func(user *user_model.User, repo *repo_model.Repository) {
|
||||
postIssue(repo, user, 450, "right issue", "an issue containing word right")
|
||||
postIssue(repo, user, 150, "left issue", "an issue containing word left")
|
||||
})
|
||||
newRepo(t, 2, "long-diff-test", nil, []FileChanges{{
|
||||
Filename: "test-README.md",
|
||||
Versions: []string{
|
||||
readStringFile(t, "tests/e2e/declarative-repo/long-diff-test/0-README.md"),
|
||||
},
|
||||
}}, func(user *user_model.User, repo *repo_model.Repository) {
|
||||
commit1Sha := addCommitToBranch(t, user, repo, "main", "test-branch", "test-README.md", "",
|
||||
readStringFile(t, "tests/e2e/declarative-repo/long-diff-test/1-README.md"))
|
||||
commit2Sha := addCommitToBranch(t, user, repo, "test-branch", "test-branch", "test-README.md", commit1Sha,
|
||||
readStringFile(t, "tests/e2e/declarative-repo/long-diff-test/2-README.md"))
|
||||
addCommitToBranch(t, user, repo, "test-branch", "test-branch", "test-README.md", commit2Sha,
|
||||
readStringFile(t, "tests/e2e/declarative-repo/long-diff-test/3-README.md"))
|
||||
})
|
||||
newRepo(t, 2, "huge-diff-test", nil, []FileChanges{{
|
||||
Filename: "glossary.po",
|
||||
Versions: []string{
|
||||
func() string {
|
||||
var sb strings.Builder
|
||||
sb.Write([]byte("0"))
|
||||
for i := 1; i < 2000; i++ {
|
||||
sb.WriteString(strconv.Itoa(i))
|
||||
sb.WriteByte('\n')
|
||||
}
|
||||
return sb.String()
|
||||
}(),
|
||||
},
|
||||
}}, func(user *user_model.User, repo *repo_model.Repository) {
|
||||
addCommitToBranch(t, user, repo, "main", "main-2", "glossary.po", "",
|
||||
func() string {
|
||||
var sb strings.Builder
|
||||
sb.Write([]byte("0"))
|
||||
for i := 1; i < 2000; i++ {
|
||||
sb.WriteString(strconv.Itoa(i))
|
||||
if i%12 == 0 {
|
||||
sb.WriteString("Blub")
|
||||
}
|
||||
return sb.String()
|
||||
}(),
|
||||
},
|
||||
}}, func(user *user_model.User, repo *repo_model.Repository) {
|
||||
addCommitToBranch(t, user, repo, "main", "main-2", "glossary.po", "",
|
||||
func() string {
|
||||
var sb strings.Builder
|
||||
sb.Write([]byte("0"))
|
||||
for i := 1; i < 2000; i++ {
|
||||
sb.WriteString(strconv.Itoa(i))
|
||||
if i%12 == 0 {
|
||||
sb.WriteString("Blub")
|
||||
}
|
||||
sb.WriteByte('\n')
|
||||
}
|
||||
return sb.String()
|
||||
}())
|
||||
}),
|
||||
// add your repo declarations here
|
||||
}
|
||||
|
||||
return func() {
|
||||
for _, cleanup := range cleanupFunctions {
|
||||
cleanup()
|
||||
}
|
||||
}
|
||||
sb.WriteByte('\n')
|
||||
}
|
||||
return sb.String()
|
||||
}())
|
||||
})
|
||||
// add your repo declarations here
|
||||
}
|
||||
|
||||
func readStringFile(t *testing.T, fn string) string {
|
||||
|
|
@ -189,18 +179,20 @@ func readStringFile(t *testing.T, fn string) string {
|
|||
return string(c)
|
||||
}
|
||||
|
||||
func newRepo(t *testing.T, userID int64, repoName string, initOpts *tests.DeclarativeRepoOptions, fileChanges []FileChanges, setup SetupRepo) func() {
|
||||
func newRepo(t *testing.T, userID int64, repoName string, enabledUnits map[unit_model.Type]convert.Conversion, fileChanges []FileChanges, setup SetupRepo) {
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID})
|
||||
|
||||
opts := tests.DeclarativeRepoOptions{}
|
||||
if initOpts != nil {
|
||||
opts = *initOpts
|
||||
somerepo := forgery.CreateRepository(t, user, &forgery.CreateRepositoryOptions{
|
||||
Name: repoName,
|
||||
Files: forgery.FilesInit{},
|
||||
})
|
||||
if len(enabledUnits) == 0 {
|
||||
forgery.EnableRepoUnit(t, somerepo, unit_model.TypeCode, nil)
|
||||
forgery.EnableRepoUnit(t, somerepo, unit_model.TypeIssues, nil)
|
||||
}
|
||||
opts.Name = optional.Some(repoName)
|
||||
if !opts.EnabledUnits.Has() {
|
||||
opts.EnabledUnits = optional.Some([]unit_model.Type{unit_model.TypeCode, unit_model.TypeIssues})
|
||||
for unit, config := range enabledUnits {
|
||||
forgery.EnableRepoUnit(t, somerepo, unit, config)
|
||||
}
|
||||
somerepo, _, cleanupFunc := tests.CreateDeclarativeRepoWithOptions(t, user, opts)
|
||||
|
||||
var lastCommitID string
|
||||
for _, file := range fileChanges {
|
||||
|
|
@ -252,8 +244,6 @@ func newRepo(t *testing.T, userID int64, repoName string, initOpts *tests.Declar
|
|||
|
||||
err := stats.UpdateRepoIndexer(somerepo)
|
||||
require.NoError(t, err)
|
||||
|
||||
return cleanupFunc
|
||||
}
|
||||
|
||||
func addCommitToBranch(t *testing.T, user *user_model.User, repo *repo_model.Repository, oldBranch, newBranch, filename, lastSha, content string) string {
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ func TestE2e(t *testing.T) {
|
|||
|
||||
// Default 2 minute timeout
|
||||
onForgejoRun(t, func(*testing.T, *url.URL) {
|
||||
defer DeclareGitRepos(t)()
|
||||
DeclareGitRepos(t)
|
||||
thisTest := runArgs
|
||||
// when all tests are run, use unique artifacts directories per test to preserve artifacts from other tests
|
||||
if testVisual {
|
||||
|
|
|
|||
112
tests/forgery/fs.go
Normal file
112
tests/forgery/fs.go
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
// Copyright 2026 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forgery
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"strings"
|
||||
"testing/fstest"
|
||||
"time"
|
||||
|
||||
repo_model "forgejo.org/models/repo"
|
||||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/git"
|
||||
files_service "forgejo.org/services/repository/files"
|
||||
)
|
||||
|
||||
type MapFS = fstest.MapFS
|
||||
|
||||
// when a file has one of this mode, it needs specific git handling
|
||||
// other non-zero modes are rejected
|
||||
const (
|
||||
modeSubmodule = fs.ModeNamedPipe // hacky, but
|
||||
modeSymlink = fs.ModeSymlink
|
||||
)
|
||||
|
||||
func MapFile(data string) *fstest.MapFile {
|
||||
return &fstest.MapFile{
|
||||
Data: []byte(data),
|
||||
}
|
||||
}
|
||||
|
||||
func MapSymlink(target string) *fstest.MapFile {
|
||||
return &fstest.MapFile{
|
||||
Data: []byte(target),
|
||||
Mode: modeSymlink,
|
||||
}
|
||||
}
|
||||
|
||||
func MapSubmodule(sha string) *fstest.MapFile {
|
||||
return &fstest.MapFile{
|
||||
Data: []byte(sha),
|
||||
Mode: modeSubmodule,
|
||||
}
|
||||
}
|
||||
|
||||
func initRepo(doer *user_model.User, repo *repo_model.Repository, format git.ObjectFormat, fsys fs.FS, commitMessage string) (string, error) {
|
||||
t, err := files_service.NewTemporaryUploadRepository(git.DefaultContext, repo)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer t.Close()
|
||||
if err := t.Init(format.Name()); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil || d.IsDir() {
|
||||
return err
|
||||
}
|
||||
|
||||
var content io.Reader
|
||||
mode := git.EntryModeBlob
|
||||
switch d.Type() {
|
||||
case modeSymlink:
|
||||
target, err := fs.ReadLink(fsys, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
content = strings.NewReader(target)
|
||||
mode = git.EntryModeSymlink
|
||||
case modeSubmodule:
|
||||
mode = git.EntryModeCommit
|
||||
fallthrough
|
||||
case 0:
|
||||
f, err := fsys.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
content = f
|
||||
default:
|
||||
return fmt.Errorf("unexpected file type in forgery.CreateRepository %s: %s", path, d.Type())
|
||||
}
|
||||
|
||||
// add object to the database
|
||||
objectHash, err := t.HashObject(content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Add the object to the index
|
||||
return t.AddObjectToIndex(mode.String(), objectHash, path)
|
||||
}); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
treeHash, err := t.WriteTree()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
commitHash, err := t.CommitTreeWithDate("", doer, doer, treeHash, commitMessage, false, now, now)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return commitHash, t.Push(doer, commitHash, repo.DefaultBranch)
|
||||
}
|
||||
138
tests/forgery/repo.go
Normal file
138
tests/forgery/repo.go
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
// Copyright 2026 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forgery
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"io/fs"
|
||||
"testing"
|
||||
|
||||
repo_model "forgejo.org/models/repo"
|
||||
unit_model "forgejo.org/models/unit"
|
||||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/git"
|
||||
repo_service "forgejo.org/services/repository"
|
||||
wiki_service "forgejo.org/services/wiki"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"xorm.io/xorm/convert"
|
||||
)
|
||||
|
||||
type CreateRepositoryOptions struct {
|
||||
Name string // if nil a unique name (derived from the test name) will be generated
|
||||
|
||||
// Content of the initial commit, if nil the git repo will be left uninitialized.
|
||||
// Use [MapFS] or [FilesInit] to setup the initial files.
|
||||
Files fs.FS
|
||||
|
||||
ObjectFormat git.ObjectFormat // If nil, SHA1
|
||||
IsTemplate bool
|
||||
IsPrivate bool
|
||||
|
||||
LatestSha *string // if not nil, the commit sha after initializing the repo with the Files will be written to this ref
|
||||
SkipCleanup bool // if true the repo will not be deleted at the end of the test (can be useful to debug locally)
|
||||
}
|
||||
|
||||
// FilesInit specifies the templates to use upon repository initialization.
|
||||
type FilesInit struct {
|
||||
Readme string
|
||||
Gitignores string
|
||||
License string
|
||||
}
|
||||
|
||||
func (FilesInit) Open(name string) (fs.File, error) {
|
||||
panic("FilesInit is only a sentinel value")
|
||||
}
|
||||
|
||||
// CreateRepository returns the repo, owner and opts can be nil
|
||||
func CreateRepository(t testing.TB, owner *user_model.User, opts *CreateRepositoryOptions) *repo_model.Repository {
|
||||
t.Helper()
|
||||
|
||||
if owner == nil {
|
||||
owner = CreateUser(t, nil) // if specific options are needed, create the owner manually
|
||||
}
|
||||
if opts == nil {
|
||||
opts = &CreateRepositoryOptions{}
|
||||
}
|
||||
|
||||
repoName := opts.Name
|
||||
if repoName == "" {
|
||||
repoName = "repo-" + uniqueSafeName(t.Name())
|
||||
}
|
||||
|
||||
gitFormat := cmp.Or(opts.ObjectFormat, git.Sha1ObjectFormat)
|
||||
|
||||
// Create the repository
|
||||
createOptions := repo_service.CreateRepoOptions{
|
||||
Name: repoName,
|
||||
Description: "Test Repo",
|
||||
DefaultBranch: "main",
|
||||
IsTemplate: opts.IsTemplate,
|
||||
ObjectFormatName: gitFormat.Name(),
|
||||
IsPrivate: opts.IsPrivate,
|
||||
}
|
||||
if fi, ok := opts.Files.(FilesInit); ok {
|
||||
createOptions.AutoInit = true
|
||||
createOptions.Readme = cmp.Or(fi.Readme, "Default")
|
||||
createOptions.Gitignores = fi.Gitignores
|
||||
createOptions.License = fi.License
|
||||
}
|
||||
repo, err := repo_service.CreateRepositoryDirectly(t.Context(), owner, owner, createOptions)
|
||||
require.NoError(t, err)
|
||||
if !opts.SkipCleanup {
|
||||
t.Cleanup(func() {
|
||||
_ = repo_service.DeleteRepository(t.Context(), owner, repo, false)
|
||||
})
|
||||
}
|
||||
require.NotEmpty(t, repo)
|
||||
|
||||
if !createOptions.AutoInit && opts.Files != nil {
|
||||
sha, err := initRepo(owner, repo, gitFormat, opts.Files, "init")
|
||||
require.NoError(t, err)
|
||||
if opts.LatestSha != nil {
|
||||
*opts.LatestSha = sha
|
||||
}
|
||||
|
||||
// reload the repo since pushing a commit might update the model via the push_update queue (IsEmpty for instance)
|
||||
repo, err = repo_model.GetRepositoryByID(t.Context(), repo.ID)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
repo.Owner = owner
|
||||
|
||||
return repo
|
||||
}
|
||||
|
||||
func InitWiki(t testing.TB, repo *repo_model.Repository, branch string) {
|
||||
// Set the wiki branch in the database first
|
||||
repo.WikiBranch = branch
|
||||
err := repo_model.UpdateRepositoryCols(t.Context(), repo, "wiki_branch")
|
||||
require.NoError(t, err)
|
||||
|
||||
// Initialize the wiki
|
||||
err = wiki_service.InitWiki(t.Context(), repo)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Add a new wiki page
|
||||
err = wiki_service.AddWikiPage(t.Context(), repo.Owner, repo, "Home", "Welcome to the wiki!", "Add a Home page")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// config may be nil
|
||||
func EnableRepoUnit(t testing.TB, repo *repo_model.Repository, unit unit_model.Type, config convert.Conversion) {
|
||||
t.Helper()
|
||||
|
||||
err := repo_service.UpdateRepositoryUnits(t.Context(), repo, []repo_model.RepoUnit{{
|
||||
RepoID: repo.ID,
|
||||
Type: unit,
|
||||
Config: config,
|
||||
}}, nil)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func DisableRepoUnits(t testing.TB, repo *repo_model.Repository, units ...unit_model.Type) {
|
||||
t.Helper()
|
||||
|
||||
err := repo_service.UpdateRepositoryUnits(t.Context(), repo, nil, units)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
66
tests/forgery/user.go
Normal file
66
tests/forgery/user.go
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
// Copyright 2026 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forgery
|
||||
|
||||
import (
|
||||
"math/rand/v2"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
org_model "forgejo.org/models/organization"
|
||||
user_model "forgejo.org/models/user"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var nameCleaner = regexp.MustCompile(`[^a-zA-Z0-9-]+`) // exclude "_", to prevent multiple consecutive dashes
|
||||
|
||||
// uniqueSafeName replaces specials chars with _ and appends a random hex suffix
|
||||
func uniqueSafeName(testName string) string {
|
||||
return nameCleaner.ReplaceAllLiteralString(testName, "_") + "-" + strconv.FormatUint(uint64(rand.Uint32()), 16)
|
||||
}
|
||||
|
||||
type CreateUserOptions struct {
|
||||
IsAdmin bool
|
||||
}
|
||||
|
||||
const userPassword = "password"
|
||||
|
||||
func CreateUser(t testing.TB, opts *CreateUserOptions) *user_model.User {
|
||||
t.Helper()
|
||||
|
||||
if opts == nil {
|
||||
opts = &CreateUserOptions{}
|
||||
}
|
||||
u := &user_model.User{}
|
||||
|
||||
name := "user-" + uniqueSafeName(t.Name())
|
||||
|
||||
u.Name = name
|
||||
u.Email = name + "@test.forgejo.org"
|
||||
u.Passwd = userPassword
|
||||
u.IsAdmin = opts.IsAdmin
|
||||
|
||||
err := user_model.CreateUser(t.Context(), u)
|
||||
require.NoError(t, err)
|
||||
return u
|
||||
}
|
||||
|
||||
func CreateOrganisation(t testing.TB, owner *user_model.User) *org_model.Organization {
|
||||
t.Helper()
|
||||
|
||||
if owner == nil {
|
||||
owner = CreateUser(t, nil) // if specific options are needed, create the owner manually
|
||||
}
|
||||
o := &org_model.Organization{}
|
||||
|
||||
name := "org-" + uniqueSafeName(t.Name())
|
||||
|
||||
o.Name = name
|
||||
|
||||
err := org_model.CreateOrganization(t.Context(), o, owner)
|
||||
require.NoError(t, err)
|
||||
return o
|
||||
}
|
||||
|
|
@ -36,6 +36,7 @@ import (
|
|||
repo_service "forgejo.org/services/repository"
|
||||
files_service "forgejo.org/services/repository/files"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -1212,17 +1213,13 @@ jobs:
|
|||
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
|
||||
// create the repo
|
||||
repo, sha, f := tests.CreateDeclarativeRepo(t, user2, "repo-workflow-dispatch",
|
||||
[]unit_model.Type{unit_model.TypeActions}, nil,
|
||||
[]*files_service.ChangeRepoFile{
|
||||
{
|
||||
Operation: "create",
|
||||
TreePath: fmt.Sprintf("%s/%s", testCase.workflowDirectory, testCase.workflowID),
|
||||
ContentReader: strings.NewReader(testCase.workflowContent),
|
||||
},
|
||||
var sha string
|
||||
repo := forgery.CreateRepository(t, user2, &forgery.CreateRepositoryOptions{
|
||||
Files: forgery.MapFS{
|
||||
fmt.Sprintf("%s/%s", testCase.workflowDirectory, testCase.workflowID): forgery.MapFile(testCase.workflowContent),
|
||||
},
|
||||
)
|
||||
defer f()
|
||||
LatestSha: &sha,
|
||||
})
|
||||
|
||||
schedules, err := db.Find[actions_model.ActionSchedule](t.Context(), actions_model.FindScheduleOptions{RepoID: repo.ID})
|
||||
require.NoError(t, err)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import (
|
|||
"forgejo.org/routers"
|
||||
"forgejo.org/services/contexttest"
|
||||
"forgejo.org/services/federation"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
ap "github.com/go-ap/activitypub"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -122,8 +122,7 @@ func TestActivityPubPersonInboxNoteToDistant(t *testing.T) {
|
|||
localSession2 := loginUser(t, localUser2.LoginName)
|
||||
localSecssion2Token := getTokenForLoggedInUser(t, localSession2, auth_model.AccessTokenScopeWriteIssue)
|
||||
|
||||
repo, _, f := tests.CreateDeclarativeRepoWithOptions(t, localUser2, tests.DeclarativeRepoOptions{})
|
||||
defer f()
|
||||
repo := forgery.CreateRepository(t, localUser2, nil)
|
||||
|
||||
// follow (distant follows local)
|
||||
followActivity := fmt.Appendf(nil,
|
||||
|
|
|
|||
|
|
@ -20,15 +20,14 @@ import (
|
|||
"forgejo.org/models/unit"
|
||||
"forgejo.org/models/unittest"
|
||||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/optional"
|
||||
"forgejo.org/modules/setting"
|
||||
api "forgejo.org/modules/structs"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"xorm.io/xorm/convert"
|
||||
)
|
||||
|
||||
func TestAPIListIssues(t *testing.T) {
|
||||
|
|
@ -752,35 +751,28 @@ func TestAPISearchIssuesAccessTokenResources(t *testing.T) {
|
|||
func TestAPIInternalAndExternalIssueTracker(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
|
||||
otherUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
|
||||
repoOptions := &forgery.CreateRepositoryOptions{
|
||||
Files: forgery.FilesInit{}, // some tests will fail with 404 if the repository is empty
|
||||
}
|
||||
user := forgery.CreateUser(t, &forgery.CreateUserOptions{
|
||||
IsAdmin: true,
|
||||
})
|
||||
otherUser := forgery.CreateUser(t, nil)
|
||||
token := getUserToken(t, user.Name, auth_model.AccessTokenScopeAll)
|
||||
|
||||
internalIssueRepo, _, reset := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
|
||||
Name: optional.Some("internal-issues"),
|
||||
EnabledUnits: optional.Some([]unit.Type{unit.TypeIssues}),
|
||||
DisabledUnits: optional.Some([]unit.Type{unit.TypeExternalTracker}),
|
||||
UnitConfig: optional.Some(map[unit.Type]convert.Conversion{
|
||||
unit.TypeIssues: &repo_model.IssuesConfig{
|
||||
EnableTimetracker: true,
|
||||
EnableDependencies: true,
|
||||
},
|
||||
}),
|
||||
internalIssueRepo := forgery.CreateRepository(t, user, repoOptions)
|
||||
forgery.DisableRepoUnits(t, internalIssueRepo, unit.TypeExternalTracker)
|
||||
forgery.EnableRepoUnit(t, internalIssueRepo, unit.TypeIssues, &repo_model.IssuesConfig{
|
||||
EnableTimetracker: true,
|
||||
EnableDependencies: true,
|
||||
})
|
||||
defer reset()
|
||||
|
||||
externalIssueRepo, _, reset := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
|
||||
Name: optional.Some("external-issues"),
|
||||
EnabledUnits: optional.Some([]unit.Type{unit.TypeExternalTracker}),
|
||||
DisabledUnits: optional.Some([]unit.Type{unit.TypeIssues}),
|
||||
})
|
||||
defer reset()
|
||||
externalIssueRepo := forgery.CreateRepository(t, user, repoOptions)
|
||||
forgery.DisableRepoUnits(t, externalIssueRepo, unit.TypeIssues)
|
||||
forgery.EnableRepoUnit(t, internalIssueRepo, unit.TypeExternalTracker, nil)
|
||||
|
||||
disabledIssueRepo, _, reset := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
|
||||
Name: optional.Some("disabled-issues"),
|
||||
DisabledUnits: optional.Some([]unit.Type{unit.TypeIssues, unit.TypeExternalTracker}),
|
||||
})
|
||||
defer reset()
|
||||
disabledIssueRepo := forgery.CreateRepository(t, user, repoOptions)
|
||||
forgery.DisableRepoUnits(t, disabledIssueRepo, unit.TypeIssues, unit.TypeExternalTracker)
|
||||
|
||||
runTest := func(t *testing.T, repo *repo_model.Repository, requestAllowed bool) {
|
||||
t.Helper()
|
||||
|
|
@ -937,15 +929,13 @@ func TestAPIIssueDependencyPermissions(t *testing.T) {
|
|||
actingUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
|
||||
token := getUserToken(t, actingUser.Name, auth_model.AccessTokenScopeAll)
|
||||
|
||||
actingUserRepo, _, reset := tests.CreateDeclarativeRepoWithOptions(t, actingUser, tests.DeclarativeRepoOptions{})
|
||||
defer reset()
|
||||
actingUserRepo := forgery.CreateRepository(t, actingUser, nil)
|
||||
actingUserIssue := createIssue(t, actingUser, actingUserRepo, "source issue", "some content")
|
||||
|
||||
otherUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
|
||||
otherUserRepo, _, reset := tests.CreateDeclarativeRepoWithOptions(t, otherUser, tests.DeclarativeRepoOptions{
|
||||
IsPrivate: optional.Some(true),
|
||||
otherUserRepo := forgery.CreateRepository(t, otherUser, &forgery.CreateRepositoryOptions{
|
||||
IsPrivate: true,
|
||||
})
|
||||
defer reset()
|
||||
otherUserIssue := createIssue(t, otherUser, otherUserRepo, "target issue", "some content")
|
||||
|
||||
apiEndpoint := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/dependencies", actingUserRepo.OwnerName, actingUserRepo.Name, actingUserIssue.Index)
|
||||
|
|
|
|||
|
|
@ -10,10 +10,9 @@ import (
|
|||
|
||||
actions_model "forgejo.org/models/actions"
|
||||
auth_model "forgejo.org/models/auth"
|
||||
org_model "forgejo.org/models/organization"
|
||||
"forgejo.org/models/unittest"
|
||||
api "forgejo.org/modules/structs"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -22,8 +21,9 @@ import (
|
|||
func TestAPIOrgVariablesCreateOrganizationVariable(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
org := unittest.AssertExistsAndLoadBean(t, &org_model.Organization{Name: "org3"})
|
||||
session := loginUser(t, "user2")
|
||||
owner := forgery.CreateUser(t, nil)
|
||||
org := forgery.CreateOrganisation(t, owner)
|
||||
session := loginUser(t, owner.Name)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization)
|
||||
|
||||
cases := []struct {
|
||||
|
|
@ -98,8 +98,9 @@ func TestAPIOrgVariablesCreateOrganizationVariable(t *testing.T) {
|
|||
func TestAPIOrgVariablesUpdateOrganizationVariable(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
org := unittest.AssertExistsAndLoadBean(t, &org_model.Organization{Name: "org3"})
|
||||
session := loginUser(t, "user2")
|
||||
owner := forgery.CreateUser(t, nil)
|
||||
org := forgery.CreateOrganisation(t, owner)
|
||||
session := loginUser(t, owner.Name)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization)
|
||||
|
||||
variableName := "test_update_var"
|
||||
|
|
@ -194,10 +195,12 @@ func TestAPIOrgVariablesUpdateOrganizationVariable(t *testing.T) {
|
|||
func TestAPIOrgVariablesDeleteOrganizationVariable(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
org := unittest.AssertExistsAndLoadBean(t, &org_model.Organization{Name: "org3"})
|
||||
owner := forgery.CreateUser(t, nil)
|
||||
org := forgery.CreateOrganisation(t, owner)
|
||||
|
||||
variable, err := actions_model.InsertVariable(t.Context(), org.ID, 0, "FORGEJO_FORBIDDEN", "illegal")
|
||||
require.NoError(t, err)
|
||||
session := loginUser(t, "user2")
|
||||
session := loginUser(t, owner.Name)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization)
|
||||
|
||||
variableName := "test_delete_var"
|
||||
|
|
@ -226,8 +229,9 @@ func TestAPIOrgVariablesDeleteOrganizationVariable(t *testing.T) {
|
|||
func TestAPIOrgVariablesGetSingleOrganizationVariable(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
org := unittest.AssertExistsAndLoadBean(t, &org_model.Organization{Name: "org3"})
|
||||
session := loginUser(t, "user2")
|
||||
owner := forgery.CreateUser(t, nil)
|
||||
org := forgery.CreateOrganisation(t, owner)
|
||||
session := loginUser(t, owner.Name)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization)
|
||||
|
||||
name := "some_variable"
|
||||
|
|
@ -258,8 +262,9 @@ func TestAPIOrgVariablesGetSingleOrganizationVariable(t *testing.T) {
|
|||
func TestAPIOrgVariablesGetAllOrganizationVariables(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
org := unittest.AssertExistsAndLoadBean(t, &org_model.Organization{Name: "org3"})
|
||||
session := loginUser(t, "user2")
|
||||
owner := forgery.CreateUser(t, nil)
|
||||
org := forgery.CreateOrganisation(t, owner)
|
||||
session := loginUser(t, owner.Name)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization)
|
||||
|
||||
variables := map[string]string{"second": "Dolor sit amet", "first": "Lorem ipsum"}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import (
|
|||
"forgejo.org/modules/private"
|
||||
"forgejo.org/modules/setting"
|
||||
"forgejo.org/modules/test"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -167,8 +167,7 @@ func TestAPIPrivateServAndNoServWithRequiredTwoFactor(t *testing.T) {
|
|||
|
||||
runTest := func(t *testing.T, user *user_model.User, useTOTP, servAllowed bool) {
|
||||
t.Helper()
|
||||
repo, _, reset := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{})
|
||||
defer reset()
|
||||
repo := forgery.CreateRepository(t, user, nil)
|
||||
|
||||
pubKey, err := asymkey_model.AddPublicKey(ctx, user.ID, "tmp-key-"+user.Name, "sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBGXEEzWmm1dxb+57RoK5KVCL0w2eNv9cqJX2AGGVlkFsVDhOXHzsadS3LTK4VlEbbrDMJdoti9yM8vclA8IeRacAAAAEc3NoOg== nocomment", 0)
|
||||
require.NoError(t, err)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import (
|
|||
"forgejo.org/models/unittest"
|
||||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/git"
|
||||
"forgejo.org/modules/optional"
|
||||
"forgejo.org/modules/setting"
|
||||
api "forgejo.org/modules/structs"
|
||||
"forgejo.org/modules/test"
|
||||
|
|
@ -34,6 +33,7 @@ import (
|
|||
mirror_service "forgejo.org/services/mirror"
|
||||
repo_service "forgejo.org/services/repository"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -313,12 +313,7 @@ func TestAPIPushMirrorSSH(t *testing.T) {
|
|||
assert.False(t, srcRepo.HasWiki())
|
||||
session := loginUser(t, user.Name)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
|
||||
pushToRepo, _, f := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
|
||||
Name: optional.Some("push-mirror-test"),
|
||||
AutoInit: optional.Some(false),
|
||||
EnabledUnits: optional.Some([]unit.Type{unit.TypeCode}),
|
||||
})
|
||||
defer f()
|
||||
pushToRepo := forgery.CreateRepository(t, user, &forgery.CreateRepositoryOptions{})
|
||||
|
||||
sshURL := fmt.Sprintf("ssh://%s@%s/%s.git", setting.SSH.User, net.JoinHostPort(setting.SSH.ListenHost, strconv.Itoa(setting.SSH.ListenPort)), pushToRepo.FullName())
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import (
|
|||
"forgejo.org/models/unittest"
|
||||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/migration"
|
||||
"forgejo.org/modules/optional"
|
||||
"forgejo.org/modules/setting"
|
||||
api "forgejo.org/modules/structs"
|
||||
"forgejo.org/modules/test"
|
||||
|
|
@ -31,6 +30,7 @@ import (
|
|||
"forgejo.org/services/forms"
|
||||
repo_service "forgejo.org/services/repository"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -281,9 +281,10 @@ func prepareQuotaEnv(t *testing.T, username string) *quotaEnv {
|
|||
env.cleanups = append(env.cleanups, userCleanup)
|
||||
|
||||
// Create a repository
|
||||
repo, _, repoCleanup := tests.CreateDeclarativeRepoWithOptions(t, env.User.User, tests.DeclarativeRepoOptions{})
|
||||
repo := forgery.CreateRepository(t, env.User.User, &forgery.CreateRepositoryOptions{
|
||||
Files: forgery.FilesInit{}, // some tests will fail with 404 if the repository is empty
|
||||
})
|
||||
env.Repo = repo
|
||||
env.cleanups = append(env.cleanups, repoCleanup)
|
||||
|
||||
return &env
|
||||
}
|
||||
|
|
@ -476,10 +477,9 @@ func testAPIQuotaEnforcement(t *testing.T) {
|
|||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// Create a template repository
|
||||
template, _, cleanup := tests.CreateDeclarativeRepoWithOptions(t, env.User.User, tests.DeclarativeRepoOptions{
|
||||
IsTemplate: optional.Some(true),
|
||||
template := forgery.CreateRepository(t, env.User.User, &forgery.CreateRepositoryOptions{
|
||||
IsTemplate: true,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
// Drop the quota to 0
|
||||
defer env.SetRuleLimit(t, "all", 0)()
|
||||
|
|
@ -513,8 +513,7 @@ func testAPIQuotaEnforcement(t *testing.T) {
|
|||
|
||||
t.Run("#/repos/{username}/{reponame}", func(t *testing.T) {
|
||||
// Lets create a new repo to play with.
|
||||
repo, _, repoCleanup := tests.CreateDeclarativeRepoWithOptions(t, env.User.User, tests.DeclarativeRepoOptions{})
|
||||
defer repoCleanup()
|
||||
repo := forgery.CreateRepository(t, env.User.User, nil)
|
||||
|
||||
// Drop the quota to 0
|
||||
defer env.SetRuleLimit(t, "all", 0)()
|
||||
|
|
@ -1198,8 +1197,7 @@ func testAPIQuotaEnforcement(t *testing.T) {
|
|||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// Create a repository to transfer
|
||||
repo, _, cleanup := tests.CreateDeclarativeRepoWithOptions(t, env.User.User, tests.DeclarativeRepoOptions{})
|
||||
defer cleanup()
|
||||
repo := forgery.CreateRepository(t, env.User.User, nil)
|
||||
|
||||
// Initiate repo transfer
|
||||
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer", env.User.User.Name, repo.Name), api.TransferRepoOption{
|
||||
|
|
@ -1233,8 +1231,7 @@ func testAPIQuotaEnforcement(t *testing.T) {
|
|||
defer env.SetRuleLimit(t, "deny-all", -1)()
|
||||
|
||||
// Create a repository to transfer
|
||||
repo, _, cleanup := tests.CreateDeclarativeRepoWithOptions(t, env.User.User, tests.DeclarativeRepoOptions{})
|
||||
defer cleanup()
|
||||
repo := forgery.CreateRepository(t, env.User.User, nil)
|
||||
|
||||
// Initiate repo transfer
|
||||
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer", env.User.User.Name, repo.Name), api.TransferRepoOption{
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ import (
|
|||
"testing"
|
||||
|
||||
auth_model "forgejo.org/models/auth"
|
||||
"forgejo.org/models/unittest"
|
||||
user_model "forgejo.org/models/user"
|
||||
api "forgejo.org/modules/structs"
|
||||
notify_service "forgejo.org/services/notify"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
|
@ -20,9 +20,9 @@ import (
|
|||
func TestAPIRepoActivityFeeds(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
|
||||
repo, _, f := tests.CreateDeclarativeRepoWithOptions(t, owner, tests.DeclarativeRepoOptions{})
|
||||
defer f()
|
||||
repo := forgery.CreateRepository(t, nil, nil)
|
||||
owner := repo.Owner
|
||||
notify_service.CreateRepository(t.Context(), owner, owner, repo)
|
||||
|
||||
feedURL := fmt.Sprintf("/api/v1/repos/%s/activities/feeds", repo.FullName())
|
||||
assertAndReturnActivities := func(t *testing.T, length int) []api.Activity {
|
||||
|
|
@ -66,7 +66,7 @@ func TestAPIRepoActivityFeeds(t *testing.T) {
|
|||
t.Run("a new watcher, no new activities", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
watcher := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
watcher := forgery.CreateUser(t, nil)
|
||||
watcherSession := loginUser(t, watcher.Name)
|
||||
watcherToken := getTokenForLoggedInUser(t, watcherSession, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeReadUser)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@ import (
|
|||
unit_model "forgejo.org/models/unit"
|
||||
"forgejo.org/models/unittest"
|
||||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/optional"
|
||||
api "forgejo.org/modules/structs"
|
||||
repo_service "forgejo.org/services/repository"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -342,11 +342,7 @@ func TestAPISetWikiGlobalEditability(t *testing.T) {
|
|||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
|
||||
|
||||
// Create a new repository for testing purposes
|
||||
repo, _, f := tests.CreateDeclarativeRepo(t, user, "", []unit_model.Type{
|
||||
unit_model.TypeCode,
|
||||
unit_model.TypeWiki,
|
||||
}, nil, nil)
|
||||
defer f()
|
||||
repo := forgery.CreateRepository(t, user, nil)
|
||||
urlStr := fmt.Sprintf("/api/v1/repos/%s", repo.FullName())
|
||||
|
||||
assertGlobalEditability := func(t *testing.T, editability bool) {
|
||||
|
|
@ -433,11 +429,8 @@ func TestAPIListPageRevisions(t *testing.T) {
|
|||
|
||||
func TestAPIWikiNonMasterBranch(t *testing.T) {
|
||||
onApplicationRun(t, func(t *testing.T, _ *url.URL) {
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
|
||||
repo, _, f := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
|
||||
WikiBranch: optional.Some("main"),
|
||||
})
|
||||
defer f()
|
||||
repo := forgery.CreateRepository(t, nil, nil)
|
||||
forgery.InitWiki(t, repo, "main")
|
||||
|
||||
uris := []string{
|
||||
"revisions/Home",
|
||||
|
|
|
|||
|
|
@ -15,13 +15,11 @@ import (
|
|||
repo_model "forgejo.org/models/repo"
|
||||
unit_model "forgejo.org/models/unit"
|
||||
"forgejo.org/models/unittest"
|
||||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/gitrepo"
|
||||
"forgejo.org/modules/optional"
|
||||
"forgejo.org/modules/test"
|
||||
repo_service "forgejo.org/services/repository"
|
||||
files_service "forgejo.org/services/repository/files"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -343,22 +341,16 @@ func TestCompareCrossRepo(t *testing.T) {
|
|||
|
||||
func TestCompareCodeExpand(t *testing.T) {
|
||||
onApplicationRun(t, func(t *testing.T, u *url.URL) {
|
||||
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
|
||||
|
||||
// Create a new repository, with a file that has many lines
|
||||
repo, _, f := tests.CreateDeclarativeRepoWithOptions(t, owner, tests.DeclarativeRepoOptions{
|
||||
Files: optional.Some([]*files_service.ChangeRepoFile{
|
||||
{
|
||||
Operation: "create",
|
||||
TreePath: "docs.md",
|
||||
ContentReader: strings.NewReader("01\n02\n03\n04\n05\n06\n07\n08\n09\n0a\n0b\n0c\n0d\n0e\n0f\n10\n11\n12\n12\n13\n14\n15\n16\n17\n18\n19\n1a\n1b\n1c\n1d\n1e\n1f\n20\n"),
|
||||
},
|
||||
}),
|
||||
repo := forgery.CreateRepository(t, nil, &forgery.CreateRepositoryOptions{
|
||||
Files: forgery.MapFS{
|
||||
"docs.md": forgery.MapFile("01\n02\n03\n04\n05\n06\n07\n08\n09\n0a\n0b\n0c\n0d\n0e\n0f\n10\n11\n12\n12\n13\n14\n15\n16\n17\n18\n19\n1a\n1b\n1c\n1d\n1e\n1f\n20\n"),
|
||||
},
|
||||
})
|
||||
defer f()
|
||||
owner := repo.Owner
|
||||
|
||||
// Fork the repository
|
||||
forker := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
forker := forgery.CreateUser(t, nil)
|
||||
session := loginUser(t, forker.Name)
|
||||
testRepoFork(t, session, owner.Name, repo.Name, forker.Name, repo.Name+"-copy")
|
||||
testCreateBranch(t, session, forker.Name, repo.Name+"-copy", "branch/main", "code-expand", http.StatusSeeOther)
|
||||
|
|
|
|||
|
|
@ -26,16 +26,15 @@ import (
|
|||
"forgejo.org/models/unittest"
|
||||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/indexer/issues"
|
||||
"forgejo.org/modules/optional"
|
||||
"forgejo.org/modules/references"
|
||||
"forgejo.org/modules/setting"
|
||||
api "forgejo.org/modules/structs"
|
||||
"forgejo.org/modules/test"
|
||||
"forgejo.org/modules/translation"
|
||||
repo_service "forgejo.org/services/repository"
|
||||
files_service "forgejo.org/services/repository/files"
|
||||
user_service "forgejo.org/services/user"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -489,8 +488,7 @@ func TestIssueDependencies(t *testing.T) {
|
|||
session := loginUser(t, owner.Name)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue)
|
||||
|
||||
repo, _, f := tests.CreateDeclarativeRepoWithOptions(t, owner, tests.DeclarativeRepoOptions{})
|
||||
defer f()
|
||||
repo := forgery.CreateRepository(t, owner, nil)
|
||||
|
||||
createIssue := func(t *testing.T, title string) api.Issue {
|
||||
t.Helper()
|
||||
|
|
@ -1359,13 +1357,9 @@ func TestIssueForm(t *testing.T) {
|
|||
onApplicationRun(t, func(t *testing.T, u *url.URL) {
|
||||
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
session := loginUser(t, user2.Name)
|
||||
repo, _, f := tests.CreateDeclarativeRepo(t, user2, "",
|
||||
[]unit_model.Type{unit_model.TypeCode, unit_model.TypeIssues}, nil,
|
||||
[]*files_service.ChangeRepoFile{
|
||||
{
|
||||
Operation: "create",
|
||||
TreePath: ".forgejo/issue_template/test.yaml",
|
||||
ContentReader: strings.NewReader(`name: Test
|
||||
repo := forgery.CreateRepository(t, user2, &forgery.CreateRepositoryOptions{
|
||||
Files: forgery.MapFS{
|
||||
".forgejo/issue_template/test.yaml": forgery.MapFile(`name: Test
|
||||
about: Hello World
|
||||
body:
|
||||
- type: checkboxes
|
||||
|
|
@ -1375,10 +1369,8 @@ body:
|
|||
options:
|
||||
- label: This is a label
|
||||
`),
|
||||
},
|
||||
},
|
||||
)
|
||||
defer f()
|
||||
})
|
||||
|
||||
t.Run("Choose list", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
|
@ -1407,10 +1399,7 @@ body:
|
|||
func TestIssueUnsubscription(t *testing.T) {
|
||||
onApplicationRun(t, func(t *testing.T, u *url.URL) {
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
|
||||
repo, _, f := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
|
||||
AutoInit: optional.Some(false),
|
||||
})
|
||||
defer f()
|
||||
repo := forgery.CreateRepository(t, user, &forgery.CreateRepositoryOptions{})
|
||||
session := loginUser(t, user.Name)
|
||||
|
||||
issueURL := testNewIssue(t, session, user.Name, repo.Name, "Issue title", "Description")
|
||||
|
|
|
|||
|
|
@ -20,13 +20,13 @@ import (
|
|||
"forgejo.org/models/unit"
|
||||
"forgejo.org/models/unittest"
|
||||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/optional"
|
||||
"forgejo.org/modules/setting"
|
||||
"forgejo.org/modules/structs"
|
||||
"forgejo.org/modules/test"
|
||||
"forgejo.org/modules/translation"
|
||||
"forgejo.org/services/migrations"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -196,11 +196,9 @@ func TestMigrateWithWiki(t *testing.T) {
|
|||
defer test.MockVariableValue(&setting.AppVer, "1.16.0")()
|
||||
require.NoError(t, migrations.Init())
|
||||
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
repo, _, f := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
|
||||
WikiBranch: optional.Some("obscure-name"),
|
||||
})
|
||||
defer f()
|
||||
repo := forgery.CreateRepository(t, nil, nil)
|
||||
forgery.InitWiki(t, repo, "obscure-name")
|
||||
user := repo.Owner
|
||||
|
||||
session := loginUser(t, user.Name)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeReadMisc)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import (
|
|||
"forgejo.org/modules/git"
|
||||
"forgejo.org/modules/gitrepo"
|
||||
"forgejo.org/modules/migration"
|
||||
"forgejo.org/modules/optional"
|
||||
"forgejo.org/modules/process"
|
||||
"forgejo.org/modules/setting"
|
||||
"forgejo.org/modules/structs"
|
||||
|
|
@ -34,6 +33,7 @@ import (
|
|||
repo_service "forgejo.org/services/repository"
|
||||
files_service "forgejo.org/services/repository/files"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/google/uuid"
|
||||
|
|
@ -183,19 +183,14 @@ func TestMirrorPull(t *testing.T) {
|
|||
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
|
||||
// Create the source repository that will be mirrored.
|
||||
sourceRepo, sourceRepoSha, cleanupSource := tests.CreateDeclarativeRepoWithOptions(t, user2,
|
||||
tests.DeclarativeRepoOptions{
|
||||
IsPrivate: optional.Some(mc.privateSource),
|
||||
Files: optional.Some([]*files_service.ChangeRepoFile{
|
||||
{
|
||||
Operation: "create",
|
||||
TreePath: "docs.md",
|
||||
ContentReader: strings.NewReader("hello, world"),
|
||||
},
|
||||
}),
|
||||
var sourceRepoSha string
|
||||
sourceRepo := forgery.CreateRepository(t, user2, &forgery.CreateRepositoryOptions{
|
||||
IsPrivate: mc.privateSource,
|
||||
Files: forgery.MapFS{
|
||||
"docs.md": forgery.MapFile("hello, world"),
|
||||
},
|
||||
)
|
||||
defer cleanupSource()
|
||||
LatestSha: &sourceRepoSha,
|
||||
})
|
||||
require.NotEmpty(t, sourceRepoSha)
|
||||
|
||||
// Create pull mirror
|
||||
|
|
@ -239,10 +234,7 @@ func TestMirrorPull(t *testing.T) {
|
|||
|
||||
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
|
||||
mirrorRepo, _, cleanupMirror := tests.CreateDeclarativeRepoWithOptions(t, user2,
|
||||
tests.DeclarativeRepoOptions{},
|
||||
)
|
||||
defer cleanupMirror()
|
||||
mirrorRepo := forgery.CreateRepository(t, user2, nil)
|
||||
|
||||
// Write to the repo a config file that would have plausibly existed before EncryptedRemoteAddress was
|
||||
// introduced:
|
||||
|
|
@ -343,8 +335,8 @@ func createPullMirrorViaWeb(t *testing.T, sourceRepo *repo_model.Repository, aut
|
|||
body := resp.Body.String()
|
||||
lastBody = body
|
||||
// Looking for the repo page to be fully populated indicating that the migration is complete:
|
||||
// Check that the first commit message is present:
|
||||
if !strings.Contains(body, "Initial commit") {
|
||||
// Check that the committed file is present:
|
||||
if !strings.Contains(body, "docs.md") {
|
||||
return false
|
||||
}
|
||||
// Check that the fork button is present:
|
||||
|
|
|
|||
|
|
@ -21,12 +21,10 @@ import (
|
|||
auth_model "forgejo.org/models/auth"
|
||||
"forgejo.org/models/db"
|
||||
repo_model "forgejo.org/models/repo"
|
||||
"forgejo.org/models/unit"
|
||||
"forgejo.org/models/unittest"
|
||||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/git"
|
||||
"forgejo.org/modules/gitrepo"
|
||||
"forgejo.org/modules/optional"
|
||||
"forgejo.org/modules/setting"
|
||||
api "forgejo.org/modules/structs"
|
||||
"forgejo.org/modules/test"
|
||||
|
|
@ -37,6 +35,7 @@ import (
|
|||
mirror_service "forgejo.org/services/mirror"
|
||||
repo_service "forgejo.org/services/repository"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -228,12 +227,7 @@ func TestSSHPushMirror(t *testing.T) {
|
|||
assert.False(t, srcRepo.HasWiki())
|
||||
sess := loginUser(t, user.Name)
|
||||
|
||||
pushToRepo, _, f := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
|
||||
Name: optional.Some("push-mirror-misc-test"),
|
||||
AutoInit: optional.Some(false),
|
||||
EnabledUnits: optional.Some([]unit.Type{unit.TypeCode}),
|
||||
})
|
||||
defer f()
|
||||
pushToRepo := forgery.CreateRepository(t, user, &forgery.CreateRepositoryOptions{})
|
||||
sshURL := fmt.Sprintf("ssh://%s@%s/%s.git", setting.SSH.User, net.JoinHostPort(setting.SSH.ListenHost, strconv.Itoa(setting.SSH.ListenPort)), pushToRepo.FullName())
|
||||
|
||||
t.Run("Mutual exclusive", func(t *testing.T) {
|
||||
|
|
@ -286,12 +280,7 @@ func TestSSHPushMirror(t *testing.T) {
|
|||
testMirrorPush := func(t *testing.T, srcRepo *repo_model.Repository, expectedSHA string) {
|
||||
t.Helper()
|
||||
|
||||
pushToRepo, _, f := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
|
||||
Name: optional.Some("push-mirror-test"),
|
||||
AutoInit: optional.Some(false),
|
||||
EnabledUnits: optional.Some([]unit.Type{unit.TypeCode}),
|
||||
})
|
||||
defer f()
|
||||
pushToRepo := forgery.CreateRepository(t, user, &forgery.CreateRepositoryOptions{})
|
||||
sshURL := fmt.Sprintf("ssh://%s@%s/%s.git", setting.SSH.User, net.JoinHostPort(setting.SSH.ListenHost, strconv.Itoa(setting.SSH.ListenPort)), pushToRepo.FullName())
|
||||
|
||||
var pushMirror *repo_model.PushMirror
|
||||
|
|
@ -404,8 +393,7 @@ func TestPushMirrorBranchFilterWebUI(t *testing.T) {
|
|||
srcRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
||||
sess := loginUser(t, user.Name)
|
||||
|
||||
mirrorRepo, _, f := tests.CreateDeclarativeRepo(t, user, "", []unit.Type{unit.TypeCode}, nil, nil)
|
||||
defer f()
|
||||
mirrorRepo := forgery.CreateRepository(t, user, nil)
|
||||
|
||||
ctx := NewAPITestContext(t, user.LowerName, srcRepo.Name, auth_model.AccessTokenScopeReadRepository)
|
||||
ctx.Session = sess
|
||||
|
|
@ -595,12 +583,8 @@ func TestPushMirrorSettings(t *testing.T) {
|
|||
srcRepo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
|
||||
assert.False(t, srcRepo.HasWiki())
|
||||
sess := loginUser(t, user.Name)
|
||||
pushToRepo, _, f := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
|
||||
Name: optional.Some("push-mirror-test"),
|
||||
AutoInit: optional.Some(false),
|
||||
EnabledUnits: optional.Some([]unit.Type{unit.TypeCode}),
|
||||
})
|
||||
defer f()
|
||||
|
||||
pushToRepo := forgery.CreateRepository(t, user, &forgery.CreateRepositoryOptions{})
|
||||
|
||||
t.Run("Adding", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
|
@ -904,8 +888,7 @@ func TestPushMirrorWebUIToAPIIntegration(t *testing.T) {
|
|||
session := loginUser(t, user.Name)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAll)
|
||||
|
||||
mirrorRepo, _, f := tests.CreateDeclarativeRepo(t, user, "", []unit.Type{unit.TypeCode}, nil, nil)
|
||||
defer f()
|
||||
mirrorRepo := forgery.CreateRepository(t, user, nil)
|
||||
|
||||
ctx := NewAPITestContext(t, user.LowerName, srcRepo.Name, auth_model.AccessTokenScopeReadRepository)
|
||||
ctx.Session = session
|
||||
|
|
@ -941,8 +924,7 @@ func TestPushMirrorWebUIToAPIIntegration(t *testing.T) {
|
|||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// Create another mirror repo for this test
|
||||
mirrorRepo2, _, f := tests.CreateDeclarativeRepo(t, user, "", []unit.Type{unit.TypeCode}, nil, nil)
|
||||
defer f()
|
||||
mirrorRepo2 := forgery.CreateRepository(t, user, nil)
|
||||
remoteAddress2 := fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(user.Name), url.PathEscape(mirrorRepo2.Name))
|
||||
|
||||
// Create push mirror with empty branch filter via web UI
|
||||
|
|
@ -967,8 +949,7 @@ func TestPushMirrorWebUIToAPIIntegration(t *testing.T) {
|
|||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// Create another mirror repo for this test
|
||||
mirrorRepo3, _, f := tests.CreateDeclarativeRepo(t, user, "", []unit.Type{unit.TypeCode}, nil, nil)
|
||||
defer f()
|
||||
mirrorRepo3 := forgery.CreateRepository(t, user, nil)
|
||||
remoteAddress3 := fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(user.Name), url.PathEscape(mirrorRepo3.Name))
|
||||
|
||||
// Create push mirror with complex branch filter via web UI
|
||||
|
|
@ -994,8 +975,7 @@ func TestPushMirrorWebUIToAPIIntegration(t *testing.T) {
|
|||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// Create another mirror repo for this test
|
||||
mirrorRepo4, _, f := tests.CreateDeclarativeRepo(t, user, "", []unit.Type{unit.TypeCode}, nil, nil)
|
||||
defer f()
|
||||
mirrorRepo4 := forgery.CreateRepository(t, user, nil)
|
||||
remoteAddress4 := fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(user.Name), url.PathEscape(mirrorRepo4.Name))
|
||||
|
||||
// First create a push mirror via API with initial branch filter
|
||||
|
|
|
|||
|
|
@ -10,22 +10,19 @@ import (
|
|||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
issues_model "forgejo.org/models/issues"
|
||||
repo_model "forgejo.org/models/repo"
|
||||
unit_model "forgejo.org/models/unit"
|
||||
"forgejo.org/models/unittest"
|
||||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/git"
|
||||
"forgejo.org/modules/optional"
|
||||
"forgejo.org/modules/test"
|
||||
pull_service "forgejo.org/services/pull"
|
||||
files_service "forgejo.org/services/repository/files"
|
||||
shared_automerge "forgejo.org/services/shared/automerge"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -36,24 +33,17 @@ func TestPatchStatus(t *testing.T) {
|
|||
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
session := loginUser(t, user2.Name)
|
||||
|
||||
var objectFormat optional.Option[string]
|
||||
var objectFormat git.ObjectFormat
|
||||
if git.SupportHashSha256 {
|
||||
objectFormat = optional.Some("sha256")
|
||||
objectFormat = git.Sha256ObjectFormat
|
||||
}
|
||||
|
||||
repo, _, f := tests.CreateDeclarativeRepoWithOptions(t, user2, tests.DeclarativeRepoOptions{
|
||||
AutoInit: optional.Some(true),
|
||||
EnabledUnits: optional.Some([]unit_model.Type{unit_model.TypeCode}),
|
||||
repo := forgery.CreateRepository(t, user2, &forgery.CreateRepositoryOptions{
|
||||
Files: forgery.MapFS{
|
||||
".spokeperson": forgery.MapFile("n0toose"),
|
||||
},
|
||||
ObjectFormat: objectFormat,
|
||||
Files: optional.Some([]*files_service.ChangeRepoFile{
|
||||
{
|
||||
Operation: "create",
|
||||
TreePath: ".spokeperson",
|
||||
ContentReader: strings.NewReader("n0toose"),
|
||||
},
|
||||
}),
|
||||
})
|
||||
defer f()
|
||||
|
||||
testAutomergeQueued := func(t *testing.T, pr *issues_model.PullRequest, expected issues_model.PullRequestStatus) {
|
||||
t.Helper()
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import (
|
|||
repo_service "forgejo.org/services/repository"
|
||||
files_service "forgejo.org/services/repository/files"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/google/uuid"
|
||||
|
|
@ -1816,21 +1817,14 @@ func newPullRequestCommentPlacementTester(t *testing.T) *PullRequestCommentPlace
|
|||
content.WriteString(fmt.Sprintf("Line %d\n", i+1)) // +1 -> make "Line N" appear on the Nth line and avoid off-by-one confusions
|
||||
}
|
||||
|
||||
repo, initialSHA, reset := tests.CreateDeclarativeRepoWithOptions(t, user2, tests.DeclarativeRepoOptions{
|
||||
Files: optional.Some([]*files_service.ChangeRepoFile{
|
||||
{
|
||||
Operation: "create",
|
||||
TreePath: "file1.md",
|
||||
ContentReader: strings.NewReader(content.String()),
|
||||
},
|
||||
{
|
||||
Operation: "create",
|
||||
TreePath: "file2.md",
|
||||
ContentReader: strings.NewReader(content.String()),
|
||||
},
|
||||
}),
|
||||
var initialSHA string
|
||||
repo := forgery.CreateRepository(t, user2, &forgery.CreateRepositoryOptions{
|
||||
Files: forgery.MapFS{
|
||||
"file1.md": forgery.MapFile(content.String()),
|
||||
"file2.md": forgery.MapFile(content.String()),
|
||||
},
|
||||
LatestSha: &initialSHA,
|
||||
})
|
||||
t.Cleanup(reset)
|
||||
|
||||
return &PullRequestCommentPlacementTester{
|
||||
t: t,
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import (
|
|||
org_model "forgejo.org/models/organization"
|
||||
quota_model "forgejo.org/models/quota"
|
||||
repo_model "forgejo.org/models/repo"
|
||||
"forgejo.org/models/unittest"
|
||||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/git"
|
||||
"forgejo.org/modules/setting"
|
||||
|
|
@ -29,8 +28,8 @@ import (
|
|||
app_context "forgejo.org/services/context"
|
||||
repo_service "forgejo.org/services/repository"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
gouuid "github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
|
@ -1025,13 +1024,13 @@ func createQuotaWebEnv(t *testing.T) *quotaWebEnv {
|
|||
user := quotaWebEnvUser{}
|
||||
|
||||
// Create the user
|
||||
userName := gouuid.NewString()
|
||||
apiCreateUser(t, userName)
|
||||
user.User = unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: userName})
|
||||
user.Session = loginUser(t, userName)
|
||||
user.User = forgery.CreateUser(t, nil)
|
||||
user.Session = loginUser(t, user.User.Name)
|
||||
|
||||
// Create a repository for the user
|
||||
repo, _, _ := tests.CreateDeclarativeRepoWithOptions(t, user.User, tests.DeclarativeRepoOptions{})
|
||||
repo := forgery.CreateRepository(t, user.User, &forgery.CreateRepositoryOptions{
|
||||
Files: forgery.FilesInit{},
|
||||
})
|
||||
user.Repo = repo
|
||||
|
||||
return user
|
||||
|
|
@ -1072,25 +1071,21 @@ func createQuotaWebEnv(t *testing.T) *quotaWebEnv {
|
|||
org := quotaWebEnvOrg{}
|
||||
|
||||
// Create the org
|
||||
userName := gouuid.NewString()
|
||||
org.Org = &org_model.Organization{
|
||||
Name: userName,
|
||||
}
|
||||
err := org_model.CreateOrganization(db.DefaultContext, org.Org, owner)
|
||||
require.NoError(t, err)
|
||||
org.Org = forgery.CreateOrganisation(t, owner)
|
||||
|
||||
// Create a repository for the org
|
||||
orgUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: org.Org.ID})
|
||||
repo, _, _ := tests.CreateDeclarativeRepoWithOptions(t, orgUser, tests.DeclarativeRepoOptions{})
|
||||
repo := forgery.CreateRepository(t, org.Org.AsUser(), &forgery.CreateRepositoryOptions{
|
||||
Files: forgery.FilesInit{},
|
||||
})
|
||||
org.Repo = repo
|
||||
|
||||
// Create a quota group for them
|
||||
group, err := quota_model.CreateGroup(db.DefaultContext, userName)
|
||||
group, err := quota_model.CreateGroup(db.DefaultContext, org.Org.Name)
|
||||
require.NoError(t, err)
|
||||
org.QuotaGroup = group
|
||||
|
||||
// Create a rule
|
||||
rule, err := quota_model.CreateRule(db.DefaultContext, userName, limit, quota_model.LimitSubjects{quota_model.LimitSubjectSizeAll})
|
||||
rule, err := quota_model.CreateRule(db.DefaultContext, org.Org.Name, limit, quota_model.LimitSubjects{quota_model.LimitSubjectSizeAll})
|
||||
require.NoError(t, err)
|
||||
org.QuotaRule = rule
|
||||
|
||||
|
|
|
|||
|
|
@ -17,12 +17,11 @@ import (
|
|||
"forgejo.org/models/unittest"
|
||||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/git"
|
||||
"forgejo.org/modules/optional"
|
||||
"forgejo.org/modules/setting"
|
||||
"forgejo.org/modules/test"
|
||||
"forgejo.org/modules/translation"
|
||||
files_service "forgejo.org/services/repository/files"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
|
@ -243,40 +242,27 @@ func TestRepoGenerateTemplating(t *testing.T) {
|
|||
expected := `# %s
|
||||
This is a Repo By %s
|
||||
ThisIsThe%sInAnInlineWay`
|
||||
templateName := "my_template"
|
||||
generatedName := "my_generated"
|
||||
|
||||
userName := "user1"
|
||||
session := loginUser(t, userName)
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: userName})
|
||||
|
||||
template, _, f := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
|
||||
Name: optional.Some(templateName),
|
||||
IsTemplate: optional.Some(true),
|
||||
Files: optional.Some([]*files_service.ChangeRepoFile{
|
||||
{
|
||||
Operation: "create",
|
||||
TreePath: ".forgejo/template",
|
||||
ContentReader: strings.NewReader("**/Readme.md"),
|
||||
},
|
||||
{
|
||||
Operation: "create",
|
||||
TreePath: "dira-${REPO_NAME}/dirb-${REPO_NAME}/Readme.md",
|
||||
ContentReader: strings.NewReader(input),
|
||||
},
|
||||
}),
|
||||
template := forgery.CreateRepository(t, nil, &forgery.CreateRepositoryOptions{
|
||||
IsTemplate: true,
|
||||
Files: forgery.MapFS{
|
||||
".forgejo/template": forgery.MapFile("**/Readme.md"),
|
||||
"dira-${REPO_NAME}/dirb-${REPO_NAME}/Readme.md": forgery.MapFile(input),
|
||||
},
|
||||
})
|
||||
defer f()
|
||||
user := template.Owner
|
||||
session := loginUser(t, user.Name)
|
||||
|
||||
// The repo.TemplateID field is not initialized. Luckily, the ID field holds the expected value
|
||||
templateID := strconv.FormatInt(template.ID, 10)
|
||||
generatedName := "my_generated"
|
||||
|
||||
testRepoGenerateSuccess(
|
||||
t,
|
||||
session,
|
||||
templateID,
|
||||
user.Name,
|
||||
templateName,
|
||||
template.Name,
|
||||
user,
|
||||
user,
|
||||
generatedName,
|
||||
|
|
@ -310,9 +296,10 @@ func TestRepoGenerateTemplating(t *testing.T) {
|
|||
|
||||
func TestRepoGenerateTemplatingSymlink(t *testing.T) {
|
||||
onApplicationRun(t, func(t *testing.T, u *url.URL) {
|
||||
userName := "user1"
|
||||
session := loginUser(t, userName)
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: userName})
|
||||
user := forgery.CreateUser(t, &forgery.CreateUserOptions{
|
||||
IsAdmin: true, // required to see the detailed error message on the error response
|
||||
})
|
||||
session := loginUser(t, user.Name)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
|
@ -337,34 +324,18 @@ func TestRepoGenerateTemplatingSymlink(t *testing.T) {
|
|||
|
||||
for i, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
templateName := fmt.Sprintf("my_template-%d", i)
|
||||
generatedName := fmt.Sprintf("my_generated-%d", i)
|
||||
template, _, f := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
|
||||
Name: optional.Some(templateName),
|
||||
IsTemplate: optional.Some(true),
|
||||
Files: optional.Some([]*files_service.ChangeRepoFile{
|
||||
{
|
||||
Operation: "create",
|
||||
TreePath: ".forgejo/template",
|
||||
ContentReader: strings.NewReader("**/Readme.md"),
|
||||
},
|
||||
{
|
||||
Operation: "create",
|
||||
TreePath: "actual-contents.txt",
|
||||
ContentReader: strings.NewReader("Here are some contents. $REPO_NAME"),
|
||||
},
|
||||
{
|
||||
Operation: "create",
|
||||
TreePath: "problem/Readme.md",
|
||||
ContentReader: strings.NewReader(tc.symlinkTarget),
|
||||
Options: files_service.RepoFileOptionMode(git.EntryModeSymlink),
|
||||
},
|
||||
}),
|
||||
template := forgery.CreateRepository(t, user, &forgery.CreateRepositoryOptions{
|
||||
IsTemplate: true,
|
||||
Files: forgery.MapFS{
|
||||
".forgejo/template": forgery.MapFile("**/Readme.md"),
|
||||
"actual-contents.txt": forgery.MapFile("Here are some contents. $REPO_NAME"),
|
||||
"problem/Readme.md": forgery.MapSymlink(tc.symlinkTarget),
|
||||
},
|
||||
})
|
||||
defer f()
|
||||
|
||||
// The repo.TemplateID field is not initialized. Luckily, the ID field holds the expected value
|
||||
templateID := strconv.FormatInt(template.ID, 10)
|
||||
generatedName := fmt.Sprintf("my_generated-%d", i)
|
||||
|
||||
if tc.expectedError != "" {
|
||||
resp := testRepoGenerateFailure(
|
||||
|
|
@ -372,7 +343,7 @@ func TestRepoGenerateTemplatingSymlink(t *testing.T) {
|
|||
session,
|
||||
templateID,
|
||||
user.Name,
|
||||
templateName,
|
||||
template.Name,
|
||||
user,
|
||||
user,
|
||||
generatedName,
|
||||
|
|
@ -384,7 +355,7 @@ func TestRepoGenerateTemplatingSymlink(t *testing.T) {
|
|||
session,
|
||||
templateID,
|
||||
user.Name,
|
||||
templateName,
|
||||
template.Name,
|
||||
user,
|
||||
user,
|
||||
generatedName,
|
||||
|
|
@ -419,36 +390,28 @@ func TestRepoGenerateTemplatingSymlink(t *testing.T) {
|
|||
|
||||
func TestRepoGenerateTemplatingSymlinkGlobFile(t *testing.T) {
|
||||
onApplicationRun(t, func(t *testing.T, u *url.URL) {
|
||||
templateName := "my_template"
|
||||
generatedName := "my_generated"
|
||||
|
||||
userName := "user1"
|
||||
session := loginUser(t, userName)
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: userName})
|
||||
|
||||
template, _, f := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
|
||||
Name: optional.Some(templateName),
|
||||
IsTemplate: optional.Some(true),
|
||||
Files: optional.Some([]*files_service.ChangeRepoFile{
|
||||
{
|
||||
Operation: "create",
|
||||
TreePath: ".forgejo/template",
|
||||
ContentReader: strings.NewReader("/etc/passwd"),
|
||||
Options: files_service.RepoFileOptionMode(git.EntryModeSymlink),
|
||||
},
|
||||
}),
|
||||
user := forgery.CreateUser(t, &forgery.CreateUserOptions{
|
||||
IsAdmin: true, // required to see the detailed error message on the error response
|
||||
})
|
||||
session := loginUser(t, user.Name)
|
||||
|
||||
template := forgery.CreateRepository(t, user, &forgery.CreateRepositoryOptions{
|
||||
IsTemplate: true,
|
||||
Files: forgery.MapFS{
|
||||
".forgejo/template": forgery.MapSymlink("/etc/passwd"),
|
||||
},
|
||||
})
|
||||
defer f()
|
||||
|
||||
// The repo.TemplateID field is not initialized. Luckily, the ID field holds the expected value
|
||||
templateID := strconv.FormatInt(template.ID, 10)
|
||||
generatedName := "my_generated"
|
||||
|
||||
resp := testRepoGenerateFailure(
|
||||
t,
|
||||
session,
|
||||
templateID,
|
||||
user.Name,
|
||||
templateName,
|
||||
template.Name,
|
||||
user,
|
||||
user,
|
||||
generatedName,
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import (
|
|||
"forgejo.org/models/unittest"
|
||||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/git"
|
||||
"forgejo.org/modules/optional"
|
||||
"forgejo.org/modules/setting"
|
||||
api "forgejo.org/modules/structs"
|
||||
"forgejo.org/modules/test"
|
||||
|
|
@ -32,6 +31,7 @@ import (
|
|||
repo_service "forgejo.org/services/repository"
|
||||
files_service "forgejo.org/services/repository/files"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -1369,21 +1369,17 @@ func TestInitInstructions(t *testing.T) {
|
|||
|
||||
forEachObjectFormat(t, func(t *testing.T, objectFormat git.ObjectFormat) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
name := objectFormat.Name()
|
||||
|
||||
var init string
|
||||
if name == "sha1" {
|
||||
if objectFormat == git.Sha1ObjectFormat {
|
||||
init = "git init"
|
||||
} else {
|
||||
init = fmt.Sprintf("git init --object-format=%s", name)
|
||||
init = fmt.Sprintf("git init --object-format=%s", objectFormat.Name())
|
||||
}
|
||||
|
||||
repo, _, f := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
|
||||
Name: optional.Some(name + "-instruction"),
|
||||
AutoInit: optional.Some(false),
|
||||
EnabledUnits: optional.Some([]unit_model.Type{unit_model.TypeCode}),
|
||||
ObjectFormat: optional.Some(name),
|
||||
repo := forgery.CreateRepository(t, user, &forgery.CreateRepositoryOptions{
|
||||
ObjectFormat: objectFormat,
|
||||
})
|
||||
defer f()
|
||||
|
||||
portMatcher := regexp.MustCompile(`localhost:\d+`)
|
||||
resp := session.MakeRequest(t, NewRequest(t, "GET", "/"+repo.FullName()), http.StatusOK)
|
||||
|
|
@ -1394,7 +1390,7 @@ func TestInitInstructions(t *testing.T) {
|
|||
git switch -c main
|
||||
git add README.md
|
||||
git commit -m "first commit"
|
||||
git remote add origin http://localhost/user2/%s-instruction.git
|
||||
git push -u origin main`, init, name), portMatcher.ReplaceAllString(htmlDoc.Find(".empty-repo-guide code").First().Text(), "localhost"))
|
||||
git remote add origin http://localhost/user2/%s.git
|
||||
git push -u origin main`, init, repo.Name), portMatcher.ReplaceAllString(htmlDoc.Find(".empty-repo-guide code").First().Text(), "localhost"))
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ import (
|
|||
"forgejo.org/models/unittest"
|
||||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/git"
|
||||
"forgejo.org/modules/optional"
|
||||
api "forgejo.org/modules/structs"
|
||||
"forgejo.org/modules/util"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/google/uuid"
|
||||
|
|
@ -95,11 +95,10 @@ func doRepoWikiGitOperation(t *testing.T, serverURL *url.URL, method RepoWikiMet
|
|||
repo := "repo1"
|
||||
if target == RepoWikiPrivate {
|
||||
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
privateRepo, _, reset := tests.CreateDeclarativeRepoWithOptions(t, user2, tests.DeclarativeRepoOptions{
|
||||
IsPrivate: optional.Some(true),
|
||||
EnabledUnits: optional.Some([]unit_model.Type{unit_model.TypeWiki}),
|
||||
privateRepo := forgery.CreateRepository(t, user2, &forgery.CreateRepositoryOptions{
|
||||
IsPrivate: true,
|
||||
})
|
||||
defer reset()
|
||||
forgery.EnableRepoUnit(t, privateRepo, unit_model.TypeWiki, nil)
|
||||
|
||||
session := loginUser(t, user2.LoginName)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@ import (
|
|||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"testing/fstest"
|
||||
"time"
|
||||
|
||||
"forgejo.org/models/db"
|
||||
|
|
@ -29,10 +29,9 @@ import (
|
|||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/base"
|
||||
"forgejo.org/modules/git"
|
||||
"forgejo.org/modules/gitrepo"
|
||||
"forgejo.org/modules/graceful"
|
||||
"forgejo.org/modules/log"
|
||||
"forgejo.org/modules/optional"
|
||||
"forgejo.org/modules/options"
|
||||
"forgejo.org/modules/process"
|
||||
repo_module "forgejo.org/modules/repository"
|
||||
"forgejo.org/modules/setting"
|
||||
|
|
@ -40,12 +39,10 @@ import (
|
|||
"forgejo.org/modules/testlogger"
|
||||
"forgejo.org/modules/util"
|
||||
"forgejo.org/routers"
|
||||
repo_service "forgejo.org/services/repository"
|
||||
"forgejo.org/services/notify"
|
||||
files_service "forgejo.org/services/repository/files"
|
||||
wiki_service "forgejo.org/services/wiki"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"xorm.io/xorm/convert"
|
||||
|
||||
|
|
@ -386,169 +383,74 @@ func Printf(format string, args ...any) {
|
|||
testlogger.Printf(format, args...)
|
||||
}
|
||||
|
||||
type DeclarativeRepoOptions struct {
|
||||
Name optional.Option[string]
|
||||
EnabledUnits optional.Option[[]unit_model.Type]
|
||||
DisabledUnits optional.Option[[]unit_model.Type]
|
||||
UnitConfig optional.Option[map[unit_model.Type]convert.Conversion]
|
||||
Files optional.Option[[]*files_service.ChangeRepoFile]
|
||||
WikiBranch optional.Option[string]
|
||||
AutoInit optional.Option[bool]
|
||||
IsTemplate optional.Option[bool]
|
||||
ObjectFormat optional.Option[string]
|
||||
IsPrivate optional.Option[bool]
|
||||
}
|
||||
|
||||
func CreateDeclarativeRepoWithOptions(t *testing.T, owner *user_model.User, opts DeclarativeRepoOptions) (*repo_model.Repository, string, func()) {
|
||||
t.Helper()
|
||||
|
||||
// Not using opts.Name.ValueOrDefault() here to avoid unnecessarily
|
||||
// generating an UUID when a name is specified.
|
||||
var repoName string
|
||||
if has, value := opts.Name.Get(); has {
|
||||
repoName = value
|
||||
} else {
|
||||
repoName = uuid.NewString()
|
||||
}
|
||||
|
||||
var autoInit bool
|
||||
if has, value := opts.AutoInit.Get(); has {
|
||||
autoInit = value
|
||||
} else {
|
||||
autoInit = true
|
||||
}
|
||||
|
||||
// Create the repository
|
||||
repo, err := repo_service.CreateRepository(db.DefaultContext, owner, owner, repo_service.CreateRepoOptions{
|
||||
Name: repoName,
|
||||
Description: "Temporary Repo",
|
||||
AutoInit: autoInit,
|
||||
Gitignores: "",
|
||||
License: "WTFPL",
|
||||
Readme: "Default",
|
||||
DefaultBranch: "main",
|
||||
IsTemplate: opts.IsTemplate.ValueOrZeroValue(),
|
||||
ObjectFormatName: opts.ObjectFormat.ValueOrZeroValue(),
|
||||
IsPrivate: opts.IsPrivate.ValueOrZeroValue(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, repo)
|
||||
|
||||
// Populate `enabledUnits` if we have any enabled.
|
||||
var enabledUnits []repo_model.RepoUnit
|
||||
if has, units := opts.EnabledUnits.Get(); has {
|
||||
enabledUnits = make([]repo_model.RepoUnit, len(units))
|
||||
|
||||
for i, unitType := range units {
|
||||
var config convert.Conversion
|
||||
if cfg, ok := opts.UnitConfig.ValueOrZeroValue()[unitType]; ok {
|
||||
config = cfg
|
||||
}
|
||||
enabledUnits[i] = repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unitType,
|
||||
Config: config,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust the repo units according to our parameters.
|
||||
if opts.EnabledUnits.Has() || opts.DisabledUnits.Has() {
|
||||
err := repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, enabledUnits, opts.DisabledUnits.ValueOrDefault(nil))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// Add files, if any.
|
||||
var sha string
|
||||
if has, files := opts.Files.Get(); has {
|
||||
assert.True(t, autoInit, "Files cannot be specified if AutoInit is disabled")
|
||||
|
||||
commitID, err := gitrepo.GetBranchCommitID(git.DefaultContext, repo, "main")
|
||||
require.NoError(t, err)
|
||||
|
||||
resp, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, owner, &files_service.ChangeRepoFilesOptions{
|
||||
Files: files,
|
||||
Message: "add files",
|
||||
OldBranch: "main",
|
||||
NewBranch: "main",
|
||||
Author: &files_service.IdentityOptions{
|
||||
Name: owner.Name,
|
||||
Email: owner.Email,
|
||||
},
|
||||
Committer: &files_service.IdentityOptions{
|
||||
Name: owner.Name,
|
||||
Email: owner.Email,
|
||||
},
|
||||
Dates: &files_service.CommitDateOptions{
|
||||
Author: time.Now(),
|
||||
Committer: time.Now(),
|
||||
},
|
||||
LastCommitID: commitID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, resp)
|
||||
|
||||
sha = resp.Commit.SHA
|
||||
}
|
||||
|
||||
// If there's a Wiki branch specified, create a wiki, and a default wiki page.
|
||||
if has, value := opts.WikiBranch.Get(); has {
|
||||
// Set the wiki branch in the database first
|
||||
repo.WikiBranch = value
|
||||
err := repo_model.UpdateRepositoryCols(db.DefaultContext, repo, "wiki_branch")
|
||||
require.NoError(t, err)
|
||||
|
||||
// Initialize the wiki
|
||||
err = wiki_service.InitWiki(db.DefaultContext, repo)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Add a new wiki page
|
||||
err = wiki_service.AddWikiPage(db.DefaultContext, owner, repo, "Home", "Welcome to the wiki!", "Add a Home page")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// Return the repo, the top commit, and a defer-able function to delete the
|
||||
// repo.
|
||||
return repo, sha, func() {
|
||||
_ = repo_service.DeleteRepository(db.DefaultContext, owner, repo, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated: use forgery.CreateRepository instead
|
||||
func CreateDeclarativeRepo(t *testing.T, owner *user_model.User, name string, enabledUnits, disabledUnits []unit_model.Type, files []*files_service.ChangeRepoFile) (*repo_model.Repository, string, func()) {
|
||||
t.Helper()
|
||||
|
||||
var opts DeclarativeRepoOptions
|
||||
|
||||
if name != "" {
|
||||
opts.Name = optional.Some(name)
|
||||
opts := &forgery.CreateRepositoryOptions{
|
||||
LatestSha: new(string),
|
||||
Name: name,
|
||||
}
|
||||
if enabledUnits != nil {
|
||||
opts.EnabledUnits = optional.Some(enabledUnits)
|
||||
|
||||
if slices.Contains(enabledUnits, unit_model.TypePullRequests) {
|
||||
opts.UnitConfig = optional.Some(map[unit_model.Type]convert.Conversion{
|
||||
unit_model.TypePullRequests: &repo_model.PullRequestsConfig{
|
||||
AllowMerge: true,
|
||||
AllowRebase: true,
|
||||
AllowRebaseMerge: true,
|
||||
AllowSquash: true,
|
||||
AllowFastForwardOnly: true,
|
||||
AllowManualMerge: true,
|
||||
AllowRebaseUpdate: true,
|
||||
DefaultMergeStyle: repo_model.MergeStyleMerge,
|
||||
DefaultUpdateStyle: repo_model.UpdateStyleMerge,
|
||||
},
|
||||
})
|
||||
if len(files) > 0 {
|
||||
licenseData, err := options.License("CC0-1.0")
|
||||
require.NoError(t, err)
|
||||
mfs := forgery.MapFS{
|
||||
"README.md": forgery.MapFile("# " + t.Name() + "\n\nThis is a test repo created via test_utils"),
|
||||
"LICENSE": &fstest.MapFile{Data: licenseData},
|
||||
}
|
||||
for _, f := range files {
|
||||
require.Empty(t, f.FromTreePath, f.TreePath)
|
||||
if f.Operation != "create" {
|
||||
require.Equal(t, "README.md", f.TreePath, "%q operation only expected on README.md", f.Operation)
|
||||
if f.Operation == "delete" {
|
||||
delete(mfs, f.TreePath)
|
||||
continue
|
||||
}
|
||||
require.Equal(t, "update", f.Operation, "only update/delete operations are supported on README.md")
|
||||
}
|
||||
if f.SHA != "" {
|
||||
require.Nil(t, f.ContentReader, f.TreePath)
|
||||
mfs[f.TreePath] = forgery.MapSubmodule(f.SHA)
|
||||
} else {
|
||||
require.Nil(t, f.Options, f.TreePath)
|
||||
|
||||
data, err := io.ReadAll(f.ContentReader)
|
||||
require.NoError(t, err)
|
||||
mfs[f.TreePath] = &fstest.MapFile{
|
||||
Data: data,
|
||||
}
|
||||
}
|
||||
}
|
||||
opts.Files = mfs
|
||||
} else {
|
||||
opts.Files = forgery.FilesInit{}
|
||||
}
|
||||
|
||||
repo := forgery.CreateRepository(t, owner, opts)
|
||||
notify.CreateRepository(t.Context(), owner, owner, repo) // CreateDeclarativeRepoWithOptions didn't call CreateRepositoryDirectly; notify manually to keep the same behavior
|
||||
|
||||
for _, unitType := range enabledUnits {
|
||||
var config convert.Conversion
|
||||
if unitType == unit_model.TypePullRequests {
|
||||
config = &repo_model.PullRequestsConfig{
|
||||
AllowMerge: true,
|
||||
AllowRebase: true,
|
||||
AllowRebaseMerge: true,
|
||||
AllowSquash: true,
|
||||
AllowFastForwardOnly: true,
|
||||
AllowManualMerge: true,
|
||||
AllowRebaseUpdate: true,
|
||||
DefaultMergeStyle: repo_model.MergeStyleMerge,
|
||||
DefaultUpdateStyle: repo_model.UpdateStyleMerge,
|
||||
}
|
||||
}
|
||||
forgery.EnableRepoUnit(t, repo, unitType, config)
|
||||
}
|
||||
if disabledUnits != nil {
|
||||
opts.DisabledUnits = optional.Some(disabledUnits)
|
||||
forgery.DisableRepoUnits(t, repo, disabledUnits...)
|
||||
}
|
||||
if files != nil {
|
||||
opts.Files = optional.Some(files)
|
||||
}
|
||||
|
||||
return CreateDeclarativeRepoWithOptions(t, owner, opts)
|
||||
return repo, *opts.LatestSha, func() {}
|
||||
}
|
||||
|
||||
func WriteImageBody(t *testing.T, buff bytes.Buffer, filename string, body *bytes.Buffer) string {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue