Commit 701976e0 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Add uploads rewriter and use it when moving issue

parent cff3497f
...@@ -43,7 +43,7 @@ module Issues ...@@ -43,7 +43,7 @@ module Issues
def create_new_issue def create_new_issue
new_params = { id: nil, iid: nil, label_ids: [], milestone: nil, new_params = { id: nil, iid: nil, label_ids: [], milestone: nil,
project: @new_project, author: @old_issue.author, project: @new_project, author: @old_issue.author,
description: unfold_references(@old_issue.description) } description: rewrite_content(@old_issue.description) }
new_params = @old_issue.serializable_hash.merge(new_params) new_params = @old_issue.serializable_hash.merge(new_params)
CreateService.new(@new_project, @current_user, new_params).execute CreateService.new(@new_project, @current_user, new_params).execute
...@@ -53,7 +53,7 @@ module Issues ...@@ -53,7 +53,7 @@ module Issues
@old_issue.notes.find_each do |note| @old_issue.notes.find_each do |note|
new_note = note.dup new_note = note.dup
new_params = { project: @new_project, noteable: @new_issue, new_params = { project: @new_project, noteable: @new_issue,
note: unfold_references(new_note.note), note: rewrite_content(new_note.note),
created_at: note.created_at, created_at: note.created_at,
updated_at: note.updated_at } updated_at: note.updated_at }
...@@ -61,6 +61,29 @@ module Issues ...@@ -61,6 +61,29 @@ module Issues
end end
end end
def rewrite_content(content)
rewrite_uploads(
unfold_references(content)
)
end
def unfold_references(content)
return unless content
rewriter = Gitlab::Gfm::ReferenceRewriter.new(content, @old_project,
@current_user)
rewriter.rewrite(@new_project)
end
def rewrite_uploads(content)
return unless content
rewriter = Gitlab::Gfm::UploadsRewriter.new(content, @old_project,
@current_user)
return content unless rewriter.has_uploads?
rewriter.rewrite(@new_project)
end
def close_issue def close_issue
close_service = CloseService.new(@old_project, @current_user) close_service = CloseService.new(@old_project, @current_user)
close_service.execute(@old_issue, notifications: false, system_note: false) close_service.execute(@old_issue, notifications: false, system_note: false)
...@@ -78,20 +101,12 @@ module Issues ...@@ -78,20 +101,12 @@ module Issues
direction: :to) direction: :to)
end end
def unfold_references(content) def mark_as_moved
return unless content @old_issue.update(moved_to: @new_issue)
rewriter = Gitlab::Gfm::ReferenceRewriter.new(content, @old_project,
@current_user)
rewriter.rewrite(@new_project)
end end
def notify_participants def notify_participants
notification_service.issue_moved(@old_issue, @new_issue, @current_user) notification_service.issue_moved(@old_issue, @new_issue, @current_user)
end end
def mark_as_moved
@old_issue.update(moved_to: @new_issue)
end
end end
end end
module Gitlab
module Gfm
##
# Class that rewrites markdown links for uploads
#
# Using a pattern defined in `FileUploader` copies files to a new project
# and rewrites all links to uploads in ain a given text.
#
class UploadsRewriter
def initialize(text, source_project, _current_user)
@text = text
@source_project = source_project
@pattern = FileUploader::MARKDOWN_PATTERN
end
def rewrite(target_project)
return unless @text
new_uploader = file_uploader(target_project)
@text.gsub(@pattern) do |markdown_link|
old_file = find_file(@source_project, $~[:secret], $~[:file])
return markdown_link unless old_file.exists?
new_uploader.store!(old_file)
new_uploader.to_h[:markdown]
end
end
def has_uploads?
!(@text =~ @pattern).nil?
end
def files
referenced_files = @text.scan(@pattern).map do
find_file(@source_project, $~[:secret], $~[:file])
end
referenced_files.compact.select(&:exists?)
end
private
def find_file(project, secret, file)
uploader = file_uploader(project, secret)
uploader.retrieve_from_store!(file)
uploader.file
end
def file_uploader(*args)
uploader = FileUploader.new(*args)
uploader.define_singleton_method(:move_to_store) { false }
uploader
end
end
end
end
require 'spec_helper'
describe Gitlab::Gfm::UploadsRewriter do
let(:user) { create(:user) }
let(:old_project) { create(:project) }
let(:new_project) { create(:project) }
let(:rewriter) { described_class.new(text, old_project, user) }
context 'text contains links to uploads' do
let(:path) { Rails.root + 'spec/fixtures/rails_sample.jpg' }
let(:file) { fixture_file_upload(path, 'image/jpg') }
let(:uploader) { FileUploader.new(old_project) }
let!(:store) { uploader.store!(file) } # TODO, see #xxx (carrierwave issue)
let(:markdown) { uploader.to_h[:markdown] }
let(:text) { "Text and #{markdown}"}
describe '#rewrite' do
let!(:new_text) { rewriter.rewrite(new_project) }
let(:new_rewriter) { described_class.new(new_text, new_project, user) }
let(:old_file) { rewriter.files.first }
let(:new_file) { new_rewriter.files.first }
it 'rewrites content' do
expect(new_text).to_not eq text
expect(new_text.length).to eq text.length
end
it 'copies files' do
expect(new_file.exists?).to eq true
expect(old_file.path).to_not eq new_file.path
expect(new_file.path).to include new_project.path_with_namespace
end
it 'does not remove old files' do
expect(old_file.exists?).to be true
end
end
describe '#has_uploads?' do
subject { rewriter.has_uploads? }
it { is_expected.to eq true }
end
describe '#files' do
subject { rewriter.files }
it { is_expected.to be_an(Array) }
end
end
end
...@@ -160,6 +160,25 @@ describe Issues::MoveService, services: true do ...@@ -160,6 +160,25 @@ describe Issues::MoveService, services: true do
.to eq "Note with reference to merge request #{old_project.to_reference}!1" .to eq "Note with reference to merge request #{old_project.to_reference}!1"
end end
end end
context 'issue description with uploads' do
let(:path) { Rails.root + 'spec/fixtures/rails_sample.jpg' }
let(:file) { fixture_file_upload(path, 'image/jpg') }
let(:uploader) { FileUploader.new(old_project) }
let!(:store) { uploader.store!(file) }
let(:markdown) { uploader.to_h[:markdown] }
let(:description) { "Text and #{markdown}"}
include_context 'issue move executed'
it 'rewrites uploads in description' do
expect(new_issue.description).to_not eq description
expect(new_issue.description)
.to match(/Text and #{FileUploader::MARKDOWN_PATTERN}/)
end
after { uploader.remove! }
end
end end
describe 'rewritting references' do describe 'rewritting references' 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