Commit 70b05a83 authored by Douwe Maan's avatar Douwe Maan

Split up MergeRequestsController

parent 92f87f6d
......@@ -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':
......
......@@ -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}`;
}
......
......@@ -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: {
......
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
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
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
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
......@@ -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
......
......@@ -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
......
......@@ -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: {
......
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,
......
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'
......
......@@ -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
......
......@@ -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
......
......@@ -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)
......
......@@ -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
......
......@@ -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') }
......
......@@ -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
......
......@@ -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')
......
......@@ -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}
......
- @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}"
});
});
......@@ -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
......
- 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"
%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)}"
});
......@@ -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'}",
});
- 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}
......@@ -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)
- 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
......
= 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'}",
});
});
......@@ -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)
......
......@@ -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
......
......@@ -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"
......
......@@ -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
......
......@@ -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: {
......
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
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
......@@ -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' })
......
......@@ -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: {
......
......@@ -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:"
......
......@@ -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: {
......
......@@ -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: {
......
......@@ -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' })
......
......@@ -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
......
......@@ -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
......@@ -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) }
......
......@@ -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) }
......
......@@ -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)
......
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
......@@ -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', () => {
......
......@@ -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');
});
......
......@@ -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
......
......@@ -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
......
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) }
......
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) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment