jojo/tests/integration/org_profile_test.go
0ko f0b4e3b943 feat(ui): JS-less dropdowns in navbar (#10025)
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>
2025-11-16 14:56:42 +01:00

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)
})
})
}