Merge branch 'go-gitea:main' into main

This commit is contained in:
Karthik Bhandary
2026-03-06 12:51:40 +05:30
committed by GitHub
311 changed files with 7747 additions and 5482 deletions
@@ -643,7 +643,7 @@ jobs:
assert.Equal(t, "job-main-v1.24.0", wf2Job2Rerun1Job.ConcurrencyGroup)
// rerun wf2-job2
req = NewRequest(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/%d/rerun", user2.Name, repo.Name, wf2Run.Index, 1))
req = NewRequest(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/1/rerun", user2.Name, repo.Name, wf2Run.Index))
_ = session.MakeRequest(t, req, http.StatusOK)
// (rerun2) fetch and exec wf2-job2
wf2Job2Rerun2Task := runner1.fetchTask(t)
@@ -1064,11 +1064,10 @@ jobs:
})
// rerun cancel true scenario
req = NewRequest(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/%d/rerun", user2.Name, apiRepo.Name, run2.Index, 1))
req = NewRequest(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/0/rerun", user2.Name, apiRepo.Name, run2.Index))
_ = session.MakeRequest(t, req, http.StatusOK)
req = NewRequest(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/%d/rerun", user2.Name, apiRepo.Name, run4.Index, 1))
req = NewRequest(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/0/rerun", user2.Name, apiRepo.Name, run4.Index))
_ = session.MakeRequest(t, req, http.StatusOK)
task5 := runner.fetchTask(t)
@@ -1084,13 +1083,13 @@ jobs:
// rerun cancel false scenario
req = NewRequest(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/%d/rerun", user2.Name, apiRepo.Name, run2.Index, 1))
req = NewRequest(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/0/rerun", user2.Name, apiRepo.Name, run2.Index))
_ = session.MakeRequest(t, req, http.StatusOK)
run2_2 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{ID: run2.ID})
assert.Equal(t, actions_model.StatusWaiting, run2_2.Status)
req = NewRequest(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/%d/rerun", user2.Name, apiRepo.Name, run2.Index+1, 1))
req = NewRequest(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/0/rerun", user2.Name, apiRepo.Name, run2.Index+1))
_ = session.MakeRequest(t, req, http.StatusOK)
task6 := runner.fetchTask(t)
+1 -1
View File
@@ -83,7 +83,7 @@ func (r *mockRunner) doRegister(t *testing.T, name, token string, labels []strin
func (r *mockRunner) registerAsRepoRunner(t *testing.T, ownerName, repoName, runnerName string, labels []string, ephemeral bool) {
session := loginUser(t, ownerName)
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/actions/runners/registration-token", ownerName, repoName)).AddTokenAuth(token)
req := NewRequest(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/actions/runners/registration-token", ownerName, repoName)).AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusOK)
var registrationToken struct {
Token string `json:"token"`
+23 -1
View File
@@ -38,6 +38,7 @@ import (
files_service "code.gitea.io/gitea/services/repository/files"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPullRequestTargetEvent(t *testing.T) {
@@ -437,7 +438,7 @@ jobs:
assert.NotNil(t, run)
// delete the branch
err = repo_service.DeleteBranch(t.Context(), user2, repo, gitRepo, "test-create-branch", nil)
err = repo_service.DeleteBranch(t.Context(), user2, repo, gitRepo, "test-create-branch")
assert.NoError(t, err)
run = unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{
Title: "add workflow",
@@ -906,6 +907,27 @@ jobs:
CommitSHA: branch.CommitID,
})
assert.NotNil(t, run)
// Now trigger with rundetails
values.Set("return_run_details", "true")
req = NewRequestWithURLValues(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/workflows/dispatch.yml/dispatches", repo.FullName()), values).
AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusOK)
runDetails := &api.RunDetails{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(runDetails))
assert.NotEqual(t, 0, runDetails.WorkflowRunID)
run = unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{
ID: runDetails.WorkflowRunID,
Title: "add workflow",
RepoID: repo.ID,
Event: "workflow_dispatch",
Ref: "refs/heads/main",
WorkflowID: "dispatch.yml",
CommitSHA: branch.CommitID,
})
assert.NotNil(t, run)
})
}
+46
View File
@@ -7,10 +7,14 @@ import (
"net/http"
"testing"
"code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/setting/config"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/tests"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestAdminConfig(t *testing.T) {
@@ -20,4 +24,46 @@ func TestAdminConfig(t *testing.T) {
req := NewRequest(t, "GET", "/-/admin/config")
resp := session.MakeRequest(t, req, http.StatusOK)
assert.True(t, test.IsNormalPageCompleted(resp.Body.String()))
t.Run("OpenEditorWithApps", func(t *testing.T) {
cfg := setting.Config().Repository.OpenWithEditorApps
editorApps := cfg.Value(t.Context())
assert.Len(t, editorApps, 3)
assert.False(t, cfg.HasValue(t.Context()))
require.NoError(t, system.SetSettings(t.Context(), map[string]string{cfg.DynKey(): "[]"}))
config.GetDynGetter().InvalidateCache()
editorApps = cfg.Value(t.Context())
assert.Len(t, editorApps, 3)
assert.False(t, cfg.HasValue(t.Context()))
require.NoError(t, system.SetSettings(t.Context(), map[string]string{cfg.DynKey(): "[{}]"}))
config.GetDynGetter().InvalidateCache()
editorApps = cfg.Value(t.Context())
assert.Len(t, editorApps, 1)
assert.True(t, cfg.HasValue(t.Context()))
})
t.Run("InstanceWebBanner", func(t *testing.T) {
banner, rev1, has := setting.Config().Instance.WebBanner.ValueRevision(t.Context())
assert.False(t, has)
assert.Equal(t, setting.WebBannerType{}, banner)
req = NewRequestWithValues(t, "POST", "/-/admin/config", map[string]string{
"key": "instance.web_banner",
"value": `{"DisplayEnabled":true,"ContentMessage":"test-msg","StartTimeUnix":123,"EndTimeUnix":456}`,
})
session.MakeRequest(t, req, http.StatusOK)
banner, rev2, has := setting.Config().Instance.WebBanner.ValueRevision(t.Context())
assert.NotEqual(t, rev1, rev2)
assert.True(t, has)
assert.Equal(t, setting.WebBannerType{
DisplayEnabled: true,
ContentMessage: "test-msg",
StartTimeUnix: 123,
EndTimeUnix: 456,
}, banner)
})
}
+2 -2
View File
@@ -43,10 +43,10 @@ func TestAdminViewUser(t *testing.T) {
func TestAdminEditUser(t *testing.T) {
defer tests.PrepareTestEnv(t)()
testSuccessfullEdit(t, user_model.User{ID: 2, Name: "newusername", LoginName: "otherlogin", Email: "new@e-mail.gitea"})
testSuccessfulEdit(t, user_model.User{ID: 2, Name: "newusername", LoginName: "otherlogin", Email: "new@e-mail.gitea"})
}
func testSuccessfullEdit(t *testing.T, formData user_model.User) {
func testSuccessfulEdit(t *testing.T, formData user_model.User) {
makeRequest(t, formData, http.StatusSeeOther)
}
+128 -36
View File
@@ -6,6 +6,7 @@ package integration
import (
"bytes"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"encoding/xml"
"fmt"
@@ -22,6 +23,7 @@ import (
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/storage"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/routers/api/actions"
actions_service "code.gitea.io/gitea/services/actions"
@@ -45,45 +47,135 @@ func TestActionsArtifactV4UploadSingleFile(t *testing.T) {
token, err := actions_service.CreateAuthorizationToken(48, 792, 193)
assert.NoError(t, err)
// acquire artifact upload url
req := NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact", toProtoJSON(&actions.CreateArtifactRequest{
Version: 4,
Name: "artifact",
WorkflowRunBackendId: "792",
WorkflowJobRunBackendId: "193",
})).AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusOK)
var uploadResp actions.CreateArtifactResponse
protojson.Unmarshal(resp.Body.Bytes(), &uploadResp)
assert.True(t, uploadResp.Ok)
assert.Contains(t, uploadResp.SignedUploadUrl, "/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact")
table := []struct {
name string
version int32
blockID bool
noLength bool
append int
}{
{
name: "artifact",
version: 4,
},
{
name: "artifact2",
version: 4,
blockID: true,
},
{
name: "artifact3",
version: 4,
noLength: true,
},
{
name: "artifact4",
version: 4,
blockID: true,
noLength: true,
},
{
name: "artifact5",
version: 7,
blockID: true,
},
{
name: "artifact6",
version: 7,
append: 2,
noLength: true,
},
{
name: "artifact7",
version: 7,
append: 3,
blockID: true,
noLength: true,
},
{
name: "artifact8",
version: 7,
append: 4,
blockID: true,
},
}
// get upload url
idx := strings.Index(uploadResp.SignedUploadUrl, "/twirp/")
url := uploadResp.SignedUploadUrl[idx:] + "&comp=block"
for _, entry := range table {
t.Run(entry.name, func(t *testing.T) {
// acquire artifact upload url
req := NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact", toProtoJSON(&actions.CreateArtifactRequest{
Version: entry.version,
Name: entry.name,
WorkflowRunBackendId: "792",
WorkflowJobRunBackendId: "193",
})).AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusOK)
var uploadResp actions.CreateArtifactResponse
protojson.Unmarshal(resp.Body.Bytes(), &uploadResp)
assert.True(t, uploadResp.Ok)
assert.Contains(t, uploadResp.SignedUploadUrl, "/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact")
// upload artifact chunk
body := strings.Repeat("A", 1024)
req = NewRequestWithBody(t, "PUT", url, strings.NewReader(body))
MakeRequest(t, req, http.StatusCreated)
h := sha256.New()
t.Logf("Create artifact confirm")
blocks := make([]string, 0, util.Iif(entry.blockID, entry.append+1, 0))
sha := sha256.Sum256([]byte(body))
// get upload url
idx := strings.Index(uploadResp.SignedUploadUrl, "/twirp/")
for i := range entry.append + 1 {
url := uploadResp.SignedUploadUrl[idx:]
// See https://learn.microsoft.com/en-us/rest/api/storageservices/append-block
// See https://learn.microsoft.com/en-us/rest/api/storageservices/put-block
if entry.blockID {
blockID := base64.RawURLEncoding.EncodeToString(fmt.Append([]byte("SOME_BIG_BLOCK_ID_"), i))
blocks = append(blocks, blockID)
url += "&comp=block&blockid=" + blockID
} else {
url += "&comp=appendBlock"
}
// confirm artifact upload
req = NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/FinalizeArtifact", toProtoJSON(&actions.FinalizeArtifactRequest{
Name: "artifact",
Size: 1024,
Hash: wrapperspb.String("sha256:" + hex.EncodeToString(sha[:])),
WorkflowRunBackendId: "792",
WorkflowJobRunBackendId: "193",
})).
AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
var finalizeResp actions.FinalizeArtifactResponse
protojson.Unmarshal(resp.Body.Bytes(), &finalizeResp)
assert.True(t, finalizeResp.Ok)
// upload artifact chunk
body := strings.Repeat("A", 1024)
_, _ = h.Write([]byte(body))
var bodyReader io.Reader = strings.NewReader(body)
if entry.noLength {
bodyReader = io.MultiReader(bodyReader)
}
req = NewRequestWithBody(t, "PUT", url, bodyReader)
MakeRequest(t, req, http.StatusCreated)
}
if entry.blockID && entry.append > 0 {
// https://learn.microsoft.com/en-us/rest/api/storageservices/put-block-list
blockListURL := uploadResp.SignedUploadUrl[idx:] + "&comp=blocklist"
// upload artifact blockList
blockList := &actions.BlockList{
Latest: blocks,
}
rawBlockList, err := xml.Marshal(blockList)
assert.NoError(t, err)
req = NewRequestWithBody(t, "PUT", blockListURL, bytes.NewReader(rawBlockList))
MakeRequest(t, req, http.StatusCreated)
}
sha := h.Sum(nil)
t.Logf("Create artifact confirm")
// confirm artifact upload
req = NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/FinalizeArtifact", toProtoJSON(&actions.FinalizeArtifactRequest{
Name: entry.name,
Size: int64(entry.append+1) * 1024,
Hash: wrapperspb.String("sha256:" + hex.EncodeToString(sha)),
WorkflowRunBackendId: "792",
WorkflowJobRunBackendId: "193",
})).
AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
var finalizeResp actions.FinalizeArtifactResponse
protojson.Unmarshal(resp.Body.Bytes(), &finalizeResp)
assert.True(t, finalizeResp.Ok)
})
}
}
func TestActionsArtifactV4UploadSingleFileWrongChecksum(t *testing.T) {
@@ -312,7 +404,7 @@ func TestActionsArtifactV4DownloadSingle(t *testing.T) {
token, err := actions_service.CreateAuthorizationToken(48, 792, 193)
assert.NoError(t, err)
// acquire artifact upload url
// list artifacts by name
req := NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/ListArtifacts", toProtoJSON(&actions.ListArtifactsRequest{
NameFilter: wrapperspb.String("artifact-v4-download"),
WorkflowRunBackendId: "792",
@@ -323,7 +415,7 @@ func TestActionsArtifactV4DownloadSingle(t *testing.T) {
protojson.Unmarshal(resp.Body.Bytes(), &listResp)
assert.Len(t, listResp.Artifacts, 1)
// confirm artifact upload
// acquire artifact download url
req = NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/GetSignedArtifactURL", toProtoJSON(&actions.GetSignedArtifactURLRequest{
Name: "artifact-v4-download",
WorkflowRunBackendId: "792",
+123
View File
@@ -169,3 +169,126 @@ func testAPIActionsDeleteRunListTasks(t *testing.T, repo *repo_model.Repository,
assert.Equal(t, expected, findTask1)
assert.Equal(t, expected, findTask2)
}
func TestAPIActionsRerunWorkflowRun(t *testing.T) {
defer prepareTestEnvActionsArtifacts(t)()
t.Run("NotDone", func(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, user.Name)
writeToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/runs/793/rerun", repo.FullName())).
AddTokenAuth(writeToken)
MakeRequest(t, req, http.StatusBadRequest)
})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, user.Name)
writeToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
readToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository)
t.Run("Success", func(t *testing.T) {
req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/runs/795/rerun", repo.FullName())).
AddTokenAuth(writeToken)
resp := MakeRequest(t, req, http.StatusCreated)
var rerunResp api.ActionWorkflowRun
err := json.Unmarshal(resp.Body.Bytes(), &rerunResp)
require.NoError(t, err)
assert.Equal(t, int64(795), rerunResp.ID)
assert.Equal(t, "queued", rerunResp.Status)
assert.Equal(t, "c2d72f548424103f01ee1dc02889c1e2bff816b0", rerunResp.HeadSha)
run, err := actions_model.GetRunByRepoAndID(t.Context(), repo.ID, 795)
require.NoError(t, err)
assert.Equal(t, actions_model.StatusWaiting, run.Status)
assert.Equal(t, timeutil.TimeStamp(0), run.Started)
assert.Equal(t, timeutil.TimeStamp(0), run.Stopped)
job198, err := actions_model.GetRunJobByID(t.Context(), 198)
require.NoError(t, err)
assert.Equal(t, actions_model.StatusWaiting, job198.Status)
assert.Equal(t, int64(0), job198.TaskID)
job199, err := actions_model.GetRunJobByID(t.Context(), 199)
require.NoError(t, err)
assert.Equal(t, actions_model.StatusWaiting, job199.Status)
assert.Equal(t, int64(0), job199.TaskID)
})
t.Run("ForbiddenWithoutWriteScope", func(t *testing.T) {
req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/runs/795/rerun", repo.FullName())).
AddTokenAuth(readToken)
MakeRequest(t, req, http.StatusForbidden)
})
t.Run("NotFound", func(t *testing.T) {
req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/runs/999999/rerun", repo.FullName())).
AddTokenAuth(writeToken)
MakeRequest(t, req, http.StatusNotFound)
})
}
func TestAPIActionsRerunWorkflowJob(t *testing.T) {
defer prepareTestEnvActionsArtifacts(t)()
t.Run("NotDone", func(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, user.Name)
writeToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/runs/793/jobs/194/rerun", repo.FullName())).
AddTokenAuth(writeToken)
MakeRequest(t, req, http.StatusBadRequest)
})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, user.Name)
writeToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
readToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository)
t.Run("Success", func(t *testing.T) {
req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/runs/795/jobs/199/rerun", repo.FullName())).
AddTokenAuth(writeToken)
resp := MakeRequest(t, req, http.StatusCreated)
var rerunResp api.ActionWorkflowJob
err := json.Unmarshal(resp.Body.Bytes(), &rerunResp)
require.NoError(t, err)
assert.Equal(t, int64(199), rerunResp.ID)
assert.Equal(t, "queued", rerunResp.Status)
run, err := actions_model.GetRunByRepoAndID(t.Context(), repo.ID, 795)
require.NoError(t, err)
assert.Equal(t, actions_model.StatusWaiting, run.Status)
job198, err := actions_model.GetRunJobByID(t.Context(), 198)
require.NoError(t, err)
assert.Equal(t, actions_model.StatusSuccess, job198.Status)
assert.Equal(t, int64(53), job198.TaskID)
job199, err := actions_model.GetRunJobByID(t.Context(), 199)
require.NoError(t, err)
assert.Equal(t, actions_model.StatusWaiting, job199.Status)
assert.Equal(t, int64(0), job199.TaskID)
})
t.Run("ForbiddenWithoutWriteScope", func(t *testing.T) {
req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/runs/795/jobs/199/rerun", repo.FullName())).
AddTokenAuth(readToken)
MakeRequest(t, req, http.StatusForbidden)
})
t.Run("NotFoundJob", func(t *testing.T) {
req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/runs/795/jobs/999999/rerun", repo.FullName())).
AddTokenAuth(writeToken)
MakeRequest(t, req, http.StatusNotFound)
})
}
@@ -1,89 +0,0 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package integration
import (
"fmt"
"net/http"
"net/http/httptest"
"testing"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/activitypub"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/routers"
"code.gitea.io/gitea/tests"
ap "github.com/go-ap/activitypub"
"github.com/stretchr/testify/assert"
)
func TestActivityPubPerson(t *testing.T) {
defer tests.PrepareTestEnv(t)()
defer test.MockVariableValue(&setting.Federation.Enabled, true)()
defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())()
t.Run("ExistingPerson", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
userID := 2
username := "user2"
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/activitypub/user-id/%v", userID))
resp := MakeRequest(t, req, http.StatusOK)
body := resp.Body.Bytes()
assert.Contains(t, string(body), "@context")
var person ap.Person
err := person.UnmarshalJSON(body)
assert.NoError(t, err)
assert.Equal(t, ap.PersonType, person.Type)
assert.Equal(t, username, person.PreferredUsername.String())
keyID := person.GetID().String()
assert.Regexp(t, fmt.Sprintf("activitypub/user-id/%v$", userID), keyID)
assert.Regexp(t, fmt.Sprintf("activitypub/user-id/%v/outbox$", userID), person.Outbox.GetID().String())
assert.Regexp(t, fmt.Sprintf("activitypub/user-id/%v/inbox$", userID), person.Inbox.GetID().String())
pubKey := person.PublicKey
assert.NotNil(t, pubKey)
publicKeyID := keyID + "#main-key"
assert.Equal(t, pubKey.ID.String(), publicKeyID)
pubKeyPem := pubKey.PublicKeyPem
assert.NotNil(t, pubKeyPem)
assert.Regexp(t, "^-----BEGIN PUBLIC KEY-----", pubKeyPem)
})
t.Run("MissingPerson", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
req := NewRequest(t, "GET", "/api/v1/activitypub/user-id/999999999")
resp := MakeRequest(t, req, http.StatusNotFound)
assert.Contains(t, resp.Body.String(), "user does not exist")
})
t.Run("MissingPersonInbox", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
srv := httptest.NewServer(testWebRoutes)
defer srv.Close()
defer test.MockVariableValue(&setting.AppURL, srv.URL+"/")()
username1 := "user1"
ctx := t.Context()
user1, err := user_model.GetUserByName(ctx, username1)
assert.NoError(t, err)
user1url := srv.URL + "/api/v1/activitypub/user-id/1#main-key"
c, err := activitypub.NewClient(t.Context(), user1, user1url)
assert.NoError(t, err)
user2inboxurl := srv.URL + "/api/v1/activitypub/user-id/2/inbox"
// Signed request succeeds
resp, err := c.Post([]byte{}, user2inboxurl)
defer resp.Body.Close()
assert.NoError(t, err)
assert.Equal(t, http.StatusNoContent, resp.StatusCode)
// Unsigned request fails
req := NewRequest(t, "POST", user2inboxurl)
MakeRequest(t, req, http.StatusInternalServerError)
})
}
+2
View File
@@ -402,6 +402,8 @@ func TestAPIBranchProtection(t *testing.T) {
// Test branch deletion
testAPIDeleteBranch(t, "master", http.StatusForbidden)
testAPIDeleteBranch(t, "branch2", http.StatusNoContent)
testAPIDeleteBranch(t, "branch2", http.StatusNotFound) // deleted branch, there is a record in DB with IsDelete=true
testAPIDeleteBranch(t, "no-such-branch", http.StatusNotFound) // non-existing branch, not exist in git or DB
}
func TestAPICreateBranchWithSyncBranches(t *testing.T) {
+3 -3
View File
@@ -63,8 +63,8 @@ func TestGPGKeys(t *testing.T) {
t.Run("CreateInvalidGPGKey", func(t *testing.T) {
testCreateInvalidGPGKey(t, tc.makeRequest, tc.token, tc.results[4])
})
t.Run("CreateNoneRegistredEmailGPGKey", func(t *testing.T) {
testCreateNoneRegistredEmailGPGKey(t, tc.makeRequest, tc.token, tc.results[5])
t.Run("CreateNoneRegisteredEmailGPGKey", func(t *testing.T) {
testCreateNoneRegisteredEmailGPGKey(t, tc.makeRequest, tc.token, tc.results[5])
})
t.Run("CreateValidGPGKey", func(t *testing.T) {
testCreateValidGPGKey(t, tc.makeRequest, tc.token, tc.results[6])
@@ -179,7 +179,7 @@ func testCreateInvalidGPGKey(t *testing.T, makeRequest makeRequestFunc, token st
testCreateGPGKey(t, makeRequest, token, expected, "invalid_key")
}
func testCreateNoneRegistredEmailGPGKey(t *testing.T, makeRequest makeRequestFunc, token string, expected int) {
func testCreateNoneRegisteredEmailGPGKey(t *testing.T, makeRequest makeRequestFunc, token string, expected int) {
testCreateGPGKey(t, makeRequest, token, expected, `-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFmGUygBCACjCNbKvMGgp0fd5vyFW9olE1CLCSyyF9gQN2hSuzmZLuAZF2Kh
+28
View File
@@ -361,6 +361,34 @@ func TestAPISearchIssues(t *testing.T) {
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 2)
query = url.Values{"created": {"1"}} // issues created by the auth user
link.RawQuery = query.Encode()
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 5)
query = url.Values{"created": {"1"}, "type": {"pulls"}} // prs created by the auth user
link.RawQuery = query.Encode()
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 3)
query = url.Values{"created_by": {"user2"}} // issues created by the user2
link.RawQuery = query.Encode()
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 9)
query = url.Values{"created_by": {"user2"}, "type": {"pulls"}} // prs created by user2
link.RawQuery = query.Encode()
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 3)
}
func TestAPISearchIssuesWithLabels(t *testing.T) {
-35
View File
@@ -1,35 +0,0 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package integration
import (
"net/http"
"testing"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/routers"
"code.gitea.io/gitea/tests"
"github.com/stretchr/testify/assert"
)
func TestNodeinfo(t *testing.T) {
defer tests.PrepareTestEnv(t)()
defer test.MockVariableValue(&setting.Federation.Enabled, true)()
defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())()
req := NewRequest(t, "GET", "/api/v1/nodeinfo")
resp := MakeRequest(t, req, http.StatusOK)
VerifyJSONSchema(t, resp, "nodeinfo_2.1.json")
var nodeinfo api.NodeInfo
DecodeJSON(t, resp, &nodeinfo)
assert.True(t, nodeinfo.OpenRegistrations)
assert.Equal(t, "gitea", nodeinfo.Software.Name)
assert.Equal(t, 29, nodeinfo.Usage.Users.Total)
assert.Equal(t, 22, nodeinfo.Usage.LocalPosts)
assert.Equal(t, 3, nodeinfo.Usage.LocalComments)
}
+1 -1
View File
@@ -200,7 +200,7 @@ func TestAPINotificationPUT(t *testing.T) {
assert.False(t, apiNL[0].Pinned)
//
// Now nofication ID 2 is the first in the list and is unread.
// Now notification ID 2 is the first in the list and is unread.
//
req = NewRequest(t, "GET", "/api/v1/notifications?all=true").
AddTokenAuth(token)
+1 -1
View File
@@ -160,7 +160,7 @@ func TestPackageMaven(t *testing.T) {
t.Run("UploadVerifySHA1", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
t.Run("Missmatch", func(t *testing.T) {
t.Run("Mismatch", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
putFile(t, fmt.Sprintf("/%s/%s.sha1", packageVersion, filename), "test", http.StatusBadRequest)
+5 -5
View File
@@ -279,10 +279,10 @@ func TestAPICreatePullSuccess(t *testing.T) {
}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusCreated)
// Also test that AllowMaintainerEdit is false by default
// Also test that AllowMaintainerEdit is true by default, the "false" case is covered by TestAPICreatePullBasePermission
prIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: prTitle})
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{IssueID: prIssue.ID})
assert.False(t, pr.AllowMaintainerEdit)
assert.True(t, pr.AllowMaintainerEdit)
MakeRequest(t, req, http.StatusUnprocessableEntity) // second request should fail
}
@@ -304,7 +304,7 @@ func TestAPICreatePullBasePermission(t *testing.T) {
Base: "master",
Title: prTitle,
AllowMaintainerEdit: new(true),
AllowMaintainerEdit: new(false),
}
req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner10.Name, repo10.Name), &opts).AddTokenAuth(token)
MakeRequest(t, req, http.StatusForbidden)
@@ -317,10 +317,10 @@ func TestAPICreatePullBasePermission(t *testing.T) {
req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner10.Name, repo10.Name), &opts).AddTokenAuth(token)
MakeRequest(t, req, http.StatusCreated)
// Also test that AllowMaintainerEdit is set to true
// Also test that AllowMaintainerEdit is set to false, the default "true" case is covered by TestAPICreatePullSuccess
prIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: prTitle})
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{IssueID: prIssue.ID})
assert.True(t, pr.AllowMaintainerEdit)
assert.False(t, pr.AllowMaintainerEdit)
}
func TestAPICreatePullHeadPermission(t *testing.T) {
+15
View File
@@ -418,5 +418,20 @@ func TestAPIRepoEdit(t *testing.T) {
req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo1.Name), &repoEditOption).
AddTokenAuth(token4)
MakeRequest(t, req, http.StatusForbidden)
// Test updating pull request settings without setting has_pull_requests
repo1 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
url = fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo1.Name)
req = NewRequestWithJSON(t, "PATCH", url, &api.EditRepoOption{
DefaultDeleteBranchAfterMerge: &bTrue,
}).AddTokenAuth(token2)
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &repo)
assert.True(t, repo.DefaultDeleteBranchAfterMerge)
// reset
req = NewRequestWithJSON(t, "PATCH", url, &api.EditRepoOption{
DefaultDeleteBranchAfterMerge: &bFalse,
}).AddTokenAuth(token2)
_ = MakeRequest(t, req, http.StatusOK)
})
}
+2 -2
View File
@@ -514,10 +514,10 @@ func runTestCase(t *testing.T, testCase *requiredScopeTestCase, user *user_model
if unauthorizedLevel == auth_model.NoAccess {
continue
}
cateogoryUnauthorizedScopes := auth_model.GetRequiredScopes(
categoryUnauthorizedScopes := auth_model.GetRequiredScopes(
unauthorizedLevel,
category)
unauthorizedScopes = append(unauthorizedScopes, cateogoryUnauthorizedScopes...)
unauthorizedScopes = append(unauthorizedScopes, categoryUnauthorizedScopes...)
}
accessToken := createAPIAccessTokenWithoutCleanUp(t, "test-token", user, unauthorizedScopes)
+58 -16
View File
@@ -15,6 +15,21 @@ import (
"github.com/stretchr/testify/assert"
)
func TestPermissionsAPI(t *testing.T) {
defer tests.PrepareTestEnv(t)()
t.Run("TokenNeeded", testTokenNeeded)
t.Run("WithOwnerUser", testWithOwnerUser)
t.Run("CanWriteUser", testCanWriteUser)
t.Run("AdminUser", testAdminUser)
t.Run("AdminCanNotCreateRepo", testAdminCanNotCreateRepo)
t.Run("CanReadUser", testCanReadUser)
t.Run("UnknownUser", testUnknownUser)
t.Run("UnknownOrganization", testUnknownOrganization)
t.Run("HiddenMemberPermissionsForbidden", testHiddenMemberPermissionsForbidden)
t.Run("PrivateOrgPermissionsNotFound", testPrivateOrgPermissionsNotFound)
}
type apiUserOrgPermTestCase struct {
LoginUser string
User string
@@ -22,16 +37,12 @@ type apiUserOrgPermTestCase struct {
ExpectedOrganizationPermissions api.OrganizationPermissions
}
func TestTokenNeeded(t *testing.T) {
defer tests.PrepareTestEnv(t)()
func testTokenNeeded(t *testing.T) {
req := NewRequest(t, "GET", "/api/v1/users/user1/orgs/org6/permissions")
MakeRequest(t, req, http.StatusUnauthorized)
}
func sampleTest(t *testing.T, auoptc apiUserOrgPermTestCase) {
defer tests.PrepareTestEnv(t)()
session := loginUser(t, auoptc.LoginUser)
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization, auth_model.AccessTokenScopeReadUser)
@@ -48,7 +59,7 @@ func sampleTest(t *testing.T, auoptc apiUserOrgPermTestCase) {
assert.Equal(t, auoptc.ExpectedOrganizationPermissions.CanCreateRepository, apiOP.CanCreateRepository)
}
func TestWithOwnerUser(t *testing.T) {
func testWithOwnerUser(t *testing.T) {
sampleTest(t, apiUserOrgPermTestCase{
LoginUser: "user2",
User: "user2",
@@ -63,7 +74,7 @@ func TestWithOwnerUser(t *testing.T) {
})
}
func TestCanWriteUser(t *testing.T) {
func testCanWriteUser(t *testing.T) {
sampleTest(t, apiUserOrgPermTestCase{
LoginUser: "user4",
User: "user4",
@@ -78,7 +89,7 @@ func TestCanWriteUser(t *testing.T) {
})
}
func TestAdminUser(t *testing.T) {
func testAdminUser(t *testing.T) {
sampleTest(t, apiUserOrgPermTestCase{
LoginUser: "user1",
User: "user28",
@@ -93,7 +104,7 @@ func TestAdminUser(t *testing.T) {
})
}
func TestAdminCanNotCreateRepo(t *testing.T) {
func testAdminCanNotCreateRepo(t *testing.T) {
sampleTest(t, apiUserOrgPermTestCase{
LoginUser: "user1",
User: "user28",
@@ -108,7 +119,7 @@ func TestAdminCanNotCreateRepo(t *testing.T) {
})
}
func TestCanReadUser(t *testing.T) {
func testCanReadUser(t *testing.T) {
sampleTest(t, apiUserOrgPermTestCase{
LoginUser: "user1",
User: "user24",
@@ -123,9 +134,7 @@ func TestCanReadUser(t *testing.T) {
})
}
func TestUnknowUser(t *testing.T) {
defer tests.PrepareTestEnv(t)()
func testUnknownUser(t *testing.T) {
session := loginUser(t, "user1")
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser, auth_model.AccessTokenScopeReadOrganization)
@@ -138,9 +147,7 @@ func TestUnknowUser(t *testing.T) {
assert.Equal(t, "user redirect does not exist [name: unknown]", apiError.Message)
}
func TestUnknownOrganization(t *testing.T) {
defer tests.PrepareTestEnv(t)()
func testUnknownOrganization(t *testing.T) {
session := loginUser(t, "user1")
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser, auth_model.AccessTokenScopeReadOrganization)
@@ -151,3 +158,38 @@ func TestUnknownOrganization(t *testing.T) {
DecodeJSON(t, resp, &apiError)
assert.Equal(t, "GetUserByName", apiError.Message)
}
func testHiddenMemberPermissionsForbidden(t *testing.T) {
session := loginUser(t, "user8")
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser, auth_model.AccessTokenScopeReadOrganization)
req := NewRequest(t, "GET", "/api/v1/users/user5/orgs/privated_org/permissions").
AddTokenAuth(token)
MakeRequest(t, req, http.StatusNotFound)
adminSession := loginUser(t, "user1")
adminToken := getTokenForLoggedInUser(t, adminSession, auth_model.AccessTokenScopeReadUser, auth_model.AccessTokenScopeReadOrganization)
adminReq := NewRequest(t, "GET", "/api/v1/users/user5/orgs/privated_org/permissions").
AddTokenAuth(adminToken)
resp := MakeRequest(t, adminReq, http.StatusOK)
var apiOP api.OrganizationPermissions
DecodeJSON(t, resp, &apiOP)
assert.Equal(t, api.OrganizationPermissions{
IsOwner: false,
IsAdmin: false,
CanWrite: true,
CanRead: true,
CanCreateRepository: true,
}, apiOP)
}
func testPrivateOrgPermissionsNotFound(t *testing.T) {
session := loginUser(t, "user8")
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser, auth_model.AccessTokenScopeReadOrganization)
req := NewRequest(t, "GET", "/api/v1/users/user5/orgs/privated_org/permissions").
AddTokenAuth(token)
MakeRequest(t, req, http.StatusNotFound)
}
+126
View File
@@ -0,0 +1,126 @@
// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package integration
import (
"net/http"
"testing"
"time"
system_model "code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/setting/config"
"code.gitea.io/gitea/tests"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func mockSystemConfig[T any](t *testing.T, opt *config.Option[T], v T) func() {
jsonBuf, _ := json.Marshal(v)
old := opt.Value(t.Context())
require.NoError(t, system_model.SetSettings(t.Context(), map[string]string{opt.DynKey(): string(jsonBuf)}))
config.GetDynGetter().InvalidateCache()
return func() {
jsonBuf, _ := json.Marshal(old)
require.NoError(t, system_model.SetSettings(t.Context(), map[string]string{opt.DynKey(): string(jsonBuf)}))
config.GetDynGetter().InvalidateCache()
}
}
func TestInstance(t *testing.T) {
defer tests.PrepareTestEnv(t)()
t.Run("WebBanner", func(t *testing.T) {
t.Run("Visibility", func(t *testing.T) {
defer mockSystemConfig(t, setting.Config().Instance.WebBanner, setting.WebBannerType{
DisplayEnabled: true,
ContentMessage: "Planned **upgrade** in progress.",
})()
t.Run("AnonymousUserSeesBanner", func(t *testing.T) {
resp := MakeRequest(t, NewRequest(t, "GET", "/"), http.StatusOK)
assert.Contains(t, resp.Body.String(), "Planned <strong>upgrade</strong> in progress.")
})
t.Run("NormalUserSeesBanner", func(t *testing.T) {
sess := loginUser(t, "user2")
resp := sess.MakeRequest(t, NewRequest(t, "GET", "/user/settings"), http.StatusOK)
assert.Contains(t, resp.Body.String(), "Planned <strong>upgrade</strong> in progress.")
})
t.Run("AdminSeesBannerWithoutEditHint", func(t *testing.T) {
sess := loginUser(t, "user1")
resp := sess.MakeRequest(t, NewRequest(t, "GET", "/-/admin"), http.StatusOK)
assert.Contains(t, resp.Body.String(), "Planned <strong>upgrade</strong> in progress.")
assert.NotContains(t, resp.Body.String(), "Edit this banner")
})
t.Run("APIRequestUnchanged", func(t *testing.T) {
MakeRequest(t, NewRequest(t, "GET", "/api/v1/version"), http.StatusOK)
})
})
t.Run("TimeWindow", func(t *testing.T) {
now := time.Now().Unix()
defer mockSystemConfig(t, setting.Config().Instance.WebBanner, setting.WebBannerType{
DisplayEnabled: true,
ContentMessage: "Future banner",
StartTimeUnix: now + 3600,
EndTimeUnix: now + 7200,
})()
resp := MakeRequest(t, NewRequest(t, "GET", "/"), http.StatusOK)
assert.NotContains(t, resp.Body.String(), "Future banner")
defer mockSystemConfig(t, setting.Config().Instance.WebBanner, setting.WebBannerType{
DisplayEnabled: true,
ContentMessage: "Expired banner",
StartTimeUnix: now - 7200,
EndTimeUnix: now - 3600,
})()
resp = MakeRequest(t, NewRequest(t, "GET", "/"), http.StatusOK)
assert.NotContains(t, resp.Body.String(), "Expired banner")
})
})
t.Run("MaintenanceMode", func(t *testing.T) {
defer mockSystemConfig(t, setting.Config().Instance.WebBanner, setting.WebBannerType{
DisplayEnabled: true,
ContentMessage: "MaintenanceModeBanner",
})()
defer mockSystemConfig(t, setting.Config().Instance.MaintenanceMode, setting.MaintenanceModeType{AdminWebAccessOnly: true})()
t.Run("AnonymousUser", func(t *testing.T) {
req := NewRequest(t, "GET", "/")
req.Header.Add("Accept", "text/html")
resp := MakeRequest(t, req, http.StatusServiceUnavailable)
assert.Contains(t, resp.Body.String(), "MaintenanceModeBanner")
assert.Contains(t, resp.Body.String(), `href="/user/login"`) // it must contain the login link
MakeRequest(t, NewRequest(t, "GET", "/user/login"), http.StatusOK)
MakeRequest(t, NewRequest(t, "GET", "/-/admin"), http.StatusSeeOther)
MakeRequest(t, NewRequest(t, "GET", "/api/internal/dummy"), http.StatusForbidden)
})
t.Run("AdminLogin", func(t *testing.T) {
req := NewRequestWithValues(t, "POST", "/user/login", map[string]string{"user_name": "user1", "password": userPassword})
resp := MakeRequest(t, req, http.StatusSeeOther)
assert.Equal(t, "/-/admin", resp.Header().Get("Location"))
sess := loginUser(t, "user1")
req = NewRequest(t, "GET", "/")
req.Header.Add("Accept", "text/html")
resp = sess.MakeRequest(t, req, http.StatusServiceUnavailable)
assert.Contains(t, resp.Body.String(), "MaintenanceModeBanner")
resp = sess.MakeRequest(t, NewRequest(t, "GET", "/user/login"), http.StatusSeeOther)
assert.Equal(t, "/-/admin", resp.Header().Get("Location"))
sess.MakeRequest(t, NewRequest(t, "GET", "/-/admin"), http.StatusOK)
})
})
}
+8 -8
View File
@@ -199,10 +199,10 @@ func lfsCommitAndPushTest(t *testing.T, dstPath string, sizes ...int) (pushedFil
_, _, err = gitcmd.NewCommand("lfs").AddArguments("track").AddDynamicArguments(prefix + "*").
WithDir(dstPath).RunStdString(t.Context())
assert.NoError(t, err)
err = git.AddChanges(t.Context(), dstPath, false, ".gitattributes")
err = gitAddChangesDeprecated(t.Context(), dstPath, false, ".gitattributes")
assert.NoError(t, err)
err = git.CommitChanges(t.Context(), dstPath, git.CommitChangesOptions{
err = gitCommitChangesDeprecated(t.Context(), dstPath, gitCommitChangesOptions{
Committer: &git.Signature{
Email: "user2@example.com",
Name: "User Two",
@@ -347,11 +347,11 @@ func generateCommitWithNewData(ctx context.Context, size int, repoPath, email, f
_ = tmpFile.Close()
// Commit
err = git.AddChanges(ctx, repoPath, false, filepath.Base(tmpFile.Name()))
err = gitAddChangesDeprecated(ctx, repoPath, false, filepath.Base(tmpFile.Name()))
if err != nil {
return "", err
}
err = git.CommitChanges(ctx, repoPath, git.CommitChangesOptions{
err = gitCommitChangesDeprecated(ctx, repoPath, gitCommitChangesOptions{
Committer: &git.Signature{
Email: email,
Name: fullName,
@@ -837,10 +837,10 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, headBranch string
err := os.WriteFile(path.Join(dstPath, "test_file"), []byte("## test content"), 0o666)
require.NoError(t, err)
err = git.AddChanges(t.Context(), dstPath, true)
err = gitAddChangesDeprecated(t.Context(), dstPath, true)
assert.NoError(t, err)
err = git.CommitChanges(t.Context(), dstPath, git.CommitChangesOptions{
err = gitCommitChangesDeprecated(t.Context(), dstPath, gitCommitChangesOptions{
Committer: &git.Signature{
Email: "user2@example.com",
Name: "user2",
@@ -909,10 +909,10 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, headBranch string
err := os.WriteFile(path.Join(dstPath, "test_file"), []byte("## test content \n ## test content 2"), 0o666)
require.NoError(t, err)
err = git.AddChanges(t.Context(), dstPath, true)
err = gitAddChangesDeprecated(t.Context(), dstPath, true)
assert.NoError(t, err)
err = git.CommitChanges(t.Context(), dstPath, git.CommitChangesOptions{
err = gitCommitChangesDeprecated(t.Context(), dstPath, gitCommitChangesOptions{
Committer: &git.Signature{
Email: "user2@example.com",
Name: "user2",
@@ -58,6 +58,52 @@ func createSSHUrl(gitPath string, u *url.URL) *url.URL {
return &u2
}
// gitAddChangesDeprecated marks local changes to be ready for commit.
// Deprecated: use "git fast-import" instead for better performance and more control over the commit creation.
func gitAddChangesDeprecated(ctx context.Context, repoPath string, all bool, files ...string) error {
cmd := gitcmd.NewCommand().AddArguments("add")
if all {
cmd.AddArguments("--all")
}
cmd.AddDashesAndList(files...)
_, _, err := cmd.WithDir(repoPath).RunStdString(ctx)
return err
}
// CommitChangesOptions the options when a commit created
type gitCommitChangesOptions struct {
Committer *git.Signature
Author *git.Signature
Message string
}
// gitCommitChangesDeprecated commits local changes with given committer, author and message.
// If author is nil, it will be the same as committer.
// Deprecated: use "git fast-import" instead for better performance and more control over the commit creation.
func gitCommitChangesDeprecated(ctx context.Context, repoPath string, opts gitCommitChangesOptions) error {
cmd := gitcmd.NewCommand()
if opts.Committer != nil {
cmd.AddOptionValues("-c", "user.name="+opts.Committer.Name)
cmd.AddOptionValues("-c", "user.email="+opts.Committer.Email)
}
cmd.AddArguments("commit")
if opts.Author == nil {
opts.Author = opts.Committer
}
if opts.Author != nil {
cmd.AddOptionFormat("--author='%s <%s>'", opts.Author.Name, opts.Author.Email)
}
cmd.AddOptionFormat("--message=%s", opts.Message)
_, _, err := cmd.WithDir(repoPath).RunStdString(ctx)
// No stderr but exit status 1 means nothing to commit.
if gitcmd.IsErrorExitCode(err, 1) {
return nil
}
return err
}
func onGiteaRun[T testing.TB](t T, callback func(T, *url.URL)) {
defer tests.PrepareTestEnv(t, 1)()
s := http.Server{
@@ -128,13 +174,13 @@ func doGitInitTestRepository(dstPath string) func(*testing.T) {
RunStdString(t.Context())
assert.NoError(t, err)
assert.NoError(t, os.WriteFile(filepath.Join(dstPath, "README.md"), []byte("# Testing Repository\n\nOriginally created in: "+dstPath), 0o644))
assert.NoError(t, git.AddChanges(t.Context(), dstPath, true))
assert.NoError(t, gitAddChangesDeprecated(t.Context(), dstPath, true))
signature := git.Signature{
Email: "test@example.com",
Name: "test",
When: time.Now(),
}
assert.NoError(t, git.CommitChanges(t.Context(), dstPath, git.CommitChangesOptions{
assert.NoError(t, gitCommitChangesDeprecated(t.Context(), dstPath, gitCommitChangesOptions{
Committer: &signature,
Author: &signature,
Message: "Initial Commit",
@@ -181,12 +227,12 @@ func doGitCheckoutWriteFileCommit(opts localGitAddCommitOptions) func(*testing.T
doGitCheckoutBranch(opts.LocalRepoPath, opts.CheckoutBranch)(t)
localFilePath := filepath.Join(opts.LocalRepoPath, opts.TreeFilePath)
require.NoError(t, os.WriteFile(localFilePath, []byte(opts.TreeFileContent), 0o644))
require.NoError(t, git.AddChanges(t.Context(), opts.LocalRepoPath, true))
require.NoError(t, gitAddChangesDeprecated(t.Context(), opts.LocalRepoPath, true))
signature := git.Signature{
Email: "test@test.test",
Name: "test",
}
require.NoError(t, git.CommitChanges(t.Context(), opts.LocalRepoPath, git.CommitChangesOptions{
require.NoError(t, gitCommitChangesDeprecated(t.Context(), opts.LocalRepoPath, gitCommitChangesOptions{
Committer: &signature,
Author: &signature,
Message: fmt.Sprintf("update %s @ %s", opts.TreeFilePath, opts.CheckoutBranch),
+4
View File
@@ -341,6 +341,10 @@ func MakeRequest(t testing.TB, rw *RequestWrapper, expectedStatus int) *httptest
if req.RemoteAddr == "" {
req.RemoteAddr = "test-mock:12345"
}
// Ensure unknown contentLength is seen as -1
if req.Body != nil && req.ContentLength == 0 {
req.ContentLength = -1
}
testWebRoutes.ServeHTTP(recorder, req)
if expectedStatus != NoExpectedStatus {
if expectedStatus != recorder.Code {
+75
View File
@@ -0,0 +1,75 @@
// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package integration
import (
"fmt"
"net/url"
"testing"
"time"
auth_model "code.gitea.io/gitea/models/auth"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestManualMergeAutodetect(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
// user2 is the repo owner
// user1 is the pusher/merger
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session2 := loginUser(t, user2.Name)
// Create a repo owned by user2
repoName := "manual-merge-autodetect"
defaultBranch := setting.Repository.DefaultBranch
user2Ctx := NewAPITestContext(t, user2.Name, repoName, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
doAPICreateRepository(user2Ctx, false)(t)
// Enable autodetect manual merge
doAPIEditRepository(user2Ctx, &api.EditRepoOption{
HasPullRequests: new(true),
AllowManualMerge: new(true),
AutodetectManualMerge: new(true),
})(t)
// Create a PR from a branch
branchName := "feature"
testEditFileToNewBranch(t, session2, user2.Name, repoName, defaultBranch, branchName, "README.md", "Manual Merge Test")
apiPull, err := doAPICreatePullRequest(NewAPITestContext(t, user1.Name, repoName, auth_model.AccessTokenScopeWriteRepository), user2.Name, repoName, defaultBranch, branchName)(t)
assert.NoError(t, err)
// user1 clones and pushes the branch to master (fast-forward)
dstPath := t.TempDir()
u, _ := url.Parse(giteaURL.String())
u.Path = fmt.Sprintf("%s/%s.git", user2.Name, repoName)
u.User = url.UserPassword(user1.Name, userPassword)
doGitClone(dstPath, u)(t)
doGitMerge(dstPath, "origin/"+branchName)(t)
doGitPushTestRepository(dstPath, "origin", defaultBranch)(t)
// Wait for the PR to be marked as merged by the background task
var pr *issues_model.PullRequest
require.Eventually(t, func() bool {
pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: apiPull.ID})
return pr.HasMerged
}, 10*time.Second, 100*time.Millisecond)
// Check if the PR is merged and who is the merger
pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: apiPull.ID})
assert.True(t, pr.HasMerged)
assert.Equal(t, issues_model.PullRequestStatusManuallyMerged, pr.Status)
// Merger should be user1 (the pusher), not the commit author (user2) or repo owner (user2)
assert.Equal(t, user1.ID, pr.MergerID)
})
}
+40
View File
@@ -20,6 +20,7 @@ import (
"code.gitea.io/gitea/services/migrations"
mirror_service "code.gitea.io/gitea/services/mirror"
repo_service "code.gitea.io/gitea/services/repository"
wiki_service "code.gitea.io/gitea/services/wiki"
"code.gitea.io/gitea/tests"
"github.com/stretchr/testify/assert"
@@ -29,6 +30,10 @@ func TestMirrorPush(t *testing.T) {
onGiteaRun(t, testMirrorPush)
}
func TestMirrorPushWikiDefaultBranchMismatch(t *testing.T) {
onGiteaRun(t, testMirrorPushWikiDefaultBranchMismatch)
}
func testMirrorPush(t *testing.T, u *url.URL) {
setting.Migrations.AllowLocalNetworks = true
assert.NoError(t, migrations.Init())
@@ -77,6 +82,41 @@ func testMirrorPush(t *testing.T, u *url.URL) {
assert.Empty(t, mirrors)
}
func testMirrorPushWikiDefaultBranchMismatch(t *testing.T, u *url.URL) {
setting.Migrations.AllowLocalNetworks = true
assert.NoError(t, migrations.Init())
_ = db.TruncateBeans(t.Context(), &repo_model.PushMirror{})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
srcRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
mirrorRepo, err := repo_service.CreateRepositoryDirectly(t.Context(), user, user, repo_service.CreateRepoOptions{
Name: "test-push-mirror-wiki",
}, true)
assert.NoError(t, err)
assert.NoError(t, wiki_service.AddWikiPage(t.Context(), user, mirrorRepo, wiki_service.WebPath("Home"), "Mirror wiki content", "init wiki"))
mirrorRepo.DefaultBranch = "mirror-head"
assert.NoError(t, repo_model.UpdateRepositoryColsNoAutoTime(t.Context(), mirrorRepo, "default_branch"))
wikiCommitID, err := gitrepo.GetBranchCommitID(t.Context(), mirrorRepo.WikiStorageRepo(), mirrorRepo.DefaultWikiBranch)
assert.NoError(t, err)
assert.NoError(t, gitrepo.CreateBranch(t.Context(), mirrorRepo.WikiStorageRepo(), "mirror-head", wikiCommitID))
session := loginUser(t, user.Name)
pushMirrorURL := fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(user.Name), url.PathEscape(mirrorRepo.Name))
testCreatePushMirror(t, session, user.Name, srcRepo.Name, pushMirrorURL, user.LowerName, userPassword, "0")
mirrors, _, err := repo_model.GetPushMirrorsByRepoID(t.Context(), srcRepo.ID, db.ListOptions{})
assert.NoError(t, err)
assert.Len(t, mirrors, 1)
ok := mirror_service.SyncPushMirror(t.Context(), mirrors[0].ID)
assert.True(t, ok)
}
func testCreatePushMirror(t *testing.T, session *TestSession, owner, repo, address, username, password, interval string) {
req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/settings", url.PathEscape(owner), url.PathEscape(repo)), map[string]string{
"action": "push-mirror-add",
+40 -77
View File
@@ -98,7 +98,7 @@ func TestPullMerge(t *testing.T) {
assert.NoError(t, err)
hookTasksLenBefore := len(hookTasks)
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n")
@@ -135,7 +135,7 @@ func TestPullRebase(t *testing.T) {
assert.NoError(t, err)
hookTasksLenBefore := len(hookTasks)
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n")
@@ -172,7 +172,7 @@ func TestPullRebaseMerge(t *testing.T) {
assert.NoError(t, err)
hookTasksLenBefore := len(hookTasks)
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n")
@@ -209,7 +209,7 @@ func TestPullSquash(t *testing.T) {
assert.NoError(t, err)
hookTasksLenBefore := len(hookTasks)
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n")
testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited!)\n")
@@ -235,7 +235,7 @@ func TestPullSquashWithHeadCommitID(t *testing.T) {
assert.NoError(t, err)
hookTasksLenBefore := len(hookTasks)
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n")
testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited!)\n")
@@ -275,7 +275,7 @@ func TestPullSquashWithHeadCommitID(t *testing.T) {
func TestPullCleanUpAfterMerge(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
testEditFileToNewBranch(t, session, "user1", "repo1", "master", "feature/test", "README.md", "Hello, World (Edited - TestPullCleanUpAfterMerge)\n")
@@ -326,7 +326,7 @@ func TestPullCleanUpAfterMerge(t *testing.T) {
func TestCantMergeWorkInProgress(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n")
@@ -345,7 +345,7 @@ func TestCantMergeWorkInProgress(t *testing.T) {
func TestCantMergeConflict(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
testEditFileToNewBranch(t, session, "user1", "repo1", "master", "conflict", "README.md", "Hello, World (Edited Once)\n")
testEditFileToNewBranch(t, session, "user1", "repo1", "master", "base", "README.md", "Hello, World (Edited Twice)\n")
@@ -387,7 +387,7 @@ func TestCantMergeConflict(t *testing.T) {
func TestCantMergeUnrelated(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
testEditFileToNewBranch(t, session, "user1", "repo1", "master", "base", "README.md", "Hello, World (Edited Twice)\n")
@@ -414,7 +414,7 @@ func TestCantMergeUnrelated(t *testing.T) {
sha := strings.TrimSpace(stdout)
_, _, err = gitcmd.NewCommand("update-index", "--add", "--replace", "--cacheinfo").
AddDynamicArguments("100644", sha, "somewher-over-the-rainbow").
AddDynamicArguments("100644", sha, "somewhere-over-the-rainbow").
WithDir(path).
RunStdString(t.Context())
assert.NoError(t, err)
@@ -479,7 +479,7 @@ func TestCantMergeUnrelated(t *testing.T) {
func TestFastForwardOnlyMerge(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
testEditFileToNewBranch(t, session, "user1", "repo1", "master", "update", "README.md", "Hello, World 2\n")
@@ -514,7 +514,7 @@ func TestFastForwardOnlyMerge(t *testing.T) {
func TestCantFastForwardOnlyMergeDiverging(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
testEditFileToNewBranch(t, session, "user1", "repo1", "master", "diverging", "README.md", "Hello, World diverged\n")
testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World 2\n")
@@ -631,7 +631,7 @@ func TestConflictChecking(t *testing.T) {
func TestPullRetargetChildOnBranchDelete(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
testEditFileToNewBranch(t, session, "user2", "repo1", "master", "base-pr", "README.md", "Hello, World\n(Edited - TestPullRetargetOnCleanup - base PR)\n")
testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
testEditFileToNewBranch(t, session, "user1", "repo1", "base-pr", "child-pr", "README.md", "Hello, World\n(Edited - TestPullRetargetOnCleanup - base PR)\n(Edited - TestPullRetargetOnCleanup - child PR)")
@@ -668,7 +668,7 @@ func TestPullRetargetChildOnBranchDelete(t *testing.T) {
func TestPullDontRetargetChildOnWrongRepo(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
testEditFileToNewBranch(t, session, "user1", "repo1", "master", "base-pr", "README.md", "Hello, World\n(Edited - TestPullDontRetargetChildOnWrongRepo - base PR)\n")
testEditFileToNewBranch(t, session, "user1", "repo1", "base-pr", "child-pr", "README.md", "Hello, World\n(Edited - TestPullDontRetargetChildOnWrongRepo - base PR)\n(Edited - TestPullDontRetargetChildOnWrongRepo - child PR)")
@@ -733,7 +733,7 @@ func TestPullRequestMergedWithNoPermissionDeleteBranch(t *testing.T) {
func TestPullMergeIndexerNotifier(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
// create a pull request
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n")
createPullResp := testPullCreate(t, session, "user1", "repo1", false, "master", "master", "Indexer notifier test pull")
@@ -793,27 +793,13 @@ func TestPullMergeIndexerNotifier(t *testing.T) {
})
}
func testResetRepo(t *testing.T, repo *repo_model.Repository, branch, commitID string) {
assert.NoError(t, gitrepo.UpdateRef(t.Context(), repo, git.BranchPrefix+branch, commitID))
gitRepo, err := gitrepo.OpenRepository(t.Context(), repo)
assert.NoError(t, err)
defer gitRepo.Close()
id, err := gitRepo.GetBranchCommitID(branch)
assert.NoError(t, err)
assert.Equal(t, commitID, id)
}
func TestPullAutoMergeAfterCommitStatusSucceed(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
// create a pull request
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
forkedName := "repo1-1"
testRepoFork(t, session, "user2", "repo1", "user1", forkedName, "")
defer func() {
testDeleteRepository(t, session, "user1", forkedName)
}()
testEditFile(t, session, "user1", forkedName, "master", "README.md", "Hello, World (Edited)\n")
testPullCreate(t, session, "user1", forkedName, false, "master", "master", "Indexer notifier test pull")
@@ -867,16 +853,10 @@ func TestPullAutoMergeAfterCommitStatusSucceed(t *testing.T) {
assert.NoError(t, err)
sha, err := baseGitRepo.GetRefCommitID(pr.GetGitHeadRefName())
assert.NoError(t, err)
masterCommitID, err := baseGitRepo.GetBranchCommitID("master")
assert.NoError(t, err)
branches, _, err := baseGitRepo.GetBranchNames(0, 100)
assert.NoError(t, err)
assert.ElementsMatch(t, []string{"sub-home-md-img-check", "home-md-img-check", "pr-to-update", "branch2", "DefaultBranch", "develop", "feature/1", "master"}, branches)
baseGitRepo.Close()
defer func() {
testResetRepo(t, baseRepo, "master", masterCommitID)
}()
err = commitstatus_service.CreateCommitStatus(t.Context(), baseRepo, user1, sha, &git_model.CommitStatus{
State: commitstatus.CommitStatusSuccess,
@@ -897,18 +877,17 @@ func TestPullAutoMergeAfterCommitStatusSucceed(t *testing.T) {
func TestPullAutoMergeAfterCommitStatusSucceedAndApproval(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
// create a pull request
session := loginUser(t, "user1")
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
forkedName := "repo1-2"
testRepoFork(t, session, "user2", "repo1", "user1", forkedName, "")
defer func() {
testDeleteRepository(t, session, "user1", forkedName)
}()
testEditFile(t, session, "user1", forkedName, "master", "README.md", "Hello, World (Edited)\n")
testPullCreate(t, session, "user1", forkedName, false, "master", "master", "Indexer notifier test pull")
baseUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
baseSession := loginUser(t, "user2")
forkUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
forkSession := loginUser(t, "user5")
forkedName := "repo1-fork"
testRepoFork(t, forkSession, "user2", "repo1", forkUser.Name, forkedName, "")
testEditFile(t, forkSession, forkUser.Name, forkedName, "master", "README.md", "Hello, World (Edited)\n")
testPullCreate(t, forkSession, forkUser.Name, forkedName, false, "master", "master", "Indexer notifier test pull")
baseRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user2", Name: "repo1"})
forkedRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user1", Name: forkedName})
forkedRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: forkUser.Name, Name: forkedName})
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{
BaseRepoID: baseRepo.ID,
BaseBranch: "master",
@@ -924,15 +903,15 @@ func TestPullAutoMergeAfterCommitStatusSucceedAndApproval(t *testing.T) {
"status_check_contexts": "gitea/actions",
"required_approvals": "1",
})
session.MakeRequest(t, req, http.StatusSeeOther)
baseSession.MakeRequest(t, req, http.StatusSeeOther)
// first time insert automerge record, return true
scheduled, err := automerge.ScheduleAutoMerge(t.Context(), user1, pr, repo_model.MergeStyleMerge, "auto merge test", false)
scheduled, err := automerge.ScheduleAutoMerge(t.Context(), baseUser, pr, repo_model.MergeStyleMerge, "auto merge test", false)
assert.NoError(t, err)
assert.True(t, scheduled)
// second time insert automerge record, return false because it does exist
scheduled, err = automerge.ScheduleAutoMerge(t.Context(), user1, pr, repo_model.MergeStyleMerge, "auto merge test", false)
scheduled, err = automerge.ScheduleAutoMerge(t.Context(), baseUser, pr, repo_model.MergeStyleMerge, "auto merge test", false)
assert.Error(t, err)
assert.False(t, scheduled)
@@ -946,14 +925,9 @@ func TestPullAutoMergeAfterCommitStatusSucceedAndApproval(t *testing.T) {
assert.NoError(t, err)
sha, err := baseGitRepo.GetRefCommitID(pr.GetGitHeadRefName())
assert.NoError(t, err)
masterCommitID, err := baseGitRepo.GetBranchCommitID("master")
assert.NoError(t, err)
baseGitRepo.Close()
defer func() {
testResetRepo(t, baseRepo, "master", masterCommitID)
}()
err = commitstatus_service.CreateCommitStatus(t.Context(), baseRepo, user1, sha, &git_model.CommitStatus{
err = commitstatus_service.CreateCommitStatus(t.Context(), baseRepo, baseUser, sha, &git_model.CommitStatus{
State: commitstatus.CommitStatusSuccess,
TargetURL: "https://gitea.com",
Context: "gitea/actions",
@@ -968,16 +942,13 @@ func TestPullAutoMergeAfterCommitStatusSucceedAndApproval(t *testing.T) {
assert.Empty(t, pr.MergedCommitID)
// approve the PR from non-author
approveSession := loginUser(t, "user2")
testSubmitReview(t, approveSession, "user2", "repo1", strconv.Itoa(int(pr.Index)), sha, "approve", http.StatusOK)
testSubmitReview(t, baseSession, "user2", "repo1", strconv.Itoa(int(pr.Index)), sha, "approve", http.StatusOK)
time.Sleep(2 * time.Second)
// reload pr again
pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID})
assert.True(t, pr.HasMerged)
assert.Eventually(t, func() bool {
pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID})
return pr.HasMerged
}, 2*time.Second, 100*time.Millisecond)
assert.NotEmpty(t, pr.MergedCommitID)
unittest.AssertNotExistsBean(t, &pull_model.AutoMerge{PullID: pr.ID})
})
}
@@ -997,10 +968,10 @@ func TestPullAutoMergeAfterCommitStatusSucceedAndApprovalForAgitFlow(t *testing.
err := os.WriteFile(path.Join(dstPath, "test_file"), []byte("## test content"), 0o666)
assert.NoError(t, err)
err = git.AddChanges(t.Context(), dstPath, true)
err = gitAddChangesDeprecated(t.Context(), dstPath, true)
assert.NoError(t, err)
err = git.CommitChanges(t.Context(), dstPath, git.CommitChangesOptions{
err = gitCommitChangesDeprecated(t.Context(), dstPath, gitCommitChangesOptions{
Committer: &git.Signature{
Email: "user2@example.com",
Name: "user2",
@@ -1035,7 +1006,7 @@ func TestPullAutoMergeAfterCommitStatusSucceedAndApprovalForAgitFlow(t *testing.
HeadBranch: "user2/test/head2",
})
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
// Change master branch to protected
req := NewRequestWithValues(t, "POST", "/user2/repo1/settings/branches/edit", map[string]string{
"rule_name": "master",
@@ -1067,13 +1038,7 @@ func TestPullAutoMergeAfterCommitStatusSucceedAndApprovalForAgitFlow(t *testing.
assert.NoError(t, err)
sha, err := baseGitRepo.GetRefCommitID(pr.GetGitHeadRefName())
assert.NoError(t, err)
masterCommitID, err := baseGitRepo.GetBranchCommitID("master")
assert.NoError(t, err)
baseGitRepo.Close()
defer func() {
testResetRepo(t, baseRepo, "master", masterCommitID)
}()
err = commitstatus_service.CreateCommitStatus(t.Context(), baseRepo, user1, sha, &git_model.CommitStatus{
State: commitstatus.CommitStatusSuccess,
TargetURL: "https://gitea.com",
@@ -1087,7 +1052,7 @@ func TestPullAutoMergeAfterCommitStatusSucceedAndApprovalForAgitFlow(t *testing.
assert.Empty(t, pr.MergedCommitID)
// approve the PR from non-author
approveSession := loginUser(t, "user1")
approveSession := loginUser(t, "user1") // FIXME: don't use admin user for testing
testSubmitReview(t, approveSession, "user2", "repo1", strconv.Itoa(int(pr.Index)), sha, "approve", http.StatusOK)
// reload pr again
@@ -1102,11 +1067,9 @@ func TestPullAutoMergeAfterCommitStatusSucceedAndApprovalForAgitFlow(t *testing.
func TestPullNonMergeForAdminWithBranchProtection(t *testing.T) {
onGiteaRun(t, func(t *testing.T, u *url.URL) {
// create a pull request
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
forkedName := "repo1-1"
testRepoFork(t, session, "user2", "repo1", "user1", forkedName, "")
defer testDeleteRepository(t, session, "user1", forkedName)
testEditFile(t, session, "user1", forkedName, "master", "README.md", "Hello, World (Edited)\n")
testPullCreate(t, session, "user1", forkedName, false, "master", "master", "Indexer notifier test pull")
@@ -1144,7 +1107,7 @@ func TestPullNonMergeForAdminWithBranchProtection(t *testing.T) {
func TestPullSquashMergeEmpty(t *testing.T) {
onGiteaRun(t, func(t *testing.T, u *url.URL) {
session := loginUser(t, "user1")
session := loginUser(t, "user1") // FIXME: don't use admin user for testing
testEditFileToNewBranch(t, session, "user2", "repo1", "master", "pr-squash-empty", "README.md", "Hello, World (Edited)\n")
resp := testPullCreate(t, session, "user2", "repo1", false, "master", "pr-squash-empty", "This is a pull title")
-44
View File
@@ -11,7 +11,6 @@ import (
"time"
auth_model "code.gitea.io/gitea/models/auth"
git_model "code.gitea.io/gitea/models/git"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
@@ -121,49 +120,6 @@ func TestAPIPullUpdateByRebase(t *testing.T) {
})
}
func TestAPIPullUpdateByRebase2(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
// Create PR to test
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26})
pr := createOutdatedPR(t, user, org26)
assert.NoError(t, pr.LoadBaseRepo(t.Context()))
assert.NoError(t, pr.LoadIssue(t.Context()))
enableRepoAllowUpdateWithRebase(t, pr.BaseRepo.ID, false)
session := loginUser(t, "user2")
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/pulls/%d/update?style=rebase", pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index).
AddTokenAuth(token)
session.MakeRequest(t, req, http.StatusForbidden)
enableRepoAllowUpdateWithRebase(t, pr.BaseRepo.ID, true)
assert.NoError(t, pr.LoadHeadRepo(t.Context()))
// add a protected branch rule to the head branch to block rebase
pb := git_model.ProtectedBranch{
RepoID: pr.HeadRepo.ID,
RuleName: pr.HeadBranch,
CanPush: false,
CanForcePush: false,
}
err := git_model.UpdateProtectBranch(t.Context(), pr.HeadRepo, &pb, git_model.WhitelistOptions{})
assert.NoError(t, err)
req = NewRequestf(t, "POST", "/api/v1/repos/%s/%s/pulls/%d/update?style=rebase", pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index).
AddTokenAuth(token)
session.MakeRequest(t, req, http.StatusForbidden)
// remove the protected branch rule to allow rebase
err = git_model.DeleteProtectedBranch(t.Context(), pr.HeadRepo, pb.ID)
assert.NoError(t, err)
req = NewRequestf(t, "POST", "/api/v1/repos/%s/%s/pulls/%d/update?style=rebase", pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index).
AddTokenAuth(token)
session.MakeRequest(t, req, http.StatusOK)
})
}
func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *issues_model.PullRequest {
baseRepo, err := repo_service.CreateRepository(t.Context(), actor, actor, repo_service.CreateRepoOptions{
Name: "repo-pr-update",
+5 -6
View File
@@ -7,6 +7,7 @@ import (
"fmt"
"net/http"
"path"
"strings"
"sync"
"testing"
@@ -37,7 +38,7 @@ func TestRepoCommits(t *testing.T) {
doc.doc.Find("#commits-table .commit-id-short").Each(func(i int, s *goquery.Selection) {
commits = append(commits, path.Base(s.AttrOr("href", "")))
})
doc.doc.Find("#commits-table .author-wrapper").Each(func(i int, s *goquery.Selection) {
doc.doc.Find("#commits-table .author-wrapper a").Each(func(i int, s *goquery.Selection) {
userHrefs = append(userHrefs, s.AttrOr("href", ""))
})
assert.Equal(t, []string{"69554a64c1e6030f051e5c3f94bfbd773cd6a324", "27566bd5738fc8b4e3fef3c5e72cce608537bd95", "5099b81332712fe655e34e8dd63574f503f61811"}, commits)
@@ -49,7 +50,7 @@ func TestRepoCommits(t *testing.T) {
resp := session.MakeRequest(t, req, http.StatusOK)
doc := NewHTMLParser(t, resp.Body)
commitHref := doc.doc.Find(".latest-commit .commit-id-short").AttrOr("href", "")
authorHref := doc.doc.Find(".latest-commit .author-wrapper").AttrOr("href", "")
authorHref := doc.doc.Find(".latest-commit .author-wrapper a").AttrOr("href", "")
assert.Equal(t, "/user2/repo16/commit/69554a64c1e6030f051e5c3f94bfbd773cd6a324", commitHref)
assert.Equal(t, "/user2", authorHref)
})
@@ -65,8 +66,7 @@ func TestRepoCommits(t *testing.T) {
commitHref := doc.doc.Find("#commits-table tr:first-child .commit-id-short").AttrOr("href", "")
assert.Equal(t, "/user2/repo1/commit/985f0301dba5e7b34be866819cd15ad3d8f508ee", commitHref)
authorElem := doc.doc.Find("#commits-table tr:first-child .author-wrapper")
assert.Equal(t, "6543", authorElem.Text())
assert.Equal(t, "span", authorElem.Nodes[0].Data)
assert.Equal(t, "6543", strings.TrimSpace(authorElem.Text()))
})
t.Run("LastCommitNonExistingCommiter", func(t *testing.T) {
@@ -76,8 +76,7 @@ func TestRepoCommits(t *testing.T) {
commitHref := doc.doc.Find(".latest-commit .commit-id-short").AttrOr("href", "")
assert.Equal(t, "/user2/repo1/commit/985f0301dba5e7b34be866819cd15ad3d8f508ee", commitHref)
authorElem := doc.doc.Find(".latest-commit .author-wrapper")
assert.Equal(t, "6543", authorElem.Text())
assert.Equal(t, "span", authorElem.Nodes[0].Data)
assert.Equal(t, "6543", strings.TrimSpace(authorElem.Text()))
})
}
-188
View File
@@ -1,188 +0,0 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "http://nodeinfo.diaspora.software/ns/schema/2.1#",
"description": "NodeInfo schema version 2.1.",
"type": "object",
"additionalProperties": false,
"required": [
"version",
"software",
"protocols",
"services",
"openRegistrations",
"usage",
"metadata"
],
"properties": {
"version": {
"description": "The schema version, must be 2.1.",
"enum": [
"2.1"
]
},
"software": {
"description": "Metadata about server software in use.",
"type": "object",
"additionalProperties": false,
"required": [
"name",
"version"
],
"properties": {
"name": {
"description": "The canonical name of this server software.",
"type": "string",
"pattern": "^[a-z0-9-]+$"
},
"version": {
"description": "The version of this server software.",
"type": "string"
},
"repository": {
"description": "The url of the source code repository of this server software.",
"type": "string"
},
"homepage": {
"description": "The url of the homepage of this server software.",
"type": "string"
}
}
},
"protocols": {
"description": "The protocols supported on this server.",
"type": "array",
"minItems": 1,
"items": {
"enum": [
"activitypub",
"buddycloud",
"dfrn",
"diaspora",
"libertree",
"ostatus",
"pumpio",
"tent",
"xmpp",
"zot"
]
}
},
"services": {
"description": "The third party sites this server can connect to via their application API.",
"type": "object",
"additionalProperties": false,
"required": [
"inbound",
"outbound"
],
"properties": {
"inbound": {
"description": "The third party sites this server can retrieve messages from for combined display with regular traffic.",
"type": "array",
"minItems": 0,
"items": {
"enum": [
"atom1.0",
"gnusocial",
"imap",
"pnut",
"pop3",
"pumpio",
"rss2.0",
"twitter"
]
}
},
"outbound": {
"description": "The third party sites this server can publish messages to on the behalf of a user.",
"type": "array",
"minItems": 0,
"items": {
"enum": [
"atom1.0",
"blogger",
"buddycloud",
"diaspora",
"dreamwidth",
"drupal",
"facebook",
"friendica",
"gnusocial",
"google",
"insanejournal",
"libertree",
"linkedin",
"livejournal",
"mediagoblin",
"myspace",
"pinterest",
"pnut",
"posterous",
"pumpio",
"redmatrix",
"rss2.0",
"smtp",
"tent",
"tumblr",
"twitter",
"wordpress",
"xmpp"
]
}
}
}
},
"openRegistrations": {
"description": "Whether this server allows open self-registration.",
"type": "boolean"
},
"usage": {
"description": "Usage statistics for this server.",
"type": "object",
"additionalProperties": false,
"required": [
"users"
],
"properties": {
"users": {
"description": "statistics about the users of this server.",
"type": "object",
"additionalProperties": false,
"properties": {
"total": {
"description": "The total amount of on this server registered users.",
"type": "integer",
"minimum": 0
},
"activeHalfyear": {
"description": "The amount of users that signed in at least once in the last 180 days.",
"type": "integer",
"minimum": 0
},
"activeMonth": {
"description": "The amount of users that signed in at least once in the last 30 days.",
"type": "integer",
"minimum": 0
}
}
},
"localPosts": {
"description": "The amount of posts that were made by users that are registered on this server.",
"type": "integer",
"minimum": 0
},
"localComments": {
"description": "The amount of comments that were made by users that are registered on this server.",
"type": "integer",
"minimum": 0
}
}
},
"metadata": {
"description": "Free form key value pairs for software specific values. Clients should not rely on any specific key present.",
"type": "object",
"minProperties": 0,
"additionalProperties": true
}
}
}
+6 -2
View File
@@ -7,7 +7,10 @@ import (
"net/http"
"testing"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/tests"
"github.com/stretchr/testify/assert"
)
func TestSignOut(t *testing.T) {
@@ -15,8 +18,9 @@ func TestSignOut(t *testing.T) {
session := loginUser(t, "user2")
req := NewRequest(t, "POST", "/user/logout")
session.MakeRequest(t, req, http.StatusOK)
req := NewRequest(t, "GET", "/user/logout")
resp := session.MakeRequest(t, req, http.StatusSeeOther)
assert.Equal(t, "/", test.RedirectURL(resp))
// try to view a private repo, should fail
req = NewRequest(t, "GET", "/user2/repo2")
+2 -2
View File
@@ -28,13 +28,13 @@ func doCheckRepositoryEmptyStatus(ctx APITestContext, isEmpty bool) func(*testin
func doAddChangesToCheckout(dstPath, filename string) func(*testing.T) {
return func(t *testing.T) {
assert.NoError(t, os.WriteFile(filepath.Join(dstPath, filename), fmt.Appendf(nil, "# Testing Repository\n\nOriginally created in: %s at time: %v", dstPath, time.Now()), 0o644))
assert.NoError(t, git.AddChanges(t.Context(), dstPath, true))
assert.NoError(t, gitAddChangesDeprecated(t.Context(), dstPath, true))
signature := git.Signature{
Email: "test@example.com",
Name: "test",
When: time.Now(),
}
assert.NoError(t, git.CommitChanges(t.Context(), dstPath, git.CommitChangesOptions{
assert.NoError(t, gitCommitChangesDeprecated(t.Context(), dstPath, gitCommitChangesOptions{
Committer: &signature,
Author: &signature,
Message: "Initial Commit",
+30 -48
View File
@@ -17,72 +17,54 @@ import (
"code.gitea.io/gitea/tests"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestUserAvatar(t *testing.T) {
defer tests.PrepareTestEnv(t)()
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo3, is an org
seed := user2.Email
if len(seed) == 0 {
seed = user2.Name
}
img, err := avatar.RandomImage([]byte(seed))
if err != nil {
assert.NoError(t, err)
return
}
session := loginUser(t, "user2")
imgData := &bytes.Buffer{}
img := avatar.RandomImageDefaultSize([]byte("any-random-image-seed"))
originAvatarData := &bytes.Buffer{}
require.NoError(t, png.Encode(originAvatarData, img))
// setup multipart form to upload avatar
body := &bytes.Buffer{}
// Setup multi-part
writer := multipart.NewWriter(body)
writer.WriteField("source", "local")
_ = writer.WriteField("source", "local")
part, err := writer.CreateFormFile("avatar", "avatar-for-testuseravatar.png")
if err != nil {
assert.NoError(t, err)
return
}
if err := png.Encode(imgData, img); err != nil {
assert.NoError(t, err)
return
}
if _, err := io.Copy(part, imgData); err != nil {
assert.NoError(t, err)
return
}
if err := writer.Close(); err != nil {
assert.NoError(t, err)
return
}
require.NoError(t, err)
_, _ = io.Copy(part, bytes.NewReader(originAvatarData.Bytes()))
require.NoError(t, writer.Close())
// upload avatar
req := NewRequestWithBody(t, "POST", "/user/settings/avatar", body)
req.Header.Add("Content-Type", writer.FormDataContentType())
session.MakeRequest(t, req, http.StatusSeeOther)
user2 = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo3, is an org
// check user2's avatar can be accessed
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
req = NewRequest(t, "GET", user2.AvatarLinkWithSize(t.Context(), 0))
_ = session.MakeRequest(t, req, http.StatusOK)
testGetAvatarRedirect(t, user2)
req = NewRequest(t, "GET", "/user2.png")
resp := MakeRequest(t, req, http.StatusSeeOther)
avatarRedirect := resp.Header().Get("Location")
assert.Equal(t, "/avatars/"+user2.Avatar, avatarRedirect)
// Can't test if the response matches because the image is re-generated on upload but checking that this at least doesn't give a 404 should be enough.
}
// check the content of the avatar is correct
resp = MakeRequest(t, NewRequest(t, "GET", avatarRedirect), http.StatusOK)
assert.Equal(t, "image/png", resp.Header().Get("Content-Type"))
avatarData, _ := io.ReadAll(resp.Body)
assert.Equal(t, originAvatarData.Bytes(), avatarData)
func testGetAvatarRedirect(t *testing.T, user *user_model.User) {
t.Run("getAvatarRedirect_"+user.Name, func(t *testing.T) {
req := NewRequestf(t, "GET", "/%s.png", user.Name)
resp := MakeRequest(t, req, http.StatusSeeOther)
assert.Equal(t, "/avatars/"+user.Avatar, resp.Header().Get("location"))
})
// for non-existing avatar, it should return a random one with proper cache control headers
resp = MakeRequest(t, NewRequest(t, "GET", "/avatars/no-such-avatar"), http.StatusOK)
assert.Equal(t, "image/png", resp.Header().Get("Content-Type"))
assert.NotEmpty(t, resp.Header().Get("ETag"))
assert.NotEmpty(t, resp.Header().Get("Last-Modified"))
assert.Contains(t, resp.Header().Get("Cache-Control"), "public")
avatarData, _ = io.ReadAll(resp.Body)
_, err = png.Decode(bytes.NewReader(avatarData))
require.NoError(t, err)
}
-66
View File
@@ -1,66 +0,0 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package integration
import (
"fmt"
"net/http"
"net/url"
"strconv"
"testing"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/tests"
"github.com/stretchr/testify/assert"
)
func TestWebfinger(t *testing.T) {
defer tests.PrepareTestEnv(t)()
defer test.MockVariableValue(&setting.Federation.Enabled, true)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
appURL, _ := url.Parse(setting.AppURL)
type webfingerLink struct {
Rel string `json:"rel,omitempty"`
Type string `json:"type,omitempty"`
Href string `json:"href,omitempty"`
Titles map[string]string `json:"titles,omitempty"`
Properties map[string]any `json:"properties,omitempty"`
}
type webfingerJRD struct {
Subject string `json:"subject,omitempty"`
Aliases []string `json:"aliases,omitempty"`
Properties map[string]any `json:"properties,omitempty"`
Links []*webfingerLink `json:"links,omitempty"`
}
session := loginUser(t, "user1")
req := NewRequest(t, "GET", fmt.Sprintf("/.well-known/webfinger?resource=acct:%s@%s", user.LowerName, appURL.Host))
resp := MakeRequest(t, req, http.StatusOK)
var jrd webfingerJRD
DecodeJSON(t, resp, &jrd)
assert.Equal(t, "acct:user2@"+appURL.Host, jrd.Subject)
assert.ElementsMatch(t, []string{user.HTMLURL(t.Context()), appURL.String() + "api/v1/activitypub/user-id/" + strconv.FormatInt(user.ID, 10)}, jrd.Aliases)
req = NewRequest(t, "GET", fmt.Sprintf("/.well-known/webfinger?resource=acct:%s@%s", user.LowerName, "unknown.host"))
MakeRequest(t, req, http.StatusBadRequest)
req = NewRequest(t, "GET", fmt.Sprintf("/.well-known/webfinger?resource=acct:%s@%s", "user31", appURL.Host))
MakeRequest(t, req, http.StatusNotFound)
req = NewRequest(t, "GET", fmt.Sprintf("/.well-known/webfinger?resource=acct:%s@%s", "user31", appURL.Host))
session.MakeRequest(t, req, http.StatusOK)
req = NewRequest(t, "GET", "/.well-known/webfinger?resource=mailto:"+user.Email)
MakeRequest(t, req, http.StatusNotFound)
}
-5
View File
@@ -41,7 +41,6 @@ SSH_LISTEN_HOST = localhost
SSH_PORT = 2201
START_SSH_SERVER = true
LFS_START_SERVER = true
OFFLINE_MODE = false
LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w
BUILTIN_SSH_SERVER_USER = git
SSH_TRUSTED_USER_CA_KEYS = ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCb4DC1dMFnJ6pXWo7GMxTchtzmJHYzfN6sZ9FAPFR4ijMLfGki+olvOMO5Fql1/yGnGfbELQa1S6y4shSvj/5K+zUFScmEXYf3Gcr87RqilLkyk16RS+cHNB1u87xTHbETaa3nyCJeGQRpd4IQ4NKob745mwDZ7jQBH8AZEng50Oh8y8fi8skBBBzaYp1ilgvzG740L7uex6fHV62myq0SXeCa+oJUjq326FU8y+Vsa32H8A3e7tOgXZPdt2TVNltx2S9H2WO8RMi7LfaSwARNfy1zu+bfR50r6ef8Yx5YKCMz4wWb1SHU1GS800mjOjlInLQORYRNMlSwR1+vLlVDciOqFapDSbj+YOVOawR0R1aqlSKpZkt33DuOBPx9qe6CVnIi7Z+Px/KqM+OLCzlLY/RS+LbxQpDWcfTVRiP+S5qRTcE3M3UioN/e0BE/1+MpX90IGpvVkA63ILYbKEa4bM3ASL7ChTCr6xN5XT+GpVJveFKK1cfNx9ExHI4rzYE=
@@ -62,10 +61,6 @@ DEFAULT_ALLOW_CREATE_ORGANIZATION = true
NO_REPLY_ADDRESS = noreply.example.org
ENABLE_NOTIFY_MAIL = true
[picture]
DISABLE_GRAVATAR = false
ENABLE_FEDERATED_AVATAR = false
[session]
PROVIDER = file
-5
View File
@@ -43,7 +43,6 @@ SSH_LISTEN_HOST = localhost
SSH_PORT = 2201
BUILTIN_SSH_SERVER_USER = git
START_SSH_SERVER = true
OFFLINE_MODE = false
LFS_START_SERVER = true
LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w
@@ -65,10 +64,6 @@ DEFAULT_ALLOW_CREATE_ORGANIZATION = true
NO_REPLY_ADDRESS = noreply.example.org
ENABLE_NOTIFY_MAIL = true
[picture]
DISABLE_GRAVATAR = false
ENABLE_FEDERATED_AVATAR = false
[session]
PROVIDER = file
-5
View File
@@ -42,7 +42,6 @@ SSH_LISTEN_HOST = localhost
SSH_PORT = 2202
START_SSH_SERVER = true
LFS_START_SERVER = true
OFFLINE_MODE = false
LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w
BUILTIN_SSH_SERVER_USER = git
SSH_TRUSTED_USER_CA_KEYS = ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCb4DC1dMFnJ6pXWo7GMxTchtzmJHYzfN6sZ9FAPFR4ijMLfGki+olvOMO5Fql1/yGnGfbELQa1S6y4shSvj/5K+zUFScmEXYf3Gcr87RqilLkyk16RS+cHNB1u87xTHbETaa3nyCJeGQRpd4IQ4NKob745mwDZ7jQBH8AZEng50Oh8y8fi8skBBBzaYp1ilgvzG740L7uex6fHV62myq0SXeCa+oJUjq326FU8y+Vsa32H8A3e7tOgXZPdt2TVNltx2S9H2WO8RMi7LfaSwARNfy1zu+bfR50r6ef8Yx5YKCMz4wWb1SHU1GS800mjOjlInLQORYRNMlSwR1+vLlVDciOqFapDSbj+YOVOawR0R1aqlSKpZkt33DuOBPx9qe6CVnIi7Z+Px/KqM+OLCzlLY/RS+LbxQpDWcfTVRiP+S5qRTcE3M3UioN/e0BE/1+MpX90IGpvVkA63ILYbKEa4bM3ASL7ChTCr6xN5XT+GpVJveFKK1cfNx9ExHI4rzYE=
@@ -63,10 +62,6 @@ DEFAULT_ALLOW_CREATE_ORGANIZATION = true
NO_REPLY_ADDRESS = noreply.example.org
ENABLE_NOTIFY_MAIL = true
[picture]
DISABLE_GRAVATAR = false
ENABLE_FEDERATED_AVATAR = false
[session]
PROVIDER = file
-5
View File
@@ -37,7 +37,6 @@ SSH_LISTEN_HOST = localhost
SSH_PORT = 2203
START_SSH_SERVER = true
LFS_START_SERVER = true
OFFLINE_MODE = false
LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w
ENABLE_GZIP = true
BUILTIN_SSH_SERVER_USER = git
@@ -59,10 +58,6 @@ DEFAULT_KEEP_EMAIL_PRIVATE = false
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
NO_REPLY_ADDRESS = noreply.example.org
[picture]
DISABLE_GRAVATAR = false
ENABLE_FEDERATED_AVATAR = false
[session]
PROVIDER = file