diff --git a/app/helpers/admin/users_helper.rb b/app/helpers/admin/users_helper.rb
index d52b2a0df..13914597e 100644
--- a/app/helpers/admin/users_helper.rb
+++ b/app/helpers/admin/users_helper.rb
@@ -52,6 +52,8 @@ module Admin
I18n.t("views.admin.users.statuses.Warned")
elsif user.comment_suspended?
I18n.t("views.admin.users.statuses.Comment Suspended")
+ elsif user.limited?
+ I18n.t("views.admin.users.statuses.Limited")
elsif user.trusted?
I18n.t("views.admin.users.statuses.Trusted")
else
@@ -101,6 +103,8 @@ module Admin
"#F59E0B"
when "Comment Suspended"
"#DC2626"
+ when "Limited"
+ "#DC2626"
when "Trusted"
"#059669"
else
diff --git a/app/lib/constants/role.rb b/app/lib/constants/role.rb
index 2edebe207..6dab2841b 100644
--- a/app/lib/constants/role.rb
+++ b/app/lib/constants/role.rb
@@ -3,6 +3,7 @@ module Constants
BASE_ROLES_LABELS_TO_WHERE_CLAUSE = {
"Warned" => { name: "warned", resource_type: nil },
"Comment Suspended" => { name: "comment_suspended", resource_type: nil },
+ "Limited" => { name: "limited", resource_type: nil },
"Suspended" => { name: "suspended", resource_type: nil },
# This "role" is a weird amalgamation of multiple roles.
"Good standing" => :good_standing,
diff --git a/app/models/role.rb b/app/models/role.rb
index ae8b7eb22..858156540 100644
--- a/app/models/role.rb
+++ b/app/models/role.rb
@@ -17,6 +17,7 @@ class Role < ApplicationRecord
trusted
warned
workshop_pass
+ limited
].freeze
ROLES.each do |role|
diff --git a/app/models/user.rb b/app/models/user.rb
index ef90c61bc..4d77fd5cb 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -417,6 +417,7 @@ class User < ApplicationRecord
:auditable?,
:banished?,
:comment_suspended?,
+ :limited?,
:creator?,
:has_trusted_role?,
:super_moderator?,
@@ -602,7 +603,7 @@ class User < ApplicationRecord
end
def set_username
- self.username = username&.downcase&.presence || generate_username
+ self.username = username&.downcase.presence || generate_username
end
def auth_provider_usernames
diff --git a/app/policies/authorizer.rb b/app/policies/authorizer.rb
index 5c6e0281d..f9a55af6f 100644
--- a/app/policies/authorizer.rb
+++ b/app/policies/authorizer.rb
@@ -71,6 +71,10 @@ module Authorizer
has_role?(:comment_suspended)
end
+ def limited?
+ has_role?(:limited)
+ end
+
def creator?
has_role?(:creator)
end
diff --git a/app/queries/admin/moderators_query.rb b/app/queries/admin/moderators_query.rb
index de3fdc8eb..f311a99ce 100644
--- a/app/queries/admin/moderators_query.rb
+++ b/app/queries/admin/moderators_query.rb
@@ -4,7 +4,7 @@ module Admin
state: :trusted
}.with_indifferent_access.freeze
- POTENTIAL_ROLE_NAMES = %i[comment_suspended suspended trusted warned].freeze
+ POTENTIAL_ROLE_NAMES = %i[comment_suspended limited suspended trusted warned].freeze
def self.call(relation: User.all, options: {})
options = DEFAULT_OPTIONS.merge(options)
diff --git a/app/services/moderator/manage_activity_and_roles.rb b/app/services/moderator/manage_activity_and_roles.rb
index 4058d3ea0..0648b59a0 100644
--- a/app/services/moderator/manage_activity_and_roles.rb
+++ b/app/services/moderator/manage_activity_and_roles.rb
@@ -65,6 +65,8 @@ module Moderator
TagModerators::AddTrustedRole.call(user)
when "Comment Suspended"
comment_suspended
+ when "Limited"
+ limited
when "Suspended" || "Spammer"
user.add_role(:suspended)
remove_privileges
@@ -116,6 +118,11 @@ module Moderator
remove_privileges
end
+ def limited
+ user.add_role(:limited)
+ remove_privileges
+ end
+
def regular_member
remove_negative_roles
remove_mod_roles
diff --git a/app/views/admin/users/index/_user_status_indicator.html.erb b/app/views/admin/users/index/_user_status_indicator.html.erb
index 81a52ea0e..f7f5a22a9 100644
--- a/app/views/admin/users/index/_user_status_indicator.html.erb
+++ b/app/views/admin/users/index/_user_status_indicator.html.erb
@@ -4,6 +4,8 @@
<%= render "admin/users/index/status_indicator", status: "Warned" %>
<% elsif user.comment_suspended? %>
<%= render "admin/users/index/status_indicator", status: "Comment Suspended" %>
+<% elsif user.limited? %>
+ <%= render "admin/users/index/status_indicator", status: "Limited" %>
<% elsif user.trusted? %>
<%= render "admin/users/index/status_indicator", status: "Trusted" %>
<% else %>
diff --git a/app/views/admin/users/show/profile/_status.html.erb b/app/views/admin/users/show/profile/_status.html.erb
index 1676dd018..c77155e02 100644
--- a/app/views/admin/users/show/profile/_status.html.erb
+++ b/app/views/admin/users/show/profile/_status.html.erb
@@ -6,6 +6,8 @@
<%= t("views.admin.users.statuses.Warned") %>
<% elsif user.comment_suspended? %>
<%= t("views.admin.users.statuses.Comment Suspended") %>
+ <% elsif user.limited? %>
+ <%= t("views.admin.users.statuses.Limited") %>
<% elsif user.trusted? %>
<%= t("views.admin.users.statuses.Trusted") %>
<% else %>
diff --git a/config/locales/views/admin/en.yml b/config/locales/views/admin/en.yml
index 6e67cf172..e134ec7a5 100644
--- a/config/locales/views/admin/en.yml
+++ b/config/locales/views/admin/en.yml
@@ -284,6 +284,7 @@ en:
admin: Admin
codeland_admin: Codeland Admin
comment_suspended: Comment Suspended
+ limited: Limited
creator: Creator
mod_relations_admin: Mod Relations Admin
super_moderator: Super Moderator
@@ -400,6 +401,7 @@ en:
statuses:
Warned: Warned
Comment Suspended: Comment Suspended
+ Limited: Limited
Suspended: Suspended
Good Standing: Good Standing
Good standing: Good standing
diff --git a/config/locales/views/admin/fr.yml b/config/locales/views/admin/fr.yml
index 69b1dcf62..9c447f993 100644
--- a/config/locales/views/admin/fr.yml
+++ b/config/locales/views/admin/fr.yml
@@ -284,6 +284,7 @@ fr:
admin: Admin
codeland_admin: Codeland Admin
comment_suspended: Comment Suspended
+ limited: Limited
creator: Creator
mod_relations_admin: Mod Relations Admin
super_moderator: Super Moderator
@@ -398,6 +399,7 @@ fr:
statuses:
Warned: Warned
Comment Suspended: Comment Suspended
+ Limited: Limited
Suspended: Suspended
Good Standing: Good Standing
Good standing: Good standing
diff --git a/cypress/e2e/seededFlows/adminFlows/users/manageRoles.spec.js b/cypress/e2e/seededFlows/adminFlows/users/manageRoles.spec.js
index a0b7fca55..b2fbf276c 100644
--- a/cypress/e2e/seededFlows/adminFlows/users/manageRoles.spec.js
+++ b/cypress/e2e/seededFlows/adminFlows/users/manageRoles.spec.js
@@ -159,6 +159,25 @@ describe('Manage User Roles', () => {
cy.findByRole('button', {
name: 'Remove role: Comment Suspended',
}).should('exist');
+
+ openRolesModal().within(() => {
+ cy.findByRole('combobox', { name: 'Role' }).select('Limited');
+ cy.findByRole('textbox', { name: 'Add a note to this action:' }).type(
+ 'some reason',
+ );
+ cy.findByRole('button', { name: 'Add' }).click();
+ });
+
+ cy.getModal().should('not.exist');
+ verifyAndDismissFlashMessage('User has been updated', 'flash-success');
+ checkUserStatus('Warned');
+
+ cy.findByRole('button', { name: 'Remove role: Warned' }).should(
+ 'exist',
+ );
+ cy.findByRole('button', {
+ name: 'Remove role: Limited',
+ }).should('exist');
});
});
});
diff --git a/spec/factories/users.rb b/spec/factories/users.rb
index 5bfe944fa..e80c87854 100644
--- a/spec/factories/users.rb
+++ b/spec/factories/users.rb
@@ -122,6 +122,10 @@ FactoryBot.define do
after(:build) { |user| user.add_role(:comment_suspended) }
end
+ trait :limited do
+ after(:build) { |user| user.add_role(:limited) }
+ end
+
trait :invited do
after(:build) do |user|
user.registered = false
diff --git a/spec/helpers/admin/users_helper_spec.rb b/spec/helpers/admin/users_helper_spec.rb
index 7f73a1d89..9c29dab0b 100644
--- a/spec/helpers/admin/users_helper_spec.rb
+++ b/spec/helpers/admin/users_helper_spec.rb
@@ -133,6 +133,12 @@ describe Admin::UsersHelper do
expect(status).to eq "Comment Suspended"
end
+ it "renders the proper status for a user that is limited" do
+ limited_user = create(:user, :limited)
+ status = helper.user_status(limited_user)
+ expect(status).to eq "Limited"
+ end
+
it "renders the proper status for a user that is trusted" do
trusted_user = create(:user, :trusted)
status = helper.user_status(trusted_user)
diff --git a/spec/models/role_spec.rb b/spec/models/role_spec.rb
index fd83763d0..4725a2751 100644
--- a/spec/models/role_spec.rb
+++ b/spec/models/role_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe Role do
describe "::ROLES" do
it "contains the correct values" do
expected_roles = %w[
- admin codeland_admin comment_suspended mod_relations_admin podcast_admin
+ admin codeland_admin comment_suspended limited mod_relations_admin podcast_admin
restricted_liquid_tag single_resource_admin super_admin support_admin suspended tag_moderator tech_admin
trusted warned workshop_pass creator super_moderator
]
diff --git a/spec/requests/admin/users_manage_spec.rb b/spec/requests/admin/users_manage_spec.rb
index 6c1dd6a50..a7d417f2a 100644
--- a/spec/requests/admin/users_manage_spec.rb
+++ b/spec/requests/admin/users_manage_spec.rb
@@ -130,6 +130,14 @@ RSpec.describe "Admin::Users" do
expect(Note.first.content).to eq("comment suspend this user")
end
+ it "adds limited role" do
+ params = { user: { user_status: "Limited", note_for_current_role: "limited role added" } }
+ patch user_status_admin_user_path(user.id), params: params
+
+ expect(user.roles.first.name).to eq("limited")
+ expect(Note.first.content).to eq("limited role added")
+ end
+
it "selects new role for user" do
user.add_role(:trusted)
user.reload
diff --git a/spec/services/moderator/manage_activity_and_roles_spec.rb b/spec/services/moderator/manage_activity_and_roles_spec.rb
index 7d7921ea4..7e45fd075 100644
--- a/spec/services/moderator/manage_activity_and_roles_spec.rb
+++ b/spec/services/moderator/manage_activity_and_roles_spec.rb
@@ -16,6 +16,17 @@ RSpec.describe Moderator::ManageActivityAndRoles, type: :service do
expect(user.suspended?).to be false
end
+ it "updates user status to limited" do
+ user.add_role(:limited)
+ user.reload
+ described_class.handle_user_roles(
+ admin: admin,
+ user: user,
+ user_params: { note_for_current_role: "limited user", user_status: "Limited" },
+ )
+ expect(user.limited?).to be true
+ end
+
it "updates user to super admin" do
described_class.handle_user_roles(
admin: admin,