Commit 5266ae87 authored by Sean McGivern's avatar Sean McGivern

Support renames in diff_for_path actions

parent e462e122
...@@ -24,7 +24,11 @@ module DiffHelper ...@@ -24,7 +24,11 @@ module DiffHelper
def diff_options def diff_options
default_options = Commit.max_diff_options default_options = Commit.max_diff_options
default_options[:paths] = [params[:path]] if params[:path]
if action_name == 'diff_for_path'
default_options[:paths] = params.values_at(:old_path, :new_path)
end
default_options.merge(ignore_whitespace_change: hide_whitespace?) default_options.merge(ignore_whitespace_change: hide_whitespace?)
end end
......
...@@ -47,7 +47,7 @@ class MergeRequestDiff < ActiveRecord::Base ...@@ -47,7 +47,7 @@ class MergeRequestDiff < ActiveRecord::Base
end end
else else
@diffs ||= {} @diffs ||= {}
@diffs[options[:paths]] ||= load_diffs(st_diffs, options) @diffs[options] ||= load_diffs(st_diffs, options)
end end
end end
...@@ -146,8 +146,9 @@ class MergeRequestDiff < ActiveRecord::Base ...@@ -146,8 +146,9 @@ class MergeRequestDiff < ActiveRecord::Base
def load_diffs(raw, options) def load_diffs(raw, options)
if raw.respond_to?(:each) if raw.respond_to?(:each)
if options[:paths] if options[:paths]
old_path, new_path = options[:paths]
raw = raw.select do |diff| raw = raw.select do |diff|
options[:paths].include?(diff[:new_path]) old_path == diff[:old_path] && new_path == diff[:new_path]
end end
end end
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
.nothing-here-block This diff was suppressed by a .gitattributes entry. .nothing-here-block This diff was suppressed by a .gitattributes entry.
- elsif diff_file.diff_lines.length > 0 - elsif diff_file.diff_lines.length > 0
- if diff_file.collapsed_by_default? && !expand_all_diffs? - if diff_file.collapsed_by_default? && !expand_all_diffs?
- url = url_for(params.merge(action: :diff_for_path, path: diff_file.file_path, format: nil)) - url = url_for(params.merge(action: :diff_for_path, old_path: diff_file.old_path, new_path: diff_file.new_path))
.nothing-here-block.diff-collapsed{data: { diff_for_path: url } } .nothing-here-block.diff-collapsed{data: { diff_for_path: url } }
This diff is collapsed. Click to expand it. This diff is collapsed. Click to expand it.
- elsif diff_view == 'parallel' - elsif diff_view == 'parallel'
......
...@@ -615,13 +615,13 @@ Rails.application.routes.draw do ...@@ -615,13 +615,13 @@ Rails.application.routes.draw do
post :retry_builds post :retry_builds
post :revert post :revert
post :cherry_pick post :cherry_pick
get '/diffs/*path', action: :diff_for_path, constraints: { format: false } get :diff_for_path
end end
end end
resources :compare, only: [:index, :create] do resources :compare, only: [:index, :create] do
collection do collection do
get '/diffs/*path', action: :diff_for_path, constraints: { format: false } get :diff_for_path
end end
end end
...@@ -711,14 +711,14 @@ Rails.application.routes.draw do ...@@ -711,14 +711,14 @@ Rails.application.routes.draw do
post :toggle_subscription post :toggle_subscription
post :toggle_award_emoji post :toggle_award_emoji
post :remove_wip post :remove_wip
get '/diffs/*path', action: :diff_for_path, constraints: { format: false } get :diff_for_path
end end
collection do collection do
get :branch_from get :branch_from
get :branch_to get :branch_to
get :update_branches get :update_branches
get '/diffs/*path', action: :diff_for_path, constraints: { format: false } get :diff_for_path
end end
end end
......
...@@ -267,7 +267,7 @@ describe Projects::CommitController do ...@@ -267,7 +267,7 @@ describe Projects::CommitController do
context 'when the user has access to the project' do context 'when the user has access to the project' do
context 'when the path exists in the diff' do context 'when the path exists in the diff' do
it 'enables diff notes' do it 'enables diff notes' do
diff_for_path(id: commit.id, path: existing_path) diff_for_path(id: commit.id, old_path: existing_path, new_path: existing_path)
expect(assigns(:diff_notes_disabled)).to be_falsey expect(assigns(:diff_notes_disabled)).to be_falsey
expect(assigns(:comments_target)).to eq(noteable_type: 'Commit', expect(assigns(:comments_target)).to eq(noteable_type: 'Commit',
...@@ -280,12 +280,12 @@ describe Projects::CommitController do ...@@ -280,12 +280,12 @@ describe Projects::CommitController do
meth.call(diffs, diff_refs, project) meth.call(diffs, diff_refs, project)
end end
diff_for_path(id: commit.id, path: existing_path) diff_for_path(id: commit.id, old_path: existing_path, new_path: existing_path)
end end
end end
context 'when the path does not exist in the diff' do context 'when the path does not exist in the diff' do
before { diff_for_path(id: commit.id, path: existing_path.succ) } before { diff_for_path(id: commit.id, old_path: existing_path.succ, new_path: existing_path.succ) }
it 'returns a 404' do it 'returns a 404' do
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
...@@ -296,7 +296,7 @@ describe Projects::CommitController do ...@@ -296,7 +296,7 @@ describe Projects::CommitController do
context 'when the user does not have access to the project' do context 'when the user does not have access to the project' do
before do before do
project.team.truncate project.team.truncate
diff_for_path(id: commit.id, path: existing_path) diff_for_path(id: commit.id, old_path: existing_path, new_path: existing_path)
end end
it 'returns a 404' do it 'returns a 404' do
...@@ -306,7 +306,7 @@ describe Projects::CommitController do ...@@ -306,7 +306,7 @@ describe Projects::CommitController do
end end
context 'when the commit does not exist' do context 'when the commit does not exist' do
before { diff_for_path(id: commit.id.succ, path: existing_path) } before { diff_for_path(id: commit.id.succ, old_path: existing_path, new_path: existing_path) }
it 'returns a 404' do it 'returns a 404' do
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
......
...@@ -81,7 +81,7 @@ describe Projects::CompareController do ...@@ -81,7 +81,7 @@ describe Projects::CompareController do
context 'when the user has access to the project' do context 'when the user has access to the project' do
context 'when the path exists in the diff' do context 'when the path exists in the diff' do
it 'disables diff notes' do it 'disables diff notes' do
diff_for_path(from: ref_from, to: ref_to, path: existing_path) diff_for_path(from: ref_from, to: ref_to, old_path: existing_path, new_path: existing_path)
expect(assigns(:diff_notes_disabled)).to be_truthy expect(assigns(:diff_notes_disabled)).to be_truthy
end end
...@@ -92,12 +92,12 @@ describe Projects::CompareController do ...@@ -92,12 +92,12 @@ describe Projects::CompareController do
meth.call(diffs, diff_refs, project) meth.call(diffs, diff_refs, project)
end end
diff_for_path(from: ref_from, to: ref_to, path: existing_path) diff_for_path(from: ref_from, to: ref_to, old_path: existing_path, new_path: existing_path)
end end
end end
context 'when the path does not exist in the diff' do context 'when the path does not exist in the diff' do
before { diff_for_path(from: ref_from, to: ref_to, path: existing_path.succ) } before { diff_for_path(from: ref_from, to: ref_to, old_path: existing_path.succ, new_path: existing_path.succ) }
it 'returns a 404' do it 'returns a 404' do
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
...@@ -108,7 +108,7 @@ describe Projects::CompareController do ...@@ -108,7 +108,7 @@ describe Projects::CompareController do
context 'when the user does not have access to the project' do context 'when the user does not have access to the project' do
before do before do
project.team.truncate project.team.truncate
diff_for_path(from: ref_from, to: ref_to, path: existing_path) diff_for_path(from: ref_from, to: ref_to, old_path: existing_path, new_path: existing_path)
end end
it 'returns a 404' do it 'returns a 404' do
...@@ -118,7 +118,7 @@ describe Projects::CompareController do ...@@ -118,7 +118,7 @@ describe Projects::CompareController do
end end
context 'when the from ref does not exist' do context 'when the from ref does not exist' do
before { diff_for_path(from: ref_from.succ, to: ref_to, path: existing_path) } before { diff_for_path(from: ref_from.succ, to: ref_to, old_path: existing_path, new_path: existing_path) }
it 'returns a 404' do it 'returns a 404' do
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
...@@ -126,7 +126,7 @@ describe Projects::CompareController do ...@@ -126,7 +126,7 @@ describe Projects::CompareController do
end end
context 'when the to ref does not exist' do context 'when the to ref does not exist' do
before { diff_for_path(from: ref_from, to: ref_to.succ, path: existing_path) } before { diff_for_path(from: ref_from, to: ref_to.succ, old_path: existing_path, new_path: existing_path) }
it 'returns a 404' do it 'returns a 404' do
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
......
...@@ -384,7 +384,7 @@ describe Projects::MergeRequestsController do ...@@ -384,7 +384,7 @@ describe Projects::MergeRequestsController do
context 'when the user can view the merge request' do context 'when the user can view the merge request' do
context 'when the path exists in the diff' do context 'when the path exists in the diff' do
it 'enables diff notes' do it 'enables diff notes' do
diff_for_path(id: merge_request.iid, path: existing_path) diff_for_path(id: merge_request.iid, old_path: existing_path, new_path: existing_path)
expect(assigns(:diff_notes_disabled)).to be_falsey expect(assigns(:diff_notes_disabled)).to be_falsey
expect(assigns(:comments_target)).to eq(noteable_type: 'MergeRequest', expect(assigns(:comments_target)).to eq(noteable_type: 'MergeRequest',
...@@ -397,12 +397,12 @@ describe Projects::MergeRequestsController do ...@@ -397,12 +397,12 @@ describe Projects::MergeRequestsController do
meth.call(diffs, diff_refs, project) meth.call(diffs, diff_refs, project)
end end
diff_for_path(id: merge_request.iid, path: existing_path) diff_for_path(id: merge_request.iid, old_path: existing_path, new_path: existing_path)
end end
end end
context 'when the path does not exist in the diff' do context 'when the path does not exist in the diff' do
before { diff_for_path(id: merge_request.iid, path: 'files/ruby/nopen.rb') } before { diff_for_path(id: merge_request.iid, old_path: 'files/ruby/nopen.rb', new_path: 'files/ruby/nopen.rb') }
it 'returns a 404' do it 'returns a 404' do
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
...@@ -413,7 +413,7 @@ describe Projects::MergeRequestsController do ...@@ -413,7 +413,7 @@ describe Projects::MergeRequestsController do
context 'when the user cannot view the merge request' do context 'when the user cannot view the merge request' do
before do before do
project.team.truncate project.team.truncate
diff_for_path(id: merge_request.iid, path: existing_path) diff_for_path(id: merge_request.iid, old_path: existing_path, new_path: existing_path)
end end
it 'returns a 404' do it 'returns a 404' do
...@@ -423,7 +423,7 @@ describe Projects::MergeRequestsController do ...@@ -423,7 +423,7 @@ describe Projects::MergeRequestsController do
end end
context 'when the merge request does not exist' do context 'when the merge request does not exist' do
before { diff_for_path(id: merge_request.iid.succ, path: existing_path) } before { diff_for_path(id: merge_request.iid.succ, old_path: existing_path, new_path: existing_path) }
it 'returns a 404' do it 'returns a 404' do
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
...@@ -435,7 +435,7 @@ describe Projects::MergeRequestsController do ...@@ -435,7 +435,7 @@ describe Projects::MergeRequestsController do
before do before do
other_project.team << [user, :master] other_project.team << [user, :master]
diff_for_path(id: merge_request.iid, path: existing_path, project_id: other_project.to_param) diff_for_path(id: merge_request.iid, old_path: existing_path, new_path: existing_path, project_id: other_project.to_param)
end end
it 'returns a 404' do it 'returns a 404' do
...@@ -449,7 +449,7 @@ describe Projects::MergeRequestsController do ...@@ -449,7 +449,7 @@ describe Projects::MergeRequestsController do
context 'when both branches are in the same project' do context 'when both branches are in the same project' do
it 'disables diff notes' do it 'disables diff notes' do
diff_for_path(path: existing_path, merge_request: { source_branch: 'feature', target_branch: 'master' }) diff_for_path(old_path: existing_path, new_path: existing_path, merge_request: { source_branch: 'feature', target_branch: 'master' })
expect(assigns(:diff_notes_disabled)).to be_truthy expect(assigns(:diff_notes_disabled)).to be_truthy
end end
...@@ -460,7 +460,7 @@ describe Projects::MergeRequestsController do ...@@ -460,7 +460,7 @@ describe Projects::MergeRequestsController do
meth.call(diffs, diff_refs, project) meth.call(diffs, diff_refs, project)
end end
diff_for_path(path: existing_path, merge_request: { source_branch: 'feature', target_branch: 'master' }) diff_for_path(old_path: existing_path, new_path: existing_path, merge_request: { source_branch: 'feature', target_branch: 'master' })
end end
end end
...@@ -471,7 +471,7 @@ describe Projects::MergeRequestsController do ...@@ -471,7 +471,7 @@ describe Projects::MergeRequestsController do
context 'when the path exists in the diff' do context 'when the path exists in the diff' do
it 'disables diff notes' do it 'disables diff notes' do
diff_for_path(path: existing_path, merge_request: { source_project: other_project, source_branch: 'feature', target_branch: 'master' }) diff_for_path(old_path: existing_path, new_path: existing_path, merge_request: { source_project: other_project, source_branch: 'feature', target_branch: 'master' })
expect(assigns(:diff_notes_disabled)).to be_truthy expect(assigns(:diff_notes_disabled)).to be_truthy
end end
...@@ -482,12 +482,12 @@ describe Projects::MergeRequestsController do ...@@ -482,12 +482,12 @@ describe Projects::MergeRequestsController do
meth.call(diffs, diff_refs, project) meth.call(diffs, diff_refs, project)
end end
diff_for_path(path: existing_path, merge_request: { source_project: other_project, source_branch: 'feature', target_branch: 'master' }) diff_for_path(old_path: existing_path, new_path: existing_path, merge_request: { source_project: other_project, source_branch: 'feature', target_branch: 'master' })
end end
end end
context 'when the path does not exist in the diff' do context 'when the path does not exist in the diff' do
before { diff_for_path(path: 'files/ruby/nopen.rb', merge_request: { source_project: other_project, source_branch: 'feature', target_branch: 'master' }) } before { diff_for_path(old_path: 'files/ruby/nopen.rb', new_path: 'files/ruby/nopen.rb', merge_request: { source_project: other_project, source_branch: 'feature', target_branch: 'master' }) }
it 'returns a 404' do it 'returns a 404' do
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
...@@ -497,7 +497,7 @@ describe Projects::MergeRequestsController do ...@@ -497,7 +497,7 @@ describe Projects::MergeRequestsController do
end end
end end
describe 'GET #commits' do describe 'GET commits' do
def go(format: 'html') def go(format: 'html')
get :commits, get :commits,
namespace_id: project.namespace.to_param, namespace_id: project.namespace.to_param,
......
...@@ -5,7 +5,7 @@ feature 'Expand and collapse diffs', js: true, feature: true do ...@@ -5,7 +5,7 @@ feature 'Expand and collapse diffs', js: true, feature: true do
before do before do
login_as :admin login_as :admin
merge_request = create(:merge_request, source_branch: 'expand-collapse-diffs', target_branch: 'master') merge_request = create(:merge_request, target_branch: 'expand-collapse-diffs-start', source_branch: 'expand-collapse-diffs')
project = merge_request.source_project project = merge_request.source_project
# Ensure that undiffable.md is in .gitattributes # Ensure that undiffable.md is in .gitattributes
...@@ -21,7 +21,12 @@ feature 'Expand and collapse diffs', js: true, feature: true do ...@@ -21,7 +21,12 @@ feature 'Expand and collapse diffs', js: true, feature: true do
# Use define_method instead of let (which is memoized) so that this just works across a # Use define_method instead of let (which is memoized) so that this just works across a
# reload. # reload.
# #
['small_diff.md', 'large_diff.md', 'undiffable.md', 'too_large.md', 'too_large_image.jpg'].each do |file| files = [
'small_diff.md', 'large_diff.md', 'large_diff_renamed.md', 'undiffable.md',
'too_large.md', 'too_large_image.jpg'
]
files.each do |file|
define_method(file.split('.').first) { file_container(file) } define_method(file.split('.').first) { file_container(file) }
end end
...@@ -31,11 +36,18 @@ feature 'Expand and collapse diffs', js: true, feature: true do ...@@ -31,11 +36,18 @@ feature 'Expand and collapse diffs', js: true, feature: true do
expect(small_diff).not_to have_selector('.nothing-here-block') expect(small_diff).not_to have_selector('.nothing-here-block')
end end
it 'collapses larges diffs by default' do it 'collapses large diffs by default' do
expect(large_diff).not_to have_selector('.code') expect(large_diff).not_to have_selector('.code')
expect(large_diff).to have_selector('.nothing-here-block') expect(large_diff).to have_selector('.nothing-here-block')
end end
it 'collapses large diffs for renamed files by default' do
expect(large_diff_renamed).not_to have_selector('.code')
expect(large_diff_renamed).to have_selector('.nothing-here-block')
expect(large_diff_renamed).to have_selector('.file-title .deletion')
expect(large_diff_renamed).to have_selector('.file-title .addition')
end
it 'shows non-renderable diffs as such immediately, regardless of their size' do it 'shows non-renderable diffs as such immediately, regardless of their size' do
expect(undiffable).not_to have_selector('.code') expect(undiffable).not_to have_selector('.code')
expect(undiffable).to have_selector('.nothing-here-block') expect(undiffable).to have_selector('.nothing-here-block')
...@@ -53,6 +65,25 @@ feature 'Expand and collapse diffs', js: true, feature: true do ...@@ -53,6 +65,25 @@ feature 'Expand and collapse diffs', js: true, feature: true do
expect(too_large_image).to have_selector('.image') expect(too_large_image).to have_selector('.image')
end end
context 'expanding a diff for a renamed file' do
before do
large_diff_renamed.find('.nothing-here-block').click
wait_for_ajax
end
it 'shows the old content' do
old_line = large_diff_renamed.find('.line_content.old')
expect(old_line).to have_content('four copies')
end
it 'shows the new content' do
new_line = large_diff_renamed.find('.line_content.new', match: :prefer_exact)
expect(new_line).to have_content('six copies')
end
end
context 'expanding a large diff' do context 'expanding a large diff' do
before do before do
click_link('large_diff.md') click_link('large_diff.md')
......
...@@ -30,10 +30,10 @@ describe MergeRequestDiff, models: true do ...@@ -30,10 +30,10 @@ describe MergeRequestDiff, models: true do
end end
context 'when the :paths option is set' do context 'when the :paths option is set' do
let(:diffs) { mr_diff.diffs(paths: ['.gitignore', 'files/ruby/popen.rb', 'files/ruby/string.rb']) } let(:diffs) { mr_diff.diffs(paths: ['files/ruby/popen.rb', 'files/ruby/popen.rb']) }
it 'only returns diffs that match the paths given' do it 'only returns diffs that match the (old path, new path) given' do
expect(diffs.map(&:new_path)).to contain_exactly('.gitignore', 'files/ruby/popen.rb') expect(diffs.map(&:new_path)).to contain_exactly('files/ruby/popen.rb')
end end
it 'uses the diffs from the DB' do it 'uses the diffs from the DB' do
......
...@@ -18,6 +18,8 @@ module TestEnv ...@@ -18,6 +18,8 @@ module TestEnv
'orphaned-branch' => '45127a9', 'orphaned-branch' => '45127a9',
'binary-encoding' => '7b1cf43', 'binary-encoding' => '7b1cf43',
'gitattributes' => '5a62481', 'gitattributes' => '5a62481',
'expand-collapse-diffs-start' => '65b04e4',
'expand-collapse-diffs' => '865e6d5'
} }
# gitlab-test-fork is a fork of gitlab-fork, but we don't necessarily # gitlab-test-fork is a fork of gitlab-fork, but we don't necessarily
......
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