added ability to assign moderator role via admin/super admin (#17759)
* added ability to assign moderator role via admin/super admin * create Mod User in seeds * add Cypress specs * fix failing Cypress tests * fix failing specs by moving test Mod user to the end * nudge Travis * nudge Travis Co-authored-by: Arit Amana <msarit@gmail.com>
This commit is contained in:
parent
eced29ce68
commit
8b70e9e1f3
7 changed files with 153 additions and 65 deletions
|
|
@ -3,7 +3,9 @@ class Role < ApplicationRecord
|
|||
admin
|
||||
codeland_admin
|
||||
comment_suspended
|
||||
creator
|
||||
mod_relations_admin
|
||||
moderator
|
||||
podcast_admin
|
||||
restricted_liquid_tag
|
||||
single_resource_admin
|
||||
|
|
@ -15,7 +17,6 @@ class Role < ApplicationRecord
|
|||
trusted
|
||||
warned
|
||||
workshop_pass
|
||||
creator
|
||||
].freeze
|
||||
|
||||
has_and_belongs_to_many :users, join_table: :users_roles # rubocop:disable Rails/HasAndBelongsToMany
|
||||
|
|
|
|||
|
|
@ -56,44 +56,47 @@ module Moderator
|
|||
|
||||
def handle_user_status(role, note)
|
||||
case role
|
||||
when "Admin"
|
||||
assign_elevated_role_to_user(user, :admin)
|
||||
TagModerators::AddTrustedRole.call(user)
|
||||
when "Comment Suspend"
|
||||
comment_suspended
|
||||
when "Suspend" || "Spammer"
|
||||
user.add_role(:suspended)
|
||||
remove_privileges
|
||||
when "Warn"
|
||||
warned
|
||||
when "Comment Suspend"
|
||||
comment_suspended
|
||||
when "Moderator"
|
||||
assign_elevated_role_to_user(user, :moderator)
|
||||
TagModerators::AddTrustedRole.call(user)
|
||||
when "Regular Member"
|
||||
regular_member
|
||||
when "Trusted"
|
||||
remove_negative_roles
|
||||
TagModerators::AddTrustedRole.call(user)
|
||||
when "Admin"
|
||||
check_super_admin
|
||||
remove_negative_roles
|
||||
user.add_role(:admin)
|
||||
TagModerators::AddTrustedRole.call(user)
|
||||
when "Super Admin"
|
||||
check_super_admin
|
||||
remove_negative_roles
|
||||
user.add_role(:super_admin)
|
||||
TagModerators::AddTrustedRole.call(user)
|
||||
when "Tech Admin"
|
||||
check_super_admin
|
||||
remove_negative_roles
|
||||
user.add_role(:tech_admin)
|
||||
# DataUpdateScripts falls under the admin namespace
|
||||
# and hence requires a single_resource_admin role to view
|
||||
# this technical admin resource
|
||||
user.add_role(:single_resource_admin, DataUpdateScript)
|
||||
when /^(Resource Admin: )/
|
||||
check_super_admin
|
||||
remove_negative_roles
|
||||
user.add_role(:single_resource_admin, role.split("Resource Admin: ").last.safe_constantize)
|
||||
when "Super Admin"
|
||||
assign_elevated_role_to_user(user, :super_admin)
|
||||
TagModerators::AddTrustedRole.call(user)
|
||||
when "Tech Admin"
|
||||
assign_elevated_role_to_user(user, :tech_admin)
|
||||
# DataUpdateScripts falls under the admin namespace
|
||||
# and hence requires a single_resource_admin role to view
|
||||
# this technical admin resource
|
||||
user.add_role(:single_resource_admin, DataUpdateScript)
|
||||
when "Trusted"
|
||||
remove_negative_roles
|
||||
TagModerators::AddTrustedRole.call(user)
|
||||
when "Warn"
|
||||
warned
|
||||
end
|
||||
create_note(role, note)
|
||||
end
|
||||
|
||||
def assign_elevated_role_to_user(user, role)
|
||||
check_super_admin
|
||||
remove_negative_roles
|
||||
user.add_role(role)
|
||||
end
|
||||
|
||||
def check_super_admin
|
||||
raise I18n.t("services.moderator.manage_activity_and_roles.need_super") unless @admin.super_admin?
|
||||
end
|
||||
|
|
|
|||
5
cypress/fixtures/users/moderatorUser.json
Normal file
5
cypress/fixtures/users/moderatorUser.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"username": "moderator_user",
|
||||
"email": "moderator-user@forem.local",
|
||||
"password": "password"
|
||||
}
|
||||
|
|
@ -21,57 +21,96 @@ describe('Moderation Tools for Posts', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should not alter tags from a post if a reason is not specified', () => {
|
||||
cy.fixture('users/adminUser.json').as('adminUser');
|
||||
cy.get('@adminUser').then((user) => {
|
||||
cy.loginAndVisit(user, '/admin_mcadmin/tag-test-article').then(() => {
|
||||
cy.findByRole('button', { name: 'Moderation' }).click();
|
||||
context('as admin user', () => {
|
||||
beforeEach(() => {
|
||||
cy.fixture('users/adminUser.json').as('adminUser');
|
||||
});
|
||||
|
||||
// Helper function for pipe command
|
||||
const click = ($el) => $el.click();
|
||||
it('should not alter tags from a post if a reason is not specified', () => {
|
||||
cy.get('@adminUser').then((user) => {
|
||||
cy.loginAndVisit(user, '/admin_mcadmin/tag-test-article').then(() => {
|
||||
cy.findByRole('button', { name: 'Moderation' }).click();
|
||||
|
||||
cy.getIframeBody('[title="Moderation panel actions"]').within(() => {
|
||||
// We use `pipe` here to retry the click, as the animation of the mod tools opening can sometimes cause the button to not be ready yet
|
||||
cy.findByRole('button', { name: 'Open adjust tags section' })
|
||||
.as('adjustTagsButton')
|
||||
.pipe(click)
|
||||
.should('have.attr', 'aria-expanded', 'true');
|
||||
// Helper function for pipe command
|
||||
const click = ($el) => $el.click();
|
||||
|
||||
cy.findByRole('button', { name: '#tag1 Remove tag' }).click();
|
||||
cy.findByRole('button', { name: 'Submit' }).click();
|
||||
cy.getIframeBody('[title="Moderation panel actions"]').within(() => {
|
||||
// We use `pipe` here to retry the click, as the animation of the mod tools opening can sometimes cause the button to not be ready yet
|
||||
cy.findByRole('button', { name: 'Open adjust tags section' })
|
||||
.as('adjustTagsButton')
|
||||
.pipe(click)
|
||||
.should('have.attr', 'aria-expanded', 'true');
|
||||
|
||||
cy.findByRole('button', { name: '#tag1 Remove tag' }).click();
|
||||
cy.findByRole('button', { name: 'Submit' }).click();
|
||||
});
|
||||
|
||||
cy.findByTestId('snackbar').should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
cy.findByTestId('snackbar').should('not.exist');
|
||||
it('should show Feature Post button on an unfeatured post for an admin user', () => {
|
||||
cy.get('@adminUser').then((user) => {
|
||||
cy.loginAndVisit(user, '/admin_mcadmin/unfeatured-article-slug').then(
|
||||
() => {
|
||||
cy.findByRole('button', { name: 'Moderation' }).click();
|
||||
|
||||
cy.getIframeBody('[title="Moderation panel actions"]').within(
|
||||
() => {
|
||||
cy.findByRole('button', { name: 'Feature Post' }).should(
|
||||
'exist',
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should show Unfeature Post button on a featured post for an admin user', () => {
|
||||
cy.get('@adminUser').then((user) => {
|
||||
cy.loginAndVisit(user, '/admin_mcadmin/test-article-slug').then(() => {
|
||||
cy.findByRole('button', { name: 'Moderation' }).click();
|
||||
|
||||
cy.getIframeBody('[title="Moderation panel actions"]').within(() => {
|
||||
cy.findByRole('button', { name: 'Unfeature Post' }).should('exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should show Feature Post button on an unfeatured post for an admin user', () => {
|
||||
cy.fixture('users/adminUser.json').as('adminUser');
|
||||
cy.get('@adminUser').then((user) => {
|
||||
cy.loginAndVisit(user, '/admin_mcadmin/unfeatured-article-slug').then(
|
||||
() => {
|
||||
cy.findByRole('button', { name: 'Moderation' }).click();
|
||||
|
||||
cy.getIframeBody('[title="Moderation panel actions"]').within(() => {
|
||||
cy.findByRole('button', { name: 'Feature Post' }).should('exist');
|
||||
});
|
||||
},
|
||||
);
|
||||
context('as moderator user', () => {
|
||||
beforeEach(() => {
|
||||
cy.fixture('users/moderatorUser.json').as('moderatorUser');
|
||||
});
|
||||
});
|
||||
|
||||
it('should show Unfeature Post button on a featured post for an admin user', () => {
|
||||
cy.fixture('users/adminUser.json').as('adminUser');
|
||||
cy.get('@adminUser').then((user) => {
|
||||
cy.loginAndVisit(user, '/admin_mcadmin/test-article-slug').then(() => {
|
||||
cy.findByRole('button', { name: 'Moderation' }).click();
|
||||
|
||||
cy.getIframeBody('[title="Moderation panel actions"]').within(() => {
|
||||
cy.findByRole('button', { name: 'Unfeature Post' }).should('exist');
|
||||
it('should load moderation tools on a post for a moderator user', () => {
|
||||
cy.get('@moderatorUser').then((user) => {
|
||||
cy.loginAndVisit(user, '/admin_mcadmin/test-article-slug').then(() => {
|
||||
cy.findByRole('button', { name: 'Moderation' }).should('exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not show Feature Post button on a post for a moderator user', () => {
|
||||
cy.get('@moderatorUser').then((user) => {
|
||||
cy.loginAndVisit(user, '/admin_mcadmin/unfeatured-article-slug').then(
|
||||
() => {
|
||||
cy.findByRole('button', { name: 'Moderation' }).click();
|
||||
|
||||
cy.getIframeBody('[title="Moderation panel actions"]').within(
|
||||
() => {
|
||||
cy.findByRole('button', { name: 'Feature Post' }).should(
|
||||
'not.exist',
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('as trusted user', () => {
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ RSpec.describe Role, type: :model do
|
|||
expected_roles = %w[
|
||||
admin codeland_admin comment_suspended 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
|
||||
trusted warned workshop_pass creator moderator
|
||||
]
|
||||
expect(described_class::ROLES).to eq(expected_roles)
|
||||
expect(described_class::ROLES).to match_array(expected_roles)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -119,5 +119,15 @@ RSpec.describe Moderator::ManageActivityAndRoles, type: :service do
|
|||
)
|
||||
end.to raise_error(StandardError)
|
||||
end
|
||||
|
||||
it "updates user to moderator" do
|
||||
expect do
|
||||
described_class.handle_user_roles(
|
||||
admin: admin,
|
||||
user: user,
|
||||
user_params: { note_for_current_role: "Upgrading to moderator", user_status: "Moderator" },
|
||||
)
|
||||
end.to raise_error(StandardError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ work_attr = ProfileField.find_by(label: "Work").attribute_name
|
|||
education_attr = ProfileField.find_by(label: "Education").attribute_name
|
||||
##############################################################################
|
||||
|
||||
# admin-user needs to be the first user, to maintain specs validity
|
||||
seeder.create_if_doesnt_exist(User, "email", "admin@forem.local") do
|
||||
user = User.create!(
|
||||
name: "Admin McAdmin",
|
||||
|
|
@ -71,6 +72,7 @@ admin_user = User.find_by(email: "admin@forem.local")
|
|||
|
||||
##############################################################################
|
||||
|
||||
# trusted-user-1 needs to be the second user, to maintain specs validity
|
||||
seeder.create_if_doesnt_exist(User, "email", "trusted-user-1@forem.local") do
|
||||
user = User.create!(
|
||||
name: "Trusted User 1 \\:/",
|
||||
|
|
@ -99,6 +101,7 @@ trusted_user = User.find_by(email: "trusted-user-1@forem.local")
|
|||
|
||||
##############################################################################
|
||||
|
||||
# punctuated-name-user needs to remain the 3rd user created, for tests' sake
|
||||
seeder.create_if_doesnt_exist(User, "email", "punctuated-name-user@forem.local") do
|
||||
user = User.create!(
|
||||
name: "User \"The test breaker\" A'postrophe \\:/",
|
||||
|
|
@ -175,6 +178,33 @@ end
|
|||
|
||||
##############################################################################
|
||||
|
||||
seeder.create_if_doesnt_exist(User, "email", "moderator-user@forem.local") do
|
||||
user = User.create!(
|
||||
name: "Moderator User",
|
||||
email: "moderator-user@forem.local",
|
||||
username: "moderator_user",
|
||||
profile_image: File.open(Rails.root.join("app/assets/images/#{rand(1..40)}.png")),
|
||||
confirmed_at: Time.current,
|
||||
registered_at: Time.current,
|
||||
password: "password",
|
||||
password_confirmation: "password",
|
||||
saw_onboarding: true,
|
||||
checked_code_of_conduct: true,
|
||||
checked_terms_and_conditions: true,
|
||||
)
|
||||
user.notification_setting.update(
|
||||
email_comment_notifications: false,
|
||||
email_follower_notifications: false,
|
||||
)
|
||||
|
||||
user.profile.update(website_url: Faker::Internet.url)
|
||||
|
||||
user.add_role(:moderator)
|
||||
user.add_role(:trusted)
|
||||
end
|
||||
|
||||
##############################################################################
|
||||
|
||||
seeder.create_if_doesnt_exist(Organization, "slug", "bachmanity") do
|
||||
organization = Organization.create!(
|
||||
name: "Bachmanity",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue