summaryrefslogtreecommitdiff
path: root/spec/models/packages
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/packages')
-rw-r--r--spec/models/packages/debian/file_metadatum_spec.rb44
-rw-r--r--spec/models/packages/debian/group_distribution_spec.rb7
-rw-r--r--spec/models/packages/debian/project_distribution_spec.rb7
-rw-r--r--spec/models/packages/dependency_spec.rb19
-rw-r--r--spec/models/packages/event_spec.rb51
-rw-r--r--spec/models/packages/npm/metadata_cache_spec.rb150
-rw-r--r--spec/models/packages/npm/metadatum_spec.rb14
-rw-r--r--spec/models/packages/package_file_spec.rb12
-rw-r--r--spec/models/packages/package_spec.rb79
9 files changed, 349 insertions, 34 deletions
diff --git a/spec/models/packages/debian/file_metadatum_spec.rb b/spec/models/packages/debian/file_metadatum_spec.rb
index 1215adfa6a1..e86c0a71c9a 100644
--- a/spec/models/packages/debian/file_metadatum_spec.rb
+++ b/spec/models/packages/debian/file_metadatum_spec.rb
@@ -2,15 +2,15 @@
require 'spec_helper'
-RSpec.describe Packages::Debian::FileMetadatum, type: :model do
- RSpec.shared_context 'Debian file metadatum' do |factory, trait|
- let_it_be_with_reload(:debian_package_file) { create(factory, trait) }
+RSpec.describe Packages::Debian::FileMetadatum, type: :model, feature_category: :package_registry do
+ RSpec.shared_context 'with Debian file metadatum' do |package_file_trait|
+ let_it_be_with_reload(:debian_package_file) { create(:debian_package_file, package_file_trait) }
let(:debian_file_metadatum) { debian_package_file.debian_file_metadatum }
subject { debian_file_metadatum }
end
- RSpec.shared_examples 'Test Debian file metadatum' do |has_component, has_architecture, has_fields, has_outdated|
+ RSpec.shared_examples 'Test Debian file metadatum' do |has_component, has_architecture, has_fields|
describe 'relationships' do
it { is_expected.to belong_to(:package_file) }
end
@@ -51,8 +51,8 @@ RSpec.describe Packages::Debian::FileMetadatum, type: :model do
describe '#fields' do
if has_fields
it { is_expected.to validate_presence_of(:fields) }
- it { is_expected.to allow_value({ 'a': 'b' }).for(:fields) }
- it { is_expected.not_to allow_value({ 'a': { 'b': 'c' } }).for(:fields) }
+ it { is_expected.to allow_value({ a: 'b' }).for(:fields) }
+ it { is_expected.not_to allow_value({ a: { b: 'c' } }).for(:fields) }
else
it { is_expected.to validate_absence_of(:fields) }
end
@@ -69,23 +69,35 @@ RSpec.describe Packages::Debian::FileMetadatum, type: :model do
end
end
end
+
+ describe 'scopes' do
+ describe '.with_file_type' do
+ subject { described_class.with_file_type(package_file_trait) }
+
+ it 'returns the matching file metadatum' do
+ expect(subject).to match_array([debian_file_metadatum])
+ end
+ end
+ end
end
using RSpec::Parameterized::TableSyntax
- where(:factory, :trait, :has_component, :has_architecture, :has_fields) do
- :debian_package_file | :unknown | false | false | false
- :debian_package_file | :source | true | false | false
- :debian_package_file | :dsc | true | false | true
- :debian_package_file | :deb | true | true | true
- :debian_package_file | :udeb | true | true | true
- :debian_package_file | :buildinfo | true | false | true
- :debian_package_file | :changes | false | false | true
+ where(:package_file_trait, :has_component, :has_architecture, :has_fields) do
+ :unknown | false | false | false
+ :source | true | false | false
+ :dsc | true | false | true
+ :deb | true | true | true
+ :udeb | true | true | true
+ :ddeb | true | true | true
+ :buildinfo | true | false | true
+ :changes | false | false | true
end
with_them do
- include_context 'Debian file metadatum', params[:factory], params[:trait] do
- it_behaves_like 'Test Debian file metadatum', params[:has_component], params[:has_architecture], params[:has_fields], params[:has_outdated]
+ include_context 'with Debian file metadatum', params[:package_file_trait] do
+ it_behaves_like 'Test Debian file metadatum',
+ params[:has_component], params[:has_architecture], params[:has_fields]
end
end
end
diff --git a/spec/models/packages/debian/group_distribution_spec.rb b/spec/models/packages/debian/group_distribution_spec.rb
index 90fb0d0e7d8..1af23ad3ac0 100644
--- a/spec/models/packages/debian/group_distribution_spec.rb
+++ b/spec/models/packages/debian/group_distribution_spec.rb
@@ -2,6 +2,9 @@
require 'spec_helper'
-RSpec.describe Packages::Debian::GroupDistribution do
- it_behaves_like 'Debian Distribution', :debian_group_distribution, :group, false
+RSpec.describe Packages::Debian::GroupDistribution, feature_category: :package_registry do
+ include_context 'for Debian Distribution', :debian_group_distribution, false
+
+ it_behaves_like 'Debian Distribution for common behavior'
+ it_behaves_like 'Debian Distribution with group container'
end
diff --git a/spec/models/packages/debian/project_distribution_spec.rb b/spec/models/packages/debian/project_distribution_spec.rb
index 5f4041ad9fe..2b79cdb539f 100644
--- a/spec/models/packages/debian/project_distribution_spec.rb
+++ b/spec/models/packages/debian/project_distribution_spec.rb
@@ -2,6 +2,9 @@
require 'spec_helper'
-RSpec.describe Packages::Debian::ProjectDistribution do
- it_behaves_like 'Debian Distribution', :debian_project_distribution, :project, true
+RSpec.describe Packages::Debian::ProjectDistribution, feature_category: :package_registry do
+ include_context 'for Debian Distribution', :debian_project_distribution, true
+
+ it_behaves_like 'Debian Distribution for common behavior'
+ it_behaves_like 'Debian Distribution with project container'
end
diff --git a/spec/models/packages/dependency_spec.rb b/spec/models/packages/dependency_spec.rb
index 1575dec98c9..80ec7f77fda 100644
--- a/spec/models/packages/dependency_spec.rb
+++ b/spec/models/packages/dependency_spec.rb
@@ -1,7 +1,11 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe Packages::Dependency, type: :model do
+RSpec.describe Packages::Dependency, type: :model, feature_category: :package_registry do
+ describe 'included modules' do
+ it { is_expected.to include_module(EachBatch) }
+ end
+
describe 'relationships' do
it { is_expected.to have_many(:dependency_links) }
end
@@ -110,6 +114,19 @@ RSpec.describe Packages::Dependency, type: :model do
end
end
+ describe '.orphaned' do
+ let_it_be(:orphaned_dependencies) { create_list(:packages_dependency, 2) }
+ let_it_be(:linked_dependency) do
+ create(:packages_dependency).tap do |dependency|
+ create(:packages_dependency_link, dependency: dependency)
+ end
+ end
+
+ it 'returns orphaned dependency records' do
+ expect(described_class.orphaned).to contain_exactly(*orphaned_dependencies)
+ end
+ end
+
def build_names_and_version_patterns(*package_dependencies)
result = Hash.new { |h, dependency| h[dependency.name] = dependency.version_pattern }
package_dependencies.each { |dependency| result[dependency] }
diff --git a/spec/models/packages/event_spec.rb b/spec/models/packages/event_spec.rb
new file mode 100644
index 00000000000..58c1c1e6e92
--- /dev/null
+++ b/spec/models/packages/event_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Packages::Event, feature_category: :package_registry do
+ let(:event_type) { :push_package }
+ let(:event_scope) { :npm }
+ let(:originator_type) { :deploy_token }
+
+ shared_examples 'handle forbidden event type' do |result: []|
+ let(:event_type) { :search }
+
+ it { is_expected.to eq(result) }
+ end
+
+ describe '.event_allowed?' do
+ subject { described_class.event_allowed?(event_type) }
+
+ it { is_expected.to eq(true) }
+
+ it_behaves_like 'handle forbidden event type', result: false
+ end
+
+ describe '.unique_counters_for' do
+ subject { described_class.unique_counters_for(event_scope, event_type, originator_type) }
+
+ it { is_expected.to contain_exactly('i_package_npm_deploy_token') }
+
+ it_behaves_like 'handle forbidden event type'
+
+ context 'when an originator type is quest' do
+ let(:originator_type) { :guest }
+
+ it { is_expected.to eq([]) }
+ end
+ end
+
+ describe '.counters_for' do
+ subject { described_class.counters_for(event_scope, event_type, originator_type) }
+
+ it do
+ is_expected.to contain_exactly(
+ 'i_package_push_package',
+ 'i_package_push_package_by_deploy_token',
+ 'i_package_npm_push_package'
+ )
+ end
+
+ it_behaves_like 'handle forbidden event type'
+ end
+end
diff --git a/spec/models/packages/npm/metadata_cache_spec.rb b/spec/models/packages/npm/metadata_cache_spec.rb
new file mode 100644
index 00000000000..5e7a710baf8
--- /dev/null
+++ b/spec/models/packages/npm/metadata_cache_spec.rb
@@ -0,0 +1,150 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Packages::Npm::MetadataCache, type: :model, feature_category: :package_registry do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:package_name) { '@root/test' }
+
+ it { is_expected.to be_a FileStoreMounter }
+
+ describe 'relationships' do
+ it { is_expected.to belong_to(:project).inverse_of(:npm_metadata_caches) }
+ end
+
+ describe 'validations' do
+ it { is_expected.to validate_presence_of(:file) }
+ it { is_expected.to validate_presence_of(:project) }
+ it { is_expected.to validate_presence_of(:size) }
+
+ describe '#package_name' do
+ let_it_be(:npm_metadata_cache) { create(:npm_metadata_cache, package_name: package_name, project: project) }
+
+ it { is_expected.to validate_presence_of(:package_name) }
+
+ describe 'uniqueness' do
+ it 'ensures the package name is unique within a given project' do
+ expect do
+ create(:npm_metadata_cache, package_name: package_name, project: project)
+ end.to raise_error(ActiveRecord::RecordInvalid, 'Validation failed: Package name has already been taken')
+ end
+
+ it 'allows duplicate file names in different projects' do
+ expect do
+ create(:npm_metadata_cache, package_name: package_name, project: create(:project))
+ end.not_to raise_error
+ end
+ end
+
+ describe 'format' do
+ it { is_expected.to allow_value('my.app-11.07.2018').for(:package_name) }
+ it { is_expected.to allow_value('@group-1/package').for(:package_name) }
+ it { is_expected.to allow_value('@any-scope/package').for(:package_name) }
+ it { is_expected.to allow_value('unscoped-package').for(:package_name) }
+
+ it { is_expected.not_to allow_value('my(dom$$$ain)com.my-app').for(:package_name) }
+ it { is_expected.not_to allow_value('@inv@lid-scope/package').for(:package_name) }
+ it { is_expected.not_to allow_value('@scope/../../package').for(:package_name) }
+ it { is_expected.not_to allow_value('@scope%2e%2e%fpackage').for(:package_name) }
+ it { is_expected.not_to allow_value('@scope/sub/package').for(:package_name) }
+ end
+ end
+ end
+
+ describe '.find_or_build' do
+ subject { described_class.find_or_build(package_name: package_name, project_id: project.id) }
+
+ context 'when a metadata cache exists' do
+ let_it_be(:npm_metadata_cache) { create(:npm_metadata_cache, package_name: package_name, project: project) }
+
+ it 'finds an existing metadata cache' do
+ expect(subject).to eq(npm_metadata_cache)
+ end
+ end
+
+ context 'when a metadata cache not found' do
+ let(:package_name) { 'not_existing' }
+
+ it 'builds a new instance', :aggregate_failures do
+ expect(subject).not_to be_persisted
+ expect(subject.package_name).to eq(package_name)
+ expect(subject.project_id).to eq(project.id)
+ end
+ end
+ end
+
+ describe 'save callbacks' do
+ describe 'object_storage_key' do
+ let(:object_storage_key) do
+ Gitlab::HashedPath.new(
+ 'packages', 'metadata_caches', 'npm', OpenSSL::Digest::SHA256.hexdigest(package_name),
+ root_hash: project.id
+ )
+ end
+
+ before do
+ allow(Gitlab::HashedPath).to receive(:new).and_return(object_storage_key)
+ end
+
+ context 'when the record is created' do
+ let(:npm_metadata_cache) { build(:npm_metadata_cache, package_name: package_name, project: project) }
+
+ it 'sets object_storage_key' do
+ npm_metadata_cache.save!
+
+ expect(npm_metadata_cache.object_storage_key).to eq(object_storage_key.to_s)
+ end
+
+ context 'when using `update!`' do
+ let(:metadata_content) { {}.to_json }
+
+ it 'sets object_storage_key' do
+ npm_metadata_cache.update!(
+ file: CarrierWaveStringFile.new(metadata_content),
+ size: metadata_content.bytesize
+ )
+
+ expect(npm_metadata_cache.object_storage_key).to eq(object_storage_key.to_s)
+ end
+ end
+ end
+
+ context 'when the record is updated' do
+ let_it_be(:npm_metadata_cache) { create(:npm_metadata_cache, package_name: package_name, project: project) }
+
+ let(:existing_object_storage_key) { npm_metadata_cache.object_storage_key }
+ let(:new_package_name) { 'updated_package_name' }
+
+ it 'does not update object_storage_key' do
+ existing_object_storage_key = npm_metadata_cache.object_storage_key
+
+ npm_metadata_cache.update!(package_name: new_package_name)
+
+ expect(npm_metadata_cache.object_storage_key).to eq(existing_object_storage_key)
+ end
+ end
+ end
+ end
+
+ describe 'readonly attributes' do
+ describe 'object_storage_key' do
+ let_it_be(:npm_metadata_cache) { create(:npm_metadata_cache) }
+
+ it 'sets object_storage_key' do
+ expect(npm_metadata_cache.object_storage_key).to be_present
+ end
+
+ context 'when the record is persisted' do
+ let(:new_object_storage_key) { 'object/storage/updated_key' }
+
+ it 'does not re-set object_storage_key' do
+ npm_metadata_cache.object_storage_key = new_object_storage_key
+
+ npm_metadata_cache.save!
+
+ expect(npm_metadata_cache.object_storage_key).not_to eq(new_object_storage_key)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/models/packages/npm/metadatum_spec.rb b/spec/models/packages/npm/metadatum_spec.rb
index ff8cce5310e..92daddded7e 100644
--- a/spec/models/packages/npm/metadatum_spec.rb
+++ b/spec/models/packages/npm/metadatum_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Packages::Npm::Metadatum, type: :model do
+RSpec.describe Packages::Npm::Metadatum, type: :model, feature_category: :package_registry do
describe 'relationships' do
it { is_expected.to belong_to(:package).inverse_of(:npm_metadatum) }
end
@@ -47,4 +47,16 @@ RSpec.describe Packages::Npm::Metadatum, type: :model do
end
end
end
+
+ describe 'scopes' do
+ describe '.package_id_in' do
+ let_it_be(:package) { create(:npm_package) }
+ let_it_be(:metadatum_1) { create(:npm_metadatum, package: package) }
+ let_it_be(:metadatum_2) { create(:npm_metadatum) }
+
+ it 'returns metadatums with the given package ids' do
+ expect(described_class.package_id_in([package.id])).to contain_exactly(metadatum_1)
+ end
+ end
+ end
end
diff --git a/spec/models/packages/package_file_spec.rb b/spec/models/packages/package_file_spec.rb
index 9b341034aaa..c9db1efc64a 100644
--- a/spec/models/packages/package_file_spec.rb
+++ b/spec/models/packages/package_file_spec.rb
@@ -153,6 +153,7 @@ RSpec.describe Packages::PackageFile, type: :model do
let_it_be(:debian_changes) { debian_package.package_files.last }
let_it_be(:debian_deb) { create(:debian_package_file, package: debian_package) }
let_it_be(:debian_udeb) { create(:debian_package_file, :udeb, package: debian_package) }
+ let_it_be(:debian_ddeb) { create(:debian_package_file, :ddeb, package: debian_package) }
let_it_be(:debian_contrib) do
create(:debian_package_file, package: debian_package).tap do |pf|
@@ -177,6 +178,17 @@ RSpec.describe Packages::PackageFile, type: :model do
describe '#with_debian_architecture_name' do
it { expect(described_class.with_debian_architecture_name('mipsel')).to contain_exactly(debian_mipsel) }
end
+
+ describe '#with_debian_unknown_since' do
+ let_it_be(:incoming) { create(:debian_incoming, project: project) }
+
+ before do
+ incoming.package_files.first.debian_file_metadatum.update! updated_at: 1.day.ago
+ incoming.package_files.second.update! updated_at: 1.day.ago, status: :error
+ end
+
+ it { expect(described_class.with_debian_unknown_since(1.hour.ago)).to contain_exactly(incoming.package_files.first) }
+ end
end
describe '.for_helm_with_channel' do
diff --git a/spec/models/packages/package_spec.rb b/spec/models/packages/package_spec.rb
index 992cc5c4354..e79459e0c7c 100644
--- a/spec/models/packages/package_spec.rb
+++ b/spec/models/packages/package_spec.rb
@@ -682,24 +682,20 @@ RSpec.describe Packages::Package, type: :model, feature_category: :package_regis
end
end
- describe "#unique_debian_package_name" do
+ describe "uniqueness for package type debian" do
let!(:package) { create(:debian_package) }
- it "will allow a Debian package with same project, name and version, but different distribution" do
- new_package = build(:debian_package, project: package.project, name: package.name, version: package.version)
- expect(new_package).to be_valid
- end
-
it "will not allow a Debian package with same project, name, version and distribution" do
new_package = build(:debian_package, project: package.project, name: package.name, version: package.version)
new_package.debian_publication.distribution = package.debian_publication.distribution
expect(new_package).not_to be_valid
- expect(new_package.errors.to_a).to include('Debian package already exists in Distribution')
+ expect(new_package.errors.to_a).to include('Name has already been taken')
end
- it "will allow a Debian package with same project, name, version, but no distribution" do
+ it "will not allow a Debian package with same project, name, version, but no distribution" do
new_package = build(:debian_package, project: package.project, name: package.name, version: package.version, published_in: nil)
- expect(new_package).to be_valid
+ expect(new_package).not_to be_valid
+ expect(new_package.errors.to_a).to include('Name has already been taken')
end
context 'with pending_destruction package' do
@@ -713,7 +709,7 @@ RSpec.describe Packages::Package, type: :model, feature_category: :package_regis
end
end
- Packages::Package.package_types.keys.without('conan', 'debian').each do |pt|
+ Packages::Package.package_types.keys.without('conan').each do |pt|
context "project id, name, version and package type uniqueness for package type #{pt}" do
let(:package) { create("#{pt}_package") }
@@ -722,6 +718,15 @@ RSpec.describe Packages::Package, type: :model, feature_category: :package_regis
expect(new_package).not_to be_valid
expect(new_package.errors.to_a).to include("Name has already been taken")
end
+
+ context 'with pending_destruction package' do
+ let!(:package) { create("#{pt}_package", :pending_destruction) }
+
+ it "will allow a #{pt} package with same project, name, version and package_type" do
+ new_package = build("#{pt}_package", project: package.project, name: package.name, version: package.version)
+ expect(new_package).to be_valid
+ end
+ end
end
end
end
@@ -842,6 +847,14 @@ RSpec.describe Packages::Package, type: :model, feature_category: :package_regis
is_expected.to match_array([package])
end
end
+
+ describe '.preload_conan_metadatum' do
+ subject { described_class.preload_conan_metadatum }
+
+ it 'loads conan metadatum' do
+ expect(subject.first.association(:conan_metadatum)).to be_loaded
+ end
+ end
end
describe '.without_nuget_temporary_name' do
@@ -1235,8 +1248,18 @@ RSpec.describe Packages::Package, type: :model, feature_category: :package_regis
let_it_be(:first_build_info) { create(:package_build_info, :with_pipeline, package: package) }
let_it_be(:second_build_info) { create(:package_build_info, :with_pipeline, package: package) }
- it 'returns the first build info' do
- expect(package.original_build_info).to eq(first_build_info)
+ it 'returns the last build info' do
+ expect(package.original_build_info).to eq(second_build_info)
+ end
+
+ context 'with packages_display_last_pipeline disabled' do
+ before do
+ stub_feature_flags(packages_display_last_pipeline: false)
+ end
+
+ it 'returns the first build info' do
+ expect(package.original_build_info).to eq(first_build_info)
+ end
end
end
end
@@ -1402,4 +1425,36 @@ RSpec.describe Packages::Package, type: :model, feature_category: :package_regis
.to change(package, :last_downloaded_at).from(nil).to(instance_of(ActiveSupport::TimeWithZone))
end
end
+
+ describe "#publish_creation_event" do
+ let_it_be(:project) { create(:project) }
+
+ let(:version) { '-' }
+ let(:package_type) { :generic }
+
+ subject { described_class.create!(project: project, name: 'incoming', version: version, package_type: package_type) }
+
+ context 'when package is generic' do
+ it 'publishes an event' do
+ expect { subject }
+ .to publish_event(::Packages::PackageCreatedEvent)
+ .with({
+ project_id: project.id,
+ id: kind_of(Numeric),
+ name: "incoming",
+ version: "-",
+ package_type: 'generic'
+ })
+ end
+ end
+
+ context 'when package is not generic' do
+ let(:package_type) { :debian }
+ let(:version) { 1 }
+
+ it 'does not create event' do
+ expect { subject }.not_to publish_event(::Packages::PackageCreatedEvent)
+ end
+ end
+ end
end