Commit 4219002f authored by Robert Speicher's avatar Robert Speicher

Greatly reduce test duration for git_access_spec

- Combine multiple `it` blocks into one where it made sense
- Use `set` for the top-level User record
- Refactor permission matrix tests
parent e4424496
require 'spec_helper'
describe Gitlab::GitAccess do
let(:pull_access_check) { access.check('git-upload-pack', '_any') }
let(:push_access_check) { access.check('git-receive-pack', '_any') }
let(:access) { described_class.new(actor, project, protocol, authentication_abilities: authentication_abilities, redirected_path: redirected_path) }
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
set(:user) { create(:user) }
let(:actor) { user }
let(:project) { create(:project, :repository) }
let(:protocol) { 'ssh' }
let(:authentication_abilities) { %i[read_project download_code push_code] }
let(:redirected_path) { nil }
let(:authentication_abilities) do
[
:read_project,
:download_code,
:push_code
]
end
let(:access) { described_class.new(actor, project, protocol, authentication_abilities: authentication_abilities, redirected_path: redirected_path) }
let(:push_access_check) { access.check('git-receive-pack', '_any') }
let(:pull_access_check) { access.check('git-upload-pack', '_any') }
describe '#check with single protocols allowed' do
def disable_protocol(protocol)
......@@ -27,14 +23,13 @@ describe Gitlab::GitAccess do
disable_protocol('ssh')
end
it 'blocks ssh git push' do
it 'blocks ssh git push and pull' do
aggregate_failures do
expect { push_access_check }.to raise_unauthorized('Git access over SSH is not allowed')
end
it 'blocks ssh git pull' do
expect { pull_access_check }.to raise_unauthorized('Git access over SSH is not allowed')
end
end
end
context 'http disabled' do
let(:protocol) { 'http' }
......@@ -43,15 +38,14 @@ describe Gitlab::GitAccess do
disable_protocol('http')
end
it 'blocks http push' do
it 'blocks http push and pull' do
aggregate_failures do
expect { push_access_check }.to raise_unauthorized('Git access over HTTP is not allowed')
end
it 'blocks http git pull' do
expect { pull_access_check }.to raise_unauthorized('Git access over HTTP is not allowed')
end
end
end
end
describe '#check_project_accessibility!' do
context 'when the project exists' do
......@@ -65,22 +59,20 @@ describe Gitlab::GitAccess do
deploy_key.projects << project
end
it 'allows pull access' do
it 'allows push and pull access' do
aggregate_failures do
expect { push_access_check }.not_to raise_error
expect { pull_access_check }.not_to raise_error
end
it 'allows push access' do
expect { push_access_check }.not_to raise_error
end
end
context 'when the Deploykey does not have access to the project' do
it 'blocks pulls with "not found"' do
it 'blocks push and pull with "not found"' do
aggregate_failures do
expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.')
expect { pull_access_check }.to raise_not_found('The project you were looking for could not be found.')
end
it 'blocks pushes with "not found"' do
expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.')
end
end
end
......@@ -88,25 +80,23 @@ describe Gitlab::GitAccess do
context 'when actor is a User' do
context 'when the User can read the project' do
before do
project.team << [user, :master]
project.add_master(user)
end
it 'allows pull access' do
it 'allows push and pull access' do
aggregate_failures do
expect { pull_access_check }.not_to raise_error
end
it 'allows push access' do
expect { push_access_check }.not_to raise_error
end
end
end
context 'when the User cannot read the project' do
it 'blocks pulls with "not found"' do
it 'blocks push and pull with "not found"' do
aggregate_failures do
expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.')
expect { pull_access_check }.to raise_not_found('The project you were looking for could not be found.')
end
it 'blocks pushes with "not found"' do
expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.')
end
end
end
......@@ -156,48 +146,50 @@ describe Gitlab::GitAccess do
context 'when the project is nil' do
let(:project) { nil }
it 'blocks any command with "not found"' do
it 'blocks push and pull with "not found"' do
aggregate_failures do
expect { pull_access_check }.to raise_not_found('The project you were looking for could not be found.')
expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.')
end
end
end
end
describe '#check_project_moved!' do
before do
project.team << [user, :master]
project.add_master(user)
end
context 'when a redirect was not followed to find the project' do
context 'pull code' do
it { expect { pull_access_check }.not_to raise_error }
it 'allows push and pull access' do
aggregate_failures do
expect { push_access_check }.not_to raise_error
expect { pull_access_check }.not_to raise_error
end
context 'push code' do
it { expect { push_access_check }.not_to raise_error }
end
end
context 'when a redirect was followed to find the project' do
let(:redirected_path) { 'some/other-path' }
context 'pull code' do
it { expect { pull_access_check }.to raise_not_found(/Project '#{redirected_path}' was moved to '#{project.full_path}'/) }
it { expect { pull_access_check }.to raise_not_found(/git remote set-url origin #{project.ssh_url_to_repo}/) }
it 'blocks push and pull access' do
aggregate_failures do
expect { push_access_check }.to raise_not_found(/Project '#{redirected_path}' was moved to '#{project.full_path}'/)
expect { push_access_check }.to raise_not_found(/git remote set-url origin #{project.ssh_url_to_repo}/)
context 'http protocol' do
let(:protocol) { 'http' }
it { expect { pull_access_check }.to raise_not_found(/git remote set-url origin #{project.http_url_to_repo}/) }
expect { pull_access_check }.to raise_not_found(/Project '#{redirected_path}' was moved to '#{project.full_path}'/)
expect { pull_access_check }.to raise_not_found(/git remote set-url origin #{project.ssh_url_to_repo}/)
end
end
context 'push code' do
it { expect { push_access_check }.to raise_not_found(/Project '#{redirected_path}' was moved to '#{project.full_path}'/) }
it { expect { push_access_check }.to raise_not_found(/git remote set-url origin #{project.ssh_url_to_repo}/) }
context 'http protocol' do
let(:protocol) { 'http' }
it { expect { push_access_check }.to raise_not_found(/git remote set-url origin #{project.http_url_to_repo}/) }
it 'includes the path to the project using HTTP' do
aggregate_failures do
expect { push_access_check }.to raise_not_found(/git remote set-url origin #{project.http_url_to_repo}/)
expect { pull_access_check }.to raise_not_found(/git remote set-url origin #{project.http_url_to_repo}/)
end
end
end
end
......@@ -242,35 +234,23 @@ describe Gitlab::GitAccess do
end
describe '#check_download_access!' do
describe 'master permissions' do
before do
project.team << [user, :master]
end
it 'allows masters to pull' do
project.add_master(user)
context 'pull code' do
it { expect { pull_access_check }.not_to raise_error }
end
expect { pull_access_check }.not_to raise_error
end
describe 'guest permissions' do
before do
project.team << [user, :guest]
end
it 'disallows guests to pull' do
project.add_guest(user)
context 'pull code' do
it { expect { pull_access_check }.to raise_unauthorized('You are not allowed to download code from this project.') }
end
expect { pull_access_check }.to raise_unauthorized('You are not allowed to download code from this project.')
end
describe 'blocked user' do
before do
project.team << [user, :master]
it 'disallows blocked users to pull' do
project.add_master(user)
user.block
end
context 'pull code' do
it { expect { pull_access_check }.to raise_unauthorized('Your account has been blocked.') }
end
expect { pull_access_check }.to raise_unauthorized('Your account has been blocked.')
end
describe 'without access to project' do
......@@ -440,28 +420,30 @@ describe Gitlab::GitAccess do
end
end
# Run permission checks for a user
def self.run_permission_checks(permissions_matrix)
permissions_matrix.keys.each do |role|
describe "#{role} access" do
before do
permissions_matrix.each_pair do |role, matrix|
# Run through the entire matrix for this role in one test to avoid
# repeated setup.
#
# Expectations are given a custom failure message proc so that it's
# easier to identify which check(s) failed.
it "has the correct permissions for #{role}s" do
if role == :admin
user.update_attribute(:admin, true)
else
project.team << [user, role]
end
end
permissions_matrix[role].each do |action, allowed|
context action.to_s do
subject { access.send(:check_push_access!, changes[action]) }
aggregate_failures do
matrix.each do |action, allowed|
check = -> { access.send(:check_push_access!, changes[action]) }
it do
if allowed
expect { subject }.not_to raise_error
expect(&check).not_to raise_error,
-> { "expected #{action} to be allowed" }
else
expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError)
end
expect(&check).to raise_error(Gitlab::GitAccess::UnauthorizedError),
-> { "expected #{action} to be disallowed" }
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment