Commit 69c4e0a1 authored by James Lopez's avatar James Lopez

Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into hotfix/ruby-21-broken-update

parents 902baa2e 88e16c3d
Please view this file on the master branch, on stable branches it's out of date. Please view this file on the master branch, on stable branches it's out of date.
v 8.5.0 (unreleased) v 8.5.0 (unreleased)
- Ensure rake tasks that don't need a DB connection can be run without one
- Add "visibility" flag to GET /projects api endpoint - Add "visibility" flag to GET /projects api endpoint
- Ignore binary files in code search to prevent Error 500 (Stan Hu) - Ignore binary files in code search to prevent Error 500 (Stan Hu)
- Upgrade gitlab_git to 7.2.23 to fix commit message mentions in first branch push - Upgrade gitlab_git to 7.2.23 to fix commit message mentions in first branch push
...@@ -14,6 +15,8 @@ v 8.5.0 (unreleased) ...@@ -14,6 +15,8 @@ v 8.5.0 (unreleased)
- Track project import failure - Track project import failure
- Fix visibility level text in admin area (Zeger-Jan van de Weg) - Fix visibility level text in admin area (Zeger-Jan van de Weg)
- Update the ExternalIssue regex pattern (Blake Hitchcock) - Update the ExternalIssue regex pattern (Blake Hitchcock)
- Deprecate API "merge_request/:merge_request_id/comments". Use "merge_requests/:merge_request_id/notes" instead
- Deprecate API "merge_request/:merge_request_id/...". Use "merge_requests/:merge_request_id/..." instead
v 8.4.2 v 8.4.2
- Bump required gitlab-workhorse version to bring in a fix for missing - Bump required gitlab-workhorse version to bring in a fix for missing
......
...@@ -50,6 +50,7 @@ class @Issue ...@@ -50,6 +50,7 @@ class @Issue
new Flash(issueFailMessage, 'alert') new Flash(issueFailMessage, 'alert')
success: (data, textStatus, jqXHR) -> success: (data, textStatus, jqXHR) ->
if data.saved if data.saved
$(document).trigger('issuable:change');
if isClose if isClose
$('a.btn-close').addClass('hidden') $('a.btn-close').addClass('hidden')
$('a.btn-reopen').removeClass('hidden') $('a.btn-reopen').removeClass('hidden')
......
...@@ -64,6 +64,9 @@ class @Notes ...@@ -64,6 +64,9 @@ class @Notes
# fetch notes when tab becomes visible # fetch notes when tab becomes visible
$(document).on "visibilitychange", @visibilityChange $(document).on "visibilitychange", @visibilityChange
# when issue status changes, we need to refresh data
$(document).on "issuable:change", @refresh
cleanBinding: -> cleanBinding: ->
$(document).off "ajax:success", ".js-main-target-form" $(document).off "ajax:success", ".js-main-target-form"
$(document).off "ajax:success", ".js-discussion-note-form" $(document).off "ajax:success", ".js-discussion-note-form"
......
...@@ -9,11 +9,13 @@ class @ProjectsList ...@@ -9,11 +9,13 @@ class @ProjectsList
$(".projects-list-filter").keyup -> $(".projects-list-filter").keyup ->
terms = $(this).val() terms = $(this).val()
uiBox = $('div.projects-list-holder') uiBox = $('div.projects-list-holder')
filterSelector = $(this).data('filter-selector') || 'span.filter-title'
if terms == "" || terms == undefined if terms == "" || terms == undefined
uiBox.find("ul.projects-list li").show() uiBox.find("ul.projects-list li").show()
else else
uiBox.find("ul.projects-list li").each (index) -> uiBox.find("ul.projects-list li").each (index) ->
name = $(this).find("span.filter-title").text() name = $(this).find(filterSelector).text()
if name.toLowerCase().search(terms.toLowerCase()) == -1 if name.toLowerCase().search(terms.toLowerCase()) == -1
$(this).hide() $(this).hide()
......
...@@ -115,7 +115,7 @@ ...@@ -115,7 +115,7 @@
ul, ol { ul, ol {
padding: 0; padding: 0;
margin: 6px 0 6px 18px !important; margin: 6px 0 6px 28px !important;
} }
li { li {
......
...@@ -564,3 +564,53 @@ pre.light-well { ...@@ -564,3 +564,53 @@ pre.light-well {
color: #E62958; color: #E62958;
margin-top: 2px; margin-top: 2px;
} }
/*
* Forks list rendered on Project's forks page
*/
.forks-top-block {
padding: 16px 0;
}
.projects-search-form {
.dropdown-toggle.btn {
margin-top: -3px;
}
&.fork-search-form {
margin: 0;
margin-top: -$gl-padding;
padding-bottom: 0;
input {
/* Small devices (tablets, 768px and up) */
@media (min-width: $screen-sm-min) { width: 180px; }
/* Medium devices (desktops, 992px and up) */
@media (min-width: $screen-md-min) { width: 350px; }
/* Large devices (large desktops, 1200px and up) */
@media (min-width: $screen-lg-min) { width: 400px; }
}
.sort-forks {
width: 160px;
}
.fork-link {
float: right;
margin-left: $gl-padding;
}
}
}
.private-forks-notice .private-fork-icon {
i:nth-child(1) {
color: #2AA056;
}
i:nth-child(2) {
color: #FFFFFF;
}
}
...@@ -298,7 +298,8 @@ class ApplicationController < ActionController::Base ...@@ -298,7 +298,8 @@ class ApplicationController < ActionController::Base
end end
def set_filters_params def set_filters_params
params[:sort] ||= 'id_desc' set_default_sort
params[:scope] = 'all' if params[:scope].blank? params[:scope] = 'all' if params[:scope].blank?
params[:state] = 'opened' if params[:state].blank? params[:state] = 'opened' if params[:state].blank?
...@@ -405,4 +406,24 @@ class ApplicationController < ActionController::Base ...@@ -405,4 +406,24 @@ class ApplicationController < ActionController::Base
current_user.nil? && root_path == request.path current_user.nil? && root_path == request.path
end end
private
def set_default_sort
key = if is_a_listing_page_for?('issues') || is_a_listing_page_for?('merge_requests')
'issuable_sort'
end
cookies[key] = params[:sort] if key && params[:sort].present?
params[:sort] = cookies[key] if key
params[:sort] ||= 'id_desc'
end
def is_a_listing_page_for?(page_type)
controller_name, action_name = params.values_at(:controller, :action)
(controller_name == "projects/#{page_type}" && action_name == 'index') ||
(controller_name == 'groups' && action_name == page_type) ||
(controller_name == 'dashboard' && action_name == page_type)
end
end end
...@@ -3,6 +3,15 @@ class Projects::ForksController < Projects::ApplicationController ...@@ -3,6 +3,15 @@ class Projects::ForksController < Projects::ApplicationController
before_action :require_non_empty_project before_action :require_non_empty_project
before_action :authorize_download_code! before_action :authorize_download_code!
def index
@sort = params[:sort] || 'id_desc'
@all_forks = project.forks.includes(:creator).order_by(@sort)
@public_forks, @protected_forks = @all_forks.partition do |project|
can?(current_user, :read_project, project)
end
end
def new def new
@namespaces = current_user.manageable_namespaces @namespaces = current_user.manageable_namespaces
@namespaces.delete(@project.namespace) @namespaces.delete(@project.namespace)
......
...@@ -36,8 +36,7 @@ module BlobHelper ...@@ -36,8 +36,7 @@ module BlobHelper
notice: edit_in_new_fork_notice, notice: edit_in_new_fork_notice,
notice_now: edit_in_new_fork_notice_now notice_now: edit_in_new_fork_notice_now
} }
fork_path = namespace_project_fork_path(project.namespace, project, namespace_key: current_user.namespace.id, fork_path = namespace_project_forks_path(project.namespace, project, namespace_key: current_user.namespace.id, continue: continue_params)
continue: continue_params)
link_to "Edit", fork_path, class: 'btn', method: :post link_to "Edit", fork_path, class: 'btn', method: :post
end end
...@@ -62,8 +61,7 @@ module BlobHelper ...@@ -62,8 +61,7 @@ module BlobHelper
notice: edit_in_new_fork_notice + " Try to #{action} this file again.", notice: edit_in_new_fork_notice + " Try to #{action} this file again.",
notice_now: edit_in_new_fork_notice_now notice_now: edit_in_new_fork_notice_now
} }
fork_path = namespace_project_fork_path(project.namespace, project, namespace_key: current_user.namespace.id, fork_path = namespace_project_forks_path(project.namespace, project, namespace_key: current_user.namespace.id, continue: continue_params)
continue: continue_params)
link_to label, fork_path, class: "btn btn-#{btn_class}", method: :post link_to label, fork_path, class: "btn btn-#{btn_class}", method: :post
end end
......
...@@ -7,7 +7,7 @@ module IconsHelper ...@@ -7,7 +7,7 @@ module IconsHelper
# font-awesome-rails gem, but should we ever use a different icon pack in the # font-awesome-rails gem, but should we ever use a different icon pack in the
# future we won't have to change hundreds of method calls. # future we won't have to change hundreds of method calls.
def icon(names, options = {}) def icon(names, options = {})
fa_icon(names, options) options.include?(:base) ? fa_stacked_icon(names, options) : fa_icon(names, options)
end end
def spinner(text = nil, visible = false) def spinner(text = nil, visible = false)
......
...@@ -116,7 +116,7 @@ module ProjectsHelper ...@@ -116,7 +116,7 @@ module ProjectsHelper
private private
def get_project_nav_tabs(project, current_user) def get_project_nav_tabs(project, current_user)
nav_tabs = [:home] nav_tabs = [:home, :forks]
if !project.empty_repo? && can?(current_user, :download_code, project) if !project.empty_repo? && can?(current_user, :download_code, project)
nav_tabs << [:files, :commits, :network, :graphs] nav_tabs << [:files, :commits, :network, :graphs]
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
.pull-right .pull-right
.dropdown.inline .dropdown.inline
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%span.light sort: %span.light
- if @sort.present? - if @sort.present?
= sort_options_hash[@sort] = sort_options_hash[@sort]
- else - else
......
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
.controls .controls
.dropdown.inline .dropdown.inline
%button.dropdown-toggle.btn.btn-sm{type: 'button', 'data-toggle' => 'dropdown'} %button.dropdown-toggle.btn.btn-sm{type: 'button', 'data-toggle' => 'dropdown'}
%span.light sort: %span.light
- if @sort.present? - if @sort.present?
= sort_options_hash[@sort] = sort_options_hash[@sort]
- else - else
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
.pull-right .pull-right
.dropdown.inline .dropdown.inline
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%span.light sort: %span.light
- if @sort.present? - if @sort.present?
= sort_options_hash[@sort] = sort_options_hash[@sort]
- else - else
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
.pull-right .pull-right
.dropdown.inline .dropdown.inline
%button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'}
%span.light sort: %span.light
- if @sort.present? - if @sort.present?
= sort_options_hash[@sort] = sort_options_hash[@sort]
- else - else
......
.dropdown.inline .dropdown.inline
%button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'}
%span.light sort: %span.light
- if @sort.present? - if @sort.present?
= sort_options_hash[@sort] = sort_options_hash[@sort]
- elsif current_page?(trending_explore_projects_path) || current_page?(explore_root_path) - elsif current_page?(trending_explore_projects_path) || current_page?(explore_root_path)
...@@ -24,4 +24,3 @@ ...@@ -24,4 +24,3 @@
= sort_title_recently_updated = sort_title_recently_updated
= link_to explore_projects_filter_path(sort: sort_value_oldest_updated) do = link_to explore_projects_filter_path(sort: sort_value_oldest_updated) do
= sort_title_oldest_updated = sort_title_oldest_updated
...@@ -98,6 +98,13 @@ ...@@ -98,6 +98,13 @@
%span %span
Wiki Wiki
- if project_nav_tab? :forks
= nav_link(controller: :forks, action: :index) do
= link_to namespace_project_forks_path(@project.namespace, @project), title: 'Forks' do
= icon('code-fork fw')
%span
Forks
- if project_nav_tab? :snippets - if project_nav_tab? :snippets
= nav_link(controller: :snippets) do = nav_link(controller: :snippets) do
= link_to namespace_project_snippets_path(@project.namespace, @project), title: 'Snippets', class: 'shortcuts-snippets' do = link_to namespace_project_snippets_path(@project.namespace, @project), title: 'Snippets', class: 'shortcuts-snippets' do
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
&nbsp; &nbsp;
.dropdown.inline .dropdown.inline
%button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'}
%span.light sort: %span.light
- if @sort.present? - if @sort.present?
= @sort.humanize = @sort.humanize
- else - else
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
- continue_params = { to: namespace_project_new_blob_path(@project.namespace, @project, @project.default_branch || 'master'), - continue_params = { to: namespace_project_new_blob_path(@project.namespace, @project, @project.default_branch || 'master'),
notice: edit_in_new_fork_notice, notice: edit_in_new_fork_notice,
notice_now: edit_in_new_fork_notice_now } notice_now: edit_in_new_fork_notice_now }
- fork_path = namespace_project_fork_path(@project.namespace, @project, namespace_key: current_user.namespace.id, - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id,
continue: continue_params) continue: continue_params)
= link_to fork_path, method: :post do = link_to fork_path, method: :post do
= icon('file fw') = icon('file fw')
......
.gray-content-block.top-block.clearfix.white.forks-top-block
.pull-left
- public_count = @public_forks.size
- protected_count = @protected_forks.size
- full_count_title = "#{public_count} public and #{protected_count} private"
== #{pluralize(@all_forks.size, 'fork')}: #{full_count_title}
.pull-right
.projects-search-form.fork-search-form
= search_field_tag :filter_projects, nil, placeholder: 'Search forks', class: 'projects-list-filter form-control',
spellcheck: false, data: { 'filter-selector' => 'span.namespace-name' }
.dropdown.inline.prepend-left-10
%button.dropdown-toggle.btn.sort-forks{type: 'button', 'data-toggle' => 'dropdown'}
%span.light sort:
- if @sort.present?
= sort_options_hash[@sort]
- else
= sort_title_recently_created
%b.caret
%ul.dropdown-menu.dropdown-menu-align-right
%li
- excluded_filters = [:state, :scope, :label_name, :milestone_id, :assignee_id, :author_id]
= link_to page_filter_path(sort: sort_value_recently_created, without: excluded_filters) do
= sort_title_recently_created
= link_to page_filter_path(sort: sort_value_oldest_created, without: excluded_filters) do
= sort_title_oldest_created
= link_to page_filter_path(sort: sort_value_recently_updated, without: excluded_filters) do
= sort_title_recently_updated
= link_to page_filter_path(sort: sort_value_oldest_updated, without: excluded_filters) do
= sort_title_oldest_updated
.fork-link.inline
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'pull-right btn btn-new' do
= icon('code-fork fw')
Fork
- else
= link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork project", class: 'pull-right btn btn-new' do
= icon('code-fork fw')
Fork
.projects-list-holder
- if @public_forks.blank?
%ul.content-list
%li
.nothing-here-block No forks to show
- else
= render 'shared/projects/list', projects: @public_forks, use_creator_avatar: true,
forks: true, show_last_commit_as_description: true
- if protected_count > 0
%ul.projects-list.private-forks-notice
%li.project-row
= icon('lock fw', base: 'circle', class: 'fa-lg private-fork-icon')
%strong= pluralize(protected_count, 'private fork')
%span you have no access to.
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
- else - else
.fork-thumbnail .fork-thumbnail
= link_to namespace_project_fork_path(@project.namespace, @project, namespace_key: namespace.id), title: "Fork here", method: "POST", class: 'has_tooltip' do = link_to namespace_project_forks_path(@project.namespace, @project, namespace_key: namespace.id), title: "Fork here", method: "POST", class: 'has_tooltip' do
= image_tag namespace_icon(namespace, 100) = image_tag namespace_icon(namespace, 100)
.caption .caption
%strong %strong
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
- continue_params = { to: namespace_project_new_blob_path(@project.namespace, @project, @id), - continue_params = { to: namespace_project_new_blob_path(@project.namespace, @project, @id),
notice: edit_in_new_fork_notice, notice: edit_in_new_fork_notice,
notice_now: edit_in_new_fork_notice_now } notice_now: edit_in_new_fork_notice_now }
- fork_path = namespace_project_fork_path(@project.namespace, @project, namespace_key: current_user.namespace.id, - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id,
continue: continue_params) continue: continue_params)
= link_to fork_path, method: :post do = link_to fork_path, method: :post do
= icon('pencil fw') = icon('pencil fw')
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
- continue_params = { to: request.fullpath, - continue_params = { to: request.fullpath,
notice: edit_in_new_fork_notice + " Try to upload a file again.", notice: edit_in_new_fork_notice + " Try to upload a file again.",
notice_now: edit_in_new_fork_notice_now } notice_now: edit_in_new_fork_notice_now }
- fork_path = namespace_project_fork_path(@project.namespace, @project, namespace_key: current_user.namespace.id, - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id,
continue: continue_params) continue: continue_params)
= link_to fork_path, method: :post do = link_to fork_path, method: :post do
= icon('file fw') = icon('file fw')
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
- continue_params = { to: request.fullpath, - continue_params = { to: request.fullpath,
notice: edit_in_new_fork_notice + " Try to create a new directory again.", notice: edit_in_new_fork_notice + " Try to create a new directory again.",
notice_now: edit_in_new_fork_notice_now } notice_now: edit_in_new_fork_notice_now }
- fork_path = namespace_project_fork_path(@project.namespace, @project, namespace_key: current_user.namespace.id, - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id,
continue: continue_params) continue: continue_params)
= link_to fork_path, method: :post do = link_to fork_path, method: :post do
= icon('folder fw') = icon('folder fw')
......
.dropdown.inline.prepend-left-10 .dropdown.inline.prepend-left-10
%button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'}
%span.light sort: %span.light
- if @sort.present? - if @sort.present?
= sort_options_hash[@sort] = sort_options_hash[@sort]
- else - else
......
- projects_limit = 20 unless local_assigns[:projects_limit] - projects_limit = 20 unless local_assigns[:projects_limit]
- avatar = true unless local_assigns[:avatar] == false - avatar = true unless local_assigns[:avatar] == false
- use_creator_avatar = false unless local_assigns[:use_creator_avatar] == true
- stars = true unless local_assigns[:stars] == false - stars = true unless local_assigns[:stars] == false
- forks = false unless local_assigns[:forks] == true
- ci = false unless local_assigns[:ci] == true - ci = false unless local_assigns[:ci] == true
- skip_namespace = false unless local_assigns[:skip_namespace] == true - skip_namespace = false unless local_assigns[:skip_namespace] == true
- show_last_commit_as_description = false unless local_assigns[:show_last_commit_as_description] == true
%ul.projects-list %ul.projects-list
- projects.each_with_index do |project, i| - projects.each_with_index do |project, i|
- css_class = (i >= projects_limit) ? 'hide' : nil - css_class = (i >= projects_limit) ? 'hide' : nil
= render "shared/projects/project", project: project, skip_namespace: skip_namespace, = render "shared/projects/project", project: project, skip_namespace: skip_namespace,
avatar: avatar, stars: stars, css_class: css_class, ci: ci avatar: avatar, stars: stars, css_class: css_class, ci: ci, use_creator_avatar: use_creator_avatar,
forks: forks, show_last_commit_as_description: show_last_commit_as_description
- if projects.size > projects_limit - if projects.size > projects_limit
%li.bottom.center %li.bottom.center
......
- avatar = true unless local_assigns[:avatar] == false - avatar = true unless local_assigns[:avatar] == false
- stars = true unless local_assigns[:stars] == false - stars = true unless local_assigns[:stars] == false
- forks = false unless local_assigns[:forks] == true
- ci = false unless local_assigns[:ci] == true - ci = false unless local_assigns[:ci] == true
- skip_namespace = false unless local_assigns[:skip_namespace] == true - skip_namespace = false unless local_assigns[:skip_namespace] == true
- css_class = '' unless local_assigns[:css_class] - css_class = '' unless local_assigns[:css_class]
- css_class += " no-description" unless project.description.present? - show_last_commit_as_description = false unless local_assigns[:show_last_commit_as_description] == true
- css_class += " no-description" if project.description.blank? && !show_last_commit_as_description
- ci_commit = project.ci_commit(project.commit.sha) if ci && !project.empty_repo? && project.commit - ci_commit = project.ci_commit(project.commit.sha) if ci && !project.empty_repo? && project.commit
- cache_key = [project.namespace, project, controller.controller_name, controller.action_name, current_application_settings, 'v2.2'] - cache_key = [project.namespace, project, controller.controller_name, controller.action_name, current_application_settings, 'v2.2']
- cache_key.push(ci_commit.status) if ci_commit - cache_key.push(ci_commit.status) if ci_commit
...@@ -13,6 +15,9 @@ ...@@ -13,6 +15,9 @@
= link_to project_path(project), class: dom_class(project) do = link_to project_path(project), class: dom_class(project) do
- if avatar - if avatar
.dash-project-avatar .dash-project-avatar
- if use_creator_avatar
= image_tag avatar_icon(project.creator.email, 46), class: "avatar s46", alt:''
- else
= project_icon(project, alt: '', class: 'avatar project-avatar s46') = project_icon(project, alt: '', class: 'avatar project-avatar s46')
%span.project-full-name %span.project-full-name
%span.namespace-name %span.namespace-name
...@@ -26,10 +31,18 @@ ...@@ -26,10 +31,18 @@
- if ci_commit - if ci_commit
= render_ci_status(ci_commit) = render_ci_status(ci_commit)
&nbsp; &nbsp;
- if forks
%span
= icon('code-fork')
= project.forks_count
- if stars - if stars
%span %span
%i.fa.fa-star = icon('star')
= project.star_count = project.star_count
- if project.description.present? - if show_last_commit_as_description
.project-description
= link_to_gfm project.commit.title, namespace_project_commit_path(project.namespace, project, project.commit),
class: "commit-row-message"
- elsif project.description.present?
.project-description .project-description
= markdown(project.description, pipeline: :description) = markdown(project.description, pipeline: :description)
...@@ -554,7 +554,7 @@ Rails.application.routes.draw do ...@@ -554,7 +554,7 @@ Rails.application.routes.draw do
end end
end end
resource :fork, only: [:new, :create] resources :forks, only: [:index, :new, :create]
resource :import, only: [:new, :create, :show] resource :import, only: [:new, :create, :show]
resources :refs, only: [] do resources :refs, only: [] do
......
...@@ -60,7 +60,7 @@ Parameters: ...@@ -60,7 +60,7 @@ Parameters:
Shows information about a single merge request. Shows information about a single merge request.
``` ```
GET /projects/:id/merge_request/:merge_request_id GET /projects/:id/merge_requests/:merge_request_id
``` ```
Parameters: Parameters:
...@@ -105,7 +105,7 @@ Parameters: ...@@ -105,7 +105,7 @@ Parameters:
Get a list of merge request commits. Get a list of merge request commits.
``` ```
GET /projects/:id/merge_request/:merge_request_id/commits GET /projects/:id/merge_requests/:merge_request_id/commits
``` ```
Parameters: Parameters:
...@@ -142,7 +142,7 @@ Parameters: ...@@ -142,7 +142,7 @@ Parameters:
Shows information about the merge request including its files and changes. Shows information about the merge request including its files and changes.
``` ```
GET /projects/:id/merge_request/:merge_request_id/changes GET /projects/:id/merge_requests/:merge_request_id/changes
``` ```
Parameters: Parameters:
...@@ -264,7 +264,7 @@ If an error occurs, an error number and a message explaining the reason is retur ...@@ -264,7 +264,7 @@ If an error occurs, an error number and a message explaining the reason is retur
Updates an existing merge request. You can change the target branch, title, or even close the MR. Updates an existing merge request. You can change the target branch, title, or even close the MR.
``` ```
PUT /projects/:id/merge_request/:merge_request_id PUT /projects/:id/merge_requests/:merge_request_id
``` ```
Parameters: Parameters:
...@@ -323,7 +323,7 @@ If merge request is already merged or closed - you get 405 and error message 'Me ...@@ -323,7 +323,7 @@ If merge request is already merged or closed - you get 405 and error message 'Me
If you don't have permissions to accept this merge request - you'll get a 401 If you don't have permissions to accept this merge request - you'll get a 401
``` ```
PUT /projects/:id/merge_request/:merge_request_id/merge PUT /projects/:id/merge_requests/:merge_request_id/merge
``` ```
Parameters: Parameters:
...@@ -373,7 +373,7 @@ If the merge request is already merged or closed - you get 405 and error message ...@@ -373,7 +373,7 @@ If the merge request is already merged or closed - you get 405 and error message
In case the merge request is not set to be merged when the build succeeds, you'll also get a 406 error. In case the merge request is not set to be merged when the build succeeds, you'll also get a 406 error.
``` ```
PUT /projects/:id/merge_request/:merge_request_id/cancel_merge_when_build_succeeds PUT /projects/:id/merge_requests/:merge_request_id/cancel_merge_when_build_succeeds
``` ```
Parameters: Parameters:
...@@ -409,66 +409,6 @@ Parameters: ...@@ -409,66 +409,6 @@ Parameters:
} }
``` ```
## Post comment to MR
Adds a comment to a merge request.
```
POST /projects/:id/merge_request/:merge_request_id/comments
```
Parameters:
- `id` (required) - The ID of a project
- `merge_request_id` (required) - ID of merge request
- `note` (required) - Text of comment
```json
{
"note": "text1"
}
```
## Get the comments on a MR
Gets all the comments associated with a merge request.
```
GET /projects/:id/merge_request/:merge_request_id/comments
```
Parameters:
- `id` (required) - The ID of a project
- `merge_request_id` (required) - ID of merge request
```json
[
{
"note": "this is the 1st comment on the 2merge merge request",
"author": {
"id": 11,
"username": "admin",
"email": "admin@example.com",
"name": "Administrator",
"state": "active",
"created_at": "2014-03-06T08:17:35.000Z"
}
},
{
"note": "Status changed to closed",
"author": {
"id": 11,
"username": "admin",
"email": "admin@example.com",
"name": "Administrator",
"state": "active",
"created_at": "2014-03-06T08:17:35.000Z"
}
}
]
```
## Comments on merge requets ## Comments on merge requets
Comments are done via the notes resource. Comments are done via the [notes](notes.md) resource.
...@@ -41,3 +41,33 @@ Feature: Dashboard ...@@ -41,3 +41,33 @@ Feature: Dashboard
And user with name "John Doe" left project "Shop" And user with name "John Doe" left project "Shop"
When I visit dashboard activity page When I visit dashboard activity page
Then I should see "John Doe left project Shop" event Then I should see "John Doe left project Shop" event
@javascript
Scenario: Sorting Issues
Given I visit dashboard issues page
And I sort the list by "Oldest updated"
And I visit dashboard activity page
And I visit dashboard issues page
Then The list should be sorted by "Oldest updated"
@javascript
Scenario: Visiting Project's issues after sorting
Given I visit dashboard issues page
And I sort the list by "Oldest updated"
And I visit project "Shop" issues page
Then The list should be sorted by "Oldest updated"
@javascript
Scenario: Sorting Merge Requests
Given I visit dashboard merge requests page
And I sort the list by "Oldest updated"
And I visit dashboard activity page
And I visit dashboard merge requests page
Then The list should be sorted by "Oldest updated"
@javascript
Scenario: Visiting Project's merge requests after sorting
Given I visit dashboard merge requests page
And I sort the list by "Oldest updated"
And I visit project "Shop" merge requests page
Then The list should be sorted by "Oldest updated"
...@@ -25,3 +25,18 @@ Feature: Project Fork ...@@ -25,3 +25,18 @@ Feature: Project Fork
Then I should see "New merge request" Then I should see "New merge request"
And I click link "New merge request" And I click link "New merge request"
Then I should see the new merge request page for my namespace Then I should see the new merge request page for my namespace
Scenario: Viewing forks of a Project
Given I click link "Fork"
When I fork to my namespace
And I visit the forks page of the "Shop" project
Then I should see my fork on the list
Scenario: Viewing private forks of a Project
Given There is an existent fork of the "Shop" project
And I click link "Fork"
When I fork to my namespace
And I visit the forks page of the "Shop" project
Then I should see my fork on the list
And I should not see the other fork listed
And I should see a private fork notice
...@@ -59,6 +59,28 @@ Feature: Project Issues ...@@ -59,6 +59,28 @@ Feature: Project Issues
And I sort the list by "Last updated" And I sort the list by "Last updated"
Then I should see "Release 0.4" at the top Then I should see "Release 0.4" at the top
@javascript
Scenario: Visiting Issues after being sorted the list
Given I visit project "Shop" issues page
And I sort the list by "Oldest updated"
And I visit my project's home page
And I visit project "Shop" issues page
Then The list should be sorted by "Oldest updated"
@javascript
Scenario: Visiting Merge Requests after being sorted the list
Given I visit project "Shop" issues page
And I sort the list by "Oldest updated"
And I visit project "Shop" merge requests page
Then The list should be sorted by "Oldest updated"
@javascript
Scenario: Visiting Merge Requests from a differente Project after sorting
Given I visit project "Shop" merge requests page
And I sort the list by "Oldest updated"
And I visit dashboard merge requests page
Then The list should be sorted by "Oldest updated"
@javascript @javascript
Scenario: I search issue Scenario: I search issue
Given I fill in issue search with "Re" Given I fill in issue search with "Re"
......
...@@ -84,6 +84,28 @@ Feature: Project Merge Requests ...@@ -84,6 +84,28 @@ Feature: Project Merge Requests
And I sort the list by "Last updated" And I sort the list by "Last updated"
Then I should see "Bug NS-04" at the top Then I should see "Bug NS-04" at the top
@javascript
Scenario: Visiting Merge Requests after being sorted the list
Given I visit project "Shop" merge requests page
And I sort the list by "Oldest updated"
And I visit my project's home page
And I visit project "Shop" merge requests page
Then The list should be sorted by "Oldest updated"
@javascript
Scenario: Visiting Issues after being sorted the list
Given I visit project "Shop" merge requests page
And I sort the list by "Oldest updated"
And I visit project "Shop" issues page
Then The list should be sorted by "Oldest updated"
@javascript
Scenario: Visiting Merge Requests from a differente Project after sorting
Given I visit project "Shop" merge requests page
And I sort the list by "Oldest updated"
And I visit dashboard merge requests page
Then The list should be sorted by "Oldest updated"
@javascript @javascript
Scenario: Visiting Merge Requests after commenting on diffs Scenario: Visiting Merge Requests after commenting on diffs
Given project "Shop" have "Bug NS-05" open merge request with diffs inside Given project "Shop" have "Bug NS-05" open merge request with diffs inside
......
...@@ -2,6 +2,7 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps ...@@ -2,6 +2,7 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps
include SharedAuthentication include SharedAuthentication
include SharedPaths include SharedPaths
include SharedProject include SharedProject
include SharedIssuable
step 'I should see "New Project" link' do step 'I should see "New Project" link' do
expect(page).to have_link "New project" expect(page).to have_link "New project"
......
...@@ -49,4 +49,29 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps ...@@ -49,4 +49,29 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps
step 'I should see the new merge request page for my namespace' do step 'I should see the new merge request page for my namespace' do
current_path.should have_content(/#{current_user.namespace.name}/i) current_path.should have_content(/#{current_user.namespace.name}/i)
end end
step 'I visit the forks page of the "Shop" project' do
@project = Project.where(name: 'Shop').last
visit namespace_project_forks_path(@project.namespace, @project)
end
step 'I should see my fork on the list' do
page.within('.projects-list-holder') do
project = @user.fork_of(@project)
expect(page).to have_content("#{project.namespace.human_name} / #{project.name}")
end
end
step 'There is an existent fork of the "Shop" project' do
user = create(:user, name: 'Mike')
@forked_project = Projects::ForkService.new(@project, user).execute
end
step 'I should not see the other fork listed' do
expect(page).not_to have_content("#{@forked_project.namespace.human_name} / #{@forked_project.name}")
end
step 'I should see a private fork notice' do
expect(page).to have_content("1 private fork")
end
end end
...@@ -43,8 +43,10 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps ...@@ -43,8 +43,10 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps
expect(page).to have_css("h3.page-title", text: "New Merge Request") expect(page).to have_css("h3.page-title", text: "New Merge Request")
page.within 'form#new_merge_request' do
fill_in "merge_request_title", with: "Merge Request On Forked Project" fill_in "merge_request_title", with: "Merge Request On Forked Project"
end end
end
step 'I submit the merge request' do step 'I submit the merge request' do
click_button "Submit merge request" click_button "Submit merge request"
......
...@@ -106,6 +106,19 @@ module SharedIssuable ...@@ -106,6 +106,19 @@ module SharedIssuable
edit_issuable edit_issuable
end end
step 'I sort the list by "Oldest updated"' do
find('button.dropdown-toggle.btn').click
page.within('ul.dropdown-menu.dropdown-menu-align-right li') do
click_link "Oldest updated"
end
end
step 'The list should be sorted by "Oldest updated"' do
page.within('div.dropdown.inline.prepend-left-10') do
expect(page.find('button.dropdown-toggle.btn')).to have_content('Oldest updated')
end
end
def create_issuable_for_project(project_name:, title:, type: :issue) def create_issuable_for_project(project_name:, title:, type: :issue)
project = Project.find_by(name: project_name) project = Project.find_by(name: project_name)
......
...@@ -59,6 +59,50 @@ module API ...@@ -59,6 +59,50 @@ module API
present paginate(merge_requests), with: Entities::MergeRequest present paginate(merge_requests), with: Entities::MergeRequest
end end
# Create MR
#
# Parameters:
#
# id (required) - The ID of a project - this will be the source of the merge request
# source_branch (required) - The source branch
# target_branch (required) - The target branch
# target_project_id - The target project of the merge request defaults to the :id of the project
# assignee_id - Assignee user ID
# title (required) - Title of MR
# description - Description of MR
# labels (optional) - Labels for MR as a comma-separated list
#
# Example:
# POST /projects/:id/merge_requests
#
post ":id/merge_requests" do
authorize! :create_merge_request, user_project
required_attributes! [:source_branch, :target_branch, :title]
attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :target_project_id, :description]
# Validate label names in advance
if (errors = validate_label_params(params)).any?
render_api_error!({ labels: errors }, 400)
end
merge_request = ::MergeRequests::CreateService.new(user_project, current_user, attrs).execute
if merge_request.valid?
# Find or create labels and attach to issue
if params[:labels].present?
merge_request.add_labels_by_names(params[:labels].split(","))
end
present merge_request, with: Entities::MergeRequest
else
handle_merge_request_errors! merge_request.errors
end
end
# Routing "merge_request/:merge_request_id/..." is DEPRECATED and WILL BE REMOVED in version 9.0
# Use "merge_requests/:merge_request_id/..." instead.
#
[":id/merge_request/:merge_request_id", ":id/merge_requests/:merge_request_id"].each do |path|
# Show MR # Show MR
# #
# Parameters: # Parameters:
...@@ -66,9 +110,9 @@ module API ...@@ -66,9 +110,9 @@ module API
# merge_request_id (required) - The ID of MR # merge_request_id (required) - The ID of MR
# #
# Example: # Example:
# GET /projects/:id/merge_request/:merge_request_id # GET /projects/:id/merge_requests/:merge_request_id
# #
get ":id/merge_request/:merge_request_id" do get path do
merge_request = user_project.merge_requests.find(params[:merge_request_id]) merge_request = user_project.merge_requests.find(params[:merge_request_id])
authorize! :read_merge_request, merge_request authorize! :read_merge_request, merge_request
...@@ -83,9 +127,9 @@ module API ...@@ -83,9 +127,9 @@ module API
# merge_request_id (required) - The ID of MR # merge_request_id (required) - The ID of MR
# #
# Example: # Example:
# GET /projects/:id/merge_request/:merge_request_id/commits # GET /projects/:id/merge_requests/:merge_request_id/commits
# #
get ':id/merge_request/:merge_request_id/commits' do get "#{path}/commits" do
merge_request = user_project.merge_requests. merge_request = user_project.merge_requests.
find(params[:merge_request_id]) find(params[:merge_request_id])
authorize! :read_merge_request, merge_request authorize! :read_merge_request, merge_request
...@@ -99,55 +143,15 @@ module API ...@@ -99,55 +143,15 @@ module API
# merge_request_id (required) - The ID of MR # merge_request_id (required) - The ID of MR
# #
# Example: # Example:
# GET /projects/:id/merge_request/:merge_request_id/changes # GET /projects/:id/merge_requests/:merge_request_id/changes
# #
get ':id/merge_request/:merge_request_id/changes' do get "#{path}/changes" do
merge_request = user_project.merge_requests. merge_request = user_project.merge_requests.
find(params[:merge_request_id]) find(params[:merge_request_id])
authorize! :read_merge_request, merge_request authorize! :read_merge_request, merge_request
present merge_request, with: Entities::MergeRequestChanges present merge_request, with: Entities::MergeRequestChanges
end end
# Create MR
#
# Parameters:
#
# id (required) - The ID of a project - this will be the source of the merge request
# source_branch (required) - The source branch
# target_branch (required) - The target branch
# target_project_id - The target project of the merge request defaults to the :id of the project
# assignee_id - Assignee user ID
# title (required) - Title of MR
# description - Description of MR
# labels (optional) - Labels for MR as a comma-separated list
#
# Example:
# POST /projects/:id/merge_requests
#
post ":id/merge_requests" do
authorize! :create_merge_request, user_project
required_attributes! [:source_branch, :target_branch, :title]
attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :target_project_id, :description]
# Validate label names in advance
if (errors = validate_label_params(params)).any?
render_api_error!({ labels: errors }, 400)
end
merge_request = ::MergeRequests::CreateService.new(user_project, current_user, attrs).execute
if merge_request.valid?
# Find or create labels and attach to issue
if params[:labels].present?
merge_request.add_labels_by_names(params[:labels].split(","))
end
present merge_request, with: Entities::MergeRequest
else
handle_merge_request_errors! merge_request.errors
end
end
# Update MR # Update MR
# #
# Parameters: # Parameters:
...@@ -160,9 +164,9 @@ module API ...@@ -160,9 +164,9 @@ module API
# description - Description of MR # description - Description of MR
# labels (optional) - Labels for a MR as a comma-separated list # labels (optional) - Labels for a MR as a comma-separated list
# Example: # Example:
# PUT /projects/:id/merge_request/:merge_request_id # PUT /projects/:id/merge_requests/:merge_request_id
# #
put ":id/merge_request/:merge_request_id" do put path do
attrs = attributes_for_keys [:target_branch, :assignee_id, :title, :state_event, :description] attrs = attributes_for_keys [:target_branch, :assignee_id, :title, :state_event, :description]
merge_request = user_project.merge_requests.find(params[:merge_request_id]) merge_request = user_project.merge_requests.find(params[:merge_request_id])
authorize! :update_merge_request, merge_request authorize! :update_merge_request, merge_request
...@@ -201,9 +205,9 @@ module API ...@@ -201,9 +205,9 @@ module API
# should_remove_source_branch (optional) - When true, the source branch will be deleted if possible # should_remove_source_branch (optional) - When true, the source branch will be deleted if possible
# merge_when_build_succeeds (optional) - When true, this MR will be merged when the build succeeds # merge_when_build_succeeds (optional) - When true, this MR will be merged when the build succeeds
# Example: # Example:
# PUT /projects/:id/merge_request/:merge_request_id/merge # PUT /projects/:id/merge_requests/:merge_request_id/merge
# #
put ":id/merge_request/:merge_request_id/merge" do put "#{path}/merge" do
merge_request = user_project.merge_requests.find(params[:merge_request_id]) merge_request = user_project.merge_requests.find(params[:merge_request_id])
# Merge request can not be merged # Merge request can not be merged
...@@ -236,7 +240,7 @@ module API ...@@ -236,7 +240,7 @@ module API
# id (required) - The ID of a project # id (required) - The ID of a project
# merge_request_id (required) - ID of MR # merge_request_id (required) - ID of MR
# #
post ":id/merge_request/:merge_request_id/cancel_merge_when_build_succeeds" do post "#{path}/cancel_merge_when_build_succeeds" do
merge_request = user_project.merge_requests.find(params[:merge_request_id]) merge_request = user_project.merge_requests.find(params[:merge_request_id])
unauthorized! unless merge_request.can_cancel_merge_when_build_succeeds?(current_user) unauthorized! unless merge_request.can_cancel_merge_when_build_succeeds?(current_user)
...@@ -244,15 +248,18 @@ module API ...@@ -244,15 +248,18 @@ module API
::MergeRequest::MergeWhenBuildSucceedsService.new(merge_request.target_project, current_user).cancel(merge_request) ::MergeRequest::MergeWhenBuildSucceedsService.new(merge_request.target_project, current_user).cancel(merge_request)
end end
# Duplicate. DEPRECATED and WILL BE REMOVED in 9.0.
# Use GET "/projects/:id/merge_requests/:merge_request_id/notes" instead
#
# Get a merge request's comments # Get a merge request's comments
# #
# Parameters: # Parameters:
# id (required) - The ID of a project # id (required) - The ID of a project
# merge_request_id (required) - ID of MR # merge_request_id (required) - ID of MR
# Examples: # Examples:
# GET /projects/:id/merge_request/:merge_request_id/comments # GET /projects/:id/merge_requests/:merge_request_id/comments
# #
get ":id/merge_request/:merge_request_id/comments" do get "#{path}/comments" do
merge_request = user_project.merge_requests.find(params[:merge_request_id]) merge_request = user_project.merge_requests.find(params[:merge_request_id])
authorize! :read_merge_request, merge_request authorize! :read_merge_request, merge_request
...@@ -260,6 +267,9 @@ module API ...@@ -260,6 +267,9 @@ module API
present paginate(merge_request.notes.fresh), with: Entities::MRNote present paginate(merge_request.notes.fresh), with: Entities::MRNote
end end
# Duplicate. DEPRECATED and WILL BE REMOVED in 9.0.
# Use POST "/projects/:id/merge_requests/:merge_request_id/notes" instead
#
# Post comment to merge request # Post comment to merge request
# #
# Parameters: # Parameters:
...@@ -267,9 +277,9 @@ module API ...@@ -267,9 +277,9 @@ module API
# merge_request_id (required) - ID of MR # merge_request_id (required) - ID of MR
# note (required) - Text of comment # note (required) - Text of comment
# Examples: # Examples:
# POST /projects/:id/merge_request/:merge_request_id/comments # POST /projects/:id/merge_requests/:merge_request_id/comments
# #
post ":id/merge_request/:merge_request_id/comments" do post "#{path}/comments" do
required_attributes! [:note] required_attributes! [:note]
merge_request = user_project.merge_requests.find(params[:merge_request_id]) merge_request = user_project.merge_requests.find(params[:merge_request_id])
...@@ -292,4 +302,5 @@ module API ...@@ -292,4 +302,5 @@ module API
end end
end end
end end
end
end end
...@@ -4,11 +4,14 @@ module Gitlab ...@@ -4,11 +4,14 @@ module Gitlab
key = :current_application_settings key = :current_application_settings
RequestStore.store[key] ||= begin RequestStore.store[key] ||= begin
settings = nil
if connect_to_db? if connect_to_db?
ApplicationSetting.current || ApplicationSetting.create_from_defaults settings = ApplicationSetting.current
else settings ||= ApplicationSetting.create_from_defaults unless ActiveRecord::Migrator.needs_migration?
fake_application_settings
end end
settings || fake_application_settings
end end
end end
...@@ -18,27 +21,31 @@ module Gitlab ...@@ -18,27 +21,31 @@ module Gitlab
default_branch_protection: Settings.gitlab['default_branch_protection'], default_branch_protection: Settings.gitlab['default_branch_protection'],
signup_enabled: Settings.gitlab['signup_enabled'], signup_enabled: Settings.gitlab['signup_enabled'],
signin_enabled: Settings.gitlab['signin_enabled'], signin_enabled: Settings.gitlab['signin_enabled'],
twitter_sharing_enabled: Settings.gitlab['twitter_sharing_enabled'],
gravatar_enabled: Settings.gravatar['enabled'], gravatar_enabled: Settings.gravatar['enabled'],
sign_in_text: Settings.extra['sign_in_text'], sign_in_text: Settings.extra['sign_in_text'],
restricted_visibility_levels: Settings.gitlab['restricted_visibility_levels'], restricted_visibility_levels: Settings.gitlab['restricted_visibility_levels'],
max_attachment_size: Settings.gitlab['max_attachment_size'], max_attachment_size: Settings.gitlab['max_attachment_size'],
session_expire_delay: Settings.gitlab['session_expire_delay'], session_expire_delay: Settings.gitlab['session_expire_delay'],
import_sources: Settings.gitlab['import_sources'], default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'],
default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'],
restricted_signup_domains: Settings.gitlab['restricted_signup_domains'],
import_sources: ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git'],
shared_runners_enabled: Settings.gitlab_ci['shared_runners_enabled'], shared_runners_enabled: Settings.gitlab_ci['shared_runners_enabled'],
max_artifacts_size: Settings.artifacts['max_size'], max_artifacts_size: Settings.artifacts['max_size'],
require_two_factor_authentication: false,
two_factor_grace_period: 48
) )
end end
private private
def connect_to_db? def connect_to_db?
use_db = if ENV['USE_DB'] == "false" # When the DBMS is not available, an exception (e.g. PG::ConnectionBad) is raised
false active_db_connection = ActiveRecord::Base.connection.active? rescue false
else
true
end
use_db && ActiveRecord::Base.connection.active? && ENV['USE_DB'] != 'false' &&
active_db_connection &&
ActiveRecord::Base.connection.table_exists?('application_settings') ActiveRecord::Base.connection.table_exists?('application_settings')
rescue ActiveRecord::NoDatabaseError rescue ActiveRecord::NoDatabaseError
......
...@@ -109,9 +109,9 @@ describe API::API, api: true do ...@@ -109,9 +109,9 @@ describe API::API, api: true do
end end
end end
describe "GET /projects/:id/merge_request/:merge_request_id" do describe "GET /projects/:id/merge_requests/:merge_request_id" do
it "should return merge_request" do it "should return merge_request" do
get api("/projects/#{project.id}/merge_request/#{merge_request.id}", user) get api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user)
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(json_response['title']).to eq(merge_request.title) expect(json_response['title']).to eq(merge_request.title)
expect(json_response['iid']).to eq(merge_request.iid) expect(json_response['iid']).to eq(merge_request.iid)
...@@ -126,14 +126,14 @@ describe API::API, api: true do ...@@ -126,14 +126,14 @@ describe API::API, api: true do
end end
it "should return a 404 error if merge_request_id not found" do it "should return a 404 error if merge_request_id not found" do
get api("/projects/#{project.id}/merge_request/999", user) get api("/projects/#{project.id}/merge_requests/999", user)
expect(response.status).to eq(404) expect(response.status).to eq(404)
end end
end end
describe 'GET /projects/:id/merge_request/:merge_request_id/commits' do describe 'GET /projects/:id/merge_requests/:merge_request_id/commits' do
context 'valid merge request' do context 'valid merge request' do
before { get api("/projects/#{project.id}/merge_request/#{merge_request.id}/commits", user) } before { get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/commits", user) }
let(:commit) { merge_request.commits.first } let(:commit) { merge_request.commits.first }
it { expect(response.status).to eq 200 } it { expect(response.status).to eq 200 }
...@@ -143,20 +143,20 @@ describe API::API, api: true do ...@@ -143,20 +143,20 @@ describe API::API, api: true do
end end
it 'returns a 404 when merge_request_id not found' do it 'returns a 404 when merge_request_id not found' do
get api("/projects/#{project.id}/merge_request/999/commits", user) get api("/projects/#{project.id}/merge_requests/999/commits", user)
expect(response.status).to eq(404) expect(response.status).to eq(404)
end end
end end
describe 'GET /projects/:id/merge_request/:merge_request_id/changes' do describe 'GET /projects/:id/merge_requests/:merge_request_id/changes' do
it 'should return the change information of the merge_request' do it 'should return the change information of the merge_request' do
get api("/projects/#{project.id}/merge_request/#{merge_request.id}/changes", user) get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/changes", user)
expect(response.status).to eq 200 expect(response.status).to eq 200
expect(json_response['changes'].size).to eq(merge_request.diffs.size) expect(json_response['changes'].size).to eq(merge_request.diffs.size)
end end
it 'returns a 404 when merge_request_id not found' do it 'returns a 404 when merge_request_id not found' do
get api("/projects/#{project.id}/merge_request/999/changes", user) get api("/projects/#{project.id}/merge_requests/999/changes", user)
expect(response.status).to eq(404) expect(response.status).to eq(404)
end end
end end
...@@ -311,19 +311,19 @@ describe API::API, api: true do ...@@ -311,19 +311,19 @@ describe API::API, api: true do
end end
end end
describe "PUT /projects/:id/merge_request/:merge_request_id to close MR" do describe "PUT /projects/:id/merge_requests/:merge_request_id to close MR" do
it "should return merge_request" do it "should return merge_request" do
put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), state_event: "close" put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), state_event: "close"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(json_response['state']).to eq('closed') expect(json_response['state']).to eq('closed')
end end
end end
describe "PUT /projects/:id/merge_request/:merge_request_id/merge" do describe "PUT /projects/:id/merge_requests/:merge_request_id/merge" do
let(:ci_commit) { create(:ci_commit_without_jobs) } let(:ci_commit) { create(:ci_commit_without_jobs) }
it "should return merge_request in case of success" do it "should return merge_request in case of success" do
put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user) put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
expect(response.status).to eq(200) expect(response.status).to eq(200)
end end
...@@ -332,7 +332,7 @@ describe API::API, api: true do ...@@ -332,7 +332,7 @@ describe API::API, api: true do
allow_any_instance_of(MergeRequest). allow_any_instance_of(MergeRequest).
to receive(:can_be_merged?).and_return(false) to receive(:can_be_merged?).and_return(false)
put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user) put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
expect(response.status).to eq(406) expect(response.status).to eq(406)
expect(json_response['message']).to eq('Branch cannot be merged') expect(json_response['message']).to eq('Branch cannot be merged')
...@@ -340,14 +340,14 @@ describe API::API, api: true do ...@@ -340,14 +340,14 @@ describe API::API, api: true do
it "should return 405 if merge_request is not open" do it "should return 405 if merge_request is not open" do
merge_request.close merge_request.close
put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user) put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
expect(response.status).to eq(405) expect(response.status).to eq(405)
expect(json_response['message']).to eq('405 Method Not Allowed') expect(json_response['message']).to eq('405 Method Not Allowed')
end end
it "should return 405 if merge_request is a work in progress" do it "should return 405 if merge_request is a work in progress" do
merge_request.update_attribute(:title, "WIP: #{merge_request.title}") merge_request.update_attribute(:title, "WIP: #{merge_request.title}")
put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user) put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
expect(response.status).to eq(405) expect(response.status).to eq(405)
expect(json_response['message']).to eq('405 Method Not Allowed') expect(json_response['message']).to eq('405 Method Not Allowed')
end end
...@@ -355,7 +355,7 @@ describe API::API, api: true do ...@@ -355,7 +355,7 @@ describe API::API, api: true do
it "should return 401 if user has no permissions to merge" do it "should return 401 if user has no permissions to merge" do
user2 = create(:user) user2 = create(:user)
project.team << [user2, :reporter] project.team << [user2, :reporter]
put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user2) put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user2)
expect(response.status).to eq(401) expect(response.status).to eq(401)
expect(json_response['message']).to eq('401 Unauthorized') expect(json_response['message']).to eq('401 Unauthorized')
end end
...@@ -364,7 +364,7 @@ describe API::API, api: true do ...@@ -364,7 +364,7 @@ describe API::API, api: true do
allow_any_instance_of(MergeRequest).to receive(:ci_commit).and_return(ci_commit) allow_any_instance_of(MergeRequest).to receive(:ci_commit).and_return(ci_commit)
allow(ci_commit).to receive(:active?).and_return(true) allow(ci_commit).to receive(:active?).and_return(true)
put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user), merge_when_build_succeeds: true put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user), merge_when_build_succeeds: true
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(json_response['title']).to eq('Test') expect(json_response['title']).to eq('Test')
...@@ -372,33 +372,33 @@ describe API::API, api: true do ...@@ -372,33 +372,33 @@ describe API::API, api: true do
end end
end end
describe "PUT /projects/:id/merge_request/:merge_request_id" do describe "PUT /projects/:id/merge_requests/:merge_request_id" do
it "should return merge_request" do it "should return merge_request" do
put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), title: "New title" put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), title: "New title"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(json_response['title']).to eq('New title') expect(json_response['title']).to eq('New title')
end end
it "should return merge_request" do it "should return merge_request" do
put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), description: "New description" put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), description: "New description"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(json_response['description']).to eq('New description') expect(json_response['description']).to eq('New description')
end end
it "should return 400 when source_branch is specified" do it "should return 400 when source_branch is specified" do
put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user),
source_branch: "master", target_branch: "master" source_branch: "master", target_branch: "master"
expect(response.status).to eq(400) expect(response.status).to eq(400)
end end
it "should return merge_request with renamed target_branch" do it "should return merge_request with renamed target_branch" do
put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), target_branch: "wiki" put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), target_branch: "wiki"
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(json_response['target_branch']).to eq('wiki') expect(json_response['target_branch']).to eq('wiki')
end end
it 'should return 400 on invalid label names' do it 'should return 400 on invalid label names' do
put api("/projects/#{project.id}/merge_request/#{merge_request.id}", put api("/projects/#{project.id}/merge_requests/#{merge_request.id}",
user), user),
title: 'new issue', title: 'new issue',
labels: 'label, ?' labels: 'label, ?'
...@@ -407,11 +407,11 @@ describe API::API, api: true do ...@@ -407,11 +407,11 @@ describe API::API, api: true do
end end
end end
describe "POST /projects/:id/merge_request/:merge_request_id/comments" do describe "POST /projects/:id/merge_requests/:merge_request_id/comments" do
it "should return comment" do it "should return comment" do
original_count = merge_request.notes.size original_count = merge_request.notes.size
post api("/projects/#{project.id}/merge_request/#{merge_request.id}/comments", user), note: "My comment" post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/comments", user), note: "My comment"
expect(response.status).to eq(201) expect(response.status).to eq(201)
expect(json_response['note']).to eq('My comment') expect(json_response['note']).to eq('My comment')
expect(json_response['author']['name']).to eq(user.name) expect(json_response['author']['name']).to eq(user.name)
...@@ -420,20 +420,20 @@ describe API::API, api: true do ...@@ -420,20 +420,20 @@ describe API::API, api: true do
end end
it "should return 400 if note is missing" do it "should return 400 if note is missing" do
post api("/projects/#{project.id}/merge_request/#{merge_request.id}/comments", user) post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/comments", user)
expect(response.status).to eq(400) expect(response.status).to eq(400)
end end
it "should return 404 if note is attached to non existent merge request" do it "should return 404 if note is attached to non existent merge request" do
post api("/projects/#{project.id}/merge_request/404/comments", user), post api("/projects/#{project.id}/merge_requests/404/comments", user),
note: 'My comment' note: 'My comment'
expect(response.status).to eq(404) expect(response.status).to eq(404)
end end
end end
describe "GET :id/merge_request/:merge_request_id/comments" do describe "GET :id/merge_requests/:merge_request_id/comments" do
it "should return merge_request comments ordered by created_at" do it "should return merge_request comments ordered by created_at" do
get api("/projects/#{project.id}/merge_request/#{merge_request.id}/comments", user) get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/comments", user)
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(json_response).to be_an Array expect(json_response).to be_an Array
expect(json_response.length).to eq(2) expect(json_response.length).to eq(2)
...@@ -443,7 +443,7 @@ describe API::API, api: true do ...@@ -443,7 +443,7 @@ describe API::API, api: true do
end end
it "should return a 404 error if merge_request_id not found" do it "should return a 404 error if merge_request_id not found" do
get api("/projects/#{project.id}/merge_request/999/comments", user) get api("/projects/#{project.id}/merge_requests/999/comments", user)
expect(response.status).to eq(404) expect(response.status).to eq(404)
end end
end end
......
...@@ -496,11 +496,11 @@ end ...@@ -496,11 +496,11 @@ end
describe Projects::ForksController, 'routing' do describe Projects::ForksController, 'routing' do
it 'to #new' do it 'to #new' do
expect(get('/gitlab/gitlabhq/fork/new')).to route_to('projects/forks#new', namespace_id: 'gitlab', project_id: 'gitlabhq') expect(get('/gitlab/gitlabhq/forks/new')).to route_to('projects/forks#new', namespace_id: 'gitlab', project_id: 'gitlabhq')
end end
it 'to #create' do it 'to #create' do
expect(post('/gitlab/gitlabhq/fork')).to route_to('projects/forks#create', namespace_id: 'gitlab', project_id: 'gitlabhq') expect(post('/gitlab/gitlabhq/forks')).to route_to('projects/forks#create', namespace_id: 'gitlab', project_id: 'gitlabhq')
end end
end end
......
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