mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-20 01:32:41 +02:00
Merge branch 'go-gitea:main' into main
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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"`
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -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),
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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()))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user