Merge pull request '[v7.0/forgejo] Show repo activities even if only code unit active or git repo is empty but issue is active' (#3514) from bp-v7.0/forgejo-c54896b into v7.0/forgejo

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3514
Reviewed-by: Otto <otto@codeberg.org>
Reviewed-by: Beowulf <beowulf@beocode.eu>
This commit is contained in:
Otto 2024-04-29 21:41:09 +00:00
commit 54f875df46
5 changed files with 137 additions and 9 deletions

View file

@ -57,7 +57,7 @@ func Activity(ctx *context.Context) {
ctx.Repo.CanRead(unit.TypeReleases), ctx.Repo.CanRead(unit.TypeReleases),
ctx.Repo.CanRead(unit.TypeIssues), ctx.Repo.CanRead(unit.TypeIssues),
ctx.Repo.CanRead(unit.TypePullRequests), ctx.Repo.CanRead(unit.TypePullRequests),
ctx.Repo.CanRead(unit.TypeCode)); err != nil { ctx.Repo.CanRead(unit.TypeCode) && !ctx.Repo.Repository.IsEmpty); err != nil {
ctx.ServerError("GetActivityStats", err) ctx.ServerError("GetActivityStats", err)
return return
} }

View file

@ -1423,16 +1423,16 @@ func registerRoutes(m *web.Route) {
m.Group("/contributors", func() { m.Group("/contributors", func() {
m.Get("", repo.Contributors) m.Get("", repo.Contributors)
m.Get("/data", repo.ContributorsData) m.Get("/data", repo.ContributorsData)
}) }, repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypeCode))
m.Group("/code-frequency", func() { m.Group("/code-frequency", func() {
m.Get("", repo.CodeFrequency) m.Get("", repo.CodeFrequency)
m.Get("/data", repo.CodeFrequencyData) m.Get("/data", repo.CodeFrequencyData)
}) }, repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypeCode))
m.Group("/recent-commits", func() { m.Group("/recent-commits", func() {
m.Get("", repo.RecentCommits) m.Get("", repo.RecentCommits)
m.Get("/data", repo.RecentCommitsData) m.Get("/data", repo.RecentCommitsData)
}) }, repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypeCode))
}, context.RepoRef(), repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypePullRequests, unit.TypeIssues, unit.TypeReleases)) }, context.RepoRef(), context.RequireRepoReaderOr(unit.TypeCode, unit.TypePullRequests, unit.TypeIssues, unit.TypeReleases))
m.Group("/activity_author_data", func() { m.Group("/activity_author_data", func() {
m.Get("", repo.ActivityAuthors) m.Get("", repo.ActivityAuthors)

View file

@ -2,9 +2,11 @@
<div role="main" aria-label="{{.Title}}" class="page-content repository commits"> <div role="main" aria-label="{{.Title}}" class="page-content repository commits">
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="ui container flex-container"> <div class="ui container flex-container">
<div class="flex-container-nav"> {{if and (not .IsEmptyRepo) (.Permission.CanRead $.UnitTypeCode)}}
{{template "repo/navbar" .}} <div class="flex-container-nav">
</div> {{template "repo/navbar" .}}
</div>
{{end}}
<div class="flex-container-main"> <div class="flex-container-main">
{{if .PageIsPulse}}{{template "repo/pulse" .}}{{end}} {{if .PageIsPulse}}{{template "repo/pulse" .}}{{end}}
{{if .PageIsContributors}}{{template "repo/contributors" .}}{{end}} {{if .PageIsContributors}}{{template "repo/contributors" .}}{{end}}

View file

@ -159,7 +159,7 @@
</a> </a>
{{end}} {{end}}
{{if and (.Permission.CanReadAny $.UnitTypePullRequests $.UnitTypeIssues $.UnitTypeReleases) (not .IsEmptyRepo)}} {{if and (.Permission.CanReadAny $.UnitTypeCode $.UnitTypePullRequests $.UnitTypeIssues $.UnitTypeReleases)}}
<a class="{{if .PageIsActivity}}active {{end}}item" href="{{.RepoLink}}/activity"> <a class="{{if .PageIsActivity}}active {{end}}item" href="{{.RepoLink}}/activity">
{{svg "octicon-pulse"}} {{ctx.Locale.Tr "repo.activity"}} {{svg "octicon-pulse"}} {{ctx.Locale.Tr "repo.activity"}}
</a> </a>

View file

@ -4,13 +4,20 @@
package integration package integration
import ( import (
"fmt"
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
"testing" "testing"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
unit_model "code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/test"
repo_service "code.gitea.io/gitea/services/repository"
"code.gitea.io/gitea/tests"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -63,3 +70,122 @@ func TestRepoActivity(t *testing.T) {
assert.Len(t, list.Nodes, 3) assert.Len(t, list.Nodes, 3)
}) })
} }
func TestRepoActivityAllUnitsDisabled(t *testing.T) {
defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"})
session := loginUser(t, user.Name)
unit_model.LoadUnitConfig()
// Create a repo, with no unit enabled.
repo, err := repo_service.CreateRepository(db.DefaultContext, user, user, repo_service.CreateRepoOptions{
Name: "empty-repo",
AutoInit: false,
})
assert.NoError(t, err)
assert.NotEmpty(t, repo)
enabledUnits := make([]repo_model.RepoUnit, 0)
disabledUnits := []unit_model.Type{unit_model.TypeCode, unit_model.TypeIssues, unit_model.TypePullRequests, unit_model.TypeReleases}
err = repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, enabledUnits, disabledUnits)
assert.NoError(t, err)
req := NewRequest(t, "GET", fmt.Sprintf("%s/activity", repo.Link()))
session.MakeRequest(t, req, http.StatusNotFound)
req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/contributors", repo.Link()))
session.MakeRequest(t, req, http.StatusNotFound)
req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/code-frequency", repo.Link()))
session.MakeRequest(t, req, http.StatusNotFound)
req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/recent-commits", repo.Link()))
session.MakeRequest(t, req, http.StatusNotFound)
}
func TestRepoActivityOnlyCodeUnitWithEmptyRepo(t *testing.T) {
defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"})
session := loginUser(t, user.Name)
unit_model.LoadUnitConfig()
// Create a empty repo, with only code unit enabled.
repo, err := repo_service.CreateRepository(db.DefaultContext, user, user, repo_service.CreateRepoOptions{
Name: "empty-repo",
AutoInit: false,
})
assert.NoError(t, err)
assert.NotEmpty(t, repo)
enabledUnits := make([]repo_model.RepoUnit, 1)
enabledUnits[0] = repo_model.RepoUnit{RepoID: repo.ID, Type: unit_model.TypeCode}
disabledUnits := []unit_model.Type{unit_model.TypeIssues, unit_model.TypePullRequests, unit_model.TypeReleases}
err = repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, enabledUnits, disabledUnits)
assert.NoError(t, err)
req := NewRequest(t, "GET", fmt.Sprintf("%s/activity", repo.Link()))
session.MakeRequest(t, req, http.StatusOK)
// Git repo empty so no activity for contributors etc
req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/contributors", repo.Link()))
session.MakeRequest(t, req, http.StatusNotFound)
req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/code-frequency", repo.Link()))
session.MakeRequest(t, req, http.StatusNotFound)
req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/recent-commits", repo.Link()))
session.MakeRequest(t, req, http.StatusNotFound)
}
func TestRepoActivityOnlyCodeUnitWithNonEmptyRepo(t *testing.T) {
defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"})
session := loginUser(t, user.Name)
unit_model.LoadUnitConfig()
// Create a repo, with only code unit enabled.
repo, _, f := CreateDeclarativeRepo(t, user, "", []unit_model.Type{unit_model.TypeCode}, nil, nil)
defer f()
req := NewRequest(t, "GET", fmt.Sprintf("%s/activity", repo.Link()))
session.MakeRequest(t, req, http.StatusOK)
// Git repo not empty so activity for contributors etc
req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/contributors", repo.Link()))
session.MakeRequest(t, req, http.StatusOK)
req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/code-frequency", repo.Link()))
session.MakeRequest(t, req, http.StatusOK)
req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/recent-commits", repo.Link()))
session.MakeRequest(t, req, http.StatusOK)
}
func TestRepoActivityOnlyIssuesUnit(t *testing.T) {
defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"})
session := loginUser(t, user.Name)
unit_model.LoadUnitConfig()
// Create a empty repo, with only code unit enabled.
repo, err := repo_service.CreateRepository(db.DefaultContext, user, user, repo_service.CreateRepoOptions{
Name: "empty-repo",
AutoInit: false,
})
assert.NoError(t, err)
assert.NotEmpty(t, repo)
enabledUnits := make([]repo_model.RepoUnit, 1)
enabledUnits[0] = repo_model.RepoUnit{RepoID: repo.ID, Type: unit_model.TypeIssues}
disabledUnits := []unit_model.Type{unit_model.TypeCode, unit_model.TypePullRequests, unit_model.TypeReleases}
err = repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, enabledUnits, disabledUnits)
assert.NoError(t, err)
req := NewRequest(t, "GET", fmt.Sprintf("%s/activity", repo.Link()))
session.MakeRequest(t, req, http.StatusOK)
// Git repo empty so no activity for contributors etc
req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/contributors", repo.Link()))
session.MakeRequest(t, req, http.StatusNotFound)
req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/code-frequency", repo.Link()))
session.MakeRequest(t, req, http.StatusNotFound)
req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/recent-commits", repo.Link()))
session.MakeRequest(t, req, http.StatusNotFound)
}