Merge pull request 'Make user privacy settings more clear' (#4439) from 0ko/forgejo:ui-settings-activity into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/4439 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
This commit is contained in:
commit
436f8fda07
4 changed files with 32 additions and 13 deletions
|
@ -768,7 +768,7 @@ comment_type_group_issue_ref = Issue reference
|
||||||
saved_successfully = Your settings were saved successfully.
|
saved_successfully = Your settings were saved successfully.
|
||||||
privacy = Privacy
|
privacy = Privacy
|
||||||
keep_activity_private = Hide activity from profile page
|
keep_activity_private = Hide activity from profile page
|
||||||
keep_activity_private_popup = Your activity will only be visible to you and the instance admins
|
keep_activity_private.description = Your <a href="%s">public activity</a> will only be visible to you and the instance administrators.
|
||||||
|
|
||||||
lookup_avatar_by_mail = Lookup avatar by email address
|
lookup_avatar_by_mail = Lookup avatar by email address
|
||||||
federated_avatar_lookup = Federated avatar lookup
|
federated_avatar_lookup = Federated avatar lookup
|
||||||
|
@ -820,7 +820,7 @@ add_email_success = The new email address has been added.
|
||||||
email_preference_set_success = Email preference has been set successfully.
|
email_preference_set_success = Email preference has been set successfully.
|
||||||
add_openid_success = The new OpenID address has been added.
|
add_openid_success = The new OpenID address has been added.
|
||||||
keep_email_private = Hide email address
|
keep_email_private = Hide email address
|
||||||
keep_email_private_popup = This will hide your email address from your profile, as well as when you make a pull request or edit a file using the web interface. Pushed commits will not be modified. Use %s in commits to associate them with your account.
|
keep_email_private_popup = This will hide your email address from your profile. It will no longer be the default for commits made via the web interface, like file uploads and edits, and will not be used for merge commits. Instead a special address %s can be used to associate commits with your account. Note that changing this option will not affect existing commits.
|
||||||
openid_desc = OpenID lets you delegate authentication to an external provider.
|
openid_desc = OpenID lets you delegate authentication to an external provider.
|
||||||
|
|
||||||
manage_ssh_keys = Manage SSH keys
|
manage_ssh_keys = Manage SSH keys
|
||||||
|
|
1
release-notes/9.0.0/4439.md
Normal file
1
release-notes/9.0.0/4439.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Make descriptions of user privacy settings more visible and clear
|
|
@ -103,16 +103,18 @@
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<div class="ui checkbox">
|
<div class="ui checkbox">
|
||||||
<label data-tooltip-content="{{ctx.Locale.Tr "settings.keep_email_private_popup" .SignedUser.GetPlaceholderEmail}}"><strong>{{ctx.Locale.Tr "settings.keep_email_private"}}</strong></label>
|
<label>{{ctx.Locale.Tr "settings.keep_email_private"}}</label>
|
||||||
<input name="keep_email_private" type="checkbox" {{if .SignedUser.KeepEmailPrivate}}checked{{end}}>
|
<input name="keep_email_private" type="checkbox" {{if .SignedUser.KeepEmailPrivate}}checked{{end}}>
|
||||||
</div>
|
</div>
|
||||||
|
<span class="help tw-block">{{ctx.Locale.Tr "settings.keep_email_private_popup" .SignedUser.GetPlaceholderEmail}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<div class="ui checkbox" id="keep-activity-private">
|
<div class="ui checkbox" id="keep-activity-private">
|
||||||
<label data-tooltip-content="{{ctx.Locale.Tr "settings.keep_activity_private_popup"}}"><strong>{{ctx.Locale.Tr "settings.keep_activity_private"}}</strong></label>
|
<label>{{ctx.Locale.Tr "settings.keep_activity_private"}}</label>
|
||||||
<input name="keep_activity_private" type="checkbox" {{if .SignedUser.KeepActivityPrivate}}checked{{end}}>
|
<input name="keep_activity_private" type="checkbox" {{if .SignedUser.KeepActivityPrivate}}checked{{end}}>
|
||||||
</div>
|
</div>
|
||||||
|
<span class="help tw-block">{{ctx.Locale.Tr "settings.keep_activity_private.description" (printf "/%s?tab=activity" .SignedUser.Name)}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
|
|
|
@ -24,11 +24,6 @@ func TestUserProfileActivity(t *testing.T) {
|
||||||
// Activity availability should be the same for guest and another non-admin user, so this is not tested separately
|
// Activity availability should be the same for guest and another non-admin user, so this is not tested separately
|
||||||
userGuest := emptyTestSession(t)
|
userGuest := emptyTestSession(t)
|
||||||
|
|
||||||
// The hint may contain "Configure" link with an anchor. Verify that it works.
|
|
||||||
response := userRegular.MakeRequest(t, NewRequest(t, "GET", "/user/settings"), http.StatusOK)
|
|
||||||
page := NewHTMLParser(t, response.Body)
|
|
||||||
assert.True(t, page.Find(".checkbox#keep-activity-private").Length() > 0)
|
|
||||||
|
|
||||||
// = Public =
|
// = Public =
|
||||||
|
|
||||||
// Set activity visibility of user2 to public. This is the default, but won't hurt to set it before testing.
|
// Set activity visibility of user2 to public. This is the default, but won't hurt to set it before testing.
|
||||||
|
@ -41,9 +36,18 @@ func TestUserProfileActivity(t *testing.T) {
|
||||||
|
|
||||||
// Verify the hint for all types of users: admin, self, guest
|
// Verify the hint for all types of users: admin, self, guest
|
||||||
testUser2ActivityVisibility(t, userAdmin, "This activity is visible to everyone, but as an administrator you can also see interactions in private spaces.", true)
|
testUser2ActivityVisibility(t, userAdmin, "This activity is visible to everyone, but as an administrator you can also see interactions in private spaces.", true)
|
||||||
testUser2ActivityVisibility(t, userRegular, "Your activity is visible to everyone, except for interactions in private spaces. Configure.", true)
|
hintLink := testUser2ActivityVisibility(t, userRegular, "Your activity is visible to everyone, except for interactions in private spaces. Configure.", true)
|
||||||
testUser2ActivityVisibility(t, userGuest, "", true)
|
testUser2ActivityVisibility(t, userGuest, "", true)
|
||||||
|
|
||||||
|
// When viewing own profile, the user is offered to configure activity visibility. Verify that the link is correct and works, also check that it links back to the activity tab.
|
||||||
|
linkCorrect := assert.EqualValues(t, "/user/settings#keep-activity-private", hintLink)
|
||||||
|
if linkCorrect {
|
||||||
|
page := NewHTMLParser(t, userRegular.MakeRequest(t, NewRequest(t, "GET", hintLink), http.StatusOK).Body)
|
||||||
|
activityLink, exists := page.Find(".field:has(.checkbox#keep-activity-private) .help a").Attr("href")
|
||||||
|
assert.True(t, exists)
|
||||||
|
assert.EqualValues(t, "/user2?tab=activity", activityLink)
|
||||||
|
}
|
||||||
|
|
||||||
// = Private =
|
// = Private =
|
||||||
|
|
||||||
// Set activity visibility of user2 to private
|
// Set activity visibility of user2 to private
|
||||||
|
@ -56,8 +60,11 @@ func TestUserProfileActivity(t *testing.T) {
|
||||||
|
|
||||||
// Verify the hint for all types of users: admin, self, guest
|
// Verify the hint for all types of users: admin, self, guest
|
||||||
testUser2ActivityVisibility(t, userAdmin, "This activity is visible to you because you're an administrator, but the user wants it to remain private.", true)
|
testUser2ActivityVisibility(t, userAdmin, "This activity is visible to you because you're an administrator, but the user wants it to remain private.", true)
|
||||||
testUser2ActivityVisibility(t, userRegular, "Your activity is only visible to you and the instance administrators. Configure.", true)
|
hintLink = testUser2ActivityVisibility(t, userRegular, "Your activity is only visible to you and the instance administrators. Configure.", true)
|
||||||
testUser2ActivityVisibility(t, userGuest, "This user has disabled the public visibility of the activity.", false)
|
testUser2ActivityVisibility(t, userGuest, "This user has disabled the public visibility of the activity.", false)
|
||||||
|
|
||||||
|
// Verify that Configure link is correct
|
||||||
|
assert.EqualValues(t, "/user/settings#keep-activity-private", hintLink)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,11 +79,14 @@ func testChangeUserActivityVisibility(t *testing.T, session *TestSession, newSta
|
||||||
}
|
}
|
||||||
|
|
||||||
// testUser2ActivityVisibility checks visibility of UI elements on /<user>?tab=activity
|
// testUser2ActivityVisibility checks visibility of UI elements on /<user>?tab=activity
|
||||||
func testUser2ActivityVisibility(t *testing.T, session *TestSession, hint string, availability bool) {
|
// It also returns the account visibility link if it is present on the page.
|
||||||
|
func testUser2ActivityVisibility(t *testing.T, session *TestSession, hint string, availability bool) string {
|
||||||
|
t.Helper()
|
||||||
response := session.MakeRequest(t, NewRequest(t, "GET", "/user2?tab=activity"), http.StatusOK)
|
response := session.MakeRequest(t, NewRequest(t, "GET", "/user2?tab=activity"), http.StatusOK)
|
||||||
page := NewHTMLParser(t, response.Body)
|
page := NewHTMLParser(t, response.Body)
|
||||||
// Check hint visibility and correctness
|
// Check hint visibility and correctness
|
||||||
testSelectorEquals(t, page, "#visibility-hint", hint)
|
testSelectorEquals(t, page, "#visibility-hint", hint)
|
||||||
|
hintLink, hintLinkExists := page.Find("#visibility-hint a").Attr("href")
|
||||||
|
|
||||||
// Check that the hint aligns with the actual feed availability
|
// Check that the hint aligns with the actual feed availability
|
||||||
assert.EqualValues(t, availability, page.Find("#activity-feed").Length() > 0)
|
assert.EqualValues(t, availability, page.Find("#activity-feed").Length() > 0)
|
||||||
|
@ -87,10 +97,16 @@ func testUser2ActivityVisibility(t *testing.T, session *TestSession, hint string
|
||||||
// Check that the current tab is displayed and is active regardless of it's actual availability
|
// Check that the current tab is displayed and is active regardless of it's actual availability
|
||||||
// For example, on /<user> it wouldn't be available to guest, but it should be still present on /<user>?tab=activity
|
// For example, on /<user> it wouldn't be available to guest, but it should be still present on /<user>?tab=activity
|
||||||
assert.True(t, page.Find("overflow-menu .active.item[href='/user2?tab=activity']").Length() > 0)
|
assert.True(t, page.Find("overflow-menu .active.item[href='/user2?tab=activity']").Length() > 0)
|
||||||
|
|
||||||
|
if hintLinkExists {
|
||||||
|
return hintLink
|
||||||
|
}
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// testUser2ActivityButtonsAvailability check visibility of Public activity tab on main profile page
|
// testUser2ActivityButtonsAvailability checks visibility of Public activity tab on main profile page
|
||||||
func testUser2ActivityButtonsAvailability(t *testing.T, session *TestSession, buttons bool) {
|
func testUser2ActivityButtonsAvailability(t *testing.T, session *TestSession, buttons bool) {
|
||||||
|
t.Helper()
|
||||||
response := session.MakeRequest(t, NewRequest(t, "GET", "/user2"), http.StatusOK)
|
response := session.MakeRequest(t, NewRequest(t, "GET", "/user2"), http.StatusOK)
|
||||||
page := NewHTMLParser(t, response.Body)
|
page := NewHTMLParser(t, response.Body)
|
||||||
assert.EqualValues(t, buttons, page.Find("overflow-menu .item[href='/user2?tab=activity']").Length() > 0)
|
assert.EqualValues(t, buttons, page.Find("overflow-menu .item[href='/user2?tab=activity']").Length() > 0)
|
||||||
|
|
Loading…
Reference in a new issue