Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into category-search-dropdown
This commit is contained in:
commit
639347bad4
16 changed files with 258 additions and 122 deletions
|
@ -56,6 +56,8 @@ v 8.9.0 (unreleased)
|
|||
- RepositoryCheck::SingleRepositoryWorker public and private methods are now instrumented
|
||||
- Improve issuables APIs performance when accessing notes !4471
|
||||
- External links now open in a new tab
|
||||
- Markdown editor now correctly resets the input value on edit cancellation !4175
|
||||
- Toggling a task list item in a issue/mr description does not creates a Todo for mentions
|
||||
|
||||
v 8.8.4 (unreleased)
|
||||
- Ensure branch cleanup regardless of whether the GitHub import process succeeds
|
||||
|
@ -68,7 +70,6 @@ v 8.8.4 (unreleased)
|
|||
- Fix importer for GitHub comments on diff
|
||||
- Disable Webhooks before proceeding with the GitHub import
|
||||
- Added descriptions to notification settings dropdown
|
||||
- Markdown editor now correctly resets the input value on edit cancellation !4175
|
||||
|
||||
v 8.8.3
|
||||
- Fix 404 page when viewing TODOs that contain milestones or labels in different projects. !4312
|
||||
|
@ -180,6 +181,7 @@ v 8.8.0
|
|||
- Fixed advice on invalid permissions on upload path !2948 (Ludovic Perrine)
|
||||
- Allows MR authors to have the source branch removed when merging the MR. !2801 (Jeroen Jacobs)
|
||||
- When creating a .gitignore file a dropdown with templates will be provided
|
||||
- Shows the issue/MR list search/filter form and corrects the mobile styling for guest users. #17562
|
||||
|
||||
v 8.7.7
|
||||
- Fix import by `Any Git URL` broken if the URL contains a space
|
||||
|
|
|
@ -226,6 +226,10 @@ $ ->
|
|||
form = btn.closest("form")
|
||||
new ConfirmDangerModal(form, text)
|
||||
|
||||
|
||||
$(document).on 'click', 'button', ->
|
||||
$(this).blur()
|
||||
|
||||
$('input[type="search"]').each ->
|
||||
$this = $(this)
|
||||
$this.attr 'value', $this.val()
|
||||
|
|
|
@ -19,3 +19,8 @@ class @Subscription
|
|||
action = if status == 'subscribed' then 'Unsubscribe' else 'Subscribe'
|
||||
btn.find('span').text(action)
|
||||
@subscription_status.find('>div').toggleClass('hidden')
|
||||
|
||||
if btn.attr('data-original-title')
|
||||
btn.tooltip('hide')
|
||||
.attr('data-original-title', action)
|
||||
.tooltip('fixTitle')
|
||||
|
|
|
@ -171,6 +171,7 @@
|
|||
> form {
|
||||
display: inline-block;
|
||||
margin-top: -1px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.icon-label {
|
||||
|
@ -207,7 +208,7 @@
|
|||
|
||||
@media (max-width: $screen-xs-max) {
|
||||
padding-bottom: 0;
|
||||
|
||||
width: 100%;
|
||||
.btn, form, .dropdown, .dropdown-menu-toggle, .form-control {
|
||||
margin: 0 0 10px;
|
||||
display: block;
|
||||
|
@ -238,16 +239,6 @@
|
|||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Small devices (tablets, 768px and lower) */
|
||||
@media (max-width: $screen-sm-max) {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
|
||||
input {
|
||||
width: 300px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,11 +50,26 @@
|
|||
|
||||
.label-row {
|
||||
.label-name {
|
||||
display: inline-block;
|
||||
width: 170px;
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
display: block;
|
||||
@media (min-width: $screen-sm-min) {
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.label-description {
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
|
||||
@media (min-width: $screen-sm-min) {
|
||||
display: inline-block;
|
||||
width: 40%;
|
||||
margin-left: 10px;
|
||||
margin-bottom: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,10 +83,6 @@
|
|||
padding: 3px 4px;
|
||||
}
|
||||
|
||||
.label-subscription {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.dropdown-labels-error {
|
||||
padding: 5px 10px;
|
||||
margin-bottom: 10px;
|
||||
|
@ -79,62 +90,27 @@
|
|||
color: $white-light;
|
||||
}
|
||||
|
||||
@mixin labels-mobile {
|
||||
@media (max-width: $screen-xs-min) {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
padding: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.manage-labels-list {
|
||||
.btn-action {
|
||||
color: $gl-dark-link-color;
|
||||
|
||||
.prepend-left-10, .prepend-description-left {
|
||||
display: inline-block;
|
||||
width: 40%;
|
||||
vertical-align: middle;
|
||||
.fa {
|
||||
font-size: 18px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@include labels-mobile;
|
||||
&:hover {
|
||||
color: $gl-link-color;
|
||||
|
||||
&.remove-row {
|
||||
color: $gl-danger;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.prepend-description-left {
|
||||
width: 57%;
|
||||
|
||||
@include labels-mobile;
|
||||
}
|
||||
|
||||
.pull-info-right {
|
||||
float: right;
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
float: none;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
border-color: transparent;
|
||||
padding: 6px;
|
||||
color: $gl-text-color;
|
||||
|
||||
&.label-subscribe-button {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
color: $gl-text-color;
|
||||
}
|
||||
|
||||
.append-right-20 {
|
||||
a {
|
||||
color: $gl-text-color;
|
||||
}
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.dropdown {
|
||||
@media (min-width: $screen-sm-min) {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,3 +162,23 @@
|
|||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.label-options-toggle {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.label-subscribe-button {
|
||||
.label-subscribe-button-loading {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
.label-subscribe-button-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.label-subscribe-button-loading {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ module LabelsHelper
|
|||
# link_to_label(label) { "My Custom Label Text" }
|
||||
#
|
||||
# Returns a String
|
||||
def link_to_label(label, project: nil, type: :issue, tooltip: true, &block)
|
||||
def link_to_label(label, project: nil, type: :issue, tooltip: true, css_class: nil, &block)
|
||||
project ||= @project || label.project
|
||||
link = send("namespace_project_#{type.to_s.pluralize}_path",
|
||||
project.namespace,
|
||||
|
@ -40,9 +40,9 @@ module LabelsHelper
|
|||
label_name: [label.name])
|
||||
|
||||
if block_given?
|
||||
link_to link, &block
|
||||
link_to link, class: css_class, &block
|
||||
else
|
||||
link_to render_colored_label(label, tooltip: tooltip), link
|
||||
link_to render_colored_label(label, tooltip: tooltip), link, class: css_class
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ class TodoService
|
|||
# * mark all pending todos related to the issue for the current user as done
|
||||
#
|
||||
def update_issue(issue, current_user)
|
||||
create_mention_todos(issue.project, issue, current_user)
|
||||
update_issuable(issue, current_user)
|
||||
end
|
||||
|
||||
# When close an issue we should:
|
||||
|
@ -53,7 +53,7 @@ class TodoService
|
|||
# * create a todo for each mentioned user on merge request
|
||||
#
|
||||
def update_merge_request(merge_request, current_user)
|
||||
create_mention_todos(merge_request.project, merge_request, current_user)
|
||||
update_issuable(merge_request, current_user)
|
||||
end
|
||||
|
||||
# When close a merge request we should:
|
||||
|
@ -153,6 +153,13 @@ class TodoService
|
|||
create_mention_todos(issuable.project, issuable, author)
|
||||
end
|
||||
|
||||
def update_issuable(issuable, author)
|
||||
# Skip toggling a task list item in a description
|
||||
return if issuable.tasks? && issuable.updated_tasks.any?
|
||||
|
||||
create_mention_todos(issuable.project, issuable, author)
|
||||
end
|
||||
|
||||
def handle_note(note, author)
|
||||
# Skip system notes, and notes on project snippet
|
||||
return if note.system? || note.for_snippet?
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
- if @user.two_factor_otp_enabled?
|
||||
%h5 Authenticate via Two-Factor App
|
||||
= form_for(resource, as: resource_name, url: session_path(resource_name), method: :post) do |f|
|
||||
= f.hidden_field :remember_me, value: params[resource_name][:remember_me]
|
||||
- resource_params = params[resource_name].presence || params
|
||||
= f.hidden_field :remember_me, value: resource_params.fetch(:remember_me, 0)
|
||||
= f.text_field :otp_attempt, class: 'form-control', placeholder: 'Two-Factor Authentication code', required: true, autofocus: true, autocomplete: 'off'
|
||||
%p.help-block.hint Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes.
|
||||
.prepend-top-20
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
= icon('rss')
|
||||
%span.icon-label
|
||||
Subscribe
|
||||
= render 'shared/issuable/search_form', path: namespace_project_issues_path(@project.namespace, @project)
|
||||
= render 'shared/issuable/search_form', path: namespace_project_issues_path(@project.namespace, @project)
|
||||
- if can? current_user, :create_issue, @project
|
||||
= link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { assignee_id: @issuable_finder.assignee.try(:id), milestone_id: @issuable_finder.milestones.try(:first).try(:id) }), class: "btn btn-new", title: "New Issue", id: "new_issue_link" do
|
||||
New Issue
|
||||
|
|
|
@ -1,28 +1,50 @@
|
|||
- label_css_id = dom_id(label)
|
||||
%li{id: label_css_id, data: { id: label.id } }
|
||||
= render "shared/label_row", label: label
|
||||
.pull-info-right
|
||||
%span.append-right-20
|
||||
= link_to_label(label, type: :merge_request) do
|
||||
= pluralize label.open_merge_requests_count, 'merge request'
|
||||
|
||||
%span.append-right-20
|
||||
= link_to_label(label) do
|
||||
= pluralize label.open_issues_count(current_user), 'open issue'
|
||||
.visible-xs.visible-sm-inline-block.visible-md-inline-block.dropdown
|
||||
%button.btn.btn-default.label-options-toggle{ data: { toggle: "dropdown" } }
|
||||
Options
|
||||
%span.caret
|
||||
.dropdown-menu.dropdown-menu-align-right
|
||||
%ul
|
||||
%li
|
||||
= link_to_label(label, type: :merge_request) do
|
||||
= pluralize label.open_merge_requests_count, 'merge request'
|
||||
%li
|
||||
= link_to_label(label) do
|
||||
= pluralize label.open_issues_count(current_user), 'open issue'
|
||||
- if current_user
|
||||
%li.label-subscription{ data: { url: toggle_subscription_namespace_project_label_path(@project.namespace, @project, label) } }
|
||||
%a.js-subscribe-button.label-subscribe-button.subscription-status{ role: "button", href: "#", data: { toggle: "tooltip", status: label_subscription_status(label) } }
|
||||
%span= label_subscription_toggle_button_text(label)
|
||||
- if can? current_user, :admin_label, @project
|
||||
%li
|
||||
= link_to "Edit", edit_namespace_project_label_path(@project.namespace, @project, label)
|
||||
%li
|
||||
= link_to "Delete", namespace_project_label_path(@project.namespace, @project, label), title: "Delete", method: :delete, remote: true, data: {confirm: "Remove this label? Are you sure?"}
|
||||
|
||||
.pull-right.hidden-xs.hidden-sm.hidden-md
|
||||
= link_to_label(label, type: :merge_request, css_class: 'btn btn-transparent btn-action') do
|
||||
= pluralize label.open_merge_requests_count, 'merge request'
|
||||
= link_to_label(label, css_class: 'btn btn-transparent btn-action') do
|
||||
= pluralize label.open_issues_count(current_user), 'open issue'
|
||||
|
||||
- if current_user
|
||||
.label-subscription{ data: { url: toggle_subscription_namespace_project_label_path(@project.namespace, @project, label) } }
|
||||
.subscription-status{ data: { status: label_subscription_status(label) } }
|
||||
.label-subscription.inline{ data: { url: toggle_subscription_namespace_project_label_path(@project.namespace, @project, label) } }
|
||||
%button.js-subscribe-button.label-subscribe-button.btn.btn-transparent.btn-action.subscription-status{ type: "button", title: label_subscription_toggle_button_text(label), data: { toggle: "tooltip", status: label_subscription_status(label) } }
|
||||
%span.sr-only= label_subscription_toggle_button_text(label)
|
||||
= icon('eye', class: 'label-subscribe-button-icon')
|
||||
= icon('spinner spin', class: 'label-subscribe-button-loading')
|
||||
|
||||
%button.js-subscribe-button.label-subscribe-button.btn.action-buttons{ type: "button", data: { toggle: "tooltip" } }
|
||||
%span= label_subscription_toggle_button_text(label)
|
||||
- if can? current_user, :admin_label, @project
|
||||
= link_to edit_namespace_project_label_path(@project.namespace, @project, label), title: "Edit", class: 'btn btn-transparent btn-action', data: {toggle: "tooltip"} do
|
||||
%span.sr-only Edit
|
||||
= icon('pencil-square-o')
|
||||
= link_to namespace_project_label_path(@project.namespace, @project, label), title: "Delete", class: 'btn btn-transparent btn-action remove-row', method: :delete, remote: true, data: {confirm: "Remove this label? Are you sure?", toggle: "tooltip"} do
|
||||
%span.sr-only Delete
|
||||
= icon('trash-o')
|
||||
|
||||
- if can?(current_user, :admin_label, @project)
|
||||
= link_to edit_namespace_project_label_path(@project.namespace, @project, label), title: "Edit", class: 'btn action-buttons', data: { toggle: 'tooltip' } do
|
||||
%i.fa.fa-pencil-square-o
|
||||
= link_to namespace_project_label_path(@project.namespace, @project, label), title: "Delete", class: 'btn action-buttons remove-row', method: :delete, remote: true, data: { confirm: 'Remove this label? Are you sure?', toggle: 'tooltip' } do
|
||||
%i.fa.fa-trash-o
|
||||
|
||||
- if current_user
|
||||
:javascript
|
||||
new Subscription('##{label_css_id} .label-subscription');
|
||||
- if current_user
|
||||
:javascript
|
||||
new Subscription('##{dom_id(label)} .label-subscription');
|
||||
|
|
|
@ -8,5 +8,6 @@
|
|||
= icon('star')
|
||||
%span.label-name
|
||||
= link_to_label(label, tooltip: false)
|
||||
%span.prepend-left-10
|
||||
= markdown(label.description, pipeline: :single_line)
|
||||
- if label.description
|
||||
%span.label-description
|
||||
= markdown(label.description, pipeline: :single_line)
|
||||
|
|
|
@ -442,22 +442,6 @@ Rails.application.routes.draw do
|
|||
resources(:projects, constraints: { id: /[a-zA-Z.0-9_\-]+(?<!\.atom)/ }, except:
|
||||
[:new, :create, :index], path: "/") do
|
||||
|
||||
# Allow /info/refs, /info/refs?service=git-upload-pack, and
|
||||
# /info/refs?service=git-receive-pack, but nothing else.
|
||||
#
|
||||
git_http_handshake = lambda do |request|
|
||||
request.query_string.blank? ||
|
||||
request.query_string.match(/\Aservice=git-(upload|receive)-pack\z/)
|
||||
end
|
||||
|
||||
ref_redirect = redirect do |params, request|
|
||||
path = "#{params[:namespace_id]}/#{params[:project_id]}.git/info/refs"
|
||||
path << "?#{request.query_string}" unless request.query_string.blank?
|
||||
path
|
||||
end
|
||||
|
||||
get '/info/refs', constraints: git_http_handshake, to: ref_redirect
|
||||
|
||||
member do
|
||||
put :transfer
|
||||
delete :remove_fork
|
||||
|
@ -472,12 +456,28 @@ Rails.application.routes.draw do
|
|||
|
||||
scope module: :projects do
|
||||
# Git HTTP clients ('git clone' etc.)
|
||||
scope constraints: { format: /(git|wiki\.git)/ } do
|
||||
scope constraints: { id: /.+\.git/, format: nil } do
|
||||
get '/info/refs', to: 'git_http#info_refs'
|
||||
post '/git-upload-pack', to: 'git_http#git_upload_pack'
|
||||
post '/git-receive-pack', to: 'git_http#git_receive_pack'
|
||||
end
|
||||
|
||||
# Allow /info/refs, /info/refs?service=git-upload-pack, and
|
||||
# /info/refs?service=git-receive-pack, but nothing else.
|
||||
#
|
||||
git_http_handshake = lambda do |request|
|
||||
request.query_string.blank? ||
|
||||
request.query_string.match(/\Aservice=git-(upload|receive)-pack\z/)
|
||||
end
|
||||
|
||||
ref_redirect = redirect do |params, request|
|
||||
path = "#{params[:namespace_id]}/#{params[:project_id]}.git/info/refs"
|
||||
path << "?#{request.query_string}" unless request.query_string.blank?
|
||||
path
|
||||
end
|
||||
|
||||
get '/info/refs', constraints: git_http_handshake, to: ref_redirect
|
||||
|
||||
# Blob routes:
|
||||
get '/new/*id', to: 'blob#new', constraints: { id: /.+/ }, as: 'new_blob'
|
||||
post '/create/*id', to: 'blob#create', constraints: { id: /.+/ }, as: 'create_blob'
|
||||
|
|
|
@ -9,7 +9,7 @@ class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps
|
|||
|
||||
step 'I remove label \'bug\'' do
|
||||
page.within "#label_#{bug_label.id}" do
|
||||
click_link 'Delete'
|
||||
first(:link, 'Delete').click
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -29,6 +29,6 @@ class Spinach::Features::Labels < Spinach::FeatureSteps
|
|||
private
|
||||
|
||||
def subscribe_button
|
||||
first('.label-subscribe-button span')
|
||||
first('.js-subscribe-button', visible: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@ require "spec_helper"
|
|||
|
||||
describe 'Git HTTP requests', lib: true do
|
||||
let(:user) { create(:user) }
|
||||
let(:project) { create(:project) }
|
||||
let(:project) { create(:project, path: 'project.git-project') }
|
||||
|
||||
it "gives WWW-Authenticate hints" do
|
||||
clone_get('doesnt/exist.git')
|
||||
|
@ -268,6 +268,87 @@ describe 'Git HTTP requests', lib: true do
|
|||
end
|
||||
end
|
||||
|
||||
context "when the project path doesn't end in .git" do
|
||||
context "GET info/refs" do
|
||||
let(:path) { "/#{project.path_with_namespace}/info/refs" }
|
||||
|
||||
context "when no params are added" do
|
||||
before { get path }
|
||||
|
||||
it "redirects to the .git suffix version" do
|
||||
expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs")
|
||||
end
|
||||
end
|
||||
|
||||
context "when the upload-pack service is requested" do
|
||||
let(:params) { { service: 'git-upload-pack' } }
|
||||
before { get path, params }
|
||||
|
||||
it "redirects to the .git suffix version" do
|
||||
expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs?service=#{params[:service]}")
|
||||
end
|
||||
end
|
||||
|
||||
context "when the receive-pack service is requested" do
|
||||
let(:params) { { service: 'git-receive-pack' } }
|
||||
before { get path, params }
|
||||
|
||||
it "redirects to the .git suffix version" do
|
||||
expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs?service=#{params[:service]}")
|
||||
end
|
||||
end
|
||||
|
||||
context "when the params are anything else" do
|
||||
let(:params) { { service: 'git-implode-pack' } }
|
||||
before { get path, params }
|
||||
|
||||
it "redirects to the sign-in page" do
|
||||
expect(response).to redirect_to(new_user_session_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "POST git-upload-pack" do
|
||||
it "fails to find a route" do
|
||||
expect { clone_post(project.path_with_namespace) }.to raise_error(ActionController::RoutingError)
|
||||
end
|
||||
end
|
||||
|
||||
context "POST git-receive-pack" do
|
||||
it "failes to find a route" do
|
||||
expect { push_post(project.path_with_namespace) }.to raise_error(ActionController::RoutingError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "retrieving an info/refs file" do
|
||||
before { project.update_attribute(:visibility_level, Project::PUBLIC) }
|
||||
|
||||
context "when the file exists" do
|
||||
before do
|
||||
# Provide a dummy file in its place
|
||||
allow_any_instance_of(Repository).to receive(:blob_at).and_call_original
|
||||
allow_any_instance_of(Repository).to receive(:blob_at).with('5937ac0a7beb003549fc5fd26fc247adbce4a52e', 'info/refs') do
|
||||
Gitlab::Git::Blob.find(project.repository, 'master', '.gitignore')
|
||||
end
|
||||
|
||||
get "/#{project.path_with_namespace}/blob/master/info/refs"
|
||||
end
|
||||
|
||||
it "returns the file" do
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the file exists" do
|
||||
before { get "/#{project.path_with_namespace}/blob/master/info/refs" }
|
||||
|
||||
it "returns not found" do
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def clone_get(project, options={})
|
||||
get "/#{project}/info/refs", { service: 'git-upload-pack' }, auth_env(*options.values_at(:user, :password))
|
||||
end
|
||||
|
|
|
@ -18,7 +18,7 @@ describe TodoService, services: true do
|
|||
end
|
||||
|
||||
describe 'Issues' do
|
||||
let(:issue) { create(:issue, project: project, assignee: john_doe, author: author, description: mentions) }
|
||||
let(:issue) { create(:issue, project: project, assignee: john_doe, author: author, description: "- [ ] Task 1\n- [ ] Task 2 #{mentions}") }
|
||||
let(:unassigned_issue) { create(:issue, project: project, assignee: nil) }
|
||||
let(:confidential_issue) { create(:issue, :confidential, project: project, author: author, assignee: assignee, description: mentions) }
|
||||
|
||||
|
@ -101,6 +101,19 @@ describe TodoService, services: true do
|
|||
should_create_todo(user: admin, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: john_doe, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
|
||||
end
|
||||
|
||||
it 'does not create todo when when tasks are marked as completed' do
|
||||
issue.update(description: "- [x] Task 1\n- [X] Task 2 #{mentions}")
|
||||
|
||||
service.update_issue(issue, author)
|
||||
|
||||
should_not_create_todo(user: admin, target: issue, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: assignee, target: issue, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: author, target: issue, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: john_doe, target: issue, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: member, target: issue, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: non_member, target: issue, action: Todo::MENTIONED)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#close_issue' do
|
||||
|
@ -210,7 +223,7 @@ describe TodoService, services: true do
|
|||
end
|
||||
|
||||
describe 'Merge Requests' do
|
||||
let(:mr_assigned) { create(:merge_request, source_project: project, author: author, assignee: john_doe, description: mentions) }
|
||||
let(:mr_assigned) { create(:merge_request, source_project: project, author: author, assignee: john_doe, description: "- [ ] Task 1\n- [ ] Task 2 #{mentions}") }
|
||||
let(:mr_unassigned) { create(:merge_request, source_project: project, author: author, assignee: nil) }
|
||||
|
||||
describe '#new_merge_request' do
|
||||
|
@ -253,6 +266,19 @@ describe TodoService, services: true do
|
|||
|
||||
expect { service.update_merge_request(mr_assigned, author) }.not_to change(member.todos, :count)
|
||||
end
|
||||
|
||||
it 'does not create todo when when tasks are marked as completed' do
|
||||
mr_assigned.update(description: "- [x] Task 1\n- [X] Task 2 #{mentions}")
|
||||
|
||||
service.update_merge_request(mr_assigned, author)
|
||||
|
||||
should_not_create_todo(user: admin, target: mr_assigned, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: assignee, target: mr_assigned, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: author, target: mr_assigned, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: john_doe, target: mr_assigned, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: member, target: mr_assigned, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: non_member, target: mr_assigned, action: Todo::MENTIONED)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#close_merge_request' do
|
||||
|
|
Loading…
Reference in a new issue