80 lines
2.1 KiB
Ruby
80 lines
2.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# AccessMatchers
|
|
#
|
|
# The custom matchers contained in this module are used to test a user's access
|
|
# to a URL by emulating a specific user or type of user account, visiting the
|
|
# URL, and then checking the response status code and resulting path.
|
|
module AccessMatchers
|
|
extend RSpec::Matchers::DSL
|
|
include Warden::Test::Helpers
|
|
|
|
def emulate_user(user_type_or_trait, membership = nil)
|
|
case user_type_or_trait
|
|
when :user, :admin
|
|
login_as(create(user_type_or_trait))
|
|
when :external, :auditor
|
|
login_as(create(:user, user_type_or_trait))
|
|
when :visitor
|
|
logout
|
|
when User
|
|
login_as(user_type_or_trait)
|
|
when *Gitlab::Access.sym_options_with_owner.keys
|
|
raise ArgumentError, "cannot emulate #{user_type_or_trait} without membership parent" unless membership
|
|
|
|
role = user_type_or_trait
|
|
user =
|
|
if role == :owner && membership.owner
|
|
membership.owner
|
|
else
|
|
create(:user).tap do |new_user|
|
|
membership.public_send(:"add_#{role}", new_user)
|
|
end
|
|
end
|
|
|
|
login_as(user)
|
|
else
|
|
raise ArgumentError, "cannot emulate user #{user}"
|
|
end
|
|
end
|
|
|
|
def description_for(user, type)
|
|
if user.is_a?(User)
|
|
# User#inspect displays too much information for RSpec's descriptions
|
|
"be #{type} for the specified user"
|
|
else
|
|
"be #{type} for #{user}"
|
|
end
|
|
end
|
|
|
|
matcher :be_allowed_for do |user|
|
|
match do |url|
|
|
emulate_user(user, @membership)
|
|
visit(url)
|
|
|
|
status_code == 200 && !current_path.in?([new_user_session_path, new_admin_session_path])
|
|
end
|
|
|
|
chain :of do |membership|
|
|
@membership = membership
|
|
end
|
|
|
|
description { description_for(user, 'allowed') }
|
|
end
|
|
|
|
matcher :be_denied_for do |user|
|
|
match do |url|
|
|
emulate_user(user, @membership)
|
|
visit(url)
|
|
|
|
[401, 404].include?(status_code) || current_path.in?([new_user_session_path, new_admin_session_path])
|
|
end
|
|
|
|
chain :of do |membership|
|
|
@membership = membership
|
|
end
|
|
|
|
description { description_for(user, 'denied') }
|
|
end
|
|
end
|