diff options
Diffstat (limited to 'spec/lib/bulk_imports')
-rw-r--r-- | spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb (renamed from spec/lib/bulk_imports/groups/pipelines/entity_finisher_spec.rb) | 2 | ||||
-rw-r--r-- | spec/lib/bulk_imports/groups/graphql/get_projects_query_spec.rb | 43 | ||||
-rw-r--r-- | spec/lib/bulk_imports/groups/pipelines/project_entities_pipeline_spec.rb | 69 | ||||
-rw-r--r-- | spec/lib/bulk_imports/groups/stage_spec.rb (renamed from spec/lib/bulk_imports/stage_spec.rb) | 23 | ||||
-rw-r--r-- | spec/lib/bulk_imports/projects/pipelines/project_pipeline_spec.rb | 95 | ||||
-rw-r--r-- | spec/lib/bulk_imports/projects/stage_spec.rb | 18 | ||||
-rw-r--r-- | spec/lib/bulk_imports/projects/transformers/project_attributes_transformer_spec.rb | 83 |
7 files changed, 322 insertions, 11 deletions
diff --git a/spec/lib/bulk_imports/groups/pipelines/entity_finisher_spec.rb b/spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb index b97aeb435b9..c1a9ea7b7e2 100644 --- a/spec/lib/bulk_imports/groups/pipelines/entity_finisher_spec.rb +++ b/spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe BulkImports::Groups::Pipelines::EntityFinisher do +RSpec.describe BulkImports::Common::Pipelines::EntityFinisher do it 'updates the entity status to finished' do entity = create(:bulk_import_entity, :started) pipeline_tracker = create(:bulk_import_tracker, entity: entity) diff --git a/spec/lib/bulk_imports/groups/graphql/get_projects_query_spec.rb b/spec/lib/bulk_imports/groups/graphql/get_projects_query_spec.rb new file mode 100644 index 00000000000..1a7c5a4993c --- /dev/null +++ b/spec/lib/bulk_imports/groups/graphql/get_projects_query_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe BulkImports::Groups::Graphql::GetProjectsQuery do + describe '#variables' do + it 'returns valid variables based on entity information' do + tracker = create(:bulk_import_tracker) + context = BulkImports::Pipeline::Context.new(tracker) + + query = GraphQL::Query.new( + GitlabSchema, + described_class.to_s, + variables: described_class.variables(context) + ) + result = GitlabSchema.static_validator.validate(query) + + expect(result[:errors]).to be_empty + end + + context 'with invalid variables' do + it 'raises an error' do + expect { GraphQL::Query.new(GitlabSchema, described_class.to_s, variables: 'invalid') }.to raise_error(ArgumentError) + end + end + end + + describe '#data_path' do + it 'returns data path' do + expected = %w[data group projects nodes] + + expect(described_class.data_path).to eq(expected) + end + end + + describe '#page_info_path' do + it 'returns pagination information path' do + expected = %w[data group projects page_info] + + expect(described_class.page_info_path).to eq(expected) + end + end +end diff --git a/spec/lib/bulk_imports/groups/pipelines/project_entities_pipeline_spec.rb b/spec/lib/bulk_imports/groups/pipelines/project_entities_pipeline_spec.rb new file mode 100644 index 00000000000..5b6c93e695f --- /dev/null +++ b/spec/lib/bulk_imports/groups/pipelines/project_entities_pipeline_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe BulkImports::Groups::Pipelines::ProjectEntitiesPipeline do + let_it_be(:user) { create(:user) } + let_it_be(:destination_group) { create(:group) } + + let_it_be(:entity) do + create( + :bulk_import_entity, + group: destination_group, + destination_namespace: destination_group.full_path + ) + end + + let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) } + let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) } + + let(:extracted_data) do + BulkImports::Pipeline::ExtractedData.new(data: { + 'name' => 'project', + 'full_path' => 'group/project' + }) + end + + subject { described_class.new(context) } + + describe '#run' do + before do + allow_next_instance_of(BulkImports::Common::Extractors::GraphqlExtractor) do |extractor| + allow(extractor).to receive(:extract).and_return(extracted_data) + end + + destination_group.add_owner(user) + end + + it 'creates project entity' do + expect { subject.run }.to change(BulkImports::Entity, :count).by(1) + + project_entity = BulkImports::Entity.last + + expect(project_entity.source_type).to eq('project_entity') + expect(project_entity.source_full_path).to eq('group/project') + expect(project_entity.destination_name).to eq('project') + expect(project_entity.destination_namespace).to eq(destination_group.full_path) + end + end + + describe 'pipeline parts' do + it { expect(described_class).to include_module(BulkImports::Pipeline) } + it { expect(described_class).to include_module(BulkImports::Pipeline::Runner) } + + it 'has extractors' do + expect(described_class.get_extractor).to eq( + klass: BulkImports::Common::Extractors::GraphqlExtractor, + options: { + query: BulkImports::Groups::Graphql::GetProjectsQuery + } + ) + end + + it 'has transformers' do + expect(described_class.transformers).to contain_exactly( + { klass: BulkImports::Common::Transformers::ProhibitedAttributesTransformer, options: nil } + ) + end + end +end diff --git a/spec/lib/bulk_imports/stage_spec.rb b/spec/lib/bulk_imports/groups/stage_spec.rb index 4398b00e7e9..81c0ffc14d4 100644 --- a/spec/lib/bulk_imports/stage_spec.rb +++ b/spec/lib/bulk_imports/groups/stage_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -require 'fast_spec_helper' +require 'spec_helper' -RSpec.describe BulkImports::Stage do +RSpec.describe BulkImports::Groups::Stage do let(:pipelines) do [ [0, BulkImports::Groups::Pipelines::GroupPipeline], @@ -19,18 +19,21 @@ RSpec.describe BulkImports::Stage do describe '.pipelines' do it 'list all the pipelines with their stage number, ordered by stage' do expect(described_class.pipelines & pipelines).to eq(pipelines) - expect(described_class.pipelines.last.last).to eq(BulkImports::Groups::Pipelines::EntityFinisher) + expect(described_class.pipelines.last.last).to eq(BulkImports::Common::Pipelines::EntityFinisher) end - end - describe '.pipeline_exists?' do - it 'returns true when the given pipeline name exists in the pipelines list' do - expect(described_class.pipeline_exists?(BulkImports::Groups::Pipelines::GroupPipeline)).to eq(true) - expect(described_class.pipeline_exists?('BulkImports::Groups::Pipelines::GroupPipeline')).to eq(true) + it 'includes project entities pipeline' do + stub_feature_flags(bulk_import_projects: true) + + expect(described_class.pipelines).to include([1, BulkImports::Groups::Pipelines::ProjectEntitiesPipeline]) end - it 'returns false when the given pipeline name exists in the pipelines list' do - expect(described_class.pipeline_exists?('BulkImports::Groups::Pipelines::InexistentPipeline')).to eq(false) + context 'when bulk_import_projects feature flag is disabled' do + it 'does not include project entities pipeline' do + stub_feature_flags(bulk_import_projects: false) + + expect(described_class.pipelines.flatten).not_to include(BulkImports::Groups::Pipelines::ProjectEntitiesPipeline) + end end end end diff --git a/spec/lib/bulk_imports/projects/pipelines/project_pipeline_spec.rb b/spec/lib/bulk_imports/projects/pipelines/project_pipeline_spec.rb new file mode 100644 index 00000000000..c53c0849931 --- /dev/null +++ b/spec/lib/bulk_imports/projects/pipelines/project_pipeline_spec.rb @@ -0,0 +1,95 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe BulkImports::Projects::Pipelines::ProjectPipeline do + describe '#run' do + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group) } + let_it_be(:bulk_import) { create(:bulk_import, user: user) } + + let_it_be(:entity) do + create( + :bulk_import_entity, + source_type: :project_entity, + bulk_import: bulk_import, + source_full_path: 'source/full/path', + destination_name: 'My Destination Project', + destination_namespace: group.full_path + ) + end + + let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) } + let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) } + + let(:project_data) do + { + 'visibility' => 'private', + 'created_at' => 10.days.ago, + 'archived' => false, + 'shared_runners_enabled' => true, + 'container_registry_enabled' => true, + 'only_allow_merge_if_pipeline_succeeds' => true, + 'only_allow_merge_if_all_discussions_are_resolved' => true, + 'request_access_enabled' => true, + 'printing_merge_request_link_enabled' => true, + 'remove_source_branch_after_merge' => true, + 'autoclose_referenced_issues' => true, + 'suggestion_commit_message' => 'message', + 'wiki_enabled' => true + } + end + + subject(:project_pipeline) { described_class.new(context) } + + before do + allow_next_instance_of(BulkImports::Common::Extractors::GraphqlExtractor) do |extractor| + allow(extractor).to receive(:extract).and_return(BulkImports::Pipeline::ExtractedData.new(data: project_data)) + end + + group.add_owner(user) + end + + it 'imports new project into destination group', :aggregate_failures do + expect { project_pipeline.run }.to change { Project.count }.by(1) + + project_path = 'my-destination-project' + imported_project = Project.find_by_path(project_path) + + expect(imported_project).not_to be_nil + expect(imported_project.group).to eq(group) + expect(imported_project.suggestion_commit_message).to eq('message') + expect(imported_project.archived?).to eq(project_data['archived']) + expect(imported_project.shared_runners_enabled?).to eq(project_data['shared_runners_enabled']) + expect(imported_project.container_registry_enabled?).to eq(project_data['container_registry_enabled']) + expect(imported_project.only_allow_merge_if_pipeline_succeeds?).to eq(project_data['only_allow_merge_if_pipeline_succeeds']) + expect(imported_project.only_allow_merge_if_all_discussions_are_resolved?).to eq(project_data['only_allow_merge_if_all_discussions_are_resolved']) + expect(imported_project.request_access_enabled?).to eq(project_data['request_access_enabled']) + expect(imported_project.printing_merge_request_link_enabled?).to eq(project_data['printing_merge_request_link_enabled']) + expect(imported_project.remove_source_branch_after_merge?).to eq(project_data['remove_source_branch_after_merge']) + expect(imported_project.autoclose_referenced_issues?).to eq(project_data['autoclose_referenced_issues']) + expect(imported_project.wiki_enabled?).to eq(project_data['wiki_enabled']) + end + end + + describe 'pipeline parts' do + it { expect(described_class).to include_module(BulkImports::Pipeline) } + it { expect(described_class).to include_module(BulkImports::Pipeline::Runner) } + + it 'has extractors' do + expect(described_class.get_extractor) + .to eq( + klass: BulkImports::Common::Extractors::GraphqlExtractor, + options: { query: BulkImports::Projects::Graphql::GetProjectQuery } + ) + end + + it 'has transformers' do + expect(described_class.transformers) + .to contain_exactly( + { klass: BulkImports::Common::Transformers::ProhibitedAttributesTransformer, options: nil }, + { klass: BulkImports::Projects::Transformers::ProjectAttributesTransformer, options: nil } + ) + end + end +end diff --git a/spec/lib/bulk_imports/projects/stage_spec.rb b/spec/lib/bulk_imports/projects/stage_spec.rb new file mode 100644 index 00000000000..428812a34ef --- /dev/null +++ b/spec/lib/bulk_imports/projects/stage_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe BulkImports::Projects::Stage do + let(:pipelines) do + [ + [0, BulkImports::Projects::Pipelines::ProjectPipeline], + [1, BulkImports::Common::Pipelines::EntityFinisher] + ] + end + + describe '.pipelines' do + it 'list all the pipelines with their stage number, ordered by stage' do + expect(described_class.pipelines).to eq(pipelines) + end + end +end diff --git a/spec/lib/bulk_imports/projects/transformers/project_attributes_transformer_spec.rb b/spec/lib/bulk_imports/projects/transformers/project_attributes_transformer_spec.rb new file mode 100644 index 00000000000..822bb9a5605 --- /dev/null +++ b/spec/lib/bulk_imports/projects/transformers/project_attributes_transformer_spec.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe BulkImports::Projects::Transformers::ProjectAttributesTransformer do + describe '#transform' do + let_it_be(:user) { create(:user) } + let_it_be(:destination_group) { create(:group) } + let_it_be(:project) { create(:project, name: 'My Source Project') } + let_it_be(:bulk_import) { create(:bulk_import, user: user) } + + let_it_be(:entity) do + create( + :bulk_import_entity, + source_type: :project_entity, + bulk_import: bulk_import, + source_full_path: 'source/full/path', + destination_name: 'Destination Project Name', + destination_namespace: destination_group.full_path + ) + end + + let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) } + let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) } + + let(:data) do + { + 'name' => 'source_name', + 'visibility' => 'private' + } + end + + subject(:transformed_data) { described_class.new.transform(context, data) } + + it 'transforms name to destination name' do + expect(transformed_data[:name]).to eq(entity.destination_name) + end + + it 'adds path as parameterized name' do + expect(transformed_data[:path]).to eq(entity.destination_name.parameterize) + end + + it 'transforms visibility level' do + visibility = data['visibility'] + + expect(transformed_data).not_to have_key(:visibility) + expect(transformed_data[:visibility_level]).to eq(Gitlab::VisibilityLevel.string_options[visibility]) + end + + it 'adds import type' do + expect(transformed_data[:import_type]).to eq(described_class::PROJECT_IMPORT_TYPE) + end + + describe 'namespace_id' do + context 'when destination namespace is present' do + it 'adds namespace_id' do + expect(transformed_data[:namespace_id]).to eq(destination_group.id) + end + end + + context 'when destination namespace is blank' do + it 'does not add namespace_id key' do + entity = create( + :bulk_import_entity, + source_type: :project_entity, + bulk_import: bulk_import, + source_full_path: 'source/full/path', + destination_name: 'Destination Project Name', + destination_namespace: '' + ) + + context = double(entity: entity) + + expect(described_class.new.transform(context, data)).not_to have_key(:namespace_id) + end + end + end + + it 'converts all keys to symbols' do + expect(transformed_data.keys).to contain_exactly(:name, :path, :import_type, :visibility_level, :namespace_id) + end + end +end |