Skip to content

Commit

Permalink
Unblock User Avo Action (#5029)
Browse files Browse the repository at this point in the history
  • Loading branch information
colby-swandale authored Sep 17, 2024
1 parent 1e79dfa commit 5f8262b
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 0 deletions.
18 changes: 18 additions & 0 deletions app/avo/actions/unblock_user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class UnblockUser < BaseAction
self.name = "Unblock User"
self.visible = lambda {
current_user.team_member?("rubygems-org") && view == :show && record.blocked?
}

self.message = lambda {
"Are you sure you would like to unblock user #{record.handle} with #{record.blocked_email}?"
}

self.confirm_button_label = "Unblock User"

class ActionHandler < ActionHandler
def handle_model(user)
user.unblock!
end
end
end
13 changes: 13 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,19 @@ def block!
end
end

def unblock!
raise ArgumentError, "User is not blocked" unless blocked?

update!(
email: blocked_email,
blocked_email: nil
)
end

def blocked?
blocked_email.present?
end

def owns_gem?(rubygem)
rubygem.owned_by?(self)
end
Expand Down
5 changes: 5 additions & 0 deletions test/factories/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,10 @@
mfa_level { User.mfa_levels["ui_and_gem_signin"] }
mfa_recovery_codes { %w[aaa bbb ccc] }
end

trait :blocked do
email { "security+locked-#{SecureRandom.hex(4)}@rubygems.org" }
blocked_email { "[email protected]" }
end
end
end
43 changes: 43 additions & 0 deletions test/models/user_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,49 @@ class UserTest < ActiveSupport::TestCase
end
end

context "#unblock!" do
setup do
@user = create(:user, :blocked)
@original_email = @user.blocked_email
@user.unblock!
end

should "restore the email field" do
assert_equal @original_email, @user.email
end

should "make the blocked email field nil" do
assert_nil @user.blocked_email
end

context "when the user is not currently blocked" do
setup do
@user = create(:user)
end

should "raise an error" do
assert_raises(ArgumentError) do
@user.unblock!
end
end
end
end

context "#blocked?" do
setup do
@blocked_user = build(:user, :blocked)
@unblocked_user = build(:user)
end

should "be true when the user has a blocked email" do
assert_predicate @blocked_user, :blocked?
end

should "be false when the user does not have a blocked email" do
refute_predicate @unblocked_user, :blocked?
end
end

context ".normalize_email" do
should "return the normalized email" do
assert_equal "[email protected]", User.normalize_email(:"UsEr@\texample . COM")
Expand Down
52 changes: 52 additions & 0 deletions test/unit/avo/actions/unblock_user_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
require "test_helper"

class UnblockUserTest < ActiveSupport::TestCase
setup do
@user = create(:user, :blocked)
@current_user = create(:admin_github_user, :is_admin)
@resource = UserResource.new.hydrate(model: @user)
@action = UnblockUser.new(model: @user, resource: @resource, user: @current_user, view: :edit)
end

should "unblock user" do
args = {
current_user: @current_user,
resource: @resource,
models: [@user],
fields: {
comment: "Unblocking incorrectly flagged user"
}
}

@action.handle(**args)

refute_predicate @user.reload, :blocked?
end

# Avo does not have an easy and direct way to test the message & visible class attributes.
# calling the lambda directly will raise an error because Avo requires the entire app to be loaded.

should "ask for confirmation" do
action_mock = Data.define(:record).new(record: @user)

assert_not_nil action_mock.instance_exec(&UnblockUser.message)
end

should "be visible" do
action_mock = Data.define(:current_user, :view, :record).new(current_user: @current_user, view: :show, record: @user)

assert action_mock.instance_exec(&UnblockUser.visible)
end

context "when the user is not blocked" do
setup do
@user = create(:user)
end

should "not be visible" do
action_mock = Data.define(:current_user, :view, :record).new(current_user: @current_user, view: :show, record: @user)

refute action_mock.instance_exec(&UnblockUser.visible)
end
end
end

0 comments on commit 5f8262b

Please sign in to comment.