[GITEA] repo: Don't redirect the repo to external units

When displaying the repo home view, do not redirect to unit types that
can't be defaults (which, at the moment, are the external wiki and issue
tracker unit types).

If we'd redirect to those, that would mean that a repository with the
Code unit disabled, and an external issue tracker would immediately
redirect to the external issue tracker, making it harder to reach other,
non-external units of the repo.

Fixes #1965.

Signed-off-by: Gergely Nagy <forgejo@gergo.csillger.hu>
(cherry picked from commit 44078e5460)
(cherry picked from commit 1868dec2e4)
(cherry picked from commit c3a8e98870)
This commit is contained in:
Gergely Nagy 2023-12-31 17:54:43 +01:00 committed by Earl Warren
parent 7a343877f1
commit 9266b1916f
No known key found for this signature in database
GPG key ID: 0579CB2928A78A00
2 changed files with 104 additions and 1 deletions

View file

@ -732,7 +732,7 @@ func checkHomeCodeViewable(ctx *context.Context) {
} }
unit, ok := unit_model.Units[repoUnit.Type] unit, ok := unit_model.Units[repoUnit.Type]
if ok && (firstUnit == nil || !firstUnit.IsLessThan(unit)) { if ok && (firstUnit == nil || !firstUnit.IsLessThan(unit)) && repoUnit.Type.CanBeDefault() {
firstUnit = &unit firstUnit = &unit
} }
} }

View file

@ -11,8 +11,13 @@ import (
"testing" "testing"
"time" "time"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
unit_model "code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"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" "code.gitea.io/gitea/tests"
"github.com/PuerkitoBio/goquery" "github.com/PuerkitoBio/goquery"
@ -710,3 +715,101 @@ func TestCommitView(t *testing.T) {
assert.Contains(t, commitTitle, "Initial commit") assert.Contains(t, commitTitle, "Initial commit")
}) })
} }
func TestRepoHomeViewRedirect(t *testing.T) {
defer tests.PrepareTestEnv(t)()
t.Run("Code", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
req := NewRequest(t, "GET", "/user2/repo1")
resp := MakeRequest(t, req, http.StatusOK)
doc := NewHTMLParser(t, resp.Body)
l := doc.Find("#repo-desc").Length()
assert.Equal(t, 1, l)
})
t.Run("No Code redirects to Issues", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
// Disable the Code unit
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
err := repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, nil, []unit_model.Type{
unit_model.TypeCode,
})
assert.NoError(t, err)
// The repo home should redirect to the built-in issue tracker
req := NewRequest(t, "GET", "/user2/repo1")
resp := MakeRequest(t, req, http.StatusSeeOther)
redir := resp.Header().Get("Location")
assert.Equal(t, "/user2/repo1/issues", redir)
})
t.Run("No Code and ExternalTracker redirects to Pulls", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
// Replace the internal tracker with an external one
// Disable Code, Projects, Packages, and Actions
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
err := repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, []repo_model.RepoUnit{{
RepoID: repo.ID,
Type: unit_model.TypeExternalTracker,
Config: &repo_model.ExternalTrackerConfig{
ExternalTrackerURL: "https://example.com",
},
}}, []unit_model.Type{
unit_model.TypeCode,
unit_model.TypeIssues,
unit_model.TypeProjects,
unit_model.TypePackages,
unit_model.TypeActions,
})
assert.NoError(t, err)
// The repo home should redirect to pull requests
req := NewRequest(t, "GET", "/user2/repo1")
resp := MakeRequest(t, req, http.StatusSeeOther)
redir := resp.Header().Get("Location")
assert.Equal(t, "/user2/repo1/pulls", redir)
})
t.Run("Only external wiki results in 404", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
// Replace the internal wiki with an external, and disable everything
// else.
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
err := repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, []repo_model.RepoUnit{{
RepoID: repo.ID,
Type: unit_model.TypeExternalWiki,
Config: &repo_model.ExternalWikiConfig{
ExternalWikiURL: "https://example.com",
},
}}, []unit_model.Type{
unit_model.TypeCode,
unit_model.TypeIssues,
unit_model.TypeExternalTracker,
unit_model.TypeProjects,
unit_model.TypePackages,
unit_model.TypeActions,
unit_model.TypePullRequests,
unit_model.TypeReleases,
unit_model.TypeWiki,
})
assert.NoError(t, err)
// The repo home ends up being 404
req := NewRequest(t, "GET", "/user2/repo1")
req.Header.Set("Accept", "text/html")
resp := MakeRequest(t, req, http.StatusNotFound)
// The external wiki is linked to from the 404 page
doc := NewHTMLParser(t, resp.Body)
txt := strings.TrimSpace(doc.Find(`a[href="https://example.com"]`).Text())
assert.Equal(t, "Wiki", txt)
})
}