Commit 44c33c0c authored by João Cunha's avatar João Cunha

Add source instance version validation for project

The Project Migration feature requires the source GitLab
instance to be a certain minimal version. If this version is
not met we have to inform the user that the Project Migraiton
might fail or not migrate the whole data.

This commit adds the version control on the page where we show
portable groups. The version validation is now also sent to the
FE so it know when to show the message.

Changelog: added
parent 1855eb3a
......@@ -22,13 +22,16 @@ class Import::BulkImportsController < ApplicationController
def status
respond_to do |format|
format.json do
data = importable_data
data = ::BulkImports::GetImportableDataService.new(params, query_params, credentials).execute
pagination_headers.each do |header|
response.set_header(header, data.headers[header])
response.set_header(header, data[:response].headers[header])
end
render json: { importable_data: serialized_data(data.parsed_response) }
json_response = { importable_data: serialized_data(data[:response].parsed_response) }
json_response[:version_validation] = data[:version_validation]
render json: json_response
end
format.html do
@source_url = session[url_key]
......@@ -66,10 +69,6 @@ class Import::BulkImportsController < ApplicationController
@serializer ||= BaseSerializer.new(current_user: current_user)
end
def importable_data
client.get('groups', query_params)
end
# Default query string params used to fetch groups from GitLab source instance
#
# top_level_only: fetch only top level groups (subgroups are fetched during import itself)
......@@ -85,15 +84,6 @@ class Import::BulkImportsController < ApplicationController
query_params
end
def client
@client ||= BulkImports::Clients::HTTP.new(
url: session[url_key],
token: session[access_token_key],
per_page: params[:per_page],
page: params[:page]
)
end
def configure_params
params.permit(access_token_key, url_key)
end
......
......@@ -4,7 +4,8 @@
# projects to a GitLab instance. It associates the import with the responsible
# user.
class BulkImport < ApplicationRecord
MINIMUM_GITLAB_MAJOR_VERSION = 14
MIN_MAJOR_VERSION = 14
MIN_MINOR_VERSION_FOR_PROJECT = 4
belongs_to :user, optional: false
......@@ -34,6 +35,14 @@ class BulkImport < ApplicationRecord
end
end
def source_version_info
Gitlab::VersionInfo.parse(source_version)
end
def self.min_gl_version_for_project_migration
Gitlab::VersionInfo.new(MIN_MAJOR_VERSION, MIN_MINOR_VERSION_FOR_PROJECT)
end
def self.all_human_statuses
state_machine.states.map(&:human_name)
end
......
......@@ -83,9 +83,9 @@ class BulkImports::Entity < ApplicationRecord
def pipelines
@pipelines ||= case source_type
when 'group_entity'
BulkImports::Groups::Stage.pipelines
BulkImports::Groups::Stage.new(bulk_import).pipelines
when 'project_entity'
BulkImports::Projects::Stage.pipelines
BulkImports::Projects::Stage.new(bulk_import).pipelines
end
end
......
......@@ -52,7 +52,11 @@ module BulkImports
def create_bulk_import
BulkImport.transaction do
bulk_import = BulkImport.create!(user: current_user, source_type: 'gitlab')
bulk_import = BulkImport.create!(
user: current_user,
source_type: 'gitlab',
source_version: client.instance_version
)
bulk_import.create_configuration!(credentials.slice(:url, :access_token))
params.each do |entity|
......@@ -68,5 +72,12 @@ module BulkImports
bulk_import
end
end
def client
@client ||= BulkImports::Clients::HTTP.new(
url: @credentials[:url],
token: @credentials[:access_token]
)
end
end
end
# frozen_string_literal: true
module BulkImports
class GetImportableDataService
def initialize(params, query_params, credentials)
@params = params
@query_params = query_params
@credentials = credentials
end
def execute
{
version_validation: version_validation,
response: importables
}
end
private
def importables
client.get('groups', @query_params)
end
def version_validation
{
features: {
project_migration: {
available: client.compatible_for_project_migration?,
min_version: BulkImport.min_gl_version_for_project_migration.to_s
},
source_instance_version: client.instance_version.to_s
}
}
end
def client
@client ||= BulkImports::Clients::HTTP.new(
url: @credentials[:url],
token: @credentials[:access_token],
per_page: @params[:per_page],
page: @params[:page]
)
end
end
end
# frozen_string_literal: true
class AddSourceVersionToBulkImports < Gitlab::Database::Migration[1.0]
def change
add_column :bulk_imports, :source_version, :text # rubocop:disable Migration/AddLimitToTextColumns
end
end
# frozen_string_literal: true
class AddTextLimitToBulkImportsSourceVersion < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
add_text_limit :bulk_imports, :source_version, 63
end
def down
remove_text_limit :bulk_imports, :source_version
end
end
23be5444bb11f731e98edc9b6aad814d02fd0f3f6be9abdea9060898cc2b95f1
\ No newline at end of file
3482e5c12f1603cb67d24aee14f003345ef2a5c350c7dccafdea6554db04c4cc
\ No newline at end of file
......@@ -11216,7 +11216,9 @@ CREATE TABLE bulk_imports (
source_type smallint NOT NULL,
status smallint NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL
updated_at timestamp with time zone NOT NULL,
source_version text,
CONSTRAINT check_ea4e58775a CHECK ((char_length(source_version) <= 63))
);
CREATE SEQUENCE bulk_imports_id_seq
......@@ -20,6 +20,12 @@ RSpec.describe BulkImports::Groups::Stage do
]
end
subject do
bulk_import = build(:bulk_import)
described_class.new(bulk_import)
end
describe '#each' do
it 'iterates over all pipelines with the stage number' do
expect(subject.pipelines).to match_array(pipelines)
......
......@@ -57,7 +57,7 @@ module BulkImports
response = client.execute('{ metadata { version } }')
version = Gitlab::VersionInfo.parse(response.data.metadata.version)
if version.major < BulkImport::MINIMUM_GITLAB_MAJOR_VERSION
if version.major < BulkImport::MIN_MAJOR_VERSION
raise ::BulkImports::Error.unsupported_gitlab_version
else
@compatible_instance_version = true
......
......@@ -3,6 +3,8 @@
module BulkImports
module Clients
class HTTP
include Gitlab::Utils::StrongMemoize
API_VERSION = 'v4'
DEFAULT_PAGE = 1
DEFAULT_PER_PAGE = 30
......@@ -52,24 +54,32 @@ module BulkImports
Gitlab::Utils.append_path(api_url, resource)
end
def validate_instance_version!
return if @compatible_instance_version
def instance_version
strong_memoize(:instance_version) do
response = with_error_handling do
Gitlab::HTTP.get(resource_url(:version), default_options)
end
response = with_error_handling do
Gitlab::HTTP.get(resource_url(:version), default_options)
Gitlab::VersionInfo.parse(response.parsed_response['version'])
end
end
def compatible_for_project_migration?
instance_version >= BulkImport.min_gl_version_for_project_migration
end
version = Gitlab::VersionInfo.parse(response.parsed_response['version'])
private
def validate_instance_version!
return if @compatible_instance_version
if version.major < BulkImport::MINIMUM_GITLAB_MAJOR_VERSION
if instance_version.major < BulkImport::MIN_MAJOR_VERSION
raise ::BulkImports::Error.unsupported_gitlab_version
else
@compatible_instance_version = true
end
end
private
# rubocop:disable GitlabSecurity/PublicSend
def request(method, resource, options = {}, &block)
validate_instance_version!
......
......@@ -3,7 +3,7 @@
module BulkImports
class Error < StandardError
def self.unsupported_gitlab_version
self.new("Unsupported GitLab Version. Minimum Supported Gitlab Version #{BulkImport::MINIMUM_GITLAB_MAJOR_VERSION}.")
self.new("Unsupported GitLab Version. Minimum Supported Gitlab Version #{BulkImport::MIN_MAJOR_VERSION}.")
end
end
end
......@@ -47,7 +47,7 @@ module BulkImports
end
def project_entities_pipeline
if ::Feature.enabled?(:bulk_import_projects, default_enabled: :yaml)
if project_pipeline_available? && ::Feature.enabled?(:bulk_import_projects, default_enabled: :yaml)
{
project_entities: {
pipeline: BulkImports::Groups::Pipelines::ProjectEntitiesPipeline,
......@@ -58,6 +58,10 @@ module BulkImports
{}
end
end
def project_pipeline_available?
@bulk_import.source_version_info >= BulkImport.min_gl_version_for_project_migration
end
end
end
end
......
......@@ -2,8 +2,10 @@
module BulkImports
class Stage
def self.pipelines
new.pipelines
def initialize(bulk_import)
raise(ArgumentError, 'Expected an argument of type ::BulkImport') unless bulk_import.is_a?(::BulkImport)
@bulk_import = bulk_import
end
def pipelines
......
......@@ -51,62 +51,87 @@ RSpec.describe Import::BulkImportsController do
end
describe 'GET status' do
def get_status(params_override = {})
params = { page: 1, per_page: 20, filter: '' }.merge(params_override)
get :status,
params: params,
format: :json,
session: {
bulk_import_gitlab_url: 'https://gitlab.example.com',
bulk_import_gitlab_access_token: 'demo-pat'
}
end
include_context 'bulk imports requests context', 'https://gitlab.example.com'
let(:client) { BulkImports::Clients::HTTP.new(url: 'http://gitlab.example', token: 'token') }
let(:version) { "#{BulkImport::MIN_MAJOR_VERSION}.#{BulkImport::MIN_MINOR_VERSION_FOR_PROJECT}.0" }
let(:version_response) { double(code: 200, success?: true, parsed_response: { 'version' => version }) }
describe 'serialized group data' do
let(:client_response) do
let(:expected_response) do
double(
parsed_response: [
{ 'id' => 1, 'full_name' => 'group1', 'full_path' => 'full/path/group1', 'web_url' => 'http://demo.host/full/path/group1' },
{ 'id' => 2, 'full_name' => 'group2', 'full_path' => 'full/path/group2', 'web_url' => 'http://demo.host/full/path/group1' }
{
"full_name" => "Stub",
"full_path" => "stub-group",
"id" => 2595438,
"web_url" => "https://gitlab.com/groups/auto-breakfast"
}
],
headers: {
'x-next-page' => '2',
'x-page' => '1',
'x-per-page' => '20',
'x-total' => '37',
'x-total' => '42',
'x-total-pages' => '2'
}
)
end
let(:client_params) do
{
top_level_only: true,
min_access_level: Gitlab::Access::OWNER
}
end
before do
allow(controller).to receive(:client).and_return(client)
allow(client).to receive(:get).with('groups', client_params).and_return(client_response)
end
it 'returns serialized group data' do
get :status, format: :json
get_status
version_validation = {
"features" => {
"project_migration" => {
"available" => true,
"min_version" => BulkImport.min_gl_version_for_project_migration.to_s
},
"source_instance_version" => version
}
}
expect(json_response).to eq({ importable_data: client_response.parsed_response }.as_json)
expect(json_response).to include("importable_data" => expected_response.parsed_response, "version_validation" => hash_including(version_validation))
end
it 'forwards pagination headers' do
get :status, format: :json
expect(response.headers['x-per-page']).to eq client_response.headers['x-per-page']
expect(response.headers['x-page']).to eq client_response.headers['x-page']
expect(response.headers['x-next-page']).to eq client_response.headers['x-next-page']
expect(response.headers['x-prev-page']).to eq client_response.headers['x-prev-page']
expect(response.headers['x-total']).to eq client_response.headers['x-total']
expect(response.headers['x-total-pages']).to eq client_response.headers['x-total-pages']
get_status
expect(response.headers['x-per-page']).to eq expected_response.headers['x-per-page']
expect(response.headers['x-page']).to eq expected_response.headers['x-page']
expect(response.headers['x-next-page']).to eq expected_response.headers['x-next-page']
expect(response.headers['x-prev-page']).to eq expected_response.headers['x-prev-page']
expect(response.headers['x-total']).to eq expected_response.headers['x-total']
expect(response.headers['x-total-pages']).to eq expected_response.headers['x-total-pages']
end
context 'when filtering' do
it 'returns filtered result' do
filter = 'test'
search_params = client_params.merge(search: filter)
let_it_be(:filter) { 'test' }
expect(client).to receive(:get).with('groups', search_params).and_return(client_response)
let(:client_params) do
{
top_level_only: true,
min_access_level: Gitlab::Access::OWNER,
search: filter
}
end
it 'returns filtered result' do
get_status(filter: filter)
get :status, format: :json, params: { filter: filter }
expect(json_response['importable_data'].first['full_name']).to eq('Test')
end
end
end
......@@ -148,18 +173,19 @@ RSpec.describe Import::BulkImportsController do
context 'when connection error occurs' do
before do
allow(controller).to receive(:client).and_return(client)
allow(client).to receive(:get).and_raise(BulkImports::Error)
allow_next_instance_of(BulkImports::Clients::HTTP) do |instance|
allow(instance).to receive(:get).and_raise(BulkImports::Error)
end
end
it 'returns 422' do
get :status, format: :json
get_status
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
it 'clears session' do
get :status, format: :json
get_status
expect(session[:gitlab_url]).to be_nil
expect(session[:gitlab_access_token]).to be_nil
......
......@@ -4,6 +4,7 @@ FactoryBot.define do
factory :bulk_import, class: 'BulkImport' do
user
source_type { :gitlab }
source_version { BulkImport.min_gl_version_for_project_migration.to_s }
trait :created do
status { 0 }
......
......@@ -19,34 +19,12 @@ RSpec.describe 'Import/Export - Connect to another instance', :js do
end
context 'when the user provides valid credentials' do
source_url = 'https://gitlab.com'
include_context 'bulk imports requests context', source_url
it 'successfully connects to remote instance' do
source_url = 'https://gitlab.com'
pat = 'demo-pat'
stub_path = 'stub-group'
total = 37
stub_request(:get, "%{url}/api/v4/groups?page=1&per_page=20&top_level_only=true&min_access_level=50&search=" % { url: source_url }).to_return(
body: [{
id: 2595438,
web_url: 'https://gitlab.com/groups/auto-breakfast',
name: 'Stub',
path: stub_path,
full_name: 'Stub',
full_path: stub_path
}].to_json,
headers: {
'Content-Type' => 'application/json',
'X-Next-Page' => 2,
'X-Page' => 1,
'X-Per-Page' => 20,
'X-Total' => total,
'X-Total-Pages' => 2
}
)
allow_next_instance_of(BulkImports::Clients::HTTP) do |client|
allow(client).to receive(:validate_instance_version!).and_return(true)
end
expect(page).to have_content 'Import groups from another instance of GitLab'
expect(page).to have_content 'Not all related objects are migrated'
......@@ -56,8 +34,8 @@ RSpec.describe 'Import/Export - Connect to another instance', :js do
click_on 'Connect instance'
expect(page).to have_content 'Showing 1-1 of %{total} groups from %{url}' % { url: source_url, total: total }
expect(page).to have_content stub_path
expect(page).to have_content 'Showing 1-1 of 42 groups from %{url}' % { url: source_url }
expect(page).to have_content 'stub-group'
visit '/'
......
......@@ -34,7 +34,7 @@ RSpec.describe BulkImports::Clients::Graphql do
let(:version) { '13.0.0' }
it 'raises an error' do
expect { subject.execute('test') }.to raise_error(::BulkImports::Error, "Unsupported GitLab Version. Minimum Supported Gitlab Version #{BulkImport::MINIMUM_GITLAB_MAJOR_VERSION}.")
expect { subject.execute('test') }.to raise_error(::BulkImports::Error, "Unsupported GitLab Version. Minimum Supported Gitlab Version #{BulkImport::MIN_MAJOR_VERSION}.")
end
end
end
......
......@@ -8,7 +8,7 @@ RSpec.describe BulkImports::Clients::HTTP do
let(:url) { 'http://gitlab.example' }
let(:token) { 'token' }
let(:resource) { 'resource' }
let(:version) { "#{BulkImport::MINIMUM_GITLAB_MAJOR_VERSION}.0.0" }
let(:version) { "#{BulkImport::MIN_MAJOR_VERSION}.0.0" }
let(:response_double) { double(code: 200, success?: true, parsed_response: {}) }
let(:version_response) { double(code: 200, success?: true, parsed_response: { 'version' => version }) }
......@@ -176,6 +176,28 @@ RSpec.describe BulkImports::Clients::HTTP do
end
end
describe '#instance_version' do
it 'returns version as an instance of Gitlab::VersionInfo' do
expect(subject.instance_version).to eq(Gitlab::VersionInfo.parse(version))
end
end
describe '#compatible_for_project_migration?' do
context 'when instance version is lower the the expected minimum' do
it 'returns false' do
expect(subject.compatible_for_project_migration?).to be false
end
end
context 'when instance version is at least the expected minimum' do
let(:version) { "14.4.4" }
it 'returns true' do
expect(subject.compatible_for_project_migration?).to be true
end
end
end
context 'when source instance is incompatible' do
let(:version) { '13.0.0' }
......@@ -183,7 +205,7 @@ RSpec.describe BulkImports::Clients::HTTP do
expect { subject.get(resource) }
.to raise_error(
::BulkImports::Error,
"Unsupported GitLab Version. Minimum Supported Gitlab Version #{BulkImport::MINIMUM_GITLAB_MAJOR_VERSION}."
"Unsupported GitLab Version. Minimum Supported Gitlab Version #{BulkImport::MIN_MAJOR_VERSION}."
)
end
end
......
......@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe BulkImports::Groups::Stage do
let(:bulk_import) { build(:bulk_import) }
let(:pipelines) do
[
[0, BulkImports::Groups::Pipelines::GroupPipeline],
......@@ -16,23 +18,27 @@ RSpec.describe BulkImports::Groups::Stage do
]
end
it 'raises error when initialized without a BulkImport' do
expect { described_class.new({}) }.to raise_error(ArgumentError, 'Expected an argument of type ::BulkImport')
end
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::Common::Pipelines::EntityFinisher)
expect(described_class.new(bulk_import).pipelines & pipelines).to eq(pipelines)
expect(described_class.new(bulk_import).pipelines.last.last).to eq(BulkImports::Common::Pipelines::EntityFinisher)
end
it 'includes project entities pipeline' do
stub_feature_flags(bulk_import_projects: true)
expect(described_class.pipelines).to include([1, BulkImports::Groups::Pipelines::ProjectEntitiesPipeline])
expect(described_class.new(bulk_import).pipelines).to include([1, BulkImports::Groups::Pipelines::ProjectEntitiesPipeline])
end
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)
expect(described_class.new(bulk_import).pipelines.flatten).not_to include(BulkImports::Groups::Pipelines::ProjectEntitiesPipeline)
end
end
end
......
......@@ -13,9 +13,15 @@ RSpec.describe BulkImports::Projects::Stage do
]
end
describe '.pipelines' do
subject do
bulk_import = build(:bulk_import)
described_class.new(bulk_import)
end
describe '#pipelines' do
it 'list all the pipelines with their stage number, ordered by stage' do
expect(described_class.pipelines).to eq(pipelines)
expect(subject.pipelines).to eq(pipelines)
end
end
end
......@@ -21,4 +21,18 @@ RSpec.describe BulkImport, type: :model do
expect(described_class.all_human_statuses).to contain_exactly('created', 'started', 'finished', 'failed')
end
end
describe '.min_gl_version_for_project' do
it { expect(described_class.min_gl_version_for_project_migration).to be_a(Gitlab::VersionInfo) }
it { expect(described_class.min_gl_version_for_project_migration.to_s).to eq('14.4.0') }
end
describe '#source_version_info' do
it 'returns source_version as Gitlab::VersionInfo' do
bulk_import = build(:bulk_import, source_version: '9.13.2')
expect(bulk_import.source_version_info).to be_a(Gitlab::VersionInfo)
expect(bulk_import.source_version_info.to_s).to eq(bulk_import.source_version)
end
end
end
......@@ -179,7 +179,7 @@ RSpec.describe BulkImports::Entity, type: :model do
entity = create(:bulk_import_entity, :group_entity)
entity.create_pipeline_trackers!
expect(entity.trackers.count).to eq(BulkImports::Groups::Stage.pipelines.count)
expect(entity.trackers.count).to eq(BulkImports::Groups::Stage.new(entity.bulk_import).pipelines.count)
expect(entity.trackers.map(&:pipeline_name)).to include(BulkImports::Groups::Pipelines::GroupPipeline.to_s)
end
end
......@@ -189,7 +189,7 @@ RSpec.describe BulkImports::Entity, type: :model do
entity = create(:bulk_import_entity, :project_entity)
entity.create_pipeline_trackers!
expect(entity.trackers.count).to eq(BulkImports::Projects::Stage.pipelines.count)
expect(entity.trackers.count).to eq(BulkImports::Projects::Stage.new(entity.bulk_import).pipelines.count)
expect(entity.trackers.map(&:pipeline_name)).to include(BulkImports::Projects::Pipelines::ProjectPipeline.to_s)
end
end
......
......@@ -66,7 +66,8 @@ RSpec.describe BulkImports::Tracker, type: :model do
describe '#pipeline_class' do
it 'returns the pipeline class' do
pipeline_class = BulkImports::Groups::Stage.pipelines.first[1]
bulk_import = create(:bulk_import)
pipeline_class = BulkImports::Groups::Stage.new(bulk_import).pipelines.first[1]
tracker = create(:bulk_import_tracker, pipeline_name: pipeline_class)
expect(tracker.pipeline_class).to eq(pipeline_class)
......
......@@ -21,6 +21,15 @@ RSpec.describe API::BulkImports do
end
describe 'POST /bulk_imports' do
before do
allow_next_instance_of(BulkImports::Clients::HTTP) do |instance|
allow(instance)
.to receive(:instance_version)
.and_return(
Gitlab::VersionInfo.new(::BulkImport::MIN_MAJOR_VERSION, ::BulkImport::MIN_MINOR_VERSION_FOR_PROJECT))
end
end
it 'starts a new migration' do
post api('/bulk_imports', user), params: {
configuration: {
......
......@@ -31,8 +31,25 @@ RSpec.describe BulkImports::CreateService do
subject { described_class.new(user, params, credentials) }
describe '#execute' do
let_it_be(:source_version) do
Gitlab::VersionInfo.new(::BulkImport::MIN_MAJOR_VERSION,
::BulkImport::MIN_MINOR_VERSION_FOR_PROJECT)
end
before do
allow_next_instance_of(BulkImports::Clients::HTTP) do |instance|
allow(instance).to receive(:instance_version).and_return(source_version)
end
end
it 'creates bulk import' do
expect { subject.execute }.to change { BulkImport.count }.by(1)
last_bulk_import = BulkImport.last
expect(last_bulk_import.user).to eq(user)
expect(last_bulk_import.source_version).to eq(source_version.to_s)
expect(last_bulk_import.user).to eq(user)
end
it 'creates bulk import entities' do
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe BulkImports::GetImportableDataService do
describe '#execute' do
include_context 'bulk imports requests context', 'https://gitlab.example.com'
let_it_be(:params) { { per_page: 20, page: 1 } }
let_it_be(:query_params) { { top_level_only: true, min_access_level: 50, search: '' } }
let_it_be(:credentials) { { url: 'https://gitlab.example.com', access_token: 'demo-pat' } }
let_it_be(:expected_version_validation) do
{
features: {
project_migration: {
available: true,
min_version: BulkImport.min_gl_version_for_project_migration.to_s
},
'source_instance_version': BulkImport.min_gl_version_for_project_migration.to_s
}
}
end
let_it_be(:expected_parsed_response) do
[
{
'id' => 2595438,
'web_url' => 'https://gitlab.com/groups/auto-breakfast',
'name' => 'Stub',
'path' => 'stub-group',
'full_name' => 'Stub',
'full_path' => 'stub-group'
}
]
end
subject do
described_class.new(params, query_params, credentials).execute
end
it 'returns version_validation and a response' do
expect(subject[:version_validation]).to eq(expected_version_validation)
expect(subject[:response].parsed_response).to eq(expected_parsed_response)
end
end
end
# frozen_string_literal: true
RSpec.shared_context 'bulk imports requests context' do |url|
let(:page_response_headers) do
{
'Content-Type' => 'application/json',
'X-Next-Page' => 2,
'X-Page' => 1,
'X-Per-Page' => 20,
'X-Total' => 42,
'X-Total-Pages' => 2
}
end
let(:request_headers) { { 'Authorization' => 'Bearer demo-pat', 'Content-Type' => 'application/json' } }
before do
stub_request(:get, "#{url}/api/v4/version")
.with(headers: request_headers)
.to_return(
status: 200,
body: { version: ::BulkImport.min_gl_version_for_project_migration.to_s }.to_json,
headers: { 'Content-Type' => 'application/json' })
stub_request(:get, "https://gitlab.example.com/api/v4/groups?min_access_level=50&page=1&per_page=20&search=test&top_level_only=true")
.with(headers: request_headers)
.to_return(status: 200,
body: [{
id: 2595440,
web_url: 'https://gitlab.com/groups/test',
name: 'Test',
path: 'stub-test-group',
full_name: 'Test',
full_path: 'stub-test-group'
}].to_json,
headers: page_response_headers
)
stub_request(:get, "%{url}/api/v4/groups?page=1&per_page=20&top_level_only=true&min_access_level=50&search=" % { url: url })
.to_return(
body: [{
id: 2595438,
web_url: 'https://gitlab.com/groups/auto-breakfast',
name: 'Stub',
path: 'stub-group',
full_name: 'Stub',
full_path: 'stub-group'
}].to_json,
headers: page_response_headers
)
end
end
......@@ -84,7 +84,7 @@ RSpec.describe BulkImportWorker do
expect { subject.perform(bulk_import.id) }
.to change(BulkImports::Tracker, :count)
.by(BulkImports::Groups::Stage.pipelines.size * 2)
.by(BulkImports::Groups::Stage.new(bulk_import).pipelines.size * 2)
expect(entity_1.trackers).not_to be_empty
expect(entity_2.trackers).not_to be_empty
......
......@@ -22,9 +22,10 @@ RSpec.describe BulkImports::PipelineWorker do
before do
stub_const('FakePipeline', pipeline_class)
allow(BulkImports::Groups::Stage)
.to receive(:pipelines)
.and_return([[0, pipeline_class]])
allow_next_instance_of(BulkImports::Groups::Stage) do |instance|
allow(instance).to receive(:pipelines)
.and_return([[0, pipeline_class]])
end
end
shared_examples 'successfully runs the pipeline' do
......@@ -206,9 +207,10 @@ RSpec.describe BulkImports::PipelineWorker do
before do
stub_const('NdjsonPipeline', ndjson_pipeline)
allow(BulkImports::Groups::Stage)
.to receive(:pipelines)
.and_return([[0, ndjson_pipeline]])
allow_next_instance_of(BulkImports::Groups::Stage) do |instance|
allow(instance).to receive(:pipelines)
.and_return([[0, ndjson_pipeline]])
end
end
it 'runs the pipeline successfully' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment