diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/action/custom_spec.rb | 136 | ||||
-rw-r--r-- | spec/gitlab_shell_spec.rb | 23 | ||||
-rw-r--r-- | spec/vcr_cassettes/custom-action-not-ok-json.yml | 40 | ||||
-rw-r--r-- | spec/vcr_cassettes/custom-action-not-ok-not-json.yml | 40 | ||||
-rw-r--r-- | spec/vcr_cassettes/custom-action-ok-not-json.yml | 51 | ||||
-rw-r--r-- | spec/vcr_cassettes/custom-action-ok.yml | 99 |
6 files changed, 389 insertions, 0 deletions
diff --git a/spec/action/custom_spec.rb b/spec/action/custom_spec.rb new file mode 100644 index 0000000..e85df71 --- /dev/null +++ b/spec/action/custom_spec.rb @@ -0,0 +1,136 @@ +require_relative '../spec_helper' +require_relative '../../lib/action/custom' + +describe Action::Custom do + let(:repo_name) { 'gitlab-ci.git' } + let(:gl_id) { 'key-1' } + let(:secret) { "0a3938d9d95d807e94d937af3a4fbbea" } + let(:base_url) { 'http://localhost:3000' } + + subject { described_class.new(gl_id, payload) } + + describe '#execute' do + context 'with an empty payload' do + let(:payload) { {} } + + it 'raises a MissingPayloadError exception' do + expect { subject.execute }.to raise_error(Action::Custom::MissingPayloadError) + end + end + + context 'with api_endpoints defined' do + before do + allow(subject).to receive(:base_url).and_return(base_url) + allow(subject).to receive(:secret_token).and_return(secret) + allow($stdin).to receive(:read).and_return('') + end + + context 'that are valid' do + let(:payload) do + { + 'action' => 'geo_proxy_to_primary', + 'data' => { + 'api_endpoints' => %w{/api/v4/fake/info_refs /api/v4/fake/push}, + 'gl_username' => 'user1', + 'primary_repo' => 'http://localhost:3001/user1/repo1.git' + } + } + end + + context 'and responds correctly' do + it 'returns an instance of Net::HTTPCreated' do + VCR.use_cassette("custom-action-ok") do + expect(subject.execute).to be_instance_of(Net::HTTPCreated) + end + end + end + + context 'but responds incorrectly' do + it 'raises an UnsuccessfulError exception' do + VCR.use_cassette("custom-action-ok-not-json") do + expect { + subject.execute + }.to raise_error(Action::Custom::UnsuccessfulError, 'Response was not valid JSON') + end + end + end + end + + context 'that are invalid' do + context 'where api_endpoints gl_id is missing' do + let(:payload) do + { + 'action' => 'geo_proxy_to_primary', + 'data' => { + 'gl_username' => 'user1', + 'primary_repo' => 'http://localhost:3001/user1/repo1.git' + } + } + end + + it 'raises a MissingAPIEndpointsError exception' do + expect { subject.execute }.to raise_error(Action::Custom::MissingAPIEndpointsError) + end + end + + context 'where api_endpoints are empty' do + let(:payload) do + { + 'action' => 'geo_proxy_to_primary', + 'data' => { + 'api_endpoints' => [], + 'gl_username' => 'user1', + 'primary_repo' => 'http://localhost:3001/user1/repo1.git' + } + } + end + + it 'raises a MissingAPIEndpointsError exception' do + expect { subject.execute }.to raise_error(Action::Custom::MissingAPIEndpointsError) + end + end + + context 'where data gl_id is missing' do + let(:payload) { { 'api_endpoints' => %w{/api/v4/fake/info_refs /api/v4/fake/push} } } + + it 'raises a MissingDataError exception' do + expect { subject.execute }.to raise_error(Action::Custom::MissingDataError) + end + end + + context 'where API endpoints are bad' do + let(:payload) do + { + 'action' => 'geo_proxy_to_primary', + 'data' => { + 'api_endpoints' => %w{/api/v4/fake/info_refs_bad /api/v4/fake/push_bad}, + 'gl_username' => 'user1', + 'primary_repo' => 'http://localhost:3001/user1/repo1.git' + } + } + end + + context 'and response is JSON' do + it 'raises an UnsuccessfulError exception' do + VCR.use_cassette("custom-action-not-ok-json") do + expect { + subject.execute + }.to raise_error(Action::Custom::UnsuccessfulError, 'You cannot perform write operations on a read-only instance (403)') + end + end + end + + context 'and response is not JSON' do + it 'raises an UnsuccessfulError exception' do + VCR.use_cassette("custom-action-not-ok-not-json") do + expect { + subject.execute + }.to raise_error(Action::Custom::UnsuccessfulError, 'No message (403)') + end + end + end + end + end + end + end +end diff --git a/spec/gitlab_shell_spec.rb b/spec/gitlab_shell_spec.rb index 24fe151..77fb6cd 100644 --- a/spec/gitlab_shell_spec.rb +++ b/spec/gitlab_shell_spec.rb @@ -256,6 +256,29 @@ describe GitlabShell do user_string = "user with id #{gl_id}" expect($logger).to receive(:info).with(message, command: "gitaly-receive-pack unix:gitaly.socket #{gitaly_message}", user: user_string) end + + context 'with a custom action' do + let(:fake_payload) { { 'api_endpoints' => [ '/fake/api/endpoint' ], 'data' => {} } } + let(:custom_action_gitlab_access_status) do + GitAccessStatus.new( + true, + HTTPCodes::HTTP_MULTIPLE_CHOICES, + 'Multiple Choices', + payload: fake_payload + ) + end + let(:action_custom) { double(Action::Custom) } + + before do + allow(api).to receive(:check_access).and_return(custom_action_gitlab_access_status) + end + + it "should not process the command" do + expect(subject).to_not receive(:process_cmd).with(%w(git-receive-pack gitlab-ci.git)) + expect(Action::Custom).to receive(:new).with(gl_id, fake_payload).and_return(action_custom) + expect(action_custom).to receive(:execute) + end + end end context 'gitaly-receive-pack' do diff --git a/spec/vcr_cassettes/custom-action-not-ok-json.yml b/spec/vcr_cassettes/custom-action-not-ok-json.yml new file mode 100644 index 0000000..e50719d --- /dev/null +++ b/spec/vcr_cassettes/custom-action-not-ok-json.yml @@ -0,0 +1,40 @@ +--- +http_interactions: +- request: + method: post + uri: http://localhost:3000/api/v4/fake/info_refs_bad + body: + encoding: UTF-8 + string: '{"data":{"gl_username":"user1","primary_repo":"http://localhost:3001/user1/repo1.git","gl_id":"key-11"},"output":"","secret_token":"0a3938d9d95d807e94d937af3a4fbbea\n"}' + headers: + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + Host: + - localhost + response: + status: + code: 403 + message: Forbidden + headers: + Date: + - Fri, 20 Jul 2018 06:54:21 GMT + Connection: + - close + Content-Type: + - application/json + X-Request-Id: + - ea0644ac-e1ad-45f6-aa72-cc7910274318 + X-Runtime: + - '1.236672' + body: + encoding: UTF-8 + string: '{"message":"You cannot perform write operations on a read-only instance"}' + http_version: + recorded_at: Fri, 20 Jul 2018 06:54:21 GMT +recorded_with: VCR 2.4.0 diff --git a/spec/vcr_cassettes/custom-action-not-ok-not-json.yml b/spec/vcr_cassettes/custom-action-not-ok-not-json.yml new file mode 100644 index 0000000..b60a93a --- /dev/null +++ b/spec/vcr_cassettes/custom-action-not-ok-not-json.yml @@ -0,0 +1,40 @@ +--- +http_interactions: +- request: + method: post + uri: http://localhost:3000/api/v4/fake/info_refs_bad + body: + encoding: UTF-8 + string: '{"data":{"gl_username":"user1","primary_repo":"http://localhost:3001/user1/repo1.git","gl_id":"key-11"},"output":"","secret_token":"0a3938d9d95d807e94d937af3a4fbbea\n"}' + headers: + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + Host: + - localhost + response: + status: + code: 403 + message: Forbidden + headers: + Date: + - Fri, 20 Jul 2018 06:54:21 GMT + Connection: + - close + Content-Type: + - application/json + X-Request-Id: + - ea0644ac-e1ad-45f6-aa72-cc7910274318 + X-Runtime: + - '1.236672' + body: + encoding: UTF-8 + string: '""' + http_version: + recorded_at: Fri, 20 Jul 2018 06:54:21 GMT +recorded_with: VCR 2.4.0 diff --git a/spec/vcr_cassettes/custom-action-ok-not-json.yml b/spec/vcr_cassettes/custom-action-ok-not-json.yml new file mode 100644 index 0000000..3bfb390 --- /dev/null +++ b/spec/vcr_cassettes/custom-action-ok-not-json.yml @@ -0,0 +1,51 @@ +--- +http_interactions: +- request: + method: post + uri: http://localhost:3000/api/v4/fake/info_refs + body: + encoding: UTF-8 + string: '{"data":{"gl_username":"user1","primary_repo":"http://localhost:3001/user1/repo1.git","gl_id":"key-1"},"output":"","secret_token":"0a3938d9d95d807e94d937af3a4fbbea"}' + headers: + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + Host: + - localhost + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 20 Jul 2018 06:18:58 GMT + Connection: + - close + X-Frame-Options: + - SAMEORIGIN + X-Content-Type-Options: + - nosniff + Content-Type: + - application/json + Content-Length: + - '172' + Vary: + - Origin + Etag: + - W/"7d01e1e3dbcbe7cca9607461352f8244" + Cache-Control: + - max-age=0, private, must-revalidate + X-Request-Id: + - 03afa234-b6be-49ab-9392-4aa35c5dee25 + X-Runtime: + - '1.436040' + body: + encoding: UTF-8 + string: '""' + http_version: + recorded_at: Fri, 20 Jul 2018 06:18:58 GMT diff --git a/spec/vcr_cassettes/custom-action-ok.yml b/spec/vcr_cassettes/custom-action-ok.yml new file mode 100644 index 0000000..a057441 --- /dev/null +++ b/spec/vcr_cassettes/custom-action-ok.yml @@ -0,0 +1,99 @@ +--- +http_interactions: +- request: + method: post + uri: http://localhost:3000/api/v4/fake/info_refs + body: + encoding: UTF-8 + string: '{"data":{"gl_username":"user1","primary_repo":"http://localhost:3001/user1/repo1.git","gl_id":"key-1"},"output":"","secret_token":"0a3938d9d95d807e94d937af3a4fbbea"}' + headers: + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + Host: + - localhost + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 20 Jul 2018 06:18:58 GMT + Connection: + - close + X-Frame-Options: + - SAMEORIGIN + X-Content-Type-Options: + - nosniff + Content-Type: + - application/json + Content-Length: + - '172' + Vary: + - Origin + Etag: + - W/"7d01e1e3dbcbe7cca9607461352f8244" + Cache-Control: + - max-age=0, private, must-revalidate + X-Request-Id: + - 03afa234-b6be-49ab-9392-4aa35c5dee25 + X-Runtime: + - '1.436040' + body: + encoding: UTF-8 + string: '{"result":"info_refs-result"}' + http_version: + recorded_at: Fri, 20 Jul 2018 06:18:58 GMT +- request: + method: post + uri: http://localhost:3000/api/v4/fake/push + body: + encoding: UTF-8 + string: '{"data":{"gl_username":"user1","primary_repo":"http://localhost:3001/user1/repo1.git","gl_id":"key-1"},"output":"info_refs-result","secret_token":"0a3938d9d95d807e94d937af3a4fbbea"}' + headers: + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + Host: + - localhost + response: + status: + code: 201 + message: Created + headers: + Date: + - Fri, 20 Jul 2018 06:19:08 GMT + Connection: + - close + X-Frame-Options: + - SAMEORIGIN + X-Content-Type-Options: + - nosniff + Content-Type: + - application/json + Content-Length: + - '13' + Vary: + - Origin + Cache-Control: + - no-cache + X-Request-Id: + - 0c6894ac-7f8e-4cdb-871f-4cb64d3731ca + X-Runtime: + - '0.786754' + body: + encoding: UTF-8 + string: '{"result":"push-result"}' + http_version: + recorded_at: Fri, 20 Jul 2018 06:19:08 GMT +recorded_with: VCR 2.4.0 |