Index: test/unit/journal_observer_test.rb IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/test/unit/journal_observer_test.rb b/test/unit/journal_observer_test.rb --- a/test/unit/journal_observer_test.rb (revision 153a4e26069b0f4182a4233516d7b4cb4aec72ac) +++ b/test/unit/journal_observer_test.rb (date 1638183313058) @@ -23,7 +23,7 @@ fixtures :issues, :issue_statuses, :journals, :journal_details, :projects, :projects_trackers, :trackers, :enabled_modules, :enumerations, :users, :user_preferences, :email_addresses, :roles, :members, :member_roles, - :versions + :versions, :custom_fields, :custom_fields_trackers def setup User.current = nil @@ -194,6 +194,326 @@ issue.init_journal(user) issue.fixed_version = versions(:versions_003) + assert issue.save + assert_equal 0, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_send_email_notification_with_issue_start_date_updated + with_settings :notified_events => %w(issue_start_date_updated) do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.start_date = Date.current + + assert issue.save + assert_equal 2, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_not_send_email_notification_without_issue_start_date_updated + with_settings :notified_events => [] do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.start_date = Date.current + + assert issue.save + assert_equal 0, ActionMailer::Base.deliveries.size + end + end + + + + def test_create_should_send_email_notification_with_issue_due_date_updated + with_settings :notified_events => %w(issue_due_date_updated) do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.due_date = Date.current + + assert issue.save + assert_equal 2, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_not_send_email_notification_without_issue_due_date_updated + with_settings :notified_events => [] do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.due_date = Date.current + + assert issue.save + assert_equal 0, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_send_email_notification_with_issue_estimated_hours_updated + with_settings :notified_events => %w(issue_estimated_hours_updated) do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.estimated_hours = '2h30' + + assert issue.save + assert_equal 2, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_not_send_email_notification_without_issue_estimated_hours_updated + with_settings :notified_events => [] do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.estimated_hours = '2h30' + + assert issue.save + assert_equal 0, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_send_email_notification_with_issue_category_updated + with_settings :notified_events => %w(issue_category_updated) do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.category_id = 2 + + assert issue.save + assert_equal 2, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_not_send_email_notification_without_issue_category_updated + with_settings :notified_events => [] do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.category_id = 2 + + assert issue.save + assert_equal 0, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_send_email_notification_with_issue_description_updated + with_settings :notified_events => %w(issue_description_updated) do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.description = 'description' + + assert issue.save + assert_equal 2, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_not_send_email_notification_without_issue_description_updated + with_settings :notified_events => [] do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.description = 'description' + + assert issue.save + assert_equal 0, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_send_email_notification_with_issue_done_ratio_updated + with_settings :notified_events => %w(issue_done_ratio_updated) do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.done_ratio = 30 + + assert issue.save + assert_equal 2, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_not_send_email_notification_without_issue_done_ratio_updated + with_settings :notified_events => [] do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.done_ratio = 30 + + assert issue.save + assert_equal 0, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_send_email_notification_with_issue_parent_updated + with_settings :notified_events => %w(issue_parent_updated) do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.parent = issues(:issues_002) + + assert issue.save + assert_equal 2, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_not_send_email_notification_without_issue_parent_updated + with_settings :notified_events => [] do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.parent = issues(:issues_002) + + assert issue.save + assert_equal 0, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_send_email_notification_with_issue_project_updated + with_settings :notified_events => %w(issue_project_updated) do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.project = projects(:projects_002) + + assert issue.save + # Dave is not a member of project + assert_equal 1, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_not_send_email_notification_without_issue_project_updated + with_settings :notified_events => [] do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.project = projects(:projects_002) + + assert issue.save + assert_equal 0, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_send_email_notification_with_issue_tracker_updated + with_settings :notified_events => %w(issue_tracker_updated) do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.tracker = trackers(:trackers_002) + + assert issue.save + assert_equal 2, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_not_send_email_notification_without_issue_tracker_updated + with_settings :notified_events => [] do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.tracker = trackers(:trackers_002) + + assert issue.save + assert_equal 0, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_send_email_notification_with_issue_subject_updated + with_settings :notified_events => %w(issue_subject_updated) do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.subject = Time.current.to_s + + assert issue.save + assert_equal 2, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_not_send_email_notification_without_issue_subject_updated + with_settings :notified_events => [] do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.subject = Time.current.to_s + + assert issue.save + assert_equal 0, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_send_email_notification_with_issue_attachment_updated + with_settings :notified_events => %w(issue_attachment_updated) do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.save_attachments('1' => {'file' => mock_file_with_options(:original_filename => 'test.png')}) + issue.attach_saved_attachments + + assert issue.save + assert_equal 2, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_not_send_email_notification_without_issue_attachment_updated + with_settings :notified_events => [] do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.save_attachments('1' => {'file' => mock_file_with_options(:original_filename => 'test.png')}) + issue.attach_saved_attachments + + assert issue.save + assert_equal 0, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_send_email_notification_with_issue_relation_updated + with_settings :notified_events => %w(issue_relation_updated) do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + rel = IssueRelation.new(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1)) + rel.init_journals(user) + rel.save + + # relation updated two issues #1 and #3 + assert issue.save + assert_equal 4, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_not_send_email_notification_without_issue_relation_updated + with_settings :notified_events => [] do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + rel = IssueRelation.new(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1)) + rel.init_journals(user) + rel.save + + assert issue.save + assert_equal 0, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_send_email_notification_with_issue_custom_value_updated + with_settings :notified_events => %w(issue_custom_value_updated) do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.custom_field_values = {'2' => 'some value'} + + assert issue.save + assert_equal 2, ActionMailer::Base.deliveries.size + end + end + + def test_create_should_not_send_email_notification_without_custom_value_updated + with_settings :notified_events => [] do + user = User.find_by_login('jsmith') + issue = issues(:issues_001) + issue.init_journal(user) + issue.custom_field_values = {'2' => 'some value'} + assert issue.save assert_equal 0, ActionMailer::Base.deliveries.size end Index: config/locales/en.yml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/config/locales/en.yml b/config/locales/en.yml --- a/config/locales/en.yml (revision 153a4e26069b0f4182a4233516d7b4cb4aec72ac) +++ b/config/locales/en.yml (date 1638181575108) @@ -622,6 +622,19 @@ label_issue_assigned_to_updated: Assignee updated label_issue_priority_updated: Priority updated label_issue_fixed_version_updated: Target version updated + label_issue_start_date_updated: Start date updated + label_issue_due_date_updated: Due date updated + label_issue_estimated_hours_updated: Estimated hours updated + label_issue_category_updated: Category updated + label_issue_description_updated: Description updated + label_issue_done_ratio_updated: Done ratio updated + label_issue_parent_updated: Parent issue updated + label_issue_project_updated: Project updated + label_issue_tracker_updated: Tracker updated + label_issue_subject_updated: Subject updated + label_issue_attachment_updated: Attachment updated + label_issue_relation_updated: Relation updated + label_issue_custom_value_updated: Custom value updated label_document: Document label_document_new: New document label_document_plural: Documents Index: app/models/journal.rb IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/app/models/journal.rb b/app/models/journal.rb --- a/app/models/journal.rb (revision 153a4e26069b0f4182a4233516d7b4cb4aec72ac) +++ b/app/models/journal.rb (date 1638183281874) @@ -119,6 +119,11 @@ details.detect {|detail| detail.prop_key == attribute} end + # Returns the JournalDetail for the given property name + def detail_for_property(property) + details.detect {|detail| detail.property == property} + end + # Returns the new status if the journal contains a status change, otherwise nil def new_status s = new_value_for('status_id') @@ -332,7 +337,20 @@ (Setting.notified_events.include?('issue_status_updated') && new_status.present?) || (Setting.notified_events.include?('issue_assigned_to_updated') && detail_for_attribute('assigned_to_id').present?) || (Setting.notified_events.include?('issue_priority_updated') && new_value_for('priority_id').present?) || - (Setting.notified_events.include?('issue_fixed_version_updated') && detail_for_attribute('fixed_version_id').present?) + (Setting.notified_events.include?('issue_fixed_version_updated') && detail_for_attribute('fixed_version_id').present?) || + (Setting.notified_events.include?('issue_start_date_updated') && detail_for_attribute('start_date').present?) || + (Setting.notified_events.include?('issue_due_date_updated') && detail_for_attribute('due_date').present?) || + (Setting.notified_events.include?('issue_estimated_hours_updated') && detail_for_attribute('estimated_hours').present?) || + (Setting.notified_events.include?('issue_category_updated') && detail_for_attribute('category_id').present?) || + (Setting.notified_events.include?('issue_description_updated') && detail_for_attribute('description').present?) || + (Setting.notified_events.include?('issue_done_ratio_updated') && detail_for_attribute('done_ratio').present?) || + (Setting.notified_events.include?('issue_parent_updated') && detail_for_attribute('parent_id').present?) || + (Setting.notified_events.include?('issue_project_updated') && detail_for_attribute('project_id').present?) || + (Setting.notified_events.include?('issue_tracker_updated') && detail_for_attribute('tracker_id').present?) || + (Setting.notified_events.include?('issue_subject_updated') && detail_for_attribute('subject').present?) || + (Setting.notified_events.include?('issue_attachment_updated') && detail_for_property('attachment').present?) || + (Setting.notified_events.include?('issue_relation_updated') && detail_for_property('relation').present?) || + (Setting.notified_events.include?('issue_custom_value_updated') && detail_for_property('cf').present?) ) Mailer.deliver_issue_edit(self) end Index: lib/redmine/notifiable.rb IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/lib/redmine/notifiable.rb b/lib/redmine/notifiable.rb --- a/lib/redmine/notifiable.rb (revision 153a4e26069b0f4182a4233516d7b4cb4aec72ac) +++ b/lib/redmine/notifiable.rb (date 1638181575120) @@ -17,6 +17,19 @@ notifications << Notifiable.new('issue_assigned_to_updated', 'issue_updated') notifications << Notifiable.new('issue_priority_updated', 'issue_updated') notifications << Notifiable.new('issue_fixed_version_updated', 'issue_updated') + notifications << Notifiable.new('issue_start_date_updated', 'issue_updated') + notifications << Notifiable.new('issue_due_date_updated', 'issue_updated') + notifications << Notifiable.new('issue_estimated_hours_updated', 'issue_updated') + notifications << Notifiable.new('issue_category_updated', 'issue_updated') + notifications << Notifiable.new('issue_description_updated', 'issue_updated') + notifications << Notifiable.new('issue_done_ratio_updated', 'issue_updated') + notifications << Notifiable.new('issue_parent_updated', 'issue_updated') + notifications << Notifiable.new('issue_project_updated', 'issue_updated') + notifications << Notifiable.new('issue_tracker_updated', 'issue_updated') + notifications << Notifiable.new('issue_subject_updated', 'issue_updated') + notifications << Notifiable.new('issue_attachment_updated', 'issue_updated') + notifications << Notifiable.new('issue_relation_updated', 'issue_updated') + notifications << Notifiable.new('issue_custom_value_updated', 'issue_updated') notifications << Notifiable.new('news_added') notifications << Notifiable.new('news_comment_added') notifications << Notifiable.new('document_added')