summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Bizon <grzesiek.bizon@gmail.com>2016-03-24 12:28:43 +0100
committerGrzegorz Bizon <grzesiek.bizon@gmail.com>2016-03-30 10:44:18 +0200
commit701976e0815c273ff4a4c6e4d3489db0ce2f0860 (patch)
treee519cfebe16a9684bb6162421c2be159243142ba
parentcff3497f2c06dd4e1785af3c844040ed7939dcb0 (diff)
downloadgitlab-ce-701976e0815c273ff4a4c6e4d3489db0ce2f0860.tar.gz
Add uploads rewriter and use it when moving issue
-rw-r--r--app/services/issues/move_service.rb39
-rw-r--r--lib/gitlab/gfm/uploads_rewriter.rb56
-rw-r--r--spec/lib/gitlab/gfm/uploads_rewriter_spec.rb49
-rw-r--r--spec/services/issues/move_service_spec.rb19
4 files changed, 151 insertions, 12 deletions
diff --git a/app/services/issues/move_service.rb b/app/services/issues/move_service.rb
index a5efb21fab6..e15e25ee536 100644
--- a/app/services/issues/move_service.rb
+++ b/app/services/issues/move_service.rb
@@ -43,7 +43,7 @@ module Issues
def create_new_issue
new_params = { id: nil, iid: nil, label_ids: [], milestone: nil,
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)
CreateService.new(@new_project, @current_user, new_params).execute
@@ -53,7 +53,7 @@ module Issues
@old_issue.notes.find_each do |note|
new_note = note.dup
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,
updated_at: note.updated_at }
@@ -61,6 +61,29 @@ module Issues
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
close_service = CloseService.new(@old_project, @current_user)
close_service.execute(@old_issue, notifications: false, system_note: false)
@@ -78,20 +101,12 @@ module Issues
direction: :to)
end
- def unfold_references(content)
- return unless content
-
- rewriter = Gitlab::Gfm::ReferenceRewriter.new(content, @old_project,
- @current_user)
- rewriter.rewrite(@new_project)
+ def mark_as_moved
+ @old_issue.update(moved_to: @new_issue)
end
def notify_participants
notification_service.issue_moved(@old_issue, @new_issue, @current_user)
end
-
- def mark_as_moved
- @old_issue.update(moved_to: @new_issue)
- end
end
end
diff --git a/lib/gitlab/gfm/uploads_rewriter.rb b/lib/gitlab/gfm/uploads_rewriter.rb
new file mode 100644
index 00000000000..778b6fe9f9d
--- /dev/null
+++ b/lib/gitlab/gfm/uploads_rewriter.rb
@@ -0,0 +1,56 @@
+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
diff --git a/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb b/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb
new file mode 100644
index 00000000000..7027954ef27
--- /dev/null
+++ b/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb
@@ -0,0 +1,49 @@
+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
diff --git a/spec/services/issues/move_service_spec.rb b/spec/services/issues/move_service_spec.rb
index 9b0c73aaf37..1cc2daa908f 100644
--- a/spec/services/issues/move_service_spec.rb
+++ b/spec/services/issues/move_service_spec.rb
@@ -160,6 +160,25 @@ describe Issues::MoveService, services: true do
.to eq "Note with reference to merge request #{old_project.to_reference}!1"
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
describe 'rewritting references' do