mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2026-05-13 06:20:24 +00:00
Replaced dropdowns in the navbar with JS-less ones from https://codeberg.org/forgejo/forgejo/pulls/7906. Also made some changes to the dropdown component: * fixed variable name * painted backgrounds (hover, focus) are now consistently applied to the actual interactive items (`<a>`, `<button>`), not to `<li>`. This is consistent with how backgrounds are conditionally applied to pre-selected (`.active`) items and is better, as it allows to place additional things to `<li>`... * ...`<hr>` can now be placed in some `<li>` instead of requiring splitting into multiple `<ul>`. This is simpler in code and I am guessing this should be better for a11y as screen readers can cast one continuous list instead of multiple ones. But have no hard proof that this is actually better. My main motivation was to avoid ugly mistake-prone tmpl logic where unconditional `<ul>` was getting closed and reopened inside of a condition. I should note that on mobile all items, including these dropdowns, are hidden in another dropdown, and it stays JS-dependand for now. So this PR only makes this part of the UI JS-less for desktop. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10025 Reviewed-by: Robert Wolff <mahlzahn@posteo.de> Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: 0ko <0ko@noreply.codeberg.org> Co-committed-by: 0ko <0ko@noreply.codeberg.org>
162 lines
6.2 KiB
Go
162 lines
6.2 KiB
Go
// Copyright 2025 The Forgejo Authors c/o Codeberg e.V.. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package integration
|
|
|
|
import (
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
|
|
"forgejo.org/models/unittest"
|
|
user_model "forgejo.org/models/user"
|
|
"forgejo.org/modules/setting"
|
|
"forgejo.org/modules/test"
|
|
files_service "forgejo.org/services/repository/files"
|
|
"forgejo.org/tests"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestOrgProfile(t *testing.T) {
|
|
onApplicationRun(t, func(t *testing.T, u *url.URL) {
|
|
checkReadme := func(t *testing.T, title, readmeFilename string, expectedCount int) {
|
|
t.Run(title, func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
|
|
// Prepare the test repository
|
|
org3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
|
|
|
|
var ops []*files_service.ChangeRepoFile
|
|
op := "create"
|
|
if readmeFilename != "README.md" {
|
|
ops = append(ops, &files_service.ChangeRepoFile{
|
|
Operation: "delete",
|
|
TreePath: "README.md",
|
|
})
|
|
} else {
|
|
op = "update"
|
|
}
|
|
if readmeFilename != "" {
|
|
ops = append(ops, &files_service.ChangeRepoFile{
|
|
Operation: op,
|
|
TreePath: readmeFilename,
|
|
ContentReader: strings.NewReader("# Hi!\n"),
|
|
})
|
|
}
|
|
|
|
_, _, f := tests.CreateDeclarativeRepo(t, org3, ".profile", nil, nil, ops)
|
|
defer f()
|
|
|
|
// Perform the test
|
|
req := NewRequest(t, "GET", "/org3")
|
|
resp := MakeRequest(t, req, http.StatusOK)
|
|
|
|
doc := NewHTMLParser(t, resp.Body)
|
|
readmeCount := doc.Find("#readme_profile").Length()
|
|
|
|
assert.Equal(t, expectedCount, readmeCount)
|
|
})
|
|
}
|
|
|
|
checkReadme(t, "No readme", "", 0)
|
|
checkReadme(t, "README.md", "README.md", 1)
|
|
checkReadme(t, "readme.md", "readme.md", 1)
|
|
checkReadme(t, "ReadMe.mD", "ReadMe.mD", 1)
|
|
checkReadme(t, "readme.org", "README.org", 1)
|
|
checkReadme(t, "README.en-us.md", "README.en-us.md", 1)
|
|
checkReadme(t, "README.en.md", "README.en.md", 1)
|
|
checkReadme(t, "README.txt", "README.txt", 1)
|
|
checkReadme(t, "README", "README", 1)
|
|
checkReadme(t, "README.mdown", "README.mdown", 1)
|
|
checkReadme(t, "README.i18n.md", "README.i18n.md", 1)
|
|
checkReadme(t, "readmee", "readmee", 0)
|
|
checkReadme(t, "test.md", "test.md", 0)
|
|
|
|
t.Run("readme-size", func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
|
|
// Prepare the test repository
|
|
org3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
|
|
|
|
_, _, f := tests.CreateDeclarativeRepo(t, org3, ".profile", nil, nil, []*files_service.ChangeRepoFile{
|
|
{
|
|
Operation: "update",
|
|
TreePath: "README.md",
|
|
ContentReader: strings.NewReader(`## Lorem ipsum
|
|
dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
|
## Ut enim ad minim veniam
|
|
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum`),
|
|
},
|
|
})
|
|
defer f()
|
|
|
|
t.Run("full", func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
defer test.MockVariableValue(&setting.UI.MaxDisplayFileSize, 500)()
|
|
|
|
req := NewRequest(t, "GET", "/org3")
|
|
resp := MakeRequest(t, req, http.StatusOK)
|
|
assert.Contains(t, resp.Body.String(), "Ut enim ad minim veniam")
|
|
assert.Contains(t, resp.Body.String(), "mollit anim id est laborum")
|
|
})
|
|
|
|
t.Run("truncated", func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
defer test.MockVariableValue(&setting.UI.MaxDisplayFileSize, 146)()
|
|
|
|
req := NewRequest(t, "GET", "/org3")
|
|
resp := MakeRequest(t, req, http.StatusOK)
|
|
assert.Contains(t, resp.Body.String(), "Ut enim ad minim")
|
|
assert.NotContains(t, resp.Body.String(), "veniam")
|
|
})
|
|
})
|
|
|
|
t.Run("More actions - feeds only", func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
defer test.MockVariableValue(&setting.Other.EnableFeed, true)()
|
|
defer test.MockVariableValue(&setting.Moderation.Enabled, false)()
|
|
|
|
// Both guests and logged in users should see the feed option
|
|
doc := NewHTMLParser(t, MakeRequest(t, NewRequest(t, "GET", "/org3"), http.StatusOK).Body)
|
|
doc.AssertElement(t, ".org-header details.dropdown a[href='/org3.rss']", true)
|
|
doc.AssertElement(t, ".org-header details.dropdown a[href^='/report_abuse']", false)
|
|
|
|
doc = NewHTMLParser(t, loginUser(t, "user10").MakeRequest(t, NewRequest(t, "GET", "/org3"), http.StatusOK).Body)
|
|
doc.AssertElement(t, ".org-header details.dropdown a[href='/org3.rss']", true)
|
|
doc.AssertElement(t, ".org-header details.dropdown a[href^='/report_abuse']", false)
|
|
})
|
|
|
|
t.Run("More actions - none", func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
defer test.MockVariableValue(&setting.Other.EnableFeed, false)()
|
|
defer test.MockVariableValue(&setting.Moderation.Enabled, false)()
|
|
|
|
// The dropdown won't appear if no entries are available, for both guests and logged in users
|
|
doc := NewHTMLParser(t, MakeRequest(t, NewRequest(t, "GET", "/org3"), http.StatusOK).Body)
|
|
doc.AssertElement(t, ".org-header details.dropdown", false)
|
|
|
|
doc = NewHTMLParser(t, loginUser(t, "user10").MakeRequest(t, NewRequest(t, "GET", "/org3"), http.StatusOK).Body)
|
|
doc.AssertElement(t, ".org-header details.dropdown", false)
|
|
})
|
|
|
|
t.Run("More actions - moderation", func(t *testing.T) {
|
|
defer tests.PrintCurrentTest(t)()
|
|
defer test.MockVariableValue(&setting.Other.EnableFeed, false)()
|
|
defer test.MockVariableValue(&setting.Moderation.Enabled, true)()
|
|
|
|
// The report option shouldn't be available to a guest
|
|
doc := NewHTMLParser(t, MakeRequest(t, NewRequest(t, "GET", "/org3"), http.StatusOK).Body)
|
|
doc.AssertElement(t, ".org-header details.dropdown", false)
|
|
|
|
// But should be available to a logged in user
|
|
doc = NewHTMLParser(t, loginUser(t, "user10").MakeRequest(t, NewRequest(t, "GET", "/org3"), http.StatusOK).Body)
|
|
doc.AssertElement(t, ".org-header details.dropdown a[href^='/report_abuse']", true)
|
|
|
|
// But the org owner shouldn't see the report option
|
|
doc = NewHTMLParser(t, loginUser(t, "user1").MakeRequest(t, NewRequest(t, "GET", "/org3"), http.StatusOK).Body)
|
|
doc.AssertElement(t, ".org-header details.dropdown", false)
|
|
})
|
|
})
|
|
}
|