Merge branch 'forgejo' into bugfix-arch

This commit is contained in:
Exploding Dragon 2024-08-27 02:34:54 +00:00
commit bc4849a904
71 changed files with 1044 additions and 365 deletions

View file

@ -14,6 +14,7 @@ env:
rules:
playwright/no-conditional-in-test: [0]
playwright/no-conditional-expect: [0]
playwright/no-networkidle: [0]
playwright/no-skipped-test: [2, {allowConditional: true}]
playwright/prefer-comparison-matcher: [2]

View file

@ -24,7 +24,8 @@ func TestDebugserver(t *testing.T) {
done := make(chan os.Signal, 1)
signal.Notify(done, syscall.SIGINT, syscall.SIGTERM)
onGiteaRun(t, func(*testing.T, *url.URL) {
onForgejoRun(t, func(*testing.T, *url.URL) {
defer DeclareGitRepos(t)()
fmt.Println(setting.AppURL)
<-done
})

View file

@ -0,0 +1,83 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: GPL-3.0-or-later
package e2e
import (
"fmt"
"strconv"
"strings"
"testing"
"time"
unit_model "code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
files_service "code.gitea.io/gitea/services/repository/files"
"code.gitea.io/gitea/tests"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type FileChanges [][]string
// 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() {
var cleanupFunctions []func()
cleanupFunctions = append(cleanupFunctions, newRepo(t, 2, "diff-test", FileChanges{
{"testfile", "hello", "hallo", "hola", "native", "ubuntu-latest", "- runs-on: ubuntu-latest", "- runs-on: debian-latest"},
}))
return func() {
for _, cleanup := range cleanupFunctions {
cleanup()
}
}
}
func newRepo(t *testing.T, userID int64, repoName string, fileChanges FileChanges) func() {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID})
somerepo, _, cleanupFunc := tests.CreateDeclarativeRepo(t, user, repoName,
[]unit_model.Type{unit_model.TypeCode, unit_model.TypeIssues}, nil,
nil,
)
for _, file := range fileChanges {
changeLen := len(file)
for i := 1; i < changeLen; i++ {
operation := "create"
if i != 1 {
operation = "update"
}
resp, err := files_service.ChangeRepoFiles(git.DefaultContext, somerepo, user, &files_service.ChangeRepoFilesOptions{
Files: []*files_service.ChangeRepoFile{{
Operation: operation,
TreePath: file[0],
ContentReader: strings.NewReader(file[i]),
}},
Message: fmt.Sprintf("Patch: %s-%s", file[0], strconv.Itoa(i)),
OldBranch: "main",
NewBranch: "main",
Author: &files_service.IdentityOptions{
Name: user.Name,
Email: user.Email,
},
Committer: &files_service.IdentityOptions{
Name: user.Name,
Email: user.Email,
},
Dates: &files_service.CommitDateOptions{
Author: time.Now(),
Committer: time.Now(),
},
})
require.NoError(t, err)
assert.NotEmpty(t, resp)
}
}
return cleanupFunc
}

View file

@ -37,7 +37,7 @@ func TestMain(m *testing.M) {
graceful.InitManager(managerCtx)
defer cancel()
tests.InitTest(false)
tests.InitTest(true)
testE2eWebRoutes = routers.NormalRoutes()
os.Unsetenv("GIT_AUTHOR_NAME")
@ -102,7 +102,8 @@ func TestE2e(t *testing.T) {
t.Run(testname, func(t *testing.T) {
// Default 2 minute timeout
onGiteaRun(t, func(*testing.T, *url.URL) {
onForgejoRun(t, func(*testing.T, *url.URL) {
defer DeclareGitRepos(t)()
thisTest := runArgs
thisTest = append(thisTest, path)
cmd := exec.Command(runArgs[0], thisTest...)

View file

@ -51,3 +51,29 @@ test('Line Range Selection', async ({browser}, workerInfo) => {
await page.goto(`${filePath}#L1-L100`);
await assertSelectedLines(page, ['1', '2', '3']);
});
test('Readable diff', async ({page}, workerInfo) => {
// remove this when the test covers more (e.g. accessibility scans or interactive behaviour)
test.skip(workerInfo.project.name !== 'firefox', 'This currently only tests the backend-generated HTML code and it is not necessary to test with multiple browsers.');
const expectedDiffs = [
{id: 'testfile-2', removed: 'e', added: 'a'},
{id: 'testfile-3', removed: 'allo', added: 'ola'},
{id: 'testfile-4', removed: 'hola', added: 'native'},
{id: 'testfile-5', removed: 'native', added: 'ubuntu-latest'},
{id: 'testfile-6', added: '- runs-on: '},
{id: 'testfile-7', removed: 'ubuntu', added: 'debian'},
];
for (const thisDiff of expectedDiffs) {
const response = await page.goto('/user2/diff-test/commits/branch/main');
await expect(response?.status()).toBe(200); // Status OK
await page.getByText(`Patch: ${thisDiff.id}`).click();
if (thisDiff.removed) {
await expect(page.getByText(thisDiff.removed, {exact: true})).toHaveClass(/removed-code/);
await expect(page.getByText(thisDiff.removed, {exact: true})).toHaveCSS('background-color', 'rgb(252, 165, 165)');
}
if (thisDiff.added) {
await expect(page.getByText(thisDiff.added, {exact: true})).toHaveClass(/added-code/);
await expect(page.getByText(thisDiff.added, {exact: true})).toHaveCSS('background-color', 'rgb(134, 239, 172)');
}
}
});

View file

@ -17,7 +17,7 @@ import (
"github.com/stretchr/testify/require"
)
func onGiteaRunTB(t testing.TB, callback func(testing.TB, *url.URL), prepare ...bool) {
func onForgejoRunTB(t testing.TB, callback func(testing.TB, *url.URL), prepare ...bool) {
if len(prepare) == 0 || prepare[0] {
defer tests.PrepareTestEnv(t, 1)()
}
@ -49,8 +49,8 @@ func onGiteaRunTB(t testing.TB, callback func(testing.TB, *url.URL), prepare ...
callback(t, u)
}
func onGiteaRun(t *testing.T, callback func(*testing.T, *url.URL), prepare ...bool) {
onGiteaRunTB(t, func(t testing.TB, u *url.URL) {
func onForgejoRun(t *testing.T, callback func(*testing.T, *url.URL), prepare ...bool) {
onForgejoRunTB(t, func(t testing.TB, u *url.URL) {
callback(t.(*testing.T), u)
}, prepare...)
}

View file

@ -11,6 +11,7 @@ import (
"net/http"
"net/url"
"os"
"os/exec"
"path/filepath"
"strconv"
"testing"
@ -23,6 +24,7 @@ import (
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
@ -141,6 +143,11 @@ func testAPIPushMirror(t *testing.T, u *url.URL) {
}
func TestAPIPushMirrorSSH(t *testing.T) {
_, err := exec.LookPath("ssh")
if err != nil {
t.Skip("SSH executable not present")
}
onGiteaRun(t, func(t *testing.T, _ *url.URL) {
defer test.MockVariableValue(&setting.Migrations.AllowLocalNetworks, true)()
defer test.MockVariableValue(&setting.Mirror.Enabled, true)()
@ -178,6 +185,22 @@ func TestAPIPushMirrorSSH(t *testing.T) {
assert.EqualValues(t, "'use_ssh' is mutually exclusive with 'remote_username' and 'remote_passoword'", apiError.Message)
})
t.Run("SSH not available", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
defer test.MockVariableValue(&git.HasSSHExecutable, false)()
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/push_mirrors", srcRepo.FullName()), &api.CreatePushMirrorOption{
RemoteAddress: sshURL,
Interval: "8h",
UseSSH: true,
}).AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusBadRequest)
var apiError api.APIError
DecodeJSON(t, resp, &apiError)
assert.EqualValues(t, "SSH authentication not available.", apiError.Message)
})
t.Run("Normal", func(t *testing.T) {
var pushMirror *repo_model.PushMirror
t.Run("Adding", func(t *testing.T) {

View file

@ -15,7 +15,7 @@ import (
"code.gitea.io/gitea/routers"
"code.gitea.io/gitea/tests"
"gitea.com/go-chi/session"
"code.forgejo.org/go-chi/session"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

View file

@ -11,6 +11,7 @@ import (
"net/http"
"net/url"
"os"
"os/exec"
"path/filepath"
"strconv"
"testing"
@ -157,6 +158,11 @@ func doRemovePushMirror(ctx APITestContext, address, username, password string,
}
func TestSSHPushMirror(t *testing.T) {
_, err := exec.LookPath("ssh")
if err != nil {
t.Skip("SSH executable not present")
}
onGiteaRun(t, func(t *testing.T, _ *url.URL) {
defer test.MockVariableValue(&setting.Migrations.AllowLocalNetworks, true)()
defer test.MockVariableValue(&setting.Mirror.Enabled, true)()
@ -194,6 +200,36 @@ func TestSSHPushMirror(t *testing.T) {
assert.Contains(t, errMsg, "Cannot use public key and password based authentication in combination.")
})
inputSelector := `input[id="push_mirror_use_ssh"]`
t.Run("SSH not available", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
defer test.MockVariableValue(&git.HasSSHExecutable, false)()
req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/settings", srcRepo.FullName()), map[string]string{
"_csrf": GetCSRF(t, sess, fmt.Sprintf("/%s/settings", srcRepo.FullName())),
"action": "push-mirror-add",
"push_mirror_address": sshURL,
"push_mirror_use_ssh": "true",
"push_mirror_interval": "0",
})
resp := sess.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
errMsg := htmlDoc.Find(".ui.negative.message").Text()
assert.Contains(t, errMsg, "SSH authentication isn't available.")
htmlDoc.AssertElement(t, inputSelector, false)
})
t.Run("SSH available", func(t *testing.T) {
req := NewRequest(t, "GET", fmt.Sprintf("/%s/settings", srcRepo.FullName()))
resp := sess.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
htmlDoc.AssertElement(t, inputSelector, true)
})
t.Run("Normal", func(t *testing.T) {
var pushMirror *repo_model.PushMirror
t.Run("Adding", func(t *testing.T) {

View file

@ -548,6 +548,42 @@ func TestGitQuotaEnforcement(t *testing.T) {
})
}
func TestQuotaConfigDefault(t *testing.T) {
onGiteaRun(t, func(t *testing.T, u *url.URL) {
env := createQuotaWebEnv(t)
defer env.Cleanup()
t.Run("with config-based default", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
defer test.MockVariableValue(&setting.Quota.Default.Total, 0)()
env.As(t, env.Users.Ungrouped).
With(Context{
Payload: &Payload{
"uid": env.Users.Ungrouped.ID().AsString(),
"repo_name": "quota-config-default",
},
}).
PostToPage("/repo/create").
ExpectStatus(http.StatusRequestEntityTooLarge)
})
t.Run("without config-based default", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
env.As(t, env.Users.Ungrouped).
With(Context{
Payload: &Payload{
"uid": env.Users.Ungrouped.ID().AsString(),
"repo_name": "quota-config-default",
},
}).
PostToPage("/repo/create").
ExpectStatus(http.StatusSeeOther)
})
})
}
/**********************
* Here be dragons! *
* *
@ -568,6 +604,7 @@ type quotaWebEnv struct {
type quotaWebEnvUsers struct {
Limited quotaWebEnvUser
Contributor quotaWebEnvUser
Ungrouped quotaWebEnvUser
}
type quotaWebEnvOrgs struct {
@ -1005,8 +1042,7 @@ func createQuotaWebEnv(t *testing.T) *quotaWebEnv {
// *** helpers ***
// Create a user, its quota group & rule
makeUser := func(t *testing.T, limit int64) quotaWebEnvUser {
makeUngroupedUser := func(t *testing.T) quotaWebEnvUser {
t.Helper()
user := quotaWebEnvUser{}
@ -1021,6 +1057,16 @@ func createQuotaWebEnv(t *testing.T) *quotaWebEnv {
repo, _, _ := tests.CreateDeclarativeRepoWithOptions(t, user.User, tests.DeclarativeRepoOptions{})
user.Repo = repo
return user
}
// Create a user, its quota group & rule
makeUser := func(t *testing.T, limit int64) quotaWebEnvUser {
t.Helper()
user := makeUngroupedUser(t)
userName := user.User.Name
// Create a quota group for them
group, err := quota_model.CreateGroup(db.DefaultContext, userName)
require.NoError(t, err)
@ -1095,5 +1141,7 @@ func createQuotaWebEnv(t *testing.T) *quotaWebEnv {
env.Orgs.Limited = makeOrg(t, env.Users.Limited.User, int64(0))
env.Orgs.Unlimited = makeOrg(t, env.Users.Limited.User, int64(-1))
env.Users.Ungrouped = makeUngroupedUser(t)
return &env
}

View file

@ -52,8 +52,13 @@ func createRepoAndGetContext(t *testing.T, files []string, deleteMdReadme bool)
ctx, _ := contexttest.MockContext(t, "user1/readmetest")
ctx.SetParams(":id", fmt.Sprint(repo.ID))
contexttest.LoadRepo(t, ctx, repo.ID)
contexttest.LoadGitRepo(t, ctx)
contexttest.LoadRepoCommit(t, ctx)
return ctx, f
return ctx, func() {
f()
ctx.Repo.GitRepo.Close()
}
}
func TestRepoView_FindReadme(t *testing.T) {

View file

@ -12,11 +12,11 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/services/contexttest"
files_service "code.gitea.io/gitea/services/repository/files"
"github.com/stretchr/testify/assert"
@ -247,16 +247,8 @@ func getExpectedFileResponseForRepofilesUpdate(commitID, filename, lastCommitSHA
func TestChangeRepoFilesForCreate(t *testing.T) {
// setup
onGiteaRun(t, func(t *testing.T, u *url.URL) {
ctx, _ := contexttest.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository
doer := ctx.Doer
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
opts := getCreateRepoFilesOptions(repo)
// test
@ -284,16 +276,8 @@ func TestChangeRepoFilesForCreate(t *testing.T) {
func TestChangeRepoFilesForUpdate(t *testing.T) {
// setup
onGiteaRun(t, func(t *testing.T, u *url.URL) {
ctx, _ := contexttest.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository
doer := ctx.Doer
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
opts := getUpdateRepoFilesOptions(repo)
// test
@ -318,16 +302,8 @@ func TestChangeRepoFilesForUpdate(t *testing.T) {
func TestChangeRepoFilesForUpdateWithFileMove(t *testing.T) {
// setup
onGiteaRun(t, func(t *testing.T, u *url.URL) {
ctx, _ := contexttest.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository
doer := ctx.Doer
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
opts := getUpdateRepoFilesOptions(repo)
opts.Files[0].FromTreePath = "README.md"
opts.Files[0].TreePath = "README_new.md" // new file name, README_new.md
@ -369,16 +345,8 @@ func TestChangeRepoFilesForUpdateWithFileMove(t *testing.T) {
func TestChangeRepoFilesWithoutBranchNames(t *testing.T) {
// setup
onGiteaRun(t, func(t *testing.T, u *url.URL) {
ctx, _ := contexttest.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository
doer := ctx.Doer
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
opts := getUpdateRepoFilesOptions(repo)
opts.OldBranch = ""
opts.NewBranch = ""
@ -405,15 +373,8 @@ func TestChangeRepoFilesForDelete(t *testing.T) {
func testDeleteRepoFiles(t *testing.T, u *url.URL) {
// setup
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository
doer := ctx.Doer
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
opts := getDeleteRepoFilesOptions(repo)
t.Run("Delete README.md file", func(t *testing.T) {
@ -444,16 +405,9 @@ func TestChangeRepoFilesForDeleteWithoutBranchNames(t *testing.T) {
func testDeleteRepoFilesWithoutBranchNames(t *testing.T, u *url.URL) {
// setup
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repo := ctx.Repo.Repository
doer := ctx.Doer
opts := getDeleteRepoFilesOptions(repo)
opts.OldBranch = ""
opts.NewBranch = ""
@ -474,16 +428,8 @@ func testDeleteRepoFilesWithoutBranchNames(t *testing.T, u *url.URL) {
func TestChangeRepoFilesErrors(t *testing.T) {
// setup
onGiteaRun(t, func(t *testing.T, u *url.URL) {
ctx, _ := contexttest.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
repo := ctx.Repo.Repository
doer := ctx.Doer
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
t.Run("bad branch", func(t *testing.T) {
opts := getUpdateRepoFilesOptions(repo)

View file

@ -389,7 +389,7 @@ func TestUserHints(t *testing.T) {
assert.Equal(t, enabled, hintChecked)
link, _ := htmlDoc.Find("form[action='/user/settings/appearance/language'] a").Attr("href")
assert.EqualValues(t, "https://forgejo.org/docs/latest/developer/localization/", link)
assert.EqualValues(t, "https://forgejo.org/docs/next/contributor/localization/", link)
}
t.Run("view", func(t *testing.T) {