diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-20 16:49:51 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-20 16:49:51 +0300 |
commit | 71786ddc8e28fbd3cb3fcc4b3ff15e5962a1c82e (patch) | |
tree | 6a2d93ef3fb2d353bb7739e4b57e6541f51cdd71 /spec/lib/gitlab/import_export | |
parent | a7253423e3403b8c08f8a161e5937e1488f5f407 (diff) |
Add latest changes from gitlab-org/gitlab@15-9-stable-eev15.9.0-rc42
Diffstat (limited to 'spec/lib/gitlab/import_export')
10 files changed, 195 insertions, 52 deletions
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 8750bf4387c..0c2c3ffc664 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -386,6 +386,7 @@ create_access_levels: - user - protected_tag - group +- deploy_key container_repositories: - project - name @@ -486,6 +487,7 @@ project: - requesters - namespace_members - namespace_requesters +- namespace_members_and_requesters - deploy_keys_projects - deploy_keys - users_star_projects @@ -669,6 +671,8 @@ project: - disable_download_button - dependency_list_exports - sbom_occurrences +- analytics_dashboards_configuration_project +- analytics_dashboards_pointer award_emoji: - awardable - user diff --git a/spec/lib/gitlab/import_export/attribute_configuration_spec.rb b/spec/lib/gitlab/import_export/attribute_configuration_spec.rb index 7e17d56def0..572f809e43b 100644 --- a/spec/lib/gitlab/import_export/attribute_configuration_spec.rb +++ b/spec/lib/gitlab/import_export/attribute_configuration_spec.rb @@ -18,7 +18,7 @@ RSpec.describe 'Import/Export attribute configuration' do it 'has no new columns' do relation_names_for(:project).each do |relation_name| relation_class = relation_class_for_name(relation_name) - relation_attributes = relation_class.new.attributes.keys - relation_class.encrypted_attributes.keys.map(&:to_s) + relation_attributes = relation_class.new.attributes.keys - relation_class.attr_encrypted_attributes.keys.map(&:to_s) current_attributes = parsed_attributes(relation_name, relation_attributes) safe_attributes = safe_model_attributes[relation_class.to_s].dup || [] diff --git a/spec/lib/gitlab/import_export/import_export_equivalence_spec.rb b/spec/lib/gitlab/import_export/import_export_equivalence_spec.rb index 18f2e8f80d7..6c997dc1361 100644 --- a/spec/lib/gitlab/import_export/import_export_equivalence_spec.rb +++ b/spec/lib/gitlab/import_export/import_export_equivalence_spec.rb @@ -13,7 +13,7 @@ require 'spec_helper' # - randomly generated fields like tokens # # as these are expected to change between import/export cycles. -RSpec.describe Gitlab::ImportExport do +RSpec.describe Gitlab::ImportExport, feature_category: :importers do include ImportExport::CommonUtil include ConfigurationHelper include ImportExport::ProjectTreeExpectations @@ -25,7 +25,8 @@ RSpec.describe Gitlab::ImportExport do end it 'yields the initial tree when importing and exporting it again' do - project = create(:project, creator: create(:user, :admin)) + project = create(:project) + user = create(:user, :admin) # We first generate a test fixture dynamically from a seed-fixture, so as to # account for any fields in the initial fixture that are missing and set to @@ -34,6 +35,7 @@ RSpec.describe Gitlab::ImportExport do expect( restore_then_save_project( project, + user, import_path: seed_fixture_path, export_path: test_fixture_path) ).to be true @@ -42,6 +44,7 @@ RSpec.describe Gitlab::ImportExport do expect( restore_then_save_project( project, + user, import_path: test_fixture_path, export_path: test_tmp_path) ).to be true diff --git a/spec/lib/gitlab/import_export/importer_spec.rb b/spec/lib/gitlab/import_export/importer_spec.rb index c9d559c992c..53d205850c8 100644 --- a/spec/lib/gitlab/import_export/importer_spec.rb +++ b/spec/lib/gitlab/import_export/importer_spec.rb @@ -6,8 +6,8 @@ RSpec.describe Gitlab::ImportExport::Importer do let(:user) { create(:user) } let(:test_path) { "#{Dir.tmpdir}/importer_spec" } let(:shared) { project.import_export_shared } - let(:project) { create(:project) } let(:import_file) { fixture_file_upload('spec/features/projects/import_export/test_project_export.tar.gz') } + let_it_be(:project) { create(:project) } subject(:importer) { described_class.new(project) } diff --git a/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb b/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb index 02ac8065c9f..103d3512e8b 100644 --- a/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb +++ b/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::ImportExport::Json::StreamingSerializer do +RSpec.describe Gitlab::ImportExport::Json::StreamingSerializer, feature_category: :importers do let_it_be(:user) { create(:user) } let_it_be(:release) { create(:release) } let_it_be(:group) { create(:group) } @@ -213,59 +213,143 @@ RSpec.describe Gitlab::ImportExport::Json::StreamingSerializer do end end - describe 'conditional export of included associations' do + describe 'with inaccessible associations' do + let_it_be(:milestone) { create(:milestone, project: exportable) } + let_it_be(:issue) { create(:issue, assignees: [user], project: exportable, milestone: milestone) } + let_it_be(:label1) { create(:label, project: exportable) } + let_it_be(:label2) { create(:label, project: exportable) } + let_it_be(:link1) { create(:label_link, label: label1, target: issue) } + let_it_be(:link2) { create(:label_link, label: label2, target: issue) } + + let(:options) { { include: [{ label_links: { include: [:label] } }, { milestone: { include: [] } }] } } + let(:include) do - [{ issues: { include: [{ label_links: { include: [:label] } }] } }] + [{ issues: options }] end - let(:include_if_exportable) do - { issues: [:label_links] } + shared_examples 'record with exportable associations' do + it 'includes exportable association' do + expect(json_writer).to receive(:write_relation_array).with(exportable_path, :issues, array_including(expected_issue)) + + subject.execute + end end - let_it_be(:label) { create(:label, project: exportable) } - let_it_be(:link) { create(:label_link, label: label, target: issue) } + context 'conditional export of included associations' do + let(:include_if_exportable) do + { issues: [:label_links, :milestone] } + end - context 'when association is exportable' do - before do - allow_next_found_instance_of(Issue) do |issue| - allow(issue).to receive(:exportable_association?).with(:label_links, current_user: user).and_return(true) + context 'when association is exportable' do + before do + allow_next_found_instance_of(Issue) do |issue| + allow(issue).to receive(:exportable_association?).with(:label_links, current_user: user).and_return(true) + allow(issue).to receive(:exportable_association?).with(:milestone, current_user: user).and_return(true) + end + end + + it_behaves_like 'record with exportable associations' do + let(:expected_issue) { issue.to_json(options) } end end - it 'includes exportable association' do - expected_issue = issue.to_json(include: [{ label_links: { include: [:label] } }]) + context 'when an association is not exportable' do + before do + allow_next_found_instance_of(Issue) do |issue| + allow(issue).to receive(:exportable_association?).with(:label_links, current_user: user).and_return(true) + allow(issue).to receive(:exportable_association?).with(:milestone, current_user: user).and_return(false) + end + end - expect(json_writer).to receive(:write_relation_array).with(exportable_path, :issues, array_including(expected_issue)) + it_behaves_like 'record with exportable associations' do + let(:expected_issue) { issue.to_json(include: [{ label_links: { include: [:label] } }]) } + end + end - subject.execute + context 'when association does not respond to exportable_association?' do + before do + allow_next_found_instance_of(Issue) do |issue| + allow(issue).to receive(:respond_to?).and_call_original + allow(issue).to receive(:respond_to?).with(:exportable_association?).and_return(false) + end + end + + it_behaves_like 'record with exportable associations' do + let(:expected_issue) { issue.to_json } + end end end - context 'when association is not exportable' do - before do - allow_next_found_instance_of(Issue) do |issue| - allow(issue).to receive(:exportable_association?).with(:label_links, current_user: user).and_return(false) + context 'export of included restricted associations' do + let(:many_relation) { :label_links } + let(:single_relation) { :milestone } + let(:issue_hash) { issue.as_json(options).with_indifferent_access } + let(:expected_issue) { issue.to_json(options) } + + context 'when the association is restricted' do + context 'when some association records are exportable' do + before do + allow_next_found_instance_of(Issue) do |issue| + allow(issue).to receive(:restricted_associations).with([many_relation, single_relation]).and_return([many_relation]) + allow(issue).to receive(:readable_records).with(many_relation, current_user: user).and_return([link1]) + end + end + + it_behaves_like 'record with exportable associations' do + let(:expected_issue) do + issue_hash[many_relation].delete_if { |record| record['id'] == link2.id } + issue_hash.to_json(options) + end + end end - end - it 'filters out not exportable association' do - expect(json_writer).to receive(:write_relation_array).with(exportable_path, :issues, array_including(issue.to_json)) + context 'when all association records are exportable' do + before do + allow_next_found_instance_of(Issue) do |issue| + allow(issue).to receive(:restricted_associations).with([many_relation, single_relation]).and_return([many_relation]) + allow(issue).to receive(:readable_records).with(many_relation, current_user: user).and_return([link1, link2]) + end + end - subject.execute - end - end + it_behaves_like 'record with exportable associations' + end - context 'when association does not respond to exportable_association?' do - before do - allow_next_found_instance_of(Issue) do |issue| - allow(issue).to receive(:respond_to?).with(:exportable_association?).and_return(false) + context 'when the single association record is exportable' do + before do + allow_next_found_instance_of(Issue) do |issue| + allow(issue).to receive(:restricted_associations).with([many_relation, single_relation]).and_return([single_relation]) + allow(issue).to receive(:readable_records).with(single_relation, current_user: user).and_return(milestone) + end + end + + it_behaves_like 'record with exportable associations' + end + + context 'when the single association record is not exportable' do + before do + allow_next_found_instance_of(Issue) do |issue| + allow(issue).to receive(:restricted_associations).with([many_relation, single_relation]).and_return([single_relation]) + allow(issue).to receive(:readable_records).with(single_relation, current_user: user).and_return(nil) + end + end + + it_behaves_like 'record with exportable associations' do + let(:expected_issue) do + issue_hash[single_relation] = nil + issue_hash.to_json(options) + end + end end end - it 'filters out not exportable association' do - expect(json_writer).to receive(:write_relation_array).with(exportable_path, :issues, array_including(issue.to_json)) + context 'when the associations are not restricted' do + before do + allow_next_found_instance_of(Issue) do |issue| + allow(issue).to receive(:restricted_associations).with([many_relation, single_relation]).and_return([]) + end + end - subject.execute + it_behaves_like 'record with exportable associations' end end end diff --git a/spec/lib/gitlab/import_export/project/relation_factory_spec.rb b/spec/lib/gitlab/import_export/project/relation_factory_spec.rb index 936c63fd6cd..d133f54ade5 100644 --- a/spec/lib/gitlab/import_export/project/relation_factory_spec.rb +++ b/spec/lib/gitlab/import_export/project/relation_factory_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::ImportExport::Project::RelationFactory, :use_clean_rails_memory_store_caching do +RSpec.describe Gitlab::ImportExport::Project::RelationFactory, :use_clean_rails_memory_store_caching, feature_category: :importers do let(:group) { create(:group).tap { |g| g.add_maintainer(importer_user) } } let(:project) { create(:project, :repository, group: group) } let(:members_mapper) { double('members_mapper').as_null_object } @@ -418,21 +418,73 @@ RSpec.describe Gitlab::ImportExport::Project::RelationFactory, :use_clean_rails_ end end - context 'merge request access level object' do - let(:relation_sym) { :'ProtectedBranch::MergeAccessLevel' } - let(:relation_hash) { { 'access_level' => 30, 'created_at' => '2022-03-29T09:53:13.457Z', 'updated_at' => '2022-03-29T09:54:13.457Z' } } + describe 'protected branch access levels' do + shared_examples 'access levels' do + let(:relation_hash) { { 'access_level' => access_level, 'created_at' => '2022-03-29T09:53:13.457Z', 'updated_at' => '2022-03-29T09:54:13.457Z' } } - it 'sets access level to maintainer' do - expect(created_object.access_level).to equal(Gitlab::Access::MAINTAINER) + context 'when access level is no one' do + let(:access_level) { Gitlab::Access::NO_ACCESS } + + it 'keeps no one access level' do + expect(created_object.access_level).to equal(access_level) + end + end + + context 'when access level is below maintainer' do + let(:access_level) { Gitlab::Access::DEVELOPER } + + it 'sets access level to maintainer' do + expect(created_object.access_level).to equal(Gitlab::Access::MAINTAINER) + end + end + + context 'when access level is above maintainer' do + let(:access_level) { Gitlab::Access::OWNER } + + it 'sets access level to maintainer' do + expect(created_object.access_level).to equal(Gitlab::Access::MAINTAINER) + end + end + + describe 'root ancestor membership' do + let(:access_level) { Gitlab::Access::DEVELOPER } + + context 'when importer user is root group owner' do + let(:importer_user) { create(:user) } + + it 'keeps access level as is' do + group.add_owner(importer_user) + + expect(created_object.access_level).to equal(access_level) + end + end + + context 'when user membership in root group is missing' do + it 'sets access level to maintainer' do + group.members.delete_all + + expect(created_object.access_level).to equal(Gitlab::Access::MAINTAINER) + end + end + + context 'when root ancestor is not a group' do + it 'sets access level to maintainer' do + expect(created_object.access_level).to equal(Gitlab::Access::MAINTAINER) + end + end + end + end + + describe 'merge access level' do + let(:relation_sym) { :'ProtectedBranch::MergeAccessLevel' } + + include_examples 'access levels' end - end - context 'push access level object' do - let(:relation_sym) { :'ProtectedBranch::PushAccessLevel' } - let(:relation_hash) { { 'access_level' => 30, 'created_at' => '2022-03-29T09:53:13.457Z', 'updated_at' => '2022-03-29T09:54:13.457Z' } } + describe 'push access level' do + let(:relation_sym) { :'ProtectedBranch::PushAccessLevel' } - it 'sets access level to maintainer' do - expect(created_object.access_level).to equal(Gitlab::Access::MAINTAINER) + include_examples 'access levels' end end end diff --git a/spec/lib/gitlab/import_export/project/relation_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project/relation_tree_restorer_spec.rb index ac646087a95..6053df8ba97 100644 --- a/spec/lib/gitlab/import_export/project/relation_tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/project/relation_tree_restorer_spec.rb @@ -9,7 +9,7 @@ require 'spec_helper' -RSpec.describe Gitlab::ImportExport::Project::RelationTreeRestorer do +RSpec.describe Gitlab::ImportExport::Project::RelationTreeRestorer, feature_category: :importers do let_it_be(:importable, reload: true) do create(:project, :builds_enabled, :issues_disabled, name: 'project', path: 'project') end diff --git a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb index 2699dc10b18..125d1736b9b 100644 --- a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb @@ -6,7 +6,7 @@ def match_mr1_note(content_regex) MergeRequest.find_by(title: 'MR1').notes.find { |n| n.note.match(/#{content_regex}/) } end -RSpec.describe Gitlab::ImportExport::Project::TreeRestorer do +RSpec.describe Gitlab::ImportExport::Project::TreeRestorer, feature_category: :importers do include ImportExport::CommonUtil using RSpec::Parameterized::TableSyntax diff --git a/spec/lib/gitlab/import_export/references_configuration_spec.rb b/spec/lib/gitlab/import_export/references_configuration_spec.rb index 6320fbed975..ad165790b77 100644 --- a/spec/lib/gitlab/import_export/references_configuration_spec.rb +++ b/spec/lib/gitlab/import_export/references_configuration_spec.rb @@ -24,7 +24,7 @@ RSpec.describe 'Import/Export Project configuration' do context "where relation #{params[:relation_path]}" do it 'does not have prohibited keys' do relation_class = relation_class_for_name(relation_name) - relation_attributes = relation_class.new.attributes.keys - relation_class.encrypted_attributes.keys.map(&:to_s) + relation_attributes = relation_class.new.attributes.keys - relation_class.attr_encrypted_attributes.keys.map(&:to_s) current_attributes = parsed_attributes(relation_name, relation_attributes) prohibited_keys = current_attributes.select do |attribute| prohibited_key?(attribute) || !relation_class.attribute_method?(attribute) diff --git a/spec/lib/gitlab/import_export/version_checker_spec.rb b/spec/lib/gitlab/import_export/version_checker_spec.rb index b3730d85f13..dd81b8b846d 100644 --- a/spec/lib/gitlab/import_export/version_checker_spec.rb +++ b/spec/lib/gitlab/import_export/version_checker_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::ImportExport::VersionChecker, feature_category: :import do +RSpec.describe Gitlab::ImportExport::VersionChecker, feature_category: :importers do include ImportExport::CommonUtil let!(:shared) { Gitlab::ImportExport::Shared.new(nil) } |