diff options
Diffstat (limited to 'spec/controllers/groups')
-rw-r--r-- | spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb | 158 | ||||
-rw-r--r-- | spec/controllers/groups/settings/integrations_controller_spec.rb | 6 |
2 files changed, 135 insertions, 29 deletions
diff --git a/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb b/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb index fa402d556c7..b22307578ab 100644 --- a/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb +++ b/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb @@ -124,6 +124,34 @@ RSpec.describe Groups::DependencyProxyForContainersController do end end + shared_examples 'authorize action with permission' do + context 'with a valid user' do + before do + group.add_guest(user) + end + + it 'sends Workhorse local file instructions', :aggregate_failures do + subject + + expect(response.headers['Content-Type']).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE) + expect(json_response['TempPath']).to eq(DependencyProxy::FileUploader.workhorse_local_upload_path) + expect(json_response['RemoteObject']).to be_nil + expect(json_response['MaximumSize']).to eq(maximum_size) + end + + it 'sends Workhorse remote object instructions', :aggregate_failures do + stub_dependency_proxy_object_storage(direct_upload: true) + + subject + + expect(response.headers['Content-Type']).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE) + expect(json_response['TempPath']).to be_nil + expect(json_response['RemoteObject']).not_to be_nil + expect(json_response['MaximumSize']).to eq(maximum_size) + end + end + end + before do allow(Gitlab.config.dependency_proxy) .to receive(:enabled).and_return(true) @@ -136,7 +164,8 @@ RSpec.describe Groups::DependencyProxyForContainersController do end describe 'GET #manifest' do - let_it_be(:manifest) { create(:dependency_proxy_manifest) } + let_it_be(:tag) { 'latest' } + let_it_be(:manifest) { create(:dependency_proxy_manifest, file_name: "alpine:#{tag}.json", group: group) } let(:pull_response) { { status: :success, manifest: manifest, from_cache: false } } @@ -146,7 +175,7 @@ RSpec.describe Groups::DependencyProxyForContainersController do end end - subject { get_manifest } + subject { get_manifest(tag) } context 'feature enabled' do before do @@ -207,11 +236,26 @@ RSpec.describe Groups::DependencyProxyForContainersController do it_behaves_like 'a successful manifest pull' it_behaves_like 'a package tracking event', described_class.name, 'pull_manifest' - context 'with a cache entry' do - let(:pull_response) { { status: :success, manifest: manifest, from_cache: true } } + context 'with workhorse response' do + let(:pull_response) { { status: :success, manifest: nil, from_cache: false } } - it_behaves_like 'returning response status', :success - it_behaves_like 'a package tracking event', described_class.name, 'pull_manifest_from_cache' + it 'returns Workhorse send-dependency instructions', :aggregate_failures do + subject + + send_data_type, send_data = workhorse_send_data + header, url = send_data.values_at('Header', 'Url') + + expect(send_data_type).to eq('send-dependency') + expect(header).to eq( + "Authorization" => ["Bearer abcd1234"], + "Accept" => ::ContainerRegistry::Client::ACCEPTED_TYPES + ) + expect(url).to eq(DependencyProxy::Registry.manifest_url('alpine', tag)) + expect(response.headers['Content-Type']).to eq('application/gzip') + expect(response.headers['Content-Disposition']).to eq( + ActionDispatch::Http::ContentDisposition.format(disposition: 'attachment', filename: manifest.file_name) + ) + end end end @@ -237,8 +281,8 @@ RSpec.describe Groups::DependencyProxyForContainersController do it_behaves_like 'not found when disabled' - def get_manifest - get :manifest, params: { group_id: group.to_param, image: 'alpine', tag: '3.9.2' } + def get_manifest(tag) + get :manifest, params: { group_id: group.to_param, image: 'alpine', tag: tag } end end @@ -381,39 +425,28 @@ RSpec.describe Groups::DependencyProxyForContainersController do end end - describe 'GET #authorize_upload_blob' do + describe 'POST #authorize_upload_blob' do let(:blob_sha) { 'a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4' } + let(:maximum_size) { DependencyProxy::Blob::MAX_FILE_SIZE } - subject(:authorize_upload_blob) do + subject do request.headers.merge!(workhorse_internal_api_request_header) - get :authorize_upload_blob, params: { group_id: group.to_param, image: 'alpine', sha: blob_sha } + post :authorize_upload_blob, params: { group_id: group.to_param, image: 'alpine', sha: blob_sha } end it_behaves_like 'without permission' - - context 'with a valid user' do - before do - group.add_guest(user) - end - - it 'sends Workhorse file upload instructions', :aggregate_failures do - authorize_upload_blob - - expect(response.headers['Content-Type']).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE) - expect(json_response['TempPath']).to eq(DependencyProxy::FileUploader.workhorse_local_upload_path) - end - end + it_behaves_like 'authorize action with permission' end - describe 'GET #upload_blob' do + describe 'POST #upload_blob' do let(:blob_sha) { 'a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4' } let(:file) { fixture_file_upload("spec/fixtures/dependency_proxy/#{blob_sha}.gz", 'application/gzip') } subject do request.headers.merge!(workhorse_internal_api_request_header) - get :upload_blob, params: { + post :upload_blob, params: { group_id: group.to_param, image: 'alpine', sha: blob_sha, @@ -436,6 +469,79 @@ RSpec.describe Groups::DependencyProxyForContainersController do end end + describe 'POST #authorize_upload_manifest' do + let(:maximum_size) { DependencyProxy::Manifest::MAX_FILE_SIZE } + + subject do + request.headers.merge!(workhorse_internal_api_request_header) + + post :authorize_upload_manifest, params: { group_id: group.to_param, image: 'alpine', tag: 'latest' } + end + + it_behaves_like 'without permission' + it_behaves_like 'authorize action with permission' + end + + describe 'POST #upload_manifest' do + let_it_be(:file) { fixture_file_upload("spec/fixtures/dependency_proxy/manifest", 'application/json') } + let_it_be(:image) { 'alpine' } + let_it_be(:tag) { 'latest' } + let_it_be(:content_type) { 'v2/manifest' } + let_it_be(:digest) { 'foo' } + let_it_be(:file_name) { "#{image}:#{tag}.json" } + + subject do + request.headers.merge!( + workhorse_internal_api_request_header.merge!( + { + Gitlab::Workhorse::SEND_DEPENDENCY_CONTENT_TYPE_HEADER => content_type, + DependencyProxy::Manifest::DIGEST_HEADER => digest + } + ) + ) + params = { + group_id: group.to_param, + image: image, + tag: tag, + file: file, + file_name: file_name + } + + post :upload_manifest, params: params + end + + it_behaves_like 'without permission' + + context 'with a valid user' do + before do + group.add_guest(user) + end + + it_behaves_like 'a package tracking event', described_class.name, 'pull_manifest' + + context 'with no existing manifest' do + it 'creates a manifest' do + expect { subject }.to change { group.dependency_proxy_manifests.count }.by(1) + + manifest = group.dependency_proxy_manifests.first.reload + expect(manifest.content_type).to eq(content_type) + expect(manifest.digest).to eq(digest) + expect(manifest.file_name).to eq(file_name) + end + end + + context 'with existing stale manifest' do + let_it_be(:old_digest) { 'asdf' } + let_it_be_with_reload(:manifest) { create(:dependency_proxy_manifest, file_name: file_name, digest: old_digest, group: group) } + + it 'updates the existing manifest' do + expect { subject }.to change { group.dependency_proxy_manifests.count }.by(0) + .and change { manifest.reload.digest }.from(old_digest).to(digest) + end + end + end + end + def enable_dependency_proxy group.create_dependency_proxy_setting!(enabled: true) end diff --git a/spec/controllers/groups/settings/integrations_controller_spec.rb b/spec/controllers/groups/settings/integrations_controller_spec.rb index 31d1946652d..c070094babd 100644 --- a/spec/controllers/groups/settings/integrations_controller_spec.rb +++ b/spec/controllers/groups/settings/integrations_controller_spec.rb @@ -10,7 +10,7 @@ RSpec.describe Groups::Settings::IntegrationsController do sign_in(user) end - it_behaves_like IntegrationsActions do + it_behaves_like Integrations::Actions do let(:integration_attributes) { { group: group, project: nil } } let(:routing_params) do @@ -78,7 +78,7 @@ RSpec.describe Groups::Settings::IntegrationsController do describe '#update' do include JiraServiceHelper - let(:integration) { create(:jira_integration, project: nil, group_id: group.id) } + let(:integration) { create(:jira_integration, :group, group: group) } before do group.add_owner(user) @@ -108,7 +108,7 @@ RSpec.describe Groups::Settings::IntegrationsController do end describe '#reset' do - let_it_be(:integration) { create(:jira_integration, group: group, project: nil) } + let_it_be(:integration) { create(:jira_integration, :group, group: group) } let_it_be(:inheriting_integration) { create(:jira_integration, inherit_from_id: integration.id) } subject do |