mirror of
https://github.com/discourse/discourse.git
synced 2025-10-04 17:32:34 +08:00
FEATURE: Make it easier for staff to see if a profile is silenced (#33537)
This commit make it easier for staff to see if a profile is silenced by aligning it with how suspended notices are shown. - The number of times a profile has been silenced is shown in the staff counters banner at the top of the public user profiles. - Clicking on the silenced note in the staff counters banner goes to a filtered view of the staff action logs for the user and the silenced action. - The profile indicates if a user is silenced and shows the date they are silenced until. This looks exactly the same as how it currently displays for suspended users, with the added info of the date. This is also displayed on the user card, the same as suspended notices currently are. ## Screenshots  
This commit is contained in:
parent
96dc65d69c
commit
a3cff97b48
21 changed files with 330 additions and 47 deletions
|
@ -71,7 +71,8 @@ export default class UserCardContents extends CardContentsBase {
|
|||
@gt("moreBadgesCount", 0) showMoreBadges;
|
||||
@and("viewingAdmin", "showName", "user.canBeDeleted") showDelete;
|
||||
@not("user.isBasic") linkWebsite;
|
||||
@or("user.suspend_reason", "user.bio_excerpt") isSuspendedOrHasBio;
|
||||
@or("user.suspend_reason", "user.silence_reason") isRestricted;
|
||||
@or("isRestricted", "user.bio_excerpt") isRestrictedOrHasBio;
|
||||
@and("user.staged", "canCheckEmails") showCheckEmail;
|
||||
|
||||
user = null;
|
||||
|
@ -551,7 +552,7 @@ export default class UserCardContents extends CardContentsBase {
|
|||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.isSuspendedOrHasBio}}
|
||||
{{#if this.isRestrictedOrHasBio}}
|
||||
<div class="card-row second-row">
|
||||
{{#if this.user.suspend_reason}}
|
||||
<div class="suspended">
|
||||
|
@ -575,15 +576,37 @@ export default class UserCardContents extends CardContentsBase {
|
|||
>{{this.user.suspend_reason}}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
{{#if this.user.bio_excerpt}}
|
||||
<div class="bio">
|
||||
<HtmlWithLinks>
|
||||
{{htmlSafe this.user.bio_excerpt}}
|
||||
</HtmlWithLinks>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if this.user.silence_reason}}
|
||||
<div class="silenced">
|
||||
<div class="silence-date">
|
||||
{{icon "microphone-slash"}}
|
||||
{{#if this.user.silencedForever}}
|
||||
{{i18n "user.silenced_permanently"}}
|
||||
{{else}}
|
||||
{{i18n
|
||||
"user.silenced_notice"
|
||||
date=this.user.silencedTillDate
|
||||
}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="silence-reason">
|
||||
<span class="silence-reason-title">{{i18n
|
||||
"user.silenced_reason"
|
||||
}}</span>
|
||||
<span
|
||||
class="silence-reason-description"
|
||||
>{{this.user.silence_reason}}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#unless this.isRestricted}}
|
||||
<div class="bio">
|
||||
<HtmlWithLinks>
|
||||
{{htmlSafe this.user.bio_excerpt}}
|
||||
</HtmlWithLinks>
|
||||
</div>
|
||||
{{/unless}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ export default class UserController extends Controller {
|
|||
@gt("model.number_of_flags_given", 0) hasGivenFlags;
|
||||
@gt("model.number_of_flagged_posts", 0) hasFlaggedPosts;
|
||||
@gt("model.number_of_deleted_posts", 0) hasDeletedPosts;
|
||||
@gt("model.number_of_silencings", 0) hasBeenSilenced;
|
||||
@gt("model.number_of_suspensions", 0) hasBeenSuspended;
|
||||
@gt("model.warnings_received_count", 0) hasReceivedWarnings;
|
||||
@gt("model.number_of_rejected_posts", 0) hasRejectedPosts;
|
||||
|
@ -36,6 +37,7 @@ export default class UserController extends Controller {
|
|||
"hasGivenFlags",
|
||||
"hasFlaggedPosts",
|
||||
"hasDeletedPosts",
|
||||
"hasBeenSilenced",
|
||||
"hasBeenSuspended",
|
||||
"hasReceivedWarnings",
|
||||
"hasRejectedPosts"
|
||||
|
@ -91,9 +93,9 @@ export default class UserController extends Controller {
|
|||
};
|
||||
}
|
||||
|
||||
@discourseComputed("model.suspended", "currentUser.staff")
|
||||
isNotSuspendedOrIsStaff(suspended, isStaff) {
|
||||
return !suspended || isStaff;
|
||||
@discourseComputed("model.suspended", "model.silenced", "currentUser.staff")
|
||||
isNotRestrictedOrIsStaff(suspended, silenced, isStaff) {
|
||||
return (!suspended && !silenced) || isStaff;
|
||||
}
|
||||
|
||||
@discourseComputed("model.trust_level")
|
||||
|
@ -210,13 +212,22 @@ export default class UserController extends Controller {
|
|||
return this.site.desktopView;
|
||||
}
|
||||
|
||||
@action
|
||||
showSuspensions(event) {
|
||||
event?.preventDefault();
|
||||
this.adminTools.showActionLogs(this, {
|
||||
target_user: this.get("model.username"),
|
||||
action_name: "suspend_user",
|
||||
});
|
||||
get silencingsRouteQuery() {
|
||||
return {
|
||||
filters: {
|
||||
target_user: this.get("model.username"),
|
||||
action_name: "silence_user",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
get suspensionsRouteQuery() {
|
||||
return {
|
||||
filters: {
|
||||
target_user: this.get("model.username"),
|
||||
action_name: "suspend_user",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
|
@ -431,6 +431,11 @@ export default class User extends RestModel.extend(Evented) {
|
|||
return isForever(suspendedTill);
|
||||
}
|
||||
|
||||
@discourseComputed("silenced_till")
|
||||
silenced(silencedTill) {
|
||||
return silencedTill && moment(silencedTill).isAfter();
|
||||
}
|
||||
|
||||
@discourseComputed("silenced_till")
|
||||
silencedForever(silencedTill) {
|
||||
return isForever(silencedTill);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { array, concat, fn, hash } from "@ember/helper";
|
||||
import { on } from "@ember/modifier";
|
||||
import { LinkTo } from "@ember/routing";
|
||||
import RouteTemplate from "ember-route-template";
|
||||
import DButton from "discourse/components/d-button";
|
||||
|
@ -120,9 +119,28 @@ export default RouteTemplate(
|
|||
</LinkTo>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if @controller.model.number_of_silencings}}
|
||||
<div>
|
||||
<LinkTo
|
||||
@route="adminLogs.staffActionLogs"
|
||||
@query={{@controller.silencingsRouteQuery}}
|
||||
>
|
||||
{{htmlSafe
|
||||
(i18n
|
||||
"user.staff_counters.silencings"
|
||||
className="silencings"
|
||||
count=@controller.model.number_of_silencings
|
||||
)
|
||||
}}
|
||||
</LinkTo>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if @controller.model.number_of_suspensions}}
|
||||
<div>
|
||||
<a href {{on "click" @controller.showSuspensions}}>
|
||||
<LinkTo
|
||||
@route="adminLogs.staffActionLogs"
|
||||
@query={{@controller.suspensionsRouteQuery}}
|
||||
>
|
||||
{{htmlSafe
|
||||
(i18n
|
||||
"user.staff_counters.suspensions"
|
||||
|
@ -130,7 +148,7 @@ export default RouteTemplate(
|
|||
count=@controller.model.number_of_suspensions
|
||||
)
|
||||
}}
|
||||
</a>
|
||||
</LinkTo>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if @controller.model.warnings_received_count}}
|
||||
|
@ -278,25 +296,51 @@ export default RouteTemplate(
|
|||
<div class="bio">
|
||||
{{#if @controller.model.suspended}}
|
||||
<div class="suspended">
|
||||
{{icon "ban"}}
|
||||
<b>
|
||||
{{#if @controller.model.suspendedForever}}
|
||||
{{i18n "user.suspended_permanently"}}
|
||||
{{else}}
|
||||
{{i18n
|
||||
"user.suspended_notice"
|
||||
date=@controller.model.suspendedTillDate
|
||||
}}
|
||||
{{/if}}
|
||||
</b>
|
||||
<br />
|
||||
<div class="suspension-date">
|
||||
{{icon "ban"}}
|
||||
<b>
|
||||
{{#if @controller.model.suspendedForever}}
|
||||
{{i18n "user.suspended_permanently"}}
|
||||
{{else}}
|
||||
{{i18n
|
||||
"user.suspended_notice"
|
||||
date=@controller.model.suspendedTillDate
|
||||
}}
|
||||
{{/if}}
|
||||
</b>
|
||||
</div>
|
||||
{{#if @controller.model.suspend_reason}}
|
||||
<b>{{i18n "user.suspended_reason"}}</b>
|
||||
{{@controller.model.suspend_reason}}
|
||||
<div class="suspension-reason">
|
||||
<b>{{i18n "user.suspended_reason"}}</b>
|
||||
{{@controller.model.suspend_reason}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if @controller.isNotSuspendedOrIsStaff}}
|
||||
{{#if @controller.model.silenced}}
|
||||
<div class="silenced">
|
||||
<div class="silence-date">
|
||||
{{icon "microphone-slash"}}
|
||||
<b>
|
||||
{{#if @controller.model.silencedForever}}
|
||||
{{i18n "user.silenced_permanently"}}
|
||||
{{else}}
|
||||
{{i18n
|
||||
"user.silenced_notice"
|
||||
date=@controller.model.silencedTillDate
|
||||
}}
|
||||
{{/if}}
|
||||
</b>
|
||||
</div>
|
||||
{{#if @controller.model.silence_reason}}
|
||||
<div class="silence-reason">
|
||||
<b>{{i18n "user.silenced_reason"}}</b>
|
||||
{{@controller.model.silence_reason}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if @controller.isNotRestrictedOrIsStaff}}
|
||||
<HtmlWithLinks>
|
||||
{{htmlSafe @controller.model.bio_cooked}}
|
||||
</HtmlWithLinks>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { getOwner } from "@ember/owner";
|
||||
import { click, currentURL, visit } from "@ember/test-helpers";
|
||||
import { test } from "qunit";
|
||||
import { longDate } from "discourse/lib/formatter";
|
||||
import { cloneJSON } from "discourse/lib/object";
|
||||
import userFixtures from "discourse/tests/fixtures/user-fixtures";
|
||||
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
|
||||
|
@ -172,3 +173,37 @@ acceptance("User Card - Inactive user", function (needs) {
|
|||
assert.dom(".user-card .inactive-user").hasText(i18n("user.inactive_user"));
|
||||
});
|
||||
});
|
||||
|
||||
acceptance("User Card - Restricted user", function (needs) {
|
||||
const tomorrow = new Date();
|
||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||||
|
||||
needs.user();
|
||||
needs.pretender((server, helper) => {
|
||||
const cardResponse = cloneJSON(userFixtures["/u/eviltrout/card.json"]);
|
||||
cardResponse.user.silence_reason = "silenced for testing";
|
||||
cardResponse.user.silenced_till = tomorrow.toISOString();
|
||||
cardResponse.user.suspend_reason = "suspended for testing";
|
||||
cardResponse.user.suspended_till = tomorrow.toISOString();
|
||||
server.get("/u/eviltrout/card.json", () => helper.response(cardResponse));
|
||||
});
|
||||
|
||||
test("it shows restricted user information", async function (assert) {
|
||||
await visit("/t/this-is-a-test-topic/9");
|
||||
await click('a[data-user-card="eviltrout"]');
|
||||
|
||||
assert
|
||||
.dom(".user-card .card-row .silence-reason")
|
||||
.hasText(i18n("user.silenced_reason") + "silenced for testing");
|
||||
assert
|
||||
.dom(".user-card .card-row .silence-date")
|
||||
.hasText(i18n("user.silenced_notice", { date: longDate(tomorrow) }));
|
||||
|
||||
assert
|
||||
.dom(".user-card .card-row .suspension-reason")
|
||||
.hasText(i18n("user.suspended_reason") + "suspended for testing");
|
||||
assert
|
||||
.dom(".user-card .card-row .suspension-date")
|
||||
.hasText(i18n("user.suspended_notice", { date: longDate(tomorrow) }));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -212,6 +212,10 @@
|
|||
color: var(--danger);
|
||||
}
|
||||
|
||||
.silenced {
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
.primary {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
@ -338,6 +342,10 @@
|
|||
background-color: var(--danger-medium);
|
||||
}
|
||||
|
||||
.silencings {
|
||||
background-color: var(--danger-medium);
|
||||
}
|
||||
|
||||
.suspensions {
|
||||
background-color: var(--danger);
|
||||
}
|
||||
|
|
|
@ -225,6 +225,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
.silenced {
|
||||
color: var(--danger);
|
||||
|
||||
.silence-reason-title,
|
||||
.silence-date {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.profile-hidden,
|
||||
.inactive-user {
|
||||
font-size: var(--font-up-1);
|
||||
|
|
|
@ -1523,6 +1523,7 @@ class UsersController < ApplicationController
|
|||
number_of_deleted_posts
|
||||
number_of_flagged_posts
|
||||
number_of_flags_given
|
||||
number_of_silencings
|
||||
number_of_suspensions
|
||||
warnings_received_count
|
||||
number_of_rejected_posts
|
||||
|
|
|
@ -1632,6 +1632,10 @@ class User < ActiveRecord::Base
|
|||
.count
|
||||
end
|
||||
|
||||
def number_of_silencings
|
||||
UserHistory.for(self, :silence_user).count
|
||||
end
|
||||
|
||||
def number_of_suspensions
|
||||
UserHistory.for(self, :suspend_user).count
|
||||
end
|
||||
|
|
|
@ -20,7 +20,6 @@ class AdminUserListSerializer < BasicUserSerializer
|
|||
:approved,
|
||||
:suspended_at,
|
||||
:suspended_till,
|
||||
:silenced,
|
||||
:silenced_till,
|
||||
:time_read,
|
||||
:staged,
|
||||
|
@ -44,14 +43,6 @@ class AdminUserListSerializer < BasicUserSerializer
|
|||
alias_method :include_secondary_emails?, :include_email?
|
||||
alias_method :include_associated_accounts?, :include_email?
|
||||
|
||||
def silenced
|
||||
object.silenced?
|
||||
end
|
||||
|
||||
def include_silenced?
|
||||
object.silenced?
|
||||
end
|
||||
|
||||
def silenced_till
|
||||
object.silenced_till
|
||||
end
|
||||
|
|
|
@ -62,6 +62,8 @@ class UserCardSerializer < BasicUserSerializer
|
|||
:title,
|
||||
:suspend_reason,
|
||||
:suspended_till,
|
||||
:silence_reason,
|
||||
:silenced_till,
|
||||
:badge_count,
|
||||
:user_fields,
|
||||
:custom_fields,
|
||||
|
@ -158,6 +160,14 @@ class UserCardSerializer < BasicUserSerializer
|
|||
object.suspended?
|
||||
end
|
||||
|
||||
def include_silence_reason?
|
||||
scope.can_see_silencing_reason?(object) && object.silenced?
|
||||
end
|
||||
|
||||
def include_silenced_till?
|
||||
object.silenced?
|
||||
end
|
||||
|
||||
def user_fields
|
||||
allowed_keys = scope.allowed_user_field_ids(object)
|
||||
object.user_fields(allowed_keys)
|
||||
|
|
|
@ -1479,6 +1479,9 @@ en:
|
|||
suspended_notice: "This user is suspended until %{date}."
|
||||
suspended_permanently: "This user is suspended."
|
||||
suspended_reason: "Reason: "
|
||||
silenced_notice: "This user is silenced until %{date}."
|
||||
silenced_permanently: "This user is silenced."
|
||||
silenced_reason: "Reason: "
|
||||
github_profile: "GitHub"
|
||||
email_activity_summary: "Activity Summary"
|
||||
mailing_list_mode:
|
||||
|
@ -1551,6 +1554,9 @@ en:
|
|||
deleted_posts:
|
||||
one: '<span class="%{className}">%{count}</span> deleted post'
|
||||
other: '<span class="%{className}">%{count}</span> deleted posts'
|
||||
silencings:
|
||||
one: '<span class="%{className}">%{count}</span> silenced'
|
||||
other: '<span class="%{className}">%{count}</span> silenced'
|
||||
suspensions:
|
||||
one: '<span class="%{className}">%{count}</span> suspension'
|
||||
other: '<span class="%{className}">%{count}</span> suspensions'
|
||||
|
|
|
@ -2428,6 +2428,8 @@ en:
|
|||
|
||||
show_inactive_accounts: "Allow logged in users to browse profiles of inactive accounts."
|
||||
|
||||
hide_silencing_reasons: "Don't display silencing reasons publically on user profiles."
|
||||
|
||||
hide_suspension_reasons: "Don't display suspension reasons publically on user profiles."
|
||||
|
||||
log_personal_messages_views: "Log personal message views by Admin for other users/groups."
|
||||
|
|
|
@ -960,6 +960,10 @@ users:
|
|||
default: false
|
||||
client: true
|
||||
area: "users"
|
||||
hide_silencing_reasons:
|
||||
default: false
|
||||
client: true
|
||||
area: "users"
|
||||
log_personal_messages_views:
|
||||
default: false
|
||||
area: "users"
|
||||
|
|
|
@ -115,6 +115,11 @@ module UserGuardian
|
|||
user == @user || is_staff?
|
||||
end
|
||||
|
||||
def can_see_silencing_reason?(user)
|
||||
return true unless SiteSetting.hide_silencing_reasons?
|
||||
user == @user || is_staff?
|
||||
end
|
||||
|
||||
def can_disable_second_factor?(user)
|
||||
user && can_administer_user?(user)
|
||||
end
|
||||
|
|
|
@ -288,6 +288,11 @@ const UserAbout = <template>
|
|||
</span> {{i18n "user.staff_counters.deleted_posts"}}
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<span class="silencings">
|
||||
{{@dummy.user.num_of_silencings}}
|
||||
</span> {{i18n "user.staff_counters.silencings"}}
|
||||
</div>
|
||||
<div>
|
||||
<span class="suspensions">
|
||||
{{@dummy.user.number_of_suspensions}}
|
||||
|
|
|
@ -4227,6 +4227,28 @@ RSpec.describe Guardian do
|
|||
end
|
||||
end
|
||||
|
||||
describe "silencing reasons" do
|
||||
it "will be shown by default" do
|
||||
expect(Guardian.new.can_see_silencing_reason?(user)).to eq(true)
|
||||
end
|
||||
|
||||
context "with hide silencing reason enabled" do
|
||||
before { SiteSetting.hide_silencing_reasons = true }
|
||||
|
||||
it "will not be shown to anonymous users" do
|
||||
expect(Guardian.new.can_see_silencing_reason?(user)).to eq(false)
|
||||
end
|
||||
|
||||
it "users can see their own silencings" do
|
||||
expect(Guardian.new(user).can_see_silencing_reason?(user)).to eq(true)
|
||||
end
|
||||
|
||||
it "staff can see silencings" do
|
||||
expect(Guardian.new(moderator).can_see_silencing_reason?(user)).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#can_remove_allowed_users?" do
|
||||
context "with staff users" do
|
||||
it "should be true" do
|
||||
|
|
|
@ -2126,6 +2126,15 @@ RSpec.describe User do
|
|||
expect(user.number_of_flagged_posts).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#number_of_silencings" do
|
||||
it "counts the number of silencings" do
|
||||
3.times do
|
||||
Fabricate(:user_history, action: UserHistory.actions[:silence_user], target_user: user)
|
||||
end
|
||||
expect(user.number_of_silencings).to eq(3)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "new_user?" do
|
||||
|
|
|
@ -7881,6 +7881,68 @@ RSpec.describe UsersController do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#staff_info" do
|
||||
context "when logged out" do
|
||||
it "responds with 403" do
|
||||
get "/u/#{user.username}/staff-info.json"
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in" do
|
||||
before do
|
||||
Fabricate(:user_history, action: UserHistory.actions[:silence_user], target_user: user)
|
||||
Fabricate(:user_history, action: UserHistory.actions[:suspend_user], target_user: user)
|
||||
Fabricate(:reviewable_flagged_post, target_created_by: user)
|
||||
end
|
||||
|
||||
it "responds with 403 for normal users" do
|
||||
sign_in(user)
|
||||
get "/u/#{user.username}/staff-info.json"
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
|
||||
it "responds with 200 for moderators" do
|
||||
sign_in(moderator)
|
||||
|
||||
get "/u/#{user.username}/staff-info.json"
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
|
||||
it "responds with 200 for admins" do
|
||||
sign_in(admin)
|
||||
|
||||
get "/u/#{user.username}/staff-info.json"
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
|
||||
it "delegates work to `User`" do
|
||||
user_instance = mock
|
||||
UsersController.any_instance.stubs(:fetch_user_from_params).returns(user_instance)
|
||||
|
||||
result = {}
|
||||
|
||||
%i[
|
||||
number_of_deleted_posts
|
||||
number_of_flagged_posts
|
||||
number_of_flags_given
|
||||
number_of_silencings
|
||||
number_of_suspensions
|
||||
warnings_received_count
|
||||
number_of_rejected_posts
|
||||
].each do |info|
|
||||
user_instance.expects(info).returns(user.public_send(info))
|
||||
result[info.to_s] = user.public_send(info)
|
||||
end
|
||||
|
||||
sign_in(admin)
|
||||
|
||||
get "/u/#{user.username}/staff-info.json"
|
||||
expect(response.parsed_body).to eq(result)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create_second_factor_security_key
|
||||
sign_in(user1)
|
||||
stub_secure_session_confirmed
|
||||
|
|
|
@ -46,6 +46,12 @@ module PageObjects
|
|||
self
|
||||
end
|
||||
|
||||
def click_staff_info_silencings_link
|
||||
staff_counters = page.find(".staff-counters")
|
||||
staff_counters.find("a:has(.silencings)").click
|
||||
self
|
||||
end
|
||||
|
||||
def expand_info_panel
|
||||
button = page.find("button[aria-controls='collapsed-info-panel']")
|
||||
button.click if button["aria-expanded"] == "false"
|
||||
|
|
|
@ -17,4 +17,25 @@ describe "Viewing user staff info as an admin", type: :system do
|
|||
expect(user_page).to have_warning_messages_path(user)
|
||||
end
|
||||
end
|
||||
|
||||
context "for silencings" do
|
||||
fab!(:silencing) do
|
||||
Fabricate(:user_history, action: UserHistory.actions[:silence_user], target_user: user)
|
||||
end
|
||||
it "should display the right link to user's silencings with the right count in text" do
|
||||
user_page.visit(user)
|
||||
silencings_counters = page.find(".staff-counters .silencings")
|
||||
expect(silencings_counters).to have_text("1")
|
||||
|
||||
user_page.click_staff_info_silencings_link
|
||||
expect(user_page).to have_current_path("/admin/logs/staff_action_logs", ignore_query: true)
|
||||
|
||||
current_url = user_page.current_url
|
||||
uri = URI.parse(current_url)
|
||||
filters = JSON.parse(URI.decode_www_form(uri.query).to_h["filters"])
|
||||
|
||||
expect(filters["target_user"]).to eq(user.username)
|
||||
expect(filters["action_name"]).to eq("silence_user")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue