Support for multiple issue update keywords/rules in commit messages (#4911).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@12197 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
b59d109680
commit
a77b462a53
|
@ -33,9 +33,7 @@ class SettingsController < ApplicationController
|
||||||
if request.post? && params[:settings] && params[:settings].is_a?(Hash)
|
if request.post? && params[:settings] && params[:settings].is_a?(Hash)
|
||||||
settings = (params[:settings] || {}).dup.symbolize_keys
|
settings = (params[:settings] || {}).dup.symbolize_keys
|
||||||
settings.each do |name, value|
|
settings.each do |name, value|
|
||||||
# remove blank values in array settings
|
Setting.set_from_params name, value
|
||||||
value.delete_if {|v| v.blank? } if value.is_a?(Array)
|
|
||||||
Setting[name] = value
|
|
||||||
end
|
end
|
||||||
flash[:notice] = l(:notice_successful_update)
|
flash[:notice] = l(:notice_successful_update)
|
||||||
redirect_to settings_path(:tab => params[:tab])
|
redirect_to settings_path(:tab => params[:tab])
|
||||||
|
@ -48,6 +46,9 @@ class SettingsController < ApplicationController
|
||||||
@guessed_host_and_path = request.host_with_port.dup
|
@guessed_host_and_path = request.host_with_port.dup
|
||||||
@guessed_host_and_path << ('/'+ Redmine::Utils.relative_url_root.gsub(%r{^\/}, '')) unless Redmine::Utils.relative_url_root.blank?
|
@guessed_host_and_path << ('/'+ Redmine::Utils.relative_url_root.gsub(%r{^\/}, '')) unless Redmine::Utils.relative_url_root.blank?
|
||||||
|
|
||||||
|
@commit_update_keywords = Setting.commit_update_keywords.dup
|
||||||
|
@commit_update_keywords[''] = {} if @commit_update_keywords.blank?
|
||||||
|
|
||||||
Redmine::Themes.rescan
|
Redmine::Themes.rescan
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -118,21 +118,21 @@ class Changeset < ActiveRecord::Base
|
||||||
ref_keywords = Setting.commit_ref_keywords.downcase.split(",").collect(&:strip)
|
ref_keywords = Setting.commit_ref_keywords.downcase.split(",").collect(&:strip)
|
||||||
ref_keywords_any = ref_keywords.delete('*')
|
ref_keywords_any = ref_keywords.delete('*')
|
||||||
# keywords used to fix issues
|
# keywords used to fix issues
|
||||||
fix_keywords = Setting.commit_fix_keywords.downcase.split(",").collect(&:strip)
|
fix_keywords = Setting.commit_update_by_keyword.keys
|
||||||
|
|
||||||
kw_regexp = (ref_keywords + fix_keywords).collect{|kw| Regexp.escape(kw)}.join("|")
|
kw_regexp = (ref_keywords + fix_keywords).collect{|kw| Regexp.escape(kw)}.join("|")
|
||||||
|
|
||||||
referenced_issues = []
|
referenced_issues = []
|
||||||
|
|
||||||
comments.scan(/([\s\(\[,-]|^)((#{kw_regexp})[\s:]+)?(#\d+(\s+@#{TIMELOG_RE})?([\s,;&]+#\d+(\s+@#{TIMELOG_RE})?)*)(?=[[:punct:]]|\s|<|$)/i) do |match|
|
comments.scan(/([\s\(\[,-]|^)((#{kw_regexp})[\s:]+)?(#\d+(\s+@#{TIMELOG_RE})?([\s,;&]+#\d+(\s+@#{TIMELOG_RE})?)*)(?=[[:punct:]]|\s|<|$)/i) do |match|
|
||||||
action, refs = match[2], match[3]
|
action, refs = match[2].to_s.downcase, match[3]
|
||||||
next unless action.present? || ref_keywords_any
|
next unless action.present? || ref_keywords_any
|
||||||
|
|
||||||
refs.scan(/#(\d+)(\s+@#{TIMELOG_RE})?/).each do |m|
|
refs.scan(/#(\d+)(\s+@#{TIMELOG_RE})?/).each do |m|
|
||||||
issue, hours = find_referenced_issue_by_id(m[0].to_i), m[2]
|
issue, hours = find_referenced_issue_by_id(m[0].to_i), m[2]
|
||||||
if issue
|
if issue
|
||||||
referenced_issues << issue
|
referenced_issues << issue
|
||||||
fix_issue(issue) if fix_keywords.include?(action.to_s.downcase)
|
fix_issue(issue, action) if fix_keywords.include?(action)
|
||||||
log_time(issue, hours) if hours && Setting.commit_logtime_enabled?
|
log_time(issue, hours) if hours && Setting.commit_logtime_enabled?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -210,12 +210,10 @@ class Changeset < ActiveRecord::Base
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fix_issue(issue)
|
# Updates the +issue+ according to +action+
|
||||||
status = IssueStatus.find_by_id(Setting.commit_fix_status_id.to_i)
|
def fix_issue(issue, action)
|
||||||
if status.nil?
|
updates = Setting.commit_update_by_keyword[action]
|
||||||
logger.warn("No status matches commit_fix_status_id setting (#{Setting.commit_fix_status_id})") if logger
|
return unless updates.is_a?(Hash)
|
||||||
return issue
|
|
||||||
end
|
|
||||||
|
|
||||||
# the issue may have been updated by the closure of another one (eg. duplicate)
|
# the issue may have been updated by the closure of another one (eg. duplicate)
|
||||||
issue.reload
|
issue.reload
|
||||||
|
@ -223,10 +221,7 @@ class Changeset < ActiveRecord::Base
|
||||||
return if issue.status && issue.status.is_closed?
|
return if issue.status && issue.status.is_closed?
|
||||||
|
|
||||||
journal = issue.init_journal(user || User.anonymous, ll(Setting.default_language, :text_status_changed_by_changeset, text_tag(issue.project)))
|
journal = issue.init_journal(user || User.anonymous, ll(Setting.default_language, :text_status_changed_by_changeset, text_tag(issue.project)))
|
||||||
issue.status = status
|
issue.assign_attributes updates.slice(*Issue.attribute_names)
|
||||||
unless Setting.commit_fix_done_ratio.blank?
|
|
||||||
issue.done_ratio = Setting.commit_fix_done_ratio.to_i
|
|
||||||
end
|
|
||||||
Redmine::Hook.call_hook(:model_changeset_scan_commit_for_issue_ids_pre_issue_update,
|
Redmine::Hook.call_hook(:model_changeset_scan_commit_for_issue_ids_pre_issue_update,
|
||||||
{ :changeset => self, :issue => issue })
|
{ :changeset => self, :issue => issue })
|
||||||
unless issue.save
|
unless issue.save
|
||||||
|
|
|
@ -132,15 +132,87 @@ class Setting < ActiveRecord::Base
|
||||||
def self.#{name}=(value)
|
def self.#{name}=(value)
|
||||||
self[:#{name}] = value
|
self[:#{name}] = value
|
||||||
end
|
end
|
||||||
END_SRC
|
END_SRC
|
||||||
class_eval src, __FILE__, __LINE__
|
class_eval src, __FILE__, __LINE__
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Sets a setting value from params
|
||||||
|
def self.set_from_params(name, params)
|
||||||
|
params = params.dup
|
||||||
|
params.delete_if {|v| v.blank? } if params.is_a?(Array)
|
||||||
|
|
||||||
|
m = "#{name}_from_params"
|
||||||
|
if respond_to? m
|
||||||
|
self[name.to_sym] = send m, params
|
||||||
|
else
|
||||||
|
self[name.to_sym] = params
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns a hash suitable for commit_update_keywords setting
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# params = {:keywords => ['fixes', 'closes'], :status_id => ["3", "5"], :done_ratio => ["", "100"]}
|
||||||
|
# Setting.commit_update_keywords_from_params(params)
|
||||||
|
# # => {'fixes' => {'status_id' => "3"}, 'closes' => {'status_id' => "5", 'done_ratio' => "100"}}
|
||||||
|
def self.commit_update_keywords_from_params(params)
|
||||||
|
s = {}
|
||||||
|
if params.is_a?(Hash) && params.key?(:keywords) && params.values.all? {|v| v.is_a? Array}
|
||||||
|
attributes = params.except(:keywords).keys
|
||||||
|
params[:keywords].each_with_index do |keywords, i|
|
||||||
|
next if keywords.blank?
|
||||||
|
s[keywords] = attributes.inject({}) {|h, a|
|
||||||
|
value = params[a][i].to_s
|
||||||
|
h[a.to_s] = value if value.present?
|
||||||
|
h
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
s
|
||||||
|
end
|
||||||
|
|
||||||
# Helper that returns an array based on per_page_options setting
|
# Helper that returns an array based on per_page_options setting
|
||||||
def self.per_page_options_array
|
def self.per_page_options_array
|
||||||
per_page_options.split(%r{[\s,]}).collect(&:to_i).select {|n| n > 0}.sort
|
per_page_options.split(%r{[\s,]}).collect(&:to_i).select {|n| n > 0}.sort
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Helper that returns a Hash with single update keywords as keys
|
||||||
|
def self.commit_update_by_keyword
|
||||||
|
h = {}
|
||||||
|
if commit_update_keywords.is_a?(Hash)
|
||||||
|
commit_update_keywords.each do |keywords, attribute_updates|
|
||||||
|
next unless attribute_updates.is_a?(Hash)
|
||||||
|
attribute_updates = attribute_updates.dup
|
||||||
|
attribute_updates.delete_if {|k, v| v.blank?}
|
||||||
|
keywords.to_s.split(",").map(&:strip).reject(&:blank?).each do |keyword|
|
||||||
|
h[keyword.downcase] = attribute_updates
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
h
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.commit_fix_keywords
|
||||||
|
ActiveSupport::Deprecation.warn "Setting.commit_fix_keywords is deprecated and will be removed in Redmine 3"
|
||||||
|
if commit_update_keywords.is_a?(Hash)
|
||||||
|
commit_update_keywords.keys.first
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.commit_fix_status_id
|
||||||
|
ActiveSupport::Deprecation.warn "Setting.commit_fix_status_id is deprecated and will be removed in Redmine 3"
|
||||||
|
if commit_update_keywords.is_a?(Hash)
|
||||||
|
commit_update_keywords[commit_fix_keywords]['status_id']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.commit_fix_done_ratio
|
||||||
|
ActiveSupport::Deprecation.warn "Setting.commit_fix_done_ratio is deprecated and will be removed in Redmine 3"
|
||||||
|
if commit_update_keywords.is_a?(Hash)
|
||||||
|
commit_update_keywords[commit_fix_keywords]['done_ratio']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def self.openid?
|
def self.openid?
|
||||||
Object.const_defined?(:OpenID) && self[:openid].to_i > 0
|
Object.const_defined?(:OpenID) && self[:openid].to_i > 0
|
||||||
end
|
end
|
||||||
|
|
|
@ -65,19 +65,6 @@
|
||||||
<p><%= setting_text_field :commit_ref_keywords, :size => 30 %>
|
<p><%= setting_text_field :commit_ref_keywords, :size => 30 %>
|
||||||
<em class="info"><%= l(:text_comma_separated) %></em></p>
|
<em class="info"><%= l(:text_comma_separated) %></em></p>
|
||||||
|
|
||||||
<p><%= setting_text_field :commit_fix_keywords, :size => 30 %>
|
|
||||||
<%= l(:label_applied_status) %>: <%= setting_select :commit_fix_status_id,
|
|
||||||
[["", 0]] +
|
|
||||||
IssueStatus.sorted.all.collect{
|
|
||||||
|status| [status.name, status.id.to_s]
|
|
||||||
},
|
|
||||||
:label => false %>
|
|
||||||
<%= l(:field_done_ratio) %>: <%= setting_select :commit_fix_done_ratio,
|
|
||||||
(0..10).to_a.collect {|r| ["#{r*10} %", "#{r*10}"] },
|
|
||||||
:blank => :label_no_change_option,
|
|
||||||
:label => false %>
|
|
||||||
<em class="info"><%= l(:text_comma_separated) %></em></p>
|
|
||||||
|
|
||||||
<p><%= setting_check_box :commit_cross_project_ref %></p>
|
<p><%= setting_check_box :commit_cross_project_ref %></p>
|
||||||
|
|
||||||
<p><%= setting_check_box :commit_logtime_enabled,
|
<p><%= setting_check_box :commit_logtime_enabled,
|
||||||
|
@ -90,5 +77,48 @@
|
||||||
:disabled => !Setting.commit_logtime_enabled?%></p>
|
:disabled => !Setting.commit_logtime_enabled?%></p>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<%= submit_tag l(:button_save) %>
|
<table class="list" id="commit-keywords">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th><%= l(:setting_commit_fix_keywords) %></th>
|
||||||
|
<th><%= l(:label_applied_status) %></th>
|
||||||
|
<th><%= l(:field_done_ratio) %></th>
|
||||||
|
<th class="buttons"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% @commit_update_keywords.each do |keywords, updates| %>
|
||||||
|
<tr class="commit-keywords">
|
||||||
|
<td><%= text_field_tag "settings[commit_update_keywords][keywords][]", keywords, :size => 30 %></td>
|
||||||
|
<td><%= select_tag "settings[commit_update_keywords][status_id][]", options_for_select([["", 0]] + IssueStatus.sorted.all.collect{|status| [status.name, status.id.to_s]}, updates['status_id']) %></td>
|
||||||
|
<td><%= select_tag "settings[commit_update_keywords][done_ratio][]", options_for_select([["", ""]] + (0..10).to_a.collect {|r| ["#{r*10} %", "#{r*10}"] }, updates['done_ratio']) %></td>
|
||||||
|
<td class="buttons"><%= link_to image_tag('delete.png'), '#', :class => 'delete-commit-keywords' %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
<tr>
|
||||||
|
<td><em class="info"><%= l(:text_comma_separated) %></em></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td class="buttons"><%= link_to image_tag('add.png'), '#', :class => 'add-commit-keywords' %></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p><%= submit_tag l(:button_save) %></p>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= javascript_tag do %>
|
||||||
|
$('#commit-keywords').on('click', 'a.delete-commit-keywords', function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
if ($('#commit-keywords tbody tr.commit-keywords').length > 1) {
|
||||||
|
$(this).parents('#commit-keywords tr').remove();
|
||||||
|
} else {
|
||||||
|
$('#commit-keywords tbody tr.commit-keywords').find('input, select').val('');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$('#commit-keywords').on('click', 'a.add-commit-keywords', function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
var row = $('#commit-keywords tr.commit-keywords:last');
|
||||||
|
row.clone().insertAfter(row).find('input, select').val('');
|
||||||
|
});
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -106,13 +106,9 @@ commit_cross_project_ref:
|
||||||
default: 0
|
default: 0
|
||||||
commit_ref_keywords:
|
commit_ref_keywords:
|
||||||
default: 'refs,references,IssueID'
|
default: 'refs,references,IssueID'
|
||||||
commit_fix_keywords:
|
commit_update_keywords:
|
||||||
default: 'fixes,closes'
|
serialized: true
|
||||||
commit_fix_status_id:
|
default: {}
|
||||||
format: int
|
|
||||||
default: 0
|
|
||||||
commit_fix_done_ratio:
|
|
||||||
default: 100
|
|
||||||
commit_logtime_enabled:
|
commit_logtime_enabled:
|
||||||
default: 0
|
default: 0
|
||||||
commit_logtime_activity_id:
|
commit_logtime_activity_id:
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
class SupportForMultipleCommitKeywords < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
# Replaces commit_fix_keywords, commit_fix_status_id, commit_fix_done_ratio settings
|
||||||
|
# with commit_update_keywords setting
|
||||||
|
keywords = Setting.where(:name => 'commit_fix_keywords').limit(1).pluck(:value).first
|
||||||
|
status_id = Setting.where(:name => 'commit_fix_status_id').limit(1).pluck(:value).first
|
||||||
|
done_ratio = Setting.where(:name => 'commit_fix_done_ratio').limit(1).pluck(:value).first
|
||||||
|
if keywords.present?
|
||||||
|
Setting.commit_update_keywords = {keywords => {'status_id' => status_id, 'done_ratio' => done_ratio}}
|
||||||
|
end
|
||||||
|
Setting.where(:name => %w(commit_fix_keywords commit_fix_status_id commit_fix_done_ratio)).delete_all
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
Setting.where(:name => 'commit_update_keywords').delete_all
|
||||||
|
end
|
||||||
|
end
|
|
@ -80,6 +80,57 @@ class SettingsControllerTest < ActionController::TestCase
|
||||||
Setting.clear_cache
|
Setting.clear_cache
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_edit_commit_update_keywords
|
||||||
|
with_settings :commit_update_keywords => {
|
||||||
|
"fixes, resolves" => {"status_id" => "3"},
|
||||||
|
"closes" => {"status_id" => "5", "done_ratio" => "100"}
|
||||||
|
} do
|
||||||
|
get :edit
|
||||||
|
end
|
||||||
|
assert_response :success
|
||||||
|
assert_select 'tr.commit-keywords', 2
|
||||||
|
assert_select 'tr.commit-keywords:nth-child(1)' do
|
||||||
|
assert_select 'input[name=?][value=?]', 'settings[commit_update_keywords][keywords][]', 'fixes, resolves'
|
||||||
|
assert_select 'select[name=?]', 'settings[commit_update_keywords][status_id][]' do
|
||||||
|
assert_select 'option[value=3][selected=selected]'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assert_select 'tr.commit-keywords:nth-child(2)' do
|
||||||
|
assert_select 'input[name=?][value=?]', 'settings[commit_update_keywords][keywords][]', 'closes'
|
||||||
|
assert_select 'select[name=?]', 'settings[commit_update_keywords][status_id][]' do
|
||||||
|
assert_select 'option[value=5][selected=selected]'
|
||||||
|
end
|
||||||
|
assert_select 'select[name=?]', 'settings[commit_update_keywords][done_ratio][]' do
|
||||||
|
assert_select 'option[value=100][selected=selected]'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_edit_without_commit_update_keywords_should_show_blank_line
|
||||||
|
with_settings :commit_update_keywords => {} do
|
||||||
|
get :edit
|
||||||
|
end
|
||||||
|
assert_response :success
|
||||||
|
assert_select 'tr.commit-keywords', 1 do
|
||||||
|
assert_select 'input[name=?][value=?]', 'settings[commit_update_keywords][keywords][]', ''
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_post_edit_commit_update_keywords
|
||||||
|
post :edit, :settings => {
|
||||||
|
:commit_update_keywords => {
|
||||||
|
:keywords => ["resolves", "closes"],
|
||||||
|
:status_id => ["3", "5"],
|
||||||
|
:done_ratio => ["", "100"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_redirected_to '/settings'
|
||||||
|
assert_equal({
|
||||||
|
"resolves" => {"status_id" => "3"},
|
||||||
|
"closes" => {"status_id" => "5", "done_ratio" => "100"}
|
||||||
|
}, Setting.commit_update_keywords)
|
||||||
|
end
|
||||||
|
|
||||||
def test_get_plugin_settings
|
def test_get_plugin_settings
|
||||||
Setting.stubs(:plugin_foo).returns({'sample_setting' => 'Plugin setting value'})
|
Setting.stubs(:plugin_foo).returns({'sample_setting' => 'Plugin setting value'})
|
||||||
ActionController::Base.append_view_path(File.join(Rails.root, "test/fixtures/plugins"))
|
ActionController::Base.append_view_path(File.join(Rails.root, "test/fixtures/plugins"))
|
||||||
|
|
|
@ -30,10 +30,8 @@ class ChangesetTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
def test_ref_keywords_any
|
def test_ref_keywords_any
|
||||||
ActionMailer::Base.deliveries.clear
|
ActionMailer::Base.deliveries.clear
|
||||||
Setting.commit_fix_status_id = IssueStatus.where(:is_closed => true).first.id
|
|
||||||
Setting.commit_fix_done_ratio = '90'
|
|
||||||
Setting.commit_ref_keywords = '*'
|
Setting.commit_ref_keywords = '*'
|
||||||
Setting.commit_fix_keywords = 'fixes , closes'
|
Setting.commit_update_keywords = {'fixes , closes' => {'status_id' => '5', 'done_ratio' => '90'}}
|
||||||
|
|
||||||
c = Changeset.new(:repository => Project.find(1).repository,
|
c = Changeset.new(:repository => Project.find(1).repository,
|
||||||
:committed_on => Time.now,
|
:committed_on => Time.now,
|
||||||
|
@ -49,7 +47,7 @@ class ChangesetTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
def test_ref_keywords
|
def test_ref_keywords
|
||||||
Setting.commit_ref_keywords = 'refs'
|
Setting.commit_ref_keywords = 'refs'
|
||||||
Setting.commit_fix_keywords = ''
|
Setting.commit_update_keywords = ''
|
||||||
c = Changeset.new(:repository => Project.find(1).repository,
|
c = Changeset.new(:repository => Project.find(1).repository,
|
||||||
:committed_on => Time.now,
|
:committed_on => Time.now,
|
||||||
:comments => 'Ignores #2. Refs #1',
|
:comments => 'Ignores #2. Refs #1',
|
||||||
|
@ -60,7 +58,7 @@ class ChangesetTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
def test_ref_keywords_any_only
|
def test_ref_keywords_any_only
|
||||||
Setting.commit_ref_keywords = '*'
|
Setting.commit_ref_keywords = '*'
|
||||||
Setting.commit_fix_keywords = ''
|
Setting.commit_update_keywords = ''
|
||||||
c = Changeset.new(:repository => Project.find(1).repository,
|
c = Changeset.new(:repository => Project.find(1).repository,
|
||||||
:committed_on => Time.now,
|
:committed_on => Time.now,
|
||||||
:comments => 'Ignores #2. Refs #1',
|
:comments => 'Ignores #2. Refs #1',
|
||||||
|
@ -112,9 +110,12 @@ class ChangesetTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_ref_keywords_closing_with_timelog
|
def test_ref_keywords_closing_with_timelog
|
||||||
Setting.commit_fix_status_id = IssueStatus.where(:is_closed => true).first.id
|
|
||||||
Setting.commit_ref_keywords = '*'
|
Setting.commit_ref_keywords = '*'
|
||||||
Setting.commit_fix_keywords = 'fixes , closes'
|
Setting.commit_update_keywords = {
|
||||||
|
'fixes , closes' => {
|
||||||
|
'status_id' => IssueStatus.where(:is_closed => true).first.id.to_s
|
||||||
|
}
|
||||||
|
}
|
||||||
Setting.commit_logtime_enabled = '1'
|
Setting.commit_logtime_enabled = '1'
|
||||||
|
|
||||||
c = Changeset.new(:repository => Project.find(1).repository,
|
c = Changeset.new(:repository => Project.find(1).repository,
|
||||||
|
@ -163,6 +164,23 @@ class ChangesetTest < ActiveSupport::TestCase
|
||||||
assert_equal [1,2,3], c.issue_ids.sort
|
assert_equal [1,2,3], c.issue_ids.sort
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_update_keywords_with_multiple_rules
|
||||||
|
Setting.commit_update_keywords = {
|
||||||
|
'fixes, closes' => {'status_id' => '5'},
|
||||||
|
'resolves' => {'status_id' => '3'}
|
||||||
|
}
|
||||||
|
issue1 = Issue.generate!
|
||||||
|
issue2 = Issue.generate!
|
||||||
|
|
||||||
|
c = Changeset.new(:repository => Project.find(1).repository,
|
||||||
|
:committed_on => Time.now,
|
||||||
|
:comments => "Closes ##{issue1.id}\nResolves ##{issue2.id}",
|
||||||
|
:revision => '12345')
|
||||||
|
assert c.save
|
||||||
|
assert_equal 5, issue1.reload.status_id
|
||||||
|
assert_equal 3, issue2.reload.status_id
|
||||||
|
end
|
||||||
|
|
||||||
def test_commit_referencing_a_subproject_issue
|
def test_commit_referencing_a_subproject_issue
|
||||||
c = Changeset.new(:repository => Project.find(1).repository,
|
c = Changeset.new(:repository => Project.find(1).repository,
|
||||||
:committed_on => Time.now,
|
:committed_on => Time.now,
|
||||||
|
@ -174,7 +192,7 @@ class ChangesetTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_commit_closing_a_subproject_issue
|
def test_commit_closing_a_subproject_issue
|
||||||
with_settings :commit_fix_status_id => 5, :commit_fix_keywords => 'closes',
|
with_settings :commit_update_keywords => {'closes' => {'status_id' => '5'}},
|
||||||
:default_language => 'en' do
|
:default_language => 'en' do
|
||||||
issue = Issue.find(5)
|
issue = Issue.find(5)
|
||||||
assert !issue.closed?
|
assert !issue.closed?
|
||||||
|
|
|
@ -182,11 +182,10 @@ class RepositoryTest < ActiveSupport::TestCase
|
||||||
def test_scan_changesets_for_issue_ids
|
def test_scan_changesets_for_issue_ids
|
||||||
Setting.default_language = 'en'
|
Setting.default_language = 'en'
|
||||||
|
|
||||||
# choosing a status to apply to fix issues
|
|
||||||
Setting.commit_fix_status_id = IssueStatus.where(:is_closed => true).first.id
|
|
||||||
Setting.commit_fix_done_ratio = "90"
|
|
||||||
Setting.commit_ref_keywords = 'refs , references, IssueID'
|
Setting.commit_ref_keywords = 'refs , references, IssueID'
|
||||||
Setting.commit_fix_keywords = 'fixes , closes'
|
Setting.commit_update_keywords = {
|
||||||
|
'fixes , closes' => {'status_id' => IssueStatus.where(:is_closed => true).first.id, 'done_ratio' => '90'}
|
||||||
|
}
|
||||||
Setting.default_language = 'en'
|
Setting.default_language = 'en'
|
||||||
ActionMailer::Base.deliveries.clear
|
ActionMailer::Base.deliveries.clear
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue