Commit c80c1e1e authored by Jean-Philippe Lang's avatar Jean-Philippe Lang

Create a journal and send an email when an issue is closed by commit (#609).

The redmine user is found using the committer username or email. Otherwise, the journal is created with anonymous user.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1126 e93f8b46-1217-0410-a6f0-8f06a7374b81
parent 943ba3e3
......@@ -48,6 +48,7 @@ class Changeset < ActiveRecord::Base
def after_create
scan_comment_for_issue_ids
end
require 'pp'
def scan_comment_for_issue_ids
return if comments.blank?
......@@ -79,11 +80,14 @@ class Changeset < ActiveRecord::Base
# update status of issues
logger.debug "Issues fixed by changeset #{self.revision}: #{issue_ids.join(', ')}." if logger && logger.debug?
target_issues.each do |issue|
# don't change the status is the issue is already closed
# don't change the status is the issue is closed
next if issue.status.is_closed?
user = committer_user || User.anonymous
journal = issue.init_journal(user, l(:text_status_changed_by_changeset, "r#{self.revision}"))
issue.status = fix_status
issue.done_ratio = done_ratio if done_ratio
issue.save
Mailer.deliver_issue_edit(journal) if Setting.notified_events.include?('issue_updated')
end
end
referenced_issues += target_issues
......@@ -92,6 +96,16 @@ class Changeset < ActiveRecord::Base
self.issues = referenced_issues.uniq
end
# Returns the Redmine User corresponding to the committer
def committer_user
if committer && committer.strip =~ /^([^<]+)(<(.*)>)?$/
username, email = $1.strip, $3
u = User.find_by_login(username)
u ||= User.find_by_mail(email) unless email.blank?
u
end
end
# Returns the previous changeset
def previous
@previous ||= Changeset.find(:first, :conditions => ['revision < ? AND repository_id = ?', self.revision, self.repository_id], :order => 'revision DESC')
......
......@@ -566,3 +566,4 @@ label_general: Основни
label_repository_plural: Хранилища
label_associated_revisions: Асоциирани ревизии
setting_user_format: Потребителски формат
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -566,3 +566,4 @@ label_general: General
label_repository_plural: Repositories
label_associated_revisions: Associated revisions
setting_user_format: Users display format
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -566,3 +566,4 @@ default_activity_development: Entwicklung
enumeration_issue_priorities: Ticket-Prioritäten
enumeration_doc_categories: Dokumentenkategorien
enumeration_activities: Aktivitäten (Zeiterfassung)
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -540,6 +540,7 @@ text_issue_category_reassign_to: Reassign issues to this category
text_user_mail_option: "For unselected projects, you will only receive notifications about things you watch or you're involved in (eg. issues you're the author or assignee)."
text_no_configuration_data: "Roles, trackers, issue statuses and workflow have not been configured yet.\nIt is highly recommended to load the default configuration. You will be able to modify it once loaded."
text_load_default_configuration: Load the default configuration
text_status_changed_by_changeset: Applied in changeset %s.
default_role_manager: Manager
default_role_developper: Developer
......
......@@ -569,3 +569,4 @@ label_general: General
label_repository_plural: Repositories
label_associated_revisions: Associated revisions
setting_user_format: Users display format
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -570,3 +570,4 @@ enumeration_doc_categories: Dokumentin luokat
enumeration_activities: Aktiviteetit (ajan seuranta)
label_associated_revisions: Liittyvät versiot
setting_user_format: Users display format
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -541,6 +541,7 @@ text_issue_category_reassign_to: Réaffecter les demandes à cette catégorie
text_user_mail_option: "Pour les projets non sélectionnés, vous recevrez seulement des notifications pour ce que vous surveillez ou à quoi vous participez (exemple: demandes dont vous êtes l'auteur ou la personne assignée)."
text_no_configuration_data: "Les rôles, trackers, statuts et le workflow ne sont pas encore paramétrés.\nIl est vivement recommandé de charger le paramétrage par defaut. Vous pourrez le modifier une fois chargé."
text_load_default_configuration: Charger le paramétrage par défaut
text_status_changed_by_changeset: Appliqué par commit %s.
default_role_manager: Manager
default_role_developper: Développeur
......
......@@ -566,3 +566,4 @@ label_general: General
label_repository_plural: Repositories
label_associated_revisions: Associated revisions
setting_user_format: Users display format
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -566,3 +566,4 @@ label_general: General
label_repository_plural: Repositories
label_associated_revisions: Associated revisions
setting_user_format: Users display format
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -567,3 +567,4 @@ label_general: General
label_repository_plural: Repositories
label_associated_revisions: Associated revisions
setting_user_format: Users display format
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -566,3 +566,4 @@ label_general: 일반
label_repository_plural: 저장소들
label_associated_revisions: Associated revisions
setting_user_format: Users display format
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -567,3 +567,4 @@ label_repository_plural: Saugiklos
error_can_t_load_default_data: "Numatytoji konfiguracija negali būti užkrauta: %s"
label_associated_revisions: susijusios revizijos
setting_user_format: Vartotojo atvaizdavimo formatas
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -567,3 +567,4 @@ label_general: General
label_repository_plural: Repositories
label_associated_revisions: Associated revisions
setting_user_format: Users display format
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -566,3 +566,4 @@ label_general: Ogólne
label_repository_plural: Repozytoria
label_associated_revisions: Associated revisions
setting_user_format: Users display format
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -566,3 +566,4 @@ label_general: General
label_repository_plural: Repositories
label_associated_revisions: Associated revisions
setting_user_format: Users display format
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -566,3 +566,4 @@ label_general: General
label_repository_plural: Repositories
label_associated_revisions: Associated revisions
setting_user_format: Users display format
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -566,3 +566,4 @@ label_general: General
label_repository_plural: Repositories
label_associated_revisions: Associated revisions
setting_user_format: Users display format
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -567,3 +567,4 @@ default_activity_development: Разработка
enumeration_issue_priorities: Приоритеты задач
enumeration_doc_categories: Категории документов
enumeration_activities: Действия (учет времени)
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -567,3 +567,4 @@ label_general: General
label_repository_plural: Repositories
label_associated_revisions: Associated revisions
setting_user_format: Users display format
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -567,3 +567,4 @@ label_general: General
label_repository_plural: Repositories
label_associated_revisions: Associated revisions
setting_user_format: Users display format
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -566,3 +566,4 @@ default_activity_development: 開發
enumeration_issue_priorities: 項目重要性
enumeration_doc_categories: 文件分類
enumeration_activities: 活動 (time tracking)
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -569,3 +569,4 @@ label_general: 一般
label_repository_plural: 源代码库
label_associated_revisions: 相关的版本
setting_user_format: 用户显示格式
text_status_changed_by_changeset: Applied in changeset %s.
......@@ -18,7 +18,16 @@
require File.dirname(__FILE__) + '/../test_helper'
class RepositoryTest < Test::Unit::TestCase
fixtures :projects, :repositories, :issues, :issue_statuses, :changesets, :changes
fixtures :projects,
:trackers,
:projects_trackers,
:repositories,
:issues,
:issue_statuses,
:changesets,
:changes,
:users,
:enumerations
def setup
@repository = Project.find(1).repository
......@@ -42,19 +51,35 @@ class RepositoryTest < Test::Unit::TestCase
Setting.commit_fix_done_ratio = "90"
Setting.commit_ref_keywords = 'refs , references, IssueID'
Setting.commit_fix_keywords = 'fixes , closes'
Setting.default_language = 'en'
ActionMailer::Base.deliveries.clear
# make sure issue 1 is not already closed
assert !Issue.find(1).status.is_closed?
fixed_issue = Issue.find(1)
assert !fixed_issue.status.is_closed?
old_status = fixed_issue.status
Repository.scan_changesets_for_issue_ids
assert_equal [101, 102], Issue.find(3).changeset_ids
# fixed issues
fixed_issue = Issue.find(1)
fixed_issue.reload
assert fixed_issue.status.is_closed?
assert_equal 90, fixed_issue.done_ratio
assert_equal [101], fixed_issue.changeset_ids
# issue change
journal = fixed_issue.journals.find(:first, :order => 'created_on desc')
assert_equal User.find_by_login('dlopper'), journal.user
assert_equal 'Applied in changeset r2.', journal.notes
# 2 email notifications
assert_equal 2, ActionMailer::Base.deliveries.size
mail = ActionMailer::Base.deliveries.first
assert_kind_of TMail::Mail, mail
assert mail.subject.starts_with?("[#{fixed_issue.project.name} - #{fixed_issue.tracker.name} ##{fixed_issue.id}]")
assert mail.body.include?("Status changed from #{old_status} to #{fixed_issue.status}")
# ignoring commits referencing an issue of another project
assert_equal [], Issue.find(4).changesets
end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment