Merge branch 'commit-project' into 'master'
Link cross-project cross-reference notes to correct project. - Fixes #1431: Don't crash when an MR from a fork has a cross-reference comment from the target project on of its commits. - Include commit comments in MR from a forked project. To accomplish this, the Commit model needs to know about its project. Adding this attribute also simplifies a bunch of other methods that deal with a note's target, that previously had to have special logic for when it belonged to a commit. See merge request !554
This commit is contained in:
commit
6ae606d81f
54 changed files with 218 additions and 205 deletions
|
@ -12,6 +12,8 @@ v 7.11.0 (unreleased)
|
||||||
-
|
-
|
||||||
- Show Atom feed buttons everywhere where applicable.
|
- Show Atom feed buttons everywhere where applicable.
|
||||||
- Add project activity atom feed.
|
- Add project activity atom feed.
|
||||||
|
- Don't crash when an MR from a fork has a cross-reference comment from the target project on of its commits.
|
||||||
|
- Include commit comments in MR from a forked project.
|
||||||
-
|
-
|
||||||
-
|
-
|
||||||
-
|
-
|
||||||
|
|
|
@ -10,11 +10,11 @@ class Projects::CommitController < Projects::ApplicationController
|
||||||
def show
|
def show
|
||||||
return git_not_found! unless @commit
|
return git_not_found! unless @commit
|
||||||
|
|
||||||
@line_notes = commit.notes(@project).inline
|
@line_notes = commit.notes.inline
|
||||||
@diffs = @commit.diffs
|
@diffs = @commit.diffs
|
||||||
@note = @project.build_commit_note(commit)
|
@note = @project.build_commit_note(commit)
|
||||||
@notes_count = commit.notes(@project).count
|
@notes_count = commit.notes.count
|
||||||
@notes = commit.notes(@project).not_inline.fresh
|
@notes = commit.notes.not_inline.fresh
|
||||||
@noteable = @commit
|
@noteable = @commit
|
||||||
@comments_allowed = @reply_allowed = true
|
@comments_allowed = @reply_allowed = true
|
||||||
@comments_target = {
|
@comments_target = {
|
||||||
|
@ -36,6 +36,6 @@ class Projects::CommitController < Projects::ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def commit
|
def commit
|
||||||
@commit ||= @project.repository.commit(params[:id])
|
@commit ||= @project.commit(params[:id])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -146,7 +146,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
||||||
|
|
||||||
def branch_to
|
def branch_to
|
||||||
@target_project = selected_target_project
|
@target_project = selected_target_project
|
||||||
@commit = @target_project.repository.commit(params[:ref]) if params[:ref].present?
|
@commit = @target_project.commit(params[:ref]) if params[:ref].present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_branches
|
def update_branches
|
||||||
|
|
|
@ -79,7 +79,7 @@ module Emails
|
||||||
@disable_diffs = disable_diffs
|
@disable_diffs = disable_diffs
|
||||||
|
|
||||||
if @compare
|
if @compare
|
||||||
@commits = Commit.decorate(compare.commits)
|
@commits = Commit.decorate(compare.commits, @project)
|
||||||
@diffs = compare.diffs
|
@diffs = compare.diffs
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -101,8 +101,8 @@ module Emails
|
||||||
if @commits.length > 1
|
if @commits.length > 1
|
||||||
@target_url = namespace_project_compare_url(@project.namespace,
|
@target_url = namespace_project_compare_url(@project.namespace,
|
||||||
@project,
|
@project,
|
||||||
from: Commit.new(@compare.base),
|
from: Commit.new(@compare.base, @project),
|
||||||
to: Commit.new(@compare.head))
|
to: Commit.new(@compare.head, @project))
|
||||||
@subject << "Deleted " if @reverse_compare
|
@subject << "Deleted " if @reverse_compare
|
||||||
@subject << "#{@commits.length} commits: #{@commits.first.title}"
|
@subject << "#{@commits.length} commits: #{@commits.first.title}"
|
||||||
else
|
else
|
||||||
|
|
|
@ -3,8 +3,12 @@ class Commit
|
||||||
include StaticModel
|
include StaticModel
|
||||||
extend ActiveModel::Naming
|
extend ActiveModel::Naming
|
||||||
include Mentionable
|
include Mentionable
|
||||||
|
include Participable
|
||||||
|
|
||||||
attr_mentionable :safe_message
|
attr_mentionable :safe_message
|
||||||
|
participant :author, :committer, :notes, :mentioned_users
|
||||||
|
|
||||||
|
attr_accessor :project
|
||||||
|
|
||||||
# Safe amount of changes (files and lines) in one commit to render
|
# Safe amount of changes (files and lines) in one commit to render
|
||||||
# Used to prevent 500 error on huge commits by suppressing diff
|
# Used to prevent 500 error on huge commits by suppressing diff
|
||||||
|
@ -18,12 +22,12 @@ class Commit
|
||||||
DIFF_HARD_LIMIT_LINES = 50000 unless defined?(DIFF_HARD_LIMIT_LINES)
|
DIFF_HARD_LIMIT_LINES = 50000 unless defined?(DIFF_HARD_LIMIT_LINES)
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def decorate(commits)
|
def decorate(commits, project)
|
||||||
commits.map do |commit|
|
commits.map do |commit|
|
||||||
if commit.kind_of?(Commit)
|
if commit.kind_of?(Commit)
|
||||||
commit
|
commit
|
||||||
else
|
else
|
||||||
self.new(commit)
|
self.new(commit, project)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -41,10 +45,11 @@ class Commit
|
||||||
|
|
||||||
attr_accessor :raw
|
attr_accessor :raw
|
||||||
|
|
||||||
def initialize(raw_commit)
|
def initialize(raw_commit, project)
|
||||||
raise "Nil as raw commit passed" unless raw_commit
|
raise "Nil as raw commit passed" unless raw_commit
|
||||||
|
|
||||||
@raw = raw_commit
|
@raw = raw_commit
|
||||||
|
@project = project
|
||||||
end
|
end
|
||||||
|
|
||||||
def id
|
def id
|
||||||
|
@ -100,7 +105,7 @@ class Commit
|
||||||
description.present?
|
description.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def hook_attrs(project)
|
def hook_attrs
|
||||||
path_with_namespace = project.path_with_namespace
|
path_with_namespace = project.path_with_namespace
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -117,7 +122,7 @@ class Commit
|
||||||
|
|
||||||
# Discover issues should be closed when this commit is pushed to a project's
|
# Discover issues should be closed when this commit is pushed to a project's
|
||||||
# default branch.
|
# default branch.
|
||||||
def closes_issues(project, current_user = self.committer)
|
def closes_issues(current_user = self.committer)
|
||||||
Gitlab::ClosingIssueExtractor.new(project, current_user).closed_by_message(safe_message)
|
Gitlab::ClosingIssueExtractor.new(project, current_user).closed_by_message(safe_message)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -134,22 +139,7 @@ class Commit
|
||||||
User.find_for_commit(committer_email, committer_name)
|
User.find_for_commit(committer_email, committer_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def participants(project, current_user = nil)
|
def notes
|
||||||
users = []
|
|
||||||
users << author
|
|
||||||
users << committer
|
|
||||||
|
|
||||||
users.push *self.mentioned_users(current_user, project)
|
|
||||||
|
|
||||||
notes(project).each do |note|
|
|
||||||
users << note.author
|
|
||||||
users.push *note.mentioned_users(current_user, project)
|
|
||||||
end
|
|
||||||
|
|
||||||
users.uniq
|
|
||||||
end
|
|
||||||
|
|
||||||
def notes(project)
|
|
||||||
project.notes.for_commit_id(self.id)
|
project.notes.for_commit_id(self.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -169,6 +159,6 @@ class Commit
|
||||||
end
|
end
|
||||||
|
|
||||||
def parents
|
def parents
|
||||||
@parents ||= Commit.decorate(super)
|
@parents ||= Commit.decorate(super, project)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
module Issuable
|
module Issuable
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
include Mentionable
|
include Mentionable
|
||||||
|
include Participable
|
||||||
|
|
||||||
included do
|
included do
|
||||||
belongs_to :author, class_name: "User"
|
belongs_to :author, class_name: "User"
|
||||||
|
@ -45,6 +46,7 @@ module Issuable
|
||||||
prefix: true
|
prefix: true
|
||||||
|
|
||||||
attr_mentionable :title, :description
|
attr_mentionable :title, :description
|
||||||
|
participant :author, :assignee, :notes, :mentioned_users
|
||||||
end
|
end
|
||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
|
@ -117,22 +119,6 @@ module Issuable
|
||||||
upvotes + downvotes
|
upvotes + downvotes
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return all users participating on the discussion
|
|
||||||
def participants(current_user = self.author)
|
|
||||||
users = []
|
|
||||||
users << author
|
|
||||||
users << assignee if is_assigned?
|
|
||||||
|
|
||||||
users.push *self.mentioned_users(current_user)
|
|
||||||
|
|
||||||
notes.each do |note|
|
|
||||||
users << note.author
|
|
||||||
users.push *note.mentioned_users(current_user)
|
|
||||||
end
|
|
||||||
|
|
||||||
users.uniq
|
|
||||||
end
|
|
||||||
|
|
||||||
def subscribed?(user)
|
def subscribed?(user)
|
||||||
subscription = subscriptions.find_by_user_id(user.id)
|
subscription = subscriptions.find_by_user_id(user.id)
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ module Mentionable
|
||||||
def create_cross_references!(p = project, a = author, without = [])
|
def create_cross_references!(p = project, a = author, without = [])
|
||||||
refs = references(p) - without
|
refs = references(p) - without
|
||||||
refs.each do |ref|
|
refs.each do |ref|
|
||||||
Note.create_cross_reference_note(ref, local_reference, a, p)
|
Note.create_cross_reference_note(ref, local_reference, a)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
65
app/models/concerns/participable.rb
Normal file
65
app/models/concerns/participable.rb
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
# == Participable concern
|
||||||
|
#
|
||||||
|
# Contains functionality related to objects that can have participants, such as
|
||||||
|
# an author, an assignee and people mentioned in its description or comments.
|
||||||
|
#
|
||||||
|
# Used by Issue, Note, MergeRequest, Snippet and Commit.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
#
|
||||||
|
# class Issue < ActiveRecord::Base
|
||||||
|
# include Participable
|
||||||
|
#
|
||||||
|
# # ...
|
||||||
|
#
|
||||||
|
# participant :author, :assignee, :mentioned_users, :notes
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# issue = Issue.last
|
||||||
|
# users = issue.participants
|
||||||
|
# # `users` will contain the issue's author, its assignee,
|
||||||
|
# # all users returned by its #mentioned_users method,
|
||||||
|
# # as well as all participants to all of the issue's notes,
|
||||||
|
# # since Note implements Participable as well.
|
||||||
|
#
|
||||||
|
module Participable
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
module ClassMethods
|
||||||
|
def participant(*attrs)
|
||||||
|
participant_attrs.concat(attrs.map(&:to_s))
|
||||||
|
end
|
||||||
|
|
||||||
|
def participant_attrs
|
||||||
|
@participant_attrs ||= []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def participants(current_user = self.author)
|
||||||
|
self.class.participant_attrs.flat_map do |attr|
|
||||||
|
meth = method(attr)
|
||||||
|
|
||||||
|
value =
|
||||||
|
if meth.arity == 1
|
||||||
|
meth.call(current_user)
|
||||||
|
else
|
||||||
|
meth.call
|
||||||
|
end
|
||||||
|
|
||||||
|
participants_for(value, current_user)
|
||||||
|
end.compact.uniq
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def participants_for(value, current_user = nil)
|
||||||
|
case value
|
||||||
|
when User
|
||||||
|
[value]
|
||||||
|
when Enumerable, ActiveRecord::Relation
|
||||||
|
value.flat_map { |v| participants_for(v, current_user) }
|
||||||
|
when Participable
|
||||||
|
value.participants(current_user)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -213,10 +213,13 @@ class MergeRequest < ActiveRecord::Base
|
||||||
commits_for_notes_limit = 100
|
commits_for_notes_limit = 100
|
||||||
commit_ids = commits.last(commits_for_notes_limit).map(&:id)
|
commit_ids = commits.last(commits_for_notes_limit).map(&:id)
|
||||||
|
|
||||||
project.notes.where(
|
Note.where(
|
||||||
"(noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR (noteable_type = 'Commit' AND commit_id IN (:commit_ids))",
|
"(project_id = :target_project_id AND noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR" +
|
||||||
|
"(project_id = :source_project_id AND noteable_type = 'Commit' AND commit_id IN (:commit_ids))",
|
||||||
mr_id: id,
|
mr_id: id,
|
||||||
commit_ids: commit_ids
|
commit_ids: commit_ids,
|
||||||
|
target_project_id: target_project_id,
|
||||||
|
source_project_id: source_project_id
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -242,7 +245,7 @@ class MergeRequest < ActiveRecord::Base
|
||||||
}
|
}
|
||||||
|
|
||||||
unless last_commit.nil?
|
unless last_commit.nil?
|
||||||
attrs.merge!(last_commit: last_commit.hook_attrs(source_project))
|
attrs.merge!(last_commit: last_commit.hook_attrs)
|
||||||
end
|
end
|
||||||
|
|
||||||
attributes.merge!(attrs)
|
attributes.merge!(attrs)
|
||||||
|
@ -259,7 +262,7 @@ class MergeRequest < ActiveRecord::Base
|
||||||
# Return the set of issues that will be closed if this merge request is accepted.
|
# Return the set of issues that will be closed if this merge request is accepted.
|
||||||
def closes_issues(current_user = self.author)
|
def closes_issues(current_user = self.author)
|
||||||
if target_branch == project.default_branch
|
if target_branch == project.default_branch
|
||||||
issues = commits.flat_map { |c| c.closes_issues(project, current_user) }
|
issues = commits.flat_map { |c| c.closes_issues(current_user) }
|
||||||
issues.push(*Gitlab::ClosingIssueExtractor.new(project, current_user).
|
issues.push(*Gitlab::ClosingIssueExtractor.new(project, current_user).
|
||||||
closed_by_message(description))
|
closed_by_message(description))
|
||||||
issues.uniq.sort_by(&:id)
|
issues.uniq.sort_by(&:id)
|
||||||
|
|
|
@ -67,7 +67,7 @@ class MergeRequestDiff < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_commits(array)
|
def load_commits(array)
|
||||||
array.map { |hash| Commit.new(Gitlab::Git::Commit.new(hash)) }
|
array.map { |hash| Commit.new(Gitlab::Git::Commit.new(hash), merge_request.source_project) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def dump_diffs(diffs)
|
def dump_diffs(diffs)
|
||||||
|
@ -88,7 +88,7 @@ class MergeRequestDiff < ActiveRecord::Base
|
||||||
commits = compare_result.commits
|
commits = compare_result.commits
|
||||||
|
|
||||||
if commits.present?
|
if commits.present?
|
||||||
commits = Commit.decorate(commits).
|
commits = Commit.decorate(commits, merge_request.source_project).
|
||||||
sort_by(&:created_at).
|
sort_by(&:created_at).
|
||||||
reverse
|
reverse
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,10 +23,12 @@ require 'file_size_validator'
|
||||||
class Note < ActiveRecord::Base
|
class Note < ActiveRecord::Base
|
||||||
include Mentionable
|
include Mentionable
|
||||||
include Gitlab::CurrentSettings
|
include Gitlab::CurrentSettings
|
||||||
|
include Participable
|
||||||
|
|
||||||
default_value_for :system, false
|
default_value_for :system, false
|
||||||
|
|
||||||
attr_mentionable :note
|
attr_mentionable :note
|
||||||
|
participant :author, :mentioned_users
|
||||||
|
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
belongs_to :noteable, polymorphic: true
|
belongs_to :noteable, polymorphic: true
|
||||||
|
@ -77,11 +79,11 @@ class Note < ActiveRecord::Base
|
||||||
# +mentioner+'s description or an associated Note.
|
# +mentioner+'s description or an associated Note.
|
||||||
# Create a system Note associated with +noteable+ with a GFM back-reference
|
# Create a system Note associated with +noteable+ with a GFM back-reference
|
||||||
# to +mentioner+.
|
# to +mentioner+.
|
||||||
def create_cross_reference_note(noteable, mentioner, author, project)
|
def create_cross_reference_note(noteable, mentioner, author)
|
||||||
gfm_reference = mentioner_gfm_ref(noteable, mentioner, project)
|
gfm_reference = mentioner_gfm_ref(noteable, mentioner)
|
||||||
|
|
||||||
note_options = {
|
note_options = {
|
||||||
project: project,
|
project: noteable.project,
|
||||||
author: author,
|
author: author,
|
||||||
note: cross_reference_note_content(gfm_reference),
|
note: cross_reference_note_content(gfm_reference),
|
||||||
system: true
|
system: true
|
||||||
|
@ -236,7 +238,7 @@ class Note < ActiveRecord::Base
|
||||||
|
|
||||||
# Determine whether or not a cross-reference note already exists.
|
# Determine whether or not a cross-reference note already exists.
|
||||||
def cross_reference_exists?(noteable, mentioner)
|
def cross_reference_exists?(noteable, mentioner)
|
||||||
gfm_reference = mentioner_gfm_ref(noteable, mentioner)
|
gfm_reference = mentioner_gfm_ref(noteable, mentioner, true)
|
||||||
notes = if noteable.is_a?(Commit)
|
notes = if noteable.is_a?(Commit)
|
||||||
where(commit_id: noteable.id, noteable_type: 'Commit')
|
where(commit_id: noteable.id, noteable_type: 'Commit')
|
||||||
else
|
else
|
||||||
|
@ -269,43 +271,19 @@ class Note < ActiveRecord::Base
|
||||||
# Prepend the mentioner's namespaced project path to the GFM reference for
|
# Prepend the mentioner's namespaced project path to the GFM reference for
|
||||||
# cross-project references. For same-project references, return the
|
# cross-project references. For same-project references, return the
|
||||||
# unmodified GFM reference.
|
# unmodified GFM reference.
|
||||||
def mentioner_gfm_ref(noteable, mentioner, project = nil)
|
def mentioner_gfm_ref(noteable, mentioner, cross_reference = false)
|
||||||
if mentioner.is_a?(Commit)
|
if mentioner.is_a?(Commit) && cross_reference
|
||||||
if project.nil?
|
|
||||||
return mentioner.gfm_reference.sub('commit ', 'commit %')
|
return mentioner.gfm_reference.sub('commit ', 'commit %')
|
||||||
else
|
|
||||||
mentioning_project = project
|
|
||||||
end
|
|
||||||
else
|
|
||||||
mentioning_project = mentioner.project
|
|
||||||
end
|
end
|
||||||
|
|
||||||
noteable_project_id = noteable_project_id(noteable, mentioning_project)
|
full_gfm_reference(mentioner.project, noteable.project, mentioner)
|
||||||
|
|
||||||
full_gfm_reference(mentioning_project, noteable_project_id, mentioner)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Return the ID of the project that +noteable+ belongs to, or nil if
|
|
||||||
# +noteable+ is a commit and is not part of the project that owns
|
|
||||||
# +mentioner+.
|
|
||||||
def noteable_project_id(noteable, mentioning_project)
|
|
||||||
if noteable.is_a?(Commit)
|
|
||||||
if mentioning_project.repository.commit(noteable.id)
|
|
||||||
# The noteable commit belongs to the mentioner's project
|
|
||||||
mentioning_project.id
|
|
||||||
else
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
else
|
|
||||||
noteable.project.id
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return the +mentioner+ GFM reference. If the mentioner and noteable
|
# Return the +mentioner+ GFM reference. If the mentioner and noteable
|
||||||
# projects are not the same, add the mentioning project's path to the
|
# projects are not the same, add the mentioning project's path to the
|
||||||
# returned value.
|
# returned value.
|
||||||
def full_gfm_reference(mentioning_project, noteable_project_id, mentioner)
|
def full_gfm_reference(mentioning_project, noteable_project, mentioner)
|
||||||
if mentioning_project.id == noteable_project_id
|
if mentioning_project == noteable_project
|
||||||
mentioner.gfm_reference
|
mentioner.gfm_reference
|
||||||
else
|
else
|
||||||
if mentioner.is_a?(Commit)
|
if mentioner.is_a?(Commit)
|
||||||
|
@ -512,7 +490,7 @@ class Note < ActiveRecord::Base
|
||||||
# override to return commits, which are not active record
|
# override to return commits, which are not active record
|
||||||
def noteable
|
def noteable
|
||||||
if for_commit?
|
if for_commit?
|
||||||
project.repository.commit(commit_id)
|
project.commit(commit_id)
|
||||||
else
|
else
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
|
@ -254,7 +254,11 @@ class Project < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def repository
|
def repository
|
||||||
@repository ||= Repository.new(path_with_namespace)
|
@repository ||= Repository.new(path_with_namespace, nil, self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def commit(id = 'HEAD')
|
||||||
|
repository.commit(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def saved?
|
def saved?
|
||||||
|
|
|
@ -112,7 +112,7 @@ class ProjectWiki
|
||||||
end
|
end
|
||||||
|
|
||||||
def repository
|
def repository
|
||||||
Repository.new(path_with_namespace, default_branch)
|
Repository.new(path_with_namespace, default_branch, @project)
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_branch
|
def default_branch
|
||||||
|
|
|
@ -18,6 +18,6 @@ class ProtectedBranch < ActiveRecord::Base
|
||||||
validates :project, presence: true
|
validates :project, presence: true
|
||||||
|
|
||||||
def commit
|
def commit
|
||||||
project.repository.commit(self.name)
|
project.commit(self.name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
class Repository
|
class Repository
|
||||||
include Gitlab::ShellAdapter
|
include Gitlab::ShellAdapter
|
||||||
|
|
||||||
attr_accessor :raw_repository, :path_with_namespace
|
attr_accessor :raw_repository, :path_with_namespace, :project
|
||||||
|
|
||||||
def initialize(path_with_namespace, default_branch = nil)
|
def initialize(path_with_namespace, default_branch = nil, project = nil)
|
||||||
@path_with_namespace = path_with_namespace
|
@path_with_namespace = path_with_namespace
|
||||||
@raw_repository = Gitlab::Git::Repository.new(path_to_repo) if path_with_namespace
|
@raw_repository = Gitlab::Git::Repository.new(path_to_repo) if path_with_namespace
|
||||||
|
@project = project
|
||||||
rescue Gitlab::Git::Repository::NoRepository
|
rescue Gitlab::Git::Repository::NoRepository
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
@ -28,7 +29,7 @@ class Repository
|
||||||
def commit(id = 'HEAD')
|
def commit(id = 'HEAD')
|
||||||
return nil unless raw_repository
|
return nil unless raw_repository
|
||||||
commit = Gitlab::Git::Commit.find(raw_repository, id)
|
commit = Gitlab::Git::Commit.find(raw_repository, id)
|
||||||
commit = Commit.new(commit) if commit
|
commit = Commit.new(commit, @project) if commit
|
||||||
commit
|
commit
|
||||||
rescue Rugged::OdbError
|
rescue Rugged::OdbError
|
||||||
nil
|
nil
|
||||||
|
@ -42,13 +43,13 @@ class Repository
|
||||||
limit: limit,
|
limit: limit,
|
||||||
offset: offset,
|
offset: offset,
|
||||||
)
|
)
|
||||||
commits = Commit.decorate(commits) if commits.present?
|
commits = Commit.decorate(commits, @project) if commits.present?
|
||||||
commits
|
commits
|
||||||
end
|
end
|
||||||
|
|
||||||
def commits_between(from, to)
|
def commits_between(from, to)
|
||||||
commits = Gitlab::Git::Commit.between(raw_repository, from, to)
|
commits = Gitlab::Git::Commit.between(raw_repository, from, to)
|
||||||
commits = Commit.decorate(commits) if commits.present?
|
commits = Commit.decorate(commits, @project) if commits.present?
|
||||||
commits
|
commits
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ class Snippet < ActiveRecord::Base
|
||||||
include Sortable
|
include Sortable
|
||||||
include Linguist::BlobHelper
|
include Linguist::BlobHelper
|
||||||
include Gitlab::VisibilityLevel
|
include Gitlab::VisibilityLevel
|
||||||
|
include Participable
|
||||||
|
|
||||||
default_value_for :visibility_level, Snippet::PRIVATE
|
default_value_for :visibility_level, Snippet::PRIVATE
|
||||||
|
|
||||||
|
@ -47,6 +48,8 @@ class Snippet < ActiveRecord::Base
|
||||||
scope :expired, -> { where(["expires_at IS NOT NULL AND expires_at < ?", Time.current]) }
|
scope :expired, -> { where(["expires_at IS NOT NULL AND expires_at < ?", Time.current]) }
|
||||||
scope :non_expired, -> { where(["expires_at IS NULL OR expires_at > ?", Time.current]) }
|
scope :non_expired, -> { where(["expires_at IS NULL OR expires_at > ?", Time.current]) }
|
||||||
|
|
||||||
|
participant :author, :notes
|
||||||
|
|
||||||
def self.content_types
|
def self.content_types
|
||||||
[
|
[
|
||||||
".rb", ".py", ".pl", ".scala", ".c", ".cpp", ".java",
|
".rb", ".py", ".pl", ".scala", ".c", ".cpp", ".java",
|
||||||
|
@ -87,18 +90,6 @@ class Snippet < ActiveRecord::Base
|
||||||
visibility_level
|
visibility_level
|
||||||
end
|
end
|
||||||
|
|
||||||
def participants(current_user = self.author)
|
|
||||||
users = []
|
|
||||||
users << author
|
|
||||||
|
|
||||||
notes.each do |note|
|
|
||||||
users << note.author
|
|
||||||
users.push *note.mentioned_users(current_user)
|
|
||||||
end
|
|
||||||
|
|
||||||
users.uniq
|
|
||||||
end
|
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def search(query)
|
def search(query)
|
||||||
where('(title LIKE :query OR file_name LIKE :query)', query: "%#{query}%")
|
where('(title LIKE :query OR file_name LIKE :query)', query: "%#{query}%")
|
||||||
|
|
|
@ -38,7 +38,7 @@ class CreateTagService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_push_data(project, user, tag)
|
def create_push_data(project, user, tag)
|
||||||
commits = [project.repository.commit(tag.target)].compact
|
commits = [project.commit(tag.target)].compact
|
||||||
Gitlab::PushDataBuilder.
|
Gitlab::PushDataBuilder.
|
||||||
build(project, user, Gitlab::Git::BLANK_SHA, tag.target, "#{Gitlab::Git::TAG_REF_PREFIX}#{tag.name}", commits, tag.message)
|
build(project, user, Gitlab::Git::BLANK_SHA, tag.target, "#{Gitlab::Git::TAG_REF_PREFIX}#{tag.name}", commits, tag.message)
|
||||||
end
|
end
|
||||||
|
|
|
@ -70,7 +70,7 @@ class GitPushService
|
||||||
# Close issues if these commits were pushed to the project's default branch and the commit message matches the
|
# Close issues if these commits were pushed to the project's default branch and the commit message matches the
|
||||||
# closing regex. Exclude any mentioned Issues from cross-referencing even if the commits are being pushed to
|
# closing regex. Exclude any mentioned Issues from cross-referencing even if the commits are being pushed to
|
||||||
# a different branch.
|
# a different branch.
|
||||||
issues_to_close = commit.closes_issues(project, user)
|
issues_to_close = commit.closes_issues(user)
|
||||||
|
|
||||||
# Load commit author only if needed.
|
# Load commit author only if needed.
|
||||||
# For push with 1k commits it prevents 900+ requests in database
|
# For push with 1k commits it prevents 900+ requests in database
|
||||||
|
@ -94,7 +94,7 @@ class GitPushService
|
||||||
author ||= commit_user(commit)
|
author ||= commit_user(commit)
|
||||||
|
|
||||||
refs.each do |r|
|
refs.each do |r|
|
||||||
Note.create_cross_reference_note(r, commit, author, project)
|
Note.create_cross_reference_note(r, commit, author)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,7 +25,7 @@ class GitTagPushService
|
||||||
tag_name = Gitlab::Git.ref_name(ref)
|
tag_name = Gitlab::Git.ref_name(ref)
|
||||||
tag = project.repository.find_tag(tag_name)
|
tag = project.repository.find_tag(tag_name)
|
||||||
if tag && tag.target == newrev
|
if tag && tag.target == newrev
|
||||||
commit = project.repository.commit(tag.target)
|
commit = project.commit(tag.target)
|
||||||
commits = [commit].compact
|
commits = [commit].compact
|
||||||
message = tag.message
|
message = tag.message
|
||||||
end
|
end
|
||||||
|
|
|
@ -29,7 +29,7 @@ module MergeRequests
|
||||||
# At this point we decide if merge request can be created
|
# At this point we decide if merge request can be created
|
||||||
# If we have at least one commit to merge -> creation allowed
|
# If we have at least one commit to merge -> creation allowed
|
||||||
if commits.present?
|
if commits.present?
|
||||||
merge_request.compare_commits = Commit.decorate(commits)
|
merge_request.compare_commits = Commit.decorate(commits, merge_request.source_project)
|
||||||
merge_request.can_be_created = true
|
merge_request.can_be_created = true
|
||||||
merge_request.compare_failed = false
|
merge_request.compare_failed = false
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ module Notes
|
||||||
# Create a cross-reference note if this Note contains GFM that names an
|
# Create a cross-reference note if this Note contains GFM that names an
|
||||||
# issue, merge request, or commit.
|
# issue, merge request, or commit.
|
||||||
note.references.each do |mentioned|
|
note.references.each do |mentioned|
|
||||||
Note.create_cross_reference_note(mentioned, note.noteable, note.author, note.project)
|
Note.create_cross_reference_note(mentioned, note.noteable, note.author)
|
||||||
end
|
end
|
||||||
|
|
||||||
execute_hooks(note)
|
execute_hooks(note)
|
||||||
|
|
|
@ -13,8 +13,7 @@ module Notes
|
||||||
# Create a cross-reference note if this Note contains GFM that
|
# Create a cross-reference note if this Note contains GFM that
|
||||||
# names an issue, merge request, or commit.
|
# names an issue, merge request, or commit.
|
||||||
note.references.each do |mentioned|
|
note.references.each do |mentioned|
|
||||||
Note.create_cross_reference_note(mentioned, note.noteable,
|
Note.create_cross_reference_note(mentioned, note.noteable, note.author)
|
||||||
note.author, note.project)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -129,9 +129,7 @@ class NotificationService
|
||||||
|
|
||||||
# Add all users participating in the thread (author, assignee, comment authors)
|
# Add all users participating in the thread (author, assignee, comment authors)
|
||||||
participants =
|
participants =
|
||||||
if target.is_a?(Commit)
|
if target.respond_to?(:participants)
|
||||||
target.participants(note.project, note.author)
|
|
||||||
elsif target.respond_to?(:participants)
|
|
||||||
target.participants(note.author)
|
target.participants(note.author)
|
||||||
else
|
else
|
||||||
note.mentioned_users
|
note.mentioned_users
|
||||||
|
|
|
@ -13,21 +13,19 @@ module Projects
|
||||||
end
|
end
|
||||||
|
|
||||||
def participants_in(type, id)
|
def participants_in(type, id)
|
||||||
users =
|
target =
|
||||||
case type
|
case type
|
||||||
when "Issue"
|
when "Issue"
|
||||||
issue = project.issues.find_by_iid(id)
|
project.issues.find_by_iid(id)
|
||||||
issue.participants(current_user) if issue
|
|
||||||
when "MergeRequest"
|
when "MergeRequest"
|
||||||
merge_request = project.merge_requests.find_by_iid(id)
|
project.merge_requests.find_by_iid(id)
|
||||||
merge_request.participants(current_user) if merge_request
|
|
||||||
when "Commit"
|
when "Commit"
|
||||||
commit = project.repository.commit(id)
|
project.commit(id)
|
||||||
commit.participants(project, current_user) if commit
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return [] unless users
|
return [] unless target
|
||||||
|
|
||||||
|
users = target.participants(current_user)
|
||||||
sorted(users)
|
sorted(users)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
.file-content.blame.highlight
|
.file-content.blame.highlight
|
||||||
%table
|
%table
|
||||||
- @blame.each do |commit, lines, since|
|
- @blame.each do |commit, lines, since|
|
||||||
- commit = Commit.new(commit)
|
- commit = Commit.new(commit, @project)
|
||||||
%tr
|
%tr
|
||||||
%td.blame-commit
|
%td.blame-commit
|
||||||
%span.commit
|
%span.commit
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
- if @note_counts
|
- if @note_counts
|
||||||
- note_count = @note_counts.fetch(commit.id, 0)
|
- note_count = @note_counts.fetch(commit.id, 0)
|
||||||
- else
|
- else
|
||||||
- notes = commit.notes(project)
|
- notes = commit.notes
|
||||||
- note_count = notes.user.count
|
- note_count = notes.user.count
|
||||||
|
|
||||||
- if note_count > 0
|
- if note_count > 0
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
Commits (#{@commits.count})
|
Commits (#{@commits.count})
|
||||||
- if @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
|
- if @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
|
||||||
%ul.well-list
|
%ul.well-list
|
||||||
- Commit.decorate(@commits.first(MergeRequestDiff::COMMITS_SAFE_SIZE)).each do |commit|
|
- Commit.decorate(@commits.first(MergeRequestDiff::COMMITS_SAFE_SIZE), @project).each do |commit|
|
||||||
= render "projects/commits/inline_commit", commit: commit, project: @project
|
= render "projects/commits/inline_commit", commit: commit, project: @project
|
||||||
%li.warning-row.unstyled
|
%li.warning-row.unstyled
|
||||||
other #{@commits.size - MergeRequestDiff::COMMITS_SAFE_SIZE} commits hidden to prevent performance issues.
|
other #{@commits.size - MergeRequestDiff::COMMITS_SAFE_SIZE} commits hidden to prevent performance issues.
|
||||||
- else
|
- else
|
||||||
%ul.well-list= render Commit.decorate(@commits), project: @project
|
%ul.well-list= render Commit.decorate(@commits, @project), project: @project
|
||||||
|
|
|
@ -137,8 +137,7 @@ class IrkerWorker
|
||||||
end
|
end
|
||||||
|
|
||||||
def commit_from_id(project, id)
|
def commit_from_id(project, id)
|
||||||
commit = Gitlab::Git::Commit.find(project.repository, id)
|
project.commit(id)
|
||||||
Commit.new(commit)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def files_count(commit)
|
def files_count(commit)
|
||||||
|
|
|
@ -32,7 +32,7 @@ module API
|
||||||
# GET /projects/:id/repository/commits/:sha
|
# GET /projects/:id/repository/commits/:sha
|
||||||
get ":id/repository/commits/:sha" do
|
get ":id/repository/commits/:sha" do
|
||||||
sha = params[:sha]
|
sha = params[:sha]
|
||||||
commit = user_project.repository.commit(sha)
|
commit = user_project.commit(sha)
|
||||||
not_found! "Commit" unless commit
|
not_found! "Commit" unless commit
|
||||||
present commit, with: Entities::RepoCommitDetail
|
present commit, with: Entities::RepoCommitDetail
|
||||||
end
|
end
|
||||||
|
@ -46,7 +46,7 @@ module API
|
||||||
# GET /projects/:id/repository/commits/:sha/diff
|
# GET /projects/:id/repository/commits/:sha/diff
|
||||||
get ":id/repository/commits/:sha/diff" do
|
get ":id/repository/commits/:sha/diff" do
|
||||||
sha = params[:sha]
|
sha = params[:sha]
|
||||||
commit = user_project.repository.commit(sha)
|
commit = user_project.commit(sha)
|
||||||
not_found! "Commit" unless commit
|
not_found! "Commit" unless commit
|
||||||
commit.diffs
|
commit.diffs
|
||||||
end
|
end
|
||||||
|
@ -60,7 +60,7 @@ module API
|
||||||
# GET /projects/:id/repository/commits/:sha/comments
|
# GET /projects/:id/repository/commits/:sha/comments
|
||||||
get ':id/repository/commits/:sha/comments' do
|
get ':id/repository/commits/:sha/comments' do
|
||||||
sha = params[:sha]
|
sha = params[:sha]
|
||||||
commit = user_project.repository.commit(sha)
|
commit = user_project.commit(sha)
|
||||||
not_found! 'Commit' unless commit
|
not_found! 'Commit' unless commit
|
||||||
notes = Note.where(commit_id: commit.id)
|
notes = Note.where(commit_id: commit.id)
|
||||||
present paginate(notes), with: Entities::CommitNote
|
present paginate(notes), with: Entities::CommitNote
|
||||||
|
@ -81,7 +81,7 @@ module API
|
||||||
required_attributes! [:note]
|
required_attributes! [:note]
|
||||||
|
|
||||||
sha = params[:sha]
|
sha = params[:sha]
|
||||||
commit = user_project.repository.commit(sha)
|
commit = user_project.commit(sha)
|
||||||
not_found! 'Commit' unless commit
|
not_found! 'Commit' unless commit
|
||||||
opts = {
|
opts = {
|
||||||
note: params[:note],
|
note: params[:note],
|
||||||
|
|
|
@ -251,11 +251,11 @@ module API
|
||||||
|
|
||||||
class Compare < Grape::Entity
|
class Compare < Grape::Entity
|
||||||
expose :commit, using: Entities::RepoCommit do |compare, options|
|
expose :commit, using: Entities::RepoCommit do |compare, options|
|
||||||
Commit.decorate(compare.commits).last
|
Commit.decorate(compare.commits, nil).last
|
||||||
end
|
end
|
||||||
|
|
||||||
expose :commits, using: Entities::RepoCommit do |compare, options|
|
expose :commits, using: Entities::RepoCommit do |compare, options|
|
||||||
Commit.decorate(compare.commits)
|
Commit.decorate(compare.commits, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
expose :diffs, using: Entities::RepoDiff do |compare, options|
|
expose :diffs, using: Entities::RepoDiff do |compare, options|
|
||||||
|
|
|
@ -34,7 +34,7 @@ module API
|
||||||
ref = attrs.delete(:ref)
|
ref = attrs.delete(:ref)
|
||||||
file_path = attrs.delete(:file_path)
|
file_path = attrs.delete(:file_path)
|
||||||
|
|
||||||
commit = user_project.repository.commit(ref)
|
commit = user_project.commit(ref)
|
||||||
not_found! 'Commit' unless commit
|
not_found! 'Commit' unless commit
|
||||||
|
|
||||||
blob = user_project.repository.blob_at(commit.sha, file_path)
|
blob = user_project.repository.blob_at(commit.sha, file_path)
|
||||||
|
|
|
@ -62,7 +62,7 @@ module API
|
||||||
ref = params[:ref_name] || user_project.try(:default_branch) || 'master'
|
ref = params[:ref_name] || user_project.try(:default_branch) || 'master'
|
||||||
path = params[:path] || nil
|
path = params[:path] || nil
|
||||||
|
|
||||||
commit = user_project.repository.commit(ref)
|
commit = user_project.commit(ref)
|
||||||
not_found!('Tree') unless commit
|
not_found!('Tree') unless commit
|
||||||
|
|
||||||
tree = user_project.repository.tree(commit.id, path)
|
tree = user_project.repository.tree(commit.id, path)
|
||||||
|
|
|
@ -5,7 +5,7 @@ module Gitlab
|
||||||
def identify(identifier, project, newrev)
|
def identify(identifier, project, newrev)
|
||||||
if identifier.blank?
|
if identifier.blank?
|
||||||
# Local push from gitlab
|
# Local push from gitlab
|
||||||
email = project.repository.commit(newrev).author_email rescue nil
|
email = project.commit(newrev).author_email rescue nil
|
||||||
User.find_by(email: email) if email
|
User.find_by(email: email) if email
|
||||||
|
|
||||||
elsif identifier =~ /\Auser-\d+\Z/
|
elsif identifier =~ /\Auser-\d+\Z/
|
||||||
|
|
|
@ -84,7 +84,7 @@ module Gitlab
|
||||||
|
|
||||||
def commit(id)
|
def commit(id)
|
||||||
unless @commit_map[id]
|
unless @commit_map[id]
|
||||||
@commit_map[id] = project.repository.commit(id)
|
@commit_map[id] = project.commit(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
@commit_map[id]
|
@commit_map[id]
|
||||||
|
|
|
@ -66,7 +66,7 @@ module Gitlab
|
||||||
|
|
||||||
def commit_from_ref(project, commit_ref)
|
def commit_from_ref(project, commit_ref)
|
||||||
if project && project.valid_repo?
|
if project && project.valid_repo?
|
||||||
project.repository.commit(commit_ref)
|
project.commit(commit_ref)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -69,8 +69,8 @@ module Gitlab
|
||||||
|
|
||||||
def build_data_for_commit(project, user, note)
|
def build_data_for_commit(project, user, note)
|
||||||
# commit_id is the SHA hash
|
# commit_id is the SHA hash
|
||||||
commit = project.repository.commit(note.commit_id)
|
commit = project.commit(note.commit_id)
|
||||||
commit.hook_attrs(project)
|
commit.hook_attrs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,9 +30,7 @@ module Gitlab
|
||||||
|
|
||||||
# For performance purposes maximum 20 latest commits
|
# For performance purposes maximum 20 latest commits
|
||||||
# will be passed as post receive hook data.
|
# will be passed as post receive hook data.
|
||||||
commit_attrs = commits_limited.map do |commit|
|
commit_attrs = commits_limited.map(&:hook_attrs)
|
||||||
commit.hook_attrs(project)
|
|
||||||
end
|
|
||||||
|
|
||||||
type = Gitlab::Git.tag_ref?(ref) ? "tag_push" : "push"
|
type = Gitlab::Git.tag_ref?(ref) ? "tag_push" : "push"
|
||||||
# Hash to be passed as post_receive_data
|
# Hash to be passed as post_receive_data
|
||||||
|
|
|
@ -3,7 +3,7 @@ require 'spec_helper'
|
||||||
describe Projects::CommitController do
|
describe Projects::CommitController do
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
let(:commit) { project.repository.commit("master") }
|
let(:commit) { project.commit("master") }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_in(user)
|
sign_in(user)
|
||||||
|
|
|
@ -14,7 +14,7 @@ describe "GitLab Flavored Markdown", feature: true do
|
||||||
Commit.any_instance.stub(title: "fix ##{issue.iid}\n\nask @#{fred.username} for details")
|
Commit.any_instance.stub(title: "fix ##{issue.iid}\n\nask @#{fred.username} for details")
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:commit) { project.repository.commit }
|
let(:commit) { project.commit }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
login_as :user
|
login_as :user
|
||||||
|
|
|
@ -4,7 +4,7 @@ describe DiffHelper do
|
||||||
include RepoHelpers
|
include RepoHelpers
|
||||||
|
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let(:commit) { project.repository.commit(sample_commit.id) }
|
let(:commit) { project.commit(sample_commit.id) }
|
||||||
let(:diff) { commit.diffs.first }
|
let(:diff) { commit.diffs.first }
|
||||||
let(:diff_file) { Gitlab::Diff::File.new(diff) }
|
let(:diff_file) { Gitlab::Diff::File.new(diff) }
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ describe GitlabMarkdownHelper do
|
||||||
let!(:project) { create(:project) }
|
let!(:project) { create(:project) }
|
||||||
|
|
||||||
let(:user) { create(:user, username: 'gfm') }
|
let(:user) { create(:user, username: 'gfm') }
|
||||||
let(:commit) { project.repository.commit }
|
let(:commit) { project.commit }
|
||||||
let(:issue) { create(:issue, project: project) }
|
let(:issue) { create(:issue, project: project) }
|
||||||
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
|
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
|
||||||
let(:snippet) { create(:project_snippet, project: project) }
|
let(:snippet) { create(:project_snippet, project: project) }
|
||||||
|
|
|
@ -6,7 +6,7 @@ describe TreeHelper do
|
||||||
|
|
||||||
before {
|
before {
|
||||||
@repository = project.repository
|
@repository = project.repository
|
||||||
@commit = project.repository.commit("e56497bb")
|
@commit = project.commit("e56497bb")
|
||||||
}
|
}
|
||||||
|
|
||||||
context "on a directory containing more than one file/directory" do
|
context "on a directory containing more than one file/directory" do
|
||||||
|
|
|
@ -4,7 +4,7 @@ describe Gitlab::Diff::File do
|
||||||
include RepoHelpers
|
include RepoHelpers
|
||||||
|
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let(:commit) { project.repository.commit(sample_commit.id) }
|
let(:commit) { project.commit(sample_commit.id) }
|
||||||
let(:diff) { commit.diffs.first }
|
let(:diff) { commit.diffs.first }
|
||||||
let(:diff_file) { Gitlab::Diff::File.new(diff) }
|
let(:diff_file) { Gitlab::Diff::File.new(diff) }
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ describe Gitlab::Diff::Parser do
|
||||||
include RepoHelpers
|
include RepoHelpers
|
||||||
|
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let(:commit) { project.repository.commit(sample_commit.id) }
|
let(:commit) { project.commit(sample_commit.id) }
|
||||||
let(:diff) { commit.diffs.first }
|
let(:diff) { commit.diffs.first }
|
||||||
let(:parser) { Gitlab::Diff::Parser.new }
|
let(:parser) { Gitlab::Diff::Parser.new }
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@ module Gitlab::Markdown
|
||||||
include ReferenceFilterSpecHelper
|
include ReferenceFilterSpecHelper
|
||||||
|
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let(:commit1) { project.repository.commit }
|
let(:commit1) { project.commit }
|
||||||
let(:commit2) { project.repository.commit("HEAD~2") }
|
let(:commit2) { project.commit("HEAD~2") }
|
||||||
|
|
||||||
it 'requires project context' do
|
it 'requires project context' do
|
||||||
expect { described_class.call('Commit Range 1c002d..d200c1', {}) }.
|
expect { described_class.call('Commit Range 1c002d..d200c1', {}) }.
|
||||||
|
@ -86,8 +86,8 @@ module Gitlab::Markdown
|
||||||
context 'cross-project reference' do
|
context 'cross-project reference' do
|
||||||
let(:namespace) { create(:namespace, name: 'cross-reference') }
|
let(:namespace) { create(:namespace, name: 'cross-reference') }
|
||||||
let(:project2) { create(:project, namespace: namespace) }
|
let(:project2) { create(:project, namespace: namespace) }
|
||||||
let(:commit1) { project.repository.commit }
|
let(:commit1) { project.commit }
|
||||||
let(:commit2) { project.repository.commit("HEAD~2") }
|
let(:commit2) { project.commit("HEAD~2") }
|
||||||
let(:reference) { "#{project2.path_with_namespace}@#{commit1.id}...#{commit2.id}" }
|
let(:reference) { "#{project2.path_with_namespace}@#{commit1.id}...#{commit2.id}" }
|
||||||
|
|
||||||
context 'when user can access reference' do
|
context 'when user can access reference' do
|
||||||
|
|
|
@ -5,7 +5,7 @@ module Gitlab::Markdown
|
||||||
include ReferenceFilterSpecHelper
|
include ReferenceFilterSpecHelper
|
||||||
|
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let(:commit) { project.repository.commit }
|
let(:commit) { project.commit }
|
||||||
|
|
||||||
it 'requires project context' do
|
it 'requires project context' do
|
||||||
expect { described_class.call('Commit 1c002d', {}) }.
|
expect { described_class.call('Commit 1c002d', {}) }.
|
||||||
|
@ -80,7 +80,7 @@ module Gitlab::Markdown
|
||||||
context 'cross-project reference' do
|
context 'cross-project reference' do
|
||||||
let(:namespace) { create(:namespace, name: 'cross-reference') }
|
let(:namespace) { create(:namespace, name: 'cross-reference') }
|
||||||
let(:project2) { create(:project, namespace: namespace) }
|
let(:project2) { create(:project, namespace: namespace) }
|
||||||
let(:commit) { project.repository.commit }
|
let(:commit) { project.commit }
|
||||||
let(:reference) { "#{project2.path_with_namespace}@#{commit.id}" }
|
let(:reference) { "#{project2.path_with_namespace}@#{commit.id}" }
|
||||||
|
|
||||||
context 'when user can access reference' do
|
context 'when user can access reference' do
|
||||||
|
|
|
@ -125,7 +125,7 @@ describe Gitlab::ReferenceExtractor do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'accesses valid commits' do
|
it 'accesses valid commits' do
|
||||||
commit = project.repository.commit('master')
|
commit = project.commit('master')
|
||||||
|
|
||||||
subject.analyze("this references commits #{commit.sha[0..6]} and 012345")
|
subject.analyze("this references commits #{commit.sha[0..6]} and 012345")
|
||||||
extracted = subject.commits
|
extracted = subject.commits
|
||||||
|
@ -135,8 +135,8 @@ describe Gitlab::ReferenceExtractor do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'accesses valid commit ranges' do
|
it 'accesses valid commit ranges' do
|
||||||
commit = project.repository.commit('master')
|
commit = project.commit('master')
|
||||||
earlier_commit = project.repository.commit('master~2')
|
earlier_commit = project.commit('master~2')
|
||||||
|
|
||||||
subject.analyze("this references commits #{earlier_commit.sha[0..6]}...#{commit.sha[0..6]}")
|
subject.analyze("this references commits #{earlier_commit.sha[0..6]}...#{commit.sha[0..6]}")
|
||||||
extracted = subject.commit_ranges
|
extracted = subject.commit_ranges
|
||||||
|
|
|
@ -466,7 +466,7 @@ describe Notify do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'on a commit' do
|
describe 'on a commit' do
|
||||||
let(:commit) { project.repository.commit }
|
let(:commit) { project.commit }
|
||||||
|
|
||||||
before(:each) { allow(note).to receive(:noteable).and_return(commit) }
|
before(:each) { allow(note).to receive(:noteable).and_return(commit) }
|
||||||
|
|
||||||
|
@ -670,8 +670,8 @@ describe Notify do
|
||||||
let(:example_site_path) { root_path }
|
let(:example_site_path) { root_path }
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
let(:compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_image_commit.id, sample_commit.id) }
|
let(:compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_image_commit.id, sample_commit.id) }
|
||||||
let(:commits) { Commit.decorate(compare.commits) }
|
let(:commits) { Commit.decorate(compare.commits, nil) }
|
||||||
let(:diff_path) { namespace_project_compare_path(project.namespace, project, from: Commit.new(compare.base), to: Commit.new(compare.head)) }
|
let(:diff_path) { namespace_project_compare_path(project.namespace, project, from: Commit.new(compare.base, project), to: Commit.new(compare.head, project)) }
|
||||||
let(:send_from_committer_email) { false }
|
let(:send_from_committer_email) { false }
|
||||||
|
|
||||||
subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare, reverse_compare: false, send_from_committer_email: send_from_committer_email) }
|
subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare, reverse_compare: false, send_from_committer_email: send_from_committer_email) }
|
||||||
|
@ -774,7 +774,7 @@ describe Notify do
|
||||||
let(:example_site_path) { root_path }
|
let(:example_site_path) { root_path }
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
let(:compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_commit.parent_id, sample_commit.id) }
|
let(:compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_commit.parent_id, sample_commit.id) }
|
||||||
let(:commits) { Commit.decorate(compare.commits) }
|
let(:commits) { Commit.decorate(compare.commits, nil) }
|
||||||
let(:diff_path) { namespace_project_commit_path(project.namespace, project, commits.first) }
|
let(:diff_path) { namespace_project_commit_path(project.namespace, project, commits.first) }
|
||||||
|
|
||||||
subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare) }
|
subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare) }
|
||||||
|
|
|
@ -2,7 +2,7 @@ require 'spec_helper'
|
||||||
|
|
||||||
describe Commit do
|
describe Commit do
|
||||||
let(:project) { create :project }
|
let(:project) { create :project }
|
||||||
let(:commit) { project.repository.commit }
|
let(:commit) { project.commit }
|
||||||
|
|
||||||
describe '#title' do
|
describe '#title' do
|
||||||
it "returns no_commit_message when safe_message is blank" do
|
it "returns no_commit_message when safe_message is blank" do
|
||||||
|
@ -58,13 +58,13 @@ eos
|
||||||
|
|
||||||
it 'detects issues that this commit is marked as closing' do
|
it 'detects issues that this commit is marked as closing' do
|
||||||
commit.stub(safe_message: "Fixes ##{issue.iid}")
|
commit.stub(safe_message: "Fixes ##{issue.iid}")
|
||||||
expect(commit.closes_issues(project)).to eq([issue])
|
expect(commit.closes_issues).to eq([issue])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not detect issues from other projects' do
|
it 'does not detect issues from other projects' do
|
||||||
ext_ref = "#{other_project.path_with_namespace}##{other_issue.iid}"
|
ext_ref = "#{other_project.path_with_namespace}##{other_issue.iid}"
|
||||||
commit.stub(safe_message: "Fixes #{ext_ref}")
|
commit.stub(safe_message: "Fixes #{ext_ref}")
|
||||||
expect(commit.closes_issues(project)).to be_empty
|
expect(commit.closes_issues).to be_empty
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -329,13 +329,13 @@ describe Note do
|
||||||
let(:author) { create(:user) }
|
let(:author) { create(:user) }
|
||||||
let(:issue) { create(:issue, project: project) }
|
let(:issue) { create(:issue, project: project) }
|
||||||
let(:mergereq) { create(:merge_request, :simple, target_project: project, source_project: project) }
|
let(:mergereq) { create(:merge_request, :simple, target_project: project, source_project: project) }
|
||||||
let(:commit) { project.repository.commit }
|
let(:commit) { project.commit }
|
||||||
|
|
||||||
# Test all of {issue, merge request, commit} in both the referenced and referencing
|
# Test all of {issue, merge request, commit} in both the referenced and referencing
|
||||||
# roles, to ensure that the correct information can be inferred from any argument.
|
# roles, to ensure that the correct information can be inferred from any argument.
|
||||||
|
|
||||||
context 'issue from a merge request' do
|
context 'issue from a merge request' do
|
||||||
subject { Note.create_cross_reference_note(issue, mergereq, author, project) }
|
subject { Note.create_cross_reference_note(issue, mergereq, author) }
|
||||||
|
|
||||||
it { is_expected.to be_valid }
|
it { is_expected.to be_valid }
|
||||||
|
|
||||||
|
@ -361,7 +361,7 @@ describe Note do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'issue from a commit' do
|
context 'issue from a commit' do
|
||||||
subject { Note.create_cross_reference_note(issue, commit, author, project) }
|
subject { Note.create_cross_reference_note(issue, commit, author) }
|
||||||
|
|
||||||
it { is_expected.to be_valid }
|
it { is_expected.to be_valid }
|
||||||
|
|
||||||
|
@ -377,7 +377,7 @@ describe Note do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'merge request from an issue' do
|
context 'merge request from an issue' do
|
||||||
subject { Note.create_cross_reference_note(mergereq, issue, author, project) }
|
subject { Note.create_cross_reference_note(mergereq, issue, author) }
|
||||||
|
|
||||||
it { is_expected.to be_valid }
|
it { is_expected.to be_valid }
|
||||||
|
|
||||||
|
@ -398,7 +398,7 @@ describe Note do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'commit from a merge request' do
|
context 'commit from a merge request' do
|
||||||
subject { Note.create_cross_reference_note(commit, mergereq, author, project) }
|
subject { Note.create_cross_reference_note(commit, mergereq, author) }
|
||||||
|
|
||||||
it { is_expected.to be_valid }
|
it { is_expected.to be_valid }
|
||||||
|
|
||||||
|
@ -419,13 +419,13 @@ describe Note do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'commit contained in a merge request' do
|
context 'commit contained in a merge request' do
|
||||||
subject { Note.create_cross_reference_note(mergereq.commits.first, mergereq, author, project) }
|
subject { Note.create_cross_reference_note(mergereq.commits.first, mergereq, author) }
|
||||||
|
|
||||||
it { is_expected.to be_nil }
|
it { is_expected.to be_nil }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'commit from issue' do
|
context 'commit from issue' do
|
||||||
subject { Note.create_cross_reference_note(commit, issue, author, project) }
|
subject { Note.create_cross_reference_note(commit, issue, author) }
|
||||||
|
|
||||||
it { is_expected.to be_valid }
|
it { is_expected.to be_valid }
|
||||||
|
|
||||||
|
@ -452,7 +452,7 @@ describe Note do
|
||||||
|
|
||||||
context 'commit from commit' do
|
context 'commit from commit' do
|
||||||
let(:parent_commit) { commit.parents.first }
|
let(:parent_commit) { commit.parents.first }
|
||||||
subject { Note.create_cross_reference_note(commit, parent_commit, author, project) }
|
subject { Note.create_cross_reference_note(commit, parent_commit, author) }
|
||||||
|
|
||||||
it { is_expected.to be_valid }
|
it { is_expected.to be_valid }
|
||||||
|
|
||||||
|
@ -482,11 +482,11 @@ describe Note do
|
||||||
let(:project) { create :project }
|
let(:project) { create :project }
|
||||||
let(:author) { create :user }
|
let(:author) { create :user }
|
||||||
let(:issue) { create :issue }
|
let(:issue) { create :issue }
|
||||||
let(:commit0) { project.repository.commit }
|
let(:commit0) { project.commit }
|
||||||
let(:commit1) { project.repository.commit('HEAD~2') }
|
let(:commit1) { project.commit('HEAD~2') }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Note.create_cross_reference_note(issue, commit0, author, project)
|
Note.create_cross_reference_note(issue, commit0, author)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'detects if a mentionable has already been mentioned' do
|
it 'detects if a mentionable has already been mentioned' do
|
||||||
|
@ -499,7 +499,7 @@ describe Note do
|
||||||
|
|
||||||
context 'commit on commit' do
|
context 'commit on commit' do
|
||||||
before do
|
before do
|
||||||
Note.create_cross_reference_note(commit0, commit1, author, project)
|
Note.create_cross_reference_note(commit0, commit1, author)
|
||||||
end
|
end
|
||||||
|
|
||||||
it { expect(Note.cross_reference_exists?(commit0, commit1)).to be_truthy }
|
it { expect(Note.cross_reference_exists?(commit0, commit1)).to be_truthy }
|
||||||
|
@ -527,7 +527,7 @@ describe Note do
|
||||||
let(:author) { create :user }
|
let(:author) { create :user }
|
||||||
let(:issue0) { create :issue, project: project }
|
let(:issue0) { create :issue, project: project }
|
||||||
let(:issue1) { create :issue, project: second_project }
|
let(:issue1) { create :issue, project: second_project }
|
||||||
let!(:note) { Note.create_cross_reference_note(issue0, issue1, author, project) }
|
let!(:note) { Note.create_cross_reference_note(issue0, issue1, author) }
|
||||||
|
|
||||||
it 'detects if a mentionable has already been mentioned' do
|
it 'detects if a mentionable has already been mentioned' do
|
||||||
expect(Note.cross_reference_exists?(issue0, issue1)).to be_truthy
|
expect(Note.cross_reference_exists?(issue0, issue1)).to be_truthy
|
||||||
|
@ -562,7 +562,7 @@ describe Note do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should identify cross-reference notes as system notes' do
|
it 'should identify cross-reference notes as system notes' do
|
||||||
@note = Note.create_cross_reference_note(issue, other, author, project)
|
@note = Note.create_cross_reference_note(issue, other, author)
|
||||||
expect(@note).to be_system
|
expect(@note).to be_system
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ describe GitPushService do
|
||||||
before do
|
before do
|
||||||
service.execute(project, user, @oldrev, @newrev, @ref)
|
service.execute(project, user, @oldrev, @newrev, @ref)
|
||||||
@push_data = service.push_data
|
@push_data = service.push_data
|
||||||
@commit = project.repository.commit(@newrev)
|
@commit = project.commit(@newrev)
|
||||||
end
|
end
|
||||||
|
|
||||||
subject { @push_data }
|
subject { @push_data }
|
||||||
|
@ -151,7 +151,7 @@ describe GitPushService do
|
||||||
describe "cross-reference notes" do
|
describe "cross-reference notes" do
|
||||||
let(:issue) { create :issue, project: project }
|
let(:issue) { create :issue, project: project }
|
||||||
let(:commit_author) { create :user }
|
let(:commit_author) { create :user }
|
||||||
let(:commit) { project.repository.commit }
|
let(:commit) { project.commit }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
commit.stub({
|
commit.stub({
|
||||||
|
@ -164,22 +164,22 @@ describe GitPushService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates a note if a pushed commit mentions an issue" do
|
it "creates a note if a pushed commit mentions an issue" do
|
||||||
expect(Note).to receive(:create_cross_reference_note).with(issue, commit, commit_author, project)
|
expect(Note).to receive(:create_cross_reference_note).with(issue, commit, commit_author)
|
||||||
|
|
||||||
service.execute(project, user, @oldrev, @newrev, @ref)
|
service.execute(project, user, @oldrev, @newrev, @ref)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "only creates a cross-reference note if one doesn't already exist" do
|
it "only creates a cross-reference note if one doesn't already exist" do
|
||||||
Note.create_cross_reference_note(issue, commit, user, project)
|
Note.create_cross_reference_note(issue, commit, user)
|
||||||
|
|
||||||
expect(Note).not_to receive(:create_cross_reference_note).with(issue, commit, commit_author, project)
|
expect(Note).not_to receive(:create_cross_reference_note).with(issue, commit, commit_author)
|
||||||
|
|
||||||
service.execute(project, user, @oldrev, @newrev, @ref)
|
service.execute(project, user, @oldrev, @newrev, @ref)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "defaults to the pushing user if the commit's author is not known" do
|
it "defaults to the pushing user if the commit's author is not known" do
|
||||||
commit.stub(author_name: 'unknown name', author_email: 'unknown@email.com')
|
commit.stub(author_name: 'unknown name', author_email: 'unknown@email.com')
|
||||||
expect(Note).to receive(:create_cross_reference_note).with(issue, commit, user, project)
|
expect(Note).to receive(:create_cross_reference_note).with(issue, commit, user)
|
||||||
|
|
||||||
service.execute(project, user, @oldrev, @newrev, @ref)
|
service.execute(project, user, @oldrev, @newrev, @ref)
|
||||||
end
|
end
|
||||||
|
@ -188,7 +188,7 @@ describe GitPushService do
|
||||||
allow(project.repository).to receive(:commits_between).with(@blankrev, @newrev).and_return([])
|
allow(project.repository).to receive(:commits_between).with(@blankrev, @newrev).and_return([])
|
||||||
allow(project.repository).to receive(:commits_between).with("master", @newrev).and_return([commit])
|
allow(project.repository).to receive(:commits_between).with("master", @newrev).and_return([commit])
|
||||||
|
|
||||||
expect(Note).to receive(:create_cross_reference_note).with(issue, commit, commit_author, project)
|
expect(Note).to receive(:create_cross_reference_note).with(issue, commit, commit_author)
|
||||||
|
|
||||||
service.execute(project, user, @blankrev, @newrev, 'refs/heads/other')
|
service.execute(project, user, @blankrev, @newrev, 'refs/heads/other')
|
||||||
end
|
end
|
||||||
|
@ -198,7 +198,7 @@ describe GitPushService do
|
||||||
let(:issue) { create :issue, project: project }
|
let(:issue) { create :issue, project: project }
|
||||||
let(:other_issue) { create :issue, project: project }
|
let(:other_issue) { create :issue, project: project }
|
||||||
let(:commit_author) { create :user }
|
let(:commit_author) { create :user }
|
||||||
let(:closing_commit) { project.repository.commit }
|
let(:closing_commit) { project.commit }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
closing_commit.stub({
|
closing_commit.stub({
|
||||||
|
|
|
@ -19,7 +19,7 @@ describe GitTagPushService do
|
||||||
@push_data = service.push_data
|
@push_data = service.push_data
|
||||||
@tag_name = Gitlab::Git.ref_name(@ref)
|
@tag_name = Gitlab::Git.ref_name(@ref)
|
||||||
@tag = project.repository.find_tag(@tag_name)
|
@tag = project.repository.find_tag(@tag_name)
|
||||||
@commit = project.repository.commit(@tag.target)
|
@commit = project.commit(@tag.target)
|
||||||
end
|
end
|
||||||
|
|
||||||
subject { @push_data }
|
subject { @push_data }
|
||||||
|
|
|
@ -57,7 +57,7 @@ describe NotificationService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters out "mentioned in" notes' do
|
it 'filters out "mentioned in" notes' do
|
||||||
mentioned_note = Note.create_cross_reference_note(mentioned_issue, issue, issue.author, issue.project)
|
mentioned_note = Note.create_cross_reference_note(mentioned_issue, issue, issue.author)
|
||||||
|
|
||||||
expect(Notify).not_to receive(:note_issue_email)
|
expect(Notify).not_to receive(:note_issue_email)
|
||||||
notification.new_note(mentioned_note)
|
notification.new_note(mentioned_note)
|
||||||
|
@ -128,7 +128,7 @@ describe NotificationService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters out "mentioned in" notes' do
|
it 'filters out "mentioned in" notes' do
|
||||||
mentioned_note = Note.create_cross_reference_note(mentioned_issue, issue, issue.author, issue.project)
|
mentioned_note = Note.create_cross_reference_note(mentioned_issue, issue, issue.author)
|
||||||
|
|
||||||
expect(Notify).not_to receive(:note_issue_email)
|
expect(Notify).not_to receive(:note_issue_email)
|
||||||
notification.new_note(mentioned_note)
|
notification.new_note(mentioned_note)
|
||||||
|
|
|
@ -83,14 +83,14 @@ shared_examples 'a mentionable' do
|
||||||
|
|
||||||
mentioned_objects.each do |referenced|
|
mentioned_objects.each do |referenced|
|
||||||
expect(Note).to receive(:create_cross_reference_note).
|
expect(Note).to receive(:create_cross_reference_note).
|
||||||
with(referenced, subject.local_reference, author, project)
|
with(referenced, subject.local_reference, author)
|
||||||
end
|
end
|
||||||
|
|
||||||
subject.create_cross_references!(project, author)
|
subject.create_cross_references!(project, author)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'detects existing cross-references' do
|
it 'detects existing cross-references' do
|
||||||
Note.create_cross_reference_note(mentioned_issue, subject.local_reference, author, project)
|
Note.create_cross_reference_note(mentioned_issue, subject.local_reference, author)
|
||||||
|
|
||||||
expect(subject).to have_mentioned(mentioned_issue)
|
expect(subject).to have_mentioned(mentioned_issue)
|
||||||
expect(subject).not_to have_mentioned(mentioned_mr)
|
expect(subject).not_to have_mentioned(mentioned_mr)
|
||||||
|
@ -107,6 +107,8 @@ shared_examples 'an editable mentionable' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates new cross-reference notes when the mentionable text is edited' do
|
it 'creates new cross-reference notes when the mentionable text is edited' do
|
||||||
|
subject.save
|
||||||
|
|
||||||
cross = ext_proj.path_with_namespace
|
cross = ext_proj.path_with_namespace
|
||||||
|
|
||||||
new_text = <<-MSG
|
new_text = <<-MSG
|
||||||
|
@ -132,10 +134,9 @@ shared_examples 'an editable mentionable' do
|
||||||
# These two issues are new and should receive reference notes
|
# These two issues are new and should receive reference notes
|
||||||
new_issues.each do |newref|
|
new_issues.each do |newref|
|
||||||
expect(Note).to receive(:create_cross_reference_note).
|
expect(Note).to receive(:create_cross_reference_note).
|
||||||
with(newref, subject.local_reference, author, project)
|
with(newref, subject.local_reference, author)
|
||||||
end
|
end
|
||||||
|
|
||||||
subject.save
|
|
||||||
set_mentionable_text.call(new_text)
|
set_mentionable_text.call(new_text)
|
||||||
subject.notice_added_references(project, author)
|
subject.notice_added_references(project, author)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue