##// END OF EJS Templates
Merged r5944 from trunk....
Jean-Philippe Lang -
r5827:fabf54a36801
parent child
Show More
@@ -1,89 +1,88
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class Journal < ActiveRecord::Base
19 19 belongs_to :journalized, :polymorphic => true
20 20 # added as a quick fix to allow eager loading of the polymorphic association
21 21 # since always associated to an issue, for now
22 22 belongs_to :issue, :foreign_key => :journalized_id
23 23
24 24 belongs_to :user
25 25 has_many :details, :class_name => "JournalDetail", :dependent => :delete_all
26 26 attr_accessor :indice
27 27
28 28 acts_as_event :title => Proc.new {|o| status = ((s = o.new_status) ? " (#{s})" : nil); "#{o.issue.tracker} ##{o.issue.id}#{status}: #{o.issue.subject}" },
29 29 :description => :notes,
30 30 :author => :user,
31 31 :type => Proc.new {|o| (s = o.new_status) ? (s.is_closed? ? 'issue-closed' : 'issue-edit') : 'issue-note' },
32 32 :url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue.id, :anchor => "change-#{o.id}"}}
33 33
34 34 acts_as_activity_provider :type => 'issues',
35 :permission => :view_issues,
36 35 :author_key => :user_id,
37 36 :find_options => {:include => [{:issue => :project}, :details, :user],
38 37 :conditions => "#{Journal.table_name}.journalized_type = 'Issue' AND" +
39 38 " (#{JournalDetail.table_name}.prop_key = 'status_id' OR #{Journal.table_name}.notes <> '')"}
40 39
41 40 named_scope :visible, lambda {|*args| {
42 41 :include => {:issue => :project},
43 42 :conditions => Issue.visible_condition(args.shift || User.current, *args)
44 43 }}
45 44
46 45 def save(*args)
47 46 # Do not save an empty journal
48 47 (details.empty? && notes.blank?) ? false : super
49 48 end
50 49
51 50 # Returns the new status if the journal contains a status change, otherwise nil
52 51 def new_status
53 52 c = details.detect {|detail| detail.prop_key == 'status_id'}
54 53 (c && c.value) ? IssueStatus.find_by_id(c.value.to_i) : nil
55 54 end
56 55
57 56 def new_value_for(prop)
58 57 c = details.detect {|detail| detail.prop_key == prop}
59 58 c ? c.value : nil
60 59 end
61 60
62 61 def editable_by?(usr)
63 62 usr && usr.logged? && (usr.allowed_to?(:edit_issue_notes, project) || (self.user == usr && usr.allowed_to?(:edit_own_issue_notes, project)))
64 63 end
65 64
66 65 def project
67 66 journalized.respond_to?(:project) ? journalized.project : nil
68 67 end
69 68
70 69 def attachments
71 70 journalized.respond_to?(:attachments) ? journalized.attachments : nil
72 71 end
73 72
74 73 # Returns a string of css classes
75 74 def css_classes
76 75 s = 'journal'
77 76 s << ' has-notes' unless notes.blank?
78 77 s << ' has-details' unless details.blank?
79 78 s
80 79 end
81 80
82 81 def notify?
83 82 @notify != false
84 83 end
85 84
86 85 def notify=(arg)
87 86 @notify = arg
88 87 end
89 88 end
@@ -1,29 +1,36
1 1 ---
2 2 journals_001:
3 3 created_on: <%= 2.days.ago.to_date.to_s(:db) %>
4 4 notes: "Journal notes"
5 5 id: 1
6 6 journalized_type: Issue
7 7 user_id: 1
8 8 journalized_id: 1
9 9 journals_002:
10 10 created_on: <%= 1.days.ago.to_date.to_s(:db) %>
11 11 notes: "Some notes with Redmine links: #2, r2."
12 12 id: 2
13 13 journalized_type: Issue
14 14 user_id: 2
15 15 journalized_id: 1
16 16 journals_003:
17 17 created_on: <%= 1.days.ago.to_date.to_s(:db) %>
18 18 notes: "A comment with inline image: !picture.jpg!"
19 19 id: 3
20 20 journalized_type: Issue
21 21 user_id: 2
22 22 journalized_id: 2
23 23 journals_004:
24 24 created_on: <%= 1.days.ago.to_date.to_s(:db) %>
25 25 notes: "A comment with a private version."
26 26 id: 4
27 27 journalized_type: Issue
28 28 user_id: 1
29 29 journalized_id: 6
30 journals_005:
31 id: 5
32 created_on: <%= 1.days.ago.to_date.to_s(:db) %>
33 notes: "A comment on a private issue."
34 user_id: 2
35 journalized_type: Issue
36 journalized_id: 14
@@ -1,92 +1,95
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class ActivityTest < ActiveSupport::TestCase
21 21 fixtures :projects, :versions, :attachments, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
22 22 :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages
23 23
24 24 def setup
25 25 @project = Project.find(1)
26 26 end
27 27
28 28 def test_activity_without_subprojects
29 29 events = find_events(User.anonymous, :project => @project)
30 30 assert_not_nil events
31 31
32 32 assert events.include?(Issue.find(1))
33 33 assert !events.include?(Issue.find(4))
34 34 # subproject issue
35 35 assert !events.include?(Issue.find(5))
36 36 end
37 37
38 38 def test_activity_with_subprojects
39 39 events = find_events(User.anonymous, :project => @project, :with_subprojects => 1)
40 40 assert_not_nil events
41 41
42 42 assert events.include?(Issue.find(1))
43 43 # subproject issue
44 44 assert events.include?(Issue.find(5))
45 45 end
46 46
47 47 def test_global_activity_anonymous
48 48 events = find_events(User.anonymous)
49 49 assert_not_nil events
50 50
51 51 assert events.include?(Issue.find(1))
52 52 assert events.include?(Message.find(5))
53 53 # Issue of a private project
54 54 assert !events.include?(Issue.find(4))
55 # Private issue and comment
56 assert !events.include?(Issue.find(14))
57 assert !events.include?(Journal.find(5))
55 58 end
56 59
57 60 def test_global_activity_logged_user
58 61 events = find_events(User.find(2)) # manager
59 62 assert_not_nil events
60 63
61 64 assert events.include?(Issue.find(1))
62 65 # Issue of a private project the user belongs to
63 66 assert events.include?(Issue.find(4))
64 67 end
65 68
66 69 def test_user_activity
67 70 user = User.find(2)
68 71 events = Redmine::Activity::Fetcher.new(User.anonymous, :author => user).events(nil, nil, :limit => 10)
69 72
70 73 assert(events.size > 0)
71 74 assert(events.size <= 10)
72 75 assert_nil(events.detect {|e| e.event_author != user})
73 76 end
74 77
75 78 def test_files_activity
76 79 f = Redmine::Activity::Fetcher.new(User.anonymous, :project => Project.find(1))
77 80 f.scope = ['files']
78 81 events = f.events
79 82
80 83 assert_kind_of Array, events
81 84 assert events.include?(Attachment.find_by_container_type_and_container_id('Project', 1))
82 85 assert events.include?(Attachment.find_by_container_type_and_container_id('Version', 1))
83 86 assert_equal [Attachment], events.collect(&:class).uniq
84 87 assert_equal %w(Project Version), events.collect(&:container_type).uniq.sort
85 88 end
86 89
87 90 private
88 91
89 92 def find_events(user, options={})
90 93 Redmine::Activity::Fetcher.new(user, options).events(Date.today - 30, Date.today + 1)
91 94 end
92 95 end
General Comments 0
You need to be logged in to leave comments. Login now