mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-05-27 04:07:08 +00:00
feat: add pronoun privacy option (#6773)
This commit contains UI changes, tests and migrations for a feature that lets users optionally hide their pronouns from the general public. This is useful if a person wants to disclose that information to a smaller set of people on a local instance belonging to a local community/association. Co-authored-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: Beowulf <beowulf@beocode.eu> Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6773 Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: Panagiotis "Ivory" Vasilopoulos <git@n0toose.net> Co-committed-by: Panagiotis "Ivory" Vasilopoulos <git@n0toose.net>
This commit is contained in:
parent
7104c73c96
commit
a1486b0ee4
17 changed files with 158 additions and 25 deletions
|
@ -438,8 +438,16 @@ func TestUserHints(t *testing.T) {
|
|||
func TestUserPronouns(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
session := loginUser(t, "user2")
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser)
|
||||
// user1 is admin, using user2 and user10 respectively instead.
|
||||
// This is explicitly mentioned here because of the unconventional
|
||||
// variable naming scheme.
|
||||
firstUserSession := loginUser(t, "user2")
|
||||
firstUserToken := getTokenForLoggedInUser(t, firstUserSession, auth_model.AccessTokenScopeWriteUser)
|
||||
|
||||
// This user has the HidePronouns setting enabled.
|
||||
// Check the fixture!
|
||||
secondUserSession := loginUser(t, "user10")
|
||||
secondUserToken := getTokenForLoggedInUser(t, secondUserSession, auth_model.AccessTokenScopeWriteUser)
|
||||
|
||||
adminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{IsAdmin: true})
|
||||
adminSession := loginUser(t, adminUser.Name)
|
||||
|
@ -449,8 +457,10 @@ func TestUserPronouns(t *testing.T) {
|
|||
t.Run("user", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequest(t, "GET", "/api/v1/user").AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
// secondUserToken was chosen arbitrarily and should have no impact.
|
||||
// See next comment.
|
||||
req := NewRequest(t, "GET", "/api/v1/user").AddTokenAuth(secondUserToken)
|
||||
resp := firstUserSession.MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
// We check the raw JSON, because we want to test the response, not
|
||||
// what it decodes into. Contents doesn't matter, we're testing the
|
||||
|
@ -468,16 +478,22 @@ func TestUserPronouns(t *testing.T) {
|
|||
// what it decodes into. Contents doesn't matter, we're testing the
|
||||
// presence only.
|
||||
assert.Contains(t, resp.Body.String(), `"pronouns":`)
|
||||
|
||||
req = NewRequest(t, "GET", "/api/v1/users/user10")
|
||||
resp = MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
// Same deal here.
|
||||
assert.Contains(t, resp.Body.String(), `"pronouns":`)
|
||||
})
|
||||
|
||||
t.Run("user/settings", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// Set pronouns first
|
||||
// Set pronouns first for user2
|
||||
pronouns := "they/them"
|
||||
req := NewRequestWithJSON(t, "PATCH", "/api/v1/user/settings", &api.UserSettingsOptions{
|
||||
Pronouns: &pronouns,
|
||||
}).AddTokenAuth(token)
|
||||
}).AddTokenAuth(firstUserToken)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
// Verify the response
|
||||
|
@ -486,7 +502,7 @@ func TestUserPronouns(t *testing.T) {
|
|||
assert.Equal(t, pronouns, user.Pronouns)
|
||||
|
||||
// Verify retrieving the settings again
|
||||
req = NewRequest(t, "GET", "/api/v1/user/settings").AddTokenAuth(token)
|
||||
req = NewRequest(t, "GET", "/api/v1/user/settings").AddTokenAuth(firstUserToken)
|
||||
resp = MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
DecodeJSON(t, resp, &user)
|
||||
|
@ -497,22 +513,40 @@ func TestUserPronouns(t *testing.T) {
|
|||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// Set the pronouns for user2
|
||||
pronouns := "she/her"
|
||||
pronouns := "he/him"
|
||||
req := NewRequestWithJSON(t, "PATCH", "/api/v1/admin/users/user2", &api.EditUserOption{
|
||||
Pronouns: &pronouns,
|
||||
}).AddTokenAuth(adminToken)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
// Verify the API response
|
||||
var user *api.User
|
||||
DecodeJSON(t, resp, &user)
|
||||
assert.Equal(t, pronouns, user.Pronouns)
|
||||
var user2 *api.User
|
||||
DecodeJSON(t, resp, &user2)
|
||||
assert.Equal(t, pronouns, user2.Pronouns)
|
||||
|
||||
// Verify via user2 too
|
||||
req = NewRequest(t, "GET", "/api/v1/user").AddTokenAuth(token)
|
||||
// Verify via user2
|
||||
req = NewRequest(t, "GET", "/api/v1/user").AddTokenAuth(firstUserToken)
|
||||
resp = MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &user)
|
||||
assert.Equal(t, pronouns, user.Pronouns)
|
||||
DecodeJSON(t, resp, &user2)
|
||||
assert.Equal(t, pronouns, user2.Pronouns) // TODO: This fails for some reason
|
||||
|
||||
// Set the pronouns for user10
|
||||
pronouns = "he/him"
|
||||
req = NewRequestWithJSON(t, "PATCH", "/api/v1/admin/users/user10", &api.EditUserOption{
|
||||
Pronouns: &pronouns,
|
||||
}).AddTokenAuth(adminToken)
|
||||
resp = MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
// Verify the API response
|
||||
var user10 *api.User
|
||||
DecodeJSON(t, resp, &user10)
|
||||
assert.Equal(t, pronouns, user10.Pronouns)
|
||||
|
||||
// Verify via user10
|
||||
req = NewRequest(t, "GET", "/api/v1/user").AddTokenAuth(secondUserToken)
|
||||
resp = MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &user10)
|
||||
assert.Equal(t, pronouns, user10.Pronouns)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -520,10 +554,10 @@ func TestUserPronouns(t *testing.T) {
|
|||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// Set the pronouns to a known state via the API
|
||||
pronouns := "she/her"
|
||||
pronouns := "they/them"
|
||||
req := NewRequestWithJSON(t, "PATCH", "/api/v1/user/settings", &api.UserSettingsOptions{
|
||||
Pronouns: &pronouns,
|
||||
}).AddTokenAuth(token)
|
||||
}).AddTokenAuth(firstUserToken)
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
t.Run("profile view", func(t *testing.T) {
|
||||
|
@ -534,14 +568,14 @@ func TestUserPronouns(t *testing.T) {
|
|||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
|
||||
userNameAndPronouns := strings.TrimSpace(htmlDoc.Find(".profile-avatar-name .username").Text())
|
||||
assert.Contains(t, userNameAndPronouns, pronouns)
|
||||
assert.NotContains(t, userNameAndPronouns, pronouns)
|
||||
})
|
||||
|
||||
t.Run("settings", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequest(t, "GET", "/user/settings")
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
resp := firstUserSession.MakeRequest(t, req, http.StatusOK)
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
|
||||
// Check that the field is present
|
||||
|
@ -550,12 +584,12 @@ func TestUserPronouns(t *testing.T) {
|
|||
assert.Equal(t, pronouns, pronounField)
|
||||
|
||||
// Check that updating the field works
|
||||
newPronouns := "they/them"
|
||||
newPronouns := "she/her"
|
||||
req = NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
|
||||
"_csrf": GetCSRF(t, session, "/user/settings"),
|
||||
"_csrf": GetCSRF(t, firstUserSession, "/user/settings"),
|
||||
"pronouns": newPronouns,
|
||||
})
|
||||
session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
firstUserSession.MakeRequest(t, req, http.StatusSeeOther)
|
||||
|
||||
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"})
|
||||
assert.Equal(t, newPronouns, user2.Pronouns)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue