summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouwe Maan <douwe@selenight.nl>2017-06-13 17:12:31 -0500
committerDouwe Maan <douwe@selenight.nl>2017-06-28 18:17:44 -0500
commit70b05a83772abc59b3c914c84bc4d2c07749884d (patch)
tree44dfcd05aa111d36e5db08777611856a7c5eb99a
parent92f87f6d8bdd4424334131132394df343c006a63 (diff)
downloadgitlab-ce-dm-merge-request-creations-controller.tar.gz
Split up MergeRequestsControllerdm-merge-request-creations-controller
-rw-r--r--app/assets/javascripts/dispatcher.js14
-rw-r--r--app/assets/javascripts/merge_request_tabs.js13
-rw-r--r--app/controllers/concerns/creates_commit.rb2
-rw-r--r--app/controllers/projects/merge_requests/application_controller.rb48
-rw-r--r--app/controllers/projects/merge_requests/conflicts_controller.rb66
-rw-r--r--app/controllers/projects/merge_requests/creations_controller.rb128
-rw-r--r--app/controllers/projects/merge_requests/diffs_controller.rb66
-rw-r--r--app/controllers/projects/merge_requests_controller.rb457
-rw-r--r--app/helpers/application_helper.rb5
-rw-r--r--app/helpers/blob_helper.rb2
-rw-r--r--app/helpers/compare_helper.rb2
-rw-r--r--app/helpers/merge_requests_helper.rb4
-rw-r--r--app/helpers/nav_helper.rb6
-rw-r--r--app/services/merge_requests/get_urls_service.rb2
-rw-r--r--app/services/projects/unlink_fork_service.rb2
-rw-r--r--app/views/layouts/header/_new_dropdown.haml2
-rw-r--r--app/views/layouts/nav/_project.html.haml4
-rw-r--r--app/views/projects/buttons/_dropdown.html.haml2
-rw-r--r--app/views/projects/commits/_commits.html.haml2
-rw-r--r--app/views/projects/diffs/_diffs.html.haml2
-rw-r--r--app/views/projects/diffs/_warning.html.haml13
-rw-r--r--app/views/projects/merge_requests/_commits.html.haml (renamed from app/views/projects/merge_requests/show/_commits.html.haml)0
-rw-r--r--app/views/projects/merge_requests/_how_to_merge.html.haml (renamed from app/views/projects/merge_requests/show/_how_to_merge.html.haml)0
-rw-r--r--app/views/projects/merge_requests/_mr_box.html.haml (renamed from app/views/projects/merge_requests/show/_mr_box.html.haml)0
-rw-r--r--app/views/projects/merge_requests/_mr_title.html.haml (renamed from app/views/projects/merge_requests/show/_mr_title.html.haml)0
-rw-r--r--app/views/projects/merge_requests/_pipelines.html.haml (renamed from app/views/projects/merge_requests/show/_pipelines.html.haml)0
-rw-r--r--app/views/projects/merge_requests/_show.html.haml97
-rw-r--r--app/views/projects/merge_requests/conflicts.html.haml4
-rw-r--r--app/views/projects/merge_requests/conflicts/show.html.haml38
-rw-r--r--app/views/projects/merge_requests/creations/_diffs.html.haml (renamed from app/views/projects/merge_requests/_new_diffs.html.haml)0
-rw-r--r--app/views/projects/merge_requests/creations/_new_compare.html.haml (renamed from app/views/projects/merge_requests/_new_compare.html.haml)8
-rw-r--r--app/views/projects/merge_requests/creations/_new_submit.html.haml (renamed from app/views/projects/merge_requests/_new_submit.html.haml)11
-rw-r--r--app/views/projects/merge_requests/creations/branch_from.html.haml (renamed from app/views/projects/merge_requests/branch_from.html.haml)0
-rw-r--r--app/views/projects/merge_requests/creations/branch_to.html.haml (renamed from app/views/projects/merge_requests/branch_to.html.haml)0
-rw-r--r--app/views/projects/merge_requests/creations/new.html.haml (renamed from app/views/projects/merge_requests/new.html.haml)0
-rw-r--r--app/views/projects/merge_requests/creations/update_branches.html.haml (renamed from app/views/projects/merge_requests/update_branches.html.haml)0
-rw-r--r--app/views/projects/merge_requests/diffs.html.haml1
-rw-r--r--app/views/projects/merge_requests/diffs/_diffs.html.haml (renamed from app/views/projects/merge_requests/show/_diffs.html.haml)2
-rw-r--r--app/views/projects/merge_requests/diffs/_versions.html.haml (renamed from app/views/projects/merge_requests/show/_versions.html.haml)0
-rw-r--r--app/views/projects/merge_requests/index.html.haml4
-rw-r--r--app/views/projects/merge_requests/invalid.html.haml4
-rw-r--r--app/views/projects/merge_requests/show.html.haml98
-rw-r--r--app/workers/expire_pipeline_cache_worker.rb2
-rw-r--r--config/routes/project.rb56
-rw-r--r--features/steps/dashboard/dashboard.rb2
-rw-r--r--features/steps/project/source/browse_files.rb4
-rw-r--r--spec/controllers/projects/blob_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/conflicts_controller_spec.rb307
-rw-r--r--spec/controllers/projects/merge_requests/creations_controller_spec.rb120
-rw-r--r--spec/controllers/projects/merge_requests/diffs_controller_spec.rb160
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb608
-rw-r--r--spec/features/merge_requests/create_new_mr_spec.rb16
-rw-r--r--spec/features/merge_requests/form_spec.rb4
-rw-r--r--spec/features/merge_requests/user_uses_slash_commands_spec.rb2
-rw-r--r--spec/features/merge_requests/widget_spec.rb2
-rw-r--r--spec/features/merge_requests/wip_message_spec.rb4
-rw-r--r--spec/features/projects/merge_request_button_spec.rb4
-rw-r--r--spec/features/projects/merge_requests/list_spec.rb2
-rw-r--r--spec/features/projects/user_create_dir_spec.rb2
-rw-r--r--spec/features/security/project/internal_access_spec.rb2
-rw-r--r--spec/features/security/project/public_access_spec.rb2
-rw-r--r--spec/javascripts/fixtures/merge_requests.rb19
-rw-r--r--spec/javascripts/fixtures/merge_requests_diffs.rb57
-rw-r--r--spec/javascripts/merge_request_notes_spec.js2
-rw-r--r--spec/javascripts/merge_request_tabs_spec.js16
-rw-r--r--spec/routing/project_routing_spec.rb73
-rw-r--r--spec/support/features/issuable_slash_commands_shared_examples.rb7
-rw-r--r--spec/views/projects/merge_requests/_commits.html.haml_spec.rb2
-rw-r--r--spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb (renamed from spec/views/projects/merge_requests/_new_submit.html.haml_spec.rb)2
69 files changed, 1341 insertions, 1247 deletions
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 31a86090242..4247540de22 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -209,8 +209,8 @@ import initExperimentalFlags from './experimental_flags';
new MilestoneSelect();
new gl.IssuableTemplateSelectors();
break;
- case 'projects:merge_requests:new':
- case 'projects:merge_requests:new_diffs':
+ case 'projects:merge_requests:creations:new':
+ case 'projects:merge_requests:creations:diffs':
case 'projects:merge_requests:edit':
new gl.Diff();
shortcut_handler = new ShortcutsNavigation();
@@ -247,10 +247,6 @@ import initExperimentalFlags from './experimental_flags';
shortcut_handler = new ShortcutsIssuable(true);
new ZenMode();
break;
- case "projects:merge_requests:diffs":
- new gl.Diff();
- new ZenMode();
- break;
case 'dashboard:activity':
new gl.Activities();
break;
@@ -319,7 +315,7 @@ import initExperimentalFlags from './experimental_flags';
new gl.Members();
new UsersSelect();
break;
- case 'projects:members:show':
+ case 'projects:settings:members:show':
new gl.MemberExpirationDate('.js-access-expiration-date-groups');
new GroupsSelect();
new gl.MemberExpirationDate();
@@ -386,7 +382,7 @@ import initExperimentalFlags from './experimental_flags';
case 'search:show':
new Search();
break;
- case 'projects:repository:show':
+ case 'projects:settings:repository:show':
// Initialize Protected Branch Settings
new gl.ProtectedBranchCreate();
new gl.ProtectedBranchEditList();
@@ -396,7 +392,7 @@ import initExperimentalFlags from './experimental_flags';
// Initialize expandable settings panels
initSettingsPanels();
break;
- case 'projects:ci_cd:show':
+ case 'projects:settings:ci_cd:show':
new gl.ProjectVariables();
break;
case 'ci:lints:create':
diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js
index 786b6014dc6..3cf3233cc65 100644
--- a/app/assets/javascripts/merge_request_tabs.js
+++ b/app/assets/javascripts/merge_request_tabs.js
@@ -168,9 +168,8 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion';
// Activate a tab based on the current action
activateTab(action) {
- const activate = action === 'show' ? 'notes' : action;
// important note: the .tab('show') method triggers 'shown.bs.tab' event itself
- $(`.merge-request-tabs a[data-action='${activate}']`).tab('show');
+ $(`.merge-request-tabs a[data-action='${action}']`).tab('show');
}
// Replaces the current Merge Request-specific action in the URL with a new one
@@ -185,7 +184,7 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion';
// location.pathname # => "/namespace/project/merge_requests/1/diffs"
//
// location.pathname # => "/namespace/project/merge_requests/1/diffs"
- // setCurrentAction('notes')
+ // setCurrentAction('show')
// location.pathname # => "/namespace/project/merge_requests/1"
//
// location.pathname # => "/namespace/project/merge_requests/1/diffs"
@@ -194,13 +193,13 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion';
//
// Returns the new URL String
setCurrentAction(action) {
- this.currentAction = action === 'show' ? 'notes' : action;
+ this.currentAction = action;
- // Remove a trailing '/commits' '/diffs' '/pipelines' '/new' '/new/diffs'
- let newState = location.pathname.replace(/\/(commits|diffs|pipelines|new|new\/diffs)(\.html)?\/?$/, '');
+ // Remove a trailing '/commits' '/diffs' '/pipelines'
+ let newState = location.pathname.replace(/\/(commits|diffs|pipelines)(\.html)?\/?$/, '');
// Append the new action if we're on a tab other than 'notes'
- if (this.currentAction !== 'notes') {
+ if (this.currentAction !== 'show' && this.currentAction !== 'new') {
newState += `/${this.currentAction}`;
}
diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb
index 1a9904bbe57..f87db4d9e84 100644
--- a/app/controllers/concerns/creates_commit.rb
+++ b/app/controllers/concerns/creates_commit.rb
@@ -78,7 +78,7 @@ module CreatesCommit
end
def new_merge_request_path
- new_namespace_project_merge_request_path(
+ namespace_project_new_merge_request_path(
@project_to_commit_into.namespace,
@project_to_commit_into,
merge_request: {
diff --git a/app/controllers/projects/merge_requests/application_controller.rb b/app/controllers/projects/merge_requests/application_controller.rb
new file mode 100644
index 00000000000..5de0f828010
--- /dev/null
+++ b/app/controllers/projects/merge_requests/application_controller.rb
@@ -0,0 +1,48 @@
+class Projects::MergeRequests::ApplicationController < Projects::ApplicationController
+ before_action :check_merge_requests_available!
+ before_action :merge_request
+ before_action :authorize_read_merge_request!
+ before_action :ensure_ref_fetched
+
+ private
+
+ def merge_request
+ @issuable = @merge_request ||= @project.merge_requests.find_by!(iid: params[:id])
+ end
+
+ # Make sure merge requests created before 8.0
+ # have head file in refs/merge-requests/
+ def ensure_ref_fetched
+ @merge_request.ensure_ref_fetched
+ end
+
+ def merge_request_params
+ params.require(:merge_request)
+ .permit(merge_request_params_attributes)
+ end
+
+ def merge_request_params_attributes
+ [
+ :assignee_id,
+ :description,
+ :force_remove_source_branch,
+ :lock_version,
+ :milestone_id,
+ :source_branch,
+ :source_project_id,
+ :state_event,
+ :target_branch,
+ :target_project_id,
+ :task_num,
+ :title,
+
+ label_ids: []
+ ]
+ end
+
+ def set_pipeline_variables
+ @pipelines = @merge_request.all_pipelines
+ @pipeline = @merge_request.head_pipeline
+ @statuses_count = @pipeline.present? ? @pipeline.statuses.relevant.count : 0
+ end
+end
diff --git a/app/controllers/projects/merge_requests/conflicts_controller.rb b/app/controllers/projects/merge_requests/conflicts_controller.rb
new file mode 100644
index 00000000000..a71f23e790d
--- /dev/null
+++ b/app/controllers/projects/merge_requests/conflicts_controller.rb
@@ -0,0 +1,66 @@
+class Projects::MergeRequests::ConflictsController < Projects::MergeRequests::ApplicationController
+ include IssuableActions
+
+ before_action :authorize_can_resolve_conflicts!
+
+ def show
+ respond_to do |format|
+ format.html do
+ labels
+ end
+
+ format.json do
+ if @conflicts_list.can_be_resolved_in_ui?
+ render json: @conflicts_list
+ elsif @merge_request.can_be_merged?
+ render json: {
+ message: 'The merge conflicts for this merge request have already been resolved. Please return to the merge request.',
+ type: 'error'
+ }
+ else
+ render json: {
+ message: 'The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally.',
+ type: 'error'
+ }
+ end
+ end
+ end
+ end
+
+ def conflict_for_path
+ return render_404 unless @conflicts_list.can_be_resolved_in_ui?
+
+ file = @conflicts_list.file_for_path(params[:old_path], params[:new_path])
+
+ return render_404 unless file
+
+ render json: file, full_content: true
+ end
+
+ def resolve_conflicts
+ return render_404 unless @conflicts_list.can_be_resolved_in_ui?
+
+ if @merge_request.can_be_merged?
+ render status: :bad_request, json: { message: 'The merge conflicts for this merge request have already been resolved.' }
+ return
+ end
+
+ begin
+ ::MergeRequests::Conflicts::ResolveService
+ .new(merge_request)
+ .execute(current_user, params)
+
+ flash[:notice] = 'All merge conflicts were resolved. The merge request can now be merged.'
+
+ render json: { redirect_to: namespace_project_merge_request_url(@project.namespace, @project, @merge_request, resolved_conflicts: true) }
+ rescue Gitlab::Conflict::ResolutionError => e
+ render status: :bad_request, json: { message: e.message }
+ end
+ end
+
+ def authorize_can_resolve_conflicts!
+ @conflicts_list = ::MergeRequests::Conflicts::ListService.new(@merge_request)
+
+ return render_404 unless @conflicts_list.can_be_resolved_by?(current_user)
+ end
+end
diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb
new file mode 100644
index 00000000000..da058da795e
--- /dev/null
+++ b/app/controllers/projects/merge_requests/creations_controller.rb
@@ -0,0 +1,128 @@
+class Projects::MergeRequests::CreationsController < Projects::MergeRequests::ApplicationController
+ include DiffForPath
+ include DiffHelper
+
+ skip_before_action :merge_request
+ skip_before_action :ensure_ref_fetched
+ before_action :authorize_create_merge_request!
+ before_action :apply_diff_view_cookie!, only: [:diffs, :diff_for_path]
+ before_action :build_merge_request, except: [:create]
+
+ def new
+ define_new_vars
+ end
+
+ def create
+ @target_branches ||= []
+ @merge_request = ::MergeRequests::CreateService.new(project, current_user, merge_request_params).execute
+
+ if @merge_request.valid?
+ redirect_to(merge_request_path(@merge_request))
+ else
+ @source_project = @merge_request.source_project
+ @target_project = @merge_request.target_project
+
+ define_new_vars
+ render action: "new"
+ end
+ end
+
+ def pipelines
+ @pipelines = @merge_request.all_pipelines
+
+ Gitlab::PollingInterval.set_header(response, interval: 10_000)
+
+ render json: {
+ pipelines: PipelineSerializer
+ .new(project: @project, current_user: @current_user)
+ .represent(@pipelines)
+ }
+ end
+
+ def diffs
+ @diffs = if @merge_request.can_be_created
+ @merge_request.diffs(diff_options)
+ else
+ []
+ end
+ @diff_notes_disabled = true
+
+ @environment = @merge_request.environments_for(current_user).last
+
+ render json: { html: view_to_html_string('projects/merge_requests/creations/_diffs', diffs: @diffs, environment: @environment) }
+ end
+
+ def diff_for_path
+ @diffs = @merge_request.diffs(diff_options)
+ @diff_notes_disabled = true
+
+ render_diff_for_path(@diffs)
+ end
+
+ def branch_from
+ # This is always source
+ @source_project = @merge_request.nil? ? @project : @merge_request.source_project
+
+ if params[:ref].present?
+ @ref = params[:ref]
+ @commit = @repository.commit("refs/heads/#{@ref}")
+ end
+
+ render layout: false
+ end
+
+ def branch_to
+ @target_project = selected_target_project
+
+ if params[:ref].present?
+ @ref = params[:ref]
+ @commit = @target_project.commit("refs/heads/#{@ref}")
+ end
+
+ render layout: false
+ end
+
+ def update_branches
+ @target_project = selected_target_project
+ @target_branches = @target_project.repository.branch_names
+
+ render layout: false
+ end
+
+ private
+
+ def build_merge_request
+ params[:merge_request] ||= ActionController::Parameters.new(source_project: @project)
+ @merge_request = ::MergeRequests::BuildService.new(project, current_user, merge_request_params.merge(diff_options: diff_options)).execute
+ end
+
+ def define_new_vars
+ @noteable = @merge_request
+
+ @target_branches = if @merge_request.target_project
+ @merge_request.target_project.repository.branch_names
+ else
+ []
+ end
+
+ @target_project = @merge_request.target_project
+ @source_project = @merge_request.source_project
+ @commits = @merge_request.compare_commits.reverse
+ @commit = @merge_request.diff_head_commit
+
+ @note_counts = Note.where(commit_id: @commits.map(&:id))
+ .group(:commit_id).count
+
+ @labels = LabelsFinder.new(current_user, project_id: @project.id).execute
+
+ set_pipeline_variables
+ end
+
+ def selected_target_project
+ if @project.id.to_s == params[:target_project_id] || @project.forked_project_link.nil?
+ @project
+ else
+ @project.forked_project_link.forked_from_project
+ end
+ end
+end
diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb
new file mode 100644
index 00000000000..330b7df4541
--- /dev/null
+++ b/app/controllers/projects/merge_requests/diffs_controller.rb
@@ -0,0 +1,66 @@
+class Projects::MergeRequests::DiffsController < Projects::MergeRequests::ApplicationController
+ include DiffForPath
+ include DiffHelper
+ include RendersNotes
+
+ before_action :apply_diff_view_cookie!
+ before_action :define_diff_vars
+ before_action :define_diff_comment_vars
+
+ def show
+ @environment = @merge_request.environments_for(current_user).last
+
+ render json: { html: view_to_html_string("projects/merge_requests/diffs/_diffs") }
+ end
+
+ def diff_for_path
+ render_diff_for_path(@diffs)
+ end
+
+ private
+
+ def define_diff_vars
+ @merge_request_diff =
+ if params[:diff_id]
+ @merge_request.merge_request_diffs.viewable.find(params[:diff_id])
+ else
+ @merge_request.merge_request_diff
+ end
+
+ @merge_request_diffs = @merge_request.merge_request_diffs.viewable.select_without_diff
+ @comparable_diffs = @merge_request_diffs.select { |diff| diff.id < @merge_request_diff.id }
+
+ if params[:start_sha].present?
+ @start_sha = params[:start_sha]
+ @start_version = @comparable_diffs.find { |diff| diff.head_commit_sha == @start_sha }
+
+ unless @start_version
+ @start_sha = @merge_request_diff.head_commit_sha
+ @start_version = @merge_request_diff
+ end
+ end
+
+ @compare =
+ if @start_sha
+ @merge_request_diff.compare_with(@start_sha)
+ else
+ @merge_request_diff
+ end
+
+ @diffs = @compare.diffs(diff_options)
+ end
+
+ def define_diff_comment_vars
+ @new_diff_note_attrs = {
+ noteable_type: 'MergeRequest',
+ noteable_id: @merge_request.id
+ }
+
+ @diff_notes_disabled = false
+
+ @use_legacy_diff_notes = !@merge_request.has_complete_diff_refs?
+
+ @grouped_diff_discussions = @merge_request.grouped_diff_discussions(@compare.diff_refs)
+ @notes = prepare_notes_for_rendering(@grouped_diff_discussions.values.flatten.flat_map(&:notes))
+ end
+end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 879ff6d393e..04f8e95aa09 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -1,38 +1,17 @@
-class Projects::MergeRequestsController < Projects::ApplicationController
+class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationController
include ToggleSubscriptionAction
- include DiffForPath
- include DiffHelper
include IssuableActions
include RendersNotes
include ToggleAwardEmoji
include IssuableCollections
- before_action :check_merge_requests_available!
- before_action :merge_request, only: [
- :edit, :update, :show, :diffs, :commits, :conflicts, :conflict_for_path, :pipelines, :merge,
- :pipeline_status, :ci_environments_status, :toggle_subscription, :cancel_merge_when_pipeline_succeeds, :remove_wip, :resolve_conflicts, :assign_related_issues, :commit_change_content
- ]
- before_action :validates_merge_request, only: [:show, :diffs, :commits, :pipelines]
- before_action :define_show_vars, only: [:diffs, :commits, :conflicts, :conflict_for_path, :builds, :pipelines]
- before_action :ensure_ref_fetched, only: [:show, :diffs, :commits, :builds, :conflicts, :conflict_for_path, :pipelines]
- before_action :close_merge_request_without_source_project, only: [:show, :diffs, :commits, :builds, :pipelines]
- before_action :check_if_can_be_merged, only: :show
- before_action :apply_diff_view_cookie!, only: [:new_diffs]
- before_action :build_merge_request, only: [:new, :new_diffs]
-
- # Allow read any merge_request
- before_action :authorize_read_merge_request!
-
- # Allow write(create) merge_request
- before_action :authorize_create_merge_request!, only: [:new, :create]
-
- # Allow modify merge_request
+ skip_before_action :merge_request, only: [:index, :bulk_update]
+ skip_before_action :ensure_ref_fetched, only: [:index, :bulk_update]
+
before_action :authorize_update_merge_request!, only: [:close, :edit, :update, :remove_wip, :sort]
before_action :authenticate_user!, only: [:assign_related_issues]
- before_action :authorize_can_resolve_conflicts!, only: [:conflicts, :conflict_for_path, :resolve_conflicts]
-
def index
@collection_type = "MergeRequest"
@merge_requests = merge_requests_collection
@@ -72,10 +51,30 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
def show
+ validates_merge_request
+ ensure_ref_fetched
+ close_merge_request_without_source_project
+ check_if_can_be_merged
+
respond_to do |format|
format.html do
- define_discussion_vars
- define_show_vars
+ # Build a note object for comment form
+ @note = @project.notes.new(noteable: @merge_request)
+
+ @discussions = @merge_request.discussions
+ @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes))
+
+ @noteable = @merge_request
+ @commits_count = @merge_request.commits_count
+
+ if @merge_request.locked_long_ago?
+ @merge_request.unlock_mr
+ @merge_request.close
+ end
+
+ labels
+
+ set_pipeline_variables
end
format.json do
@@ -98,198 +97,40 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
end
- def diffs
- apply_diff_view_cookie!
-
- respond_to do |format|
- format.html { define_discussion_vars }
- format.json do
- define_diff_vars
- define_diff_comment_vars
-
- @environment = @merge_request.environments_for(current_user).last
-
- render json: { html: view_to_html_string("projects/merge_requests/show/_diffs") }
- end
- end
- end
-
- # With an ID param, loads the MR at that ID. Otherwise, accepts the same params as #new
- # and uses that (unsaved) MR.
- #
- def diff_for_path
- if params[:id]
- merge_request
- define_diff_vars
- define_diff_comment_vars
- else
- build_merge_request
- @compare = @merge_request
- @diffs = @compare.diffs(diff_options)
- @diff_notes_disabled = true
- end
-
- render_diff_for_path(@diffs)
- end
-
def commits
- respond_to do |format|
- format.html do
- define_discussion_vars
-
- render 'show'
- end
- format.json do
- # Get commits from repository
- # or from cache if already merged
- @commits = @merge_request.commits
- @note_counts = Note.where(commit_id: @commits.map(&:id))
- .group(:commit_id).count
-
- render json: { html: view_to_html_string('projects/merge_requests/show/_commits') }
- end
- end
- end
-
- def conflicts
- respond_to do |format|
- format.html { define_discussion_vars }
-
- format.json do
- if @conflicts_list.can_be_resolved_in_ui?
- render json: @conflicts_list
- elsif @merge_request.can_be_merged?
- render json: {
- message: 'The merge conflicts for this merge request have already been resolved. Please return to the merge request.',
- type: 'error'
- }
- else
- render json: {
- message: 'The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally.',
- type: 'error'
- }
- end
- end
- end
- end
-
- def conflict_for_path
- return render_404 unless @conflicts_list.can_be_resolved_in_ui?
-
- file = @conflicts_list.file_for_path(params[:old_path], params[:new_path])
-
- return render_404 unless file
-
- render json: file, full_content: true
- end
-
- def resolve_conflicts
- return render_404 unless @conflicts_list.can_be_resolved_in_ui?
-
- if @merge_request.can_be_merged?
- render status: :bad_request, json: { message: 'The merge conflicts for this merge request have already been resolved.' }
- return
- end
-
- begin
- MergeRequests::Conflicts::ResolveService
- .new(merge_request)
- .execute(current_user, params)
-
- flash[:notice] = 'All merge conflicts were resolved. The merge request can now be merged.'
+ # Get commits from repository
+ # or from cache if already merged
+ @commits = @merge_request.commits
+ @note_counts = Note.where(commit_id: @commits.map(&:id))
+ .group(:commit_id).count
- render json: { redirect_to: namespace_project_merge_request_url(@project.namespace, @project, @merge_request, resolved_conflicts: true) }
- rescue Gitlab::Conflict::ResolutionError => e
- render status: :bad_request, json: { message: e.message }
- end
+ render json: { html: view_to_html_string('projects/merge_requests/_commits') }
end
def pipelines
@pipelines = @merge_request.all_pipelines
- respond_to do |format|
- format.html do
- define_discussion_vars
-
- render 'show'
- end
-
- format.json do
- Gitlab::PollingInterval.set_header(response, interval: 10_000)
+ Gitlab::PollingInterval.set_header(response, interval: 10_000)
- render json: PipelineSerializer
- .new(project: @project, current_user: @current_user)
- .represent(@pipelines)
- end
- end
- end
-
- def new
- respond_to do |format|
- format.html { define_new_vars }
- format.json do
- define_pipelines_vars
-
- Gitlab::PollingInterval.set_header(response, interval: 10_000)
-
- render json: {
- pipelines: PipelineSerializer
- .new(project: @project, current_user: @current_user)
- .represent(@pipelines)
- }
- end
- end
- end
-
- def new_diffs
- respond_to do |format|
- format.html do
- define_new_vars
- @show_changes_tab = true
- render "new"
- end
- format.json do
- @diffs = if @merge_request.can_be_created
- @merge_request.diffs(diff_options)
- else
- []
- end
- @diff_notes_disabled = true
-
- @environment = @merge_request.environments_for(current_user).last
-
- render json: { html: view_to_html_string('projects/merge_requests/_new_diffs', diffs: @diffs, environment: @environment) }
- end
- end
- end
-
- def create
- @target_branches ||= []
- @merge_request = MergeRequests::CreateService.new(project, current_user, merge_request_params).execute
-
- if @merge_request.valid?
- redirect_to(merge_request_path(@merge_request))
- else
- @source_project = @merge_request.source_project
- @target_project = @merge_request.target_project
- render action: "new"
- end
+ render json: PipelineSerializer
+ .new(project: @project, current_user: @current_user)
+ .represent(@pipelines)
end
def edit
- @source_project = @merge_request.source_project
- @target_project = @merge_request.target_project
- @target_branches = @merge_request.target_project.repository.branch_names
+ define_edit_vars
end
def update
- @merge_request = MergeRequests::UpdateService.new(project, current_user, merge_request_params).execute(@merge_request)
+ @merge_request = ::MergeRequests::UpdateService.new(project, current_user, merge_request_params).execute(@merge_request)
respond_to do |format|
format.html do
if @merge_request.valid?
redirect_to([@merge_request.target_project.namespace.becomes(Namespace), @merge_request.target_project, @merge_request])
else
+ define_edit_vars
+
render :edit
end
end
@@ -299,11 +140,13 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
end
rescue ActiveRecord::StaleObjectError
+ define_edit_vars if request.format.html?
+
render_conflict_response
end
def remove_wip
- @merge_request = MergeRequests::UpdateService
+ @merge_request = ::MergeRequests::UpdateService
.new(project, current_user, wip_event: 'unwip')
.execute(@merge_request)
@@ -319,7 +162,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
return access_denied!
end
- MergeRequests::MergeWhenPipelineSucceedsService
+ ::MergeRequests::MergeWhenPipelineSucceedsService
.new(@project, current_user)
.cancel(@merge_request)
@@ -338,53 +181,19 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
end
- def branch_from
- # This is always source
- @source_project = @merge_request.nil? ? @project : @merge_request.source_project
-
- if params[:ref].present?
- @ref = params[:ref]
- @commit = @repository.commit("refs/heads/#{@ref}")
- end
-
- render layout: false
- end
-
- def branch_to
- @target_project = selected_target_project
-
- if params[:ref].present?
- @ref = params[:ref]
- @commit = @target_project.commit("refs/heads/#{@ref}")
- end
-
- render layout: false
- end
-
- def update_branches
- @target_project = selected_target_project
- @target_branches = @target_project.repository.branch_names
-
- render layout: false
- end
-
def assign_related_issues
- result = MergeRequests::AssignIssuesService.new(project, current_user, merge_request: @merge_request).execute
+ result = ::MergeRequests::AssignIssuesService.new(project, current_user, merge_request: @merge_request).execute
- respond_to do |format|
- format.html do
- case result[:count]
- when 0
- flash[:error] = "Failed to assign you issues related to the merge request"
- when 1
- flash[:notice] = "1 issue has been assigned to you"
- else
- flash[:notice] = "#{result[:count]} issues have been assigned to you"
- end
-
- redirect_to(merge_request_path(@merge_request))
- end
+ case result[:count]
+ when 0
+ flash[:error] = "Failed to assign you issues related to the merge request"
+ when 1
+ flash[:notice] = "1 issue has been assigned to you"
+ else
+ flash[:notice] = "#{result[:count]} issues have been assigned to you"
end
+
+ redirect_to(merge_request_path(@merge_request))
end
def pipeline_status
@@ -432,17 +241,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController
protected
- def selected_target_project
- if @project.id.to_s == params[:target_project_id] || @project.forked_project_link.nil?
- @project
- else
- @project.forked_project_link.forked_from_project
- end
- end
-
- def merge_request
- @issuable = @merge_request ||= @project.merge_requests.find_by!(iid: params[:id])
- end
alias_method :subscribable_resource, :merge_request
alias_method :issuable, :merge_request
alias_method :awardable, :merge_request
@@ -455,12 +253,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController
return render_404 unless can?(current_user, :admin_merge_request, @merge_request)
end
- def authorize_can_resolve_conflicts!
- @conflicts_list = MergeRequests::Conflicts::ListService.new(@merge_request)
-
- return render_404 unless @conflicts_list.can_be_resolved_by?(current_user)
- end
-
def validates_merge_request
# Show git not found page
# if there is no saved commits between source & target branch
@@ -470,133 +262,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
end
- def define_show_vars
- @noteable = @merge_request
- @commits_count = @merge_request.commits_count
-
- if @merge_request.locked_long_ago?
- @merge_request.unlock_mr
- @merge_request.close
- end
-
- labels
- define_pipelines_vars
- end
-
- # Discussion tab data is rendered on html responses of actions
- # :show, :diff, :commits, :builds. but not when request the data through AJAX
- def define_discussion_vars
- # Build a note object for comment form
- @note = @project.notes.new(noteable: @merge_request)
-
- @discussions = @merge_request.discussions
- @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes))
- end
-
- def define_diff_vars
- @merge_request_diff =
- if params[:diff_id]
- @merge_request.merge_request_diffs.viewable.find(params[:diff_id])
- else
- @merge_request.merge_request_diff
- end
-
- @merge_request_diffs = @merge_request.merge_request_diffs.viewable.select_without_diff
- @comparable_diffs = @merge_request_diffs.select { |diff| diff.id < @merge_request_diff.id }
-
- if params[:start_sha].present?
- @start_sha = params[:start_sha]
- @start_version = @comparable_diffs.find { |diff| diff.head_commit_sha == @start_sha }
-
- unless @start_version
- @start_sha = @merge_request_diff.head_commit_sha
- @start_version = @merge_request_diff
- end
- end
-
- @compare =
- if @start_sha
- @merge_request_diff.compare_with(@start_sha)
- else
- @merge_request_diff
- end
-
- @diffs = @compare.diffs(diff_options)
- end
-
- def define_diff_comment_vars
- @new_diff_note_attrs = {
- noteable_type: 'MergeRequest',
- noteable_id: @merge_request.id
- }
-
- @diff_notes_disabled = false
-
- @use_legacy_diff_notes = !@merge_request.has_complete_diff_refs?
-
- @grouped_diff_discussions = @merge_request.grouped_diff_discussions(@compare.diff_refs)
- @notes = prepare_notes_for_rendering(@grouped_diff_discussions.values.flatten.flat_map(&:notes))
- end
-
- def define_pipelines_vars
- @pipelines = @merge_request.all_pipelines
- @pipeline = @merge_request.head_pipeline
- @statuses_count = @pipeline.present? ? @pipeline.statuses.relevant.count : 0
- end
-
- def define_new_vars
- @noteable = @merge_request
-
- @target_branches = if @merge_request.target_project
- @merge_request.target_project.repository.branch_names
- else
- []
- end
-
- @target_project = merge_request.target_project
- @source_project = merge_request.source_project
- @commits = @merge_request.compare_commits.reverse
- @commit = @merge_request.diff_head_commit
-
- @note_counts = Note.where(commit_id: @commits.map(&:id))
- .group(:commit_id).count
-
- @labels = LabelsFinder.new(current_user, project_id: @project.id).execute
-
- @show_changes_tab = params[:show_changes].present?
-
- define_pipelines_vars
- end
-
def invalid_mr
# Render special view for MR with removed target branch
render 'invalid'
end
- def merge_request_params
- params.require(:merge_request)
- .permit(merge_request_params_attributes)
- end
-
- def merge_request_params_attributes
- [
- :assignee_id,
- :description,
- :force_remove_source_branch,
- :lock_version,
- :milestone_id,
- :source_branch,
- :source_project_id,
- :state_event,
- :target_branch,
- :target_project_id,
- :task_num,
- :title,
-
- label_ids: []
- ]
- end
-
def merge_params
params.permit(merge_params_attributes)
end
@@ -605,22 +275,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController
[:should_remove_source_branch, :commit_message]
end
- # Make sure merge requests created before 8.0
- # have head file in refs/merge-requests/
- def ensure_ref_fetched
- @merge_request.ensure_ref_fetched
- end
-
def merge_when_pipeline_succeeds_active?
params[:merge_when_pipeline_succeeds].present? &&
@merge_request.head_pipeline && @merge_request.head_pipeline.active?
end
- def build_merge_request
- params[:merge_request] ||= ActionController::Parameters.new(source_project: @project)
- @merge_request = MergeRequests::BuildService.new(project, current_user, merge_request_params.merge(diff_options: diff_options)).execute
- end
-
def close_merge_request_without_source_project
if !@merge_request.source_project && @merge_request.open?
@merge_request.close
@@ -648,7 +307,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
return :failed unless @merge_request.head_pipeline
if @merge_request.head_pipeline.active?
- MergeRequests::MergeWhenPipelineSucceedsService
+ ::MergeRequests::MergeWhenPipelineSucceedsService
.new(@project, current_user, merge_params)
.execute(@merge_request)
@@ -672,4 +331,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController
def serializer
MergeRequestSerializer.new(current_user: current_user, project: merge_request.project)
end
+
+ def define_edit_vars
+ @source_project = @merge_request.source_project
+ @target_project = @merge_request.target_project
+ @target_branches = @merge_request.target_project.repository.branch_names
+ end
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index dc7ff78f3df..7be8e3b96cf 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -131,10 +131,7 @@ module ApplicationHelper
end
def body_data_page
- path = controller.controller_path.split('/')
- namespace = path.first if path.second
-
- [namespace, controller.controller_name, controller.action_name].compact.join(':')
+ [*controller.controller_path.split('/'), controller.action_name].compact.join(':')
end
# shortcut for gitlab config
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index 3efa7c36057..ee36617ba9a 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -284,7 +284,7 @@ module BlobHelper
merge_project = can?(current_user, :create_merge_request, project) ? project : (current_user && current_user.fork_of(project))
if merge_project
- options << link_to("create a merge request", new_namespace_project_merge_request_path(project.namespace, project))
+ options << link_to("create a merge request", namespace_project_new_merge_request_path(project.namespace, project))
end
options
diff --git a/app/helpers/compare_helper.rb b/app/helpers/compare_helper.rb
index 2aa0449c46e..424ded2b69d 100644
--- a/app/helpers/compare_helper.rb
+++ b/app/helpers/compare_helper.rb
@@ -9,7 +9,7 @@ module CompareHelper
end
def create_mr_path(from = params[:from], to = params[:to], project = @project)
- new_namespace_project_merge_request_path(
+ namespace_project_new_merge_request_path(
project.namespace,
project,
merge_request: {
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 39d30631646..54d6f86fa11 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -1,7 +1,7 @@
module MergeRequestsHelper
def new_mr_path_from_push_event(event)
target_project = event.project.default_merge_request_target
- new_namespace_project_merge_request_path(
+ namespace_project_new_merge_request_path(
event.project.namespace,
event.project,
new_mr_from_push_event(event, target_project)
@@ -48,7 +48,7 @@ module MergeRequestsHelper
end
def mr_change_branches_path(merge_request)
- new_namespace_project_merge_request_path(
+ namespace_project_new_merge_request_path(
@project.namespace, @project,
merge_request: {
source_project_id: merge_request.source_project_id,
diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb
index 833d3c36b28..e589ed4e56d 100644
--- a/app/helpers/nav_helper.rb
+++ b/app/helpers/nav_helper.rb
@@ -1,11 +1,7 @@
module NavHelper
def page_gutter_class
if current_path?('merge_requests#show') ||
- current_path?('merge_requests#diffs') ||
- current_path?('merge_requests#commits') ||
- current_path?('merge_requests#builds') ||
- current_path?('merge_requests#conflicts') ||
- current_path?('merge_requests#pipelines') ||
+ current_path?('projects/merge_requests/conflicts#show') ||
current_path?('issues#show') ||
current_path?('milestones#show')
if cookies[:collapsed_gutter] == 'true'
diff --git a/app/services/merge_requests/get_urls_service.rb b/app/services/merge_requests/get_urls_service.rb
index f00a33969a8..5dd40e07c0d 100644
--- a/app/services/merge_requests/get_urls_service.rb
+++ b/app/services/merge_requests/get_urls_service.rb
@@ -49,7 +49,7 @@ module MergeRequests
def url_for_new_merge_request(branch_name)
merge_request_params = { source_branch: branch_name }
- url = Gitlab::Routing.url_helpers.new_namespace_project_merge_request_url(project.namespace, project, merge_request: merge_request_params)
+ url = Gitlab::Routing.url_helpers.namespace_project_new_merge_request_url(project.namespace, project, merge_request: merge_request_params)
{ branch_name: branch_name, url: url, new_merge_request: true }
end
diff --git a/app/services/projects/unlink_fork_service.rb b/app/services/projects/unlink_fork_service.rb
index 315c3e16292..f385e426827 100644
--- a/app/services/projects/unlink_fork_service.rb
+++ b/app/services/projects/unlink_fork_service.rb
@@ -10,7 +10,7 @@ module Projects
merge_requests = @project.forked_from_project.merge_requests.opened.from_project(@project)
merge_requests.each do |mr|
- MergeRequests::CloseService.new(@project, @current_user).execute(mr)
+ ::MergeRequests::CloseService.new(@project, @current_user).execute(mr)
end
@project.forked_project_link.destroy
diff --git a/app/views/layouts/header/_new_dropdown.haml b/app/views/layouts/header/_new_dropdown.haml
index 9ff1164f2ee..4d41579168c 100644
--- a/app/views/layouts/header/_new_dropdown.haml
+++ b/app/views/layouts/header/_new_dropdown.haml
@@ -33,7 +33,7 @@
= link_to 'New issue', new_namespace_project_issue_path(@project.namespace, @project)
- if merge_project
%li
- = link_to 'New merge request', new_namespace_project_merge_request_path(merge_project.namespace, merge_project)
+ = link_to 'New merge request', namespace_project_new_merge_request_path(merge_project.namespace, merge_project)
- if create_project_snippet
%li.header-new-project-snippet
= link_to 'New snippet', new_namespace_project_snippet_path(@project.namespace, @project)
diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml
index 29658da7792..68024d782a6 100644
--- a/app/views/layouts/nav/_project.html.haml
+++ b/app/views/layouts/nav/_project.html.haml
@@ -31,7 +31,9 @@
%span.badge.count.issue_counter= number_with_delimiter(IssuesFinder.new(current_user, project_id: @project.id).execute.opened.count)
- if project_nav_tab? :merge_requests
- = nav_link(controller: @project.default_issues_tracker? ? :merge_requests : [:merge_requests, :labels, :milestones]) do
+ - controllers = [:merge_requests, 'projects/merge_requests/conflicts']
+ - controllers.push(:merge_requests, :labels, :milestones) unless @project.default_issues_tracker?
+ = nav_link(controller: controllers) do
= link_to namespace_project_merge_requests_path(@project.namespace, @project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do
%span
Merge Requests
diff --git a/app/views/projects/buttons/_dropdown.html.haml b/app/views/projects/buttons/_dropdown.html.haml
index 960b57a8008..aa1a533b5cb 100644
--- a/app/views/projects/buttons/_dropdown.html.haml
+++ b/app/views/projects/buttons/_dropdown.html.haml
@@ -16,7 +16,7 @@
- if merge_project
%li
- = link_to new_namespace_project_merge_request_path(merge_project.namespace, merge_project) do
+ = link_to namespace_project_new_merge_request_path(merge_project.namespace, merge_project) do
= icon('tasks fw')
#{ _('New merge request') }
diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml
index 93fd0789c11..cf8dffc8957 100644
--- a/app/views/projects/commits/_commits.html.haml
+++ b/app/views/projects/commits/_commits.html.haml
@@ -8,7 +8,7 @@
%li.commits-row{ data: { day: day } }
%ul.content-list.commit-list
- = render commits, project: project, ref: ref
+ = render partial: 'projects/commits/commit', collection: commits, locals: { project: project, ref: ref }
- if hidden > 0
%li.alert.alert-warning
diff --git a/app/views/projects/diffs/_diffs.html.haml b/app/views/projects/diffs/_diffs.html.haml
index d538c4c86c8..f9385459a66 100644
--- a/app/views/projects/diffs/_diffs.html.haml
+++ b/app/views/projects/diffs/_diffs.html.haml
@@ -10,7 +10,7 @@
- if show_whitespace_toggle
- if current_controller?(:commit)
= commit_diff_whitespace_link(diffs.project, @commit, class: 'hidden-xs')
- - elsif current_controller?(:merge_requests)
+ - elsif current_controller?('projects/merge_requests/diffs')
= diff_merge_request_whitespace_link(diffs.project, @merge_request, class: 'hidden-xs')
- elsif current_controller?(:compare)
= diff_compare_whitespace_link(diffs.project, params[:from], params[:to], class: 'hidden-xs')
diff --git a/app/views/projects/diffs/_warning.html.haml b/app/views/projects/diffs/_warning.html.haml
index 295a1b62535..402c18c447e 100644
--- a/app/views/projects/diffs/_warning.html.haml
+++ b/app/views/projects/diffs/_warning.html.haml
@@ -2,13 +2,12 @@
%h4
Too many changes to show.
.pull-right
- - if current_controller?(:commit) or current_controller?(:merge_requests)
- - if current_controller?(:commit)
- = link_to "Plain diff", namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff), class: "btn btn-sm"
- = link_to "Email patch", namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch), class: "btn btn-sm"
- - elsif @merge_request && @merge_request.persisted?
- = link_to "Plain diff", merge_request_path(@merge_request, format: :diff), class: "btn btn-sm"
- = link_to "Email patch", merge_request_path(@merge_request, format: :patch), class: "btn btn-sm"
+ - if current_controller?(:commit)
+ = link_to "Plain diff", namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff), class: "btn btn-sm"
+ = link_to "Email patch", namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch), class: "btn btn-sm"
+ - elsif current_controller?('projects/merge_requests/diffs') && @merge_request&.persisted?
+ = link_to "Plain diff", merge_request_path(@merge_request, format: :diff), class: "btn btn-sm"
+ = link_to "Email patch", merge_request_path(@merge_request, format: :patch), class: "btn btn-sm"
%p
To preserve performance only
%strong #{diff_files.size} of #{diff_files.real_size}
diff --git a/app/views/projects/merge_requests/show/_commits.html.haml b/app/views/projects/merge_requests/_commits.html.haml
index 11793919ff7..11793919ff7 100644
--- a/app/views/projects/merge_requests/show/_commits.html.haml
+++ b/app/views/projects/merge_requests/_commits.html.haml
diff --git a/app/views/projects/merge_requests/show/_how_to_merge.html.haml b/app/views/projects/merge_requests/_how_to_merge.html.haml
index 766cb272bec..766cb272bec 100644
--- a/app/views/projects/merge_requests/show/_how_to_merge.html.haml
+++ b/app/views/projects/merge_requests/_how_to_merge.html.haml
diff --git a/app/views/projects/merge_requests/show/_mr_box.html.haml b/app/views/projects/merge_requests/_mr_box.html.haml
index 8a390cf8700..8a390cf8700 100644
--- a/app/views/projects/merge_requests/show/_mr_box.html.haml
+++ b/app/views/projects/merge_requests/_mr_box.html.haml
diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/_mr_title.html.haml
index d9428b8562e..d9428b8562e 100644
--- a/app/views/projects/merge_requests/show/_mr_title.html.haml
+++ b/app/views/projects/merge_requests/_mr_title.html.haml
diff --git a/app/views/projects/merge_requests/show/_pipelines.html.haml b/app/views/projects/merge_requests/_pipelines.html.haml
index 2f1dbe87619..2f1dbe87619 100644
--- a/app/views/projects/merge_requests/show/_pipelines.html.haml
+++ b/app/views/projects/merge_requests/_pipelines.html.haml
diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml
deleted file mode 100644
index 75120409bb3..00000000000
--- a/app/views/projects/merge_requests/_show.html.haml
+++ /dev/null
@@ -1,97 +0,0 @@
-- @content_class = "limit-container-width" unless fluid_layout
-- page_title "#{@merge_request.title} (#{@merge_request.to_reference})", "Merge Requests"
-- page_description @merge_request.description
-- page_card_attributes @merge_request.card_attributes
-- content_for :page_specific_javascripts do
- = page_specific_javascript_bundle_tag('common_vue')
- = page_specific_javascript_bundle_tag('diff_notes')
-
-.merge-request{ 'data-url' => merge_request_path(@merge_request, format: :json), 'data-project-path' => project_path(@merge_request.project) }
- = render "projects/merge_requests/show/mr_title"
-
- .merge-request-details.issuable-details{ data: { id: @merge_request.project.id } }
- = render "projects/merge_requests/show/mr_box"
-
- - if @merge_request.source_branch_exists?
- = render "projects/merge_requests/show/how_to_merge"
-
- :javascript
- window.gl.mrWidgetData = #{serialize_issuable(@merge_request)}
-
- #js-vue-mr-widget.mr-widget
-
- - content_for :page_specific_javascripts do
- = webpack_bundle_tag 'common_vue'
- = webpack_bundle_tag 'vue_merge_request_widget'
-
- .content-block.content-block-small.emoji-list-container
- = render 'award_emoji/awards_block', awardable: @merge_request, inline: true
-
- .merge-request-tabs-holder{ class: ("js-tabs-affix" unless ENV['RAILS_ENV'] == 'test') }
- .merge-request-tabs-container
- .scrolling-tabs-container.inner-page-scroll-tabs.is-smaller
- .fade-left= icon('angle-left')
- .fade-right= icon('angle-right')
- .nav-links.scrolling-tabs
- %ul.merge-request-tabs
- %li.notes-tab
- = link_to namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#notes', action: 'notes', toggle: 'tab' } do
- Discussion
- %span.badge= @merge_request.related_notes.user.count
- - if @merge_request.source_project
- %li.commits-tab
- = link_to commits_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#commits', action: 'commits', toggle: 'tab' } do
- Commits
- %span.badge= @commits_count
- - if @pipelines.any?
- %li.pipelines-tab
- = link_to pipelines_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: '#pipelines', action: 'pipelines', toggle: 'tab' } do
- Pipelines
- %span.badge= @pipelines.size
- %li.diffs-tab
- = link_to diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#diffs', action: 'diffs', toggle: 'tab' } do
- Changes
- %span.badge= @merge_request.diff_size
- #resolve-count-app.line-resolve-all-container.prepend-top-10{ "v-cloak" => true }
- %resolve-count{ "inline-template" => true, ":logged-out" => "#{current_user.nil?}" }
- %div
- .line-resolve-all{ "v-show" => "discussionCount > 0",
- ":class" => "{ 'has-next-btn': !loggedOut && resolvedDiscussionCount !== discussionCount }" }
- %span.line-resolve-btn.is-disabled{ type: "button",
- ":class" => "{ 'is-active': resolvedDiscussionCount === discussionCount }" }
- = render "shared/icons/icon_status_success.svg"
- %span.line-resolve-text
- {{ resolvedDiscussionCount }}/{{ discussionCount }} {{ resolvedCountText }} resolved
- = render "discussions/new_issue_for_all_discussions", merge_request: @merge_request
- = render "discussions/jump_to_next"
-
- .tab-content#diff-notes-app
- #notes.notes.tab-pane.voting_notes
- .row
- %section.col-md-12
- .issuable-discussion
- = render "projects/merge_requests/discussion"
-
- #commits.commits.tab-pane
- -# This tab is always loaded via AJAX
- #pipelines.pipelines.tab-pane
- - if @pipelines.any?
- = render 'projects/commit/pipelines_list', disable_initialization: true, endpoint: pipelines_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)
- #diffs.diffs.tab-pane
- -# This tab is always loaded via AJAX
-
- .mr-loading-status
- = spinner
-
-= render 'shared/issuable/sidebar', issuable: @merge_request
-- if @merge_request.can_be_reverted?(current_user)
- = render "projects/commit/change", type: 'revert', commit: @merge_request.merge_commit, title: @merge_request.title
-- if @merge_request.can_be_cherry_picked?
- = render "projects/commit/change", type: 'cherry-pick', commit: @merge_request.merge_commit, title: @merge_request.title
-
-:javascript
- $(function () {
- window.mergeRequest = new MergeRequest({
- action: "#{controller.action_name}"
- });
- });
diff --git a/app/views/projects/merge_requests/conflicts.html.haml b/app/views/projects/merge_requests/conflicts.html.haml
index 51d59280be8..f016b9c13b3 100644
--- a/app/views/projects/merge_requests/conflicts.html.haml
+++ b/app/views/projects/merge_requests/conflicts.html.haml
@@ -3,10 +3,10 @@
= page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('merge_conflicts')
= page_specific_javascript_tag('lib/ace.js')
-= render "projects/merge_requests/show/mr_title"
+= render "projects/merge_requests/mr_title"
.merge-request-details.issuable-details
- = render "projects/merge_requests/show/mr_box"
+ = render "projects/merge_requests/mr_box"
= render 'shared/issuable/sidebar', issuable: @merge_request
diff --git a/app/views/projects/merge_requests/conflicts/show.html.haml b/app/views/projects/merge_requests/conflicts/show.html.haml
new file mode 100644
index 00000000000..f016b9c13b3
--- /dev/null
+++ b/app/views/projects/merge_requests/conflicts/show.html.haml
@@ -0,0 +1,38 @@
+- page_title "Merge Conflicts", "#{@merge_request.title} (#{@merge_request.to_reference}", "Merge Requests"
+- content_for :page_specific_javascripts do
+ = page_specific_javascript_bundle_tag('common_vue')
+ = page_specific_javascript_bundle_tag('merge_conflicts')
+ = page_specific_javascript_tag('lib/ace.js')
+= render "projects/merge_requests/mr_title"
+
+.merge-request-details.issuable-details
+ = render "projects/merge_requests/mr_box"
+
+= render 'shared/issuable/sidebar', issuable: @merge_request
+
+#conflicts{ "v-cloak" => "true", data: { conflicts_path: conflicts_namespace_project_merge_request_path(@merge_request.project.namespace, @merge_request.project, @merge_request, format: :json),
+ resolve_conflicts_path: resolve_conflicts_namespace_project_merge_request_path(@merge_request.project.namespace, @merge_request.project, @merge_request) } }
+ .loading{ "v-if" => "isLoading" }
+ %i.fa.fa-spinner.fa-spin
+
+ .nothing-here-block{ "v-if" => "hasError" }
+ {{conflictsData.errorMessage}}
+
+ = render partial: "projects/merge_requests/conflicts/commit_stats"
+
+ .files-wrapper{ "v-if" => "!isLoading && !hasError" }
+ .files
+ .diff-file.file-holder.conflict{ "v-for" => "file in conflictsData.files" }
+ .js-file-title.file-title
+ %i.fa.fa-fw{ ":class" => "file.iconClass" }
+ %strong {{file.filePath}}
+ = render partial: 'projects/merge_requests/conflicts/file_actions'
+ .diff-content.diff-wrap-lines
+ .diff-wrap-lines.code.file-content.js-syntax-highlight{ "v-show" => "!isParallel && file.resolveMode === 'interactive' && file.type === 'text'" }
+ = render partial: "projects/merge_requests/conflicts/components/inline_conflict_lines"
+ .diff-wrap-lines.code.file-content.js-syntax-highlight{ "v-show" => "isParallel && file.resolveMode === 'interactive' && file.type === 'text'" }
+ %parallel-conflict-lines{ ":file" => "file" }
+ %div{ "v-show" => "file.resolveMode === 'edit' || file.type === 'text-editor'" }
+ = render partial: "projects/merge_requests/conflicts/components/diff_file_editor"
+
+ = render partial: "projects/merge_requests/conflicts/submit_form"
diff --git a/app/views/projects/merge_requests/_new_diffs.html.haml b/app/views/projects/merge_requests/creations/_diffs.html.haml
index 627fc4e9671..627fc4e9671 100644
--- a/app/views/projects/merge_requests/_new_diffs.html.haml
+++ b/app/views/projects/merge_requests/creations/_diffs.html.haml
diff --git a/app/views/projects/merge_requests/_new_compare.html.haml b/app/views/projects/merge_requests/creations/_new_compare.html.haml
index 0f37abb579c..7cda326afef 100644
--- a/app/views/projects/merge_requests/_new_compare.html.haml
+++ b/app/views/projects/merge_requests/creations/_new_compare.html.haml
@@ -1,7 +1,7 @@
%h3.page-title
New Merge Request
-= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], url: new_namespace_project_merge_request_path(@project.namespace, @project), method: :get, html: { class: "merge-request-form form-inline js-requires-input" } do |f|
+= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], url: namespace_project_new_merge_request_path(@project.namespace, @project), method: :get, html: { class: "merge-request-form form-inline js-requires-input" } do |f|
.hide.alert.alert-danger.mr-compare-errors
.merge-request-branches.row
.col-md-6
@@ -69,7 +69,7 @@
:javascript
new Compare({
- targetProjectUrl: "#{update_branches_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}",
- sourceBranchUrl: "#{branch_from_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}",
- targetBranchUrl: "#{branch_to_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}"
+ targetProjectUrl: "#{namespace_project_new_merge_request_update_branches_path(@source_project.namespace, @source_project)}",
+ sourceBranchUrl: "#{namespace_project_new_merge_request_branch_from_path(@source_project.namespace, @source_project)}",
+ targetBranchUrl: "#{namespace_project_new_merge_request_branch_to_path(@source_project.namespace, @source_project)}"
});
diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/creations/_new_submit.html.haml
index e3ecbee5490..c72dd1d8e29 100644
--- a/app/views/projects/merge_requests/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/creations/_new_submit.html.haml
@@ -31,28 +31,27 @@
%span.badge= @commits.size
- if @pipelines.any?
%li.builds-tab
- = link_to url_for(params), data: {target: 'div#pipelines', action: 'pipelines', toggle: 'tab'} do
+ = link_to url_for(params.merge(action: 'pipelines')), data: {target: 'div#pipelines', action: 'pipelines', toggle: 'tab'} do
Pipelines
%span.badge= @pipelines.size
%li.diffs-tab
- = link_to url_for(params.merge(action: 'new_diffs')), data: {target: 'div#diffs', action: 'new/diffs', toggle: 'tab'} do
+ = link_to url_for(params.merge(action: 'diffs')), data: {target: 'div#diffs', action: 'diffs', toggle: 'tab'} do
Changes
%span.badge= @merge_request.diff_size
.tab-content
#commits.commits.tab-pane.active
- = render "projects/merge_requests/show/commits"
+ = render "projects/merge_requests/commits"
#diffs.diffs.tab-pane
-# This tab is always loaded via AJAX
- if @pipelines.any?
#pipelines.pipelines.tab-pane
- = render 'projects/merge_requests/show/pipelines', endpoint: url_for(params.merge(format: :json)), disable_initialization: true
+ = render 'projects/merge_requests/pipelines', endpoint: url_for(params.merge(action: 'pipelines', format: :json)), disable_initialization: true
.mr-loading-status
= spinner
:javascript
var merge_request = new MergeRequest({
- action: "#{(@show_changes_tab ? 'new/diffs' : 'new')}",
- setUrl: false,
+ action: "#{j params[:tab].presence || 'new'}",
});
diff --git a/app/views/projects/merge_requests/branch_from.html.haml b/app/views/projects/merge_requests/creations/branch_from.html.haml
index 3837c4b388d..3837c4b388d 100644
--- a/app/views/projects/merge_requests/branch_from.html.haml
+++ b/app/views/projects/merge_requests/creations/branch_from.html.haml
diff --git a/app/views/projects/merge_requests/branch_to.html.haml b/app/views/projects/merge_requests/creations/branch_to.html.haml
index d69b71790a0..d69b71790a0 100644
--- a/app/views/projects/merge_requests/branch_to.html.haml
+++ b/app/views/projects/merge_requests/creations/branch_to.html.haml
diff --git a/app/views/projects/merge_requests/new.html.haml b/app/views/projects/merge_requests/creations/new.html.haml
index 2e798ce780a..2e798ce780a 100644
--- a/app/views/projects/merge_requests/new.html.haml
+++ b/app/views/projects/merge_requests/creations/new.html.haml
diff --git a/app/views/projects/merge_requests/update_branches.html.haml b/app/views/projects/merge_requests/creations/update_branches.html.haml
index 64482973a89..64482973a89 100644
--- a/app/views/projects/merge_requests/update_branches.html.haml
+++ b/app/views/projects/merge_requests/creations/update_branches.html.haml
diff --git a/app/views/projects/merge_requests/diffs.html.haml b/app/views/projects/merge_requests/diffs.html.haml
deleted file mode 100644
index 2a5b8b1441e..00000000000
--- a/app/views/projects/merge_requests/diffs.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-= render "show"
diff --git a/app/views/projects/merge_requests/show/_diffs.html.haml b/app/views/projects/merge_requests/diffs/_diffs.html.haml
index 7f0913ea516..fb31e2fef00 100644
--- a/app/views/projects/merge_requests/show/_diffs.html.haml
+++ b/app/views/projects/merge_requests/diffs/_diffs.html.haml
@@ -1,5 +1,5 @@
- if @merge_request_diff.collected? || @merge_request_diff.overflow?
- = render 'projects/merge_requests/show/versions'
+ = render 'projects/merge_requests/diffs/versions'
= render "projects/diffs/diffs", diffs: @diffs, environment: @environment
- elsif @merge_request_diff.empty?
.nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch}
diff --git a/app/views/projects/merge_requests/show/_versions.html.haml b/app/views/projects/merge_requests/diffs/_versions.html.haml
index 0999b95c9c9..0999b95c9c9 100644
--- a/app/views/projects/merge_requests/show/_versions.html.haml
+++ b/app/views/projects/merge_requests/diffs/_versions.html.haml
diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml
index 6d75a9f34a3..86996e488a1 100644
--- a/app/views/projects/merge_requests/index.html.haml
+++ b/app/views/projects/merge_requests/index.html.haml
@@ -22,7 +22,7 @@
= button_tag "Edit Merge Requests", class: "btn js-bulk-update-toggle"
- merge_project = can?(current_user, :create_merge_request, @project) ? @project : (current_user && current_user.fork_of(@project))
- if merge_project
- = link_to new_namespace_project_merge_request_path(merge_project.namespace, merge_project), class: "btn btn-new", title: "New merge request" do
+ = link_to namespace_project_new_merge_request_path(merge_project.namespace, merge_project), class: "btn btn-new", title: "New merge request" do
New merge request
= render 'shared/issuable/search_bar', type: :merge_requests
@@ -33,4 +33,4 @@
.merge-requests-holder
= render 'merge_requests'
- else
- = render 'shared/empty_states/merge_requests', button_path: new_namespace_project_merge_request_path(@project.namespace, @project)
+ = render 'shared/empty_states/merge_requests', button_path: namespace_project_new_merge_request_path(@project.namespace, @project)
diff --git a/app/views/projects/merge_requests/invalid.html.haml b/app/views/projects/merge_requests/invalid.html.haml
index a00d3128ffe..6df19d6438b 100644
--- a/app/views/projects/merge_requests/invalid.html.haml
+++ b/app/views/projects/merge_requests/invalid.html.haml
@@ -1,8 +1,8 @@
- page_title "#{@merge_request.title} (#{@merge_request.to_reference}", "Merge Requests"
.merge-request
- = render "projects/merge_requests/show/mr_title"
- = render "projects/merge_requests/show/mr_box"
+ = render "projects/merge_requests/mr_title"
+ = render "projects/merge_requests/mr_box"
.alert.alert-danger
%p
diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml
index 2a5b8b1441e..dbbf1bde088 100644
--- a/app/views/projects/merge_requests/show.html.haml
+++ b/app/views/projects/merge_requests/show.html.haml
@@ -1 +1,97 @@
-= render "show"
+- @content_class = "limit-container-width" unless fluid_layout
+- page_title "#{@merge_request.title} (#{@merge_request.to_reference})", "Merge Requests"
+- page_description @merge_request.description
+- page_card_attributes @merge_request.card_attributes
+- content_for :page_specific_javascripts do
+ = page_specific_javascript_bundle_tag('common_vue')
+ = page_specific_javascript_bundle_tag('diff_notes')
+
+.merge-request{ 'data-url' => merge_request_path(@merge_request, format: :json), 'data-project-path' => project_path(@merge_request.project) }
+ = render "projects/merge_requests/mr_title"
+
+ .merge-request-details.issuable-details{ data: { id: @merge_request.project.id } }
+ = render "projects/merge_requests/mr_box"
+
+ - if @merge_request.source_branch_exists?
+ = render "projects/merge_requests/how_to_merge"
+
+ :javascript
+ window.gl.mrWidgetData = #{serialize_issuable(@merge_request)}
+
+ #js-vue-mr-widget.mr-widget
+
+ - content_for :page_specific_javascripts do
+ = webpack_bundle_tag 'common_vue'
+ = webpack_bundle_tag 'vue_merge_request_widget'
+
+ .content-block.content-block-small.emoji-list-container
+ = render 'award_emoji/awards_block', awardable: @merge_request, inline: true
+
+ .merge-request-tabs-holder{ class: ("js-tabs-affix" unless ENV['RAILS_ENV'] == 'test') }
+ .merge-request-tabs-container
+ .scrolling-tabs-container.inner-page-scroll-tabs.is-smaller
+ .fade-left= icon('angle-left')
+ .fade-right= icon('angle-right')
+ .nav-links.scrolling-tabs
+ %ul.merge-request-tabs
+ %li.notes-tab
+ = link_to namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#notes', action: 'show', toggle: 'tab' } do
+ Discussion
+ %span.badge= @merge_request.related_notes.user.count
+ - if @merge_request.source_project
+ %li.commits-tab
+ = link_to commits_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#commits', action: 'commits', toggle: 'tab' } do
+ Commits
+ %span.badge= @commits_count
+ - if @pipelines.any?
+ %li.pipelines-tab
+ = link_to pipelines_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: '#pipelines', action: 'pipelines', toggle: 'tab' } do
+ Pipelines
+ %span.badge= @pipelines.size
+ %li.diffs-tab
+ = link_to diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#diffs', action: 'diffs', toggle: 'tab' } do
+ Changes
+ %span.badge= @merge_request.diff_size
+ #resolve-count-app.line-resolve-all-container.prepend-top-10{ "v-cloak" => true }
+ %resolve-count{ "inline-template" => true, ":logged-out" => "#{current_user.nil?}" }
+ %div
+ .line-resolve-all{ "v-show" => "discussionCount > 0",
+ ":class" => "{ 'has-next-btn': !loggedOut && resolvedDiscussionCount !== discussionCount }" }
+ %span.line-resolve-btn.is-disabled{ type: "button",
+ ":class" => "{ 'is-active': resolvedDiscussionCount === discussionCount }" }
+ = render "shared/icons/icon_status_success.svg"
+ %span.line-resolve-text
+ {{ resolvedDiscussionCount }}/{{ discussionCount }} {{ resolvedCountText }} resolved
+ = render "discussions/new_issue_for_all_discussions", merge_request: @merge_request
+ = render "discussions/jump_to_next"
+
+ .tab-content#diff-notes-app
+ #notes.notes.tab-pane.voting_notes
+ .row
+ %section.col-md-12
+ .issuable-discussion
+ = render "projects/merge_requests/discussion"
+
+ #commits.commits.tab-pane
+ -# This tab is always loaded via AJAX
+ #pipelines.pipelines.tab-pane
+ - if @pipelines.any?
+ = render 'projects/commit/pipelines_list', disable_initialization: true, endpoint: pipelines_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)
+ #diffs.diffs.tab-pane
+ -# This tab is always loaded via AJAX
+
+ .mr-loading-status
+ = spinner
+
+= render 'shared/issuable/sidebar', issuable: @merge_request
+- if @merge_request.can_be_reverted?(current_user)
+ = render "projects/commit/change", type: 'revert', commit: @merge_request.merge_commit, title: @merge_request.title
+- if @merge_request.can_be_cherry_picked?
+ = render "projects/commit/change", type: 'cherry-pick', commit: @merge_request.merge_commit, title: @merge_request.title
+
+:javascript
+ $(function () {
+ window.mergeRequest = new MergeRequest({
+ action: "#{j params[:tab].presence || 'show'}",
+ });
+ });
diff --git a/app/workers/expire_pipeline_cache_worker.rb b/app/workers/expire_pipeline_cache_worker.rb
index d760f5b140f..92e622285de 100644
--- a/app/workers/expire_pipeline_cache_worker.rb
+++ b/app/workers/expire_pipeline_cache_worker.rb
@@ -46,7 +46,7 @@ class ExpirePipelineCacheWorker
end
def new_merge_request_pipelines_path(project)
- Gitlab::Routing.url_helpers.new_namespace_project_merge_request_path(
+ Gitlab::Routing.url_helpers.namespace_project_new_merge_request_path(
project.namespace,
project,
format: :json)
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 19e18c733b1..0d0a8dff25e 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -87,13 +87,8 @@ constraints(ProjectUrlConstrainer.new) do
resources :forks, only: [:index, :new, :create]
resource :import, only: [:new, :create, :show]
- resources :merge_requests, concerns: :awardable, constraints: { id: /\d+/ } do
+ resources :merge_requests, concerns: :awardable, except: [:new, :create], constraints: { id: /\d+/ } do
member do
- get :commits
- get :diffs
- get :conflicts
- get :conflict_for_path
- get :pipelines
get :commit_change_content
post :merge
post :cancel_merge_when_pipeline_succeeds
@@ -101,18 +96,32 @@ constraints(ProjectUrlConstrainer.new) do
get :ci_environments_status
post :toggle_subscription
post :remove_wip
- get :diff_for_path
- post :resolve_conflicts
post :assign_related_issues
+
+ scope constraints: { format: nil }, action: :show do
+ get :commits, defaults: { tab: 'commits' }
+ get :pipelines, defaults: { tab: 'pipelines' }
+ get :diffs, defaults: { tab: 'diffs' }
+ end
+
+ scope constraints: { format: 'json' }, as: :json do
+ get :commits
+ get :pipelines
+ get :diffs, to: 'merge_requests/diffs#show'
+ end
+
+ get :diff_for_path, controller: 'merge_requests/diffs'
+
+ scope controller: 'merge_requests/conflicts' do
+ get :conflicts, action: :show
+ get :conflict_for_path
+ post :resolve_conflicts
+ end
end
collection do
- get :branch_from
- get :branch_to
- get :update_branches
get :diff_for_path
post :bulk_update
- get :new_diffs, path: 'new/diffs'
end
resources :discussions, only: [], constraints: { id: /\h{40}/ } do
@@ -123,6 +132,29 @@ constraints(ProjectUrlConstrainer.new) do
end
end
+ controller 'merge_requests/creations', path: 'merge_requests' do
+ post '', action: :create, as: nil
+
+ scope path: 'new', as: :new_merge_request do
+ get '', action: :new
+
+ scope constraints: { format: nil }, action: :new do
+ get :diffs, defaults: { tab: 'diffs' }
+ get :pipelines, defaults: { tab: 'pipelines' }
+ end
+
+ scope constraints: { format: 'json' }, as: :json do
+ get :diffs
+ get :pipelines
+ end
+
+ get :diff_for_path
+ get :update_branches
+ get :branch_from
+ get :branch_to
+ end
+ end
+
resources :variables, only: [:index, :show, :update, :create, :destroy]
resources :triggers, only: [:index, :create, :edit, :update, :destroy] do
member do
diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb
index 71c69a4fdea..3c06b188f3e 100644
--- a/features/steps/dashboard/dashboard.rb
+++ b/features/steps/dashboard/dashboard.rb
@@ -27,7 +27,7 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps
step 'I see prefilled new Merge Request page' do
expect(page).to have_selector('.merge-request-form')
- expect(current_path).to eq new_namespace_project_merge_request_path(@project.namespace, @project)
+ expect(current_path).to eq namespace_project_new_merge_request_path(@project.namespace, @project)
expect(find("#merge_request_target_project_id").value).to eq @project.id.to_s
expect(find("input#merge_request_source_branch").value).to eq "fix"
expect(find("input#merge_request_target_branch").value).to eq "master"
diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb
index 9ed4f8ea1f9..02434319a08 100644
--- a/features/steps/project/source/browse_files.rb
+++ b/features/steps/project/source/browse_files.rb
@@ -266,12 +266,12 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
end
step 'I am redirected to the new merge request page' do
- expect(current_path).to eq(new_namespace_project_merge_request_path(@project.namespace, @project))
+ expect(current_path).to eq(namespace_project_new_merge_request_path(@project.namespace, @project))
end
step "I am redirected to the fork's new merge request page" do
fork = @user.fork_of(@project)
- expect(current_path).to eq(new_namespace_project_merge_request_path(fork.namespace, fork))
+ expect(current_path).to eq(namespace_project_new_merge_request_path(fork.namespace, fork))
end
step 'I am redirected to the root directory' do
diff --git a/spec/controllers/projects/blob_controller_spec.rb b/spec/controllers/projects/blob_controller_spec.rb
index c20cf6a4291..561bc219bb4 100644
--- a/spec/controllers/projects/blob_controller_spec.rb
+++ b/spec/controllers/projects/blob_controller_spec.rb
@@ -235,7 +235,7 @@ describe Projects::BlobController do
put :update, default_params
expect(response).to redirect_to(
- new_namespace_project_merge_request_path(
+ namespace_project_new_merge_request_path(
forked_project.namespace,
forked_project,
merge_request: {
diff --git a/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb b/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
new file mode 100644
index 00000000000..9278ac8edd8
--- /dev/null
+++ b/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
@@ -0,0 +1,307 @@
+require 'spec_helper'
+
+describe Projects::MergeRequests::ConflictsController do
+ let(:project) { create(:project) }
+ let(:user) { project.owner }
+ let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
+ let(:merge_request_with_conflicts) do
+ create(:merge_request, source_branch: 'conflict-resolvable', target_branch: 'conflict-start', source_project: project) do |mr|
+ mr.mark_as_unmergeable
+ end
+ end
+
+ before do
+ sign_in(user)
+ end
+
+ describe 'GET show' do
+ context 'when the conflicts cannot be resolved in the UI' do
+ before do
+ allow_any_instance_of(Gitlab::Conflict::Parser)
+ .to receive(:parse).and_raise(Gitlab::Conflict::Parser::UnmergeableFile)
+
+ get :show,
+ namespace_id: merge_request_with_conflicts.project.namespace.to_param,
+ project_id: merge_request_with_conflicts.project,
+ id: merge_request_with_conflicts.iid,
+ format: 'json'
+ end
+
+ it 'returns a 200 status code' do
+ expect(response).to have_http_status(:ok)
+ end
+
+ it 'returns JSON with a message' do
+ expect(json_response.keys).to contain_exactly('message', 'type')
+ end
+ end
+
+ context 'with valid conflicts' do
+ before do
+ get :show,
+ namespace_id: merge_request_with_conflicts.project.namespace.to_param,
+ project_id: merge_request_with_conflicts.project,
+ id: merge_request_with_conflicts.iid,
+ format: 'json'
+ end
+
+ it 'matches the schema' do
+ expect(response).to match_response_schema('conflicts')
+ end
+
+ it 'includes meta info about the MR' do
+ expect(json_response['commit_message']).to include('Merge branch')
+ expect(json_response['commit_sha']).to match(/\h{40}/)
+ expect(json_response['source_branch']).to eq(merge_request_with_conflicts.source_branch)
+ expect(json_response['target_branch']).to eq(merge_request_with_conflicts.target_branch)
+ end
+
+ it 'includes each file that has conflicts' do
+ filenames = json_response['files'].map { |file| file['new_path'] }
+
+ expect(filenames).to contain_exactly('files/ruby/popen.rb', 'files/ruby/regex.rb')
+ end
+
+ it 'splits files into sections with lines' do
+ json_response['files'].each do |file|
+ file['sections'].each do |section|
+ expect(section).to include('conflict', 'lines')
+
+ section['lines'].each do |line|
+ if section['conflict']
+ expect(line['type']).to be_in(%w(old new))
+ expect(line.values_at('old_line', 'new_line')).to contain_exactly(nil, a_kind_of(Integer))
+ else
+ if line['type'].nil?
+ expect(line['old_line']).not_to eq(nil)
+ expect(line['new_line']).not_to eq(nil)
+ else
+ expect(line['type']).to eq('match')
+ expect(line['old_line']).to eq(nil)
+ expect(line['new_line']).to eq(nil)
+ end
+ end
+ end
+ end
+ end
+ end
+
+ it 'has unique section IDs across files' do
+ section_ids = json_response['files'].flat_map do |file|
+ file['sections'].map { |section| section['id'] }.compact
+ end
+
+ expect(section_ids.uniq).to eq(section_ids)
+ end
+ end
+ end
+
+ describe 'GET conflict_for_path' do
+ def conflict_for_path(path)
+ get :conflict_for_path,
+ namespace_id: merge_request_with_conflicts.project.namespace.to_param,
+ project_id: merge_request_with_conflicts.project,
+ id: merge_request_with_conflicts.iid,
+ old_path: path,
+ new_path: path,
+ format: 'json'
+ end
+
+ context 'when the conflicts cannot be resolved in the UI' do
+ before do
+ allow_any_instance_of(Gitlab::Conflict::Parser)
+ .to receive(:parse).and_raise(Gitlab::Conflict::Parser::UnmergeableFile)
+
+ conflict_for_path('files/ruby/regex.rb')
+ end
+
+ it 'returns a 404 status code' do
+ expect(response).to have_http_status(:not_found)
+ end
+ end
+
+ context 'when the file does not exist cannot be resolved in the UI' do
+ before do
+ conflict_for_path('files/ruby/regexp.rb')
+ end
+
+ it 'returns a 404 status code' do
+ expect(response).to have_http_status(:not_found)
+ end
+ end
+
+ context 'with an existing file' do
+ let(:path) { 'files/ruby/regex.rb' }
+
+ before do
+ conflict_for_path(path)
+ end
+
+ it 'returns a 200 status code' do
+ expect(response).to have_http_status(:ok)
+ end
+
+ it 'returns the file in JSON format' do
+ content = MergeRequests::Conflicts::ListService.new(merge_request_with_conflicts)
+ .file_for_path(path, path)
+ .content
+
+ expect(json_response).to include('old_path' => path,
+ 'new_path' => path,
+ 'blob_icon' => 'file-text-o',
+ 'blob_path' => a_string_ending_with(path),
+ 'blob_ace_mode' => 'ruby',
+ 'content' => content)
+ end
+ end
+ end
+
+ context 'POST resolve_conflicts' do
+ let!(:original_head_sha) { merge_request_with_conflicts.diff_head_sha }
+
+ def resolve_conflicts(files)
+ post :resolve_conflicts,
+ namespace_id: merge_request_with_conflicts.project.namespace.to_param,
+ project_id: merge_request_with_conflicts.project,
+ id: merge_request_with_conflicts.iid,
+ format: 'json',
+ files: files,
+ commit_message: 'Commit message'
+ end
+
+ context 'with valid params' do
+ before do
+ resolved_files = [
+ {
+ 'new_path' => 'files/ruby/popen.rb',
+ 'old_path' => 'files/ruby/popen.rb',
+ 'sections' => {
+ '2f6fcd96b88b36ce98c38da085c795a27d92a3dd_14_14' => 'head'
+ }
+ }, {
+ 'new_path' => 'files/ruby/regex.rb',
+ 'old_path' => 'files/ruby/regex.rb',
+ 'sections' => {
+ '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_9_9' => 'head',
+ '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_21_21' => 'origin',
+ '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_49_49' => 'origin'
+ }
+ }
+ ]
+
+ resolve_conflicts(resolved_files)
+ end
+
+ it 'creates a new commit on the branch' do
+ expect(original_head_sha).not_to eq(merge_request_with_conflicts.source_branch_head.sha)
+ expect(merge_request_with_conflicts.source_branch_head.message).to include('Commit message')
+ end
+
+ it 'returns an OK response' do
+ expect(response).to have_http_status(:ok)
+ end
+ end
+
+ context 'when sections are missing' do
+ before do
+ resolved_files = [
+ {
+ 'new_path' => 'files/ruby/popen.rb',
+ 'old_path' => 'files/ruby/popen.rb',
+ 'sections' => {
+ '2f6fcd96b88b36ce98c38da085c795a27d92a3dd_14_14' => 'head'
+ }
+ }, {
+ 'new_path' => 'files/ruby/regex.rb',
+ 'old_path' => 'files/ruby/regex.rb',
+ 'sections' => {
+ '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_9_9' => 'head'
+ }
+ }
+ ]
+
+ resolve_conflicts(resolved_files)
+ end
+
+ it 'returns a 400 error' do
+ expect(response).to have_http_status(:bad_request)
+ end
+
+ it 'has a message with the name of the first missing section' do
+ expect(json_response['message']).to include('6eb14e00385d2fb284765eb1cd8d420d33d63fc9_21_21')
+ end
+
+ it 'does not create a new commit' do
+ expect(original_head_sha).to eq(merge_request_with_conflicts.source_branch_head.sha)
+ end
+ end
+
+ context 'when files are missing' do
+ before do
+ resolved_files = [
+ {
+ 'new_path' => 'files/ruby/regex.rb',
+ 'old_path' => 'files/ruby/regex.rb',
+ 'sections' => {
+ '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_9_9' => 'head',
+ '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_21_21' => 'origin',
+ '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_49_49' => 'origin'
+ }
+ }
+ ]
+
+ resolve_conflicts(resolved_files)
+ end
+
+ it 'returns a 400 error' do
+ expect(response).to have_http_status(:bad_request)
+ end
+
+ it 'has a message with the name of the missing file' do
+ expect(json_response['message']).to include('files/ruby/popen.rb')
+ end
+
+ it 'does not create a new commit' do
+ expect(original_head_sha).to eq(merge_request_with_conflicts.source_branch_head.sha)
+ end
+ end
+
+ context 'when a file has identical content to the conflict' do
+ before do
+ content = MergeRequests::Conflicts::ListService.new(merge_request_with_conflicts)
+ .file_for_path('files/ruby/popen.rb', 'files/ruby/popen.rb')
+ .content
+
+ resolved_files = [
+ {
+ 'new_path' => 'files/ruby/popen.rb',
+ 'old_path' => 'files/ruby/popen.rb',
+ 'content' => content
+ }, {
+ 'new_path' => 'files/ruby/regex.rb',
+ 'old_path' => 'files/ruby/regex.rb',
+ 'sections' => {
+ '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_9_9' => 'head',
+ '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_21_21' => 'origin',
+ '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_49_49' => 'origin'
+ }
+ }
+ ]
+
+ resolve_conflicts(resolved_files)
+ end
+
+ it 'returns a 400 error' do
+ expect(response).to have_http_status(:bad_request)
+ end
+
+ it 'has a message with the path of the problem file' do
+ expect(json_response['message']).to include('files/ruby/popen.rb')
+ end
+
+ it 'does not create a new commit' do
+ expect(original_head_sha).to eq(merge_request_with_conflicts.source_branch_head.sha)
+ end
+ end
+ end
+end
diff --git a/spec/controllers/projects/merge_requests/creations_controller_spec.rb b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
new file mode 100644
index 00000000000..f9d8f0f5fcf
--- /dev/null
+++ b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
@@ -0,0 +1,120 @@
+require 'spec_helper'
+
+describe Projects::MergeRequests::CreationsController do
+ let(:project) { create(:project) }
+ let(:user) { project.owner }
+ let(:fork_project) { create(:forked_project_with_submodules) }
+
+ before do
+ fork_project.team << [user, :master]
+
+ sign_in(user)
+ end
+
+ describe 'GET new' do
+ context 'merge request that removes a submodule' do
+ render_views
+
+ it 'renders new merge request widget template' do
+ get :new,
+ namespace_id: fork_project.namespace.to_param,
+ project_id: fork_project,
+ merge_request: {
+ source_branch: 'remove-submodule',
+ target_branch: 'master'
+ }
+
+ expect(response).to be_success
+ end
+ end
+ end
+
+ describe 'GET pipelines' do
+ before do
+ create(:ci_pipeline, sha: fork_project.commit('remove-submodule').id,
+ ref: 'remove-submodule',
+ project: fork_project)
+ end
+
+ it 'renders JSON including serialized pipelines' do
+ get :pipelines,
+ namespace_id: fork_project.namespace.to_param,
+ project_id: fork_project,
+ merge_request: {
+ source_branch: 'remove-submodule',
+ target_branch: 'master'
+ },
+ format: :json
+
+ expect(response).to be_ok
+ expect(json_response).to have_key 'pipelines'
+ expect(json_response['pipelines']).not_to be_empty
+ end
+ end
+
+ describe 'GET diff_for_path' do
+ def diff_for_path(extra_params = {})
+ params = {
+ namespace_id: project.namespace.to_param,
+ project_id: project,
+ format: 'json'
+ }
+
+ get :diff_for_path, params.merge(extra_params)
+ end
+
+ let(:existing_path) { 'files/ruby/feature.rb' }
+
+ context 'when both branches are in the same project' do
+ it 'disables diff notes' do
+ 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
+ end
+
+ it 'only renders the diffs for the path given' do
+ expect(controller).to receive(:render_diff_for_path).and_wrap_original do |meth, diffs|
+ expect(diffs.diff_files.map(&:new_path)).to contain_exactly(existing_path)
+ meth.call(diffs)
+ end
+
+ diff_for_path(old_path: existing_path, new_path: existing_path, merge_request: { source_branch: 'feature', target_branch: 'master' })
+ end
+ end
+
+ context 'when the source branch is in a different project to the target' do
+ let(:other_project) { create(:project) }
+
+ before do
+ other_project.team << [user, :master]
+ end
+
+ context 'when the path exists in the diff' do
+ it 'disables diff notes' do
+ 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
+ end
+
+ it 'only renders the diffs for the path given' do
+ expect(controller).to receive(:render_diff_for_path).and_wrap_original do |meth, diffs|
+ expect(diffs.diff_files.map(&:new_path)).to contain_exactly(existing_path)
+ meth.call(diffs)
+ end
+
+ 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
+
+ context 'when the path does not exist in the diff' do
+ before do
+ 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' })
+ end
+
+ it 'returns a 404' do
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
new file mode 100644
index 00000000000..53fe2bdb189
--- /dev/null
+++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
@@ -0,0 +1,160 @@
+require 'spec_helper'
+
+describe Projects::MergeRequests::DiffsController do
+ let(:project) { create(:project) }
+ let(:user) { project.owner }
+ let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
+
+ before do
+ sign_in(user)
+ end
+
+ describe 'GET show' do
+ def go(extra_params = {})
+ params = {
+ namespace_id: project.namespace.to_param,
+ project_id: project,
+ id: merge_request.iid,
+ format: 'json'
+ }
+
+ get :show, params.merge(extra_params)
+ end
+
+ context 'with default params' do
+ context 'for the same project' do
+ before do
+ go
+ end
+
+ it 'renders the diffs template to a string' do
+ expect(response).to render_template('projects/merge_requests/diffs/_diffs')
+ expect(json_response).to have_key('html')
+ end
+ end
+
+ context 'with forked projects with submodules' do
+ render_views
+
+ let(:project) { create(:project) }
+ let(:fork_project) { create(:forked_project_with_submodules) }
+ let(:merge_request) { create(:merge_request_with_diffs, source_project: fork_project, source_branch: 'add-submodule-version-bump', target_branch: 'master', target_project: project) }
+
+ before do
+ fork_project.build_forked_project_link(forked_to_project_id: fork_project.id, forked_from_project_id: project.id)
+ fork_project.save
+ merge_request.reload
+ go
+ end
+
+ it 'renders' do
+ expect(response).to be_success
+ expect(response.body).to have_content('Subproject commit')
+ end
+ end
+ end
+
+ context 'with ignore_whitespace_change' do
+ before do
+ go(w: 1)
+ end
+
+ it 'renders the diffs template to a string' do
+ expect(response).to render_template('projects/merge_requests/diffs/_diffs')
+ expect(json_response).to have_key('html')
+ end
+ end
+
+ context 'with view' do
+ before do
+ go(view: 'parallel')
+ end
+
+ it 'saves the preferred diff view in a cookie' do
+ expect(response.cookies['diff_view']).to eq('parallel')
+ end
+ end
+ end
+
+ describe 'GET diff_for_path' do
+ def diff_for_path(extra_params = {})
+ params = {
+ namespace_id: project.namespace.to_param,
+ project_id: project,
+ id: merge_request.iid,
+ format: 'json'
+ }
+
+ get :diff_for_path, params.merge(extra_params)
+ end
+
+ let(:existing_path) { 'files/ruby/popen.rb' }
+
+ context 'when the merge request exists' do
+ context 'when the user can view the merge request' do
+ context 'when the path exists in the diff' do
+ it 'enables diff notes' do
+ diff_for_path(old_path: existing_path, new_path: existing_path)
+
+ expect(assigns(:diff_notes_disabled)).to be_falsey
+ expect(assigns(:new_diff_note_attrs)).to eq(noteable_type: 'MergeRequest',
+ noteable_id: merge_request.id)
+ end
+
+ it 'only renders the diffs for the path given' do
+ expect(controller).to receive(:render_diff_for_path).and_wrap_original do |meth, diffs|
+ expect(diffs.diff_files.map(&:new_path)).to contain_exactly(existing_path)
+ meth.call(diffs)
+ end
+
+ diff_for_path(old_path: existing_path, new_path: existing_path)
+ end
+ end
+
+ context 'when the path does not exist in the diff' do
+ before do
+ diff_for_path(old_path: 'files/ruby/nopen.rb', new_path: 'files/ruby/nopen.rb')
+ end
+
+ it 'returns a 404' do
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+
+ context 'when the user cannot view the merge request' do
+ before do
+ project.team.truncate
+ diff_for_path(old_path: existing_path, new_path: existing_path)
+ end
+
+ it 'returns a 404' do
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+
+ context 'when the merge request does not exist' do
+ before do
+ diff_for_path(id: merge_request.iid.succ, old_path: existing_path, new_path: existing_path)
+ end
+
+ it 'returns a 404' do
+ expect(response).to have_http_status(404)
+ end
+ end
+
+ context 'when the merge request belongs to a different project' do
+ let(:other_project) { create(:empty_project) }
+
+ before do
+ other_project.team << [user, :master]
+ diff_for_path(old_path: existing_path, new_path: existing_path, project_id: other_project)
+ end
+
+ it 'returns a 404' do
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+end
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 6817c2652fd..6f9ce60cf75 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -14,53 +14,6 @@ describe Projects::MergeRequestsController do
sign_in(user)
end
- describe 'GET new' do
- context 'merge request that removes a submodule' do
- render_views
-
- let(:fork_project) { create(:forked_project_with_submodules) }
-
- before do
- fork_project.team << [user, :master]
- end
-
- context 'when rendering HTML response' do
- it 'renders new merge request widget template' do
- submit_new_merge_request
-
- expect(response).to be_success
- end
- end
-
- context 'when rendering JSON response' do
- before do
- create(:ci_pipeline, sha: fork_project.commit('remove-submodule').id,
- ref: 'remove-submodule',
- project: fork_project)
- end
-
- it 'renders JSON including serialized pipelines' do
- submit_new_merge_request(format: :json)
-
- expect(response).to be_ok
- expect(json_response).to have_key 'pipelines'
- expect(json_response['pipelines']).not_to be_empty
- end
- end
- end
-
- def submit_new_merge_request(format: :html)
- get :new,
- namespace_id: fork_project.namespace.to_param,
- project_id: fork_project,
- merge_request: {
- source_branch: 'remove-submodule',
- target_branch: 'master'
- },
- format: format
- end
- end
-
describe 'GET commit_change_content' do
it 'renders commit_change_content template' do
get :commit_change_content,
@@ -497,234 +450,6 @@ describe Projects::MergeRequestsController do
end
end
- describe 'GET diffs' do
- def go(extra_params = {})
- params = {
- namespace_id: project.namespace.to_param,
- project_id: project,
- id: merge_request.iid
- }
-
- get :diffs, params.merge(extra_params)
- end
-
- it_behaves_like "loads labels", :diffs
-
- context 'with default params' do
- context 'as html' do
- before do
- go(format: 'html')
- end
-
- it 'renders the diff template' do
- expect(response).to render_template('diffs')
- end
- end
-
- context 'as json' do
- before do
- go(format: 'json')
- end
-
- it 'renders the diffs template to a string' do
- expect(response).to render_template('projects/merge_requests/show/_diffs')
- expect(json_response).to have_key('html')
- end
- end
-
- context 'with forked projects with submodules' do
- render_views
-
- let(:project) { create(:project) }
- let(:fork_project) { create(:forked_project_with_submodules) }
- let(:merge_request) { create(:merge_request_with_diffs, source_project: fork_project, source_branch: 'add-submodule-version-bump', target_branch: 'master', target_project: project) }
-
- before do
- fork_project.build_forked_project_link(forked_to_project_id: fork_project.id, forked_from_project_id: project.id)
- fork_project.save
- merge_request.reload
- go(format: 'json')
- end
-
- it 'renders' do
- expect(response).to be_success
- expect(response.body).to have_content('Subproject commit')
- end
- end
- end
-
- context 'with ignore_whitespace_change' do
- context 'as html' do
- before do
- go(format: 'html', w: 1)
- end
-
- it 'renders the diff template' do
- expect(response).to render_template('diffs')
- end
- end
-
- context 'as json' do
- before do
- go(format: 'json', w: 1)
- end
-
- it 'renders the diffs template to a string' do
- expect(response).to render_template('projects/merge_requests/show/_diffs')
- expect(json_response).to have_key('html')
- end
- end
- end
-
- context 'with view' do
- before do
- go(view: 'parallel')
- end
-
- it 'saves the preferred diff view in a cookie' do
- expect(response.cookies['diff_view']).to eq('parallel')
- end
- end
- end
-
- describe 'GET diff_for_path' do
- def diff_for_path(extra_params = {})
- params = {
- namespace_id: project.namespace.to_param,
- project_id: project
- }
-
- get :diff_for_path, params.merge(extra_params)
- end
-
- context 'when an ID param is passed' do
- let(:existing_path) { 'files/ruby/popen.rb' }
-
- context 'when the merge request exists' do
- context 'when the user can view the merge request' do
- context 'when the path exists in the diff' do
- it 'enables diff notes' do
- 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(:new_diff_note_attrs)).to eq(noteable_type: 'MergeRequest',
- noteable_id: merge_request.id)
- end
-
- it 'only renders the diffs for the path given' do
- expect(controller).to receive(:render_diff_for_path).and_wrap_original do |meth, diffs|
- expect(diffs.diff_files.map(&:new_path)).to contain_exactly(existing_path)
- meth.call(diffs)
- end
-
- diff_for_path(id: merge_request.iid, old_path: existing_path, new_path: existing_path)
- end
- end
-
- context 'when the path does not exist in the diff' do
- before do
- diff_for_path(id: merge_request.iid, old_path: 'files/ruby/nopen.rb', new_path: 'files/ruby/nopen.rb')
- end
-
- it 'returns a 404' do
- expect(response).to have_http_status(404)
- end
- end
- end
-
- context 'when the user cannot view the merge request' do
- before do
- project.team.truncate
- diff_for_path(id: merge_request.iid, old_path: existing_path, new_path: existing_path)
- end
-
- it 'returns a 404' do
- expect(response).to have_http_status(404)
- end
- end
- end
-
- context 'when the merge request does not exist' do
- before do
- diff_for_path(id: merge_request.iid.succ, old_path: existing_path, new_path: existing_path)
- end
-
- it 'returns a 404' do
- expect(response).to have_http_status(404)
- end
- end
-
- context 'when the merge request belongs to a different project' do
- let(:other_project) { create(:empty_project) }
-
- before do
- other_project.team << [user, :master]
- diff_for_path(id: merge_request.iid, old_path: existing_path, new_path: existing_path, project_id: other_project)
- end
-
- it 'returns a 404' do
- expect(response).to have_http_status(404)
- end
- end
- end
-
- context 'when source and target params are passed' do
- let(:existing_path) { 'files/ruby/feature.rb' }
-
- context 'when both branches are in the same project' do
- it 'disables diff notes' do
- 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
- end
-
- it 'only renders the diffs for the path given' do
- expect(controller).to receive(:render_diff_for_path).and_wrap_original do |meth, diffs|
- expect(diffs.diff_files.map(&:new_path)).to contain_exactly(existing_path)
- meth.call(diffs)
- end
-
- diff_for_path(old_path: existing_path, new_path: existing_path, merge_request: { source_branch: 'feature', target_branch: 'master' })
- end
- end
-
- context 'when the source branch is in a different project to the target' do
- let(:other_project) { create(:project) }
-
- before do
- other_project.team << [user, :master]
- end
-
- context 'when the path exists in the diff' do
- it 'disables diff notes' do
- 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
- end
-
- it 'only renders the diffs for the path given' do
- expect(controller).to receive(:render_diff_for_path).and_wrap_original do |meth, diffs|
- expect(diffs.diff_files.map(&:new_path)).to contain_exactly(existing_path)
- meth.call(diffs)
- end
-
- 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
-
- context 'when the path does not exist in the diff' do
- before do
- 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' })
- end
-
- it 'returns a 404' do
- expect(response).to have_http_status(404)
- end
- end
- end
- end
- end
-
describe 'GET commits' do
def go(format: 'html')
get :commits,
@@ -734,23 +459,11 @@ describe Projects::MergeRequestsController do
format: format
end
- it_behaves_like "loads labels", :commits
+ it 'renders the commits template to a string' do
+ go format: 'json'
- context 'as html' do
- it 'renders the show template' do
- go
-
- expect(response).to render_template('show')
- end
- end
-
- context 'as json' do
- it 'renders the commits template to a string' do
- go format: 'json'
-
- expect(response).to render_template('projects/merge_requests/show/_commits')
- expect(json_response).to have_key('html')
- end
+ expect(response).to render_template('projects/merge_requests/_commits')
+ expect(json_response).to have_key('html')
end
end
@@ -759,106 +472,16 @@ describe Projects::MergeRequestsController do
create(:ci_pipeline, project: merge_request.source_project,
ref: merge_request.source_branch,
sha: merge_request.diff_head_sha)
- end
-
- context 'when using HTML format' do
- it_behaves_like "loads labels", :pipelines
- end
- context 'when using JSON format' do
- before do
- get :pipelines,
- namespace_id: project.namespace.to_param,
- project_id: project,
- id: merge_request.iid,
- format: :json
- end
-
- it 'responds with serialized pipelines' do
- expect(json_response).not_to be_empty
- end
- end
- end
-
- describe 'GET conflicts' do
- context 'when the conflicts cannot be resolved in the UI' do
- before do
- allow_any_instance_of(Gitlab::Conflict::Parser)
- .to receive(:parse).and_raise(Gitlab::Conflict::Parser::UnmergeableFile)
-
- get :conflicts,
- namespace_id: merge_request_with_conflicts.project.namespace.to_param,
- project_id: merge_request_with_conflicts.project,
- id: merge_request_with_conflicts.iid,
- format: 'json'
- end
-
- it 'returns a 200 status code' do
- expect(response).to have_http_status(:ok)
- end
-
- it 'returns JSON with a message' do
- expect(json_response.keys).to contain_exactly('message', 'type')
- end
+ get :pipelines,
+ namespace_id: project.namespace.to_param,
+ project_id: project,
+ id: merge_request.iid,
+ format: :json
end
- context 'with valid conflicts' do
- before do
- get :conflicts,
- namespace_id: merge_request_with_conflicts.project.namespace.to_param,
- project_id: merge_request_with_conflicts.project,
- id: merge_request_with_conflicts.iid,
- format: 'json'
- end
-
- it 'matches the schema' do
- expect(response).to match_response_schema('conflicts')
- end
-
- it 'includes meta info about the MR' do
- expect(json_response['commit_message']).to include('Merge branch')
- expect(json_response['commit_sha']).to match(/\h{40}/)
- expect(json_response['source_branch']).to eq(merge_request_with_conflicts.source_branch)
- expect(json_response['target_branch']).to eq(merge_request_with_conflicts.target_branch)
- end
-
- it 'includes each file that has conflicts' do
- filenames = json_response['files'].map { |file| file['new_path'] }
-
- expect(filenames).to contain_exactly('files/ruby/popen.rb', 'files/ruby/regex.rb')
- end
-
- it 'splits files into sections with lines' do
- json_response['files'].each do |file|
- file['sections'].each do |section|
- expect(section).to include('conflict', 'lines')
-
- section['lines'].each do |line|
- if section['conflict']
- expect(line['type']).to be_in(%w(old new))
- expect(line.values_at('old_line', 'new_line')).to contain_exactly(nil, a_kind_of(Integer))
- else
- if line['type'].nil?
- expect(line['old_line']).not_to eq(nil)
- expect(line['new_line']).not_to eq(nil)
- else
- expect(line['type']).to eq('match')
- expect(line['old_line']).to eq(nil)
- expect(line['new_line']).to eq(nil)
- end
- end
- end
- end
- end
- end
-
- it 'has unique section IDs across files' do
- section_ids = json_response['files'].flat_map do |file|
- file['sections'].map { |section| section['id'] }.compact
- end
-
- expect(section_ids.uniq).to eq(section_ids)
- end
+ it 'responds with serialized pipelines' do
+ expect(json_response).not_to be_empty
end
end
@@ -913,215 +536,6 @@ describe Projects::MergeRequestsController do
end
end
- describe 'GET conflict_for_path' do
- def conflict_for_path(path)
- get :conflict_for_path,
- namespace_id: merge_request_with_conflicts.project.namespace.to_param,
- project_id: merge_request_with_conflicts.project,
- id: merge_request_with_conflicts.iid,
- old_path: path,
- new_path: path,
- format: 'json'
- end
-
- context 'when the conflicts cannot be resolved in the UI' do
- before do
- allow_any_instance_of(Gitlab::Conflict::Parser)
- .to receive(:parse).and_raise(Gitlab::Conflict::Parser::UnmergeableFile)
-
- conflict_for_path('files/ruby/regex.rb')
- end
-
- it 'returns a 404 status code' do
- expect(response).to have_http_status(:not_found)
- end
- end
-
- context 'when the file does not exist cannot be resolved in the UI' do
- before do
- conflict_for_path('files/ruby/regexp.rb')
- end
-
- it 'returns a 404 status code' do
- expect(response).to have_http_status(:not_found)
- end
- end
-
- context 'with an existing file' do
- let(:path) { 'files/ruby/regex.rb' }
-
- before do
- conflict_for_path(path)
- end
-
- it 'returns a 200 status code' do
- expect(response).to have_http_status(:ok)
- end
-
- it 'returns the file in JSON format' do
- content = MergeRequests::Conflicts::ListService.new(merge_request_with_conflicts)
- .file_for_path(path, path)
- .content
-
- expect(json_response).to include('old_path' => path,
- 'new_path' => path,
- 'blob_icon' => 'file-text-o',
- 'blob_path' => a_string_ending_with(path),
- 'blob_ace_mode' => 'ruby',
- 'content' => content)
- end
- end
- end
-
- context 'POST resolve_conflicts' do
- let!(:original_head_sha) { merge_request_with_conflicts.diff_head_sha }
-
- def resolve_conflicts(files)
- post :resolve_conflicts,
- namespace_id: merge_request_with_conflicts.project.namespace.to_param,
- project_id: merge_request_with_conflicts.project,
- id: merge_request_with_conflicts.iid,
- format: 'json',
- files: files,
- commit_message: 'Commit message'
- end
-
- context 'with valid params' do
- before do
- resolved_files = [
- {
- 'new_path' => 'files/ruby/popen.rb',
- 'old_path' => 'files/ruby/popen.rb',
- 'sections' => {
- '2f6fcd96b88b36ce98c38da085c795a27d92a3dd_14_14' => 'head'
- }
- }, {
- 'new_path' => 'files/ruby/regex.rb',
- 'old_path' => 'files/ruby/regex.rb',
- 'sections' => {
- '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_9_9' => 'head',
- '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_21_21' => 'origin',
- '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_49_49' => 'origin'
- }
- }
- ]
-
- resolve_conflicts(resolved_files)
- end
-
- it 'creates a new commit on the branch' do
- expect(original_head_sha).not_to eq(merge_request_with_conflicts.source_branch_head.sha)
- expect(merge_request_with_conflicts.source_branch_head.message).to include('Commit message')
- end
-
- it 'returns an OK response' do
- expect(response).to have_http_status(:ok)
- end
- end
-
- context 'when sections are missing' do
- before do
- resolved_files = [
- {
- 'new_path' => 'files/ruby/popen.rb',
- 'old_path' => 'files/ruby/popen.rb',
- 'sections' => {
- '2f6fcd96b88b36ce98c38da085c795a27d92a3dd_14_14' => 'head'
- }
- }, {
- 'new_path' => 'files/ruby/regex.rb',
- 'old_path' => 'files/ruby/regex.rb',
- 'sections' => {
- '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_9_9' => 'head'
- }
- }
- ]
-
- resolve_conflicts(resolved_files)
- end
-
- it 'returns a 400 error' do
- expect(response).to have_http_status(:bad_request)
- end
-
- it 'has a message with the name of the first missing section' do
- expect(json_response['message']).to include('6eb14e00385d2fb284765eb1cd8d420d33d63fc9_21_21')
- end
-
- it 'does not create a new commit' do
- expect(original_head_sha).to eq(merge_request_with_conflicts.source_branch_head.sha)
- end
- end
-
- context 'when files are missing' do
- before do
- resolved_files = [
- {
- 'new_path' => 'files/ruby/regex.rb',
- 'old_path' => 'files/ruby/regex.rb',
- 'sections' => {
- '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_9_9' => 'head',
- '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_21_21' => 'origin',
- '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_49_49' => 'origin'
- }
- }
- ]
-
- resolve_conflicts(resolved_files)
- end
-
- it 'returns a 400 error' do
- expect(response).to have_http_status(:bad_request)
- end
-
- it 'has a message with the name of the missing file' do
- expect(json_response['message']).to include('files/ruby/popen.rb')
- end
-
- it 'does not create a new commit' do
- expect(original_head_sha).to eq(merge_request_with_conflicts.source_branch_head.sha)
- end
- end
-
- context 'when a file has identical content to the conflict' do
- before do
- content = MergeRequests::Conflicts::ListService.new(merge_request_with_conflicts)
- .file_for_path('files/ruby/popen.rb', 'files/ruby/popen.rb')
- .content
-
- resolved_files = [
- {
- 'new_path' => 'files/ruby/popen.rb',
- 'old_path' => 'files/ruby/popen.rb',
- 'content' => content
- }, {
- 'new_path' => 'files/ruby/regex.rb',
- 'old_path' => 'files/ruby/regex.rb',
- 'sections' => {
- '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_9_9' => 'head',
- '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_21_21' => 'origin',
- '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_49_49' => 'origin'
- }
- }
- ]
-
- resolve_conflicts(resolved_files)
- end
-
- it 'returns a 400 error' do
- expect(response).to have_http_status(:bad_request)
- end
-
- it 'has a message with the path of the problem file' do
- expect(json_response['message']).to include('files/ruby/popen.rb')
- end
-
- it 'does not create a new commit' do
- expect(original_head_sha).to eq(merge_request_with_conflicts.source_branch_head.sha)
- end
- end
- end
-
describe 'POST assign_related_issues' do
let(:issue1) { create(:issue, project: project) }
let(:issue2) { create(:issue, project: project) }
diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb
index 8f7adbccaaa..6a08e50bf5e 100644
--- a/spec/features/merge_requests/create_new_mr_spec.rb
+++ b/spec/features/merge_requests/create_new_mr_spec.rb
@@ -65,7 +65,7 @@ feature 'Create New Merge Request', feature: true, js: true do
it 'does not leak the private project name & namespace' do
private_project = create(:project, :private)
- visit new_namespace_project_merge_request_path(project.namespace, project, merge_request: { target_project_id: private_project.id })
+ visit namespace_project_new_merge_request_path(project.namespace, project, merge_request: { target_project_id: private_project.id })
expect(page).not_to have_content private_project.path_with_namespace
expect(page).to have_content project.path_with_namespace
@@ -76,7 +76,7 @@ feature 'Create New Merge Request', feature: true, js: true do
it 'does not leak the private project name & namespace' do
private_project = create(:project, :private)
- visit new_namespace_project_merge_request_path(project.namespace, project, merge_request: { source_project_id: private_project.id })
+ visit namespace_project_new_merge_request_path(project.namespace, project, merge_request: { source_project_id: private_project.id })
expect(page).not_to have_content private_project.path_with_namespace
expect(page).to have_content project.path_with_namespace
@@ -84,13 +84,13 @@ feature 'Create New Merge Request', feature: true, js: true do
end
it 'populates source branch button' do
- visit new_namespace_project_merge_request_path(project.namespace, project, change_branches: true, merge_request: { target_branch: 'master', source_branch: 'fix' })
+ visit namespace_project_new_merge_request_path(project.namespace, project, change_branches: true, merge_request: { target_branch: 'master', source_branch: 'fix' })
expect(find('.js-source-branch')).to have_content('fix')
end
it 'allows to change the diff view' do
- visit new_namespace_project_merge_request_path(project.namespace, project, merge_request: { target_branch: 'master', source_branch: 'fix' })
+ visit namespace_project_new_merge_request_path(project.namespace, project, merge_request: { target_branch: 'master', source_branch: 'fix' })
click_link 'Changes'
@@ -106,7 +106,7 @@ feature 'Create New Merge Request', feature: true, js: true do
end
it 'does not allow non-existing branches' do
- visit new_namespace_project_merge_request_path(project.namespace, project, merge_request: { target_branch: 'non-exist-target', source_branch: 'non-exist-source' })
+ visit namespace_project_new_merge_request_path(project.namespace, project, merge_request: { target_branch: 'non-exist-target', source_branch: 'non-exist-source' })
expect(page).to have_content('The form contains the following errors')
expect(page).to have_content('Source branch "non-exist-source" does not exist')
@@ -115,7 +115,7 @@ feature 'Create New Merge Request', feature: true, js: true do
context 'when a branch contains commits that both delete and add the same image' do
it 'renders the diff successfully' do
- visit new_namespace_project_merge_request_path(project.namespace, project, merge_request: { target_branch: 'master', source_branch: 'deleted-image-test' })
+ visit namespace_project_new_merge_request_path(project.namespace, project, merge_request: { target_branch: 'master', source_branch: 'deleted-image-test' })
click_link "Changes"
@@ -125,7 +125,7 @@ feature 'Create New Merge Request', feature: true, js: true do
# Isolates a regression (see #24627)
it 'does not show error messages on initial form' do
- visit new_namespace_project_merge_request_path(project.namespace, project)
+ visit namespace_project_new_merge_request_path(project.namespace, project)
expect(page).not_to have_selector('#error_explanation')
expect(page).not_to have_content('The form contains the following error')
end
@@ -138,7 +138,7 @@ feature 'Create New Merge Request', feature: true, js: true do
end
it 'shows pipelines for a new merge request' do
- visit new_namespace_project_merge_request_path(
+ visit namespace_project_new_merge_request_path(
project.namespace, project,
merge_request: { target_branch: 'master', source_branch: 'fix' })
diff --git a/spec/features/merge_requests/form_spec.rb b/spec/features/merge_requests/form_spec.rb
index 1996c2fa09a..d03d498ce21 100644
--- a/spec/features/merge_requests/form_spec.rb
+++ b/spec/features/merge_requests/form_spec.rb
@@ -23,7 +23,7 @@ describe 'New/edit merge request', feature: true, js: true do
context 'new merge request' do
before do
- visit new_namespace_project_merge_request_path(
+ visit namespace_project_new_merge_request_path(
project.namespace,
project,
merge_request: {
@@ -182,7 +182,7 @@ describe 'New/edit merge request', feature: true, js: true do
context 'new merge request' do
before do
- visit new_namespace_project_merge_request_path(
+ visit namespace_project_new_merge_request_path(
fork_project.namespace,
fork_project,
merge_request: {
diff --git a/spec/features/merge_requests/user_uses_slash_commands_spec.rb b/spec/features/merge_requests/user_uses_slash_commands_spec.rb
index 71aa71e380e..a1f123f15ec 100644
--- a/spec/features/merge_requests/user_uses_slash_commands_spec.rb
+++ b/spec/features/merge_requests/user_uses_slash_commands_spec.rb
@@ -131,7 +131,7 @@ feature 'Merge Requests > User uses quick actions', feature: true, js: true do
end
it 'changes target_branch in new merge_request' do
- visit new_namespace_project_merge_request_path(another_project.namespace, another_project, new_url_opts)
+ visit namespace_project_new_merge_request_path(another_project.namespace, another_project, new_url_opts)
fill_in "merge_request_title", with: 'My brand new feature'
fill_in "merge_request_description", with: "le feature \n/target_branch fix\nFeature description:"
diff --git a/spec/features/merge_requests/widget_spec.rb b/spec/features/merge_requests/widget_spec.rb
index 3ac1f603de6..d8e9b949204 100644
--- a/spec/features/merge_requests/widget_spec.rb
+++ b/spec/features/merge_requests/widget_spec.rb
@@ -12,7 +12,7 @@ describe 'Merge request', :feature, :js do
context 'new merge request' do
before do
- visit new_namespace_project_merge_request_path(
+ visit namespace_project_new_merge_request_path(
project.namespace,
project,
merge_request: {
diff --git a/spec/features/merge_requests/wip_message_spec.rb b/spec/features/merge_requests/wip_message_spec.rb
index 72d001bf408..0e304ba50af 100644
--- a/spec/features/merge_requests/wip_message_spec.rb
+++ b/spec/features/merge_requests/wip_message_spec.rb
@@ -11,7 +11,7 @@ feature 'Work In Progress help message', feature: true do
context 'with WIP commits' do
it 'shows a specific WIP hint' do
- visit new_namespace_project_merge_request_path(
+ visit namespace_project_new_merge_request_path(
project.namespace,
project,
merge_request: {
@@ -32,7 +32,7 @@ feature 'Work In Progress help message', feature: true do
context 'without WIP commits' do
it 'shows the regular WIP message' do
- visit new_namespace_project_merge_request_path(
+ visit namespace_project_new_merge_request_path(
project.namespace,
project,
merge_request: {
diff --git a/spec/features/projects/merge_request_button_spec.rb b/spec/features/projects/merge_request_button_spec.rb
index 6de8855016d..58054bbbbed 100644
--- a/spec/features/projects/merge_request_button_spec.rb
+++ b/spec/features/projects/merge_request_button_spec.rb
@@ -23,7 +23,7 @@ feature 'Merge Request button', feature: true do
end
it 'shows Create merge request button' do
- href = new_namespace_project_merge_request_path(project.namespace,
+ href = namespace_project_new_merge_request_path(project.namespace,
project,
merge_request: { source_branch: 'feature',
target_branch: 'master' })
@@ -67,7 +67,7 @@ feature 'Merge Request button', feature: true do
let(:user) { forked_project.owner }
it 'shows Create merge request button' do
- href = new_namespace_project_merge_request_path(forked_project.namespace,
+ href = namespace_project_new_merge_request_path(forked_project.namespace,
forked_project,
merge_request: { source_branch: 'feature',
target_branch: 'master' })
diff --git a/spec/features/projects/merge_requests/list_spec.rb b/spec/features/projects/merge_requests/list_spec.rb
index f2a2fd0311f..7ce3156215a 100644
--- a/spec/features/projects/merge_requests/list_spec.rb
+++ b/spec/features/projects/merge_requests/list_spec.rb
@@ -27,7 +27,7 @@ feature 'Merge Requests List' do
it 'empty state should have a create merge request button' do
visit namespace_project_merge_requests_path(project.namespace, project)
- expect(page).to have_link 'New merge request', href: new_namespace_project_merge_request_path(project.namespace, project)
+ expect(page).to have_link 'New merge request', href: namespace_project_new_merge_request_path(project.namespace, project)
end
context 'if there are merge requests' do
diff --git a/spec/features/projects/user_create_dir_spec.rb b/spec/features/projects/user_create_dir_spec.rb
index f375e1215db..5d0acad3832 100644
--- a/spec/features/projects/user_create_dir_spec.rb
+++ b/spec/features/projects/user_create_dir_spec.rb
@@ -51,7 +51,7 @@ feature 'New directory creation', feature: true, js: true do
expect(page).to have_content 'New Merge Request'
expect(page).to have_content "From #{new_branch_name} into master"
expect(page).to have_content 'Add new directory'
- expect(current_path).to eq(new_namespace_project_merge_request_path(project.namespace, project))
+ expect(current_path).to eq(namespace_project_new_merge_request_path(project.namespace, project))
end
end
end
diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb
index f33406a40a7..5e26b8bbed6 100644
--- a/spec/features/security/project/internal_access_spec.rb
+++ b/spec/features/security/project/internal_access_spec.rb
@@ -239,7 +239,7 @@ describe "Internal Project Access", feature: true do
end
describe "GET /:project_path/merge_requests/new" do
- subject { new_namespace_project_merge_request_path(project.namespace, project) }
+ subject { namespace_project_new_merge_request_path(project.namespace, project) }
it { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb
index 16a1331b2f3..59655b0c31a 100644
--- a/spec/features/security/project/public_access_spec.rb
+++ b/spec/features/security/project/public_access_spec.rb
@@ -452,7 +452,7 @@ describe "Public Project Access", feature: true do
end
describe "GET /:project_path/merge_requests/new" do
- subject { new_namespace_project_merge_request_path(project.namespace, project) }
+ subject { namespace_project_new_merge_request_path(project.namespace, project) }
it { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
diff --git a/spec/javascripts/fixtures/merge_requests.rb b/spec/javascripts/fixtures/merge_requests.rb
index daaddd8f390..7e2f364ffa4 100644
--- a/spec/javascripts/fixtures/merge_requests.rb
+++ b/spec/javascripts/fixtures/merge_requests.rb
@@ -55,27 +55,14 @@ describe Projects::MergeRequestsController, '(JavaScript fixtures)', type: :cont
render_merge_request(example.description, merge_request)
end
- it 'merge_requests/inline_changes_tab_with_comments.json' do |example|
- create(:diff_note_on_merge_request, project: project, author: admin, position: position, noteable: merge_request)
- create(:note_on_merge_request, author: admin, project: project, noteable: merge_request)
- render_merge_request(example.description, merge_request, action: :diffs, format: :json)
- end
-
- it 'merge_requests/parallel_changes_tab_with_comments.json' do |example|
- create(:diff_note_on_merge_request, project: project, author: admin, position: position, noteable: merge_request)
- create(:note_on_merge_request, author: admin, project: project, noteable: merge_request)
- render_merge_request(example.description, merge_request, action: :diffs, format: :json, view: 'parallel')
- end
-
private
- def render_merge_request(fixture_file_name, merge_request, action: :show, format: :html, view: 'inline')
- get action,
+ def render_merge_request(fixture_file_name, merge_request)
+ get :show,
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.to_param,
- format: format,
- view: view
+ format: :html
expect(response).to be_success
store_frontend_fixture(response, fixture_file_name)
diff --git a/spec/javascripts/fixtures/merge_requests_diffs.rb b/spec/javascripts/fixtures/merge_requests_diffs.rb
new file mode 100644
index 00000000000..ac5b06ace6d
--- /dev/null
+++ b/spec/javascripts/fixtures/merge_requests_diffs.rb
@@ -0,0 +1,57 @@
+
+require 'spec_helper'
+
+describe Projects::MergeRequests::DiffsController, '(JavaScript fixtures)', type: :controller do
+ include JavaScriptFixturesHelpers
+
+ let(:admin) { create(:admin) }
+ let(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
+ let(:project) { create(:project, namespace: namespace, path: 'merge-requests-project') }
+ let(:merge_request) { create(:merge_request, :with_diffs, source_project: project, target_project: project, description: '- [ ] Task List Item') }
+ let(:path) { "files/ruby/popen.rb" }
+ let(:position) do
+ Gitlab::Diff::Position.new(
+ old_path: path,
+ new_path: path,
+ old_line: nil,
+ new_line: 14,
+ diff_refs: merge_request.diff_refs
+ )
+ end
+
+ render_views
+
+ before(:all) do
+ clean_frontend_fixtures('merge_request_diffs/')
+ end
+
+ before(:each) do
+ sign_in(admin)
+ end
+
+ it 'merge_request_diffs/inline_changes_tab_with_comments.json' do |example|
+ create(:diff_note_on_merge_request, project: project, author: admin, position: position, noteable: merge_request)
+ create(:note_on_merge_request, author: admin, project: project, noteable: merge_request)
+ render_merge_request(example.description, merge_request)
+ end
+
+ it 'merge_request_diffs/parallel_changes_tab_with_comments.json' do |example|
+ create(:diff_note_on_merge_request, project: project, author: admin, position: position, noteable: merge_request)
+ create(:note_on_merge_request, author: admin, project: project, noteable: merge_request)
+ render_merge_request(example.description, merge_request, view: 'parallel')
+ end
+
+ private
+
+ def render_merge_request(fixture_file_name, merge_request, view: 'inline')
+ get :show,
+ namespace_id: project.namespace.to_param,
+ project_id: project,
+ id: merge_request.to_param,
+ format: :json,
+ view: view
+
+ expect(response).to be_success
+ store_frontend_fixture(response, fixture_file_name)
+ end
+end
diff --git a/spec/javascripts/merge_request_notes_spec.js b/spec/javascripts/merge_request_notes_spec.js
index 9e9eb17d439..395dc560671 100644
--- a/spec/javascripts/merge_request_notes_spec.js
+++ b/spec/javascripts/merge_request_notes_spec.js
@@ -15,7 +15,7 @@ describe('Merge request notes', () => {
gl.utils = gl.utils || {};
const discussionTabFixture = 'merge_requests/diff_comment.html.raw';
- const changesTabJsonFixture = 'merge_requests/inline_changes_tab_with_comments.json';
+ const changesTabJsonFixture = 'merge_request_diffs/inline_changes_tab_with_comments.json';
preloadFixtures(discussionTabFixture, changesTabJsonFixture);
describe('Discussion tab with diff comments', () => {
diff --git a/spec/javascripts/merge_request_tabs_spec.js b/spec/javascripts/merge_request_tabs_spec.js
index bb6b5d852d3..49ef21f75de 100644
--- a/spec/javascripts/merge_request_tabs_spec.js
+++ b/spec/javascripts/merge_request_tabs_spec.js
@@ -23,8 +23,8 @@ import 'vendor/jquery.scrollTo';
$.extend(stubLocation, defaults, stubs || {});
};
- const inlineChangesTabJsonFixture = 'merge_requests/inline_changes_tab_with_comments.json';
- const parallelChangesTabJsonFixture = 'merge_requests/parallel_changes_tab_with_comments.json';
+ const inlineChangesTabJsonFixture = 'merge_request_diffs/inline_changes_tab_with_comments.json';
+ const parallelChangesTabJsonFixture = 'merge_request_diffs/parallel_changes_tab_with_comments.json';
preloadFixtures(
'merge_requests/merge_request_with_task_list.html.raw',
'merge_requests/diff_comment.html.raw',
@@ -52,14 +52,10 @@ import 'vendor/jquery.scrollTo';
loadFixtures('merge_requests/merge_request_with_task_list.html.raw');
this.subject = this.class.activateTab;
});
- it('shows the first tab when action is show', function () {
+ it('shows the notes tab when action is show', function () {
this.subject('show');
expect($('#notes')).toHaveClass('active');
});
- it('shows the notes tab when action is notes', function () {
- this.subject('notes');
- expect($('#notes')).toHaveClass('active');
- });
it('shows the commits tab when action is commits', function () {
this.subject('commits');
expect($('#commits')).toHaveClass('active');
@@ -161,7 +157,7 @@ import 'vendor/jquery.scrollTo';
setLocation({
pathname: '/foo/bar/merge_requests/1/commits'
});
- expect(this.subject('notes')).toBe('/foo/bar/merge_requests/1');
+ expect(this.subject('show')).toBe('/foo/bar/merge_requests/1');
expect(this.subject('diffs')).toBe('/foo/bar/merge_requests/1/diffs');
});
@@ -170,7 +166,7 @@ import 'vendor/jquery.scrollTo';
pathname: '/foo/bar/merge_requests/1/diffs'
});
- expect(this.subject('notes')).toBe('/foo/bar/merge_requests/1');
+ expect(this.subject('show')).toBe('/foo/bar/merge_requests/1');
expect(this.subject('commits')).toBe('/foo/bar/merge_requests/1/commits');
});
@@ -178,7 +174,7 @@ import 'vendor/jquery.scrollTo';
setLocation({
pathname: '/foo/bar/merge_requests/1/diffs.html'
});
- expect(this.subject('notes')).toBe('/foo/bar/merge_requests/1');
+ expect(this.subject('show')).toBe('/foo/bar/merge_requests/1');
expect(this.subject('commits')).toBe('/foo/bar/merge_requests/1/commits');
});
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index 95d40138fea..2f1c3c95e59 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -246,28 +246,13 @@ describe 'project routing' do
end
end
- # diffs_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/diffs(.:format) projects/merge_requests#diffs
- # commits_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/commits(.:format) projects/merge_requests#commits
- # merge_namespace_project_merge_request POST /:namespace_id/:project_id/merge_requests/:id/merge(.:format) projects/merge_requests#merge
- # ci_status_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/ci_status(.:format) projects/merge_requests#ci_status
- # toggle_subscription_namespace_project_merge_request POST /:namespace_id/:project_id/merge_requests/:id/toggle_subscription(.:format) projects/merge_requests#toggle_subscription
- # branch_from_namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests/branch_from(.:format) projects/merge_requests#branch_from
- # branch_to_namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests/branch_to(.:format) projects/merge_requests#branch_to
- # update_branches_namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests/update_branches(.:format) projects/merge_requests#update_branches
- # namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests(.:format) projects/merge_requests#index
- # POST /:namespace_id/:project_id/merge_requests(.:format) projects/merge_requests#create
- # new_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/new(.:format) projects/merge_requests#new
- # edit_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/edit(.:format) projects/merge_requests#edit
- # namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id(.:format) projects/merge_requests#show
- # PATCH /:namespace_id/:project_id/merge_requests/:id(.:format) projects/merge_requests#update
- # PUT /:namespace_id/:project_id/merge_requests/:id(.:format) projects/merge_requests#update
describe Projects::MergeRequestsController, 'routing' do
- it 'to #diffs' do
- expect(get('/gitlab/gitlabhq/merge_requests/1/diffs')).to route_to('projects/merge_requests#diffs', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
+ it 'to #commits' do
+ expect(get('/gitlab/gitlabhq/merge_requests/1/commits.json')).to route_to('projects/merge_requests#commits', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', format: 'json')
end
- it 'to #commits' do
- expect(get('/gitlab/gitlabhq/merge_requests/1/commits')).to route_to('projects/merge_requests#commits', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
+ it 'to #pipelines' do
+ expect(get('/gitlab/gitlabhq/merge_requests/1/pipelines.json')).to route_to('projects/merge_requests#pipelines', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', format: 'json')
end
it 'to #merge' do
@@ -277,25 +262,59 @@ describe 'project routing' do
)
end
+ it 'to #show' do
+ expect(get('/gitlab/gitlabhq/merge_requests/1.diff')).to route_to('projects/merge_requests#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', format: 'diff')
+ expect(get('/gitlab/gitlabhq/merge_requests/1.patch')).to route_to('projects/merge_requests#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', format: 'patch')
+ expect(get('/gitlab/gitlabhq/merge_requests/1/diffs')).to route_to('projects/merge_requests#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', tab: 'diffs')
+ expect(get('/gitlab/gitlabhq/merge_requests/1/commits')).to route_to('projects/merge_requests#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', tab: 'commits')
+ expect(get('/gitlab/gitlabhq/merge_requests/1/pipelines')).to route_to('projects/merge_requests#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', tab: 'pipelines')
+ end
+
+ it_behaves_like 'RESTful project resources' do
+ let(:controller) { 'merge_requests' }
+ let(:actions) { [:index, :edit, :show, :update] }
+ end
+ end
+
+ describe Projects::MergeRequests::CreationsController, 'routing' do
+ it 'to #new' do
+ expect(get('/gitlab/gitlabhq/merge_requests/new')).to route_to('projects/merge_requests/creations#new', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ expect(get('/gitlab/gitlabhq/merge_requests/new/diffs')).to route_to('projects/merge_requests/creations#new', namespace_id: 'gitlab', project_id: 'gitlabhq', tab: 'diffs')
+ expect(get('/gitlab/gitlabhq/merge_requests/new/pipelines')).to route_to('projects/merge_requests/creations#new', namespace_id: 'gitlab', project_id: 'gitlabhq', tab: 'pipelines')
+ end
+
+ it 'to #create' do
+ expect(post('/gitlab/gitlabhq/merge_requests')).to route_to('projects/merge_requests/creations#create', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ end
+
it 'to #branch_from' do
- expect(get('/gitlab/gitlabhq/merge_requests/branch_from')).to route_to('projects/merge_requests#branch_from', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ expect(get('/gitlab/gitlabhq/merge_requests/new/branch_from')).to route_to('projects/merge_requests/creations#branch_from', namespace_id: 'gitlab', project_id: 'gitlabhq')
end
it 'to #branch_to' do
- expect(get('/gitlab/gitlabhq/merge_requests/branch_to')).to route_to('projects/merge_requests#branch_to', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ expect(get('/gitlab/gitlabhq/merge_requests/new/branch_to')).to route_to('projects/merge_requests/creations#branch_to', namespace_id: 'gitlab', project_id: 'gitlabhq')
end
- it 'to #show' do
- expect(get('/gitlab/gitlabhq/merge_requests/1.diff')).to route_to('projects/merge_requests#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', format: 'diff')
- expect(get('/gitlab/gitlabhq/merge_requests/1.patch')).to route_to('projects/merge_requests#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', format: 'patch')
+ it 'to #pipelines' do
+ expect(get('/gitlab/gitlabhq/merge_requests/new/pipelines.json')).to route_to('projects/merge_requests/creations#pipelines', namespace_id: 'gitlab', project_id: 'gitlabhq', format: 'json')
end
- it_behaves_like 'RESTful project resources' do
- let(:controller) { 'merge_requests' }
- let(:actions) { [:index, :create, :new, :edit, :show, :update] }
+ it 'to #diffs' do
+ expect(get('/gitlab/gitlabhq/merge_requests/new/diffs.json')).to route_to('projects/merge_requests/creations#diffs', namespace_id: 'gitlab', project_id: 'gitlabhq', format: 'json')
+ end
+ end
+
+ describe Projects::MergeRequests::DiffsController, 'routing' do
+ it 'to #show' do
+ expect(get('/gitlab/gitlabhq/merge_requests/1/diffs.json')).to route_to('projects/merge_requests/diffs#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', format: 'json')
end
end
+ describe Projects::MergeRequests::ConflictsController, 'routing' do
+ it 'to #show' do
+ expect(get('/gitlab/gitlabhq/merge_requests/1/conflicts')).to route_to('projects/merge_requests/conflicts#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
+ end
+ end
# raw_project_snippet GET /:project_id/snippets/:id/raw(.:format) snippets#raw
# project_snippets GET /:project_id/snippets(.:format) snippets#index
# POST /:project_id/snippets(.:format) snippets#create
diff --git a/spec/support/features/issuable_slash_commands_shared_examples.rb b/spec/support/features/issuable_slash_commands_shared_examples.rb
index 50869099bb7..98b014df6cd 100644
--- a/spec/support/features/issuable_slash_commands_shared_examples.rb
+++ b/spec/support/features/issuable_slash_commands_shared_examples.rb
@@ -28,7 +28,12 @@ shared_examples 'issuable record that supports quick actions in its description
describe "new #{issuable_type}", js: true do
context 'with commands in the description' do
it "creates the #{issuable_type} and interpret commands accordingly" do
- visit public_send("new_namespace_project_#{issuable_type}_path", project.namespace, project, new_url_opts)
+ case issuable_type
+ when :merge_request
+ visit public_send("namespace_project_new_merge_request_path", project.namespace, project, new_url_opts)
+ when :issue
+ visit public_send("new_namespace_project_issue_path", project.namespace, project, new_url_opts)
+ end
fill_in "#{issuable_type}_title", with: 'bug 345'
fill_in "#{issuable_type}_description", with: "bug description\n/label ~bug\n/milestone %\"ASAP\""
click_button "Submit #{issuable_type}".humanize
diff --git a/spec/views/projects/merge_requests/_commits.html.haml_spec.rb b/spec/views/projects/merge_requests/_commits.html.haml_spec.rb
index 4052dbf8df3..3e17fe2104b 100644
--- a/spec/views/projects/merge_requests/_commits.html.haml_spec.rb
+++ b/spec/views/projects/merge_requests/_commits.html.haml_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'projects/merge_requests/show/_commits.html.haml' do
+describe 'projects/merge_requests/_commits.html.haml' do
include Devise::Test::ControllerHelpers
let(:user) { create(:user) }
diff --git a/spec/views/projects/merge_requests/_new_submit.html.haml_spec.rb b/spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb
index 4f698a34ab5..1e9bdf9108f 100644
--- a/spec/views/projects/merge_requests/_new_submit.html.haml_spec.rb
+++ b/spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'projects/merge_requests/_new_submit.html.haml', :view do
+describe 'projects/merge_requests/creations/_new_submit.html.haml', :view do
let(:merge_request) { create(:merge_request) }
let!(:pipeline) { create(:ci_empty_pipeline) }