diff options
Diffstat (limited to 'spec/lib/gitlab/github_import/importer')
4 files changed, 264 insertions, 4 deletions
diff --git a/spec/lib/gitlab/github_import/importer/collaborator_importer_spec.rb b/spec/lib/gitlab/github_import/importer/collaborator_importer_spec.rb new file mode 100644 index 00000000000..07c10fe57f0 --- /dev/null +++ b/spec/lib/gitlab/github_import/importer/collaborator_importer_spec.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::GithubImport::Importer::CollaboratorImporter, feature_category: :importers do + subject(:importer) { described_class.new(collaborator, project, client) } + + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, :repository, group: group) } + let_it_be(:user) { create(:user) } + + let(:client) { instance_double(Gitlab::GithubImport::Client) } + let(:github_user_id) { rand(1000) } + let(:collaborator) do + Gitlab::GithubImport::Representation::Collaborator.from_json_hash( + 'id' => github_user_id, + 'login' => user.username, + 'role_name' => github_role_name + ) + end + + let(:basic_member_attrs) do + { + source: project, + user_id: user.id, + member_namespace_id: project.project_namespace_id, + created_by_id: project.creator_id + }.stringify_keys + end + + describe '#execute' do + before do + allow_next_instance_of(Gitlab::GithubImport::UserFinder) do |finder| + allow(finder).to receive(:find).with(github_user_id, user.username).and_return(user.id) + end + end + + shared_examples 'role mapping' do |collaborator_role, member_access_level| + let(:github_role_name) { collaborator_role } + + it 'creates expected member' do + expect { importer.execute }.to change { project.members.count } + .from(0).to(1) + + expected_member_attrs = basic_member_attrs.merge(access_level: member_access_level) + expect(project.members.last).to have_attributes(expected_member_attrs) + end + end + + it_behaves_like 'role mapping', 'read', Gitlab::Access::GUEST + it_behaves_like 'role mapping', 'triage', Gitlab::Access::REPORTER + it_behaves_like 'role mapping', 'write', Gitlab::Access::DEVELOPER + it_behaves_like 'role mapping', 'maintain', Gitlab::Access::MAINTAINER + it_behaves_like 'role mapping', 'admin', Gitlab::Access::OWNER + + context 'when role name is unknown (custom role)' do + let(:github_role_name) { 'custom_role' } + + it 'raises expected error' do + expect { importer.execute }.to raise_exception( + ::Gitlab::GithubImport::ObjectImporter::NotRetriableError + ).with_message("Unknown GitHub role: #{github_role_name}") + end + end + + context 'when user has lower role in a project group' do + before do + create(:group_member, group: group, user: user, access_level: Gitlab::Access::DEVELOPER) + end + + it_behaves_like 'role mapping', 'maintain', Gitlab::Access::MAINTAINER + end + + context 'when user has higher role in a project group' do + let(:github_role_name) { 'write' } + + before do + create(:group_member, group: group, user: user, access_level: Gitlab::Access::MAINTAINER) + end + + it 'skips creating member for the project' do + expect { importer.execute }.not_to change { project.members.count } + end + end + end +end diff --git a/spec/lib/gitlab/github_import/importer/collaborators_importer_spec.rb b/spec/lib/gitlab/github_import/importer/collaborators_importer_spec.rb new file mode 100644 index 00000000000..e48b562279e --- /dev/null +++ b/spec/lib/gitlab/github_import/importer/collaborators_importer_spec.rb @@ -0,0 +1,119 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::GithubImport::Importer::CollaboratorsImporter, feature_category: :importers do + subject(:importer) { described_class.new(project, client, parallel: parallel) } + + let(:parallel) { true } + let(:project) { instance_double(Project, id: 4, import_source: 'foo/bar', import_state: nil) } + let(:client) { instance_double(Gitlab::GithubImport::Client) } + + let(:github_collaborator) do + { + id: 100500, + login: 'bob', + role_name: 'maintainer' + } + end + + describe '#parallel?' do + context 'when parallel option is true' do + it { expect(importer).to be_parallel } + end + + context 'when parallel option is false' do + let(:parallel) { false } + + it { expect(importer).not_to be_parallel } + end + end + + describe '#execute' do + context 'when running in parallel mode' do + it 'imports collaborators in parallel' do + expect(importer).to receive(:parallel_import) + importer.execute + end + end + + context 'when running in sequential mode' do + let(:parallel) { false } + + it 'imports collaborators in sequence' do + expect(importer).to receive(:sequential_import) + importer.execute + end + end + end + + describe '#sequential_import' do + let(:parallel) { false } + + it 'imports each collaborator in sequence' do + collaborator_importer = instance_double(Gitlab::GithubImport::Importer::CollaboratorImporter) + + allow(importer) + .to receive(:each_object_to_import) + .and_yield(github_collaborator) + + expect(Gitlab::GithubImport::Importer::CollaboratorImporter) + .to receive(:new) + .with( + an_instance_of(Gitlab::GithubImport::Representation::Collaborator), + project, + client + ) + .and_return(collaborator_importer) + + expect(collaborator_importer).to receive(:execute) + + importer.sequential_import + end + end + + describe '#parallel_import', :clean_gitlab_redis_cache do + let(:page_struct) { Struct.new(:objects, :number, keyword_init: true) } + + before do + allow(client).to receive(:each_page) + .with(:collaborators, project.import_source, { page: 1 }) + .and_yield(page_struct.new(number: 1, objects: [github_collaborator])) + end + + it 'imports each collaborator in parallel' do + expect(Gitlab::GithubImport::ImportCollaboratorWorker).to receive(:perform_in) + .with(1.second, project.id, an_instance_of(Hash), an_instance_of(String)) + + waiter = importer.parallel_import + + expect(waiter).to be_an_instance_of(Gitlab::JobWaiter) + expect(waiter.jobs_remaining).to eq(1) + end + + context 'when collaborator is already imported' do + before do + Gitlab::Cache::Import::Caching.set_add( + "github-importer/already-imported/#{project.id}/collaborators", + github_collaborator[:id] + ) + end + + it "doesn't run importer on it" do + expect(Gitlab::GithubImport::ImportCollaboratorWorker).not_to receive(:perform_in) + + waiter = importer.parallel_import + + expect(waiter).to be_an_instance_of(Gitlab::JobWaiter) + expect(waiter.jobs_remaining).to eq(0) + end + end + end + + describe '#id_for_already_imported_cache' do + it 'returns the ID of the given note' do + expect(importer.id_for_already_imported_cache(github_collaborator)) + .to eq(100500) + end + end +end diff --git a/spec/lib/gitlab/github_import/importer/label_links_importer_spec.rb b/spec/lib/gitlab/github_import/importer/label_links_importer_spec.rb index e005d8eda84..16816dfbcea 100644 --- a/spec/lib/gitlab/github_import/importer/label_links_importer_spec.rb +++ b/spec/lib/gitlab/github_import/importer/label_links_importer_spec.rb @@ -44,6 +44,10 @@ RSpec.describe Gitlab::GithubImport::Importer::LabelLinksImporter do end it 'does not insert label links for non-existing labels' do + expect(importer) + .to receive(:find_target_id) + .and_return(4) + expect(importer.label_finder) .to receive(:id_for) .with('bug') @@ -55,6 +59,20 @@ RSpec.describe Gitlab::GithubImport::Importer::LabelLinksImporter do importer.create_labels end + + it 'does not insert label links for non-existing targets' do + expect(importer) + .to receive(:find_target_id) + .and_return(nil) + + expect(importer.label_finder) + .not_to receive(:id_for) + + expect(LabelLink) + .not_to receive(:bulk_insert!) + + importer.create_labels + end end describe '#find_target_id' do diff --git a/spec/lib/gitlab/github_import/importer/note_attachments_importer_spec.rb b/spec/lib/gitlab/github_import/importer/note_attachments_importer_spec.rb index 7d4e3c3bcce..450ebe9a719 100644 --- a/spec/lib/gitlab/github_import/importer/note_attachments_importer_spec.rb +++ b/spec/lib/gitlab/github_import/importer/note_attachments_importer_spec.rb @@ -2,10 +2,10 @@ require 'spec_helper' -RSpec.describe Gitlab::GithubImport::Importer::NoteAttachmentsImporter do +RSpec.describe Gitlab::GithubImport::Importer::NoteAttachmentsImporter, feature_category: :importers do subject(:importer) { described_class.new(note_text, project, client) } - let_it_be(:project) { create(:project) } + let_it_be(:project) { create(:project, import_source: 'nickname/public-test-repo') } let(:note_text) { Gitlab::GithubImport::Representation::NoteText.from_db_record(record) } let(:client) { instance_double('Gitlab::GithubImport::Client') } @@ -13,6 +13,8 @@ RSpec.describe Gitlab::GithubImport::Importer::NoteAttachmentsImporter do let(:doc_url) { 'https://github.com/nickname/public-test-repo/files/9020437/git-cheat-sheet.txt' } let(:image_url) { 'https://user-images.githubusercontent.com/6833842/0cf366b61ef2.jpeg' } let(:image_tag_url) { 'https://user-images.githubusercontent.com/6833842/0cf366b61ea5.jpeg' } + let(:project_blob_url) { 'https://github.com/nickname/public-test-repo/blob/main/example.md' } + let(:other_project_blob_url) { 'https://github.com/nickname/other-repo/blob/main/README.md' } let(:text) do <<-TEXT.split("\n").map(&:strip).join("\n") Some text... @@ -20,11 +22,14 @@ RSpec.describe Gitlab::GithubImport::Importer::NoteAttachmentsImporter do [special-doc](#{doc_url}) ![image.jpeg](#{image_url}) <img width=\"248\" alt=\"tag-image\" src="#{image_tag_url}"> + + [link to project blob file](#{project_blob_url}) + [link to other project blob file](#{other_project_blob_url}) TEXT end shared_examples 'updates record description' do - it do + it 'changes attachment links' do importer.execute record.reload @@ -32,6 +37,22 @@ RSpec.describe Gitlab::GithubImport::Importer::NoteAttachmentsImporter do expect(record.description).to include('![image.jpeg](/uploads/') expect(record.description).to include('<img width="248" alt="tag-image" src="/uploads') end + + it 'changes link to project blob files' do + importer.execute + + record.reload + expected_blob_link = "[link to project blob file](http://localhost/#{project.full_path}/-/blob/main/example.md)" + expect(record.description).not_to include("[link to project blob file](#{project_blob_url})") + expect(record.description).to include(expected_blob_link) + end + + it "doesn't change links to other projects" do + importer.execute + + record.reload + expect(record.description).to include("[link to other project blob file](#{other_project_blob_url})") + end end describe '#execute' do @@ -72,7 +93,7 @@ RSpec.describe Gitlab::GithubImport::Importer::NoteAttachmentsImporter do context 'when importing note attachments' do let(:record) { create(:note, project: project, note: text) } - it 'updates note text with new attachment urls' do + it 'changes note text with new attachment urls' do importer.execute record.reload @@ -80,6 +101,22 @@ RSpec.describe Gitlab::GithubImport::Importer::NoteAttachmentsImporter do expect(record.note).to include('![image.jpeg](/uploads/') expect(record.note).to include('<img width="248" alt="tag-image" src="/uploads') end + + it 'changes note links to project blob files' do + importer.execute + + record.reload + expected_blob_link = "[link to project blob file](http://localhost/#{project.full_path}/-/blob/main/example.md)" + expect(record.note).not_to include("[link to project blob file](#{project_blob_url})") + expect(record.note).to include(expected_blob_link) + end + + it "doesn't change note links to other projects" do + importer.execute + + record.reload + expect(record.note).to include("[link to other project blob file](#{other_project_blob_url})") + end end end end |