Commit 88c60307 authored by Sean McGivern's avatar Sean McGivern

Merge branch 'dm-merge-request-creations-controller' into 'master'

Split up MergeRequestsController

See merge request !12150
parents 971604de 70b05a83
...@@ -209,8 +209,8 @@ import initExperimentalFlags from './experimental_flags'; ...@@ -209,8 +209,8 @@ import initExperimentalFlags from './experimental_flags';
new MilestoneSelect(); new MilestoneSelect();
new gl.IssuableTemplateSelectors(); new gl.IssuableTemplateSelectors();
break; break;
case 'projects:merge_requests:new': case 'projects:merge_requests:creations:new':
case 'projects:merge_requests:new_diffs': case 'projects:merge_requests:creations:diffs':
case 'projects:merge_requests:edit': case 'projects:merge_requests:edit':
new gl.Diff(); new gl.Diff();
shortcut_handler = new ShortcutsNavigation(); shortcut_handler = new ShortcutsNavigation();
...@@ -247,10 +247,6 @@ import initExperimentalFlags from './experimental_flags'; ...@@ -247,10 +247,6 @@ import initExperimentalFlags from './experimental_flags';
shortcut_handler = new ShortcutsIssuable(true); shortcut_handler = new ShortcutsIssuable(true);
new ZenMode(); new ZenMode();
break; break;
case "projects:merge_requests:diffs":
new gl.Diff();
new ZenMode();
break;
case 'dashboard:activity': case 'dashboard:activity':
new gl.Activities(); new gl.Activities();
break; break;
...@@ -319,7 +315,7 @@ import initExperimentalFlags from './experimental_flags'; ...@@ -319,7 +315,7 @@ import initExperimentalFlags from './experimental_flags';
new gl.Members(); new gl.Members();
new UsersSelect(); new UsersSelect();
break; break;
case 'projects:members:show': case 'projects:settings:members:show':
new gl.MemberExpirationDate('.js-access-expiration-date-groups'); new gl.MemberExpirationDate('.js-access-expiration-date-groups');
new GroupsSelect(); new GroupsSelect();
new gl.MemberExpirationDate(); new gl.MemberExpirationDate();
...@@ -386,7 +382,7 @@ import initExperimentalFlags from './experimental_flags'; ...@@ -386,7 +382,7 @@ import initExperimentalFlags from './experimental_flags';
case 'search:show': case 'search:show':
new Search(); new Search();
break; break;
case 'projects:repository:show': case 'projects:settings:repository:show':
// Initialize Protected Branch Settings // Initialize Protected Branch Settings
new gl.ProtectedBranchCreate(); new gl.ProtectedBranchCreate();
new gl.ProtectedBranchEditList(); new gl.ProtectedBranchEditList();
...@@ -396,7 +392,7 @@ import initExperimentalFlags from './experimental_flags'; ...@@ -396,7 +392,7 @@ import initExperimentalFlags from './experimental_flags';
// Initialize expandable settings panels // Initialize expandable settings panels
initSettingsPanels(); initSettingsPanels();
break; break;
case 'projects:ci_cd:show': case 'projects:settings:ci_cd:show':
new gl.ProjectVariables(); new gl.ProjectVariables();
break; break;
case 'ci:lints:create': case 'ci:lints:create':
......
...@@ -168,9 +168,8 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion'; ...@@ -168,9 +168,8 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion';
// Activate a tab based on the current action // Activate a tab based on the current action
activateTab(action) { activateTab(action) {
const activate = action === 'show' ? 'notes' : action;
// important note: the .tab('show') method triggers 'shown.bs.tab' event itself // 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 // 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'; ...@@ -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"
// //
// 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"
// //
// location.pathname # => "/namespace/project/merge_requests/1/diffs" // location.pathname # => "/namespace/project/merge_requests/1/diffs"
...@@ -194,13 +193,13 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion'; ...@@ -194,13 +193,13 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion';
// //
// Returns the new URL String // Returns the new URL String
setCurrentAction(action) { setCurrentAction(action) {
this.currentAction = action === 'show' ? 'notes' : action; this.currentAction = action;
// Remove a trailing '/commits' '/diffs' '/pipelines' '/new' '/new/diffs' // Remove a trailing '/commits' '/diffs' '/pipelines'
let newState = location.pathname.replace(/\/(commits|diffs|pipelines|new|new\/diffs)(\.html)?\/?$/, ''); let newState = location.pathname.replace(/\/(commits|diffs|pipelines)(\.html)?\/?$/, '');
// Append the new action if we're on a tab other than 'notes' // 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}`; newState += `/${this.currentAction}`;
} }
......
...@@ -78,7 +78,7 @@ module CreatesCommit ...@@ -78,7 +78,7 @@ module CreatesCommit
end end
def new_merge_request_path 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.namespace,
@project_to_commit_into, @project_to_commit_into,
merge_request: { 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 ...@@ -131,10 +131,7 @@ module ApplicationHelper
end end
def body_data_page def body_data_page
path = controller.controller_path.split('/') [*controller.controller_path.split('/'), controller.action_name].compact.join(':')
namespace = path.first if path.second
[namespace, controller.controller_name, controller.action_name].compact.join(':')
end end
# shortcut for gitlab config # shortcut for gitlab config
......
...@@ -284,7 +284,7 @@ module BlobHelper ...@@ -284,7 +284,7 @@ module BlobHelper
merge_project = can?(current_user, :create_merge_request, project) ? project : (current_user && current_user.fork_of(project)) merge_project = can?(current_user, :create_merge_request, project) ? project : (current_user && current_user.fork_of(project))
if merge_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 end
options options
......
...@@ -9,7 +9,7 @@ module CompareHelper ...@@ -9,7 +9,7 @@ module CompareHelper
end end
def create_mr_path(from = params[:from], to = params[:to], project = @project) 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.namespace,
project, project,
merge_request: { merge_request: {
......
module MergeRequestsHelper module MergeRequestsHelper
def new_mr_path_from_push_event(event) def new_mr_path_from_push_event(event)
target_project = event.project.default_merge_request_target 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.namespace,
event.project, event.project,
new_mr_from_push_event(event, target_project) new_mr_from_push_event(event, target_project)
...@@ -48,7 +48,7 @@ module MergeRequestsHelper ...@@ -48,7 +48,7 @@ module MergeRequestsHelper
end end
def mr_change_branches_path(merge_request) def mr_change_branches_path(merge_request)
new_namespace_project_merge_request_path( namespace_project_new_merge_request_path(
@project.namespace, @project, @project.namespace, @project,
merge_request: { merge_request: {
source_project_id: merge_request.source_project_id, source_project_id: merge_request.source_project_id,
......
module NavHelper module NavHelper
def page_gutter_class def page_gutter_class
if current_path?('merge_requests#show') || if current_path?('merge_requests#show') ||
current_path?('merge_requests#diffs') || current_path?('projects/merge_requests/conflicts#show') ||
current_path?('merge_requests#commits') ||
current_path?('merge_requests#builds') ||
current_path?('merge_requests#conflicts') ||
current_path?('merge_requests#pipelines') ||
current_path?('issues#show') || current_path?('issues#show') ||
current_path?('milestones#show') current_path?('milestones#show')
if cookies[:collapsed_gutter] == 'true' if cookies[:collapsed_gutter] == 'true'
......
...@@ -49,7 +49,7 @@ module MergeRequests ...@@ -49,7 +49,7 @@ module MergeRequests
def url_for_new_merge_request(branch_name) def url_for_new_merge_request(branch_name)
merge_request_params = { source_branch: 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 } { branch_name: branch_name, url: url, new_merge_request: true }
end end
......
...@@ -10,7 +10,7 @@ module Projects ...@@ -10,7 +10,7 @@ module Projects
merge_requests = @project.forked_from_project.merge_requests.opened.from_project(@project) merge_requests = @project.forked_from_project.merge_requests.opened.from_project(@project)
merge_requests.each do |mr| merge_requests.each do |mr|
MergeRequests::CloseService.new(@project, @current_user).execute(mr) ::MergeRequests::CloseService.new(@project, @current_user).execute(mr)
end end
@project.forked_project_link.destroy @project.forked_project_link.destroy
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
= link_to 'New issue', new_namespace_project_issue_path(@project.namespace, @project) = link_to 'New issue', new_namespace_project_issue_path(@project.namespace, @project)
- if merge_project - if merge_project
%li %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 - if create_project_snippet
%li.header-new-project-snippet %li.header-new-project-snippet
= link_to 'New snippet', new_namespace_project_snippet_path(@project.namespace, @project) = link_to 'New snippet', new_namespace_project_snippet_path(@project.namespace, @project)
......
...@@ -31,7 +31,9 @@ ...@@ -31,7 +31,9 @@
%span.badge.count.issue_counter= number_with_delimiter(IssuesFinder.new(current_user, project_id: @project.id).execute.opened.count) %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 - 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 = link_to namespace_project_merge_requests_path(@project.namespace, @project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do
%span %span
Merge Requests Merge Requests
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
- if merge_project - if merge_project
%li %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') = icon('tasks fw')
#{ _('New merge request') } #{ _('New merge request') }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
%li.commits-row{ data: { day: day } } %li.commits-row{ data: { day: day } }
%ul.content-list.commit-list %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 - if hidden > 0
%li.alert.alert-warning %li.alert.alert-warning
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
- if show_whitespace_toggle - if show_whitespace_toggle
- if current_controller?(:commit) - if current_controller?(:commit)
= commit_diff_whitespace_link(diffs.project, @commit, class: 'hidden-xs') = 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') = diff_merge_request_whitespace_link(diffs.project, @merge_request, class: 'hidden-xs')
- elsif current_controller?(:compare) - elsif current_controller?(:compare)
= diff_compare_whitespace_link(diffs.project, params[:from], params[:to], class: 'hidden-xs') = diff_compare_whitespace_link(diffs.project, params[:from], params[:to], class: 'hidden-xs')
......
...@@ -2,11 +2,10 @@ ...@@ -2,11 +2,10 @@
%h4 %h4
Too many changes to show. Too many changes to show.
.pull-right .pull-right
- if current_controller?(:commit) or current_controller?(:merge_requests)
- if current_controller?(:commit) - if current_controller?(:commit)
= link_to "Plain diff", namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff), class: "btn btn-sm" = 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" = link_to "Email patch", namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch), class: "btn btn-sm"
- elsif @merge_request && @merge_request.persisted? - 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 "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" = link_to "Email patch", merge_request_path(@merge_request, format: :patch), class: "btn btn-sm"
%p %p
......
- @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 @@ ...@@ -3,10 +3,10 @@
= page_specific_javascript_bundle_tag('common_vue') = page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('merge_conflicts') = page_specific_javascript_bundle_tag('merge_conflicts')
= page_specific_javascript_tag('lib/ace.js') = 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 .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 = 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 %h3.page-title
New Merge Request 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 .hide.alert.alert-danger.mr-compare-errors
.merge-request-branches.row .merge-request-branches.row
.col-md-6 .col-md-6
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
:javascript :javascript
new Compare({ new Compare({
targetProjectUrl: "#{update_branches_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: "#{branch_from_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}", sourceBranchUrl: "#{namespace_project_new_merge_request_branch_from_path(@source_project.namespace, @source_project)}",
targetBranchUrl: "#{branch_to_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}" targetBranchUrl: "#{namespace_project_new_merge_request_branch_to_path(@source_project.namespace, @source_project)}"
}); });
...@@ -31,28 +31,27 @@ ...@@ -31,28 +31,27 @@
%span.badge= @commits.size %span.badge= @commits.size
- if @pipelines.any? - if @pipelines.any?
%li.builds-tab %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 Pipelines
%span.badge= @pipelines.size %span.badge= @pipelines.size
%li.diffs-tab %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 Changes
%span.badge= @merge_request.diff_size %span.badge= @merge_request.diff_size
.tab-content .tab-content
#commits.commits.tab-pane.active #commits.commits.tab-pane.active
= render "projects/merge_requests/show/commits" = render "projects/merge_requests/commits"
#diffs.diffs.tab-pane #diffs.diffs.tab-pane
-# This tab is always loaded via AJAX -# This tab is always loaded via AJAX
- if @pipelines.any? - if @pipelines.any?
#pipelines.pipelines.tab-pane #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 .mr-loading-status
= spinner = spinner
:javascript :javascript
var merge_request = new MergeRequest({ var merge_request = new MergeRequest({
action: "#{(@show_changes_tab ? 'new/diffs' : 'new')}", action: "#{j params[:tab].presence || 'new'}",
setUrl: false,
}); });
- if @merge_request_diff.collected? || @merge_request_diff.overflow? - 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 = render "projects/diffs/diffs", diffs: @diffs, environment: @environment
- elsif @merge_request_diff.empty? - elsif @merge_request_diff.empty?
.nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch} .nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch}
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
= button_tag "Edit Merge Requests", class: "btn js-bulk-update-toggle" = 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)) - merge_project = can?(current_user, :create_merge_request, @project) ? @project : (current_user && current_user.fork_of(@project))
- if merge_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 New merge request
= render 'shared/issuable/search_bar', type: :merge_requests = render 'shared/issuable/search_bar', type: :merge_requests
...@@ -33,4 +33,4 @@ ...@@ -33,4 +33,4 @@
.merge-requests-holder .merge-requests-holder
= render 'merge_requests' = render 'merge_requests'
- else - 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" - page_title "#{@merge_request.title} (#{@merge_request.to_reference}", "Merge Requests"
.merge-request .merge-request
= render "projects/merge_requests/show/mr_title" = render "projects/merge_requests/mr_title"
= render "projects/merge_requests/show/mr_box" = render "projects/merge_requests/mr_box"
.alert.alert-danger .alert.alert-danger
%p %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 ...@@ -46,7 +46,7 @@ class ExpirePipelineCacheWorker
end end
def new_merge_request_pipelines_path(project) 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.namespace,
project, project,
format: :json) format: :json)
......
...@@ -87,13 +87,8 @@ constraints(ProjectUrlConstrainer.new) do ...@@ -87,13 +87,8 @@ constraints(ProjectUrlConstrainer.new) do
resources :forks, only: [:index, :new, :create] resources :forks, only: [:index, :new, :create]
resource :import, only: [:new, :create, :show] 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 member do
get :commits
get :diffs
get :conflicts
get :conflict_for_path
get :pipelines
get :commit_change_content get :commit_change_content
post :merge post :merge
post :cancel_merge_when_pipeline_succeeds post :cancel_merge_when_pipeline_succeeds
...@@ -101,18 +96,32 @@ constraints(ProjectUrlConstrainer.new) do ...@@ -101,18 +96,32 @@ constraints(ProjectUrlConstrainer.new) do
get :ci_environments_status get :ci_environments_status
post :toggle_subscription post :toggle_subscription
post :remove_wip post :remove_wip
get :diff_for_path
post :resolve_conflicts
post :assign_related_issues 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 end
collection do collection do
get :branch_from
get :branch_to
get :update_branches
get :diff_for_path get :diff_for_path
post :bulk_update post :bulk_update
get :new_diffs, path: 'new/diffs'
end end
resources :discussions, only: [], constraints: { id: /\h{40}/ } do resources :discussions, only: [], constraints: { id: /\h{40}/ } do
...@@ -123,6 +132,29 @@ constraints(ProjectUrlConstrainer.new) do ...@@ -123,6 +132,29 @@ constraints(ProjectUrlConstrainer.new) do
end end
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 :variables, only: [:index, :show, :update, :create, :destroy]
resources :triggers, only: [:index, :create, :edit, :update, :destroy] do resources :triggers, only: [:index, :create, :edit, :update, :destroy] do
member do member do
......
...@@ -27,7 +27,7 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps ...@@ -27,7 +27,7 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps
step 'I see prefilled new Merge Request page' do step 'I see prefilled new Merge Request page' do
expect(page).to have_selector('.merge-request-form') 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("#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_source_branch").value).to eq "fix"
expect(find("input#merge_request_target_branch").value).to eq "master" expect(find("input#merge_request_target_branch").value).to eq "master"
......
...@@ -266,12 +266,12 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps ...@@ -266,12 +266,12 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
end end
step 'I am redirected to the new merge request page' do 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 end
step "I am redirected to the fork's new merge request page" do step "I am redirected to the fork's new merge request page" do
fork = @user.fork_of(@project) 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 end
step 'I am redirected to the root directory' do step 'I am redirected to the root directory' do
......
...@@ -235,7 +235,7 @@ describe Projects::BlobController do ...@@ -235,7 +235,7 @@ describe Projects::BlobController do
put :update, default_params put :update, default_params
expect(response).to redirect_to( expect(response).to redirect_to(
new_namespace_project_merge_request_path( namespace_project_new_merge_request_path(
forked_project.namespace, forked_project.namespace,
forked_project, forked_project,
merge_request: { 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 ...@@ -65,7 +65,7 @@ feature 'Create New Merge Request', feature: true, js: true do
it 'does not leak the private project name & namespace' do it 'does not leak the private project name & namespace' do
private_project = create(:project, :private) 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).not_to have_content private_project.path_with_namespace
expect(page).to have_content 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 ...@@ -76,7 +76,7 @@ feature 'Create New Merge Request', feature: true, js: true do
it 'does not leak the private project name & namespace' do it 'does not leak the private project name & namespace' do
private_project = create(:project, :private) 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).not_to have_content private_project.path_with_namespace
expect(page).to have_content 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 ...@@ -84,13 +84,13 @@ feature 'Create New Merge Request', feature: true, js: true do
end end
it 'populates source branch button' do 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') expect(find('.js-source-branch')).to have_content('fix')
end end
it 'allows to change the diff view' do 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' click_link 'Changes'
...@@ -106,7 +106,7 @@ feature 'Create New Merge Request', feature: true, js: true do ...@@ -106,7 +106,7 @@ feature 'Create New Merge Request', feature: true, js: true do
end end
it 'does not allow non-existing branches' do 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('The form contains the following errors')
expect(page).to have_content('Source branch "non-exist-source" does not exist') 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 ...@@ -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 context 'when a branch contains commits that both delete and add the same image' do
it 'renders the diff successfully' 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" click_link "Changes"
...@@ -125,7 +125,7 @@ feature 'Create New Merge Request', feature: true, js: true do ...@@ -125,7 +125,7 @@ feature 'Create New Merge Request', feature: true, js: true do
# Isolates a regression (see #24627) # Isolates a regression (see #24627)
it 'does not show error messages on initial form' do 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_selector('#error_explanation')
expect(page).not_to have_content('The form contains the following error') expect(page).not_to have_content('The form contains the following error')
end end
...@@ -138,7 +138,7 @@ feature 'Create New Merge Request', feature: true, js: true do ...@@ -138,7 +138,7 @@ feature 'Create New Merge Request', feature: true, js: true do
end end
it 'shows pipelines for a new merge request' do 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, project.namespace, project,
merge_request: { target_branch: 'master', source_branch: 'fix' }) merge_request: { target_branch: 'master', source_branch: 'fix' })
......
...@@ -23,7 +23,7 @@ describe 'New/edit merge request', feature: true, js: true do ...@@ -23,7 +23,7 @@ describe 'New/edit merge request', feature: true, js: true do
context 'new merge request' do context 'new merge request' do
before do before do
visit new_namespace_project_merge_request_path( visit namespace_project_new_merge_request_path(
project.namespace, project.namespace,
project, project,
merge_request: { merge_request: {
...@@ -182,7 +182,7 @@ describe 'New/edit merge request', feature: true, js: true do ...@@ -182,7 +182,7 @@ describe 'New/edit merge request', feature: true, js: true do
context 'new merge request' do context 'new merge request' do
before do before do
visit new_namespace_project_merge_request_path( visit namespace_project_new_merge_request_path(
fork_project.namespace, fork_project.namespace,
fork_project, fork_project,
merge_request: { merge_request: {
......
...@@ -131,7 +131,7 @@ feature 'Merge Requests > User uses quick actions', feature: true, js: true do ...@@ -131,7 +131,7 @@ feature 'Merge Requests > User uses quick actions', feature: true, js: true do
end end
it 'changes target_branch in new merge_request' do 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_title", with: 'My brand new feature'
fill_in "merge_request_description", with: "le feature \n/target_branch fix\nFeature description:" fill_in "merge_request_description", with: "le feature \n/target_branch fix\nFeature description:"
......
...@@ -12,7 +12,7 @@ describe 'Merge request', :feature, :js do ...@@ -12,7 +12,7 @@ describe 'Merge request', :feature, :js do
context 'new merge request' do context 'new merge request' do
before do before do
visit new_namespace_project_merge_request_path( visit namespace_project_new_merge_request_path(
project.namespace, project.namespace,
project, project,
merge_request: { merge_request: {
......
...@@ -11,7 +11,7 @@ feature 'Work In Progress help message', feature: true do ...@@ -11,7 +11,7 @@ feature 'Work In Progress help message', feature: true do
context 'with WIP commits' do context 'with WIP commits' do
it 'shows a specific WIP hint' 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.namespace,
project, project,
merge_request: { merge_request: {
...@@ -32,7 +32,7 @@ feature 'Work In Progress help message', feature: true do ...@@ -32,7 +32,7 @@ feature 'Work In Progress help message', feature: true do
context 'without WIP commits' do context 'without WIP commits' do
it 'shows the regular WIP message' 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.namespace,
project, project,
merge_request: { merge_request: {
......
...@@ -23,7 +23,7 @@ feature 'Merge Request button', feature: true do ...@@ -23,7 +23,7 @@ feature 'Merge Request button', feature: true do
end end
it 'shows Create merge request button' do 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, project,
merge_request: { source_branch: 'feature', merge_request: { source_branch: 'feature',
target_branch: 'master' }) target_branch: 'master' })
...@@ -67,7 +67,7 @@ feature 'Merge Request button', feature: true do ...@@ -67,7 +67,7 @@ feature 'Merge Request button', feature: true do
let(:user) { forked_project.owner } let(:user) { forked_project.owner }
it 'shows Create merge request button' do 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, forked_project,
merge_request: { source_branch: 'feature', merge_request: { source_branch: 'feature',
target_branch: 'master' }) target_branch: 'master' })
......
...@@ -27,7 +27,7 @@ feature 'Merge Requests List' do ...@@ -27,7 +27,7 @@ feature 'Merge Requests List' do
it 'empty state should have a create merge request button' do it 'empty state should have a create merge request button' do
visit namespace_project_merge_requests_path(project.namespace, project) 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 end
context 'if there are merge requests' do context 'if there are merge requests' do
......
...@@ -51,7 +51,7 @@ feature 'New directory creation', feature: true, js: true 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 'New Merge Request'
expect(page).to have_content "From #{new_branch_name} into master" expect(page).to have_content "From #{new_branch_name} into master"
expect(page).to have_content 'Add new directory' 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 end
end end
...@@ -239,7 +239,7 @@ describe "Internal Project Access", feature: true do ...@@ -239,7 +239,7 @@ describe "Internal Project Access", feature: true do
end end
describe "GET /:project_path/merge_requests/new" do 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(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:owner).of(project) }
......
...@@ -452,7 +452,7 @@ describe "Public Project Access", feature: true do ...@@ -452,7 +452,7 @@ describe "Public Project Access", feature: true do
end end
describe "GET /:project_path/merge_requests/new" do 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(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:owner).of(project) }
......
...@@ -55,27 +55,14 @@ describe Projects::MergeRequestsController, '(JavaScript fixtures)', type: :cont ...@@ -55,27 +55,14 @@ describe Projects::MergeRequestsController, '(JavaScript fixtures)', type: :cont
render_merge_request(example.description, merge_request) render_merge_request(example.description, merge_request)
end 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 private
def render_merge_request(fixture_file_name, merge_request, action: :show, format: :html, view: 'inline') def render_merge_request(fixture_file_name, merge_request)
get action, get :show,
namespace_id: project.namespace.to_param, namespace_id: project.namespace.to_param,
project_id: project, project_id: project,
id: merge_request.to_param, id: merge_request.to_param,
format: format, format: :html
view: view
expect(response).to be_success expect(response).to be_success
store_frontend_fixture(response, fixture_file_name) 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', () => { ...@@ -15,7 +15,7 @@ describe('Merge request notes', () => {
gl.utils = gl.utils || {}; gl.utils = gl.utils || {};
const discussionTabFixture = 'merge_requests/diff_comment.html.raw'; 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); preloadFixtures(discussionTabFixture, changesTabJsonFixture);
describe('Discussion tab with diff comments', () => { describe('Discussion tab with diff comments', () => {
......
...@@ -23,8 +23,8 @@ import 'vendor/jquery.scrollTo'; ...@@ -23,8 +23,8 @@ import 'vendor/jquery.scrollTo';
$.extend(stubLocation, defaults, stubs || {}); $.extend(stubLocation, defaults, stubs || {});
}; };
const inlineChangesTabJsonFixture = 'merge_requests/inline_changes_tab_with_comments.json'; const inlineChangesTabJsonFixture = 'merge_request_diffs/inline_changes_tab_with_comments.json';
const parallelChangesTabJsonFixture = 'merge_requests/parallel_changes_tab_with_comments.json'; const parallelChangesTabJsonFixture = 'merge_request_diffs/parallel_changes_tab_with_comments.json';
preloadFixtures( preloadFixtures(
'merge_requests/merge_request_with_task_list.html.raw', 'merge_requests/merge_request_with_task_list.html.raw',
'merge_requests/diff_comment.html.raw', 'merge_requests/diff_comment.html.raw',
...@@ -52,14 +52,10 @@ import 'vendor/jquery.scrollTo'; ...@@ -52,14 +52,10 @@ import 'vendor/jquery.scrollTo';
loadFixtures('merge_requests/merge_request_with_task_list.html.raw'); loadFixtures('merge_requests/merge_request_with_task_list.html.raw');
this.subject = this.class.activateTab; 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'); this.subject('show');
expect($('#notes')).toHaveClass('active'); 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 () { it('shows the commits tab when action is commits', function () {
this.subject('commits'); this.subject('commits');
expect($('#commits')).toHaveClass('active'); expect($('#commits')).toHaveClass('active');
...@@ -161,7 +157,7 @@ import 'vendor/jquery.scrollTo'; ...@@ -161,7 +157,7 @@ import 'vendor/jquery.scrollTo';
setLocation({ setLocation({
pathname: '/foo/bar/merge_requests/1/commits' 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'); expect(this.subject('diffs')).toBe('/foo/bar/merge_requests/1/diffs');
}); });
...@@ -170,7 +166,7 @@ import 'vendor/jquery.scrollTo'; ...@@ -170,7 +166,7 @@ import 'vendor/jquery.scrollTo';
pathname: '/foo/bar/merge_requests/1/diffs' 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'); expect(this.subject('commits')).toBe('/foo/bar/merge_requests/1/commits');
}); });
...@@ -178,7 +174,7 @@ import 'vendor/jquery.scrollTo'; ...@@ -178,7 +174,7 @@ import 'vendor/jquery.scrollTo';
setLocation({ setLocation({
pathname: '/foo/bar/merge_requests/1/diffs.html' 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'); expect(this.subject('commits')).toBe('/foo/bar/merge_requests/1/commits');
}); });
......
...@@ -246,28 +246,13 @@ describe 'project routing' do ...@@ -246,28 +246,13 @@ describe 'project routing' do
end end
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 describe Projects::MergeRequestsController, 'routing' do
it 'to #diffs' do it 'to #commits' do
expect(get('/gitlab/gitlabhq/merge_requests/1/diffs')).to route_to('projects/merge_requests#diffs', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') 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 end
it 'to #commits' do it 'to #pipelines' do
expect(get('/gitlab/gitlabhq/merge_requests/1/commits')).to route_to('projects/merge_requests#commits', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') 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 end
it 'to #merge' do it 'to #merge' do
...@@ -277,25 +262,59 @@ describe 'project routing' do ...@@ -277,25 +262,59 @@ describe 'project routing' do
) )
end 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 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 end
it 'to #branch_to' do 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 end
it 'to #show' do it 'to #pipelines' 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/new/pipelines.json')).to route_to('projects/merge_requests/creations#pipelines', namespace_id: 'gitlab', project_id: 'gitlabhq', format: 'json')
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')
end end
it_behaves_like 'RESTful project resources' do it 'to #diffs' do
let(:controller) { 'merge_requests' } 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')
let(:actions) { [:index, :create, :new, :edit, :show, :update] } 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
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 # raw_project_snippet GET /:project_id/snippets/:id/raw(.:format) snippets#raw
# project_snippets GET /:project_id/snippets(.:format) snippets#index # project_snippets GET /:project_id/snippets(.:format) snippets#index
# POST /:project_id/snippets(.:format) snippets#create # POST /:project_id/snippets(.:format) snippets#create
......
...@@ -28,7 +28,12 @@ shared_examples 'issuable record that supports quick actions in its description ...@@ -28,7 +28,12 @@ shared_examples 'issuable record that supports quick actions in its description
describe "new #{issuable_type}", js: true do describe "new #{issuable_type}", js: true do
context 'with commands in the description' do context 'with commands in the description' do
it "creates the #{issuable_type} and interpret commands accordingly" 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}_title", with: 'bug 345'
fill_in "#{issuable_type}_description", with: "bug description\n/label ~bug\n/milestone %\"ASAP\"" fill_in "#{issuable_type}_description", with: "bug description\n/label ~bug\n/milestone %\"ASAP\""
click_button "Submit #{issuable_type}".humanize click_button "Submit #{issuable_type}".humanize
......
require 'spec_helper' require 'spec_helper'
describe 'projects/merge_requests/show/_commits.html.haml' do describe 'projects/merge_requests/_commits.html.haml' do
include Devise::Test::ControllerHelpers include Devise::Test::ControllerHelpers
let(:user) { create(:user) } let(:user) { create(:user) }
......
require 'spec_helper' 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(:merge_request) { create(:merge_request) }
let!(:pipeline) { create(:ci_empty_pipeline) } 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