gitlab-org--gitlab-foss/spec/services/bulk_imports/relation_export_service_spe...

147 lines
4.2 KiB
Ruby

# frozen_string_literal: true
require 'spec_helper'
RSpec.describe BulkImports::RelationExportService do
let_it_be(:jid) { 'jid' }
let_it_be(:relation) { 'labels' }
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project) }
let_it_be(:label) { create(:group_label, group: group) }
let_it_be(:export_path) { "#{Dir.tmpdir}/relation_export_service_spec/tree" }
let_it_be_with_reload(:export) { create(:bulk_import_export, group: group, relation: relation) }
before do
group.add_owner(user)
project.add_maintainer(user)
allow(export).to receive(:export_path).and_return(export_path)
end
after :all do
FileUtils.rm_rf(export_path)
end
subject { described_class.new(user, group, relation, jid) }
describe '#execute' do
it 'exports specified relation and marks export as finished' do
expect_next_instance_of(BulkImports::TreeExportService) do |service|
expect(service).to receive(:execute).and_call_original
end
subject.execute
expect(export.reload.upload.export_file).to be_present
expect(export.finished?).to eq(true)
end
it 'removes temp export files' do
subject.execute
expect(Dir.exist?(export_path)).to eq(false)
end
it 'exports specified relation and marks export as finished' do
subject.execute
expect(export.upload.export_file).to be_present
end
context 'when exporting a file relation' do
it 'uses file export service' do
service = described_class.new(user, project, 'uploads', jid)
expect_next_instance_of(BulkImports::FileExportService) do |service|
expect(service).to receive(:execute)
end
service.execute
end
end
context 'when export record does not exist' do
let(:another_group) { create(:group) }
subject { described_class.new(user, another_group, relation, jid) }
it 'creates export record' do
another_group.add_owner(user)
expect { subject.execute }
.to change { another_group.bulk_import_exports.count }
.from(0)
.to(1)
end
end
context 'when there is existing export present' do
let(:upload) { create(:bulk_import_export_upload, export: export) }
it 'removes existing export before exporting' do
upload.update!(export_file: fixture_file_upload('spec/fixtures/bulk_imports/gz/labels.ndjson.gz'))
expect_any_instance_of(BulkImports::ExportUpload) do |upload|
expect(upload).to receive(:remove_export_file!)
end
subject.execute
end
context 'when export is recently finished' do
it 'returns recently finished export instead of re-exporting' do
updated_at = 5.seconds.ago
export.update!(status: 1, updated_at: updated_at)
expect { subject.execute }.not_to change { export.updated_at }
expect(export.status).to eq(1)
expect(export.updated_at).to eq(updated_at)
end
end
end
context 'when exception occurs during export' do
shared_examples 'tracks exception' do |exception_class|
it 'tracks exception' do
expect(Gitlab::ErrorTracking)
.to receive(:track_exception)
.with(exception_class, portable_id: group.id, portable_type: group.class.name)
.and_call_original
subject.execute
end
end
before do
allow_next_instance_of(BulkImports::ExportUpload) do |upload|
allow(upload).to receive(:save!).and_raise(StandardError)
end
end
it 'marks export as failed' do
subject.execute
expect(export.reload.failed?).to eq(true)
end
include_examples 'tracks exception', StandardError
context 'when passed relation is not supported' do
let(:relation) { 'unsupported' }
include_examples 'tracks exception', ActiveRecord::RecordInvalid
end
context 'when user is not allowed to perform export' do
let(:another_user) { create(:user) }
subject { described_class.new(another_user, group, relation, jid) }
include_examples 'tracks exception', Gitlab::ImportExport::Error
end
end
end
end