test: consolidate Go tests (#39962)

Consolidate all Go tests. Coverage is identical to before. Go tests are
around 5% faster while being 7% smaller. No non-test code is touched.
This commit is contained in:
silverwind authored and GitHub committed 2026-10-24 13:48:19 +00:00
1 parent ce7364e215
commit 8abda62312
388 files changed
+18410 -29561

No files matched your search

+1 -9
View File
@@ -212,15 +212,7 @@ func TestStopEndlessTasksSkipsCancelling(t *testing.T) {
var seq int64
newTaskWithJob := func(status actions_model.Status) *actions_model.ActionTask {
seq++
run := &actions_model.ActionRun{
RepoID: 1, OwnerID: 2, TriggerUserID: 2, WorkflowID: "test.yml",
Index: 99500 + seq, Ref: "refs/heads/main", Status: actions_model.StatusRunning,
}
require.NoError(t, db.Insert(t.Context(), run))
attempt := &actions_model.ActionRunAttempt{
RepoID: run.RepoID, RunID: run.ID, Attempt: 1, TriggerUserID: run.TriggerUserID, Status: actions_model.StatusRunning,
}
require.NoError(t, db.Insert(t.Context(), attempt))
run, attempt := createRunAttempt(t, 99500+seq, "", actions_model.StatusRunning)
job := &actions_model.ActionRunJob{
RunID: run.ID, RunAttemptID: attempt.ID, AttemptJobID: 1, RepoID: run.RepoID, OwnerID: run.OwnerID,
CommitSHA: "c2d72f548424103f01ee1dc02889c1e2bff816b0", Name: "j", JobID: "j", Status: status,
+16 -26
View File
@@ -439,32 +439,22 @@ func TestGenerateGiteaContextRefProtected(t *testing.T) {
NamePattern: "v*",
}))
gitCtx := GenerateGiteaContext(t.Context(), &actions_model.ActionRun{
RepoID: repo.ID,
Repo: repo,
TriggerUser: &user_model.User{Name: "test-user"},
Ref: "refs/heads/master",
}, nil, nil)
assert.Equal(t, true, gitCtx["ref_protected"])
tagCtx := GenerateGiteaContext(t.Context(), &actions_model.ActionRun{
RepoID: repo.ID,
Repo: repo,
TriggerUser: &user_model.User{Name: "test-user"},
Ref: "refs/tags/v1.0.0",
}, nil, nil)
assert.Equal(t, true, tagCtx["ref_protected"])
unprotectedTagCtx := GenerateGiteaContext(t.Context(), &actions_model.ActionRun{
RepoID: repo.ID,
Repo: repo,
TriggerUser: &user_model.User{Name: "test-user"},
Ref: "refs/tags/other",
}, nil, nil)
assert.Equal(t, false, unprotectedTagCtx["ref_protected"])
for _, tc := range []struct {
ref string
protected bool
}{
{"refs/heads/master", true},
{"refs/tags/v1.0.0", true},
{"refs/tags/other", false},
} {
gitCtx := GenerateGiteaContext(t.Context(), &actions_model.ActionRun{
RepoID: repo.ID,
Repo: repo,
TriggerUser: &user_model.User{Name: "test-user"},
Ref: tc.ref,
}, nil, nil)
assert.Equal(t, tc.protected, gitCtx["ref_protected"])
}
}
// TestGenerateGiteaContext_NilAttempt verifies that, with no explicit attempt,
+26 -43
View File
@@ -99,47 +99,30 @@ func TestPullRequestTargetBaseSHA(t *testing.T) {
return string(payload)
}
t.Run("pull_request_target with base SHA", func(t *testing.T) {
run := &actions_model.ActionRun{
Event: webhook_module.HookEventPullRequest,
TriggerEvent: actions_module.GithubEventPullRequestTarget,
EventPayload: prPayload("base-sha"),
}
got, ok := pullRequestTargetBaseSHA(run)
assert.True(t, ok)
assert.Equal(t, "base-sha", got)
})
t.Run("non pull_request_target trigger", func(t *testing.T) {
run := &actions_model.ActionRun{
Event: webhook_module.HookEventPullRequest,
TriggerEvent: actions_module.GithubEventPullRequest,
EventPayload: prPayload("base-sha"),
}
got, ok := pullRequestTargetBaseSHA(run)
assert.False(t, ok)
assert.Empty(t, got)
})
t.Run("missing base SHA", func(t *testing.T) {
run := &actions_model.ActionRun{
Event: webhook_module.HookEventPullRequest,
TriggerEvent: actions_module.GithubEventPullRequestTarget,
EventPayload: prPayload(""),
}
got, ok := pullRequestTargetBaseSHA(run)
assert.False(t, ok)
assert.Empty(t, got)
})
t.Run("invalid payload", func(t *testing.T) {
run := &actions_model.ActionRun{
Event: webhook_module.HookEventPullRequest,
TriggerEvent: actions_module.GithubEventPullRequestTarget,
EventPayload: "{",
}
got, ok := pullRequestTargetBaseSHA(run)
assert.False(t, ok)
assert.Empty(t, got)
})
for _, test := range []struct {
name string
triggerEvent string
payload string
wantSHA string
}{
{"pull_request_target with base SHA", actions_module.GithubEventPullRequestTarget, prPayload("base-sha"), "base-sha"},
{"non pull_request_target trigger", actions_module.GithubEventPullRequest, prPayload("base-sha"), ""},
{"missing base SHA", actions_module.GithubEventPullRequestTarget, prPayload(""), ""},
{"invalid payload", actions_module.GithubEventPullRequestTarget, "{", ""},
} {
t.Run(test.name, func(t *testing.T) {
got, ok := pullRequestTargetBaseSHA(&actions_model.ActionRun{
Event: webhook_module.HookEventPullRequest,
TriggerEvent: test.triggerEvent,
EventPayload: test.payload,
})
if test.wantSHA != "" {
assert.True(t, ok)
assert.Equal(t, test.wantSHA, got)
} else {
assert.False(t, ok)
assert.Empty(t, got)
}
})
}
}
+87 -125
View File
@@ -431,94 +431,95 @@ func Test_maxParallelConverges(t *testing.T) {
// ConcurrencyGroup has already been checked at the run level, the same group is not
// re-checked for individual jobs.
func Test_checkRunConcurrency_NoDuplicateConcurrencyGroupCheck(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
ctx := t.Context()
for _, test := range []struct {
name string
index int64
status actions_model.Status
}{
// Run A: the triggering run of attempt A. It is done, so it no longer holds "test-cg", which is what lets checkRunConcurrency wake the blocked waiter.
// Attempt A: a done attempt of run A with concurrency group "test-cg"
{name: "free group", index: 9901, status: actions_model.StatusSuccess},
// Test_checkRunConcurrency_HeldGroupDoesNotWake verifies that only an unoccupied concurrency group can wake up a blocked run/job.
// Run A holds "test-cg": its attempt is still running.
{name: "held group", index: 9911, status: actions_model.StatusRunning},
} {
t.Run(test.name, func(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
ctx := t.Context()
insertRun := func(index int64, status actions_model.Status) (*actions_model.ActionRun, *actions_model.ActionRunAttempt) {
run := &actions_model.ActionRun{
RepoID: 4,
OwnerID: 1,
TriggerUserID: 1,
WorkflowID: "test.yml",
Index: index,
Ref: "refs/heads/main",
Status: status,
}
assert.NoError(t, db.Insert(ctx, run))
attempt := &actions_model.ActionRunAttempt{
RepoID: 4,
RunID: run.ID,
Attempt: 1,
Status: status,
ConcurrencyGroup: "test-cg",
}
assert.NoError(t, db.Insert(ctx, attempt))
_, err := db.Exec(ctx, "UPDATE `action_run` SET latest_attempt_id = ? WHERE id = ?", attempt.ID, run.ID)
assert.NoError(t, err)
return run, attempt
}
// Run A: the triggering run of attempt A. It is done, so it no longer holds "test-cg", which is what lets checkRunConcurrency wake the blocked waiter.
runA := &actions_model.ActionRun{
RepoID: 4,
OwnerID: 1,
TriggerUserID: 1,
WorkflowID: "test.yml",
Index: 9901,
Ref: "refs/heads/main",
Status: actions_model.StatusSuccess,
runA, runAAttempt := insertRun(test.index, test.status)
if test.status == actions_model.StatusSuccess {
// A done job for run A with the same ConcurrencyGroup.
// This triggers the job-level concurrency check in checkRunConcurrency.
assert.NoError(t, db.Insert(ctx, &actions_model.ActionRunJob{
RunID: runA.ID,
RunAttemptID: runAAttempt.ID,
AttemptJobID: 1,
RepoID: 4,
OwnerID: 1,
JobID: "job1",
Name: "job1",
Status: actions_model.StatusSuccess,
ConcurrencyGroup: "test-cg",
}))
}
// Run B: a run blocked by concurrency
// Run B is blocked on the same group.
// Attempt B: an blocked attempt of run B
runB, runBAttempt := insertRun(test.index+1, actions_model.StatusBlocked)
if test.status == actions_model.StatusSuccess {
// A blocked job belonging to run B (no job-level concurrency group).
assert.NoError(t, db.Insert(ctx, &actions_model.ActionRunJob{
RunID: runB.ID,
RunAttemptID: runBAttempt.ID,
AttemptJobID: 1,
RepoID: 4,
OwnerID: 1,
JobID: "job1",
Name: "job1",
Status: actions_model.StatusBlocked,
}))
}
runA, _, _ = db.GetByID[actions_model.ActionRun](ctx, runA.ID)
result, err := checkRunConcurrency(ctx, runA)
assert.NoError(t, err)
if test.status == actions_model.StatusSuccess {
// "test-cg" is free, so the single blocked waiter (run B) is collected for re-emit.
if assert.Len(t, result.RunIDsToReEmit, 1) {
assert.Equal(t, runB.ID, result.RunIDsToReEmit[0])
}
assert.Empty(t, result.Jobs)
} else {
// The group is held by run A, so run B must not be woken; A will wake it when it releases the group.
assert.Empty(t, result.RunIDsToReEmit)
}
})
}
assert.NoError(t, db.Insert(ctx, runA))
// Attempt A: a done attempt of run A with concurrency group "test-cg"
runAAttempt := &actions_model.ActionRunAttempt{
RepoID: 4,
RunID: runA.ID,
Attempt: 1,
Status: actions_model.StatusSuccess,
ConcurrencyGroup: "test-cg",
}
assert.NoError(t, db.Insert(ctx, runAAttempt))
_, err := db.Exec(t.Context(), "UPDATE `action_run` SET latest_attempt_id = ? WHERE id = ?", runAAttempt.ID, runA.ID)
assert.NoError(t, err)
// A done job for run A with the same ConcurrencyGroup.
// This triggers the job-level concurrency check in checkRunConcurrency.
jobADone := &actions_model.ActionRunJob{
RunID: runA.ID,
RunAttemptID: runAAttempt.ID,
AttemptJobID: 1,
RepoID: 4,
OwnerID: 1,
JobID: "job1",
Name: "job1",
Status: actions_model.StatusSuccess,
ConcurrencyGroup: "test-cg",
}
assert.NoError(t, db.Insert(ctx, jobADone))
// Run B: a run blocked by concurrency
runB := &actions_model.ActionRun{
RepoID: 4,
OwnerID: 1,
TriggerUserID: 1,
WorkflowID: "test.yml",
Index: 9902,
Ref: "refs/heads/main",
Status: actions_model.StatusBlocked,
}
assert.NoError(t, db.Insert(ctx, runB))
// Attempt B: an blocked attempt of run B
runBAttempt := &actions_model.ActionRunAttempt{
RepoID: 4,
RunID: runB.ID,
Attempt: 1,
Status: actions_model.StatusBlocked,
ConcurrencyGroup: "test-cg",
}
assert.NoError(t, db.Insert(ctx, runBAttempt))
_, err = db.Exec(t.Context(), "UPDATE `action_run` SET latest_attempt_id = ? WHERE id = ?", runBAttempt.ID, runB.ID)
assert.NoError(t, err)
// A blocked job belonging to run B (no job-level concurrency group).
jobBBlocked := &actions_model.ActionRunJob{
RunID: runB.ID,
RunAttemptID: runBAttempt.ID,
AttemptJobID: 1,
RepoID: 4,
OwnerID: 1,
JobID: "job1",
Name: "job1",
Status: actions_model.StatusBlocked,
}
assert.NoError(t, db.Insert(ctx, jobBBlocked))
runA, _, _ = db.GetByID[actions_model.ActionRun](t.Context(), runA.ID)
result, err := checkRunConcurrency(ctx, runA)
assert.NoError(t, err)
// "test-cg" is free, so the single blocked waiter (run B) is collected for re-emit.
if assert.Len(t, result.RunIDsToReEmit, 1) {
assert.Equal(t, runB.ID, result.RunIDsToReEmit[0])
}
assert.Empty(t, result.Jobs)
}
// Test_checkJobsOfCurrentRunAttempt_RunLevelConcurrencyKeepsJobsBlocked verifies that
@@ -732,45 +733,6 @@ func Test_checkJobsOfCurrentRunAttempt_SkippedCallerIsUpdated(t *testing.T) {
assert.Equal(t, actions_model.StatusWaiting, unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: after.ID}).Status)
}
// Test_checkRunConcurrency_HeldGroupDoesNotWake verifies that only an unoccupied concurrency group can wake up a blocked run/job.
func Test_checkRunConcurrency_HeldGroupDoesNotWake(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
ctx := t.Context()
// Run A holds "test-cg": its attempt is still running.
runA := &actions_model.ActionRun{
RepoID: 4, OwnerID: 1, TriggerUserID: 1, WorkflowID: "test.yml",
Index: 9911, Ref: "refs/heads/main", Status: actions_model.StatusRunning,
}
assert.NoError(t, db.Insert(ctx, runA))
runAAttempt := &actions_model.ActionRunAttempt{
RepoID: 4, RunID: runA.ID, Attempt: 1, Status: actions_model.StatusRunning, ConcurrencyGroup: "test-cg",
}
assert.NoError(t, db.Insert(ctx, runAAttempt))
_, err := db.Exec(ctx, "UPDATE `action_run` SET latest_attempt_id = ? WHERE id = ?", runAAttempt.ID, runA.ID)
assert.NoError(t, err)
// Run B is blocked on the same group.
runB := &actions_model.ActionRun{
RepoID: 4, OwnerID: 1, TriggerUserID: 1, WorkflowID: "test.yml",
Index: 9912, Ref: "refs/heads/main", Status: actions_model.StatusBlocked,
}
assert.NoError(t, db.Insert(ctx, runB))
runBAttempt := &actions_model.ActionRunAttempt{
RepoID: 4, RunID: runB.ID, Attempt: 1, Status: actions_model.StatusBlocked, ConcurrencyGroup: "test-cg",
}
assert.NoError(t, db.Insert(ctx, runBAttempt))
_, err = db.Exec(ctx, "UPDATE `action_run` SET latest_attempt_id = ? WHERE id = ?", runBAttempt.ID, runB.ID)
assert.NoError(t, err)
runA, _, _ = db.GetByID[actions_model.ActionRun](ctx, runA.ID)
result, err := checkRunConcurrency(ctx, runA)
assert.NoError(t, err)
// The group is held by run A, so run B must not be woken; A will wake it when it releases the group.
assert.Empty(t, result.RunIDsToReEmit)
}
// Test_findConcurrencyWaiterToWake covers the finder's contract: it skips the run being processed (excludeRunID),
// returns another blocked waiter when the group is free, and returns 0 while the group is still held.
func Test_findConcurrencyWaiterToWake(t *testing.T) {
+21 -35
View File
@@ -41,41 +41,27 @@ func TestIfNeedApproval(t *testing.T) {
normalUser := &user_model.User{ID: 10}
restrictedUser := &user_model.User{ID: 11, IsRestricted: true}
t.Run("not a fork PR never needs approval", func(t *testing.T) {
need, err := ifNeedApprovalWith(t.Context(), nonForkRun, repo, normalUser, alwaysWrite, hasMerged)
require.NoError(t, err)
assert.False(t, need)
})
t.Run("pull_request_target never needs approval even when fork", func(t *testing.T) {
need, err := ifNeedApprovalWith(t.Context(), prTargetRun, repo, normalUser, alwaysWrite, hasMerged)
require.NoError(t, err)
assert.False(t, need)
})
t.Run("restricted user always needs approval", func(t *testing.T) {
need, err := ifNeedApprovalWith(t.Context(), forkRun, repo, restrictedUser, alwaysWrite, hasMerged)
require.NoError(t, err)
assert.True(t, need)
})
t.Run("fork PR with write permission does not need approval", func(t *testing.T) {
need, err := ifNeedApprovalWith(t.Context(), forkRun, repo, normalUser, alwaysWrite, noMerged)
require.NoError(t, err)
assert.False(t, need)
})
t.Run("fork PR with merged PR but no write permission does not need approval", func(t *testing.T) {
need, err := ifNeedApprovalWith(t.Context(), forkRun, repo, normalUser, neverWrite, hasMerged)
require.NoError(t, err)
assert.False(t, need)
})
t.Run("fork PR with no write and no merged PR needs approval", func(t *testing.T) {
need, err := ifNeedApprovalWith(t.Context(), forkRun, repo, normalUser, neverWrite, noMerged)
require.NoError(t, err)
assert.True(t, need)
})
for _, tt := range []struct {
name string
run *actions_model.ActionRun
user *user_model.User
canWrite func(context.Context, *repo_model.Repository, *user_model.User) (bool, error)
hasMerged func(context.Context, int64, int64) (bool, error)
check assert.BoolAssertionFunc
}{
{"not a fork PR never needs approval", nonForkRun, normalUser, alwaysWrite, hasMerged, assert.False},
{"pull_request_target never needs approval even when fork", prTargetRun, normalUser, alwaysWrite, hasMerged, assert.False},
{"restricted user always needs approval", forkRun, restrictedUser, alwaysWrite, hasMerged, assert.True},
{"fork PR with write permission does not need approval", forkRun, normalUser, alwaysWrite, noMerged, assert.False},
{"fork PR with merged PR but no write permission does not need approval", forkRun, normalUser, neverWrite, hasMerged, assert.False},
{"fork PR with no write and no merged PR needs approval", forkRun, normalUser, neverWrite, noMerged, assert.True},
} {
t.Run(tt.name, func(t *testing.T) {
need, err := ifNeedApprovalWith(t.Context(), tt.run, repo, tt.user, tt.canWrite, tt.hasMerged)
require.NoError(t, err)
tt.check(t, need)
})
}
t.Run("canWriteActions error is propagated", func(t *testing.T) {
failWrite := func(_ context.Context, _ *repo_model.Repository, _ *user_model.User) (bool, error) {
+46 -61
View File
@@ -16,21 +16,52 @@ import (
"go.yaml.in/yaml/v4"
)
func TestParseRawPermissions_ReadAll(t *testing.T) {
var rawPerms yaml.Node
err := yaml.Unmarshal([]byte(`read-all`), &rawPerms)
assert.NoError(t, err)
result := parseRawPermissionsExplicit(&rawPerms)
require.NotNil(t, result)
assert.Equal(t, perm.AccessModeRead, result.UnitAccessModes[unit.TypeCode])
assert.Equal(t, perm.AccessModeRead, result.UnitAccessModes[unit.TypeIssues])
assert.Equal(t, perm.AccessModeRead, result.UnitAccessModes[unit.TypePullRequests])
assert.Equal(t, perm.AccessModeRead, result.UnitAccessModes[unit.TypePackages])
assert.Equal(t, perm.AccessModeRead, result.UnitAccessModes[unit.TypeActions])
assert.Equal(t, perm.AccessModeRead, result.UnitAccessModes[unit.TypeWiki])
assert.Equal(t, perm.AccessModeRead, result.UnitAccessModes[unit.TypeProjects])
func TestParseRawPermissions_Scopes(t *testing.T) {
for _, tt := range []struct {
name string
input string
expectedModes [7]perm.AccessMode
idToken bool
}{
{"ReadAll", "read-all", [7]perm.AccessMode{
perm.AccessModeRead, perm.AccessModeRead, perm.AccessModeRead,
perm.AccessModeRead, perm.AccessModeRead, perm.AccessModeRead, perm.AccessModeRead,
}, false},
{"WriteAll", "write-all", [7]perm.AccessMode{
perm.AccessModeWrite, perm.AccessModeWrite, perm.AccessModeWrite,
perm.AccessModeWrite, perm.AccessModeWrite, perm.AccessModeWrite, perm.AccessModeWrite,
}, true},
{"IndividualScopes", `
contents: write
issues: read
pull-requests: none
packages: write
actions: read
wiki: write
projects: none
id-token: write
`, [7]perm.AccessMode{
perm.AccessModeWrite, perm.AccessModeRead, perm.AccessModeNone,
perm.AccessModeWrite, perm.AccessModeRead, perm.AccessModeWrite, perm.AccessModeNone,
}, true},
} {
t.Run(tt.name, func(t *testing.T) {
var rawPerms yaml.Node
err := yaml.Unmarshal([]byte(tt.input), &rawPerms)
assert.NoError(t, err)
result := parseRawPermissionsExplicit(&rawPerms)
require.NotNil(t, result)
for i, unitType := range []unit.Type{
unit.TypeCode, unit.TypeIssues, unit.TypePullRequests, unit.TypePackages,
unit.TypeActions, unit.TypeWiki, unit.TypeProjects,
} {
assert.Equal(t, tt.expectedModes[i], result.UnitAccessModes[unitType])
}
if tt.idToken {
assert.True(t, result.IDToken)
}
})
}
}
// TestParseRawPermissions_GithubScopes verifies that all scopes that github supports are accounted for
@@ -63,52 +94,6 @@ statuses: read`
// No asserts for permissions set on purpose
}
func TestParseRawPermissions_WriteAll(t *testing.T) {
var rawPerms yaml.Node
err := yaml.Unmarshal([]byte(`write-all`), &rawPerms)
assert.NoError(t, err)
result := parseRawPermissionsExplicit(&rawPerms)
require.NotNil(t, result)
assert.Equal(t, perm.AccessModeWrite, result.UnitAccessModes[unit.TypeCode])
assert.Equal(t, perm.AccessModeWrite, result.UnitAccessModes[unit.TypeIssues])
assert.Equal(t, perm.AccessModeWrite, result.UnitAccessModes[unit.TypePullRequests])
assert.Equal(t, perm.AccessModeWrite, result.UnitAccessModes[unit.TypePackages])
assert.Equal(t, perm.AccessModeWrite, result.UnitAccessModes[unit.TypeActions])
assert.Equal(t, perm.AccessModeWrite, result.UnitAccessModes[unit.TypeWiki])
assert.Equal(t, perm.AccessModeWrite, result.UnitAccessModes[unit.TypeProjects])
assert.True(t, result.IDToken)
}
func TestParseRawPermissions_IndividualScopes(t *testing.T) {
yamlContent := `
contents: write
issues: read
pull-requests: none
packages: write
actions: read
wiki: write
projects: none
id-token: write
`
var rawPerms yaml.Node
err := yaml.Unmarshal([]byte(yamlContent), &rawPerms)
assert.NoError(t, err)
result := parseRawPermissionsExplicit(&rawPerms)
require.NotNil(t, result)
assert.Equal(t, perm.AccessModeWrite, result.UnitAccessModes[unit.TypeCode])
assert.Equal(t, perm.AccessModeRead, result.UnitAccessModes[unit.TypeIssues])
assert.Equal(t, perm.AccessModeNone, result.UnitAccessModes[unit.TypePullRequests])
assert.Equal(t, perm.AccessModeWrite, result.UnitAccessModes[unit.TypePackages])
assert.Equal(t, perm.AccessModeRead, result.UnitAccessModes[unit.TypeActions])
assert.Equal(t, perm.AccessModeWrite, result.UnitAccessModes[unit.TypeWiki])
assert.Equal(t, perm.AccessModeNone, result.UnitAccessModes[unit.TypeProjects])
assert.True(t, result.IDToken)
}
func TestParseRawPermissions_Priority(t *testing.T) {
t.Run("granular-wins-over-contents", func(t *testing.T) {
yamlContent := `
+38 -65
View File
@@ -25,63 +25,38 @@ import (
)
func TestCheckCallerChain_Cycle(t *testing.T) {
t.Run("DirectCycle", func(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
for _, testCase := range []struct {
name string
uses []string
sourceRepoID int64
error string
}{
// A -> A: leaf's CallUses matches its direct parent's.
chain := buildCallerChain(t,
"./.gitea/workflows/a.yml",
"./.gitea/workflows/a.yml",
)
err := checkCallerChain(t.Context(), chain[len(chain)-1])
assert.ErrorContains(t, err, "cycle detected")
})
t.Run("IndirectCycle", func(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
{"DirectCycle", []string{"./.gitea/workflows/a.yml", "./.gitea/workflows/a.yml"}, 0, "cycle detected"},
// A -> B -> A: leaf's CallUses matches its grandparent's.
chain := buildCallerChain(t,
"./.gitea/workflows/a.yml",
"./.gitea/workflows/b.yml",
"./.gitea/workflows/a.yml",
)
err := checkCallerChain(t.Context(), chain[len(chain)-1])
assert.ErrorContains(t, err, "cycle detected")
})
t.Run("MixedPrefixCycle", func(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
{"IndirectCycle", []string{"./.gitea/workflows/a.yml", "./.gitea/workflows/b.yml", "./.gitea/workflows/a.yml"}, 0, "cycle detected"},
// A -> A written with both same-repo prefixes: they name the same file.
chain := buildCallerChain(t,
"./.gitea/workflows/a.yml",
"$/.gitea/workflows/a.yml",
)
err := checkCallerChain(t.Context(), chain[len(chain)-1])
assert.ErrorContains(t, err, "cycle detected")
assert.Equal(t, canonicalCallUses(&actions_model.ActionRunJob{CallUses: "owner/repo/.gitea/workflows/a.yml@v1"}), canonicalCallUses(&actions_model.ActionRunJob{CallUses: "self:owner/repo/.gitea/workflows/a.yml@v1"}))
})
t.Run("NoCycle", func(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
{"MixedPrefixCycle", []string{"./.gitea/workflows/a.yml", "$/.gitea/workflows/a.yml"}, 0, "cycle detected"},
// Sanity: linear chain with distinct CallUses must not trip cycle detection.
chain := buildCallerChain(t,
"./.gitea/workflows/a.yml",
"./.gitea/workflows/b.yml",
"./.gitea/workflows/c.yml",
)
require.NoError(t, checkCallerChain(t.Context(), chain[len(chain)-1]))
})
t.Run("SameLocalPathInOtherRepo", func(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
chain := buildCallerChain(t,
"./.gitea/workflows/a.yml",
"owner/lib/.gitea/workflows/lib.yml@v1",
"./.gitea/workflows/a.yml",
)
leaf := chain[len(chain)-1]
leaf.WorkflowSourceRepoID = 2
require.NoError(t, checkCallerChain(t.Context(), leaf))
})
{"NoCycle", []string{"./.gitea/workflows/a.yml", "./.gitea/workflows/b.yml", "./.gitea/workflows/c.yml"}, 0, ""},
{"SameLocalPathInOtherRepo", []string{"./.gitea/workflows/a.yml", "owner/lib/.gitea/workflows/lib.yml@v1", "./.gitea/workflows/a.yml"}, 2, ""},
} {
t.Run(testCase.name, func(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
chain := buildCallerChain(t, testCase.uses...)
leaf := chain[len(chain)-1]
leaf.WorkflowSourceRepoID = testCase.sourceRepoID
err := checkCallerChain(t.Context(), leaf)
if testCase.error == "" {
require.NoError(t, err)
} else {
assert.ErrorContains(t, err, testCase.error)
}
if testCase.name == "MixedPrefixCycle" {
assert.Equal(t, canonicalCallUses(&actions_model.ActionRunJob{CallUses: "owner/repo/.gitea/workflows/a.yml@v1"}), canonicalCallUses(&actions_model.ActionRunJob{CallUses: "self:owner/repo/.gitea/workflows/a.yml@v1"}))
}
})
}
t.Run("ResolvedIdentityCycle", func(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
@@ -205,20 +180,18 @@ func TestResolveUses(t *testing.T) {
t.Run("DirectoryAllowlist", func(t *testing.T) {
// SCOPED_WORKFLOW_DIRS is allowed (local and cross-repo).
ref, err := ResolveUses(ctx, "./.gitea/scoped_workflows/lib.yml")
require.NoError(t, err)
assert.Equal(t, ".gitea/scoped_workflows/lib.yml", ref.Path)
ref, err = ResolveUses(ctx, "owner/repo/.gitea/scoped_workflows/lib.yml@v1")
require.NoError(t, err)
assert.Equal(t, ".gitea/scoped_workflows/lib.yml", ref.Path)
ref, err = ResolveUses(ctx, "self:owner/repo/.gitea/scoped_workflows/lib.yml@v1")
require.NoError(t, err)
assert.Equal(t, ".gitea/scoped_workflows/lib.yml", ref.Path)
for _, uses := range []string{
"./.gitea/scoped_workflows/lib.yml",
"owner/repo/.gitea/scoped_workflows/lib.yml@v1",
"self:owner/repo/.gitea/scoped_workflows/lib.yml@v1",
} {
ref, err := ResolveUses(ctx, uses)
require.NoError(t, err)
assert.Equal(t, ".gitea/scoped_workflows/lib.yml", ref.Path)
}
// A directory that is neither WORKFLOW_DIRS nor SCOPED_WORKFLOW_DIRS parses but is rejected by the allowlist.
_, err = ResolveUses(ctx, "./not-workflows/build.yml")
_, err := ResolveUses(ctx, "./not-workflows/build.yml")
require.Error(t, err)
_, err = ResolveUses(ctx, "owner/repo/lib/build.yml@v1")
require.Error(t, err)
+27 -33
View File
@@ -25,37 +25,31 @@ func TestParseAgitPushOptionValue(t *testing.T) {
func TestGetAgitBranchInfo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
_, _, err := GetAgitBranchInfo(t.Context(), 1, "non-exist-basebranch")
assert.ErrorIs(t, err, util.ErrNotExist)
baseBranch, currentTopicBranch, err := GetAgitBranchInfo(t.Context(), 1, "master")
assert.NoError(t, err)
assert.Equal(t, "master", baseBranch)
assert.Empty(t, currentTopicBranch)
baseBranch, currentTopicBranch, err = GetAgitBranchInfo(t.Context(), 1, "master/topicbranch")
assert.NoError(t, err)
assert.Equal(t, "master", baseBranch)
assert.Equal(t, "topicbranch", currentTopicBranch)
baseBranch, currentTopicBranch, err = GetAgitBranchInfo(t.Context(), 1, "master/")
assert.NoError(t, err)
assert.Equal(t, "master", baseBranch)
assert.Empty(t, currentTopicBranch)
_, _, err = GetAgitBranchInfo(t.Context(), 1, "/")
assert.ErrorIs(t, err, util.ErrNotExist)
_, _, err = GetAgitBranchInfo(t.Context(), 1, "//")
assert.ErrorIs(t, err, util.ErrNotExist)
baseBranch, currentTopicBranch, err = GetAgitBranchInfo(t.Context(), 1, "master/topicbranch/")
assert.NoError(t, err)
assert.Equal(t, "master", baseBranch)
assert.Equal(t, "topicbranch/", currentTopicBranch)
baseBranch, currentTopicBranch, err = GetAgitBranchInfo(t.Context(), 1, "master/topicbranch/1")
assert.NoError(t, err)
assert.Equal(t, "master", baseBranch)
assert.Equal(t, "topicbranch/1", currentTopicBranch)
for _, tc := range []struct {
branch string
topic string
missing bool
}{
{"non-exist-basebranch", "", true},
{"master", "", false},
{"master/topicbranch", "topicbranch", false},
{"master/", "", false},
{"/", "", true},
{"//", "", true},
{"master/topicbranch/", "topicbranch/", false},
{"master/topicbranch/1", "topicbranch/1", false},
} {
baseBranch, currentTopicBranch, err := GetAgitBranchInfo(t.Context(), 1, tc.branch)
if tc.missing {
assert.ErrorIs(t, err, util.ErrNotExist)
} else {
assert.NoError(t, err)
assert.Equal(t, "master", baseBranch)
if tc.topic == "" {
assert.Empty(t, currentTopicBranch)
} else {
assert.Equal(t, tc.topic, currentTopicBranch)
}
}
}
}
+10 -40
View File
@@ -21,50 +21,20 @@ func TestAddLdapSSHPublicKeys(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
s := &auth.Source{ID: 1}
testCases := []struct {
const (
rsaKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM="
dssKey = "ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag="
)
for i, kase := range []struct {
keyString string
number int
keyContents []string
}{
{
keyString: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment\n",
number: 1,
keyContents: []string{
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=",
},
},
{
keyString: `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment
ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag= nocomment`,
number: 2,
keyContents: []string{
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=",
"ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag=",
},
},
{
keyString: `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment
# comment asmdna,ndp
ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag= nocomment`,
number: 2,
keyContents: []string{
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=",
"ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag=",
},
},
{
keyString: `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment
382488320jasdj1lasmva/vasodifipi4193-fksma.cm
ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag= nocomment`,
number: 2,
keyContents: []string{
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=",
"ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag=",
},
},
}
for i, kase := range testCases {
{rsaKey + " nocomment\n", 1, []string{rsaKey}},
{rsaKey + " nocomment\n" + dssKey + " nocomment", 2, []string{rsaKey, dssKey}},
{rsaKey + " nocomment\n# comment asmdna,ndp\n" + dssKey + " nocomment", 2, []string{rsaKey, dssKey}},
{rsaKey + " nocomment\n382488320jasdj1lasmva/vasodifipi4193-fksma.cm\n" + dssKey + " nocomment", 2, []string{rsaKey, dssKey}},
} {
s.ID = int64(i) + 20
asymkey_model.AddPublicKeysBySource(t.Context(), user, s, []string{kase.keyString}, false)
keys, err := db.Find[asymkey_model.PublicKey](t.Context(), asymkey_model.FindPublicKeyOptions{
+15 -24
View File
@@ -236,30 +236,21 @@ func TestRenderMessage(t *testing.T) {
}
})
t.Run("ReservedPlaceholders", func(t *testing.T) {
assert.Equal(t,
"User Actor started impersonating user owner/repo.",
renderMessage(audit_model.UserImpersonation, actor, scope, nil),
)
})
t.Run("NonStringMetadata", func(t *testing.T) {
assert.Equal(t,
"Removed external login from authentication source 7 for user owner/repo.",
renderMessage(audit_model.UserExternalLoginRemove, actor, scope, map[string]any{"auth_source_id": int64(7)}),
)
})
t.Run("MissingMetadataKeepsTheKey", func(t *testing.T) {
assert.Equal(t,
"Added deploy key deploy_key for repository owner/repo.",
renderMessage(audit_model.RepositoryDeployKeyAdd, actor, scope, nil),
)
})
t.Run("UnknownActionFallsBackToItsName", func(t *testing.T) {
assert.Equal(t, "not:an:action", renderMessage(audit_model.Action("not:an:action"), actor, scope, nil))
})
for _, tc := range []struct {
name string
action audit_model.Action
metadata map[string]any
message string
}{
{"ReservedPlaceholders", audit_model.UserImpersonation, nil, "User Actor started impersonating user owner/repo."},
{"NonStringMetadata", audit_model.UserExternalLoginRemove, map[string]any{"auth_source_id": int64(7)}, "Removed external login from authentication source 7 for user owner/repo."},
{"MissingMetadataKeepsTheKey", audit_model.RepositoryDeployKeyAdd, nil, "Added deploy key deploy_key for repository owner/repo."},
{"UnknownActionFallsBackToItsName", audit_model.Action("not:an:action"), nil, "not:an:action"},
} {
t.Run(tc.name, func(t *testing.T) {
assert.Equal(t, tc.message, renderMessage(tc.action, actor, scope, tc.metadata))
})
}
}
func TestActionFilters(t *testing.T) {
+38 -50
View File
@@ -28,54 +28,42 @@ func TestAuditNotifier(t *testing.T) {
SetRequestInfo(ctx, audit_model.OriginUI, "127.0.0.1")
notifier := new(auditNotifier)
issue := &issues_model.Issue{ID: 10, Index: 5, Title: "Issue title", Poster: doer, Repo: repo}
notifier.NewIssue(ctx, issue, nil)
unittest.AssertExistsAndLoadBean(t, &audit_model.Event{
Action: audit_model.IssueCreate,
ScopeType: audit_model.ScopeRepository,
ScopeID: repo.ID,
Origin: audit_model.OriginUI,
})
pr := &issues_model.PullRequest{ID: 11, Issue: &issues_model.Issue{ID: 12, Index: 6, Title: "PR title", Poster: doer, Repo: repo, IsPull: true}}
notifier.NewPullRequest(ctx, pr, nil)
unittest.AssertExistsAndLoadBean(t, &audit_model.Event{
Action: audit_model.PullRequestCreate,
ScopeType: audit_model.ScopeRepository,
ScopeID: repo.ID,
Origin: audit_model.OriginUI,
})
notifier.NewWikiPage(ctx, doer, repo, "Home", "")
unittest.AssertExistsAndLoadBean(t, &audit_model.Event{
Action: audit_model.WikiPageCreate,
ScopeType: audit_model.ScopeRepository,
ScopeID: repo.ID,
Origin: audit_model.OriginUI,
})
notifier.CreateRepository(ctx, doer, doer, repo)
unittest.AssertExistsAndLoadBean(t, &audit_model.Event{
Action: audit_model.RepositoryCreate,
ActorID: doer.ID,
ScopeType: audit_model.ScopeRepository,
ScopeID: repo.ID,
Origin: audit_model.OriginUI,
})
notifier.TransferRepository(ctx, doer, repo, "previous_owner")
unittest.AssertExistsAndLoadBean(t, &audit_model.Event{
Action: audit_model.RepositoryTransferFinish,
ActorID: doer.ID,
ScopeType: audit_model.ScopeRepository,
ScopeID: repo.ID,
Message: "Transferred repository owner/repo from previous_owner to owner.",
})
notifier.ChangeDefaultBranch(ctx, repo)
unittest.AssertExistsAndLoadBean(t, &audit_model.Event{
Action: audit_model.RepositoryBranchDefault,
ScopeType: audit_model.ScopeRepository,
ScopeID: repo.ID,
})
for _, tc := range []struct {
notify func()
event audit_model.Event
}{
{
func() {
notifier.NewIssue(ctx, &issues_model.Issue{ID: 10, Index: 5, Title: "Issue title", Poster: doer, Repo: repo}, nil)
},
audit_model.Event{Action: audit_model.IssueCreate, Origin: audit_model.OriginUI},
},
{
func() {
notifier.NewPullRequest(ctx, &issues_model.PullRequest{ID: 11, Issue: &issues_model.Issue{ID: 12, Index: 6, Title: "PR title", Poster: doer, Repo: repo, IsPull: true}}, nil)
},
audit_model.Event{Action: audit_model.PullRequestCreate, Origin: audit_model.OriginUI},
},
{
func() { notifier.NewWikiPage(ctx, doer, repo, "Home", "") },
audit_model.Event{Action: audit_model.WikiPageCreate, Origin: audit_model.OriginUI},
},
{
func() { notifier.CreateRepository(ctx, doer, doer, repo) },
audit_model.Event{Action: audit_model.RepositoryCreate, ActorID: doer.ID, Origin: audit_model.OriginUI},
},
{
func() { notifier.TransferRepository(ctx, doer, repo, "previous_owner") },
audit_model.Event{Action: audit_model.RepositoryTransferFinish, ActorID: doer.ID, Message: "Transferred repository owner/repo from previous_owner to owner."},
},
{
func() { notifier.ChangeDefaultBranch(ctx, repo) },
audit_model.Event{Action: audit_model.RepositoryBranchDefault},
},
} {
tc.notify()
tc.event.ScopeType = audit_model.ScopeRepository
tc.event.ScopeID = repo.ID
unittest.AssertExistsAndLoadBean(t, &tc.event)
}
}
+15 -164
View File
@@ -21,174 +21,25 @@ func TestUpload(t *testing.T) {
kases := []struct {
data []byte
fileName string
allowedTypes string
allowedTypes []string
err error
}{
{
data: testContent,
fileName: "test.txt",
allowedTypes: "",
err: nil,
},
{
data: testContent,
fileName: "dir/test.txt",
allowedTypes: "",
err: nil,
},
{
data: testContent,
fileName: "../../../test.txt",
allowedTypes: "",
err: nil,
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: "",
err: nil,
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: ",",
err: nil,
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: "|",
err: nil,
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: "*/*",
err: nil,
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: "*/*,",
err: nil,
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: "*/*|",
err: nil,
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: "text/plain",
err: nil,
},
{
data: testContent,
fileName: "dir/test.txt",
allowedTypes: "text/plain",
err: nil,
},
{
data: testContent,
fileName: "/dir.txt/test.js",
allowedTypes: ".js",
err: nil,
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: " text/plain ",
err: nil,
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: ".txt",
err: nil,
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: " .txt,.js",
err: nil,
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: " .txt|.js",
err: nil,
},
{
data: testContent,
fileName: "../../test.txt",
allowedTypes: " .txt|.js",
err: nil,
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: " .txt ,.js ",
err: nil,
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: "text/plain, .txt",
err: nil,
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: "text/*",
err: nil,
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: "text/*,.js",
err: nil,
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: "text/**",
err: ErrFileTypeForbidden{"text/plain; charset=utf-8"},
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: "application/x-gzip",
err: ErrFileTypeForbidden{"text/plain; charset=utf-8"},
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: ".zip",
err: ErrFileTypeForbidden{"text/plain; charset=utf-8"},
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: ".zip,.txtx",
err: ErrFileTypeForbidden{"text/plain; charset=utf-8"},
},
{
data: testContent,
fileName: "test.txt",
allowedTypes: ".zip|.txtx",
err: ErrFileTypeForbidden{"text/plain; charset=utf-8"},
},
{
data: b.Bytes(),
fileName: "test.txt",
allowedTypes: "application/x-gzip",
err: nil,
},
{testContent, "test.txt", []string{""}, nil},
{testContent, "dir/test.txt", []string{""}, nil},
{testContent, "../../../test.txt", []string{""}, nil},
{testContent, "test.txt", []string{"", ",", "|", "*/*", "*/*,", "*/*|", "text/plain"}, nil},
{testContent, "dir/test.txt", []string{"text/plain"}, nil},
{testContent, "/dir.txt/test.js", []string{".js"}, nil},
{testContent, "test.txt", []string{" text/plain ", ".txt", " .txt,.js", " .txt|.js"}, nil},
{testContent, "../../test.txt", []string{" .txt|.js"}, nil},
{testContent, "test.txt", []string{" .txt ,.js ", "text/plain, .txt", "text/*", "text/*,.js"}, nil},
{testContent, "test.txt", []string{"text/**", "application/x-gzip", ".zip", ".zip,.txtx", ".zip|.txtx"}, ErrFileTypeForbidden{"text/plain; charset=utf-8"}},
{b.Bytes(), "test.txt", []string{"application/x-gzip"}, nil},
}
for _, kase := range kases {
assert.Equal(t, kase.err, Verify(kase.data, kase.fileName, kase.allowedTypes))
for _, allowedTypes := range kase.allowedTypes {
assert.Equal(t, kase.err, Verify(kase.data, kase.fileName, allowedTypes))
}
}
}
+4 -9
View File
@@ -16,9 +16,9 @@ import (
"github.com/stretchr/testify/require"
)
func TestToCommitMeta(t *testing.T) {
func TestToCommitMetaAndTree(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
sha1 := git.Sha1ObjectFormat
signature := &git.Signature{Name: "Test Signature", Email: "test@email.com", When: time.Unix(0, 0)}
tag := &git.Tag{
@@ -30,20 +30,15 @@ func TestToCommitMeta(t *testing.T) {
CommitMessage: git.CommitMessage{MessageRaw: "Test Message"},
}
commitMeta := ToCommitMeta(headRepo, tag)
commitMeta := ToCommitMeta(repo, tag)
assert.NotNil(t, commitMeta)
assert.Equal(t, &api.CommitMeta{
SHA: sha1.EmptyObjectID().String(),
URL: headRepo.APIURL() + "/git/commits/" + sha1.EmptyObjectID().String(),
URL: repo.APIURL() + "/git/commits/" + sha1.EmptyObjectID().String(),
Created: time.Unix(0, 0),
}, commitMeta)
}
func TestToCommitTree(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
signature := &git.Signature{Name: "Test Signature", Email: "test@email.com", When: time.Unix(0, 0)}
commit := &git.Commit{
ID: git.MustIDFromString("65f1bf27bc3bf70f64657658635e66094edbcb4d"),
TreeID: git.MustIDFromString("2a2f1d4670728a2e10049e345bd7a276468beab6"),
+28 -39
View File
@@ -96,49 +96,38 @@ func TestToNotificationThread(t *testing.T) {
assert.True(t, thread.Pinned)
})
t.Run("merged pull request returns merged state", func(t *testing.T) {
for _, test := range []struct {
name string
issueID int64
notificationID int64
state api.NotifySubjectStateType
}{
// Issue 2 is a pull request; pull_request 1 has has_merged=true.
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
n := &activities_model.Notification{
ID: 999,
UserID: 2,
RepoID: repo.ID,
Status: activities_model.NotificationStatusUnread,
Source: activities_model.NotificationSourcePullRequest,
IssueID: issue.ID,
Issue: issue,
Repository: repo,
}
thread := ToNotificationThread(t.Context(), n)
require.NotNil(t, thread.Subject)
assert.Equal(t, api.NotifySubjectPull, thread.Subject.Type)
assert.Equal(t, api.NotifySubjectStateMerged, thread.Subject.State)
})
t.Run("open pull request returns open state", func(t *testing.T) {
{"merged pull request returns merged state", 2, 999, api.NotifySubjectStateMerged},
// Issue 3 is a pull request; pull_request 2 has has_merged=false.
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
{"open pull request returns open state", 3, 998, api.NotifySubjectStateOpen},
} {
t.Run(test.name, func(t *testing.T) {
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
n := &activities_model.Notification{
ID: 998,
UserID: 2,
RepoID: repo.ID,
Status: activities_model.NotificationStatusUnread,
Source: activities_model.NotificationSourcePullRequest,
IssueID: issue.ID,
Issue: issue,
Repository: repo,
}
n := &activities_model.Notification{
ID: test.notificationID,
UserID: 2,
RepoID: repo.ID,
Status: activities_model.NotificationStatusUnread,
Source: activities_model.NotificationSourcePullRequest,
IssueID: issue.ID,
Issue: issue,
Repository: repo,
}
thread := ToNotificationThread(t.Context(), n)
require.NotNil(t, thread.Subject)
assert.Equal(t, api.NotifySubjectPull, thread.Subject.Type)
assert.Equal(t, api.NotifySubjectStateOpen, thread.Subject.State)
})
thread := ToNotificationThread(t.Context(), n)
require.NotNil(t, thread.Subject)
assert.Equal(t, api.NotifySubjectPull, thread.Subject.Type)
assert.Equal(t, test.state, thread.Subject.State)
})
}
}
func newRepoNotification(t *testing.T, repoID, userID int64) *activities_model.Notification {
+21 -29
View File
@@ -19,34 +19,27 @@ func TestAddTaskToScheduler(t *testing.T) {
}
}()
// no seconds
err := addTaskToScheduler(&Task{
Name: "task 1",
config: &BaseConfig{
Schedule: "5 4 * * *",
},
})
assert.NoError(t, err)
jobs := scheduler.Jobs()
assert.Len(t, jobs, 1)
assert.Equal(t, "task 1", jobs[0].Tags()[0])
assert.Equal(t, "5 4 * * *", jobs[0].Tags()[1])
// with seconds
err = addTaskToScheduler(&Task{
Name: "task 2",
config: &BaseConfig{
Schedule: "30 5 4 * * *",
},
})
assert.NoError(t, err)
jobs = scheduler.Jobs() // the item order is not guaranteed, so we need to sort it before "assert"
sort.Slice(jobs, func(i, j int) bool {
return jobs[i].Tags()[0] < jobs[j].Tags()[0]
})
assert.Len(t, jobs, 2)
assert.Equal(t, "task 2", jobs[1].Tags()[0])
assert.Equal(t, "30 5 4 * * *", jobs[1].Tags()[1])
for i, task := range []struct {
name, schedule string
}{
{"task 1", "5 4 * * *"}, // no seconds
{"task 2", "30 5 4 * * *"}, // with seconds
} {
assert.NoError(t, addTaskToScheduler(&Task{
Name: task.name,
config: &BaseConfig{Schedule: task.schedule},
}))
jobs := scheduler.Jobs()
if i > 0 {
// the item order is not guaranteed, so we need to sort it before "assert"
sort.Slice(jobs, func(i, j int) bool {
return jobs[i].Tags()[0] < jobs[j].Tags()[0]
})
}
assert.Len(t, jobs, i+1)
assert.Equal(t, task.name, jobs[i].Tags()[0])
assert.Equal(t, task.schedule, jobs[i].Tags()[1])
}
}
func TestScheduleHasSeconds(t *testing.T) {
@@ -57,7 +50,6 @@ func TestScheduleHasSeconds(t *testing.T) {
{"* * * * * *", true},
{"* * * * *", false},
{"5 4 * * *", false},
{"5 4 * * *", false},
{"5,8 4 * * *", false},
{"* * * * * *", true},
{"5,8 4 * * *", false},
+65 -116
View File
@@ -16,33 +16,45 @@ import (
)
func TestGetFeeds(t *testing.T) {
// test with an individual user
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
actions, count, err := GetFeeds(t.Context(), activities_model.GetFeedsOptions{
RequestedUser: user,
Actor: user,
IncludePrivate: true,
OnlyPerformedBy: false,
IncludeDeleted: true,
})
assert.NoError(t, err)
if assert.Len(t, actions, 1) {
assert.EqualValues(t, 1, actions[0].ID)
assert.Equal(t, user.ID, actions[0].UserID)
for _, test := range []struct {
requestedUser *user_model.User
actionID int
includeDeleted bool
}{
{user, 1, false}, // test with an individual user
{org, 2, true}, // test with an organization user
} {
t.Run(test.requestedUser.Name, func(t *testing.T) {
actions, count, err := GetFeeds(t.Context(), activities_model.GetFeedsOptions{
RequestedUser: test.requestedUser,
Actor: user,
IncludePrivate: true,
OnlyPerformedBy: false,
IncludeDeleted: true,
})
assert.NoError(t, err)
if assert.Len(t, actions, 1) {
assert.EqualValues(t, test.actionID, actions[0].ID)
assert.Equal(t, test.requestedUser.ID, actions[0].UserID)
}
assert.Equal(t, int64(1), count)
actions, count, err = GetFeeds(t.Context(), activities_model.GetFeedsOptions{
RequestedUser: test.requestedUser,
Actor: user,
IncludePrivate: false,
OnlyPerformedBy: false,
IncludeDeleted: test.includeDeleted,
})
assert.NoError(t, err)
assert.Empty(t, actions)
assert.Equal(t, int64(0), count)
})
}
assert.Equal(t, int64(1), count)
actions, count, err = GetFeeds(t.Context(), activities_model.GetFeedsOptions{
RequestedUser: user,
Actor: user,
IncludePrivate: false,
OnlyPerformedBy: false,
})
assert.NoError(t, err)
assert.Empty(t, actions)
assert.Equal(t, int64(0), count)
}
func TestGetFeedsForRepos(t *testing.T) {
@@ -51,76 +63,29 @@ func TestGetFeedsForRepos(t *testing.T) {
privRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
pubRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8})
// private repo & no login
actions, count, err := GetFeeds(t.Context(), activities_model.GetFeedsOptions{
RequestedRepo: privRepo,
IncludePrivate: true,
})
assert.NoError(t, err)
assert.Empty(t, actions)
assert.Equal(t, int64(0), count)
// public repo & no login
actions, count, err = GetFeeds(t.Context(), activities_model.GetFeedsOptions{
RequestedRepo: pubRepo,
IncludePrivate: true,
})
assert.NoError(t, err)
assert.Len(t, actions, 1)
assert.Equal(t, int64(1), count)
// private repo and login
actions, count, err = GetFeeds(t.Context(), activities_model.GetFeedsOptions{
RequestedRepo: privRepo,
IncludePrivate: true,
Actor: user,
})
assert.NoError(t, err)
assert.Len(t, actions, 1)
assert.Equal(t, int64(1), count)
// public repo & login
actions, count, err = GetFeeds(t.Context(), activities_model.GetFeedsOptions{
RequestedRepo: pubRepo,
IncludePrivate: true,
Actor: user,
})
assert.NoError(t, err)
assert.Len(t, actions, 1)
assert.Equal(t, int64(1), count)
}
func TestGetFeeds2(t *testing.T) {
// test with an organization user
assert.NoError(t, unittest.PrepareTestDatabase())
org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
actions, count, err := GetFeeds(t.Context(), activities_model.GetFeedsOptions{
RequestedUser: org,
Actor: user,
IncludePrivate: true,
OnlyPerformedBy: false,
IncludeDeleted: true,
})
assert.NoError(t, err)
assert.Len(t, actions, 1)
if assert.Len(t, actions, 1) {
assert.EqualValues(t, 2, actions[0].ID)
assert.Equal(t, org.ID, actions[0].UserID)
for _, test := range []struct {
repo *repo_model.Repository
actor *user_model.User
count int64
}{
{privRepo, nil, 0}, // private repo & no login
{pubRepo, nil, 1}, // public repo & no login
{privRepo, user, 1}, // private repo and login
{pubRepo, user, 1}, // public repo & login
} {
actions, count, err := GetFeeds(t.Context(), activities_model.GetFeedsOptions{
RequestedRepo: test.repo,
IncludePrivate: true,
Actor: test.actor,
})
assert.NoError(t, err)
if test.count == 0 {
assert.Empty(t, actions)
} else {
assert.Len(t, actions, 1)
}
assert.Equal(t, test.count, count)
}
assert.Equal(t, int64(1), count)
actions, count, err = GetFeeds(t.Context(), activities_model.GetFeedsOptions{
RequestedUser: org,
Actor: user,
IncludePrivate: false,
OnlyPerformedBy: false,
IncludeDeleted: true,
})
assert.NoError(t, err)
assert.Empty(t, actions)
assert.Equal(t, int64(0), count)
}
func TestGetFeedsCorrupted(t *testing.T) {
@@ -175,30 +140,14 @@ func TestNotifyWatchers(t *testing.T) {
assert.NoError(t, NotifyWatchers(t.Context(), action))
// One watchers are inactive, thus action is only created for user 8, 1, 4, 11
unittest.AssertExistsAndLoadBean(t, &activities_model.Action{
ActUserID: action.ActUserID,
UserID: 8,
RepoID: action.RepoID,
OpType: action.OpType,
})
unittest.AssertExistsAndLoadBean(t, &activities_model.Action{
ActUserID: action.ActUserID,
UserID: 1,
RepoID: action.RepoID,
OpType: action.OpType,
})
unittest.AssertExistsAndLoadBean(t, &activities_model.Action{
ActUserID: action.ActUserID,
UserID: 4,
RepoID: action.RepoID,
OpType: action.OpType,
})
unittest.AssertExistsAndLoadBean(t, &activities_model.Action{
ActUserID: action.ActUserID,
UserID: 11,
RepoID: action.RepoID,
OpType: action.OpType,
})
for _, userID := range []int64{8, 1, 4, 11} {
unittest.AssertExistsAndLoadBean(t, &activities_model.Action{
ActUserID: action.ActUserID,
UserID: userID,
RepoID: action.RepoID,
OpType: action.OpType,
})
}
}
func TestNotifyWatchersRespectsWatchOptions(t *testing.T) {
+7 -26
View File
@@ -23,16 +23,8 @@ func TestRegisterForm_IsDomainAllowed_Empty(t *testing.T) {
func TestRegisterForm_IsDomainAllowed_InvalidEmail(t *testing.T) {
defer test.MockVariableValue(&setting.Service.EmailDomainAllowList, []glob.Glob{glob.MustCompile("gitea.io")})()
tt := []struct {
email string
}{
{"invalid-email"},
{"gitea.io"},
}
for _, v := range tt {
form := RegisterForm{Email: v.email}
for _, email := range []string{"invalid-email", "gitea.io"} {
form := RegisterForm{Email: email}
assert.False(t, form.IsEmailDomainAllowed())
}
}
@@ -87,23 +79,12 @@ func TestRegisterForm_IsDomainAllowed_BlockedEmail(t *testing.T) {
func TestDetectInvalidOAuth2ApplicationRedirectURI(t *testing.T) {
defer test.MockVariableValue(&setting.OAuth2.CustomSchemes)()
setting.OAuth2.CustomSchemes = []string{"my-app"}
assertValid := func(t *testing.T, s string, valid bool) {
ret := DetectInvalidOAuth2ApplicationRedirectURI([]string{s})
if valid {
assert.Empty(t, ret)
} else {
assert.Equal(t, s, ret)
}
for _, uri := range []string{"my-app:", "my-app:/foo", "http://foo", "https://foo"} {
assert.Empty(t, DetectInvalidOAuth2ApplicationRedirectURI([]string{uri}))
}
for _, uri := range []string{"my-app", "ftp:", "ftp://foo", "https://[invalid"} {
assert.Equal(t, uri, DetectInvalidOAuth2ApplicationRedirectURI([]string{uri}))
}
assertValid(t, "my-app:", true)
assertValid(t, "my-app:/foo", true)
assertValid(t, "http://foo", true)
assertValid(t, "https://foo", true)
assertValid(t, "my-app", false)
assertValid(t, "ftp:", false)
assertValid(t, "ftp://foo", false)
assertValid(t, "https://[invalid", false)
ret := DetectInvalidOAuth2ApplicationRedirectURI([]string{"my-app:", "http://foo", "https://foo"})
assert.Empty(t, ret)
+14 -36
View File
@@ -15,6 +15,11 @@ import (
)
func TestCSVDiff(t *testing.T) {
const diffHeader = `diff --git a/unittest.csv b/unittest.csv
--- a/unittest.csv
+++ b/unittest.csv
`
cases := []struct {
diff string
base string
@@ -23,10 +28,7 @@ func TestCSVDiff(t *testing.T) {
}{
// case 0 - initial commit of a csv
{
diff: `diff --git a/unittest.csv b/unittest.csv
--- a/unittest.csv
+++ b/unittest.csv
@@ -0,0 +1,2 @@
diff: diffHeader + `@@ -0,0 +1,2 @@
+col1,col2
+a,a`,
base: "",
@@ -39,10 +41,7 @@ a,a`,
},
// case 1 - adding 1 row at end
{
diff: `diff --git a/unittest.csv b/unittest.csv
--- a/unittest.csv
+++ b/unittest.csv
@@ -1,2 +1,3 @@
diff: diffHeader + `@@ -1,2 +1,3 @@
col1,col2
-a,a
+a,a
@@ -60,10 +59,7 @@ b,b`,
},
// case 2 - row deleted
{
diff: `diff --git a/unittest.csv b/unittest.csv
--- a/unittest.csv
+++ b/unittest.csv
@@ -1,3 +1,2 @@
diff: diffHeader + `@@ -1,3 +1,2 @@
col1,col2
-a,a
b,b`,
@@ -80,10 +76,7 @@ b,b`,
},
// case 3 - row changed
{
diff: `diff --git a/unittest.csv b/unittest.csv
--- a/unittest.csv
+++ b/unittest.csv
@@ -1,2 +1,2 @@
diff: diffHeader + `@@ -1,2 +1,2 @@
col1,col2
-b,b
+b,c`,
@@ -98,10 +91,7 @@ b,c`,
},
// case 4 - all deleted
{
diff: `diff --git a/unittest.csv b/unittest.csv
--- a/unittest.csv
+++ b/unittest.csv
@@ -1,2 +0,0 @@
diff: diffHeader + `@@ -1,2 +0,0 @@
-col1,col2
-b,c`,
base: `col1,col2
@@ -114,10 +104,7 @@ b,c`,
},
// case 5 - renames first column
{
diff: `diff --git a/unittest.csv b/unittest.csv
--- a/unittest.csv
+++ b/unittest.csv
@@ -1,3 +1,3 @@
diff: diffHeader + `@@ -1,3 +1,3 @@
-col1,col2,col3
+cola,col2,col3
a,b,c`,
@@ -132,10 +119,7 @@ a,b,c`,
},
// case 6 - inserts a column after first, deletes last column
{
diff: `diff --git a/unittest.csv b/unittest.csv
--- a/unittest.csv
+++ b/unittest.csv
@@ -1,2 +1,2 @@
diff: diffHeader + `@@ -1,2 +1,2 @@
-col1,col2,col3
-a,b,c
+col1,col1a,col2
@@ -151,10 +135,7 @@ a,d,b`,
},
// case 7 - deletes first column, inserts column after last
{
diff: `diff --git a/unittest.csv b/unittest.csv
--- a/unittest.csv
+++ b/unittest.csv
@@ -1,2 +1,2 @@
diff: diffHeader + `@@ -1,2 +1,2 @@
-col1,col2,col3
-a,b,c
+col2,col3,col4
@@ -170,10 +151,7 @@ b,c,d`,
},
// case 8 - two columns deleted, 2 added
{
diff: `diff --git a/unittest.csv b/unittest.csv
--- a/unittest.csv
+++ b/unittest.csv
@@ -1,2 +1,2 @@
diff: diffHeader + `@@ -1,2 +1,2 @@
-col1,col2,col
-a,b,c
+col3,col4,col5
+65 -112
View File
@@ -17,19 +17,59 @@ import (
)
func TestGitDiffTree(t *testing.T) {
firstCommitDiff := &DiffTree{
Files: []*DiffTreeRecord{
{
Status: "added",
HeadPath: ".gitignore",
BasePath: ".gitignore",
HeadMode: git.EntryModeBlob,
BaseMode: git.EntryModeNoEntry,
HeadBlobID: "f1c181ec9c5c921245027c6b452ecfc1d3626364",
BaseBlobID: "0000000000000000000000000000000000000000",
},
{
Status: "added",
HeadPath: "LICENSE",
BasePath: "LICENSE",
HeadMode: git.EntryModeBlob,
BaseMode: git.EntryModeNoEntry,
HeadBlobID: "c996f4725be8fc8c1d1c776e58c97ddc5d03b336",
BaseBlobID: "0000000000000000000000000000000000000000",
},
{
Status: "added",
HeadPath: "README.md",
BasePath: "README.md",
HeadMode: git.EntryModeBlob,
BaseMode: git.EntryModeNoEntry,
HeadBlobID: "074e590b8e64898b02beef03ece83f962c94f54c",
BaseBlobID: "0000000000000000000000000000000000000000",
},
},
}
readmeDiff := &DiffTreeRecord{
Status: "modified",
HeadPath: "README.md",
BasePath: "README.md",
HeadMode: git.EntryModeBlob,
BaseMode: git.EntryModeBlob,
HeadBlobID: "fb39771a8865c9a67f2ab9b616c854805664553c",
BaseBlobID: "9dfc0a6257d8eff526f0cfaf6a8ea950f55a9dba",
}
test := []struct {
Name string
RepoPath string
BaseSha string
HeadSha string
useMergeBase bool
Expected *DiffTree
}{
{
Name: "happy path",
RepoPath: "../../modules/git/tests/repos/repo5_pulls",
BaseSha: "72866af952e98d02a73003501836074b286a78f6",
HeadSha: "d8e0bbb45f200e67d9a784ce55bd90821af45ebd",
Name: "happy path",
BaseSha: "72866af952e98d02a73003501836074b286a78f6",
HeadSha: "d8e0bbb45f200e67d9a784ce55bd90821af45ebd",
Expected: &DiffTree{
Files: []*DiffTreeRecord{
{
@@ -55,89 +95,25 @@ func TestGitDiffTree(t *testing.T) {
},
{
Name: "first commit (no parent)",
RepoPath: "../../modules/git/tests/repos/repo5_pulls",
HeadSha: "72866af952e98d02a73003501836074b286a78f6",
Expected: &DiffTree{
Files: []*DiffTreeRecord{
{
Status: "added",
HeadPath: ".gitignore",
BasePath: ".gitignore",
HeadMode: git.EntryModeBlob,
BaseMode: git.EntryModeNoEntry,
HeadBlobID: "f1c181ec9c5c921245027c6b452ecfc1d3626364",
BaseBlobID: "0000000000000000000000000000000000000000",
},
{
Status: "added",
HeadPath: "LICENSE",
BasePath: "LICENSE",
HeadMode: git.EntryModeBlob,
BaseMode: git.EntryModeNoEntry,
HeadBlobID: "c996f4725be8fc8c1d1c776e58c97ddc5d03b336",
BaseBlobID: "0000000000000000000000000000000000000000",
},
{
Status: "added",
HeadPath: "README.md",
BasePath: "README.md",
HeadMode: git.EntryModeBlob,
BaseMode: git.EntryModeNoEntry,
HeadBlobID: "074e590b8e64898b02beef03ece83f962c94f54c",
BaseBlobID: "0000000000000000000000000000000000000000",
},
},
},
Expected: firstCommitDiff,
},
{
Name: "first commit (no parent), merge base = true",
RepoPath: "../../modules/git/tests/repos/repo5_pulls",
HeadSha: "72866af952e98d02a73003501836074b286a78f6",
useMergeBase: true,
Expected: &DiffTree{
Files: []*DiffTreeRecord{
{
Status: "added",
HeadPath: ".gitignore",
BasePath: ".gitignore",
HeadMode: git.EntryModeBlob,
BaseMode: git.EntryModeNoEntry,
HeadBlobID: "f1c181ec9c5c921245027c6b452ecfc1d3626364",
BaseBlobID: "0000000000000000000000000000000000000000",
},
{
Status: "added",
HeadPath: "LICENSE",
BasePath: "LICENSE",
HeadMode: git.EntryModeBlob,
BaseMode: git.EntryModeNoEntry,
HeadBlobID: "c996f4725be8fc8c1d1c776e58c97ddc5d03b336",
BaseBlobID: "0000000000000000000000000000000000000000",
},
{
Status: "added",
HeadPath: "README.md",
BasePath: "README.md",
HeadMode: git.EntryModeBlob,
BaseMode: git.EntryModeNoEntry,
HeadBlobID: "074e590b8e64898b02beef03ece83f962c94f54c",
BaseBlobID: "0000000000000000000000000000000000000000",
},
},
},
Expected: firstCommitDiff,
},
{
Name: "base and head same",
RepoPath: "../../modules/git/tests/repos/repo5_pulls",
BaseSha: "ed8f4d2fa5b2420706580d191f5dd50c4e491f3f",
HeadSha: "ed8f4d2fa5b2420706580d191f5dd50c4e491f3f",
Name: "base and head same",
BaseSha: "ed8f4d2fa5b2420706580d191f5dd50c4e491f3f",
HeadSha: "ed8f4d2fa5b2420706580d191f5dd50c4e491f3f",
Expected: &DiffTree{
Files: []*DiffTreeRecord{},
},
},
{
Name: "useMergeBase false",
RepoPath: "../../modules/git/tests/repos/repo5_pulls",
BaseSha: "ed8f4d2fa5b2420706580d191f5dd50c4e491f3f",
HeadSha: "111cac04bd7d20301964e27a93698aabb5781b80", // this commit can be found on the update-readme branch
useMergeBase: false,
@@ -152,42 +128,23 @@ func TestGitDiffTree(t *testing.T) {
HeadBlobID: "c996f4725be8fc8c1d1c776e58c97ddc5d03b336",
BaseBlobID: "ed5119b3c1f45547b6785bc03eac7f87570fa17f",
},
{
Status: "modified",
HeadPath: "README.md",
BasePath: "README.md",
HeadMode: git.EntryModeBlob,
BaseMode: git.EntryModeBlob,
HeadBlobID: "fb39771a8865c9a67f2ab9b616c854805664553c",
BaseBlobID: "9dfc0a6257d8eff526f0cfaf6a8ea950f55a9dba",
},
readmeDiff,
},
},
},
{
Name: "useMergeBase true",
RepoPath: "../../modules/git/tests/repos/repo5_pulls",
BaseSha: "ed8f4d2fa5b2420706580d191f5dd50c4e491f3f",
HeadSha: "111cac04bd7d20301964e27a93698aabb5781b80", // this commit can be found on the update-readme branch
useMergeBase: true,
Expected: &DiffTree{
Files: []*DiffTreeRecord{
{
Status: "modified",
HeadPath: "README.md",
BasePath: "README.md",
HeadMode: git.EntryModeBlob,
BaseMode: git.EntryModeBlob,
HeadBlobID: "fb39771a8865c9a67f2ab9b616c854805664553c",
BaseBlobID: "9dfc0a6257d8eff526f0cfaf6a8ea950f55a9dba",
},
readmeDiff,
},
},
},
{
Name: "no base set",
RepoPath: "../../modules/git/tests/repos/repo5_pulls",
HeadSha: "d8e0bbb45f200e67d9a784ce55bd90821af45ebd", // this commit can be found on the update-readme branch
useMergeBase: false,
Expected: &DiffTree{
@@ -208,7 +165,7 @@ func TestGitDiffTree(t *testing.T) {
for _, tt := range test {
t.Run(tt.Name, func(t *testing.T) {
gitRepo, err := git.OpenRepositoryLocal(t.Context(), tt.RepoPath)
gitRepo, err := git.OpenRepositoryLocal(t.Context(), "../../modules/git/tests/repos/repo5_pulls")
assert.NoError(t, err)
defer gitRepo.Close()
@@ -444,33 +401,29 @@ func TestParseGitDiffTree(t *testing.T) {
func TestGitDiffTreeErrors(t *testing.T) {
test := []struct {
Name string
RepoPath string
BaseSha string
HeadSha string
Name string
BaseSha string
HeadSha string
}{
{
Name: "head doesn't exist",
RepoPath: "../../modules/git/tests/repos/repo5_pulls",
BaseSha: "f32b0a9dfd09a60f616f29158f772cedd89942d2",
HeadSha: "asdfasdfasdf",
Name: "head doesn't exist",
BaseSha: "f32b0a9dfd09a60f616f29158f772cedd89942d2",
HeadSha: "asdfasdfasdf",
},
{
Name: "base doesn't exist",
RepoPath: "../../modules/git/tests/repos/repo5_pulls",
BaseSha: "asdfasdfasdf",
HeadSha: "f32b0a9dfd09a60f616f29158f772cedd89942d2",
Name: "base doesn't exist",
BaseSha: "asdfasdfasdf",
HeadSha: "f32b0a9dfd09a60f616f29158f772cedd89942d2",
},
{
Name: "head not set",
RepoPath: "../../modules/git/tests/repos/repo5_pulls",
BaseSha: "f32b0a9dfd09a60f616f29158f772cedd89942d2",
Name: "head not set",
BaseSha: "f32b0a9dfd09a60f616f29158f772cedd89942d2",
},
}
for _, tt := range test {
t.Run(tt.Name, func(t *testing.T) {
gitRepo, err := git.OpenRepositoryLocal(t.Context(), tt.RepoPath)
gitRepo, err := git.OpenRepositoryLocal(t.Context(), "../../modules/git/tests/repos/repo5_pulls")
assert.NoError(t, err)
defer gitRepo.Close()
+17 -27
View File
@@ -13,36 +13,26 @@ func TestTryFixTruncatedString(t *testing.T) {
assert.Equal(t, "", tryFixTruncatedString(""))
t.Run("UTF8", func(t *testing.T) {
s := "🌞a🌛"
assert.Equal(t, s[:1], tryFixTruncatedString(s[:1]))
assert.Equal(t, s[:2], tryFixTruncatedString(s[:2]))
assert.Equal(t, s[:3], tryFixTruncatedString(s[:3]))
assert.Equal(t, "🌞", tryFixTruncatedString(s[:4]))
assert.Equal(t, "🌞a", tryFixTruncatedString(s[:5]))
assert.Equal(t, "🌞a", tryFixTruncatedString(s[:6]))
assert.Equal(t, "🌞a", tryFixTruncatedString(s[:7]))
assert.Equal(t, "🌞a", tryFixTruncatedString(s[:8]))
assert.Equal(t, "🌞a🌛", tryFixTruncatedString(s[:9]))
s = "a🌞🌛"
assert.Equal(t, "a", tryFixTruncatedString(s[:1]))
assert.Equal(t, "a", tryFixTruncatedString(s[:2]))
assert.Equal(t, "a", tryFixTruncatedString(s[:3]))
assert.Equal(t, "a", tryFixTruncatedString(s[:4]))
assert.Equal(t, "a🌞", tryFixTruncatedString(s[:5]))
assert.Equal(t, "a🌞", tryFixTruncatedString(s[:6]))
for _, test := range []struct {
input string
expected []string
}{
{"🌞a🌛", []string{"🌞"[:1], "🌞"[:2], "🌞"[:3], "🌞", "🌞a", "🌞a", "🌞a", "🌞a", "🌞a🌛"}},
{"a🌞🌛", []string{"a", "a", "a", "a", "a🌞", "a🌞"}},
} {
for i, expected := range test.expected {
assert.Equal(t, expected, tryFixTruncatedString(test.input[:i+1]))
}
}
})
t.Run("Non-UTF8", func(t *testing.T) {
s := "\xff\xee\xff\xeeb\xff\xee\xff\xee"
assert.Equal(t, "\xff", tryFixTruncatedString(s[:1]))
assert.Equal(t, "\xff\xee", tryFixTruncatedString(s[:2]))
assert.Equal(t, "\xff\xee\xff", tryFixTruncatedString(s[:3]))
assert.Equal(t, "\xff\xee\xff\xee", tryFixTruncatedString(s[:4]))
assert.Equal(t, "\xff\xee\xff\xeeb", tryFixTruncatedString(s[:5]))
assert.Equal(t, "\xff\xee\xff\xeeb", tryFixTruncatedString(s[:6]))
assert.Equal(t, "\xff\xee\xff\xeeb", tryFixTruncatedString(s[:7]))
assert.Equal(t, "\xff\xee\xff\xeeb", tryFixTruncatedString(s[:8]))
assert.Equal(t, "\xff\xee\xff\xeeb\xff\xee\xff\xee", tryFixTruncatedString(s[:9]))
for i, expected := range []string{
"\xff", "\xff\xee", "\xff\xee\xff", "\xff\xee\xff\xee",
"\xff\xee\xff\xeeb", "\xff\xee\xff\xeeb", "\xff\xee\xff\xeeb", "\xff\xee\xff\xeeb", "\xff\xee\xff\xeeb\xff\xee\xff\xee",
} {
assert.Equal(t, expected, tryFixTruncatedString(s[:i+1]))
}
})
}
+108 -232
View File
@@ -269,27 +269,22 @@ index 0000000..6bb8f39
diffBuilder.WriteString("+line" + strconv.Itoa(i) + "\n")
}
diff = diffBuilder.String()
result, err := ParsePatch(t.Context(), 20, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff))
if err != nil {
t.Errorf("There should not be an error: %v", err)
}
if !result.Files[0].IsIncomplete {
t.Errorf("Files should be incomplete! %v", result.Files[0])
}
result, err = ParsePatch(t.Context(), 40, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff))
if err != nil {
t.Errorf("There should not be an error: %v", err)
}
if result.Files[0].IsIncomplete {
t.Errorf("Files should not be incomplete! %v", result.Files[0])
}
result, err = ParsePatch(t.Context(), 40, 5, setting.Git.MaxGitDiffFiles, strings.NewReader(diff))
if err != nil {
t.Errorf("There should not be an error: %v", err)
}
if result.Files[0].IsIncomplete {
t.Errorf("Files should not be incomplete! %v", result.Files[0])
checkLimits := func(maxLines, maxCharacters int, incomplete bool) {
result, err := ParsePatch(t.Context(), maxLines, maxCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff))
if err != nil {
t.Errorf("There should not be an error: %v", err)
}
if result.Files[0].IsIncomplete != incomplete {
if incomplete {
t.Errorf("Files should be incomplete! %v", result.Files[0])
} else {
t.Errorf("Files should not be incomplete! %v", result.Files[0])
}
}
}
checkLimits(20, setting.Git.MaxGitDiffLineCharacters, true)
checkLimits(40, setting.Git.MaxGitDiffLineCharacters, false)
checkLimits(40, 5, false)
// Test max characters
diff = `diff --git a/newfile2 b/newfile2
@@ -314,72 +309,24 @@ index 0000000..6bb8f39
diffBuilder.WriteString("+line" + strconv.Itoa(35) + "\n")
diff = diffBuilder.String()
result, err = ParsePatch(t.Context(), 20, 4096, setting.Git.MaxGitDiffFiles, strings.NewReader(diff))
if err != nil {
t.Errorf("There should not be an error: %v", err)
}
if !result.Files[0].IsIncomplete {
t.Errorf("Files should be incomplete! %v", result.Files[0])
}
result, err = ParsePatch(t.Context(), 40, 4096, setting.Git.MaxGitDiffFiles, strings.NewReader(diff))
if err != nil {
t.Errorf("There should not be an error: %v", err)
}
if result.Files[0].IsIncomplete {
t.Errorf("Files should not be incomplete! %v", result.Files[0])
}
checkLimits(20, 4096, true)
checkLimits(40, 4096, false)
diff = `diff --git "a/README.md" "b/README.md"
for _, header := range []string{
`diff --git "a/README.md" "b/README.md"
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
# gitea-github-migrator
+
+ Build Status
- Latest Release
Docker Pulls
+ cut off
+ cut off`
_, err = ParsePatch(t.Context(), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff))
if err != nil {
t.Errorf("ParsePatch failed: %s", err)
}
diff2 := `diff --git "a/A \\ B" "b/A \\ B"
+++ b/README.md`,
`diff --git "a/A \\ B" "b/A \\ B"
--- "a/A \\ B"
+++ "b/A \\ B"
@@ -1,3 +1,6 @@
# gitea-github-migrator
+
+ Build Status
- Latest Release
Docker Pulls
+ cut off
+ cut off`
_, err = ParsePatch(t.Context(), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2))
if err != nil {
t.Errorf("ParsePatch failed: %s", err)
}
diff2a := `diff --git "a/A \\ B" b/A/B
+++ "b/A \\ B"`,
`diff --git "a/A \\ B" b/A/B
--- "a/A \\ B"
+++ b/A/B
@@ -1,3 +1,6 @@
# gitea-github-migrator
+
+ Build Status
- Latest Release
Docker Pulls
+ cut off
+ cut off`
_, err = ParsePatch(t.Context(), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2a))
if err != nil {
t.Errorf("ParsePatch failed: %s", err)
}
diff3 := `diff --git a/README.md b/README.md
+++ b/A/B`,
`diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
+++ b/README.md`,
} {
_, err := ParsePatch(t.Context(), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(header+`
@@ -1,3 +1,6 @@
# gitea-github-migrator
+
@@ -387,10 +334,10 @@ index 0000000..6bb8f39
- Latest Release
Docker Pulls
+ cut off
+ cut off`
_, err = ParsePatch(t.Context(), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff3))
if err != nil {
t.Errorf("ParsePatch failed: %s", err)
+ cut off`))
if err != nil {
t.Errorf("ParsePatch failed: %s", err)
}
}
}
@@ -506,24 +453,21 @@ func setupDefaultDiff() *Diff {
}
}
func TestDiff_LoadCommentsNoOutdated(t *testing.T) {
func TestDiff_LoadComments(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
diff := setupDefaultDiff()
assert.NoError(t, diff.LoadComments(t.Context(), issue, user, false))
assert.Len(t, diff.Files[0].Sections[0].Lines[0].Comments, 2)
}
func TestDiff_LoadCommentsWithOutdated(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
diff := setupDefaultDiff()
assert.NoError(t, diff.LoadComments(t.Context(), issue, user, true))
assert.Len(t, diff.Files[0].Sections[0].Lines[0].Comments, 3)
for _, test := range []struct {
showOutdated bool
comments int
}{{false, 2}, {true, 3}} {
t.Run(strconv.FormatBool(test.showOutdated), func(t *testing.T) {
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
diff := setupDefaultDiff()
assert.NoError(t, diff.LoadComments(t.Context(), issue, user, test.showOutdated))
assert.Len(t, diff.Files[0].Sections[0].Lines[0].Comments, test.comments)
})
}
}
func TestDiffLine_CanComment(t *testing.T) {
@@ -574,21 +518,9 @@ func TestGetDiffRangeWithWhitespaceBehavior(t *testing.T) {
}
func TestNoCrashes(t *testing.T) {
type testcase struct {
gitdiff string
}
tests := []testcase{
{
gitdiff: "diff --git \n--- a\t\n",
},
{
gitdiff: "diff --git \"0\n",
},
}
for _, testcase := range tests {
for _, patch := range []string{"diff --git \n--- a\t\n", "diff --git \"0\n"} {
// It shouldn't crash, so don't care about the output.
ParsePatch(t.Context(), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(testcase.gitdiff))
ParsePatch(t.Context(), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(patch))
}
}
@@ -712,18 +644,15 @@ func TestGeneratePatchForUnchangedLineFromReader(t *testing.T) {
func TestCalculateHiddenCommentIDsForLine(t *testing.T) {
tests := []struct {
name string
line *DiffLine
sectionInfo *DiffLineSectionInfo
lineComments map[int64][]*issues_model.Comment
expected []int64
}{
{
name: "comments in hidden range",
line: &DiffLine{
Type: DiffLineSection,
SectionInfo: &DiffLineSectionInfo{
LastRightIdx: 10,
RightIdx: 20,
},
sectionInfo: &DiffLineSectionInfo{
LastRightIdx: 10,
RightIdx: 20,
},
lineComments: map[int64][]*issues_model.Comment{
15: {{ID: 100}, {ID: 101}},
@@ -733,12 +662,9 @@ func TestCalculateHiddenCommentIDsForLine(t *testing.T) {
},
{
name: "comments outside hidden range",
line: &DiffLine{
Type: DiffLineSection,
SectionInfo: &DiffLineSectionInfo{
LastRightIdx: 10,
RightIdx: 20,
},
sectionInfo: &DiffLineSectionInfo{
LastRightIdx: 10,
RightIdx: 20,
},
lineComments: map[int64][]*issues_model.Comment{
5: {{ID: 100}},
@@ -748,12 +674,9 @@ func TestCalculateHiddenCommentIDsForLine(t *testing.T) {
},
{
name: "negative line numbers (left side)",
line: &DiffLine{
Type: DiffLineSection,
SectionInfo: &DiffLineSectionInfo{
LastRightIdx: 10,
RightIdx: 20,
},
sectionInfo: &DiffLineSectionInfo{
LastRightIdx: 10,
RightIdx: 20,
},
lineComments: map[int64][]*issues_model.Comment{
-15: {{ID: 100}}, // Left-side comment, should NOT be counted
@@ -763,13 +686,10 @@ func TestCalculateHiddenCommentIDsForLine(t *testing.T) {
},
{
name: "boundary conditions - normal expansion (both boundaries exclusive)",
line: &DiffLine{
Type: DiffLineSection,
SectionInfo: &DiffLineSectionInfo{
LastRightIdx: 10,
RightIdx: 20,
RightHunkSize: 5, // Normal case: next section has content
},
sectionInfo: &DiffLineSectionInfo{
LastRightIdx: 10,
RightIdx: 20,
RightHunkSize: 5, // Normal case: next section has content
},
lineComments: map[int64][]*issues_model.Comment{
10: {{ID: 100}}, // at LastRightIdx (visible line), should NOT be included
@@ -781,13 +701,10 @@ func TestCalculateHiddenCommentIDsForLine(t *testing.T) {
},
{
name: "boundary conditions - end of file expansion (RightIdx inclusive)",
line: &DiffLine{
Type: DiffLineSection,
SectionInfo: &DiffLineSectionInfo{
LastRightIdx: 54,
RightIdx: 70,
RightHunkSize: 0, // End of file: no more content after
},
sectionInfo: &DiffLineSectionInfo{
LastRightIdx: 54,
RightIdx: 70,
RightHunkSize: 0, // End of file: no more content after
},
lineComments: map[int64][]*issues_model.Comment{
54: {{ID: 54}}, // at LastRightIdx (visible line), should NOT be included
@@ -798,13 +715,10 @@ func TestCalculateHiddenCommentIDsForLine(t *testing.T) {
},
{
name: "real-world scenario - start of file with hunk",
line: &DiffLine{
Type: DiffLineSection,
SectionInfo: &DiffLineSectionInfo{
LastRightIdx: 0, // No previous visible section
RightIdx: 26, // Line 26 is first visible line of hunk
RightHunkSize: 9, // Normal hunk with content
},
sectionInfo: &DiffLineSectionInfo{
LastRightIdx: 0, // No previous visible section
RightIdx: 26, // Line 26 is first visible line of hunk
RightHunkSize: 9, // Normal hunk with content
},
lineComments: map[int64][]*issues_model.Comment{
1: {{ID: 1}}, // Line 1 is hidden
@@ -818,8 +732,9 @@ func TestCalculateHiddenCommentIDsForLine(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
FillHiddenCommentIDsForDiffLine(tt.line, tt.lineComments)
assert.ElementsMatch(t, tt.expected, tt.line.SectionInfo.HiddenCommentIDs)
line := &DiffLine{Type: DiffLineSection, SectionInfo: tt.sectionInfo}
FillHiddenCommentIDsForDiffLine(line, tt.lineComments)
assert.ElementsMatch(t, tt.expected, line.SectionInfo.HiddenCommentIDs)
})
}
}
@@ -827,7 +742,7 @@ func TestCalculateHiddenCommentIDsForLine(t *testing.T) {
func TestDiffLine_RenderBlobExcerptButtons(t *testing.T) {
tests := []struct {
name string
line *DiffLine
sectionInfo *DiffLineSectionInfo
fileNameHash string
data *DiffBlobExcerptData
expectContains []string
@@ -835,17 +750,14 @@ func TestDiffLine_RenderBlobExcerptButtons(t *testing.T) {
}{
{
name: "expand up button with hidden comments",
line: &DiffLine{
Type: DiffLineSection,
SectionInfo: &DiffLineSectionInfo{
LastRightIdx: 0,
RightIdx: 26,
LeftIdx: 26,
LastLeftIdx: 0,
LeftHunkSize: 0,
RightHunkSize: 0,
HiddenCommentIDs: []int64{100},
},
sectionInfo: &DiffLineSectionInfo{
LastRightIdx: 0,
RightIdx: 26,
LeftIdx: 26,
LastLeftIdx: 0,
LeftHunkSize: 0,
RightHunkSize: 0,
HiddenCommentIDs: []int64{100},
},
fileNameHash: "abc123",
data: &DiffBlobExcerptData{
@@ -862,17 +774,14 @@ func TestDiffLine_RenderBlobExcerptButtons(t *testing.T) {
},
{
name: "expand up and down buttons with pull request",
line: &DiffLine{
Type: DiffLineSection,
SectionInfo: &DiffLineSectionInfo{
LastRightIdx: 10,
RightIdx: 50,
LeftIdx: 10,
LastLeftIdx: 5,
LeftHunkSize: 5,
RightHunkSize: 5,
HiddenCommentIDs: []int64{200, 201},
},
sectionInfo: &DiffLineSectionInfo{
LastRightIdx: 10,
RightIdx: 50,
LeftIdx: 10,
LastLeftIdx: 5,
LeftHunkSize: 5,
RightHunkSize: 5,
HiddenCommentIDs: []int64{200, 201},
},
fileNameHash: "def456",
data: &DiffBlobExcerptData{
@@ -893,17 +802,14 @@ func TestDiffLine_RenderBlobExcerptButtons(t *testing.T) {
},
{
name: "no hidden comments",
line: &DiffLine{
Type: DiffLineSection,
SectionInfo: &DiffLineSectionInfo{
LastRightIdx: 10,
RightIdx: 20,
LeftIdx: 10,
LastLeftIdx: 5,
LeftHunkSize: 5,
RightHunkSize: 5,
HiddenCommentIDs: nil,
},
sectionInfo: &DiffLineSectionInfo{
LastRightIdx: 10,
RightIdx: 20,
LeftIdx: 10,
LastLeftIdx: 5,
LeftHunkSize: 5,
RightHunkSize: 5,
HiddenCommentIDs: nil,
},
fileNameHash: "ghi789",
data: &DiffBlobExcerptData{
@@ -921,7 +827,7 @@ func TestDiffLine_RenderBlobExcerptButtons(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := tt.line.RenderBlobExcerptButtons(tt.fileNameHash, tt.data)
result := (&DiffLine{Type: DiffLineSection, SectionInfo: tt.sectionInfo}).RenderBlobExcerptButtons(tt.fileNameHash, tt.data)
resultStr := string(result)
for _, expected := range tt.expectContains {
@@ -1084,63 +990,33 @@ func TestDiffSection_GetComputedInlineDiffFor(t *testing.T) {
}
func TestHighlightCodeLines(t *testing.T) {
highlightLines := func(name string, lines []*DiffLine, content string) map[int]template.HTML {
return highlightCodeLinesForDiffFile(&DiffFile{
Name: name,
Sections: []*DiffSection{{Lines: lines}},
}, true, []byte(content))
}
t.Run("CharsetDetecting", func(t *testing.T) {
diffFile := &DiffFile{
Name: "a.c",
Sections: []*DiffSection{
{
Lines: []*DiffLine{{LeftIdx: 1}},
},
},
}
ret := highlightCodeLinesForDiffFile(diffFile, true, []byte("// abc\xcc def\xcd")) // ISO-8859-1 bytes
ret := highlightLines("a.c", []*DiffLine{{LeftIdx: 1}}, "// abc\xcc def\xcd") // ISO-8859-1 bytes
assert.Equal(t, "<span class=\"c1\">// abcÌ defÍ\n</span>", string(ret[0]))
})
t.Run("LeftLines", func(t *testing.T) {
diffFile := &DiffFile{
Name: "a.c",
Sections: []*DiffSection{
{
Lines: []*DiffLine{
{LeftIdx: 1},
{LeftIdx: 2},
{LeftIdx: 3},
},
},
},
}
const nl = "\n"
ret := highlightCodeLinesForDiffFile(diffFile, true, []byte("a\nb\n"))
ret := highlightLines("a.c", []*DiffLine{{LeftIdx: 1}, {LeftIdx: 2}, {LeftIdx: 3}}, "a\nb\n")
assert.Equal(t, map[int]template.HTML{
0: `<span class="n">a</span>` + nl,
1: `<span class="n">b</span>` + nl,
}, ret)
})
t.Run("CharCR", func(t *testing.T) {
diffFile := &DiffFile{
Name: "a.txt",
Sections: []*DiffSection{
{
Lines: []*DiffLine{{LeftIdx: 1}, {LeftIdx: 2}},
},
},
}
ret := highlightCodeLinesForDiffFile(diffFile, true, []byte("a\rb\r\nc"))
ret := highlightLines("a.txt", []*DiffLine{{LeftIdx: 1}, {LeftIdx: 2}}, "a\rb\r\nc")
assert.Equal(t, "a␍b\n", string(ret[0]))
assert.Equal(t, `c`, string(ret[1]))
})
t.Run("LongLineTruncated", func(t *testing.T) {
diffFile := &DiffFile{
Name: "a.c",
Sections: []*DiffSection{
{
Lines: []*DiffLine{{LeftIdx: 1, IsTruncated: true}},
},
},
}
ret := highlightCodeLinesForDiffFile(diffFile, true, []byte("// anything"))
ret := highlightLines("a.c", []*DiffLine{{LeftIdx: 1, IsTruncated: true}}, "// anything")
assert.Empty(t, ret)
})
}
+24 -41
View File
@@ -14,6 +14,26 @@ import (
)
func TestParseSubmoduleInfo(t *testing.T) {
const (
deletedGitmodules = `diff --git a/.gitmodules b/.gitmodules
index 0510edd..e69de29 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "gitea-mirror"]
- path = gitea
- url = https://gitea.com/gitea/gitea-mirror
`
deletedSubmodule = `diff --git a/gitea b/gitea
deleted file mode 160000
index c8ffe77..0000000
--- a/gitea
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit c8ffe777cf9c5bb47a38e3e0b3a3b5de6cd8813d
`
)
type testcase struct {
name string
gitdiff string
@@ -79,23 +99,8 @@ rename to gitea
`,
},
{
name: "deleted",
gitdiff: `diff --git a/.gitmodules b/.gitmodules
index 0510edd..e69de29 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "gitea-mirror"]
- path = gitea
- url = https://gitea.com/gitea/gitea-mirror
diff --git a/gitea b/gitea
deleted file mode 160000
index c8ffe77..0000000
--- a/gitea
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit c8ffe777cf9c5bb47a38e3e0b3a3b5de6cd8813d
`,
name: "deleted",
gitdiff: deletedGitmodules + deletedSubmodule,
infos: map[int]SubmoduleDiffInfo{
1: {
PreviousRefID: "c8ffe777cf9c5bb47a38e3e0b3a3b5de6cd8813d",
@@ -113,14 +118,7 @@ index 0510edd..bced3d8 100644
- path = gitea
+ path = gitea-1.22
url = https://gitea.com/gitea/gitea-mirror
diff --git a/gitea b/gitea
deleted file mode 160000
index c8ffe77..0000000
--- a/gitea
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit c8ffe777cf9c5bb47a38e3e0b3a3b5de6cd8813d
diff --git a/gitea-1.22 b/gitea-1.22
` + deletedSubmodule + `diff --git a/gitea-1.22 b/gitea-1.22
new file mode 160000
index 0000000..8eefa1f
--- /dev/null
@@ -139,22 +137,7 @@ index 0000000..8eefa1f
},
{
name: "converted to file",
gitdiff: `diff --git a/.gitmodules b/.gitmodules
index 0510edd..e69de29 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "gitea-mirror"]
- path = gitea
- url = https://gitea.com/gitea/gitea-mirror
diff --git a/gitea b/gitea
deleted file mode 160000
index c8ffe77..0000000
--- a/gitea
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit c8ffe777cf9c5bb47a38e3e0b3a3b5de6cd8813d
diff --git a/gitea b/gitea
gitdiff: deletedGitmodules + deletedSubmodule + `diff --git a/gitea b/gitea
new file mode 100644
index 0000000..33a9488
--- /dev/null
+37 -65
View File
@@ -186,73 +186,45 @@ func TestUpdateIssuesCommit_Issue5957(t *testing.T) {
}
func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
for _, message := range []string{
"close user2/repo1#1",
"close " + setting.AppURL + "user2/repo1/issues/1",
} {
t.Run(message, func(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Test that a push to default branch closes issue in another repo
// If the user also has push permissions to that repo
pushCommits := []*repository.PushCommit{
{
Sha1: "abcdef1",
CommitterEmail: "user2@example.com",
CommitterName: "User Two",
AuthorEmail: "user2@example.com",
AuthorName: "User Two",
Message: "close user2/repo1#1",
},
// Test that a push to default branch closes issue in another repo
// If the user also has push permissions to that repo
pushCommits := []*repository.PushCommit{
{
Sha1: "abcdef1",
CommitterEmail: "user2@example.com",
CommitterName: "User Two",
AuthorEmail: "user2@example.com",
AuthorName: "User Two",
Message: message,
},
}
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
commentBean := &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef1",
PosterID: user.ID,
IssueID: 1,
}
issueBean := &issues_model.Issue{RepoID: 1, Index: 1, ID: 1}
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
})
}
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
commentBean := &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef1",
PosterID: user.ID,
IssueID: 1,
}
issueBean := &issues_model.Issue{RepoID: 1, Index: 1, ID: 1}
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}
func TestUpdateIssuesCommit_AnotherRepo_FullAddress(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Test that a push to default branch closes issue in another repo
// If the user also has push permissions to that repo
pushCommits := []*repository.PushCommit{
{
Sha1: "abcdef1",
CommitterEmail: "user2@example.com",
CommitterName: "User Two",
AuthorEmail: "user2@example.com",
AuthorName: "User Two",
Message: "close " + setting.AppURL + "user2/repo1/issues/1",
},
}
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
commentBean := &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef1",
PosterID: user.ID,
IssueID: 1,
}
issueBean := &issues_model.Issue{RepoID: 1, Index: 1, ID: 1}
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}
func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) {
+4 -31
View File
@@ -36,15 +36,6 @@ func TestIssueAddReaction(t *testing.T) {
addReaction(t, user1, issue, nil, "heart")
unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue.ID})
}
func TestIssueAddDuplicateReaction(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
addReaction(t, user1, issue, nil, "heart")
reaction, err := CreateIssueReaction(t.Context(), user1, issue, "heart")
assert.Error(t, err)
@@ -52,17 +43,8 @@ func TestIssueAddDuplicateReaction(t *testing.T) {
existingR := unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue.ID})
assert.Equal(t, existingR.ID, reaction.ID)
}
func TestIssueDeleteReaction(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
addReaction(t, user1, issue, nil, "heart")
err := issues_model.DeleteIssueReaction(t.Context(), user1.ID, issue.ID, "heart")
err = issues_model.DeleteIssueReaction(t.Context(), user1.ID, issue.ID, "heart")
assert.NoError(t, err)
unittest.AssertNotExistsBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue.ID})
@@ -117,6 +99,9 @@ func TestIssueCommentAddReaction(t *testing.T) {
addReaction(t, user1, nil, comment, "heart")
unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: comment.IssueID, CommentID: comment.ID})
assert.NoError(t, issues_model.DeleteCommentReaction(t.Context(), user1.ID, comment.IssueID, comment.ID, "heart"))
unittest.AssertNotExistsBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: comment.IssueID, CommentID: comment.ID})
}
func TestIssueCommentDeleteReaction(t *testing.T) {
@@ -142,15 +127,3 @@ func TestIssueCommentDeleteReaction(t *testing.T) {
assert.Len(t, reactions["heart"], 3)
assert.Len(t, reactions["+1"], 1)
}
func TestIssueCommentReactionCount(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 1})
addReaction(t, user1, nil, comment, "heart")
assert.NoError(t, issues_model.DeleteCommentReaction(t.Context(), user1.ID, comment.IssueID, comment.ID, "heart"))
unittest.AssertNotExistsBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: comment.IssueID, CommentID: comment.ID})
}
+12 -20
View File
@@ -29,37 +29,34 @@ func TestAuthenticate(t *testing.T) {
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
getUserToken := func(op string, userID int64, repo *repo_model.Repository) string {
s, _ := GetLFSAuthTokenWithBearer(AuthTokenOptions{Op: op, UserID: userID, RepoID: repo.ID})
getUserToken := func(op string, userID int64, repo *repo_model.Repository, extDoerData string) string {
s, _ := GetLFSAuthTokenWithBearer(AuthTokenOptions{Op: op, UserID: userID, RepoID: repo.ID, UserExtDoerData: extDoerData})
_, token, _ := strings.Cut(s, " ")
return token
}
t.Run("handleLFSToken", func(t *testing.T) {
u, err := handleLFSToken(ctx, "", repo1, perm_model.AccessModeRead)
require.Error(t, err)
assert.Nil(t, u)
for _, token := range []string{"", "invalid"} {
u, err := handleLFSToken(ctx, token, repo1, perm_model.AccessModeRead)
require.Error(t, err)
assert.Nil(t, u)
}
u, err = handleLFSToken(ctx, "invalid", repo1, perm_model.AccessModeRead)
require.Error(t, err)
assert.Nil(t, u)
u, err = handleLFSToken(ctx, getUserToken("download", 2, repo1), repo1, perm_model.AccessModeRead)
u, err := handleLFSToken(ctx, getUserToken("download", 2, repo1, ""), repo1, perm_model.AccessModeRead)
require.NoError(t, err)
assert.EqualValues(t, 2, u.ID)
})
t.Run("authenticate", func(t *testing.T) {
const prefixBearer = "Bearer "
token := getUserToken("download", 2, repo1)
token := getUserToken("download", 2, repo1, "")
assert.False(t, authenticate(ctx, repo1, "", true, false))
assert.False(t, authenticate(ctx, repo1, prefixBearer+"invalid", true, false))
assert.True(t, authenticate(ctx, repo1, prefixBearer+token, true, false))
})
handleLFSTokenTestPerm := func(op string, userID int64, repo *repo_model.Repository, accessMode perm_model.AccessMode) error {
token := getUserToken(op, userID, repo)
u, err := handleLFSToken(ctx, token, repo, accessMode)
u, err := handleLFSToken(ctx, getUserToken(op, userID, repo, ""), repo, accessMode)
if err == nil {
assert.Equal(t, userID, u.ID)
}
@@ -108,17 +105,12 @@ func TestAuthenticate(t *testing.T) {
key, err := deploykey_model.AddDeployKeyToken(t.Context(), repo1.ID, "lfs", perm_model.AccessModeRead)
require.NoError(t, err)
doer := user_model.NewDeployKeyUserWithKeyID(key.ID)
getDoerToken := func(op string) string {
s, _ := GetLFSAuthTokenWithBearer(AuthTokenOptions{Op: op, UserID: doer.ID, UserExtDoerData: doer.ExtDoerData.EncodeToString(), RepoID: repo1.ID})
_, token, _ := strings.Cut(s, " ")
return token
}
u, err := handleLFSToken(ctx, getDoerToken("download"), repo1, perm_model.AccessModeRead)
u, err := handleLFSToken(ctx, getUserToken("download", doer.ID, repo1, doer.ExtDoerData.EncodeToString()), repo1, perm_model.AccessModeRead)
require.NoError(t, err)
assert.Equal(t, user_model.DeployKeyUserID, u.ID)
_, err = handleLFSToken(ctx, getDoerToken("upload"), repo1, perm_model.AccessModeWrite)
_, err = handleLFSToken(ctx, getUserToken("upload", doer.ID, repo1, doer.ExtDoerData.EncodeToString()), repo1, perm_model.AccessModeWrite)
assert.ErrorContains(t, err, "no permission to access the repository")
})
}
+27 -73
View File
@@ -395,103 +395,57 @@ func TestGenerateMessageIDForIssue(t *testing.T) {
_, _, pullIssue, _ := prepareMailerTest(t)
pullIssue.IsPull = true
type args struct {
for _, testCase := range []struct {
name string
issue *issues_model.Issue
comment *issues_model.Comment
actionType activities_model.ActionType
}
tests := []struct {
name string
args args
prefix string
prefix string
}{
{
name: "Open Issue",
args: args{
issue: issue,
actionType: activities_model.ActionCreateIssue,
},
prefix: fmt.Sprintf("<%s/issues/%d@%s>", issue.Repo.FullName(), issue.Index, setting.AppDomain),
"Open Issue", issue, nil, activities_model.ActionCreateIssue,
fmt.Sprintf("<%s/issues/%d@%s>", issue.Repo.FullName(), issue.Index, setting.AppDomain),
},
{
name: "Open Pull",
args: args{
issue: pullIssue,
actionType: activities_model.ActionCreatePullRequest,
},
prefix: fmt.Sprintf("<%s/pulls/%d@%s>", issue.Repo.FullName(), issue.Index, setting.AppDomain),
"Open Pull", pullIssue, nil, activities_model.ActionCreatePullRequest,
fmt.Sprintf("<%s/pulls/%d@%s>", issue.Repo.FullName(), issue.Index, setting.AppDomain),
},
{
name: "Comment Issue",
args: args{
issue: issue,
comment: comment,
actionType: activities_model.ActionCommentIssue,
},
prefix: fmt.Sprintf("<%s/issues/%d/comment/%d@%s>", issue.Repo.FullName(), issue.Index, comment.ID, setting.AppDomain),
"Comment Issue", issue, comment, activities_model.ActionCommentIssue,
fmt.Sprintf("<%s/issues/%d/comment/%d@%s>", issue.Repo.FullName(), issue.Index, comment.ID, setting.AppDomain),
},
{
name: "Comment Pull",
args: args{
issue: pullIssue,
comment: comment,
actionType: activities_model.ActionCommentPull,
},
prefix: fmt.Sprintf("<%s/pulls/%d/comment/%d@%s>", issue.Repo.FullName(), issue.Index, comment.ID, setting.AppDomain),
"Comment Pull", pullIssue, comment, activities_model.ActionCommentPull,
fmt.Sprintf("<%s/pulls/%d/comment/%d@%s>", issue.Repo.FullName(), issue.Index, comment.ID, setting.AppDomain),
},
{
name: "Close Issue",
args: args{
issue: issue,
actionType: activities_model.ActionCloseIssue,
},
prefix: fmt.Sprintf("<%s/issues/%d/close/", issue.Repo.FullName(), issue.Index),
"Close Issue", issue, nil, activities_model.ActionCloseIssue,
fmt.Sprintf("<%s/issues/%d/close/", issue.Repo.FullName(), issue.Index),
},
{
name: "Close Pull",
args: args{
issue: pullIssue,
actionType: activities_model.ActionClosePullRequest,
},
prefix: fmt.Sprintf("<%s/pulls/%d/close/", issue.Repo.FullName(), issue.Index),
"Close Pull", pullIssue, nil, activities_model.ActionClosePullRequest,
fmt.Sprintf("<%s/pulls/%d/close/", issue.Repo.FullName(), issue.Index),
},
{
name: "Reopen Issue",
args: args{
issue: issue,
actionType: activities_model.ActionReopenIssue,
},
prefix: fmt.Sprintf("<%s/issues/%d/reopen/", issue.Repo.FullName(), issue.Index),
"Reopen Issue", issue, nil, activities_model.ActionReopenIssue,
fmt.Sprintf("<%s/issues/%d/reopen/", issue.Repo.FullName(), issue.Index),
},
{
name: "Reopen Pull",
args: args{
issue: pullIssue,
actionType: activities_model.ActionReopenPullRequest,
},
prefix: fmt.Sprintf("<%s/pulls/%d/reopen/", issue.Repo.FullName(), issue.Index),
"Reopen Pull", pullIssue, nil, activities_model.ActionReopenPullRequest,
fmt.Sprintf("<%s/pulls/%d/reopen/", issue.Repo.FullName(), issue.Index),
},
{
name: "Merge Pull",
args: args{
issue: pullIssue,
actionType: activities_model.ActionMergePullRequest,
},
prefix: fmt.Sprintf("<%s/pulls/%d/merge/", issue.Repo.FullName(), issue.Index),
"Merge Pull", pullIssue, nil, activities_model.ActionMergePullRequest,
fmt.Sprintf("<%s/pulls/%d/merge/", issue.Repo.FullName(), issue.Index),
},
{
name: "Ready Pull",
args: args{
issue: pullIssue,
actionType: activities_model.ActionPullRequestReadyForReview,
},
prefix: fmt.Sprintf("<%s/pulls/%d/ready/", issue.Repo.FullName(), issue.Index),
"Ready Pull", pullIssue, nil, activities_model.ActionPullRequestReadyForReview,
fmt.Sprintf("<%s/pulls/%d/ready/", issue.Repo.FullName(), issue.Index),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := generateMessageIDForIssue(tt.args.issue, tt.args.comment, tt.args.actionType)
assert.True(t, strings.HasPrefix(got, tt.prefix), "%v, want %v", got, tt.prefix)
} {
t.Run(testCase.name, func(t *testing.T) {
got := generateMessageIDForIssue(testCase.issue, testCase.comment, testCase.actionType)
assert.True(t, strings.HasPrefix(got, testCase.prefix), "%v, want %v", got, testCase.prefix)
})
}
}
+51 -66
View File
@@ -160,44 +160,61 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) {
// call remapLocalUser
uploader.sameApp = true
externalID := int64(1234567)
externalName := "username"
source := base.Release{
PublisherID: externalID,
PublisherName: externalName,
for _, tc := range []struct {
source base.Release
expectedUserID int64
}{
//
// The externalID does not match any existing user, everything
// belongs to the doer
//
{base.Release{PublisherID: 1234567, PublisherName: "username"}, doer.ID},
//
// The externalID matches a known user but the name does not match,
// everything belongs to the doer
//
{base.Release{PublisherID: user.ID, PublisherName: "username"}, doer.ID},
//
// The externalID and externalName match an existing user, everything
// belongs to the existing user
//
{base.Release{PublisherID: user.ID, PublisherName: user.Name}, user.ID},
} {
target := repo_model.Release{}
uploader.userMap = make(map[int64]int64)
err := uploader.remapUser(ctx, &tc.source, &target)
assert.NoError(t, err)
assert.Equal(t, tc.expectedUserID, target.GetUserID())
}
//
// The externalID does not match any existing user, everything
// belongs to the doer
//
target := repo_model.Release{}
uploader.userMap = make(map[int64]int64)
err := uploader.remapUser(ctx, &source, &target)
assert.NoError(t, err)
assert.Equal(t, doer.ID, target.GetUserID())
t.Run("TimelineLabelAndMilestoneComments", func(t *testing.T) {
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1})
//
// The externalID matches a known user but the name does not match,
// everything belongs to the doer
//
source.PublisherID = user.ID
target = repo_model.Release{}
uploader.userMap = make(map[int64]int64)
err = uploader.remapUser(ctx, &source, &target)
assert.NoError(t, err)
assert.Equal(t, doer.ID, target.GetUserID())
uploader := NewGiteaLocalUploader(ctx, doer, doer.Name, "migrated")
uploader.issues[issue.Index] = issue
uploader.labels[label.Name] = label
uploader.milestones[milestone.Name] = milestone.ID
//
// The externalID and externalName match an existing user, everything
// belongs to the existing user
//
source.PublisherName = user.Name
target = repo_model.Release{}
uploader.userMap = make(map[int64]int64)
err = uploader.remapUser(ctx, &source, &target)
assert.NoError(t, err)
assert.Equal(t, user.ID, target.GetUserID())
require.NoError(t, uploader.CreateComments(ctx,
&base.Comment{IssueIndex: issue.Index, CommentType: "label", Content: "1", Meta: map[string]any{"LabelName": label.Name}},
&base.Comment{IssueIndex: issue.Index, CommentType: "label", Meta: map[string]any{"LabelName": "deleted-upstream"}},
&base.Comment{IssueIndex: issue.Index, CommentType: "milestone", Meta: map[string]any{"MilestoneTitle": milestone.Name}},
&base.Comment{IssueIndex: issue.Index, CommentType: "milestone", Meta: map[string]any{"MilestoneTitle": milestone.Name, "Removed": true}},
&base.Comment{IssueIndex: issue.Index, CommentType: "delete_branch", Content: "feature"},
))
unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: issue.ID, Type: issues_model.CommentTypeLabel, LabelID: label.ID, Content: "1"})
unittest.AssertCountByCond(t, "comment", builder.Eq{
"issue_id": issue.ID,
"type": issues_model.CommentTypeLabel,
"label_id": 0,
}, 0)
unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: issue.ID, Type: issues_model.CommentTypeMilestone, MilestoneID: milestone.ID})
unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: issue.ID, Type: issues_model.CommentTypeMilestone, OldMilestoneID: milestone.ID})
assert.Empty(t, unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: issue.ID, Type: issues_model.CommentTypeDeleteBranch, OldRef: "feature"}).Content)
})
}
func TestGiteaUploadRemapExternalUser(t *testing.T) {
@@ -332,35 +349,3 @@ func TestGiteaUploadForkPullRequestHeadInRepository(t *testing.T) {
require.NoError(t, err)
assert.Empty(t, strings.TrimSpace(remotes), "no remote is added for a local head")
}
func TestGiteaUploadTimelineLabelAndMilestoneComments(t *testing.T) {
unittest.PrepareTestEnv(t)
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1})
ctx := t.Context()
uploader := NewGiteaLocalUploader(ctx, doer, doer.Name, "migrated")
uploader.issues[issue.Index] = issue
uploader.labels[label.Name] = label
uploader.milestones[milestone.Name] = milestone.ID
require.NoError(t, uploader.CreateComments(ctx,
&base.Comment{IssueIndex: issue.Index, CommentType: "label", Content: "1", Meta: map[string]any{"LabelName": label.Name}},
&base.Comment{IssueIndex: issue.Index, CommentType: "label", Meta: map[string]any{"LabelName": "deleted-upstream"}},
&base.Comment{IssueIndex: issue.Index, CommentType: "milestone", Meta: map[string]any{"MilestoneTitle": milestone.Name}},
&base.Comment{IssueIndex: issue.Index, CommentType: "milestone", Meta: map[string]any{"MilestoneTitle": milestone.Name, "Removed": true}},
&base.Comment{IssueIndex: issue.Index, CommentType: "delete_branch", Content: "feature"},
))
unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: issue.ID, Type: issues_model.CommentTypeLabel, LabelID: label.ID, Content: "1"})
unittest.AssertCountByCond(t, "comment", builder.Eq{
"issue_id": issue.ID,
"type": issues_model.CommentTypeLabel,
"label_id": 0,
}, 0)
unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: issue.ID, Type: issues_model.CommentTypeMilestone, MilestoneID: milestone.ID})
unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: issue.ID, Type: issues_model.CommentTypeMilestone, OldMilestoneID: milestone.ID})
assert.Empty(t, unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: issue.ID, Type: issues_model.CommentTypeDeleteBranch, OldRef: "feature"}).Content)
}
+27 -60
View File
@@ -599,73 +599,40 @@ func TestNoteToComment(t *testing.T) {
downloader := &GitlabDownloader{}
now := time.Now()
makeTestNote := func(id int64, body string, system bool) gitlab.Note {
return gitlab.Note{
ID: id,
for _, testCase := range []struct {
id int64
body string
system bool
commentType string
meta map[string]any
}{
{1, "This is a regular comment", false, "", map[string]any{}},
{2, "enabled an automatic merge for abcd1234", true, "pull_scheduled_merge", map[string]any{}},
{3, "changed target branch from `master` to `main`", true, "change_target_branch", map[string]any{"OldRef": "master", "NewRef": "main"}},
{4, "canceled the automatic merge", true, "pull_cancel_scheduled_merge", map[string]any{}},
} {
note := gitlab.Note{
ID: testCase.id,
Author: gitlab.NoteAuthor{
ID: 72,
Email: "test@example.com",
Username: "test",
},
Body: body,
Body: testCase.body,
CreatedAt: &now,
System: system,
System: testCase.system,
}
}
notes := []gitlab.Note{
makeTestNote(1, "This is a regular comment", false),
makeTestNote(2, "enabled an automatic merge for abcd1234", true),
makeTestNote(3, "changed target branch from `master` to `main`", true),
makeTestNote(4, "canceled the automatic merge", true),
}
comments := []base.Comment{{
IssueIndex: 17,
Index: 1,
PosterID: 72,
PosterName: "test",
PosterEmail: "test@example.com",
CommentType: "",
Content: "This is a regular comment",
Created: now,
Meta: map[string]any{},
}, {
IssueIndex: 17,
Index: 2,
PosterID: 72,
PosterName: "test",
PosterEmail: "test@example.com",
CommentType: "pull_scheduled_merge",
Content: "enabled an automatic merge for abcd1234",
Created: now,
Meta: map[string]any{},
}, {
IssueIndex: 17,
Index: 3,
PosterID: 72,
PosterName: "test",
PosterEmail: "test@example.com",
CommentType: "change_target_branch",
Content: "changed target branch from `master` to `main`",
Created: now,
Meta: map[string]any{
"OldRef": "master",
"NewRef": "main",
},
}, {
IssueIndex: 17,
Index: 4,
PosterID: 72,
PosterName: "test",
PosterEmail: "test@example.com",
CommentType: "pull_cancel_scheduled_merge",
Content: "canceled the automatic merge",
Created: now,
Meta: map[string]any{},
}}
for i, note := range notes {
actualComment := *downloader.convertNoteToComment(17, &note)
assert.Equal(t, actualComment, comments[i])
assert.Equal(t, base.Comment{
IssueIndex: 17,
Index: testCase.id,
PosterID: 72,
PosterName: "test",
PosterEmail: "test@example.com",
CommentType: testCase.commentType,
Content: testCase.body,
Created: now,
Meta: testCase.meta,
}, *downloader.convertNoteToComment(17, &note))
}
}
@@ -1,43 +0,0 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package oauth2_provider
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestGrantAdditionalScopes(t *testing.T) {
tests := []struct {
grantScopes string
expectedScopes string
}{
{"", "all"}, // for old tokens without scope, treat it as "all"
{"openid profile email", "all"},
{"openid profile email groups", "all"},
{"openid profile email all", "all"},
{"openid profile email read:user all", "all"},
{"openid profile email groups read:user", "read:user"},
{"read:user read:repository", "read:repository,read:user"},
{"read:user write:issue public-only", "public-only,write:issue,read:user"},
{"openid profile email read:user", "read:user"},
{"no-token-scope", "no-token-scope"},
{"openid no-token-scope", "no-token-scope"},
{"no-token-scope read:user", "read:user"},
{"read:invalid_scope", "no-token-scope"},
{"read:invalid_scope,write:scope_invalid,just-plain-wrong", "no-token-scope"},
{"openid invalid:scope", "no-token-scope"},
{"openid ,,", "no-token-scope"},
{"read:user invalid:scope", "read:user"},
{"read:user,invalid:scope public-only", "public-only,read:user"},
}
for _, test := range tests {
t.Run("scope:"+test.grantScopes, func(t *testing.T) {
result := GrantAdditionalScopes(test.grantScopes)
assert.Equal(t, test.expectedScopes, string(result))
})
}
}
@@ -60,3 +60,36 @@ func TestECDSASigningKeyToJWK(t *testing.T) {
})
}
}
func TestGrantAdditionalScopes(t *testing.T) {
tests := []struct {
grantScopes string
expectedScopes string
}{
{"", "all"}, // for old tokens without scope, treat it as "all"
{"openid profile email", "all"},
{"openid profile email groups", "all"},
{"openid profile email all", "all"},
{"openid profile email read:user all", "all"},
{"openid profile email groups read:user", "read:user"},
{"read:user read:repository", "read:repository,read:user"},
{"read:user write:issue public-only", "public-only,write:issue,read:user"},
{"openid profile email read:user", "read:user"},
{"no-token-scope", "no-token-scope"},
{"openid no-token-scope", "no-token-scope"},
{"no-token-scope read:user", "read:user"},
{"read:invalid_scope", "no-token-scope"},
{"read:invalid_scope,write:scope_invalid,just-plain-wrong", "no-token-scope"},
{"openid invalid:scope", "no-token-scope"},
{"openid ,,", "no-token-scope"},
{"read:user invalid:scope", "read:user"},
{"read:user,invalid:scope public-only", "public-only,read:user"},
}
for _, test := range tests {
t.Run("scope:"+test.grantScopes, func(t *testing.T) {
result := GrantAdditionalScopes(test.grantScopes)
assert.Equal(t, test.expectedScopes, string(result))
})
}
}
+26 -30
View File
@@ -104,37 +104,33 @@ func TestNewTeam(t *testing.T) {
}
func TestUpdateTeam(t *testing.T) {
// successful update
assert.NoError(t, unittest.PrepareTestDatabase())
for _, name := range []string{
// successful update
"newName",
// update to already-existing team
"Owners",
} {
assert.NoError(t, unittest.PrepareTestDatabase())
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
team.LowerName = "newname"
team.Name = "newName"
team.Description = strings.Repeat("A long description!", 100)
team.AccessMode = perm.AccessModeAdmin
assert.NoError(t, UpdateTeam(t.Context(), team, true, false))
team = unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: "newName"})
assert.True(t, strings.HasPrefix(team.Description, "A long description!"))
access := unittest.AssertExistsAndLoadBean(t, &access_model.Access{UserID: 4, RepoID: 3})
assert.Equal(t, perm.AccessModeAdmin, access.Mode)
unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID})
}
func TestUpdateTeam2(t *testing.T) {
// update to already-existing team
assert.NoError(t, unittest.PrepareTestDatabase())
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
team.LowerName = "owners"
team.Name = "Owners"
team.Description = strings.Repeat("A long description!", 100)
err := UpdateTeam(t.Context(), team, true, false)
assert.True(t, organization.IsErrTeamAlreadyExist(err))
unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID})
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
team.LowerName = strings.ToLower(name)
team.Name = name
team.Description = strings.Repeat("A long description!", 100)
if name == "newName" {
team.AccessMode = perm.AccessModeAdmin
}
err := UpdateTeam(t.Context(), team, true, false)
if name == "newName" {
assert.NoError(t, err)
team = unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: "newName"})
assert.True(t, strings.HasPrefix(team.Description, "A long description!"))
access := unittest.AssertExistsAndLoadBean(t, &access_model.Access{UserID: 4, RepoID: 3})
assert.Equal(t, perm.AccessModeAdmin, access.Mode)
} else {
assert.True(t, organization.IsErrTeamAlreadyExist(err))
}
unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID})
}
}
func TestDeleteTeam(t *testing.T) {
+10 -15
View File
@@ -47,26 +47,21 @@ func TestUser_RemoveMember(t *testing.T) {
func TestRemoveOrgUser(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(org *organization.Organization, user *user_model.User) {
expectedNumMembers := org.NumMembers
if unittest.GetBean(t, &organization.OrgUser{OrgID: org.ID, UID: user.ID}) != nil {
expectedNumMembers--
}
assert.NoError(t, RemoveOrgUser(t.Context(), org, user))
unittest.AssertNotExistsBean(t, &organization.OrgUser{OrgID: org.ID, UID: user.ID})
org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: org.ID})
assert.Equal(t, expectedNumMembers, org.NumMembers)
}
org3 := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
org7 := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 7})
user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
testSuccess(org3, user4)
org3 = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
testSuccess(org3, user4)
for range 2 {
expectedNumMembers := org3.NumMembers
if unittest.GetBean(t, &organization.OrgUser{OrgID: org3.ID, UID: user4.ID}) != nil {
expectedNumMembers--
}
assert.NoError(t, RemoveOrgUser(t.Context(), org3, user4))
unittest.AssertNotExistsBean(t, &organization.OrgUser{OrgID: org3.ID, UID: user4.ID})
org3 = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: org3.ID})
assert.Equal(t, expectedNumMembers, org3.NumMembers)
}
err := RemoveOrgUser(t.Context(), org7, user5)
assert.Error(t, err)
+58 -118
View File
@@ -30,29 +30,19 @@ func Test_Projects(t *testing.T) {
user15 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15})
t.Run("User projects", func(t *testing.T) {
pi1 := project_model.ProjectIssue{
ProjectID: 4,
IssueID: 1,
ProjectColumnID: 4,
}
err := db.Insert(t.Context(), &pi1)
assert.NoError(t, err)
defer func() {
_, err = db.DeleteByID[project_model.ProjectIssue](t.Context(), pi1.ID)
for _, issueID := range []int64{1, 4} {
projectIssue := project_model.ProjectIssue{
ProjectID: 4,
IssueID: issueID,
ProjectColumnID: 4,
}
err := db.Insert(t.Context(), &projectIssue)
assert.NoError(t, err)
}()
pi2 := project_model.ProjectIssue{
ProjectID: 4,
IssueID: 4,
ProjectColumnID: 4,
defer func() {
_, err := db.DeleteByID[project_model.ProjectIssue](t.Context(), projectIssue.ID)
assert.NoError(t, err)
}()
}
err = db.Insert(t.Context(), &pi2)
assert.NoError(t, err)
defer func() {
_, err = db.DeleteByID[project_model.ProjectIssue](t.Context(), pi2.ID)
assert.NoError(t, err)
}()
projects, err := db.Find[project_model.Project](t.Context(), project_model.SearchOptions{
OwnerID: user2.ID,
@@ -61,34 +51,22 @@ func Test_Projects(t *testing.T) {
assert.Len(t, projects, 3)
assert.EqualValues(t, 4, projects[0].ID)
t.Run("Authenticated user", func(t *testing.T) {
columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{
Owner: user2,
Doer: user2,
for _, testCase := range []struct {
name string
options issues_model.IssuesOptions
issueCount int
}{
{"Authenticated user", issues_model.IssuesOptions{Owner: user2, Doer: user2}, 2}, // user2 can visit both issues, one from public repository one from private repository
{"Anonymous user", issues_model.IssuesOptions{AllPublic: true}, 1}, // anonymous user can only visit public repo issues
{"Authenticated user with no permission to the private repo", issues_model.IssuesOptions{Owner: user2, Doer: user4}, 1}, // user4 can only visit public repo issues
} {
t.Run(testCase.name, func(t *testing.T) {
columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &testCase.options)
assert.NoError(t, err)
assert.Len(t, columnIssues, 1) // 4 has 2 issues, 6 will not contains here because 0 issues
assert.Len(t, columnIssues[4], testCase.issueCount)
})
assert.NoError(t, err)
assert.Len(t, columnIssues, 1) // 4 has 2 issues, 6 will not contains here because 0 issues
assert.Len(t, columnIssues[4], 2) // user2 can visit both issues, one from public repository one from private repository
})
t.Run("Anonymous user", func(t *testing.T) {
columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{
AllPublic: true,
})
assert.NoError(t, err)
assert.Len(t, columnIssues, 1)
assert.Len(t, columnIssues[4], 1) // anonymous user can only visit public repo issues
})
t.Run("Authenticated user with no permission to the private repo", func(t *testing.T) {
columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{
Owner: user2,
Doer: user4,
})
assert.NoError(t, err)
assert.Len(t, columnIssues, 1)
assert.Len(t, columnIssues[4], 1) // user4 can only visit public repo issues
})
}
})
t.Run("Org projects", func(t *testing.T) {
@@ -126,48 +104,27 @@ func Test_Projects(t *testing.T) {
assert.Len(t, projects, 1)
assert.Equal(t, project1.ID, projects[0].ID)
t.Run("Authenticated user", func(t *testing.T) {
columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{
Owner: org3.AsUser(),
Doer: userAdmin,
})
assert.NoError(t, err)
assert.Len(t, columnIssues, 1) // default column has 2 issues
assert.Len(t, columnIssues[defaultColumn.ID], 2) // admin can visit both issues, one from public repository one from private repository
})
t.Run("Anonymous user", func(t *testing.T) {
columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{
AllPublic: true,
})
assert.NoError(t, err)
assert.Len(t, columnIssues, 1)
assert.Len(t, columnIssues[defaultColumn.ID], 1) // anonymous user can only visit public repo issues
})
t.Run("Authenticated user with no permission to the private repo", func(t *testing.T) {
for _, testCase := range []struct {
name string
options issues_model.IssuesOptions
issueCount int
}{
{"Authenticated user", issues_model.IssuesOptions{Owner: org3.AsUser(), Doer: userAdmin}, 2}, // admin can visit both issues, one from public repository one from private repository
{"Anonymous user", issues_model.IssuesOptions{AllPublic: true}, 1}, // anonymous user can only visit public repo issues
// user2 is on org3's Owners team and has owner access to the private repo3, so it is not a
// valid "no permission" subject; user15 has no access to repo3 but can see the public repo32.
columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{
Owner: org3.AsUser(),
Doer: user15,
})
assert.NoError(t, err)
assert.Len(t, columnIssues, 1)
assert.Len(t, columnIssues[defaultColumn.ID], 1) // user15 can only visit public repo issues
})
t.Run("Org owner team member", func(t *testing.T) {
{"Authenticated user with no permission to the private repo", issues_model.IssuesOptions{Owner: org3.AsUser(), Doer: user15}, 1}, // user15 can only visit public repo issues
// user2 is on org3's Owners team, so it has access to the private repo3 and must see both the
// public and the private issue — the owner-team access that team.authorize grants at runtime.
columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{
Owner: org3.AsUser(),
Doer: user2,
{"Org owner team member", issues_model.IssuesOptions{Owner: org3.AsUser(), Doer: user2}, 2}, // owner-team member visits both public and private issues
} {
t.Run(testCase.name, func(t *testing.T) {
columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &testCase.options)
assert.NoError(t, err)
assert.Len(t, columnIssues, 1) // default column has 2 issues
assert.Len(t, columnIssues[defaultColumn.ID], testCase.issueCount)
})
assert.NoError(t, err)
assert.Len(t, columnIssues, 1)
assert.Len(t, columnIssues[defaultColumn.ID], 2) // owner-team member visits both public and private issues
})
}
})
t.Run("Moving an issue in one project keeps its column in other projects", func(t *testing.T) {
@@ -219,39 +176,22 @@ func Test_Projects(t *testing.T) {
assert.Len(t, projects, 1)
assert.EqualValues(t, 1, projects[0].ID)
t.Run("Authenticated user", func(t *testing.T) {
columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{
RepoIDs: []int64{repo1.ID},
Doer: userAdmin,
for _, testCase := range []struct {
name string
options issues_model.IssuesOptions
}{
{"Authenticated user", issues_model.IssuesOptions{RepoIDs: []int64{repo1.ID}, Doer: userAdmin}},
{"Anonymous user", issues_model.IssuesOptions{AllPublic: true}},
{"Authenticated user with no permission to the private repo", issues_model.IssuesOptions{RepoIDs: []int64{repo1.ID}, Doer: user2}},
} {
t.Run(testCase.name, func(t *testing.T) {
columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &testCase.options)
assert.NoError(t, err)
assert.Len(t, columnIssues, 3)
assert.Len(t, columnIssues[1], 2)
assert.Len(t, columnIssues[2], 1)
assert.Len(t, columnIssues[3], 1)
})
assert.NoError(t, err)
assert.Len(t, columnIssues, 3)
assert.Len(t, columnIssues[1], 2)
assert.Len(t, columnIssues[2], 1)
assert.Len(t, columnIssues[3], 1)
})
t.Run("Anonymous user", func(t *testing.T) {
columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{
AllPublic: true,
})
assert.NoError(t, err)
assert.Len(t, columnIssues, 3)
assert.Len(t, columnIssues[1], 2)
assert.Len(t, columnIssues[2], 1)
assert.Len(t, columnIssues[3], 1)
})
t.Run("Authenticated user with no permission to the private repo", func(t *testing.T) {
columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{
RepoIDs: []int64{repo1.ID},
Doer: user2,
})
assert.NoError(t, err)
assert.Len(t, columnIssues, 3)
assert.Len(t, columnIssues[1], 2)
assert.Len(t, columnIssues[2], 1)
assert.Len(t, columnIssues[3], 1)
})
}
})
}
+2 -6
View File
@@ -206,20 +206,16 @@ func TestWorkflowExecution(t *testing.T) {
}
t.Run("ColumnChangedFromDefaultColumn", func(t *testing.T) {
setup(t, project_model.Workflow{WorkflowEvent: project_model.WorkflowEventItemColumnChanged, WorkflowFilters: project_model.WorkflowFilters{SourceColumnID: 1, TargetColumnID: 2}, WorkflowActions: addLabel})
addWorkflow(t, project_model.Workflow{WorkflowEvent: project_model.WorkflowEventItemColumnChanged, WorkflowFilters: project_model.WorkflowFilters{SourceColumnID: 1, TargetColumnID: 2}, WorkflowActions: addLabel})
moveIssue(t, t.Context(), 2, 2)
assert.True(t, hasLabel(t, 2))
})
t.Run("NoOpMoveWithinDefaultColumn", func(t *testing.T) {
t.Run("NoOpMoveWithinDefaultColumnAndNoCascadeFromWorkflows", func(t *testing.T) {
setup(t, project_model.Workflow{WorkflowEvent: project_model.WorkflowEventItemColumnChanged, WorkflowActions: addLabel})
moveIssue(t, t.Context(), 2, 1)
assert.False(t, hasLabel(t, 2))
unittest.AssertNotExistsBean(t, &issues_model.Comment{IssueID: 2, Type: issues_model.CommentTypeProjectColumn})
})
t.Run("NoCascadeFromWorkflows", func(t *testing.T) {
setup(t, project_model.Workflow{WorkflowEvent: project_model.WorkflowEventItemColumnChanged, WorkflowActions: addLabel})
moveIssue(t, issues_model.WithProjectWorkflow(t.Context(), project_model.WorkflowEventItemAddedToProject), 1, 2)
assert.False(t, hasLabel(t, 1))
})
+2 -7
View File
@@ -27,14 +27,9 @@ func TestMemoryBroker_HasNoTopicSubscribers(t *testing.T) {
_, cancel := b.Subscribe("topic")
cancel()
assert.False(t, b.HasTopicSubscribers("topic"))
}
// Backend-specific: MemoryBroker prunes empty topics from its internal map so
// idle-user entries don't accumulate.
func TestMemoryBroker_CancelDeletesEmptyTopic(t *testing.T) {
b := NewMemoryBroker()
_, cancel := b.Subscribe("topic")
cancel()
// Backend-specific: MemoryBroker prunes empty topics from its internal map so
// idle-user entries don't accumulate.
b.mu.RLock()
defer b.mu.RUnlock()
_, present := b.subs["topic"]
+43 -75
View File
@@ -17,58 +17,36 @@ import (
)
func Test_expandDefaultMergeMessage(t *testing.T) {
type args struct {
template string
vars map[string]string
}
tests := []struct {
name string
args args
want string
template string
wantBody string
}{
{
name: "single line",
args: args{
template: "Merge ${PullRequestTitle}",
vars: map[string]string{
"PullRequestTitle": "PullRequestTitle",
"PullRequestDescription": "Pull\nRequest\nDescription\n",
},
},
want: "Merge PullRequestTitle",
name: "single line",
template: "Merge ${PullRequestTitle}",
wantBody: "",
},
{
name: "multiple lines",
args: args{
template: "Merge ${PullRequestTitle}\nDescription:\n\n${PullRequestDescription}\n",
vars: map[string]string{
"PullRequestTitle": "PullRequestTitle",
"PullRequestDescription": "Pull\nRequest\nDescription\n",
},
},
want: "Merge PullRequestTitle",
name: "multiple lines",
template: "Merge ${PullRequestTitle}\nDescription:\n\n${PullRequestDescription}\n",
wantBody: "Description:\n\nPull\nRequest\nDescription\n",
},
{
name: "leading newlines",
args: args{
template: "\n\n\nMerge ${PullRequestTitle}\n\n\nDescription:\n\n${PullRequestDescription}\n",
vars: map[string]string{
"PullRequestTitle": "PullRequestTitle",
"PullRequestDescription": "Pull\nRequest\nDescription\n",
},
},
want: "Merge PullRequestTitle",
name: "leading newlines",
template: "\n\n\nMerge ${PullRequestTitle}\n\n\nDescription:\n\n${PullRequestDescription}\n",
wantBody: "Description:\n\nPull\nRequest\nDescription\n",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, got1 := expandDefaultMergeMessage(tt.args.template, tt.args.vars)
assert.Equalf(t, tt.want, got, "expandDefaultMergeMessage(%v, %v)", tt.args.template, tt.args.vars)
assert.Equalf(t, tt.wantBody, got1, "expandDefaultMergeMessage(%v, %v)", tt.args.template, tt.args.vars)
vars := map[string]string{
"PullRequestTitle": "PullRequestTitle",
"PullRequestDescription": "Pull\nRequest\nDescription\n",
}
got, got1 := expandDefaultMergeMessage(tt.template, vars)
assert.Equalf(t, "Merge PullRequestTitle", got, "expandDefaultMergeMessage(%v, %v)", tt.template, vars)
assert.Equalf(t, tt.wantBody, got1, "expandDefaultMergeMessage(%v, %v)", tt.template, vars)
})
}
}
@@ -99,47 +77,37 @@ func TestAddCommitMessageTailer(t *testing.T) {
}
func TestResolveMergeMessageTemplate(t *testing.T) {
t.Run("NoDefault", func(t *testing.T) {
repo, err := git.ForceFastImportWithInit(t.Context(), t.TempDir(), []git.FastImportCommit{
{Ref: "refs/heads/master", Files: []git.FastImportFile{
{Path: ".gitea/default_merge_message/REBASE_TEMPLATE.md", Content: "rebase template"},
}},
})
require.NoError(t, err)
gitRepo, err := git.OpenRepository(t.Context(), repo)
require.NoError(t, err)
defer gitRepo.Close()
for _, tt := range []struct {
name string
want string
}{
{"NoDefault", ""},
{"WithDefault", "default template"},
} {
t.Run(tt.name, func(t *testing.T) {
var files []git.FastImportFile
if tt.want != "" {
files = append(files, git.FastImportFile{Path: ".gitea/default_merge_message/DEFAULT_TEMPLATE.md", Content: tt.want})
}
files = append(files, git.FastImportFile{Path: ".gitea/default_merge_message/REBASE_TEMPLATE.md", Content: "rebase template"})
repo, err := git.ForceFastImportWithInit(t.Context(), t.TempDir(), []git.FastImportCommit{
{Ref: "refs/heads/master", Files: files},
})
require.NoError(t, err)
gitRepo, err := git.OpenRepository(t.Context(), repo)
require.NoError(t, err)
defer gitRepo.Close()
commit, err := gitRepo.GetBranchCommit(t.Context(), "master")
require.NoError(t, err)
tmpl, err := resolveMergeMessageTemplate(t.Context(), gitRepo, commit, "merge")
assert.NoError(t, err)
assert.Equal(t, "", tmpl)
tmpl, err = resolveMergeMessageTemplate(t.Context(), gitRepo, commit, "rebase")
assert.NoError(t, err)
assert.Equal(t, "rebase template", tmpl)
})
t.Run("WithDefault", func(t *testing.T) {
repo, err := git.ForceFastImportWithInit(t.Context(), t.TempDir(), []git.FastImportCommit{
{Ref: "refs/heads/master", Files: []git.FastImportFile{
{Path: ".gitea/default_merge_message/DEFAULT_TEMPLATE.md", Content: "default template"},
{Path: ".gitea/default_merge_message/REBASE_TEMPLATE.md", Content: "rebase template"},
}},
commit, err := gitRepo.GetBranchCommit(t.Context(), "master")
require.NoError(t, err)
tmpl, err := resolveMergeMessageTemplate(t.Context(), gitRepo, commit, "merge")
assert.NoError(t, err)
assert.Equal(t, tt.want, tmpl)
tmpl, err = resolveMergeMessageTemplate(t.Context(), gitRepo, commit, "rebase")
assert.NoError(t, err)
assert.Equal(t, "rebase template", tmpl)
})
require.NoError(t, err)
gitRepo, err := git.OpenRepository(t.Context(), repo)
require.NoError(t, err)
defer gitRepo.Close()
commit, err := gitRepo.GetBranchCommit(t.Context(), "master")
require.NoError(t, err)
tmpl, err := resolveMergeMessageTemplate(t.Context(), gitRepo, commit, "merge")
assert.NoError(t, err)
assert.Equal(t, "default template", tmpl)
tmpl, err = resolveMergeMessageTemplate(t.Context(), gitRepo, commit, "rebase")
assert.NoError(t, err)
assert.Equal(t, "rebase template", tmpl)
})
}
}
func TestMergeIntentWithMissingCommit(t *testing.T) {
+9 -15
View File
@@ -34,21 +34,15 @@ func TestDismissReview(t *testing.T) {
})
assert.NoError(t, err)
issue.IsClosed = true
pull.HasMerged = false
assert.NoError(t, issues_model.UpdateIssueCols(t.Context(), issue, "is_closed"))
assert.NoError(t, pull.UpdateCols(t.Context(), "has_merged"))
_, err = pull_service.DismissReview(t.Context(), review.ID, issue.RepoID, "", &user_model.User{}, false, false)
assert.Error(t, err)
assert.True(t, pull_service.IsErrDismissRequestOnClosedPR(err))
pull.HasMerged = true
pull.Issue.IsClosed = false
assert.NoError(t, issues_model.UpdateIssueCols(t.Context(), issue, "is_closed"))
assert.NoError(t, pull.UpdateCols(t.Context(), "has_merged"))
_, err = pull_service.DismissReview(t.Context(), review.ID, issue.RepoID, "", &user_model.User{}, false, false)
assert.Error(t, err)
assert.True(t, pull_service.IsErrDismissRequestOnClosedPR(err))
for _, hasMerged := range []bool{false, true} {
issue.IsClosed = !hasMerged
pull.HasMerged = hasMerged
assert.NoError(t, issues_model.UpdateIssueCols(t.Context(), issue, "is_closed"))
assert.NoError(t, pull.UpdateCols(t.Context(), "has_merged"))
_, err = pull_service.DismissReview(t.Context(), review.ID, issue.RepoID, "", &user_model.User{}, false, false)
assert.Error(t, err)
assert.True(t, pull_service.IsErrDismissRequestOnClosedPR(err))
}
}
func TestCreateCodeCommentContextOfUnchangedLine(t *testing.T) {
+2 -6
View File
@@ -54,17 +54,13 @@ func TestRepoGetReviewers(t *testing.T) {
reviewers, err = pull_service.GetReviewers(ctx, repo3, 2, 2)
assert.NoError(t, err)
assert.Len(t, reviewers, 1)
}
func TestRepoGetReviewerTeams(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
repo2 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
teams, err := pull_service.GetReviewerTeams(t.Context(), repo2)
assert.NoError(t, err)
assert.Empty(t, teams)
repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
repo3 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
teams, err = pull_service.GetReviewerTeams(t.Context(), repo3)
assert.NoError(t, err)
assert.Len(t, teams, 2)
+41 -57
View File
@@ -157,65 +157,49 @@ func TestIsUserAllowedToUpdate(t *testing.T) {
assert.False(t, rebaseAllowed)
})
t.Run("MaintainerEditInheritsPosterPermissions", func(t *testing.T) {
pr3 := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 3})
pr3.AllowMaintainerEdit = true
protectedBranch := &git_model.ProtectedBranch{
RepoID: pr3.HeadRepoID,
RuleName: pr3.HeadBranch,
CanPush: true,
CanForcePush: true,
}
_, err := db.GetEngine(t.Context()).Insert(protectedBranch)
require.NoError(t, err)
defer db.DeleteByBean(t.Context(), protectedBranch)
for _, testCase := range []struct {
name string
disableRebase bool
}{
{"MaintainerEditInheritsPosterPermissions", false},
{"MaintainerEditInheritsPosterPermissionsRebaseDisabled", true},
} {
t.Run(testCase.name, func(t *testing.T) {
pr3 := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 3})
pr3.AllowMaintainerEdit = true
protectedBranch := &git_model.ProtectedBranch{
RepoID: pr3.HeadRepoID,
RuleName: pr3.HeadBranch,
CanPush: true,
CanForcePush: true,
}
_, err := db.GetEngine(t.Context()).Insert(protectedBranch)
require.NoError(t, err)
defer db.DeleteByBean(t.Context(), protectedBranch)
collaboration := &repo_model.Collaboration{
RepoID: pr3.HeadRepoID,
UserID: pr3Poster.ID,
Mode: perm.AccessModeWrite,
}
require.NoError(t, db.Insert(t.Context(), collaboration))
defer db.DeleteByBean(t.Context(), collaboration)
collaboration := &repo_model.Collaboration{
RepoID: pr3.HeadRepoID,
UserID: pr3Poster.ID,
Mode: perm.AccessModeWrite,
}
require.NoError(t, db.Insert(t.Context(), collaboration))
defer db.DeleteByBean(t.Context(), collaboration)
require.NoError(t, pr3.LoadHeadRepo(t.Context()))
assert.NoError(t, access_model.RecalculateUserAccess(t.Context(), pr3.HeadRepo, pr3Poster.ID))
require.NoError(t, pr3.LoadHeadRepo(t.Context()))
assert.NoError(t, access_model.RecalculateUserAccess(t.Context(), pr3.HeadRepo, pr3Poster.ID))
pushAllowed, rebaseAllowed, _, err := checkUserAllowedToUpdate(t.Context(), pr3, pr3Poster)
assert.NoError(t, err)
assert.True(t, pushAllowed)
assert.True(t, rebaseAllowed)
})
if testCase.disableRebase {
setRepoAllowRebaseUpdate(t, pr3.BaseRepoID, false)
}
t.Run("MaintainerEditInheritsPosterPermissionsRebaseDisabled", func(t *testing.T) {
pr3 := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 3})
pr3.AllowMaintainerEdit = true
protectedBranch := &git_model.ProtectedBranch{
RepoID: pr3.HeadRepoID,
RuleName: pr3.HeadBranch,
CanPush: true,
CanForcePush: true,
}
_, err := db.GetEngine(t.Context()).Insert(protectedBranch)
require.NoError(t, err)
defer db.DeleteByBean(t.Context(), protectedBranch)
collaboration := &repo_model.Collaboration{
RepoID: pr3.HeadRepoID,
UserID: pr3Poster.ID,
Mode: perm.AccessModeWrite,
}
require.NoError(t, db.Insert(t.Context(), collaboration))
defer db.DeleteByBean(t.Context(), collaboration)
require.NoError(t, pr3.LoadHeadRepo(t.Context()))
assert.NoError(t, access_model.RecalculateUserAccess(t.Context(), pr3.HeadRepo, pr3Poster.ID))
setRepoAllowRebaseUpdate(t, pr3.BaseRepoID, false)
pushAllowed, rebaseAllowed, _, err := checkUserAllowedToUpdate(t.Context(), pr3, pr3Poster)
assert.NoError(t, err)
assert.True(t, pushAllowed)
assert.False(t, rebaseAllowed)
})
pushAllowed, rebaseAllowed, _, err := checkUserAllowedToUpdate(t.Context(), pr3, pr3Poster)
assert.NoError(t, err)
assert.True(t, pushAllowed)
if testCase.disableRebase {
assert.False(t, rebaseAllowed)
} else {
assert.True(t, rebaseAllowed)
}
})
}
}
+68 -138
View File
@@ -39,75 +39,30 @@ func TestRelease_Create(t *testing.T) {
assert.NoError(t, err)
defer gitRepo.Close()
assert.NoError(t, CreateRelease(t.Context(), gitRepo, &repo_model.Release{
RepoID: repo.ID,
Repo: repo,
PublisherID: user.ID,
Publisher: user,
TagName: "v0.1",
Target: "master",
Title: "v0.1 is released",
Note: "v0.1 is released",
IsDraft: false,
IsPrerelease: false,
IsTag: false,
}, nil, ""))
assert.NoError(t, CreateRelease(t.Context(), gitRepo, &repo_model.Release{
RepoID: repo.ID,
Repo: repo,
PublisherID: user.ID,
Publisher: user,
TagName: "v0.1.1",
Target: "65f1bf27bc3bf70f64657658635e66094edbcb4d",
Title: "v0.1.1 is released",
Note: "v0.1.1 is released",
IsDraft: false,
IsPrerelease: false,
IsTag: false,
}, nil, ""))
assert.NoError(t, CreateRelease(t.Context(), gitRepo, &repo_model.Release{
RepoID: repo.ID,
Repo: repo,
PublisherID: user.ID,
Publisher: user,
TagName: "v0.1.2",
Target: "65f1bf2",
Title: "v0.1.2 is released",
Note: "v0.1.2 is released",
IsDraft: false,
IsPrerelease: false,
IsTag: false,
}, nil, ""))
assert.NoError(t, CreateRelease(t.Context(), gitRepo, &repo_model.Release{
RepoID: repo.ID,
Repo: repo,
PublisherID: user.ID,
Publisher: user,
TagName: "v0.1.3",
Target: "65f1bf2",
Title: "v0.1.3 is released",
Note: "v0.1.3 is released",
IsDraft: true,
IsPrerelease: false,
IsTag: false,
}, nil, ""))
assert.NoError(t, CreateRelease(t.Context(), gitRepo, &repo_model.Release{
RepoID: repo.ID,
Repo: repo,
PublisherID: user.ID,
Publisher: user,
TagName: "v0.1.4",
Target: "65f1bf2",
Title: "v0.1.4 is released",
Note: "v0.1.4 is released",
IsDraft: false,
IsPrerelease: true,
IsTag: false,
}, nil, ""))
for _, testCase := range []struct {
tagName, target string
isDraft, isPrerelease bool
}{
{"v0.1", "master", false, false},
{"v0.1.1", "65f1bf27bc3bf70f64657658635e66094edbcb4d", false, false},
{"v0.1.2", "65f1bf2", false, false},
{"v0.1.3", "65f1bf2", true, false},
{"v0.1.4", "65f1bf2", false, true},
} {
assert.NoError(t, CreateRelease(t.Context(), gitRepo, &repo_model.Release{
RepoID: repo.ID,
Repo: repo,
PublisherID: user.ID,
Publisher: user,
TagName: testCase.tagName,
Target: testCase.target,
Title: testCase.tagName + " is released",
Note: testCase.tagName + " is released",
IsDraft: testCase.isDraft,
IsPrerelease: testCase.isPrerelease,
IsTag: false,
}, nil, ""))
}
testPlayload := "testtest"
@@ -328,76 +283,51 @@ func TestRelease_createTag(t *testing.T) {
defer timeutil.MockSet(fakeNow)()
advance := func() { fakeNow = fakeNow.Add(time.Second); timeutil.MockSet(fakeNow) }
// Test a changed release
release := &repo_model.Release{
RepoID: repo.ID,
Repo: repo,
PublisherID: user.ID,
Publisher: user,
TagName: "v2.1.1",
Target: "master",
Title: "v2.1.1 is released",
Note: "v2.1.1 is released",
IsDraft: false,
IsPrerelease: false,
IsTag: false,
for _, testCase := range []struct {
tagName, target, state string
isDraft, isPrerelease bool
}{
// Test a changed release
{"v2.1.1", "master", "released", false, false},
// Test a changed draft
{"v2.2.1", "65f1bf2", "draft", true, false},
// Test a changed pre-release
{"v2.3.1", "65f1bf2", "pre-released", false, true},
} {
release := &repo_model.Release{
RepoID: repo.ID,
Repo: repo,
PublisherID: user.ID,
Publisher: user,
TagName: testCase.tagName,
Target: testCase.target,
Title: testCase.tagName + " is " + testCase.state,
Note: testCase.tagName + " is " + testCase.state,
IsDraft: testCase.isDraft,
IsPrerelease: testCase.isPrerelease,
IsTag: false,
}
_, err = createTag(t.Context(), gitRepo, release, "")
assert.NoError(t, err)
if !testCase.isDraft && !testCase.isPrerelease {
assert.NotEmpty(t, release.CreatedUnix)
}
releaseCreatedUnix := release.CreatedUnix
advance()
if testCase.isDraft || testCase.isPrerelease {
release.Title = "Changed title"
}
if !testCase.isDraft {
release.Note = "Changed note"
}
_, err = createTag(t.Context(), gitRepo, release, "")
assert.NoError(t, err)
if testCase.isDraft {
assert.Less(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
} else {
assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
}
}
_, err = createTag(t.Context(), gitRepo, release, "")
assert.NoError(t, err)
assert.NotEmpty(t, release.CreatedUnix)
releaseCreatedUnix := release.CreatedUnix
advance()
release.Note = "Changed note"
_, err = createTag(t.Context(), gitRepo, release, "")
assert.NoError(t, err)
assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
// Test a changed draft
release = &repo_model.Release{
RepoID: repo.ID,
Repo: repo,
PublisherID: user.ID,
Publisher: user,
TagName: "v2.2.1",
Target: "65f1bf2",
Title: "v2.2.1 is draft",
Note: "v2.2.1 is draft",
IsDraft: true,
IsPrerelease: false,
IsTag: false,
}
_, err = createTag(t.Context(), gitRepo, release, "")
assert.NoError(t, err)
releaseCreatedUnix = release.CreatedUnix
advance()
release.Title = "Changed title"
_, err = createTag(t.Context(), gitRepo, release, "")
assert.NoError(t, err)
assert.Less(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
// Test a changed pre-release
release = &repo_model.Release{
RepoID: repo.ID,
Repo: repo,
PublisherID: user.ID,
Publisher: user,
TagName: "v2.3.1",
Target: "65f1bf2",
Title: "v2.3.1 is pre-released",
Note: "v2.3.1 is pre-released",
IsDraft: false,
IsPrerelease: true,
IsTag: false,
}
_, err = createTag(t.Context(), gitRepo, release, "")
assert.NoError(t, err)
releaseCreatedUnix = release.CreatedUnix
advance()
release.Title = "Changed title"
release.Note = "Changed note"
_, err = createTag(t.Context(), gitRepo, release, "")
assert.NoError(t, err)
assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
}
func TestCreateNewTag(t *testing.T) {
+7 -11
View File
@@ -76,17 +76,13 @@ func TestListUnadoptedRepositories_ListOptions(t *testing.T) {
_ = os.Mkdir(filepath.Join(setting.RepoRootPath, unadopted+".git"), 0o755)
}
opts := db.ListOptions{Page: 1, PageSize: 1}
repoNames, count, err := ListUnadoptedRepositories(t.Context(), "", &opts)
assert.NoError(t, err)
assert.EqualValues(t, 2, count)
assert.Equal(t, unadoptedList[0], repoNames[0])
opts = db.ListOptions{Page: 2, PageSize: 1}
repoNames, count, err = ListUnadoptedRepositories(t.Context(), "", &opts)
assert.NoError(t, err)
assert.EqualValues(t, 2, count)
assert.Equal(t, unadoptedList[1], repoNames[0])
for i, unadopted := range unadoptedList {
opts := db.ListOptions{Page: i + 1, PageSize: 1}
repoNames, count, err := ListUnadoptedRepositories(t.Context(), "", &opts)
assert.NoError(t, err)
assert.EqualValues(t, 2, count)
assert.Equal(t, unadopted, repoNames[0])
}
}
func TestAdoptRepository(t *testing.T) {
+27 -40
View File
@@ -17,48 +17,35 @@ import (
)
func TestUploadAvatar(t *testing.T) {
// Generate image
myImage := image.NewRGBA(image.Rect(0, 0, 1, 1))
var buff bytes.Buffer
png.Encode(&buff, myImage)
for _, testCase := range []struct {
width int
deleteAvatar bool
}{
{1, false},
{5000, false},
{1, true},
} {
// Generate image
var buff bytes.Buffer
png.Encode(&buff, image.NewRGBA(image.Rect(0, 0, testCase.width, 1)))
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
err := UploadAvatar(t.Context(), repo, buff.Bytes())
assert.NoError(t, err)
assert.Equal(t, avatar.HashAvatar(10, buff.Bytes()), repo.Avatar)
}
func TestUploadBigAvatar(t *testing.T) {
// Generate BIG image
myImage := image.NewRGBA(image.Rect(0, 0, 5000, 1))
var buff bytes.Buffer
png.Encode(&buff, myImage)
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
err := UploadAvatar(t.Context(), repo, buff.Bytes())
assert.Error(t, err)
}
func TestDeleteAvatar(t *testing.T) {
// Generate image
myImage := image.NewRGBA(image.Rect(0, 0, 1, 1))
var buff bytes.Buffer
png.Encode(&buff, myImage)
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
err := UploadAvatar(t.Context(), repo, buff.Bytes())
assert.NoError(t, err)
err = DeleteAvatar(t.Context(), repo)
assert.NoError(t, err)
assert.Empty(t, repo.Avatar)
err := UploadAvatar(t.Context(), repo, buff.Bytes())
if testCase.width == 5000 {
assert.Error(t, err)
continue
}
assert.NoError(t, err)
if testCase.deleteAvatar {
err = DeleteAvatar(t.Context(), repo)
assert.NoError(t, err)
assert.Empty(t, repo.Avatar)
} else {
assert.Equal(t, avatar.HashAvatar(10, buff.Bytes()), repo.Avatar)
}
}
}
func TestGenerateAvatar(t *testing.T) {
+7 -11
View File
@@ -24,14 +24,11 @@ func TestRepository_AddCollaborator(t *testing.T) {
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
testSuccess := func(repo *repo_model.Repository, user *user_model.User) {
for _, repo := range []*repo_model.Repository{repo1, repo1, repo3} {
assert.NoError(t, repo.LoadOwner(t.Context()))
assert.NoError(t, AddOrUpdateCollaborator(t.Context(), repo, user, perm.AccessModeWrite))
unittest.CheckConsistencyFor(t, repo, user)
assert.NoError(t, AddOrUpdateCollaborator(t.Context(), repo, user4, perm.AccessModeWrite))
unittest.CheckConsistencyFor(t, repo, user4)
}
testSuccess(repo1, user4)
testSuccess(repo1, user4)
testSuccess(repo3, user4)
assert.Error(t, AddOrUpdateCollaborator(t.Context(), repo1, user4, perm.AccessModeOwner))
assert.NoError(t, AddOrUpdateCollaborator(t.Context(), repo1, user4, perm.AccessModeAdmin))
@@ -44,11 +41,10 @@ func TestRepository_DeleteCollaboration(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 22})
assert.NoError(t, repo.LoadOwner(t.Context()))
assert.NoError(t, DeleteCollaboration(t.Context(), repo, user))
unittest.AssertNotExistsBean(t, &repo_model.Collaboration{RepoID: repo.ID, UserID: user.ID})
assert.NoError(t, DeleteCollaboration(t.Context(), repo, user))
unittest.AssertNotExistsBean(t, &repo_model.Collaboration{RepoID: repo.ID, UserID: user.ID})
for range 2 {
assert.NoError(t, DeleteCollaboration(t.Context(), repo, user))
unittest.AssertNotExistsBean(t, &repo_model.Collaboration{RepoID: repo.ID, UserID: user.ID})
}
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repo.ID})
}
-4
View File
@@ -34,10 +34,6 @@ func TestTeam_HasRepository(t *testing.T) {
test(2, 3, true)
test(2, 5, false)
}
func TestTeam_RemoveRepository(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(teamID, repoID int64) {
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
+31 -37
View File
@@ -31,24 +31,21 @@ func TestGetDiffPreview(t *testing.T) {
content := "# repo1\n\nDescription for repo1\nthis is a new line"
t.Run("Errors", func(t *testing.T) {
t.Run("empty repo", func(t *testing.T) {
diff, err := GetDiffPreview(ctx, &repo_model.Repository{}, branch, treePath, oldContent, content)
assert.Nil(t, diff)
assert.EqualError(t, err, "repository does not exist [id: 0, uid: 0, owner_name: , name: ]")
})
t.Run("bad branch", func(t *testing.T) {
badBranch := "bad_branch"
diff, err := GetDiffPreview(ctx, ctx.Repo.Repository, badBranch, treePath, oldContent, content)
assert.Nil(t, diff)
assert.EqualError(t, err, "branch does not exist [name: "+badBranch+"]")
})
t.Run("empty treePath", func(t *testing.T) {
diff, err := GetDiffPreview(ctx, ctx.Repo.Repository, branch, "", oldContent, content)
assert.Nil(t, diff)
assert.EqualError(t, err, "path is invalid [path: ]")
})
for _, test := range []struct {
name string
repo *repo_model.Repository
branch, treePath, expectedError string
}{
{"empty repo", &repo_model.Repository{}, branch, treePath, "repository does not exist [id: 0, uid: 0, owner_name: , name: ]"},
{"bad branch", ctx.Repo.Repository, "bad_branch", treePath, "branch does not exist [name: bad_branch]"},
{"empty treePath", ctx.Repo.Repository, branch, "", "path is invalid [path: ]"},
} {
t.Run(test.name, func(t *testing.T) {
diff, err := GetDiffPreview(ctx, test.repo, test.branch, test.treePath, oldContent, content)
assert.Nil(t, diff)
assert.EqualError(t, err, test.expectedError)
})
}
})
expectedDiff := &gitdiff.Diff{
@@ -133,23 +130,20 @@ func TestGetDiffPreview(t *testing.T) {
IsIncomplete: false,
}
t.Run("with given branch", func(t *testing.T) {
diff, err := GetDiffPreview(ctx, ctx.Repo.Repository, branch, treePath, oldContent, content)
assert.NoError(t, err)
expectedBs, err := json.Marshal(expectedDiff)
assert.NoError(t, err)
bs, err := json.Marshal(diff)
assert.NoError(t, err)
assert.JSONEq(t, string(expectedBs), string(bs))
})
t.Run("empty branch, same results", func(t *testing.T) {
diff, err := GetDiffPreview(ctx, ctx.Repo.Repository, "", treePath, oldContent, content)
assert.NoError(t, err)
expectedBs, err := json.Marshal(expectedDiff)
assert.NoError(t, err)
bs, err := json.Marshal(diff)
assert.NoError(t, err)
assert.JSONEq(t, string(expectedBs), string(bs))
})
for _, test := range []struct {
name, branch string
}{
{"with given branch", branch},
{"empty branch, same results", ""},
} {
t.Run(test.name, func(t *testing.T) {
diff, err := GetDiffPreview(ctx, ctx.Repo.Repository, test.branch, treePath, oldContent, content)
assert.NoError(t, err)
expectedBs, err := json.Marshal(expectedDiff)
assert.NoError(t, err)
bs, err := json.Marshal(diff)
assert.NoError(t, err)
assert.JSONEq(t, string(expectedBs), string(bs))
})
}
}
+10 -24
View File
@@ -78,7 +78,7 @@ func TestGetTreeViewNodes(t *testing.T) {
}
treeNodes, err := GetTreeViewNodes(ctx, curRepoLink, renderedIconPool, ctx.Repo.GitRepo, ctx.Repo.Commit, "", "")
assert.NoError(t, err)
assert.Equal(t, []*TreeViewNode{
expectedNodes := []*TreeViewNode{
{
EntryName: "docs",
EntryMode: "tree",
@@ -86,36 +86,22 @@ func TestGetTreeViewNodes(t *testing.T) {
EntryIcon: mockIconForFolder(),
EntryIconOpen: mockOpenIconForFolder(),
},
}, treeNodes)
}
assert.Equal(t, expectedNodes, treeNodes)
treeNodes, err = GetTreeViewNodes(ctx, curRepoLink, renderedIconPool, ctx.Repo.GitRepo, ctx.Repo.Commit, "", "docs/README.md")
assert.NoError(t, err)
assert.Equal(t, []*TreeViewNode{
{
EntryName: "docs",
EntryMode: "tree",
FullPath: "docs",
EntryIcon: mockIconForFolder(),
EntryIconOpen: mockOpenIconForFolder(),
Children: []*TreeViewNode{
{
EntryName: "README.md",
EntryMode: "blob",
FullPath: "docs/README.md",
EntryIcon: mockIconForFile(`svg-mfi-readme`),
},
},
},
}, treeNodes)
treeNodes, err = GetTreeViewNodes(ctx, curRepoLink, renderedIconPool, ctx.Repo.GitRepo, ctx.Repo.Commit, "docs", "README.md")
assert.NoError(t, err)
assert.Equal(t, []*TreeViewNode{
expectedNodes[0].Children = []*TreeViewNode{
{
EntryName: "README.md",
EntryMode: "blob",
FullPath: "docs/README.md",
EntryIcon: mockIconForFile(`svg-mfi-readme`),
},
}, treeNodes)
}
assert.Equal(t, expectedNodes, treeNodes)
treeNodes, err = GetTreeViewNodes(ctx, curRepoLink, renderedIconPool, ctx.Repo.GitRepo, ctx.Repo.Commit, "docs", "README.md")
assert.NoError(t, err)
assert.Equal(t, expectedNodes[0].Children, treeNodes)
}
+16 -40
View File
@@ -114,22 +114,25 @@ func TestReleaseUnusedColors(t *testing.T) {
parser.firstAvailable = testcase.firstAvailable
parser.firstInUse = testcase.firstInUse
parser.releaseUnusedColors()
reportColorError := func(format string, color int) {
t.Errorf(format,
testcase.availableColors,
testcase.oldColors,
testcase.firstAvailable,
testcase.firstInUse,
parser.availableColors,
parser.oldColors,
parser.firstAvailable,
parser.firstInUse,
color)
}
if parser.firstAvailable == -1 {
// All in use
for _, color := range parser.availableColors {
found := slices.Contains(parser.oldColors, color)
if !found {
t.Errorf("In testcase:\n%d\t%d\t%d %d =>\n%d\t%d\t%d %d: %d should be available but is not",
testcase.availableColors,
testcase.oldColors,
testcase.firstAvailable,
testcase.firstInUse,
parser.availableColors,
parser.oldColors,
parser.firstAvailable,
parser.firstInUse,
color)
reportColorError("In testcase:\n%d\t%d\t%d %d =>\n%d\t%d\t%d %d: %d should be available but is not", color)
}
}
} else if parser.firstInUse != -1 {
@@ -138,48 +141,21 @@ func TestReleaseUnusedColors(t *testing.T) {
color := parser.availableColors[i]
found := slices.Contains(parser.oldColors, color)
if !found {
t.Errorf("In testcase:\n%d\t%d\t%d %d =>\n%d\t%d\t%d %d: %d should be available but is not",
testcase.availableColors,
testcase.oldColors,
testcase.firstAvailable,
testcase.firstInUse,
parser.availableColors,
parser.oldColors,
parser.firstAvailable,
parser.firstInUse,
color)
reportColorError("In testcase:\n%d\t%d\t%d %d =>\n%d\t%d\t%d %d: %d should be available but is not", color)
}
}
for i := parser.firstAvailable; i != parser.firstInUse; i = (i + 1) % len(parser.availableColors) {
color := parser.availableColors[i]
found := slices.Contains(parser.oldColors, color)
if found {
t.Errorf("In testcase:\n%d\t%d\t%d %d =>\n%d\t%d\t%d %d: %d should not be available but is",
testcase.availableColors,
testcase.oldColors,
testcase.firstAvailable,
testcase.firstInUse,
parser.availableColors,
parser.oldColors,
parser.firstAvailable,
parser.firstInUse,
color)
reportColorError("In testcase:\n%d\t%d\t%d %d =>\n%d\t%d\t%d %d: %d should not be available but is", color)
}
}
} else {
// None in use
for _, color := range parser.oldColors {
if color != 0 {
t.Errorf("In testcase:\n%d\t%d\t%d %d =>\n%d\t%d\t%d %d: %d should not be available but is",
testcase.availableColors,
testcase.oldColors,
testcase.firstAvailable,
testcase.firstInUse,
parser.availableColors,
parser.oldColors,
parser.firstAvailable,
parser.firstInUse,
color)
reportColorError("In testcase:\n%d\t%d\t%d %d =>\n%d\t%d\t%d %d: %d should not be available but is", color)
}
}
}
+21 -40
View File
@@ -107,49 +107,37 @@ func Test_resolveLicenses(t *testing.T) {
require.NoError(t, err)
defer gitRepo.Close()
// 1. repo with no license at all
require.NoError(t, git.ForceFastImport(t.Context(), gitRepo, []git.FastImportCommit{{
Ref: "refs/heads/master",
Message: "empty",
}}))
commit, err := gitRepo.GetBranchCommit(t.Context(), "master")
require.NoError(t, err)
resolve := func(message string, files ...git.FastImportFile) ([]repo_model.DetectedLicense, error) {
require.NoError(t, git.ForceFastImport(t.Context(), gitRepo, []git.FastImportCommit{{
Ref: "refs/heads/master",
Message: message,
Files: files,
}}))
commit, err := gitRepo.GetBranchCommit(t.Context(), "master")
require.NoError(t, err)
return resolveLicenses(t.Context(), gitRepo, commit)
}
licenses, err := resolveLicenses(t.Context(), gitRepo, commit)
// 1. repo with no license at all
licenses, err := resolve("empty")
assert.Empty(t, licenses)
assert.NoError(t, err)
// 2. repo with a plain LICENSE file — classifier should detect MIT
require.NoError(t, git.ForceFastImport(t.Context(), gitRepo, []git.FastImportCommit{{
Ref: "refs/heads/master",
Message: "add LICENSE",
Files: []git.FastImportFile{
{Mode: git.EntryModeBlob, Path: "LICENSE", Content: string(mitLicense)},
},
}}))
commit, err = gitRepo.GetBranchCommit(t.Context(), "master")
require.NoError(t, err)
licenses, err = resolveLicenses(t.Context(), gitRepo, commit)
licenses, err = resolve("add LICENSE",
git.FastImportFile{Mode: git.EntryModeBlob, Path: "LICENSE", Content: string(mitLicense)},
)
assert.NoError(t, err)
assert.Len(t, licenses, 1)
assert.Equal(t, "MIT", licenses[0].SPDXID)
assert.Equal(t, "LICENSE", licenses[0].LicensePath)
// 3. repo with REUSE LICENSES/ dir — should take priority over root LICENSE
require.NoError(t, git.ForceFastImport(t.Context(), gitRepo, []git.FastImportCommit{{
Ref: "refs/heads/master",
Message: "add LICENSES dir",
Files: []git.FastImportFile{
{Mode: git.EntryModeBlob, Path: "LICENSE", Content: string(mitLicense)},
{Mode: git.EntryModeBlob, Path: "LICENSES/MIT.txt", Content: "MIT license text"},
{Mode: git.EntryModeBlob, Path: "LICENSES/Apache-2.0.txt", Content: "Apache license text"},
},
}}))
commit, err = gitRepo.GetBranchCommit(t.Context(), "master")
require.NoError(t, err)
licenses, err = resolveLicenses(t.Context(), gitRepo, commit)
licenses, err = resolve("add LICENSES dir",
git.FastImportFile{Mode: git.EntryModeBlob, Path: "LICENSE", Content: string(mitLicense)},
git.FastImportFile{Mode: git.EntryModeBlob, Path: "LICENSES/MIT.txt", Content: "MIT license text"},
git.FastImportFile{Mode: git.EntryModeBlob, Path: "LICENSES/Apache-2.0.txt", Content: "Apache license text"},
)
assert.NoError(t, err)
assert.Len(t, licenses, 2)
@@ -161,14 +149,7 @@ func Test_resolveLicenses(t *testing.T) {
}
// 4. remove all licenses — should return not exist
require.NoError(t, git.ForceFastImport(t.Context(), gitRepo, []git.FastImportCommit{{
Ref: "refs/heads/master",
Message: "remove licenses",
}}))
commit, err = gitRepo.GetBranchCommit(t.Context(), "master")
require.NoError(t, err)
licenses, err = resolveLicenses(t.Context(), gitRepo, commit)
licenses, err = resolve("remove licenses")
assert.Empty(t, licenses)
assert.NoError(t, err)
}
+24 -36
View File
@@ -71,45 +71,33 @@ func TestRepository_HasWiki(t *testing.T) {
}
func TestMakeRepoPrivateClearsWatches(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
for _, name := range []string{"MakeRepoPrivate", "updateRepository"} {
t.Run(name, func(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
assert.False(t, repo.IsPrivate)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
assert.False(t, repo.IsPrivate)
watchers, err := repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1})
require.NoError(t, err)
require.NotEmpty(t, watchers)
watchers, err := repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1})
require.NoError(t, err)
require.NotEmpty(t, watchers)
assert.NoError(t, MakeRepoPrivate(t.Context(), repo, true))
if name == "MakeRepoPrivate" {
assert.NoError(t, MakeRepoPrivate(t.Context(), repo, true))
} else {
repo.IsPrivate = true
require.NoError(t, updateRepository(t.Context(), repo, true))
}
watchers, err = repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Empty(t, watchers)
watchers, err = repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Empty(t, watchers)
updatedRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo.ID})
assert.True(t, updatedRepo.IsPrivate)
assert.Zero(t, updatedRepo.NumWatches)
}
// TestUpdateRepositoryClearsWatchesOnVisibilityChange ensures the shared updateRepository
// helper (used by the API EditRepo path) also clears watches when a repo goes private.
func TestUpdateRepositoryClearsWatchesOnVisibilityChange(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
assert.False(t, repo.IsPrivate)
watchers, err := repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1})
require.NoError(t, err)
require.NotEmpty(t, watchers)
repo.IsPrivate = true
require.NoError(t, updateRepository(t.Context(), repo, true))
watchers, err = repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Empty(t, watchers)
updatedRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo.ID})
assert.Zero(t, updatedRepo.NumWatches)
updatedRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo.ID})
if name == "MakeRepoPrivate" {
assert.True(t, updatedRepo.IsPrivate)
}
assert.Zero(t, updatedRepo.NumWatches)
})
}
}
+20 -26
View File
@@ -78,32 +78,26 @@ func TestStartRepositoryTransferSetPermission(t *testing.T) {
assert.NoError(t, err)
assert.False(t, hasAccess)
t.Run("RevokeAccessAfterRejection", func(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
assert.NoError(t, repo.LoadOwner(t.Context()))
assert.NoError(t, StartRepositoryTransfer(t.Context(), doer, recipient, repo, nil))
hasAccess, err = access_model.HasAnyUnitAccess(t.Context(), recipient.ID, repo)
assert.NoError(t, err)
assert.True(t, hasAccess)
assert.NoError(t, RejectRepositoryTransfer(t.Context(), repo, recipient))
hasAccess, err = access_model.HasAnyUnitAccess(t.Context(), recipient.ID, repo)
assert.NoError(t, err)
assert.False(t, hasAccess)
})
t.Run("RevokeAccessAfterCancel", func(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
assert.NoError(t, repo.LoadOwner(t.Context()))
assert.NoError(t, StartRepositoryTransfer(t.Context(), doer, recipient, repo, nil))
hasAccess, err = access_model.HasAnyUnitAccess(t.Context(), recipient.ID, repo)
assert.NoError(t, err)
assert.True(t, hasAccess)
transfer, err := repo_model.GetPendingRepositoryTransfer(t.Context(), repo)
assert.NoError(t, err)
assert.NoError(t, CancelRepositoryTransfer(t.Context(), transfer, doer))
hasAccess, err = access_model.HasAnyUnitAccess(t.Context(), recipient.ID, repo)
assert.NoError(t, err)
assert.False(t, hasAccess)
})
for _, name := range []string{"RevokeAccessAfterRejection", "RevokeAccessAfterCancel"} {
t.Run(name, func(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
assert.NoError(t, repo.LoadOwner(t.Context()))
assert.NoError(t, StartRepositoryTransfer(t.Context(), doer, recipient, repo, nil))
hasAccess, err = access_model.HasAnyUnitAccess(t.Context(), recipient.ID, repo)
assert.NoError(t, err)
assert.True(t, hasAccess)
if name == "RevokeAccessAfterRejection" {
assert.NoError(t, RejectRepositoryTransfer(t.Context(), repo, recipient))
} else {
transfer, err := repo_model.GetPendingRepositoryTransfer(t.Context(), repo)
assert.NoError(t, err)
assert.NoError(t, CancelRepositoryTransfer(t.Context(), transfer, doer))
}
hasAccess, err = access_model.HasAnyUnitAccess(t.Context(), recipient.ID, repo)
assert.NoError(t, err)
assert.False(t, hasAccess)
})
}
t.Run("KeepOriginAccessOnStop", func(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
assert.NoError(t, repo.LoadOwner(t.Context()))
+1 -8
View File
@@ -12,7 +12,7 @@ import (
"github.com/stretchr/testify/assert"
)
func TestCanBlockUser(t *testing.T) {
func TestCanBlockAndUnblockUser(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
@@ -39,15 +39,8 @@ func TestCanBlockUser(t *testing.T) {
assert.True(t, CanBlockUser(t.Context(), user1, user2, user4))
assert.True(t, CanBlockUser(t.Context(), user2, user2, user4))
assert.True(t, CanBlockUser(t.Context(), user2, org3, user29))
}
func TestCanUnblockUser(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
user28 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 28})
user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29})
org17 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 17})
// Doer can't self unblock
+22 -38
View File
@@ -58,44 +58,28 @@ func TestUpdateUser(t *testing.T) {
}
assert.NoError(t, UpdateUser(t.Context(), user, opts))
assert.Equal(t, opts.KeepEmailPrivate.Value(), user.KeepEmailPrivate)
assert.Equal(t, opts.FullName.Value(), user.FullName)
assert.Equal(t, opts.Website.Value(), user.Website)
assert.Equal(t, opts.Location.Value(), user.Location)
assert.Equal(t, opts.Description.Value(), user.Description)
assert.Equal(t, opts.AllowGitHook.Value(), user.AllowGitHook)
assert.Equal(t, opts.AllowImportLocal.Value(), user.AllowImportLocal)
assert.Equal(t, opts.MaxRepoCreation.Value(), user.MaxRepoCreation)
assert.Equal(t, opts.IsRestricted.Value(), user.IsRestricted)
assert.Equal(t, opts.IsActive.Value(), user.IsActive)
assert.Equal(t, opts.IsAdmin.Value().FieldValue, user.IsAdmin)
assert.Equal(t, opts.Visibility.Value(), user.Visibility)
assert.Equal(t, opts.KeepActivityPrivate.Value(), user.KeepActivityPrivate)
assert.Equal(t, opts.Language.Value(), user.Language)
assert.Equal(t, opts.Theme.Value(), user.Theme)
assert.Equal(t, opts.DiffViewStyle.Value(), user.DiffViewStyle)
assert.Equal(t, opts.AllowCreateOrganization.Value(), user.AllowCreateOrganization)
assert.Equal(t, opts.EmailNotificationsPreference.Value(), user.EmailNotificationsPreference)
user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 28})
assert.Equal(t, opts.KeepEmailPrivate.Value(), user.KeepEmailPrivate)
assert.Equal(t, opts.FullName.Value(), user.FullName)
assert.Equal(t, opts.Website.Value(), user.Website)
assert.Equal(t, opts.Location.Value(), user.Location)
assert.Equal(t, opts.Description.Value(), user.Description)
assert.Equal(t, opts.AllowGitHook.Value(), user.AllowGitHook)
assert.Equal(t, opts.AllowImportLocal.Value(), user.AllowImportLocal)
assert.Equal(t, opts.MaxRepoCreation.Value(), user.MaxRepoCreation)
assert.Equal(t, opts.IsRestricted.Value(), user.IsRestricted)
assert.Equal(t, opts.IsActive.Value(), user.IsActive)
assert.Equal(t, opts.IsAdmin.Value().FieldValue, user.IsAdmin)
assert.Equal(t, opts.Visibility.Value(), user.Visibility)
assert.Equal(t, opts.KeepActivityPrivate.Value(), user.KeepActivityPrivate)
assert.Equal(t, opts.Language.Value(), user.Language)
assert.Equal(t, opts.Theme.Value(), user.Theme)
assert.Equal(t, opts.DiffViewStyle.Value(), user.DiffViewStyle)
assert.Equal(t, opts.AllowCreateOrganization.Value(), user.AllowCreateOrganization)
assert.Equal(t, opts.EmailNotificationsPreference.Value(), user.EmailNotificationsPreference)
assertUpdatedUser := func(user *user_model.User) {
assert.Equal(t, opts.KeepEmailPrivate.Value(), user.KeepEmailPrivate)
assert.Equal(t, opts.FullName.Value(), user.FullName)
assert.Equal(t, opts.Website.Value(), user.Website)
assert.Equal(t, opts.Location.Value(), user.Location)
assert.Equal(t, opts.Description.Value(), user.Description)
assert.Equal(t, opts.AllowGitHook.Value(), user.AllowGitHook)
assert.Equal(t, opts.AllowImportLocal.Value(), user.AllowImportLocal)
assert.Equal(t, opts.MaxRepoCreation.Value(), user.MaxRepoCreation)
assert.Equal(t, opts.IsRestricted.Value(), user.IsRestricted)
assert.Equal(t, opts.IsActive.Value(), user.IsActive)
assert.Equal(t, opts.IsAdmin.Value().FieldValue, user.IsAdmin)
assert.Equal(t, opts.Visibility.Value(), user.Visibility)
assert.Equal(t, opts.KeepActivityPrivate.Value(), user.KeepActivityPrivate)
assert.Equal(t, opts.Language.Value(), user.Language)
assert.Equal(t, opts.Theme.Value(), user.Theme)
assert.Equal(t, opts.DiffViewStyle.Value(), user.DiffViewStyle)
assert.Equal(t, opts.AllowCreateOrganization.Value(), user.AllowCreateOrganization)
assert.Equal(t, opts.EmailNotificationsPreference.Value(), user.EmailNotificationsPreference)
}
assertUpdatedUser(user)
assertUpdatedUser(unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 28}))
}
func TestUpdateAuth(t *testing.T) {
+5 -14
View File
@@ -76,14 +76,10 @@ func TestDeleteUser(t *testing.T) {
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueWatch{UserID: 2})
// delete users
user24 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 24})
assert.NoError(t, DeleteUser(t.Context(), user24, true))
user32 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 32})
assert.NoError(t, DeleteUser(t.Context(), user32, true))
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
assert.NoError(t, DeleteUser(t.Context(), user2, true))
for _, userID := range []int64{24, 32, 2} {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID})
assert.NoError(t, DeleteUser(t.Context(), user, true))
}
// assert they do not exist after deletion
unittest.AssertNotExistsBean(t, &auth.TwoFactor{UID: 24})
@@ -112,7 +108,7 @@ func TestDeleteUserUnlinkedAttachments(t *testing.T) {
}
func TestPurgeUser(t *testing.T) {
test := func(userID int64) {
for _, userID := range []int64{2, 4, 8, 11} {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID})
@@ -122,11 +118,6 @@ func TestPurgeUser(t *testing.T) {
unittest.AssertNotExistsBean(t, &user_model.User{ID: userID})
unittest.CheckConsistencyFor(t, &user_model.User{}, &repo_model.Repository{})
}
test(2)
test(4)
test(8)
test(11)
org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
assert.Error(t, DeleteUser(t.Context(), org, false))
}
+28 -45
View File
@@ -157,55 +157,38 @@ func TestWebhookDeliverHookTask(t *testing.T) {
}
assert.NoError(t, webhook_model.CreateWebhook(t.Context(), hook))
t.Run("Version 1", func(t *testing.T) {
testVersion = 1
hookTask := &webhook_model.HookTask{
HookID: hook.ID,
EventType: webhook_module.HookEventPush,
PayloadContent: `{"data": 42}`,
PayloadVersion: 1,
}
for version, name := range []string{"Version 1", "Version 2"} {
t.Run(name, func(t *testing.T) {
payloadContent := `{"data": 42}`
if version == 1 {
p := pushTestPayload()
data, err := p.JSONPayload()
assert.NoError(t, err)
payloadContent = string(data)
}
hookTask, err := webhook_model.CreateHookTask(t.Context(), hookTask)
assert.NoError(t, err)
assert.NotNil(t, hookTask)
testVersion = version + 1
hookTask := &webhook_model.HookTask{
HookID: hook.ID,
EventType: webhook_module.HookEventPush,
PayloadContent: payloadContent,
PayloadVersion: testVersion,
}
assert.NoError(t, Deliver(t.Context(), hookTask))
select {
case <-done:
case <-time.After(5 * time.Second):
t.Fatal("waited to long for request to happen")
}
hookTask, err := webhook_model.CreateHookTask(t.Context(), hookTask)
assert.NoError(t, err)
assert.NotNil(t, hookTask)
assert.True(t, hookTask.IsSucceed)
})
assert.NoError(t, Deliver(t.Context(), hookTask))
select {
case <-done:
case <-time.After(5 * time.Second):
t.Fatal("waited to long for request to happen")
}
t.Run("Version 2", func(t *testing.T) {
p := pushTestPayload()
data, err := p.JSONPayload()
assert.NoError(t, err)
testVersion = 2
hookTask := &webhook_model.HookTask{
HookID: hook.ID,
EventType: webhook_module.HookEventPush,
PayloadContent: string(data),
PayloadVersion: 2,
}
hookTask, err = webhook_model.CreateHookTask(t.Context(), hookTask)
assert.NoError(t, err)
assert.NotNil(t, hookTask)
assert.NoError(t, Deliver(t.Context(), hookTask))
select {
case <-done:
case <-time.After(5 * time.Second):
t.Fatal("waited to long for request to happen")
}
assert.True(t, hookTask.IsSucceed)
})
assert.True(t, hookTask.IsSucceed)
})
}
}
func TestWebhookDeliverSpecificTypes(t *testing.T) {
+22 -64
View File
@@ -27,6 +27,12 @@ func TestDingTalkPayload(t *testing.T) {
return ""
}
dc := dingtalkConvertor{}
assertPayload := func(t *testing.T, pl DingtalkPayload, text, title, singleTitle, singleURL string) {
assert.Equal(t, text, pl.ActionCard.Text)
assert.Equal(t, title, pl.ActionCard.Title)
assert.Equal(t, singleTitle, pl.ActionCard.SingleTitle)
assert.Equal(t, singleURL, parseRealSingleURL(pl.ActionCard.SingleURL))
}
t.Run("Create", func(t *testing.T) {
p := createTestPayload()
@@ -34,10 +40,7 @@ func TestDingTalkPayload(t *testing.T) {
pl, err := dc.Create(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] branch test created", pl.ActionCard.Text)
assert.Equal(t, "[test/repo] branch test created", pl.ActionCard.Title)
assert.Equal(t, "view ref test", pl.ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/src/test", parseRealSingleURL(pl.ActionCard.SingleURL))
assertPayload(t, pl, "[test/repo] branch test created", "[test/repo] branch test created", "view ref test", "http://localhost:3000/test/repo/src/test")
})
t.Run("Delete", func(t *testing.T) {
@@ -46,10 +49,7 @@ func TestDingTalkPayload(t *testing.T) {
pl, err := dc.Delete(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] branch test deleted", pl.ActionCard.Text)
assert.Equal(t, "[test/repo] branch test deleted", pl.ActionCard.Title)
assert.Equal(t, "view ref test", pl.ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/src/test", parseRealSingleURL(pl.ActionCard.SingleURL))
assertPayload(t, pl, "[test/repo] branch test deleted", "[test/repo] branch test deleted", "view ref test", "http://localhost:3000/test/repo/src/test")
})
t.Run("Fork", func(t *testing.T) {
@@ -58,10 +58,7 @@ func TestDingTalkPayload(t *testing.T) {
pl, err := dc.Fork(p)
require.NoError(t, err)
assert.Equal(t, "test/repo2 is forked to test/repo", pl.ActionCard.Text)
assert.Equal(t, "test/repo2 is forked to test/repo", pl.ActionCard.Title)
assert.Equal(t, "view forked repo test/repo", pl.ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo", parseRealSingleURL(pl.ActionCard.SingleURL))
assertPayload(t, pl, "test/repo2 is forked to test/repo", "test/repo2 is forked to test/repo", "view forked repo test/repo", "http://localhost:3000/test/repo")
})
t.Run("Push", func(t *testing.T) {
@@ -70,10 +67,7 @@ func TestDingTalkPayload(t *testing.T) {
pl, err := dc.Push(p)
require.NoError(t, err)
assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", pl.ActionCard.Text)
assert.Equal(t, "[test/repo:test] 2 new commits", pl.ActionCard.Title)
assert.Equal(t, "view commits", pl.ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/src/test", parseRealSingleURL(pl.ActionCard.SingleURL))
assertPayload(t, pl, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", "[test/repo:test] 2 new commits", "view commits", "http://localhost:3000/test/repo/src/test")
})
t.Run("Issue", func(t *testing.T) {
@@ -83,19 +77,13 @@ func TestDingTalkPayload(t *testing.T) {
pl, err := dc.Issue(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Issue opened: #2 crash by user1\r\n\r\nissue body", pl.ActionCard.Text)
assert.Equal(t, "#2 crash", pl.ActionCard.Title)
assert.Equal(t, "view issue", pl.ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/issues/2", parseRealSingleURL(pl.ActionCard.SingleURL))
assertPayload(t, pl, "[test/repo] Issue opened: #2 crash by user1\r\n\r\nissue body", "#2 crash", "view issue", "http://localhost:3000/test/repo/issues/2")
p.Action = api.HookIssueClosed
pl, err = dc.Issue(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Issue closed: #2 crash by user1", pl.ActionCard.Text)
assert.Equal(t, "#2 crash", pl.ActionCard.Title)
assert.Equal(t, "view issue", pl.ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/issues/2", parseRealSingleURL(pl.ActionCard.SingleURL))
assertPayload(t, pl, "[test/repo] Issue closed: #2 crash by user1", "#2 crash", "view issue", "http://localhost:3000/test/repo/issues/2")
})
t.Run("IssueComment", func(t *testing.T) {
@@ -104,10 +92,7 @@ func TestDingTalkPayload(t *testing.T) {
pl, err := dc.IssueComment(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] New comment on issue #2 crash by user1\r\n\r\nmore info needed", pl.ActionCard.Text)
assert.Equal(t, "#2 crash", pl.ActionCard.Title)
assert.Equal(t, "view issue comment", pl.ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/issues/2#issuecomment-4", parseRealSingleURL(pl.ActionCard.SingleURL))
assertPayload(t, pl, "[test/repo] New comment on issue #2 crash by user1\r\n\r\nmore info needed", "#2 crash", "view issue comment", "http://localhost:3000/test/repo/issues/2#issuecomment-4")
})
t.Run("PullRequest", func(t *testing.T) {
@@ -116,10 +101,7 @@ func TestDingTalkPayload(t *testing.T) {
pl, err := dc.PullRequest(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Pull request opened: #12 Fix bug by user1\r\n\r\nfixes bug #2", pl.ActionCard.Text)
assert.Equal(t, "#12 Fix bug", pl.ActionCard.Title)
assert.Equal(t, "view pull request", pl.ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", parseRealSingleURL(pl.ActionCard.SingleURL))
assertPayload(t, pl, "[test/repo] Pull request opened: #12 Fix bug by user1\r\n\r\nfixes bug #2", "#12 Fix bug", "view pull request", "http://localhost:3000/test/repo/pulls/12")
})
t.Run("PullRequestComment", func(t *testing.T) {
@@ -128,10 +110,7 @@ func TestDingTalkPayload(t *testing.T) {
pl, err := dc.IssueComment(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] New comment on pull request #12 Fix bug by user1\r\n\r\nchanges requested", pl.ActionCard.Text)
assert.Equal(t, "#12 Fix bug", pl.ActionCard.Title)
assert.Equal(t, "view issue comment", pl.ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/pulls/12#issuecomment-4", parseRealSingleURL(pl.ActionCard.SingleURL))
assertPayload(t, pl, "[test/repo] New comment on pull request #12 Fix bug by user1\r\n\r\nchanges requested", "#12 Fix bug", "view issue comment", "http://localhost:3000/test/repo/pulls/12#issuecomment-4")
})
t.Run("Review", func(t *testing.T) {
@@ -141,10 +120,7 @@ func TestDingTalkPayload(t *testing.T) {
pl, err := dc.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Pull request review approved : #12 Fix bug\r\n\r\ngood job", pl.ActionCard.Text)
assert.Equal(t, "[test/repo] Pull request review approved : #12 Fix bug", pl.ActionCard.Title)
assert.Equal(t, "view pull request", pl.ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", parseRealSingleURL(pl.ActionCard.SingleURL))
assertPayload(t, pl, "[test/repo] Pull request review approved : #12 Fix bug\r\n\r\ngood job", "[test/repo] Pull request review approved : #12 Fix bug", "view pull request", "http://localhost:3000/test/repo/pulls/12")
})
t.Run("Repository", func(t *testing.T) {
@@ -153,10 +129,7 @@ func TestDingTalkPayload(t *testing.T) {
pl, err := dc.Repository(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Repository created", pl.ActionCard.Text)
assert.Equal(t, "[test/repo] Repository created", pl.ActionCard.Title)
assert.Equal(t, "view repository", pl.ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo", parseRealSingleURL(pl.ActionCard.SingleURL))
assertPayload(t, pl, "[test/repo] Repository created", "[test/repo] Repository created", "view repository", "http://localhost:3000/test/repo")
})
t.Run("Package", func(t *testing.T) {
@@ -165,10 +138,7 @@ func TestDingTalkPayload(t *testing.T) {
pl, err := dc.Package(p)
require.NoError(t, err)
assert.Equal(t, "Package created: GiteaContainer:latest by user1", pl.ActionCard.Text)
assert.Equal(t, "Package created: GiteaContainer:latest by user1", pl.ActionCard.Title)
assert.Equal(t, "view package", pl.ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/user1/-/packages/container/GiteaContainer/latest", parseRealSingleURL(pl.ActionCard.SingleURL))
assertPayload(t, pl, "Package created: GiteaContainer:latest by user1", "Package created: GiteaContainer:latest by user1", "view package", "http://localhost:3000/user1/-/packages/container/GiteaContainer/latest")
})
t.Run("Wiki", func(t *testing.T) {
@@ -178,28 +148,19 @@ func TestDingTalkPayload(t *testing.T) {
pl, err := dc.Wiki(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment) by user1", pl.ActionCard.Text)
assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment) by user1", pl.ActionCard.Title)
assert.Equal(t, "view wiki", pl.ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", parseRealSingleURL(pl.ActionCard.SingleURL))
assertPayload(t, pl, "[test/repo] New wiki page 'index' (Wiki change comment) by user1", "[test/repo] New wiki page 'index' (Wiki change comment) by user1", "view wiki", "http://localhost:3000/test/repo/wiki/index")
p.Action = api.HookWikiEdited
pl, err = dc.Wiki(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment) by user1", pl.ActionCard.Text)
assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment) by user1", pl.ActionCard.Title)
assert.Equal(t, "view wiki", pl.ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", parseRealSingleURL(pl.ActionCard.SingleURL))
assertPayload(t, pl, "[test/repo] Wiki page 'index' edited (Wiki change comment) by user1", "[test/repo] Wiki page 'index' edited (Wiki change comment) by user1", "view wiki", "http://localhost:3000/test/repo/wiki/index")
p.Action = api.HookWikiDeleted
pl, err = dc.Wiki(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Wiki page 'index' deleted by user1", pl.ActionCard.Text)
assert.Equal(t, "[test/repo] Wiki page 'index' deleted by user1", pl.ActionCard.Title)
assert.Equal(t, "view wiki", pl.ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", parseRealSingleURL(pl.ActionCard.SingleURL))
assertPayload(t, pl, "[test/repo] Wiki page 'index' deleted by user1", "[test/repo] Wiki page 'index' deleted by user1", "view wiki", "http://localhost:3000/test/repo/wiki/index")
})
t.Run("Release", func(t *testing.T) {
@@ -208,10 +169,7 @@ func TestDingTalkPayload(t *testing.T) {
pl, err := dc.Release(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Release created: v1.0 by user1", pl.ActionCard.Text)
assert.Equal(t, "[test/repo] Release created: v1.0 by user1", pl.ActionCard.Title)
assert.Equal(t, "view release", pl.ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/releases/tag/v1.0", parseRealSingleURL(pl.ActionCard.SingleURL))
assertPayload(t, pl, "[test/repo] Release created: v1.0 by user1", "[test/repo] Release created: v1.0 by user1", "view release", "http://localhost:3000/test/repo/releases/tag/v1.0")
})
}
+33 -124
View File
@@ -18,6 +18,21 @@ import (
func TestDiscordPayload(t *testing.T) {
dc := discordConvertor{}
assertPayload := func(t *testing.T, pl DiscordPayload, sender *api.User, title, description, link string) {
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, title, pl.Embeds[0].Title)
if description == "" {
assert.Empty(t, pl.Embeds[0].Description)
} else {
assert.Equal(t, description, pl.Embeds[0].Description)
}
if link != "" {
assert.Equal(t, link, pl.Embeds[0].URL)
}
assert.Equal(t, sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, sender.AvatarURL, pl.Embeds[0].Author.IconURL)
}
t.Run("Create", func(t *testing.T) {
p := createTestPayload()
@@ -25,13 +40,7 @@ func TestDiscordPayload(t *testing.T) {
pl, err := dc.Create(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "[test/repo] branch test created", pl.Embeds[0].Title)
assert.Empty(t, pl.Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "[test/repo] branch test created", "", "http://localhost:3000/test/repo/src/test")
})
t.Run("Delete", func(t *testing.T) {
@@ -40,13 +49,7 @@ func TestDiscordPayload(t *testing.T) {
pl, err := dc.Delete(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "[test/repo] branch test deleted", pl.Embeds[0].Title)
assert.Empty(t, pl.Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "[test/repo] branch test deleted", "", "http://localhost:3000/test/repo/src/test")
})
t.Run("Fork", func(t *testing.T) {
@@ -55,13 +58,7 @@ func TestDiscordPayload(t *testing.T) {
pl, err := dc.Fork(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "test/repo2 is forked to test/repo", pl.Embeds[0].Title)
assert.Empty(t, pl.Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo", pl.Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "test/repo2 is forked to test/repo", "", "http://localhost:3000/test/repo")
})
t.Run("Push", func(t *testing.T) {
@@ -70,13 +67,7 @@ func TestDiscordPayload(t *testing.T) {
pl, err := dc.Push(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "[test/repo:test] 2 new commits", pl.Embeds[0].Title)
assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", pl.Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "[test/repo:test] 2 new commits", "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", "http://localhost:3000/test/repo/src/test")
})
t.Run("PushWithMultilineCommitMessage", func(t *testing.T) {
@@ -85,12 +76,7 @@ func TestDiscordPayload(t *testing.T) {
pl, err := dc.Push(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "[test/repo:test] 2 new commits", pl.Embeds[0].Title)
assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) chore: This is a commit summary - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) chore: This is a commit summary - user1", pl.Embeds[0].Description)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "[test/repo:test] 2 new commits", "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) chore: This is a commit summary - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) chore: This is a commit summary - user1", "")
})
t.Run("PushWithLongCommitSummary", func(t *testing.T) {
@@ -99,12 +85,7 @@ func TestDiscordPayload(t *testing.T) {
pl, err := dc.Push(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "[test/repo:test] 2 new commits", pl.Embeds[0].Title)
assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) This is a commit summary ⚠️⚠️⚠️⚠️ containing 你好... - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) This is a commit summary ⚠️⚠️⚠️⚠️ containing 你好... - user1", pl.Embeds[0].Description)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "[test/repo:test] 2 new commits", "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) This is a commit summary ⚠️⚠️⚠️⚠️ containing 你好... - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) This is a commit summary ⚠️⚠️⚠️⚠️ containing 你好... - user1", "")
})
t.Run("Issue", func(t *testing.T) {
@@ -114,25 +95,13 @@ func TestDiscordPayload(t *testing.T) {
pl, err := dc.Issue(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "[test/repo] Issue opened: #2 crash", pl.Embeds[0].Title)
assert.Equal(t, "issue body", pl.Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/issues/2", pl.Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "[test/repo] Issue opened: #2 crash", "issue body", "http://localhost:3000/test/repo/issues/2")
p.Action = api.HookIssueClosed
pl, err = dc.Issue(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "[test/repo] Issue closed: #2 crash", pl.Embeds[0].Title)
assert.Empty(t, pl.Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/issues/2", pl.Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "[test/repo] Issue closed: #2 crash", "", "http://localhost:3000/test/repo/issues/2")
})
t.Run("IssueComment", func(t *testing.T) {
@@ -141,13 +110,7 @@ func TestDiscordPayload(t *testing.T) {
pl, err := dc.IssueComment(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "[test/repo] New comment on issue #2 crash", pl.Embeds[0].Title)
assert.Equal(t, "more info needed", pl.Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/issues/2#issuecomment-4", pl.Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "[test/repo] New comment on issue #2 crash", "more info needed", "http://localhost:3000/test/repo/issues/2#issuecomment-4")
})
t.Run("PullRequest", func(t *testing.T) {
@@ -156,13 +119,7 @@ func TestDiscordPayload(t *testing.T) {
pl, err := dc.PullRequest(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "[test/repo] Pull request opened: #12 Fix bug", pl.Embeds[0].Title)
assert.Equal(t, "fixes bug #2", pl.Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", pl.Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "[test/repo] Pull request opened: #12 Fix bug", "fixes bug #2", "http://localhost:3000/test/repo/pulls/12")
})
t.Run("PullRequestComment", func(t *testing.T) {
@@ -171,13 +128,7 @@ func TestDiscordPayload(t *testing.T) {
pl, err := dc.IssueComment(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "[test/repo] New comment on pull request #12 Fix bug", pl.Embeds[0].Title)
assert.Equal(t, "changes requested", pl.Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/pulls/12#issuecomment-4", pl.Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "[test/repo] New comment on pull request #12 Fix bug", "changes requested", "http://localhost:3000/test/repo/pulls/12#issuecomment-4")
})
t.Run("Review", func(t *testing.T) {
@@ -187,13 +138,7 @@ func TestDiscordPayload(t *testing.T) {
pl, err := dc.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "[test/repo] Pull request review approved: #12 Fix bug", pl.Embeds[0].Title)
assert.Equal(t, "good job", pl.Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", pl.Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "[test/repo] Pull request review approved: #12 Fix bug", "good job", "http://localhost:3000/test/repo/pulls/12")
})
t.Run("Repository", func(t *testing.T) {
@@ -202,13 +147,7 @@ func TestDiscordPayload(t *testing.T) {
pl, err := dc.Repository(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "[test/repo] Repository created", pl.Embeds[0].Title)
assert.Empty(t, pl.Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo", pl.Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "[test/repo] Repository created", "", "http://localhost:3000/test/repo")
})
t.Run("Package", func(t *testing.T) {
@@ -217,13 +156,7 @@ func TestDiscordPayload(t *testing.T) {
pl, err := dc.Package(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "Package created: GiteaContainer:latest", pl.Embeds[0].Title)
assert.Empty(t, pl.Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/user1/-/packages/container/GiteaContainer/latest", pl.Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "Package created: GiteaContainer:latest", "", "http://localhost:3000/user1/-/packages/container/GiteaContainer/latest")
})
t.Run("Wiki", func(t *testing.T) {
@@ -233,37 +166,19 @@ func TestDiscordPayload(t *testing.T) {
pl, err := dc.Wiki(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment)", pl.Embeds[0].Title)
assert.Equal(t, "Wiki change comment", pl.Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "[test/repo] New wiki page 'index' (Wiki change comment)", "Wiki change comment", "http://localhost:3000/test/repo/wiki/index")
p.Action = api.HookWikiEdited
pl, err = dc.Wiki(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment)", pl.Embeds[0].Title)
assert.Equal(t, "Wiki change comment", pl.Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "[test/repo] Wiki page 'index' edited (Wiki change comment)", "Wiki change comment", "http://localhost:3000/test/repo/wiki/index")
p.Action = api.HookWikiDeleted
pl, err = dc.Wiki(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "[test/repo] Wiki page 'index' deleted", pl.Embeds[0].Title)
assert.Empty(t, pl.Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "[test/repo] Wiki page 'index' deleted", "", "http://localhost:3000/test/repo/wiki/index")
})
t.Run("Release", func(t *testing.T) {
@@ -272,13 +187,7 @@ func TestDiscordPayload(t *testing.T) {
pl, err := dc.Release(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "[test/repo] Release created: v1.0", pl.Embeds[0].Title)
assert.Equal(t, "Note of first stable release", pl.Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/releases/tag/v1.0", pl.Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
assertPayload(t, pl, p.Sender, "[test/repo] Release created: v1.0", "Note of first stable release", "http://localhost:3000/test/repo/releases/tag/v1.0")
})
}
+62 -89
View File
@@ -17,41 +17,68 @@ import (
func TestFeishuPayload(t *testing.T) {
fc := feishuConvertor{}
t.Run("Create", func(t *testing.T) {
p := createTestPayload()
pl, err := fc.Create(p)
require.NoError(t, err)
assert.Equal(t, `[test/repo] branch test created`, pl.Content.Text)
})
t.Run("Delete", func(t *testing.T) {
p := deleteTestPayload()
pl, err := fc.Delete(p)
require.NoError(t, err)
assert.Equal(t, `[test/repo] branch test deleted`, pl.Content.Text)
})
t.Run("Fork", func(t *testing.T) {
p := forkTestPayload()
pl, err := fc.Fork(p)
require.NoError(t, err)
assert.Equal(t, `test/repo2 is forked to test/repo`, pl.Content.Text)
})
t.Run("Push", func(t *testing.T) {
p := pushTestPayload()
pl, err := fc.Push(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo:test] \r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", pl.Content.Text)
})
for _, test := range []struct {
name string
convert func() (FeishuPayload, error)
text string
}{
{
"Create",
func() (FeishuPayload, error) { return fc.Create(createTestPayload()) },
`[test/repo] branch test created`,
},
{
"Delete",
func() (FeishuPayload, error) { return fc.Delete(deleteTestPayload()) },
`[test/repo] branch test deleted`,
},
{
"Fork",
func() (FeishuPayload, error) { return fc.Fork(forkTestPayload()) },
`test/repo2 is forked to test/repo`,
},
{
"Push",
func() (FeishuPayload, error) { return fc.Push(pushTestPayload()) },
"[test/repo:test] \r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1",
},
{
"IssueComment",
func() (FeishuPayload, error) { return fc.IssueComment(issueCommentTestPayload()) },
"[Comment-test/repo #2]: created\ncrash\nhttp://localhost:3000/test/repo/issues/2\nIssue by user1\nOperator: user1\n\nmore info needed",
},
{
"PullRequest",
func() (FeishuPayload, error) { return fc.PullRequest(pullRequestTestPayload()) },
"[PullRequest-test/repo #12]: opened\nFix bug\nhttp://localhost:3000/test/repo/pulls/12\nPullRequest by user1\nOperator: user1\nAssignees: user1\n\nfixes bug #2",
},
{
"PullRequestComment",
func() (FeishuPayload, error) { return fc.IssueComment(pullRequestCommentTestPayload()) },
"[Comment-test/repo #12]: created\nFix bug\nhttp://localhost:3000/test/repo/pulls/12\nPullRequest by user1\nOperator: user1\n\nchanges requested",
},
{
"Repository",
func() (FeishuPayload, error) { return fc.Repository(repositoryTestPayload()) },
"[test/repo] Repository created",
},
{
"Package",
func() (FeishuPayload, error) { return fc.Package(packageTestPayload()) },
"Package created: GiteaContainer:latest by user1",
},
{
"Release",
func() (FeishuPayload, error) { return fc.Release(pullReleaseTestPayload()) },
"[test/repo] Release created: v1.0 by user1",
},
} {
t.Run(test.name, func(t *testing.T) {
pl, err := test.convert()
require.NoError(t, err)
assert.Equal(t, test.text, pl.Content.Text)
})
}
t.Run("Issue", func(t *testing.T) {
p := issueTestPayload()
@@ -69,33 +96,6 @@ func TestFeishuPayload(t *testing.T) {
assert.Equal(t, "[Issue-test/repo #2]: closed\ncrash\nhttp://localhost:3000/test/repo/issues/2\nIssue by user1\nOperator: user1\nAssignees: user1\n\nissue body", pl.Content.Text)
})
t.Run("IssueComment", func(t *testing.T) {
p := issueCommentTestPayload()
pl, err := fc.IssueComment(p)
require.NoError(t, err)
assert.Equal(t, "[Comment-test/repo #2]: created\ncrash\nhttp://localhost:3000/test/repo/issues/2\nIssue by user1\nOperator: user1\n\nmore info needed", pl.Content.Text)
})
t.Run("PullRequest", func(t *testing.T) {
p := pullRequestTestPayload()
pl, err := fc.PullRequest(p)
require.NoError(t, err)
assert.Equal(t, "[PullRequest-test/repo #12]: opened\nFix bug\nhttp://localhost:3000/test/repo/pulls/12\nPullRequest by user1\nOperator: user1\nAssignees: user1\n\nfixes bug #2", pl.Content.Text)
})
t.Run("PullRequestComment", func(t *testing.T) {
p := pullRequestCommentTestPayload()
pl, err := fc.IssueComment(p)
require.NoError(t, err)
assert.Equal(t, "[Comment-test/repo #12]: created\nFix bug\nhttp://localhost:3000/test/repo/pulls/12\nPullRequest by user1\nOperator: user1\n\nchanges requested", pl.Content.Text)
})
t.Run("Review", func(t *testing.T) {
p := pullRequestTestPayload()
p.Action = api.HookIssueReviewed
@@ -106,24 +106,6 @@ func TestFeishuPayload(t *testing.T) {
assert.Equal(t, "[test/repo] Pull request review approved : #12 Fix bug\r\n\r\ngood job", pl.Content.Text)
})
t.Run("Repository", func(t *testing.T) {
p := repositoryTestPayload()
pl, err := fc.Repository(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Repository created", pl.Content.Text)
})
t.Run("Package", func(t *testing.T) {
p := packageTestPayload()
pl, err := fc.Package(p)
require.NoError(t, err)
assert.Equal(t, "Package created: GiteaContainer:latest by user1", pl.Content.Text)
})
t.Run("Wiki", func(t *testing.T) {
p := wikiTestPayload()
@@ -145,15 +127,6 @@ func TestFeishuPayload(t *testing.T) {
assert.Equal(t, "[test/repo] Wiki page 'index' deleted by user1", pl.Content.Text)
})
t.Run("Release", func(t *testing.T) {
p := pullReleaseTestPayload()
pl, err := fc.Release(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Release created: v1.0 by user1", pl.Content.Text)
})
}
func TestFeishuJSONPayload(t *testing.T) {
+56 -145
View File
@@ -383,202 +383,113 @@ func packageTestPayload() *api.PackagePayload {
}
func TestGetIssuesPayloadInfo(t *testing.T) {
p := issueTestPayload()
p.Changes = &api.ChangesPayload{AddedAssignees: p.Issue.Assignees}
issue := issueTestPayload()
issue.Changes = &api.ChangesPayload{AddedAssignees: issue.Issue.Assignees}
pull := pullRequestTestPayload()
pull.Changes = &api.ChangesPayload{AddedAssignees: pull.PullRequest.Assignees}
cases := []struct {
action api.HookIssueAction
text string
issueTitle string
attachmentText string
color int
action api.HookIssueAction
issueText string
pullRequestText string
issueMarkdown string
pullRequestMarkdown string
issueColor int
pullRequestColor int
}{
{
api.HookIssueOpened,
"[test/repo] Issue opened: #2 crash by user1",
"#2 crash",
"issue body",
orangeColor,
"[test/repo] Pull request opened: #12 Fix bug by user1",
"issue body", "fixes bug #2",
orangeColor, greenColor,
},
{
api.HookIssueClosed,
"[test/repo] Issue closed: #2 crash by user1",
"#2 crash",
"",
redColor,
"[test/repo] Pull request closed: #12 Fix bug by user1",
"", "",
redColor, redColor,
},
{
api.HookIssueReOpened,
"[test/repo] Issue re-opened: #2 crash by user1",
"#2 crash",
"",
yellowColor,
"[test/repo] Pull request re-opened: #12 Fix bug by user1",
"", "",
yellowColor, yellowColor,
},
{
api.HookIssueEdited,
"[test/repo] Issue edited: #2 crash by user1",
"#2 crash",
"issue body",
yellowColor,
"[test/repo] Pull request edited: #12 Fix bug by user1",
"issue body", "fixes bug #2",
yellowColor, yellowColor,
},
{
api.HookIssueAssigned,
"[test/repo] Issue assigned to user1: #2 crash by user1",
"#2 crash",
"",
greenColor,
"[test/repo] Pull request assigned to user1: #12 Fix bug by user1",
"", "",
greenColor, greenColor,
},
{
api.HookIssueUnassigned,
"[test/repo] Issue unassigned: #2 crash by user1",
"#2 crash",
"",
yellowColor,
"[test/repo] Pull request unassigned: #12 Fix bug by user1",
"", "",
yellowColor, yellowColor,
},
{
api.HookIssueLabelUpdated,
"[test/repo] Issue labels updated: #2 crash by user1",
"#2 crash",
"",
yellowColor,
"[test/repo] Pull request labels updated: #12 Fix bug by user1",
"", "",
yellowColor, yellowColor,
},
{
api.HookIssueLabelCleared,
"[test/repo] Issue labels cleared: #2 crash by user1",
"#2 crash",
"",
yellowColor,
"[test/repo] Pull request labels cleared: #12 Fix bug by user1",
"", "",
yellowColor, yellowColor,
},
{
api.HookIssueSynchronized,
"[test/repo] Issue synchronized: #2 crash by user1",
"#2 crash",
"",
yellowColor,
"[test/repo] Pull request synchronized: #12 Fix bug by user1",
"", "",
yellowColor, yellowColor,
},
{
api.HookIssueMilestoned,
"[test/repo] Issue milestoned to Milestone Title: #2 crash by user1",
"#2 crash",
"",
yellowColor,
"[test/repo] Pull request milestoned to Milestone Title: #12 Fix bug by user1",
"", "",
yellowColor, yellowColor,
},
{
api.HookIssueDemilestoned,
"[test/repo] Issue milestone cleared: #2 crash by user1",
"#2 crash",
"",
yellowColor,
},
}
for i, c := range cases {
p.Action = c.action
text, issueTitle, extraMarkdown, color := getIssuesPayloadInfo(p, noneLinkFormatter, true)
assert.Equal(t, c.text, text, "case %d", i)
assert.Equal(t, c.issueTitle, issueTitle, "case %d", i)
assert.Equal(t, c.attachmentText, extraMarkdown, "case %d", i)
assert.Equal(t, c.color, color, "case %d", i)
}
}
func TestGetPullRequestPayloadInfo(t *testing.T) {
p := pullRequestTestPayload()
p.Changes = &api.ChangesPayload{AddedAssignees: p.PullRequest.Assignees}
cases := []struct {
action api.HookIssueAction
text string
issueTitle string
attachmentText string
color int
}{
{
api.HookIssueOpened,
"[test/repo] Pull request opened: #12 Fix bug by user1",
"#12 Fix bug",
"fixes bug #2",
greenColor,
},
{
api.HookIssueClosed,
"[test/repo] Pull request closed: #12 Fix bug by user1",
"#12 Fix bug",
"",
redColor,
},
{
api.HookIssueReOpened,
"[test/repo] Pull request re-opened: #12 Fix bug by user1",
"#12 Fix bug",
"",
yellowColor,
},
{
api.HookIssueEdited,
"[test/repo] Pull request edited: #12 Fix bug by user1",
"#12 Fix bug",
"fixes bug #2",
yellowColor,
},
{
api.HookIssueAssigned,
"[test/repo] Pull request assigned to user1: #12 Fix bug by user1",
"#12 Fix bug",
"",
greenColor,
},
{
api.HookIssueUnassigned,
"[test/repo] Pull request unassigned: #12 Fix bug by user1",
"#12 Fix bug",
"",
yellowColor,
},
{
api.HookIssueLabelUpdated,
"[test/repo] Pull request labels updated: #12 Fix bug by user1",
"#12 Fix bug",
"",
yellowColor,
},
{
api.HookIssueLabelCleared,
"[test/repo] Pull request labels cleared: #12 Fix bug by user1",
"#12 Fix bug",
"",
yellowColor,
},
{
api.HookIssueSynchronized,
"[test/repo] Pull request synchronized: #12 Fix bug by user1",
"#12 Fix bug",
"",
yellowColor,
},
{
api.HookIssueMilestoned,
"[test/repo] Pull request milestoned to Milestone Title: #12 Fix bug by user1",
"#12 Fix bug",
"",
yellowColor,
},
{
api.HookIssueDemilestoned,
"[test/repo] Pull request milestone cleared: #12 Fix bug by user1",
"#12 Fix bug",
"",
yellowColor,
"", "",
yellowColor, yellowColor,
},
}
for i, c := range cases {
p.Action = c.action
text, issueTitle, extraMarkdown, color := getPullRequestPayloadInfo(p, noneLinkFormatter, true)
assert.Equal(t, c.text, text, "case %d", i)
assert.Equal(t, c.issueTitle, issueTitle, "case %d", i)
assert.Equal(t, c.attachmentText, extraMarkdown, "case %d", i)
assert.Equal(t, c.color, color, "case %d", i)
issue.Action = c.action
text, issueTitle, extraMarkdown, color := getIssuesPayloadInfo(issue, noneLinkFormatter, true)
assert.Equal(t, c.issueText, text, "case %d", i)
assert.Equal(t, "#2 crash", issueTitle, "case %d", i)
assert.Equal(t, c.issueMarkdown, extraMarkdown, "case %d", i)
assert.Equal(t, c.issueColor, color, "case %d", i)
pull.Action = c.action
text, issueTitle, extraMarkdown, color = getPullRequestPayloadInfo(pull, noneLinkFormatter, true)
assert.Equal(t, c.pullRequestText, text, "case %d", i)
assert.Equal(t, "#12 Fix bug", issueTitle, "case %d", i)
assert.Equal(t, c.pullRequestMarkdown, extraMarkdown, "case %d", i)
assert.Equal(t, c.pullRequestColor, color, "case %d", i)
}
}
+8 -26
View File
@@ -229,30 +229,12 @@ func TestMatrixJSONPayload(t *testing.T) {
}
func Test_getTxnID(t *testing.T) {
type args struct {
payload []byte
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "dummy payload",
args: args{payload: []byte("Hello World")},
want: "0a4d55a8d778e5022fab701977c5d840bbc486d0",
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := getMatrixTxnID(tt.args.payload)
if (err != nil) != tt.wantErr {
t.Errorf("getMatrixTxnID() error = %v, wantErr %v", err, tt.wantErr)
return
}
assert.Equal(t, tt.want, got)
})
}
t.Run("dummy payload", func(t *testing.T) {
got, err := getMatrixTxnID([]byte("Hello World"))
if err != nil {
t.Errorf("getMatrixTxnID() error = %v, wantErr %v", err, false)
return
}
assert.Equal(t, "0a4d55a8d778e5022fab701977c5d840bbc486d0", got)
})
}
+99 -275
View File
@@ -18,30 +18,42 @@ import (
func TestMSTeamsPayload(t *testing.T) {
mc := msteamsConvertor{}
checkPayload := func(t *testing.T, pl MSTeamsPayload, title, text string, facts map[string]string) {
assert.Equal(t, title, pl.Title)
assert.Equal(t, title, pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
if text == "" {
assert.Empty(t, pl.Sections[0].Text)
} else {
assert.Equal(t, text, pl.Sections[0].Text)
}
assert.Len(t, pl.Sections[0].Facts, len(facts))
for _, fact := range pl.Sections[0].Facts {
if expected, ok := facts[fact.Name]; ok {
assert.Equal(t, expected, fact.Value)
} else {
t.Fail()
}
}
}
checkAction := func(t *testing.T, pl MSTeamsPayload, target string) {
assert.Len(t, pl.PotentialAction, 1)
assert.Len(t, pl.PotentialAction[0].Targets, 1)
assert.Equal(t, target, pl.PotentialAction[0].Targets[0].URI)
}
t.Run("Create", func(t *testing.T) {
p := createTestPayload()
pl, err := mc.Create(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] branch test created", pl.Title)
assert.Equal(t, "[test/repo] branch test created", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
assert.Empty(t, pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 2)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, fmt.Sprintf("[%s](%s)", p.Repo.FullName, p.Repo.HTMLURL), fact.Value)
} else if fact.Name == "branch:" {
assert.Equal(t, "test", fact.Value)
} else {
t.Fail()
}
}
assert.Len(t, pl.PotentialAction, 1)
assert.Len(t, pl.PotentialAction[0].Targets, 1)
assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.PotentialAction[0].Targets[0].URI)
checkPayload(t, pl, "[test/repo] branch test created", "", map[string]string{
"Repository:": fmt.Sprintf("[%s](%s)", p.Repo.FullName, p.Repo.HTMLURL),
"branch:": "test",
})
checkAction(t, pl, "http://localhost:3000/test/repo/src/test")
})
t.Run("Delete", func(t *testing.T) {
@@ -50,24 +62,11 @@ func TestMSTeamsPayload(t *testing.T) {
pl, err := mc.Delete(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] branch test deleted", pl.Title)
assert.Equal(t, "[test/repo] branch test deleted", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
assert.Empty(t, pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 2)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, fmt.Sprintf("[%s](%s)", p.Repo.FullName, p.Repo.HTMLURL), fact.Value)
} else if fact.Name == "branch:" {
assert.Equal(t, "test", fact.Value)
} else {
t.Fail()
}
}
assert.Len(t, pl.PotentialAction, 1)
assert.Len(t, pl.PotentialAction[0].Targets, 1)
assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.PotentialAction[0].Targets[0].URI)
checkPayload(t, pl, "[test/repo] branch test deleted", "", map[string]string{
"Repository:": fmt.Sprintf("[%s](%s)", p.Repo.FullName, p.Repo.HTMLURL),
"branch:": "test",
})
checkAction(t, pl, "http://localhost:3000/test/repo/src/test")
})
t.Run("Fork", func(t *testing.T) {
@@ -76,24 +75,11 @@ func TestMSTeamsPayload(t *testing.T) {
pl, err := mc.Fork(p)
require.NoError(t, err)
assert.Equal(t, "test/repo2 is forked to test/repo", pl.Title)
assert.Equal(t, "test/repo2 is forked to test/repo", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
assert.Empty(t, pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 2)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, fmt.Sprintf("[%s](%s)", p.Repo.FullName, p.Repo.HTMLURL), fact.Value)
} else if fact.Name == "Forkee:" {
assert.Equal(t, p.Forkee.FullName, fact.Value)
} else {
t.Fail()
}
}
assert.Len(t, pl.PotentialAction, 1)
assert.Len(t, pl.PotentialAction[0].Targets, 1)
assert.Equal(t, "http://localhost:3000/test/repo", pl.PotentialAction[0].Targets[0].URI)
checkPayload(t, pl, "test/repo2 is forked to test/repo", "", map[string]string{
"Repository:": fmt.Sprintf("[%s](%s)", p.Repo.FullName, p.Repo.HTMLURL),
"Forkee:": p.Forkee.FullName,
})
checkAction(t, pl, "http://localhost:3000/test/repo")
})
t.Run("Push", func(t *testing.T) {
@@ -102,24 +88,11 @@ func TestMSTeamsPayload(t *testing.T) {
pl, err := mc.Push(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo:test] 2 new commits", pl.Title)
assert.Equal(t, "[test/repo:test] 2 new commits", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\n\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 2)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, fmt.Sprintf("[%s](%s)", p.Repo.FullName, p.Repo.HTMLURL), fact.Value)
} else if fact.Name == "Commit count:" {
assert.Equal(t, "2", fact.Value)
} else {
t.Fail()
}
}
assert.Len(t, pl.PotentialAction, 1)
assert.Len(t, pl.PotentialAction[0].Targets, 1)
assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.PotentialAction[0].Targets[0].URI)
checkPayload(t, pl, "[test/repo:test] 2 new commits", "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\n\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", map[string]string{
"Repository:": fmt.Sprintf("[%s](%s)", p.Repo.FullName, p.Repo.HTMLURL),
"Commit count:": "2",
})
checkAction(t, pl, "http://localhost:3000/test/repo/src/test")
})
t.Run("Issue", func(t *testing.T) {
@@ -129,47 +102,21 @@ func TestMSTeamsPayload(t *testing.T) {
pl, err := mc.Issue(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Issue opened: #2 crash", pl.Title)
assert.Equal(t, "[test/repo] Issue opened: #2 crash", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
assert.Equal(t, "issue body", pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 2)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL), fact.Value)
} else if fact.Name == "Issue #:" {
assert.Equal(t, "2", fact.Value)
} else {
t.Fail()
}
}
assert.Len(t, pl.PotentialAction, 1)
assert.Len(t, pl.PotentialAction[0].Targets, 1)
assert.Equal(t, "http://localhost:3000/test/repo/issues/2", pl.PotentialAction[0].Targets[0].URI)
checkPayload(t, pl, "[test/repo] Issue opened: #2 crash", "issue body", map[string]string{
"Repository:": fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL),
"Issue #:": "2",
})
checkAction(t, pl, "http://localhost:3000/test/repo/issues/2")
p.Action = api.HookIssueClosed
pl, err = mc.Issue(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Issue closed: #2 crash", pl.Title)
assert.Equal(t, "[test/repo] Issue closed: #2 crash", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
assert.Empty(t, pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 2)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL), fact.Value)
} else if fact.Name == "Issue #:" {
assert.Equal(t, "2", fact.Value)
} else {
t.Fail()
}
}
assert.Len(t, pl.PotentialAction, 1)
assert.Len(t, pl.PotentialAction[0].Targets, 1)
assert.Equal(t, "http://localhost:3000/test/repo/issues/2", pl.PotentialAction[0].Targets[0].URI)
checkPayload(t, pl, "[test/repo] Issue closed: #2 crash", "", map[string]string{
"Repository:": fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL),
"Issue #:": "2",
})
checkAction(t, pl, "http://localhost:3000/test/repo/issues/2")
})
t.Run("IssueComment", func(t *testing.T) {
@@ -178,24 +125,11 @@ func TestMSTeamsPayload(t *testing.T) {
pl, err := mc.IssueComment(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] New comment on issue #2 crash", pl.Title)
assert.Equal(t, "[test/repo] New comment on issue #2 crash", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
assert.Equal(t, "more info needed", pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 2)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL), fact.Value)
} else if fact.Name == "Issue #:" {
assert.Equal(t, "2", fact.Value)
} else {
t.Fail()
}
}
assert.Len(t, pl.PotentialAction, 1)
assert.Len(t, pl.PotentialAction[0].Targets, 1)
assert.Equal(t, "http://localhost:3000/test/repo/issues/2#issuecomment-4", pl.PotentialAction[0].Targets[0].URI)
checkPayload(t, pl, "[test/repo] New comment on issue #2 crash", "more info needed", map[string]string{
"Repository:": fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL),
"Issue #:": "2",
})
checkAction(t, pl, "http://localhost:3000/test/repo/issues/2#issuecomment-4")
})
t.Run("PullRequest", func(t *testing.T) {
@@ -204,24 +138,11 @@ func TestMSTeamsPayload(t *testing.T) {
pl, err := mc.PullRequest(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Pull request opened: #12 Fix bug", pl.Title)
assert.Equal(t, "[test/repo] Pull request opened: #12 Fix bug", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
assert.Equal(t, "fixes bug #2", pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 2)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL), fact.Value)
} else if fact.Name == "Pull request:" {
assert.Equal(t, fmt.Sprintf("[#%d](%s)", p.PullRequest.Index, p.PullRequest.HTMLURL), fact.Value)
} else {
t.Fail()
}
}
assert.Len(t, pl.PotentialAction, 1)
assert.Len(t, pl.PotentialAction[0].Targets, 1)
assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", pl.PotentialAction[0].Targets[0].URI)
checkPayload(t, pl, "[test/repo] Pull request opened: #12 Fix bug", "fixes bug #2", map[string]string{
"Repository:": fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL),
"Pull request:": fmt.Sprintf("[#%d](%s)", p.PullRequest.Index, p.PullRequest.HTMLURL),
})
checkAction(t, pl, "http://localhost:3000/test/repo/pulls/12")
})
t.Run("PullRequestReviewRequest", func(t *testing.T) {
@@ -258,24 +179,11 @@ func TestMSTeamsPayload(t *testing.T) {
pl, err := mc.IssueComment(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] New comment on pull request #12 Fix bug", pl.Title)
assert.Equal(t, "[test/repo] New comment on pull request #12 Fix bug", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
assert.Equal(t, "changes requested", pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 2)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL), fact.Value)
} else if fact.Name == "Issue #:" {
assert.Equal(t, "12", fact.Value)
} else {
t.Fail()
}
}
assert.Len(t, pl.PotentialAction, 1)
assert.Len(t, pl.PotentialAction[0].Targets, 1)
assert.Equal(t, "http://localhost:3000/test/repo/pulls/12#issuecomment-4", pl.PotentialAction[0].Targets[0].URI)
checkPayload(t, pl, "[test/repo] New comment on pull request #12 Fix bug", "changes requested", map[string]string{
"Repository:": fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL),
"Issue #:": "12",
})
checkAction(t, pl, "http://localhost:3000/test/repo/pulls/12#issuecomment-4")
})
t.Run("Review", func(t *testing.T) {
@@ -285,24 +193,11 @@ func TestMSTeamsPayload(t *testing.T) {
pl, err := mc.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Pull request review approved: #12 Fix bug", pl.Title)
assert.Equal(t, "[test/repo] Pull request review approved: #12 Fix bug", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
assert.Equal(t, "good job", pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 2)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL), fact.Value)
} else if fact.Name == "Pull request:" {
assert.Equal(t, fmt.Sprintf("[#%d](%s)", p.PullRequest.Index, p.PullRequest.HTMLURL), fact.Value)
} else {
t.Fail()
}
}
assert.Len(t, pl.PotentialAction, 1)
assert.Len(t, pl.PotentialAction[0].Targets, 1)
assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", pl.PotentialAction[0].Targets[0].URI)
checkPayload(t, pl, "[test/repo] Pull request review approved: #12 Fix bug", "good job", map[string]string{
"Repository:": fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL),
"Pull request:": fmt.Sprintf("[#%d](%s)", p.PullRequest.Index, p.PullRequest.HTMLURL),
})
checkAction(t, pl, "http://localhost:3000/test/repo/pulls/12")
})
t.Run("Repository", func(t *testing.T) {
@@ -311,22 +206,10 @@ func TestMSTeamsPayload(t *testing.T) {
pl, err := mc.Repository(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Repository created", pl.Title)
assert.Equal(t, "[test/repo] Repository created", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
assert.Empty(t, pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 1)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL), fact.Value)
} else {
t.Fail()
}
}
assert.Len(t, pl.PotentialAction, 1)
assert.Len(t, pl.PotentialAction[0].Targets, 1)
assert.Equal(t, "http://localhost:3000/test/repo", pl.PotentialAction[0].Targets[0].URI)
checkPayload(t, pl, "[test/repo] Repository created", "", map[string]string{
"Repository:": fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL),
})
checkAction(t, pl, "http://localhost:3000/test/repo")
})
t.Run("Package", func(t *testing.T) {
@@ -335,22 +218,10 @@ func TestMSTeamsPayload(t *testing.T) {
pl, err := mc.Package(p)
require.NoError(t, err)
assert.Equal(t, "Package created: GiteaContainer:latest", pl.Title)
assert.Equal(t, "Package created: GiteaContainer:latest", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
assert.Empty(t, pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 1)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Package:" {
assert.Equal(t, p.Package.Name, fact.Value)
} else {
t.Fail()
}
}
assert.Len(t, pl.PotentialAction, 1)
assert.Len(t, pl.PotentialAction[0].Targets, 1)
assert.Equal(t, "http://localhost:3000/user1/-/packages/container/GiteaContainer/latest", pl.PotentialAction[0].Targets[0].URI)
checkPayload(t, pl, "Package created: GiteaContainer:latest", "", map[string]string{
"Package:": p.Package.Name,
})
checkAction(t, pl, "http://localhost:3000/user1/-/packages/container/GiteaContainer/latest")
})
t.Run("Wiki", func(t *testing.T) {
@@ -360,61 +231,27 @@ func TestMSTeamsPayload(t *testing.T) {
pl, err := mc.Wiki(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment)", pl.Title)
assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment)", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
assert.Empty(t, pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 1)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL), fact.Value)
} else {
t.Fail()
}
}
checkPayload(t, pl, "[test/repo] New wiki page 'index' (Wiki change comment)", "", map[string]string{
"Repository:": fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL),
})
p.Action = api.HookWikiEdited
pl, err = mc.Wiki(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment)", pl.Title)
assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment)", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
assert.Empty(t, pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 1)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL), fact.Value)
} else {
t.Fail()
}
}
assert.Len(t, pl.PotentialAction, 1)
assert.Len(t, pl.PotentialAction[0].Targets, 1)
assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.PotentialAction[0].Targets[0].URI)
checkPayload(t, pl, "[test/repo] Wiki page 'index' edited (Wiki change comment)", "", map[string]string{
"Repository:": fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL),
})
checkAction(t, pl, "http://localhost:3000/test/repo/wiki/index")
p.Action = api.HookWikiDeleted
pl, err = mc.Wiki(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Wiki page 'index' deleted", pl.Title)
assert.Equal(t, "[test/repo] Wiki page 'index' deleted", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
assert.Empty(t, pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 1)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL), fact.Value)
} else {
t.Fail()
}
}
assert.Len(t, pl.PotentialAction, 1)
assert.Len(t, pl.PotentialAction[0].Targets, 1)
assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.PotentialAction[0].Targets[0].URI)
checkPayload(t, pl, "[test/repo] Wiki page 'index' deleted", "", map[string]string{
"Repository:": fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL),
})
checkAction(t, pl, "http://localhost:3000/test/repo/wiki/index")
})
t.Run("Release", func(t *testing.T) {
@@ -423,24 +260,11 @@ func TestMSTeamsPayload(t *testing.T) {
pl, err := mc.Release(p)
require.NoError(t, err)
assert.Equal(t, "[test/repo] Release created: v1.0", pl.Title)
assert.Equal(t, "[test/repo] Release created: v1.0", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
assert.Empty(t, pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 2)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL), fact.Value)
} else if fact.Name == "Tag:" {
assert.Equal(t, "v1.0", fact.Value)
} else {
t.Fail()
}
}
assert.Len(t, pl.PotentialAction, 1)
assert.Len(t, pl.PotentialAction[0].Targets, 1)
assert.Equal(t, "http://localhost:3000/test/repo/releases/tag/v1.0", pl.PotentialAction[0].Targets[0].URI)
checkPayload(t, pl, "[test/repo] Release created: v1.0", "", map[string]string{
"Repository:": fmt.Sprintf("[%s](%s)", p.Repository.FullName, p.Repository.HTMLURL),
"Tag:": "v1.0",
})
checkAction(t, pl, "http://localhost:3000/test/repo/releases/tag/v1.0")
})
}
+80 -170
View File
@@ -19,29 +19,31 @@ func TestPackagistPayload(t *testing.T) {
pc := packagistConvertor{
PackageURL: "https://packagist.org/packages/example",
}
t.Run("Create", func(t *testing.T) {
p := createTestPayload()
pl, err := pc.Create(p)
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
})
t.Run("Delete", func(t *testing.T) {
p := deleteTestPayload()
pl, err := pc.Delete(p)
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
})
t.Run("Fork", func(t *testing.T) {
p := forkTestPayload()
pl, err := pc.Fork(p)
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
})
for _, testCase := range []struct {
name string
call func() (PackagistPayload, error)
}{
{"Create", func() (PackagistPayload, error) { return pc.Create(createTestPayload()) }},
{"Delete", func() (PackagistPayload, error) { return pc.Delete(deleteTestPayload()) }},
{"Fork", func() (PackagistPayload, error) { return pc.Fork(forkTestPayload()) }},
{"IssueComment", func() (PackagistPayload, error) { return pc.IssueComment(issueCommentTestPayload()) }},
{"PullRequest", func() (PackagistPayload, error) { return pc.PullRequest(pullRequestTestPayload()) }},
{"PullRequestComment", func() (PackagistPayload, error) { return pc.IssueComment(pullRequestCommentTestPayload()) }},
{"Review", func() (PackagistPayload, error) {
p := pullRequestTestPayload()
p.Action = api.HookIssueReviewed
return pc.Review(p, webhook_module.HookEventPullRequestReviewApproved)
}},
{"Repository", func() (PackagistPayload, error) { return pc.Repository(repositoryTestPayload()) }},
{"Package", func() (PackagistPayload, error) { return pc.Package(packageTestPayload()) }},
{"Release", func() (PackagistPayload, error) { return pc.Release(pullReleaseTestPayload()) }},
} {
t.Run(testCase.name, func(t *testing.T) {
pl, err := testCase.call()
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
})
}
t.Run("Push", func(t *testing.T) {
p := pushTestPayload()
@@ -54,161 +56,69 @@ func TestPackagistPayload(t *testing.T) {
t.Run("Issue", func(t *testing.T) {
p := issueTestPayload()
p.Action = api.HookIssueOpened
pl, err := pc.Issue(p)
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
p.Action = api.HookIssueClosed
pl, err = pc.Issue(p)
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
})
t.Run("IssueComment", func(t *testing.T) {
p := issueCommentTestPayload()
pl, err := pc.IssueComment(p)
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
})
t.Run("PullRequest", func(t *testing.T) {
p := pullRequestTestPayload()
pl, err := pc.PullRequest(p)
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
})
t.Run("PullRequestComment", func(t *testing.T) {
p := pullRequestCommentTestPayload()
pl, err := pc.IssueComment(p)
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
})
t.Run("Review", func(t *testing.T) {
p := pullRequestTestPayload()
p.Action = api.HookIssueReviewed
pl, err := pc.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
})
t.Run("Repository", func(t *testing.T) {
p := repositoryTestPayload()
pl, err := pc.Repository(p)
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
})
t.Run("Package", func(t *testing.T) {
p := packageTestPayload()
pl, err := pc.Package(p)
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
for _, action := range []api.HookIssueAction{api.HookIssueOpened, api.HookIssueClosed} {
p.Action = action
pl, err := pc.Issue(p)
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
}
})
t.Run("Wiki", func(t *testing.T) {
p := wikiTestPayload()
p.Action = api.HookWikiCreated
pl, err := pc.Wiki(p)
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
p.Action = api.HookWikiEdited
pl, err = pc.Wiki(p)
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
p.Action = api.HookWikiDeleted
pl, err = pc.Wiki(p)
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
})
t.Run("Release", func(t *testing.T) {
p := pullReleaseTestPayload()
pl, err := pc.Release(p)
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
for _, action := range []api.HookWikiAction{api.HookWikiCreated, api.HookWikiEdited, api.HookWikiDeleted} {
p.Action = action
pl, err := pc.Wiki(p)
require.NoError(t, err)
require.Equal(t, PackagistPayload{}, pl)
}
})
}
func TestPackagistJSONPayload(t *testing.T) {
p := pushTestPayload()
data, err := p.JSONPayload()
require.NoError(t, err)
for _, testCase := range []struct {
event webhook_module.HookEventType
payload func() api.Payloader
}{
{webhook_module.HookEventPush, func() api.Payloader { return pushTestPayload() }},
{webhook_module.HookEventCreate, func() api.Payloader { return createTestPayload() }},
} {
t.Run(string(testCase.event), func(t *testing.T) {
data, err := testCase.payload().JSONPayload()
require.NoError(t, err)
hook := &webhook_model.Webhook{
RepoID: 3,
IsActive: true,
Type: webhook_module.PACKAGIST,
URL: "https://packagist.org/api/update-package?username=THEUSERNAME&apiToken=TOPSECRETAPITOKEN",
Meta: `{"package_url":"https://packagist.org/packages/example"}`,
HTTPMethod: "POST",
hook := &webhook_model.Webhook{
RepoID: 3,
IsActive: true,
Type: webhook_module.PACKAGIST,
URL: "https://packagist.org/api/update-package?username=THEUSERNAME&apiToken=TOPSECRETAPITOKEN",
Meta: `{"package_url":"https://packagist.org/packages/example"}`,
HTTPMethod: "POST",
}
task := &webhook_model.HookTask{
HookID: hook.ID,
EventType: testCase.event,
PayloadContent: string(data),
PayloadVersion: 2,
}
req, reqBody, err := newPackagistRequest(t.Context(), hook, task)
require.NotNil(t, req)
require.NotNil(t, reqBody)
require.NoError(t, err)
assert.Equal(t, "POST", req.Method)
assert.Equal(t, "https://packagist.org/api/update-package?username=THEUSERNAME&apiToken=TOPSECRETAPITOKEN", req.URL.String())
assert.Equal(t, "sha256=", req.Header.Get("X-Hub-Signature-256"))
assert.Equal(t, "application/json", req.Header.Get("Content-Type"))
var body PackagistPayload
err = json.NewDecoder(req.Body).Decode(&body)
assert.NoError(t, err)
if testCase.event == webhook_module.HookEventPush {
assert.Equal(t, "https://packagist.org/packages/example", body.PackagistRepository.URL)
} else {
assert.Empty(t, body.PackagistRepository.URL)
}
})
}
task := &webhook_model.HookTask{
HookID: hook.ID,
EventType: webhook_module.HookEventPush,
PayloadContent: string(data),
PayloadVersion: 2,
}
req, reqBody, err := newPackagistRequest(t.Context(), hook, task)
require.NotNil(t, req)
require.NotNil(t, reqBody)
require.NoError(t, err)
assert.Equal(t, "POST", req.Method)
assert.Equal(t, "https://packagist.org/api/update-package?username=THEUSERNAME&apiToken=TOPSECRETAPITOKEN", req.URL.String())
assert.Equal(t, "sha256=", req.Header.Get("X-Hub-Signature-256"))
assert.Equal(t, "application/json", req.Header.Get("Content-Type"))
var body PackagistPayload
err = json.NewDecoder(req.Body).Decode(&body)
assert.NoError(t, err)
assert.Equal(t, "https://packagist.org/packages/example", body.PackagistRepository.URL)
}
func TestPackagistEmptyPayload(t *testing.T) {
p := createTestPayload()
data, err := p.JSONPayload()
require.NoError(t, err)
hook := &webhook_model.Webhook{
RepoID: 3,
IsActive: true,
Type: webhook_module.PACKAGIST,
URL: "https://packagist.org/api/update-package?username=THEUSERNAME&apiToken=TOPSECRETAPITOKEN",
Meta: `{"package_url":"https://packagist.org/packages/example"}`,
HTTPMethod: "POST",
}
task := &webhook_model.HookTask{
HookID: hook.ID,
EventType: webhook_module.HookEventCreate,
PayloadContent: string(data),
PayloadVersion: 2,
}
req, reqBody, err := newPackagistRequest(t.Context(), hook, task)
require.NotNil(t, req)
require.NotNil(t, reqBody)
require.NoError(t, err)
assert.Equal(t, "POST", req.Method)
assert.Equal(t, "https://packagist.org/api/update-package?username=THEUSERNAME&apiToken=TOPSECRETAPITOKEN", req.URL.String())
assert.Equal(t, "sha256=", req.Header.Get("X-Hub-Signature-256"))
assert.Equal(t, "application/json", req.Header.Get("Content-Type"))
var body PackagistPayload
err = json.NewDecoder(req.Body).Decode(&body)
assert.NoError(t, err)
assert.Empty(t, body.PackagistRepository.URL)
}
+76 -120
View File
@@ -18,45 +18,69 @@ import (
func TestSlackPayload(t *testing.T) {
sc := slackConvertor{}
t.Run("Create", func(t *testing.T) {
p := createTestPayload()
pl, err := sc.Create(p)
require.NoError(t, err)
assert.Equal(t, "[<http://localhost:3000/test/repo|test/repo>:<http://localhost:3000/test/repo/src/branch/test|test>] branch created by user1", pl.Text)
})
t.Run("Delete", func(t *testing.T) {
p := deleteTestPayload()
pl, err := sc.Delete(p)
require.NoError(t, err)
assert.Equal(t, "[<http://localhost:3000/test/repo|test/repo>:test] branch deleted by user1", pl.Text)
})
t.Run("Fork", func(t *testing.T) {
p := forkTestPayload()
pl, err := sc.Fork(p)
require.NoError(t, err)
assert.Equal(t, "<http://localhost:3000/test/repo2|test/repo2> is forked to <http://localhost:3000/test/repo|test/repo>", pl.Text)
})
t.Run("Push", func(t *testing.T) {
p := pushTestPayload()
pl, err := sc.Push(p)
require.NoError(t, err)
assert.Equal(t, "[<http://localhost:3000/test/repo|test/repo>:<http://localhost:3000/test/repo/src/branch/test|test>] 2 new commits pushed by user1", pl.Text)
require.Len(t, pl.Attachments, 1)
assert.Equal(t, "user1", pl.Attachments[0].AuthorName)
assert.Equal(t, "http://localhost:3000/user1/avatar", pl.Attachments[0].AuthorIcon)
assert.Equal(t, "http://localhost:3000/user1", pl.Attachments[0].AuthorLink)
})
for _, testCase := range []struct {
name string
call func() (SlackPayload, error)
text string
attachments bool
}{
{
"Create", func() (SlackPayload, error) { return sc.Create(createTestPayload()) },
"[<http://localhost:3000/test/repo|test/repo>:<http://localhost:3000/test/repo/src/branch/test|test>] branch created by user1", false,
},
{
"Delete", func() (SlackPayload, error) { return sc.Delete(deleteTestPayload()) },
"[<http://localhost:3000/test/repo|test/repo>:test] branch deleted by user1", false,
},
{
"Fork", func() (SlackPayload, error) { return sc.Fork(forkTestPayload()) },
"<http://localhost:3000/test/repo2|test/repo2> is forked to <http://localhost:3000/test/repo|test/repo>", false,
},
{
"Push", func() (SlackPayload, error) { return sc.Push(pushTestPayload()) },
"[<http://localhost:3000/test/repo|test/repo>:<http://localhost:3000/test/repo/src/branch/test|test>] 2 new commits pushed by user1", true,
},
{
"IssueComment", func() (SlackPayload, error) { return sc.IssueComment(issueCommentTestPayload()) },
"[<http://localhost:3000/test/repo|test/repo>] New comment on issue <http://localhost:3000/test/repo/issues/2|#2 crash> by <https://try.gitea.io/user1|user1>", true,
},
{
"PullRequest", func() (SlackPayload, error) { return sc.PullRequest(pullRequestTestPayload()) },
"[<http://localhost:3000/test/repo|test/repo>] Pull request opened: <http://localhost:3000/test/repo/pulls/12|#12 Fix bug> by <https://try.gitea.io/user1|user1>", true,
},
{
"PullRequestComment", func() (SlackPayload, error) { return sc.IssueComment(pullRequestCommentTestPayload()) },
"[<http://localhost:3000/test/repo|test/repo>] New comment on pull request <http://localhost:3000/test/repo/pulls/12|#12 Fix bug> by <https://try.gitea.io/user1|user1>", false,
},
{
"Review", func() (SlackPayload, error) {
p := pullRequestTestPayload()
p.Action = api.HookIssueReviewed
return sc.Review(p, webhook_module.HookEventPullRequestReviewApproved)
},
"[<http://localhost:3000/test/repo|test/repo>] Pull request review approved: [#12 Fix bug](http://localhost:3000/test/repo/pulls/12) by <https://try.gitea.io/user1|user1>", false,
},
{
"Package", func() (SlackPayload, error) { return sc.Package(packageTestPayload()) },
"Package created: <http://localhost:3000/user1/-/packages/container/GiteaContainer/latest|GiteaContainer:latest> by <https://try.gitea.io/user1|user1>", false,
},
{
"Release", func() (SlackPayload, error) { return sc.Release(pullReleaseTestPayload()) },
"[<http://localhost:3000/test/repo|test/repo>] Release created: <http://localhost:3000/test/repo/releases/tag/v1.0|v1.0> by <https://try.gitea.io/user1|user1>", false,
},
} {
t.Run(testCase.name, func(t *testing.T) {
pl, err := testCase.call()
require.NoError(t, err)
assert.Equal(t, testCase.text, pl.Text)
if testCase.attachments {
require.Len(t, pl.Attachments, 1)
assert.Equal(t, "user1", pl.Attachments[0].AuthorName)
assert.Equal(t, "http://localhost:3000/user1/avatar", pl.Attachments[0].AuthorIcon)
assert.Equal(t, "http://localhost:3000/user1", pl.Attachments[0].AuthorLink)
}
})
}
t.Run("Issue", func(t *testing.T) {
p := issueTestPayload()
@@ -78,51 +102,6 @@ func TestSlackPayload(t *testing.T) {
assert.Equal(t, "[<http://localhost:3000/test/repo|test/repo>] Issue closed: <http://localhost:3000/test/repo/issues/2|#2 crash> by <https://try.gitea.io/user1|user1>", pl.Text)
})
t.Run("IssueComment", func(t *testing.T) {
p := issueCommentTestPayload()
pl, err := sc.IssueComment(p)
require.NoError(t, err)
assert.Equal(t, "[<http://localhost:3000/test/repo|test/repo>] New comment on issue <http://localhost:3000/test/repo/issues/2|#2 crash> by <https://try.gitea.io/user1|user1>", pl.Text)
require.Len(t, pl.Attachments, 1)
assert.Equal(t, "user1", pl.Attachments[0].AuthorName)
assert.Equal(t, "http://localhost:3000/user1/avatar", pl.Attachments[0].AuthorIcon)
assert.Equal(t, "http://localhost:3000/user1", pl.Attachments[0].AuthorLink)
})
t.Run("PullRequest", func(t *testing.T) {
p := pullRequestTestPayload()
pl, err := sc.PullRequest(p)
require.NoError(t, err)
assert.Equal(t, "[<http://localhost:3000/test/repo|test/repo>] Pull request opened: <http://localhost:3000/test/repo/pulls/12|#12 Fix bug> by <https://try.gitea.io/user1|user1>", pl.Text)
require.Len(t, pl.Attachments, 1)
assert.Equal(t, "user1", pl.Attachments[0].AuthorName)
assert.Equal(t, "http://localhost:3000/user1/avatar", pl.Attachments[0].AuthorIcon)
assert.Equal(t, "http://localhost:3000/user1", pl.Attachments[0].AuthorLink)
})
t.Run("PullRequestComment", func(t *testing.T) {
p := pullRequestCommentTestPayload()
pl, err := sc.IssueComment(p)
require.NoError(t, err)
assert.Equal(t, "[<http://localhost:3000/test/repo|test/repo>] New comment on pull request <http://localhost:3000/test/repo/pulls/12|#12 Fix bug> by <https://try.gitea.io/user1|user1>", pl.Text)
})
t.Run("Review", func(t *testing.T) {
p := pullRequestTestPayload()
p.Action = api.HookIssueReviewed
pl, err := sc.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err)
assert.Equal(t, "[<http://localhost:3000/test/repo|test/repo>] Pull request review approved: [#12 Fix bug](http://localhost:3000/test/repo/pulls/12) by <https://try.gitea.io/user1|user1>", pl.Text)
})
t.Run("Repository", func(t *testing.T) {
p := repositoryTestPayload()
@@ -138,44 +117,21 @@ func TestSlackPayload(t *testing.T) {
assert.Equal(t, "[<http://localhost:3000/test/repo|test/repo>] Repository renamed from old-repo by <https://try.gitea.io/user1|user1>", pl.Text)
})
t.Run("Package", func(t *testing.T) {
p := packageTestPayload()
pl, err := sc.Package(p)
require.NoError(t, err)
assert.Equal(t, "Package created: <http://localhost:3000/user1/-/packages/container/GiteaContainer/latest|GiteaContainer:latest> by <https://try.gitea.io/user1|user1>", pl.Text)
})
t.Run("Wiki", func(t *testing.T) {
p := wikiTestPayload()
p.Action = api.HookWikiCreated
pl, err := sc.Wiki(p)
require.NoError(t, err)
assert.Equal(t, "[<http://localhost:3000/test/repo|test/repo>] New wiki page '<http://localhost:3000/test/repo/wiki/index|index>' (Wiki change comment) by <https://try.gitea.io/user1|user1>", pl.Text)
p.Action = api.HookWikiEdited
pl, err = sc.Wiki(p)
require.NoError(t, err)
assert.Equal(t, "[<http://localhost:3000/test/repo|test/repo>] Wiki page '<http://localhost:3000/test/repo/wiki/index|index>' edited (Wiki change comment) by <https://try.gitea.io/user1|user1>", pl.Text)
p.Action = api.HookWikiDeleted
pl, err = sc.Wiki(p)
require.NoError(t, err)
assert.Equal(t, "[<http://localhost:3000/test/repo|test/repo>] Wiki page '<http://localhost:3000/test/repo/wiki/index|index>' deleted by <https://try.gitea.io/user1|user1>", pl.Text)
})
t.Run("Release", func(t *testing.T) {
p := pullReleaseTestPayload()
pl, err := sc.Release(p)
require.NoError(t, err)
assert.Equal(t, "[<http://localhost:3000/test/repo|test/repo>] Release created: <http://localhost:3000/test/repo/releases/tag/v1.0|v1.0> by <https://try.gitea.io/user1|user1>", pl.Text)
for _, testCase := range []struct {
action api.HookWikiAction
text string
}{
{api.HookWikiCreated, "[<http://localhost:3000/test/repo|test/repo>] New wiki page '<http://localhost:3000/test/repo/wiki/index|index>' (Wiki change comment) by <https://try.gitea.io/user1|user1>"},
{api.HookWikiEdited, "[<http://localhost:3000/test/repo|test/repo>] Wiki page '<http://localhost:3000/test/repo/wiki/index|index>' edited (Wiki change comment) by <https://try.gitea.io/user1|user1>"},
{api.HookWikiDeleted, "[<http://localhost:3000/test/repo|test/repo>] Wiki page '<http://localhost:3000/test/repo/wiki/index|index>' deleted by <https://try.gitea.io/user1|user1>"},
} {
p.Action = testCase.action
pl, err := sc.Wiki(p)
require.NoError(t, err)
assert.Equal(t, testCase.text, pl.Text)
}
})
}
+85 -129
View File
@@ -33,142 +33,98 @@ func TestTelegramPayload(t *testing.T) {
assert.Equal(t, "first line<br>second line<br>third line", p.RichMessage.HTML)
})
t.Run("Create", func(t *testing.T) {
p := createTestPayload()
pl, err := tc.Create(p)
require.NoError(t, err)
assert.Equal(t, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] branch <a href="http://localhost:3000/test/repo/src/test" rel="nofollow">test</a> created`, pl.RichMessage.HTML)
})
t.Run("Delete", func(t *testing.T) {
p := deleteTestPayload()
pl, err := tc.Delete(p)
require.NoError(t, err)
assert.Equal(t, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] branch <a href="http://localhost:3000/test/repo/src/test" rel="nofollow">test</a> deleted`, pl.RichMessage.HTML)
})
t.Run("Fork", func(t *testing.T) {
p := forkTestPayload()
pl, err := tc.Fork(p)
require.NoError(t, err)
assert.Equal(t, `test/repo2 is forked to <a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>`, pl.RichMessage.HTML)
})
t.Run("Push", func(t *testing.T) {
p := pushTestPayload()
pl, err := tc.Push(p)
require.NoError(t, err)
assert.Equal(t, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>:<a href="http://localhost:3000/test/repo/src/test" rel="nofollow">test</a>] 2 new commits<br>[<a href="http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778" rel="nofollow">2020558</a>] commit message - user1<br>[<a href="http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778" rel="nofollow">2020558</a>] commit message - user1`, pl.RichMessage.HTML)
})
for _, testCase := range []struct {
name string
call func() (TelegramPayload, error)
text string
}{
{
"Create", func() (TelegramPayload, error) { return tc.Create(createTestPayload()) },
`[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] branch <a href="http://localhost:3000/test/repo/src/test" rel="nofollow">test</a> created`,
},
{
"Delete", func() (TelegramPayload, error) { return tc.Delete(deleteTestPayload()) },
`[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] branch <a href="http://localhost:3000/test/repo/src/test" rel="nofollow">test</a> deleted`,
},
{
"Fork", func() (TelegramPayload, error) { return tc.Fork(forkTestPayload()) },
`test/repo2 is forked to <a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>`,
},
{
"Push", func() (TelegramPayload, error) { return tc.Push(pushTestPayload()) },
`[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>:<a href="http://localhost:3000/test/repo/src/test" rel="nofollow">test</a>] 2 new commits<br>[<a href="http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778" rel="nofollow">2020558</a>] commit message - user1<br>[<a href="http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778" rel="nofollow">2020558</a>] commit message - user1`,
},
{
"IssueComment", func() (TelegramPayload, error) { return tc.IssueComment(issueCommentTestPayload()) },
`[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] New comment on issue <a href="http://localhost:3000/test/repo/issues/2" rel="nofollow">#2 crash</a> by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a><br>more info needed`,
},
{
"PullRequest", func() (TelegramPayload, error) { return tc.PullRequest(pullRequestTestPayload()) },
`[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] Pull request opened: <a href="http://localhost:3000/test/repo/pulls/12" rel="nofollow">#12 Fix bug</a> by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a><br>fixes bug #2`,
},
{
"PullRequestComment", func() (TelegramPayload, error) { return tc.IssueComment(pullRequestCommentTestPayload()) },
`[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] New comment on pull request <a href="http://localhost:3000/test/repo/pulls/12" rel="nofollow">#12 Fix bug</a> by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a><br>changes requested`,
},
{
"Review", func() (TelegramPayload, error) {
p := pullRequestTestPayload()
p.Action = api.HookIssueReviewed
return tc.Review(p, webhook_module.HookEventPullRequestReviewApproved)
},
`[test/repo] Pull request review approved: #12 Fix bug<br>good job`,
},
{
"Repository", func() (TelegramPayload, error) { return tc.Repository(repositoryTestPayload()) },
`[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] Repository created`,
},
{
"Package", func() (TelegramPayload, error) { return tc.Package(packageTestPayload()) },
`Package created: <a href="http://localhost:3000/user1/-/packages/container/GiteaContainer/latest" rel="nofollow">GiteaContainer:latest</a> by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a>`,
},
{
"Release", func() (TelegramPayload, error) { return tc.Release(pullReleaseTestPayload()) },
`[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] Release created: <a href="http://localhost:3000/test/repo/releases/tag/v1.0" rel="nofollow">v1.0</a> by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a>`,
},
} {
t.Run(testCase.name, func(t *testing.T) {
pl, err := testCase.call()
require.NoError(t, err)
assert.Equal(t, testCase.text, pl.RichMessage.HTML)
})
}
t.Run("Issue", func(t *testing.T) {
p := issueTestPayload()
p.Action = api.HookIssueOpened
pl, err := tc.Issue(p)
require.NoError(t, err)
assert.Equal(t, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] Issue opened: <a href="http://localhost:3000/test/repo/issues/2" rel="nofollow">#2 crash</a> by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a><br><br>issue body`, pl.RichMessage.HTML)
p.Action = api.HookIssueClosed
pl, err = tc.Issue(p)
require.NoError(t, err)
assert.Equal(t, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] Issue closed: <a href="http://localhost:3000/test/repo/issues/2" rel="nofollow">#2 crash</a> by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a>`, pl.RichMessage.HTML)
})
t.Run("IssueComment", func(t *testing.T) {
p := issueCommentTestPayload()
pl, err := tc.IssueComment(p)
require.NoError(t, err)
assert.Equal(t, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] New comment on issue <a href="http://localhost:3000/test/repo/issues/2" rel="nofollow">#2 crash</a> by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a><br>more info needed`, pl.RichMessage.HTML)
})
t.Run("PullRequest", func(t *testing.T) {
p := pullRequestTestPayload()
pl, err := tc.PullRequest(p)
require.NoError(t, err)
assert.Equal(t, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] Pull request opened: <a href="http://localhost:3000/test/repo/pulls/12" rel="nofollow">#12 Fix bug</a> by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a><br>fixes bug #2`, pl.RichMessage.HTML)
})
t.Run("PullRequestComment", func(t *testing.T) {
p := pullRequestCommentTestPayload()
pl, err := tc.IssueComment(p)
require.NoError(t, err)
assert.Equal(t, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] New comment on pull request <a href="http://localhost:3000/test/repo/pulls/12" rel="nofollow">#12 Fix bug</a> by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a><br>changes requested`, pl.RichMessage.HTML)
})
t.Run("Review", func(t *testing.T) {
p := pullRequestTestPayload()
p.Action = api.HookIssueReviewed
pl, err := tc.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err)
assert.Equal(t, `[test/repo] Pull request review approved: #12 Fix bug<br>good job`, pl.RichMessage.HTML)
})
t.Run("Repository", func(t *testing.T) {
p := repositoryTestPayload()
pl, err := tc.Repository(p)
require.NoError(t, err)
assert.Equal(t, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] Repository created`, pl.RichMessage.HTML)
})
t.Run("Package", func(t *testing.T) {
p := packageTestPayload()
pl, err := tc.Package(p)
require.NoError(t, err)
assert.Equal(t, `Package created: <a href="http://localhost:3000/user1/-/packages/container/GiteaContainer/latest" rel="nofollow">GiteaContainer:latest</a> by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a>`, pl.RichMessage.HTML)
for _, testCase := range []struct {
action api.HookIssueAction
text string
}{
{api.HookIssueOpened, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] Issue opened: <a href="http://localhost:3000/test/repo/issues/2" rel="nofollow">#2 crash</a> by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a><br><br>issue body`},
{api.HookIssueClosed, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] Issue closed: <a href="http://localhost:3000/test/repo/issues/2" rel="nofollow">#2 crash</a> by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a>`},
} {
p.Action = testCase.action
pl, err := tc.Issue(p)
require.NoError(t, err)
assert.Equal(t, testCase.text, pl.RichMessage.HTML)
}
})
t.Run("Wiki", func(t *testing.T) {
p := wikiTestPayload()
p.Action = api.HookWikiCreated
pl, err := tc.Wiki(p)
require.NoError(t, err)
assert.Equal(t, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] New wiki page &#39;<a href="http://localhost:3000/test/repo/wiki/index" rel="nofollow">index</a>&#39; (Wiki change comment) by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a>`, pl.RichMessage.HTML)
p.Action = api.HookWikiEdited
pl, err = tc.Wiki(p)
require.NoError(t, err)
assert.Equal(t, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] Wiki page &#39;<a href="http://localhost:3000/test/repo/wiki/index" rel="nofollow">index</a>&#39; edited (Wiki change comment) by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a>`, pl.RichMessage.HTML)
p.Action = api.HookWikiDeleted
pl, err = tc.Wiki(p)
require.NoError(t, err)
assert.Equal(t, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] Wiki page &#39;<a href="http://localhost:3000/test/repo/wiki/index" rel="nofollow">index</a>&#39; deleted by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a>`, pl.RichMessage.HTML)
})
t.Run("Release", func(t *testing.T) {
p := pullReleaseTestPayload()
pl, err := tc.Release(p)
require.NoError(t, err)
assert.Equal(t, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] Release created: <a href="http://localhost:3000/test/repo/releases/tag/v1.0" rel="nofollow">v1.0</a> by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a>`, pl.RichMessage.HTML)
for _, testCase := range []struct {
action api.HookWikiAction
text string
}{
{api.HookWikiCreated, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] New wiki page &#39;<a href="http://localhost:3000/test/repo/wiki/index" rel="nofollow">index</a>&#39; (Wiki change comment) by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a>`},
{api.HookWikiEdited, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] Wiki page &#39;<a href="http://localhost:3000/test/repo/wiki/index" rel="nofollow">index</a>&#39; edited (Wiki change comment) by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a>`},
{api.HookWikiDeleted, `[<a href="http://localhost:3000/test/repo" rel="nofollow">test/repo</a>] Wiki page &#39;<a href="http://localhost:3000/test/repo/wiki/index" rel="nofollow">index</a>&#39; deleted by <a href="https://try.gitea.io/user1" rel="nofollow">user1</a>`},
} {
p.Action = testCase.action
pl, err := tc.Wiki(p)
require.NoError(t, err)
assert.Equal(t, testCase.text, pl.RichMessage.HTML)
}
})
}