summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG4
-rw-r--r--Gemfile7
-rw-r--r--Gemfile.lock26
-rw-r--r--app/assets/stylesheets/pages/dashboard.scss2
-rw-r--r--app/controllers/profiles_controller.rb3
-rw-r--r--app/helpers/gitlab_routing_helper.rb1
-rw-r--r--app/models/note.rb25
-rw-r--r--app/services/notification_service.rb2
-rw-r--r--app/views/projects/_commit_button.html.haml3
-rw-r--r--app/views/projects/issues/_issue.html.haml2
-rw-r--r--app/views/projects/merge_requests/_merge_request.html.haml2
-rw-r--r--app/views/projects/new.html.haml103
-rw-r--r--app/views/projects/show.html.haml2
-rw-r--r--config/initializers/timeout.rb8
-rw-r--r--config/unicorn.rb.example20
-rw-r--r--doc/api/merge_requests.md2
-rw-r--r--doc/api/notes.md2
-rw-r--r--lib/gitlab/middleware/timeout.rb13
-rw-r--r--lib/tasks/gitlab/cleanup.rake9
-rw-r--r--public/503.html13
-rw-r--r--spec/lib/gitlab/reference_extractor_spec.rb14
-rw-r--r--spec/models/note_spec.rb153
22 files changed, 268 insertions, 148 deletions
diff --git a/CHANGELOG b/CHANGELOG
index e0676b30ce8..f38a075fff5 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,8 @@
Please view this file on the master branch, on stable branches it's out of date.
v 7.10.0 (unreleased)
+ - Update poltergeist to version 1.6.0 to support PhantomJS 2.0 (Zeger-Jan van de Weg)
+ - Fix cross references when usernames, milestones, or project names contain underscores (Stan Hu)
- enable line wrapping per default and remove the checkbox to toggle it (Hannes Rosenögger)
- extend the commit calendar to show the actual commits made on a date (Hannes Rosenögger)
- Add a service to support external wikis (Hannes Rosenögger)
@@ -9,6 +11,8 @@ v 7.10.0 (unreleased)
- Improve diff UI
- Fix alignment of navbar toggle button (Cody Mize)
- Identical look of selectboxes in UI
+ - Move "Import existing repository by URL" option to button.
+ - Improve error message when save profile has error.
v 7.9.0 (unreleased)
- Add HipChat integration documentation (Stan Hu)
diff --git a/Gemfile b/Gemfile
index ad33116db3e..285ccf32b66 100644
--- a/Gemfile
+++ b/Gemfile
@@ -31,7 +31,7 @@ gem 'omniauth-shibboleth'
gem 'omniauth-kerberos'
gem 'omniauth-gitlab'
gem 'omniauth-bitbucket'
-gem 'doorkeeper', '2.1.0'
+gem 'doorkeeper', '2.1.3'
gem "rack-oauth2", "~> 1.0.5"
# Browser detection
@@ -48,7 +48,7 @@ gem 'gitlab-grack', '~> 2.0.0.rc2', require: 'grack'
gem 'gitlab_omniauth-ldap', '1.2.1', require: "omniauth-ldap"
# Git Wiki
-gem 'gollum-lib', '~> 4.0.0'
+gem 'gollum-lib', '~> 4.0.2'
# Language detection
gem "gitlab-linguist", "~> 3.0.1", require: "linguist"
@@ -180,9 +180,6 @@ gem 'mousetrap-rails'
# Detect and convert string character encoding
gem 'charlock_holmes'
-# Shutting down requests that take too long
-gem "slowpoke"
-
gem "sass-rails", '~> 4.0.2'
gem "coffee-rails"
gem "uglifier"
diff --git a/Gemfile.lock b/Gemfile.lock
index 71936584d6e..80eebc16e4c 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -136,8 +136,8 @@ GEM
diff-lcs (1.2.5)
diffy (3.0.3)
docile (1.1.5)
- doorkeeper (2.1.0)
- railties (>= 3.1)
+ doorkeeper (2.1.3)
+ railties (>= 3.2)
dotenv (0.9.0)
dropzonejs-rails (0.4.14)
rails (> 3.1)
@@ -147,7 +147,6 @@ GEM
enumerize (0.7.0)
activesupport (>= 3.2)
equalizer (0.0.8)
- errbase (0.0.2)
erubis (2.7.0)
escape_utils (0.2.4)
eventmachine (1.0.4)
@@ -224,11 +223,11 @@ GEM
omniauth (~> 1.0)
pyu-ruby-sasl (~> 0.0.3.1)
rubyntlm (~> 0.3)
- gollum-grit_adapter (0.1.0)
- gitlab-grit (~> 2.7.1)
- gollum-lib (4.0.0)
+ gollum-grit_adapter (0.1.3)
+ gitlab-grit (~> 2.7, >= 2.7.1)
+ gollum-lib (4.0.2)
github-markup (~> 1.3.1)
- gollum-grit_adapter (~> 0.1.0)
+ gollum-grit_adapter (~> 0.1, >= 0.1.1)
nokogiri (~> 1.6.4)
rouge (~> 1.7.4)
sanitize (~> 2.1.0)
@@ -429,7 +428,6 @@ GEM
rack
rack-test (0.6.3)
rack (>= 1.0)
- rack-timeout (0.2.0)
rails (4.1.9)
actionmailer (= 4.1.9)
actionpack (= 4.1.9)
@@ -482,9 +480,7 @@ GEM
rest-client (1.6.7)
mime-types (>= 1.16)
rinku (1.7.3)
- robustly (0.0.3)
- errbase
- rouge (1.7.4)
+ rouge (1.7.7)
rspec (2.99.0)
rspec-core (~> 2.99.0)
rspec-expectations (~> 2.99.0)
@@ -566,9 +562,6 @@ GEM
temple (~> 0.6.6)
tilt (>= 1.3.3, < 2.1)
slop (3.6.0)
- slowpoke (0.0.5)
- rack-timeout (>= 0.1.0)
- robustly
spinach (0.8.7)
colorize (= 0.5.8)
gherkin-ruby (>= 0.3.1)
@@ -690,7 +683,7 @@ DEPENDENCIES
devise (= 3.2.4)
devise-async (= 0.9.0)
diffy (~> 3.0.3)
- doorkeeper (= 2.1.0)
+ doorkeeper (= 2.1.3)
dropzonejs-rails
email_spec
enumerize
@@ -708,7 +701,7 @@ DEPENDENCIES
gitlab_git (~> 7.1.2)
gitlab_meta (= 7.0)
gitlab_omniauth-ldap (= 1.2.1)
- gollum-lib (~> 4.0.0)
+ gollum-lib (~> 4.0.2)
gon (~> 5.0.0)
grape (~> 0.6.1)
grape-entity (~> 0.4.2)
@@ -776,7 +769,6 @@ DEPENDENCIES
six
slack-notifier (~> 1.0.0)
slim
- slowpoke
spinach-rails
spring (~> 1.3.1)
spring-commands-rspec (= 1.0.4)
diff --git a/app/assets/stylesheets/pages/dashboard.scss b/app/assets/stylesheets/pages/dashboard.scss
index e408211fc7d..af9c83e5dc8 100644
--- a/app/assets/stylesheets/pages/dashboard.scss
+++ b/app/assets/stylesheets/pages/dashboard.scss
@@ -29,7 +29,7 @@
line-height: 24px;
.str-truncated {
- max-width: 75%;
+ max-width: 72%;
}
a {
diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb
index 1b9a86ee42c..3c7f45d559b 100644
--- a/app/controllers/profiles_controller.rb
+++ b/app/controllers/profiles_controller.rb
@@ -25,7 +25,8 @@ class ProfilesController < ApplicationController
if @user.update_attributes(user_params)
flash[:notice] = "Profile was successfully updated"
else
- flash[:alert] = "Failed to update profile"
+ messages = @user.errors.full_messages.uniq.join('. ')
+ flash[:alert] = "Failed to update profile. #{messages}"
end
respond_to do |format|
diff --git a/app/helpers/gitlab_routing_helper.rb b/app/helpers/gitlab_routing_helper.rb
index b005cb8e417..3386fac8657 100644
--- a/app/helpers/gitlab_routing_helper.rb
+++ b/app/helpers/gitlab_routing_helper.rb
@@ -47,6 +47,5 @@ module GitlabRoutingHelper
def project_snippet_url(entity, *args)
namespace_project_snippet_url(entity.project.namespace, entity.project, entity, *args)
-
end
end
diff --git a/app/models/note.rb b/app/models/note.rb
index 649e9b4e852..27b583a869a 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -59,7 +59,7 @@ class Note < ActiveRecord::Base
class << self
def create_status_change_note(noteable, project, author, status, source)
- body = "_Status changed to #{status}#{' by ' + source.gfm_reference if source}_"
+ body = "Status changed to #{status}#{' by ' + source.gfm_reference if source}"
create(
noteable: noteable,
@@ -95,9 +95,9 @@ class Note < ActiveRecord::Base
def create_milestone_change_note(noteable, project, author, milestone)
body = if milestone.nil?
- '_Milestone removed_'
+ 'Milestone removed'
else
- "_Milestone changed to #{milestone.title}_"
+ "Milestone changed to #{milestone.title}"
end
create(
@@ -110,7 +110,7 @@ class Note < ActiveRecord::Base
end
def create_assignee_change_note(noteable, project, author, assignee)
- body = assignee.nil? ? '_Assignee removed_' : "_Reassigned to @#{assignee.username}_"
+ body = assignee.nil? ? 'Assignee removed' : "Reassigned to @#{assignee.username}"
create({
noteable: noteable,
@@ -140,7 +140,7 @@ class Note < ActiveRecord::Base
end
message << ' ' << 'label'.pluralize(labels_count)
- body = "_#{message.capitalize}_"
+ body = "#{message.capitalize}"
create(
noteable: noteable,
@@ -170,14 +170,14 @@ class Note < ActiveRecord::Base
commits_text = ActionController::Base.helpers.pluralize(existing_commits.length, 'commit')
- branch =
+ branch =
if merge_request.for_fork?
"#{merge_request.target_project_namespace}:#{merge_request.target_branch}"
else
merge_request.target_branch
end
- message = "* #{commit_ids} - _#{commits_text} from branch `#{branch}`_"
+ message = "* #{commit_ids} - #{commits_text} from branch `#{branch}`"
body << message
body << "\n"
end
@@ -240,7 +240,7 @@ class Note < ActiveRecord::Base
where(noteable_id: noteable.id)
end
- notes.where('note like ?', cross_reference_note_content(gfm_reference)).
+ notes.where('note like ?', cross_reference_note_pattern(gfm_reference)).
system.any?
end
@@ -249,13 +249,18 @@ class Note < ActiveRecord::Base
end
def cross_reference_note_prefix
- '_mentioned in '
+ 'mentioned in '
end
private
def cross_reference_note_content(gfm_reference)
- cross_reference_note_prefix + "#{gfm_reference}_"
+ cross_reference_note_prefix + "#{gfm_reference}"
+ end
+
+ def cross_reference_note_pattern(gfm_reference)
+ # Older cross reference notes contained underscores for emphasis
+ "%" + cross_reference_note_content(gfm_reference) + "%"
end
# Prepend the mentioner's namespaced project path to the GFM reference for
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index 848ed77ebf8..cc5853144c5 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -120,7 +120,7 @@ class NotificationService
return true unless note.noteable_type.present?
# ignore gitlab service messages
- return true if note.note.start_with?('_Status changed to closed_')
+ return true if note.note.start_with?('Status changed to closed')
return true if note.cross_reference? && note.system == true
opts = { noteable_type: note.noteable_type, project_id: note.project_id }
diff --git a/app/views/projects/_commit_button.html.haml b/app/views/projects/_commit_button.html.haml
index fd8320adb8d..35f7e7bb34b 100644
--- a/app/views/projects/_commit_button.html.haml
+++ b/app/views/projects/_commit_button.html.haml
@@ -2,8 +2,5 @@
.commit-button-annotation
= button_tag 'Commit Changes',
class: 'btn commit-btn js-commit-button btn-create'
- .message
- to branch
- %strong= ref
= link_to 'Cancel', cancel_path,
class: 'btn btn-cancel', data: {confirm: leave_edit_message}
diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml
index 3b50ce01351..7b06fe72882 100644
--- a/app/views/projects/issues/_issue.html.haml
+++ b/app/views/projects/issues/_issue.html.haml
@@ -17,7 +17,7 @@
= issue.notes.count
.issue-info
- %span.light= "##{issue.iid}"
+ = link_to "##{issue.iid}", issue_path(issue), class: "light"
- if issue.assignee
assigned to #{link_to_member(@project, issue.assignee)}
- if issue.votes_count > 0
diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml
index 1eba1a96b7b..ecbff722b42 100644
--- a/app/views/projects/merge_requests/_merge_request.html.haml
+++ b/app/views/projects/merge_requests/_merge_request.html.haml
@@ -22,7 +22,7 @@
%i.fa.fa-comments
= merge_request.mr_and_commit_notes.count
.merge-request-info
- %span.light= "##{merge_request.iid}"
+ = link_to "##{merge_request.iid}", merge_request_path(merge_request), class: "light"
- if merge_request.assignee
assigned to #{link_to_member(merge_request.source_project, merge_request.assignee)}
- else
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index 7fc612c0c7d..173a3080b31 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -21,64 +21,65 @@
= f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user), {}, {class: 'select2', tabindex: 2}
%hr
- .js-toggle-container
+
+ .project-import.js-toggle-container
.form-group
- .col-sm-2
+ %label.control-label Import project from
.col-sm-10
- = link_to "#", class: 'js-toggle-button' do
- %i.fa.fa-upload
- %span Import existing repository by URL
- .js-toggle-content.hide
- .form-group.import-url-data
- = f.label :import_url, class: 'control-label' do
- %span Import existing git repo
- .col-sm-10
- = f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git'
- .alert.alert-info.prepend-top-10
- This URL must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git.
- %br
- The import will time out after 4 minutes. For big repositories, use a clone/push combination.
- For SVN repositories, check #{link_to "this migrating from SVN doc.", "http://doc.gitlab.com/ce/workflow/migrating_from_svn.html"}
+ - if github_import_enabled?
+ = link_to status_import_github_path, class: 'btn' do
+ %i.fa.fa-github
+ GitHub
+ - else
+ = link_to '#', class: 'how_to_import_link light btn' do
+ %i.fa.fa-github
+ GitHub
+ = render 'github_import_modal'
- .project-import.form-group
- %label.control-label Import projects from
- .col-sm-10
- - if github_import_enabled?
- = link_to status_import_github_path, class: 'btn' do
- %i.fa.fa-github
- GitHub
- - else
- = link_to '#', class: 'how_to_import_link light btn' do
- %i.fa.fa-github
- GitHub
- = render 'github_import_modal'
-
-
- - if bitbucket_import_enabled?
- = link_to status_import_bitbucket_path, class: 'btn' do
- %i.fa.fa-bitbucket
- Bitbucket
- - else
- = link_to '#', class: 'how_to_import_link light btn' do
- %i.fa.fa-bitbucket
- Bitbucket
- = render 'bitbucket_import_modal'
-
- - unless request.host == 'gitlab.com'
- - if gitlab_import_enabled?
- = link_to status_import_gitlab_path, class: 'btn' do
- %i.fa.fa-heart
- GitLab.com
+ - if bitbucket_import_enabled?
+ = link_to status_import_bitbucket_path, class: 'btn' do
+ %i.fa.fa-bitbucket
+ Bitbucket
- else
= link_to '#', class: 'how_to_import_link light btn' do
- %i.fa.fa-heart
- GitLab.com
- = render 'gitlab_import_modal'
+ %i.fa.fa-bitbucket
+ Bitbucket
+ = render 'bitbucket_import_modal'
- = link_to new_import_gitorious_path, class: 'btn' do
- %i.icon-gitorious.icon-gitorious-small
- Gitorious.org
+ - unless request.host == 'gitlab.com'
+ - if gitlab_import_enabled?
+ = link_to status_import_gitlab_path, class: 'btn' do
+ %i.fa.fa-heart
+ GitLab.com
+ - else
+ = link_to '#', class: 'how_to_import_link light btn' do
+ %i.fa.fa-heart
+ GitLab.com
+ = render 'gitlab_import_modal'
+
+ = link_to new_import_gitorious_path, class: 'btn' do
+ %i.icon-gitorious.icon-gitorious-small
+ Gitorious.org
+
+ = link_to "#", class: 'btn js-toggle-button' do
+ %i.fa.fa-git
+ %span Any repo by URL
+
+ .js-toggle-content.hide
+ .form-group.import-url-data
+ = f.label :import_url, class: 'control-label' do
+ %span Git repository URL
+ .col-sm-10
+ = f.text_field :import_url, class: 'form-control', placeholder: 'https://username:password@gitlab.company.com/group/project.git'
+ .alert.alert-info.prepend-top-10
+ %ul
+ %li
+ The repository must be accessible over HTTP(S). If it is not publicly accessible, you can add authentication information to the URL: <code>https://username:password@gitlab.company.com/group/project.git</code>.
+ %li
+ The import will time out after 4 minutes. For big repositories, use a clone/push combination.
+ %li
+ To migrate an SVN repository, check out #{link_to "this document", "http://doc.gitlab.com/ce/workflow/migrating_from_svn.html"}.
%hr.prepend-botton-10
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index cfa6cda0466..cfa6f558dd6 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -73,7 +73,7 @@
%span.light Created on
#{@project.created_at.stamp('Aug 22, 2013')}
%p
- %span.light Owned by
+ %span.light Owned by #{@project.group ? "the" : nil}
- if @project.group
#{link_to @project.group.name, @project.group} group
- else
diff --git a/config/initializers/timeout.rb b/config/initializers/timeout.rb
deleted file mode 100644
index bc88595cf26..00000000000
--- a/config/initializers/timeout.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-# Slowpoke extends Rack::Timeout to gracefully kill Unicorn workers so they can clean up state.
-Slowpoke.timeout = 60
-
-# The `Rack::Timeout` middleware kills requests after 60 seconds (as set above).
-# We're replacing it with our `Gitlab::Middleware::Timeout` that does the same,
-# except ignoring Git-over-HTTP requests, letting those take as long as they need.
-
-Rails.application.config.middleware.swap(Rack::Timeout, Gitlab::Middleware::Timeout)
diff --git a/config/unicorn.rb.example b/config/unicorn.rb.example
index 3aee718097f..86a5512e761 100644
--- a/config/unicorn.rb.example
+++ b/config/unicorn.rb.example
@@ -35,10 +35,22 @@ working_directory "/home/git/gitlab" # available in 0.94.0+
listen "/home/git/gitlab/tmp/sockets/gitlab.socket", :backlog => 1024
listen "127.0.0.1:8080", :tcp_nopush => true
-# Kill workers after 1 hour.
-# A shorter timeout of 60 seconds is enforced by rack-timeout for web requests.
-# Git-over-HTTP only has the below timeout since large pulls/pushes can take a long time.
-timeout 60 * 60
+# nuke workers after 30 seconds instead of 60 seconds (the default)
+#
+# NOTICE: git push over http depends on this value.
+# If you want be able to push huge amount of data to git repository over http
+# you will have to increase this value too.
+#
+# Example of output if you try to push 1GB repo to GitLab over http.
+# -> git push http://gitlab.... master
+#
+# error: RPC failed; result=18, HTTP code = 200
+# fatal: The remote end hung up unexpectedly
+# fatal: The remote end hung up unexpectedly
+#
+# For more information see http://stackoverflow.com/a/21682112/752049
+#
+timeout 60
# feel free to point this anywhere accessible on the filesystem
pid "/home/git/gitlab/tmp/pids/unicorn.pid"
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index 1f3fd26a241..6a272539e45 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -375,7 +375,7 @@ Parameters:
}
},
{
- "note": "_Status changed to closed_",
+ "note": "Status changed to closed",
"author": {
"id": 11,
"username": "admin",
diff --git a/doc/api/notes.md b/doc/api/notes.md
index c22e493562a..ee2f9fa0eac 100644
--- a/doc/api/notes.md
+++ b/doc/api/notes.md
@@ -21,7 +21,7 @@ Parameters:
[
{
"id": 302,
- "body": "_Status changed to closed_",
+ "body": "Status changed to closed",
"attachment": null,
"author": {
"id": 1,
diff --git a/lib/gitlab/middleware/timeout.rb b/lib/gitlab/middleware/timeout.rb
deleted file mode 100644
index 015600392b9..00000000000
--- a/lib/gitlab/middleware/timeout.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-module Gitlab
- module Middleware
- class Timeout < Rack::Timeout
- GRACK_REGEX = /[-\/\w\.]+\.git\//.freeze
-
- def call(env)
- return @app.call(env) if env['PATH_INFO'] =~ GRACK_REGEX
-
- super
- end
- end
- end
-end
diff --git a/lib/tasks/gitlab/cleanup.rake b/lib/tasks/gitlab/cleanup.rake
index 189ad6090a4..3c9802a0be4 100644
--- a/lib/tasks/gitlab/cleanup.rake
+++ b/lib/tasks/gitlab/cleanup.rake
@@ -90,13 +90,14 @@ namespace :gitlab do
warn_user_is_not_gitlab
block_flag = ENV['BLOCK']
- User.ldap.each do |ldap_user|
- print "#{ldap_user.name} (#{ldap_user.extern_uid}) ..."
- if Gitlab::LDAP::Access.allowed?(ldap_user)
+ User.find_each do |user|
+ next unless user.ldap_user?
+ print "#{user.name} (#{user.ldap_identity.extern_uid}) ..."
+ if Gitlab::LDAP::Access.allowed?(user)
puts " [OK]".green
else
if block_flag
- ldap_user.block! unless ldap_user.blocked?
+ user.block! unless user.blocked?
puts " [BLOCKED]".red
else
puts " [NOT IN LDAP]".yellow
diff --git a/public/503.html b/public/503.html
deleted file mode 100644
index efdae0f512d..00000000000
--- a/public/503.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <title>Page took too long to load (503)</title>
- <link href="/static.css" media="screen" rel="stylesheet" type="text/css" />
-</head>
-<body>
- <h1>503</h1>
- <h3>Page took too long to load.</h3>
- <hr/>
- <p>Please contact your GitLab administrator if this problem persists.</p>
-</body>
-</html>
diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb
index 034f8ee7c45..5ebe44f6fb7 100644
--- a/spec/lib/gitlab/reference_extractor_spec.rb
+++ b/spec/lib/gitlab/reference_extractor_spec.rb
@@ -120,4 +120,18 @@ describe Gitlab::ReferenceExtractor do
expect(extracted[0][1].message).to eq(commit.message)
end
end
+
+ context 'with a project with an underscore' do
+ let(:project) { create(:project, path: 'test_project') }
+ let(:issue) { create(:issue, project: project) }
+
+ it 'handles project issue references' do
+ subject.analyze("this refers issue #{project.path_with_namespace}##{issue.iid}",
+ project)
+ extracted = subject.issues_for(project)
+ expect(extracted.size).to eq(1)
+ expect(extracted).to eq([issue])
+ end
+
+ end
end
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 17cb439c90e..a7bf5081d5b 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -182,14 +182,14 @@ describe Note do
describe '#note' do
subject { super().note }
- it { is_expected.to match(/Status changed to #{status}/) }
+ it { is_expected.to eq("Status changed to #{status}") }
end
it 'appends a back-reference if a closing mentionable is supplied' do
commit = double('commit', gfm_reference: 'commit 123456')
n = Note.create_status_change_note(thing, project, author, status, commit)
- expect(n.note).to match(/Status changed to #{status} by commit 123456/)
+ expect(n.note).to eq("Status changed to #{status} by commit 123456")
end
end
@@ -197,7 +197,7 @@ describe Note do
let(:project) { create(:project) }
let(:thing) { create(:issue, project: project) }
let(:author) { create(:user) }
- let(:assignee) { create(:user) }
+ let(:assignee) { create(:user, username: "assigned_user") }
subject { Note.create_assignee_change_note(thing, project, author, assignee) }
@@ -227,7 +227,7 @@ describe Note do
describe '#note' do
subject { super().note }
- it { is_expected.to match(/Reassigned to @#{assignee.username}/) }
+ it { is_expected.to eq('Reassigned to @assigned_user') }
end
context 'assignee is removed' do
@@ -235,11 +235,95 @@ describe Note do
describe '#note' do
subject { super().note }
- it { is_expected.to match(/Assignee removed/) }
+ it { is_expected.to eq('Assignee removed') }
end
end
end
+ describe '#create_labels_change_note' do
+ let(:project) { create(:project) }
+ let(:thing) { create(:issue, project: project) }
+ let(:author) { create(:user) }
+ let(:label1) { create(:label) }
+ let(:label2) { create(:label) }
+ let(:added_labels) { [label1, label2] }
+ let(:removed_labels) { [] }
+
+ subject { Note.create_labels_change_note(thing, project, author, added_labels, removed_labels) }
+
+ context 'creates and saves a Note' do
+ it { is_expected.to be_a Note }
+
+ describe '#id' do
+ subject { super().id }
+ it { is_expected.not_to be_nil }
+ end
+ end
+
+ describe '#noteable' do
+ subject { super().noteable }
+ it { is_expected.to eq(thing) }
+ end
+
+ describe '#project' do
+ subject { super().project }
+ it { is_expected.to eq(thing.project) }
+ end
+
+ describe '#author' do
+ subject { super().author }
+ it { is_expected.to eq(author) }
+ end
+
+ describe '#note' do
+ subject { super().note }
+ it { is_expected.to eq("Added ~#{label1.id} ~#{label2.id} labels") }
+ end
+
+ context 'label is removed' do
+ let(:added_labels) { [label1] }
+ let(:removed_labels) { [label2] }
+
+ describe '#note' do
+ subject { super().note }
+ it { is_expected.to eq("Added ~#{label1.id} and removed ~#{label2.id} labels") }
+ end
+ end
+ end
+
+ describe '#create_milestone_change_note' do
+ let(:project) { create(:project) }
+ let(:thing) { create(:issue, project: project) }
+ let(:milestone) { create(:milestone, project: project, title: "first_milestone") }
+ let(:author) { create(:user) }
+
+ subject { Note.create_milestone_change_note(thing, project, author, milestone) }
+
+ context 'creates and saves a Note' do
+ it { is_expected.to be_a Note }
+
+ describe '#id' do
+ subject { super().id }
+ it { is_expected.not_to be_nil }
+ end
+ end
+
+ describe '#project' do
+ subject { super().project }
+ it { is_expected.to eq(thing.project) }
+ end
+
+ describe '#author' do
+ subject { super().author }
+ it { is_expected.to eq(author) }
+ end
+
+ describe '#note' do
+ subject { super().note }
+ it { is_expected.to eq("Milestone changed to first_milestone") }
+ end
+ end
+
describe '#create_cross_reference_note' do
let(:project) { create(:project) }
let(:author) { create(:user) }
@@ -272,7 +356,7 @@ describe Note do
describe '#note' do
subject { super().note }
- it { is_expected.to eq("_mentioned in merge request !#{mergereq.iid}_") }
+ it { is_expected.to eq("mentioned in merge request !#{mergereq.iid}") }
end
end
@@ -288,7 +372,7 @@ describe Note do
describe '#note' do
subject { super().note }
- it { is_expected.to eq("_mentioned in commit #{commit.sha}_") }
+ it { is_expected.to eq("mentioned in commit #{commit.sha}") }
end
end
@@ -309,7 +393,7 @@ describe Note do
describe '#note' do
subject { super().note }
- it { is_expected.to eq("_mentioned in issue ##{issue.iid}_") }
+ it { is_expected.to eq("mentioned in issue ##{issue.iid}") }
end
end
@@ -330,7 +414,7 @@ describe Note do
describe '#note' do
subject { super().note }
- it { is_expected.to eq("_mentioned in merge request !#{mergereq.iid}_") }
+ it { is_expected.to eq("mentioned in merge request !#{mergereq.iid}") }
end
end
@@ -362,7 +446,7 @@ describe Note do
describe '#note' do
subject { super().note }
- it { is_expected.to eq("_mentioned in issue ##{issue.iid}_") }
+ it { is_expected.to eq("mentioned in issue ##{issue.iid}") }
end
end
@@ -389,7 +473,7 @@ describe Note do
describe '#note' do
subject { super().note }
- it { is_expected.to eq("_mentioned in commit #{parent_commit.id}_") }
+ it { is_expected.to eq("mentioned in commit #{parent_commit.id}") }
end
end
end
@@ -421,6 +505,41 @@ describe Note do
it { expect(Note.cross_reference_exists?(commit0, commit1)).to be_truthy }
it { expect(Note.cross_reference_exists?(commit1, commit0)).to be_falsey }
end
+
+ context 'legacy note with Markdown emphasis' do
+ let(:issue2) { create :issue, project: project }
+ let!(:note) do
+ create :note, system: true, noteable_id: issue2.id,
+ noteable_type: "Issue", note: "_mentioned in issue " \
+ "#{issue.project.path_with_namespace}##{issue.iid}_"
+ end
+
+ it 'detects if a mentionable with emphasis has been mentioned' do
+ expect(Note.cross_reference_exists?(issue2, issue)).to be_truthy
+ end
+ end
+ end
+
+ describe '#cross_references_with_underscores?' do
+ let(:project) { create :project, path: "first_project" }
+ let(:second_project) { create :project, path: "second_project" }
+
+ let(:author) { create :user }
+ let(:issue0) { create :issue, project: project }
+ let(:issue1) { create :issue, project: second_project }
+ let!(:note) { Note.create_cross_reference_note(issue0, issue1, author, project) }
+
+ it 'detects if a mentionable has already been mentioned' do
+ expect(Note.cross_reference_exists?(issue0, issue1)).to be_truthy
+ end
+
+ it 'detects if a mentionable has not already been mentioned' do
+ expect(Note.cross_reference_exists?(issue1, issue0)).to be_falsey
+ end
+
+ it 'detects that text has underscores' do
+ expect(note.note).to eq("mentioned in issue #{second_project.path_with_namespace}##{issue1.iid}")
+ end
end
describe '#system?' do
@@ -429,6 +548,8 @@ describe Note do
let(:other) { create(:issue, project: project) }
let(:author) { create(:user) }
let(:assignee) { create(:user) }
+ let(:label) { create(:label) }
+ let(:milestone) { create(:milestone) }
it 'should recognize user-supplied notes as non-system' do
@note = create(:note_on_issue)
@@ -449,6 +570,16 @@ describe Note do
@note = Note.create_assignee_change_note(issue, project, author, assignee)
expect(@note).to be_system
end
+
+ it 'should identify label-change notes as system notes' do
+ @note = Note.create_labels_change_note(issue, project, author, [label], [])
+ expect(@note).to be_system
+ end
+
+ it 'should identify milestone-change notes as system notes' do
+ @note = Note.create_milestone_change_note(issue, project, author, milestone)
+ expect(@note).to be_system
+ end
end
describe :authorization do