gitlab-org--gitlab-foss/spec/services/packages/maven/find_or_create_package_serv...

172 lines
5.8 KiB
Ruby

# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Packages::Maven::FindOrCreatePackageService do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let(:app_name) { 'my-app' }
let(:path) { "sandbox/test/app/#{app_name}" }
let(:version) { '1.0.0' }
let(:file_name) { 'test.jar' }
let(:param_path) { "#{path}/#{version}" }
let(:params) { { path: param_path, file_name: file_name } }
let(:service) { described_class.new(project, user, params) }
describe '#execute' do
using RSpec::Parameterized::TableSyntax
subject { service.execute }
shared_examples 'reuse existing package' do
it { expect { subject }.not_to change { Packages::Package.count } }
it 'returns the existing package' do
expect(subject.payload).to eq(package: existing_package)
end
end
shared_examples 'create package' do
it { expect { subject }.to change { Packages::Package.count }.by(1) }
it 'sets the proper name and version', :aggregate_failures do
pkg = subject.payload[:package]
expect(pkg.name).to eq(path)
expect(pkg.version).to eq(version)
end
context 'with optional attributes' do
subject { service.execute.payload[:package] }
it_behaves_like 'assigns build to package'
it_behaves_like 'assigns status to package'
end
end
context 'path with version' do
# Note that "path with version" and "file type maven metadata xml" only exists for snapshot versions
# In other words, we will never have an metadata xml upload on a path with version for a non snapshot version
where(:package_exist, :file_type, :snapshot_version, :shared_example_name) do
true | :jar | false | 'reuse existing package'
false | :jar | false | 'create package'
true | :jar | true | 'reuse existing package'
false | :jar | true | 'create package'
true | :maven_xml | true | 'reuse existing package'
false | :maven_xml | true | 'create package'
end
with_them do
let(:version) { snapshot_version ? '1.0-SNAPSHOT' : '1.0.0' }
let(:file_name) { file_type == :maven_xml ? 'maven-metadata.xml' : 'test.jar' }
let!(:existing_package) do
if package_exist
create(:maven_package, name: path, version: version, project: project)
end
end
it_behaves_like params[:shared_example_name]
end
end
context 'path without version' do
let(:param_path) { path }
let(:version) { nil }
context 'maven-metadata.xml file' do
let(:file_name) { 'maven-metadata.xml' }
context 'with existing package' do
let!(:existing_package) { create(:maven_package, name: path, version: version, project: project) }
it_behaves_like 'reuse existing package'
context 'marked as pending_destruction' do
before do
existing_package.pending_destruction!
end
it_behaves_like 'create package'
end
end
context 'without existing package' do
it_behaves_like 'create package'
end
end
end
context 'with a build' do
let_it_be(:pipeline) { create(:ci_pipeline, user: user) }
let(:build) { double('build', pipeline: pipeline) }
let(:params) { { path: param_path, file_name: file_name, build: build } }
it 'creates a build_info' do
expect { subject }.to change { Packages::BuildInfo.count }.by(1)
end
context 'with multiple files for the same package and the same pipeline' do
let(:file_2_params) { params.merge(file_name: 'test2.jar') }
let(:file_3_params) { params.merge(file_name: 'test3.jar') }
it 'creates a single build info' do
expect do
described_class.new(project, user, params).execute
described_class.new(project, user, file_2_params).execute
described_class.new(project, user, file_3_params).execute
end.to change { ::Packages::BuildInfo.count }.by(1)
end
end
end
context 'when package duplicates are not allowed' do
let_it_be_with_refind(:package_settings) { create(:namespace_package_setting, :group, maven_duplicates_allowed: false) }
let_it_be_with_refind(:group) { package_settings.namespace }
let_it_be_with_refind(:project) { create(:project, group: group) }
let!(:existing_package) { create(:maven_package, name: path, version: version, project: project) }
it { expect { subject }.not_to change { project.package_files.count } }
it 'returns an error', :aggregate_failures do
expect(subject.payload).to be_empty
expect(subject.errors).to include('Duplicate package is not allowed')
end
context 'when uploading to the versionless package which contains metadata about all versions' do
let(:version) { nil }
let(:param_path) { path }
it_behaves_like 'reuse existing package'
end
context 'when uploading different non-duplicate files to the same package' do
before do
package_file = existing_package.package_files.find_by(file_name: 'my-app-1.0-20180724.124855-1.jar')
package_file.destroy!
end
it_behaves_like 'reuse existing package'
end
context 'when the package name matches the exception regex' do
before do
package_settings.update!(maven_duplicate_exception_regex: existing_package.name)
end
it_behaves_like 'reuse existing package'
end
context 'when the package version matches the exception regex' do
before do
package_settings.update!(maven_duplicate_exception_regex: existing_package.version)
end
it_behaves_like 'reuse existing package'
end
end
end
end