##// END OF EJS Templates
Create a journal and send an email when an issue is closed by commit (#609)....
Jean-Philippe Lang -
r1112:c80c1e1eada5
parent child
Show More
@@ -48,6 +48,7 class Changeset < ActiveRecord::Base
48 def after_create
48 def after_create
49 scan_comment_for_issue_ids
49 scan_comment_for_issue_ids
50 end
50 end
51 require 'pp'
51
52
52 def scan_comment_for_issue_ids
53 def scan_comment_for_issue_ids
53 return if comments.blank?
54 return if comments.blank?
@@ -79,11 +80,14 class Changeset < ActiveRecord::Base
79 # update status of issues
80 # update status of issues
80 logger.debug "Issues fixed by changeset #{self.revision}: #{issue_ids.join(', ')}." if logger && logger.debug?
81 logger.debug "Issues fixed by changeset #{self.revision}: #{issue_ids.join(', ')}." if logger && logger.debug?
81 target_issues.each do |issue|
82 target_issues.each do |issue|
82 # don't change the status is the issue is already closed
83 # don't change the status is the issue is closed
83 next if issue.status.is_closed?
84 next if issue.status.is_closed?
85 user = committer_user || User.anonymous
86 journal = issue.init_journal(user, l(:text_status_changed_by_changeset, "r#{self.revision}"))
84 issue.status = fix_status
87 issue.status = fix_status
85 issue.done_ratio = done_ratio if done_ratio
88 issue.done_ratio = done_ratio if done_ratio
86 issue.save
89 issue.save
90 Mailer.deliver_issue_edit(journal) if Setting.notified_events.include?('issue_updated')
87 end
91 end
88 end
92 end
89 referenced_issues += target_issues
93 referenced_issues += target_issues
@@ -92,6 +96,16 class Changeset < ActiveRecord::Base
92 self.issues = referenced_issues.uniq
96 self.issues = referenced_issues.uniq
93 end
97 end
94
98
99 # Returns the Redmine User corresponding to the committer
100 def committer_user
101 if committer && committer.strip =~ /^([^<]+)(<(.*)>)?$/
102 username, email = $1.strip, $3
103 u = User.find_by_login(username)
104 u ||= User.find_by_mail(email) unless email.blank?
105 u
106 end
107 end
108
95 # Returns the previous changeset
109 # Returns the previous changeset
96 def previous
110 def previous
97 @previous ||= Changeset.find(:first, :conditions => ['revision < ? AND repository_id = ?', self.revision, self.repository_id], :order => 'revision DESC')
111 @previous ||= Changeset.find(:first, :conditions => ['revision < ? AND repository_id = ?', self.revision, self.repository_id], :order => 'revision DESC')
@@ -566,3 +566,4 label_general: Основни
566 label_repository_plural: Хранилища
566 label_repository_plural: Хранилища
567 label_associated_revisions: Асоциирани ревизии
567 label_associated_revisions: Асоциирани ревизии
568 setting_user_format: Потребителски формат
568 setting_user_format: Потребителски формат
569 text_status_changed_by_changeset: Applied in changeset %s.
@@ -566,3 +566,4 label_general: General
566 label_repository_plural: Repositories
566 label_repository_plural: Repositories
567 label_associated_revisions: Associated revisions
567 label_associated_revisions: Associated revisions
568 setting_user_format: Users display format
568 setting_user_format: Users display format
569 text_status_changed_by_changeset: Applied in changeset %s.
@@ -566,3 +566,4 default_activity_development: Entwicklung
566 enumeration_issue_priorities: Ticket-Prioritäten
566 enumeration_issue_priorities: Ticket-Prioritäten
567 enumeration_doc_categories: Dokumentenkategorien
567 enumeration_doc_categories: Dokumentenkategorien
568 enumeration_activities: Aktivitäten (Zeiterfassung)
568 enumeration_activities: Aktivitäten (Zeiterfassung)
569 text_status_changed_by_changeset: Applied in changeset %s.
@@ -540,6 +540,7 text_issue_category_reassign_to: Reassign issues to this category
540 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)."
540 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)."
541 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."
541 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."
542 text_load_default_configuration: Load the default configuration
542 text_load_default_configuration: Load the default configuration
543 text_status_changed_by_changeset: Applied in changeset %s.
543
544
544 default_role_manager: Manager
545 default_role_manager: Manager
545 default_role_developper: Developer
546 default_role_developper: Developer
@@ -569,3 +569,4 label_general: General
569 label_repository_plural: Repositories
569 label_repository_plural: Repositories
570 label_associated_revisions: Associated revisions
570 label_associated_revisions: Associated revisions
571 setting_user_format: Users display format
571 setting_user_format: Users display format
572 text_status_changed_by_changeset: Applied in changeset %s.
@@ -570,3 +570,4 enumeration_doc_categories: Dokumentin luokat
570 enumeration_activities: Aktiviteetit (ajan seuranta)
570 enumeration_activities: Aktiviteetit (ajan seuranta)
571 label_associated_revisions: Liittyvät versiot
571 label_associated_revisions: Liittyvät versiot
572 setting_user_format: Users display format
572 setting_user_format: Users display format
573 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
541 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)."
541 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)."
542 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é."
542 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é."
543 text_load_default_configuration: Charger le paramétrage par défaut
543 text_load_default_configuration: Charger le paramétrage par défaut
544 text_status_changed_by_changeset: Appliqué par commit %s.
544
545
545 default_role_manager: Manager
546 default_role_manager: Manager
546 default_role_developper: Développeur
547 default_role_developper: Développeur
@@ -566,3 +566,4 label_general: General
566 label_repository_plural: Repositories
566 label_repository_plural: Repositories
567 label_associated_revisions: Associated revisions
567 label_associated_revisions: Associated revisions
568 setting_user_format: Users display format
568 setting_user_format: Users display format
569 text_status_changed_by_changeset: Applied in changeset %s.
@@ -566,3 +566,4 label_general: General
566 label_repository_plural: Repositories
566 label_repository_plural: Repositories
567 label_associated_revisions: Associated revisions
567 label_associated_revisions: Associated revisions
568 setting_user_format: Users display format
568 setting_user_format: Users display format
569 text_status_changed_by_changeset: Applied in changeset %s.
@@ -567,3 +567,4 label_general: General
567 label_repository_plural: Repositories
567 label_repository_plural: Repositories
568 label_associated_revisions: Associated revisions
568 label_associated_revisions: Associated revisions
569 setting_user_format: Users display format
569 setting_user_format: Users display format
570 text_status_changed_by_changeset: Applied in changeset %s.
@@ -566,3 +566,4 label_general: 일반
566 label_repository_plural: 저장소들
566 label_repository_plural: 저장소들
567 label_associated_revisions: Associated revisions
567 label_associated_revisions: Associated revisions
568 setting_user_format: Users display format
568 setting_user_format: Users display format
569 text_status_changed_by_changeset: Applied in changeset %s.
@@ -567,3 +567,4 label_repository_plural: Saugiklos
567 error_can_t_load_default_data: "Numatytoji konfiguracija negali būti užkrauta: %s"
567 error_can_t_load_default_data: "Numatytoji konfiguracija negali būti užkrauta: %s"
568 label_associated_revisions: susijusios revizijos
568 label_associated_revisions: susijusios revizijos
569 setting_user_format: Vartotojo atvaizdavimo formatas
569 setting_user_format: Vartotojo atvaizdavimo formatas
570 text_status_changed_by_changeset: Applied in changeset %s.
@@ -567,3 +567,4 label_general: General
567 label_repository_plural: Repositories
567 label_repository_plural: Repositories
568 label_associated_revisions: Associated revisions
568 label_associated_revisions: Associated revisions
569 setting_user_format: Users display format
569 setting_user_format: Users display format
570 text_status_changed_by_changeset: Applied in changeset %s.
@@ -566,3 +566,4 label_general: Ogólne
566 label_repository_plural: Repozytoria
566 label_repository_plural: Repozytoria
567 label_associated_revisions: Associated revisions
567 label_associated_revisions: Associated revisions
568 setting_user_format: Users display format
568 setting_user_format: Users display format
569 text_status_changed_by_changeset: Applied in changeset %s.
@@ -566,3 +566,4 label_general: General
566 label_repository_plural: Repositories
566 label_repository_plural: Repositories
567 label_associated_revisions: Associated revisions
567 label_associated_revisions: Associated revisions
568 setting_user_format: Users display format
568 setting_user_format: Users display format
569 text_status_changed_by_changeset: Applied in changeset %s.
@@ -566,3 +566,4 label_general: General
566 label_repository_plural: Repositories
566 label_repository_plural: Repositories
567 label_associated_revisions: Associated revisions
567 label_associated_revisions: Associated revisions
568 setting_user_format: Users display format
568 setting_user_format: Users display format
569 text_status_changed_by_changeset: Applied in changeset %s.
@@ -566,3 +566,4 label_general: General
566 label_repository_plural: Repositories
566 label_repository_plural: Repositories
567 label_associated_revisions: Associated revisions
567 label_associated_revisions: Associated revisions
568 setting_user_format: Users display format
568 setting_user_format: Users display format
569 text_status_changed_by_changeset: Applied in changeset %s.
@@ -567,3 +567,4 default_activity_development: Разработка
567 enumeration_issue_priorities: Приоритеты задач
567 enumeration_issue_priorities: Приоритеты задач
568 enumeration_doc_categories: Категории документов
568 enumeration_doc_categories: Категории документов
569 enumeration_activities: Действия (учет времени)
569 enumeration_activities: Действия (учет времени)
570 text_status_changed_by_changeset: Applied in changeset %s.
@@ -567,3 +567,4 label_general: General
567 label_repository_plural: Repositories
567 label_repository_plural: Repositories
568 label_associated_revisions: Associated revisions
568 label_associated_revisions: Associated revisions
569 setting_user_format: Users display format
569 setting_user_format: Users display format
570 text_status_changed_by_changeset: Applied in changeset %s.
@@ -567,3 +567,4 label_general: General
567 label_repository_plural: Repositories
567 label_repository_plural: Repositories
568 label_associated_revisions: Associated revisions
568 label_associated_revisions: Associated revisions
569 setting_user_format: Users display format
569 setting_user_format: Users display format
570 text_status_changed_by_changeset: Applied in changeset %s.
@@ -566,3 +566,4 default_activity_development: 開發
566 enumeration_issue_priorities: 項目重要性
566 enumeration_issue_priorities: 項目重要性
567 enumeration_doc_categories: 文件分類
567 enumeration_doc_categories: 文件分類
568 enumeration_activities: 活動 (time tracking)
568 enumeration_activities: 活動 (time tracking)
569 text_status_changed_by_changeset: Applied in changeset %s.
@@ -569,3 +569,4 label_general: 一般
569 label_repository_plural: 源代码库
569 label_repository_plural: 源代码库
570 label_associated_revisions: 相关的版本
570 label_associated_revisions: 相关的版本
571 setting_user_format: 用户显示格式
571 setting_user_format: 用户显示格式
572 text_status_changed_by_changeset: Applied in changeset %s.
@@ -18,7 +18,16
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.dirname(__FILE__) + '/../test_helper'
19
19
20 class RepositoryTest < Test::Unit::TestCase
20 class RepositoryTest < Test::Unit::TestCase
21 fixtures :projects, :repositories, :issues, :issue_statuses, :changesets, :changes
21 fixtures :projects,
22 :trackers,
23 :projects_trackers,
24 :repositories,
25 :issues,
26 :issue_statuses,
27 :changesets,
28 :changes,
29 :users,
30 :enumerations
22
31
23 def setup
32 def setup
24 @repository = Project.find(1).repository
33 @repository = Project.find(1).repository
@@ -42,19 +51,35 class RepositoryTest < Test::Unit::TestCase
42 Setting.commit_fix_done_ratio = "90"
51 Setting.commit_fix_done_ratio = "90"
43 Setting.commit_ref_keywords = 'refs , references, IssueID'
52 Setting.commit_ref_keywords = 'refs , references, IssueID'
44 Setting.commit_fix_keywords = 'fixes , closes'
53 Setting.commit_fix_keywords = 'fixes , closes'
45
54 Setting.default_language = 'en'
55 ActionMailer::Base.deliveries.clear
56
46 # make sure issue 1 is not already closed
57 # make sure issue 1 is not already closed
47 assert !Issue.find(1).status.is_closed?
58 fixed_issue = Issue.find(1)
59 assert !fixed_issue.status.is_closed?
60 old_status = fixed_issue.status
48
61
49 Repository.scan_changesets_for_issue_ids
62 Repository.scan_changesets_for_issue_ids
50 assert_equal [101, 102], Issue.find(3).changeset_ids
63 assert_equal [101, 102], Issue.find(3).changeset_ids
51
64
52 # fixed issues
65 # fixed issues
53 fixed_issue = Issue.find(1)
66 fixed_issue.reload
54 assert fixed_issue.status.is_closed?
67 assert fixed_issue.status.is_closed?
55 assert_equal 90, fixed_issue.done_ratio
68 assert_equal 90, fixed_issue.done_ratio
56 assert_equal [101], fixed_issue.changeset_ids
69 assert_equal [101], fixed_issue.changeset_ids
57
70
71 # issue change
72 journal = fixed_issue.journals.find(:first, :order => 'created_on desc')
73 assert_equal User.find_by_login('dlopper'), journal.user
74 assert_equal 'Applied in changeset r2.', journal.notes
75
76 # 2 email notifications
77 assert_equal 2, ActionMailer::Base.deliveries.size
78 mail = ActionMailer::Base.deliveries.first
79 assert_kind_of TMail::Mail, mail
80 assert mail.subject.starts_with?("[#{fixed_issue.project.name} - #{fixed_issue.tracker.name} ##{fixed_issue.id}]")
81 assert mail.body.include?("Status changed from #{old_status} to #{fixed_issue.status}")
82
58 # ignoring commits referencing an issue of another project
83 # ignoring commits referencing an issue of another project
59 assert_equal [], Issue.find(4).changesets
84 assert_equal [], Issue.find(4).changesets
60 end
85 end
General Comments 0
You need to be logged in to leave comments. Login now