@@ -0,0 +1,39 | |||||
|
1 | # redMine - project management software | |||
|
2 | # Copyright (C) 2006-2007 Jean-Philippe Lang | |||
|
3 | # | |||
|
4 | # This program is free software; you can redistribute it and/or | |||
|
5 | # modify it under the terms of the GNU General Public License | |||
|
6 | # as published by the Free Software Foundation; either version 2 | |||
|
7 | # of the License, or (at your option) any later version. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
14 | # You should have received a copy of the GNU General Public License | |||
|
15 | # along with this program; if not, write to the Free Software | |||
|
16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
|
17 | ||||
|
18 | require File.dirname(__FILE__) + '/../test_helper' | |||
|
19 | ||||
|
20 | class JournalTest < Test::Unit::TestCase | |||
|
21 | fixtures :issues, :issue_statuses, :journals, :journal_details | |||
|
22 | ||||
|
23 | def setup | |||
|
24 | @journal = Journal.find 1 | |||
|
25 | end | |||
|
26 | ||||
|
27 | def test_journalized_is_an_issue | |||
|
28 | issue = @journal.issue | |||
|
29 | assert_kind_of Issue, issue | |||
|
30 | assert_equal 1, issue.id | |||
|
31 | end | |||
|
32 | ||||
|
33 | def test_new_status | |||
|
34 | status = @journal.new_status | |||
|
35 | assert_not_nil status | |||
|
36 | assert_kind_of IssueStatus, status | |||
|
37 | assert_equal 2, status.id | |||
|
38 | end | |||
|
39 | end |
@@ -405,6 +405,7 class ProjectsController < ApplicationController | |||||
405 |
|
405 | |||
406 | if @scope.include?('issues') |
|
406 | if @scope.include?('issues') | |
407 | @events += @project.issues.find(:all, :include => [:author, :tracker], :conditions => ["#{Issue.table_name}.created_on>=? and #{Issue.table_name}.created_on<=?", @date_from, @date_to] ) |
|
407 | @events += @project.issues.find(:all, :include => [:author, :tracker], :conditions => ["#{Issue.table_name}.created_on>=? and #{Issue.table_name}.created_on<=?", @date_from, @date_to] ) | |
|
408 | @events += @project.issues_status_changes(@date_from, @date_to) | |||
408 | end |
|
409 | end | |
409 |
|
410 | |||
410 | if @scope.include?('news') |
|
411 | if @scope.include?('news') |
@@ -29,12 +29,19 class Journal < ActiveRecord::Base | |||||
29 | :project_key => "#{Issue.table_name}.project_id", |
|
29 | :project_key => "#{Issue.table_name}.project_id", | |
30 | :date_column => "#{Issue.table_name}.created_on" |
|
30 | :date_column => "#{Issue.table_name}.created_on" | |
31 |
|
31 | |||
32 | acts_as_event :title => Proc.new {|o| "#{o.issue.tracker.name} ##{o.issue.id}: #{o.issue.subject}"}, |
|
32 | acts_as_event :title => Proc.new {|o| "#{o.issue.tracker.name} ##{o.issue.id}: #{o.issue.subject}" + ((s = o.new_status) ? " (#{s})" : '') }, | |
33 | :description => :notes, |
|
33 | :description => :notes, | |
|
34 | :author => :user, | |||
34 | :url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue.id}} |
|
35 | :url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue.id}} | |
35 |
|
36 | |||
36 | def save |
|
37 | def save | |
37 | # Do not save an empty journal |
|
38 | # Do not save an empty journal | |
38 | (details.empty? && notes.blank?) ? false : super |
|
39 | (details.empty? && notes.blank?) ? false : super | |
39 | end |
|
40 | end | |
|
41 | ||||
|
42 | # Returns the new status if the journal contains a status change, otherwise nil | |||
|
43 | def new_status | |||
|
44 | c = details.detect {|detail| detail.prop_key == 'status_id'} | |||
|
45 | (c && c.value) ? IssueStatus.find_by_id(c.value.to_i) : nil | |||
|
46 | end | |||
40 | end |
|
47 | end |
@@ -75,7 +75,17 class Project < ActiveRecord::Base | |||||
75 | yield |
|
75 | yield | |
76 | end |
|
76 | end | |
77 | end |
|
77 | end | |
78 |
|
78 | |||
|
79 | # Return all issues status changes for the project between the 2 given dates | |||
|
80 | def issues_status_changes(from, to) | |||
|
81 | Journal.find(:all, :include => [:issue, :details, :user], | |||
|
82 | :conditions => ["#{Journal.table_name}.journalized_type = 'Issue'" + | |||
|
83 | " AND #{Issue.table_name}.project_id = ?" + | |||
|
84 | " AND #{JournalDetail.table_name}.prop_key = 'status_id'" + | |||
|
85 | " AND #{Journal.table_name}.created_on BETWEEN ? AND ?", | |||
|
86 | id, from, to+1]) | |||
|
87 | end | |||
|
88 | ||||
79 | # returns latest created projects |
|
89 | # returns latest created projects | |
80 | # non public projects will be returned only if user is a member of those |
|
90 | # non public projects will be returned only if user is a member of those | |
81 | def self.latest(user=nil, count=5) |
|
91 | def self.latest(user=nil, count=5) |
@@ -6,7 +6,7 | |||||
6 | <% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| %> |
|
6 | <% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| %> | |
7 | <li><p><%= e.event_datetime.strftime("%H:%M") %> <%= link_to truncate(e.event_title, 100), e.event_url %><br /> |
|
7 | <li><p><%= e.event_datetime.strftime("%H:%M") %> <%= link_to truncate(e.event_title, 100), e.event_url %><br /> | |
8 | <% unless e.event_description.blank? %><em><%= truncate(e.event_description, 500) %></em><br /><% end %> |
|
8 | <% unless e.event_description.blank? %><em><%= truncate(e.event_description, 500) %></em><br /><% end %> | |
9 | <span class="author"><%= e.event_author if e.respond_to?(:author) %></span></p></li> |
|
9 | <span class="author"><%= e.event_author if e.respond_to?(:event_author) %></span></p></li> | |
10 | <% end %> |
|
10 | <% end %> | |
11 | </ul> |
|
11 | </ul> | |
12 | <% end %> |
|
12 | <% end %> |
@@ -1,8 +1,8 | |||||
1 | --- |
|
1 | --- | |
2 | issues_001: |
|
2 | issues_001: | |
3 | created_on: 2006-07-19 21:02:17 +02:00 |
|
3 | created_on: <%= 3.days.ago.to_date.to_s(:db) %> | |
4 | project_id: 1 |
|
4 | project_id: 1 | |
5 | updated_on: 2006-07-19 21:04:30 +02:00 |
|
5 | updated_on: <%= 1.day.ago.to_date.to_s(:db) %> | |
6 | priority_id: 4 |
|
6 | priority_id: 4 | |
7 | subject: Can't print recipes |
|
7 | subject: Can't print recipes | |
8 | id: 1 |
|
8 | id: 1 | |
@@ -55,4 +55,4 issues_004: | |||||
55 | assigned_to_id: |
|
55 | assigned_to_id: | |
56 | author_id: 2 |
|
56 | author_id: 2 | |
57 | status_id: 1 |
|
57 | status_id: 1 | |
58 | No newline at end of file |
|
58 |
@@ -1,6 +1,6 | |||||
1 | --- |
|
1 | --- | |
2 | journals_001: |
|
2 | journals_001: | |
3 | created_on: 2007-01-26 19:58:40 +01:00 |
|
3 | created_on: <%= 2.days.ago.to_date.to_s(:db) %> | |
4 | notes: "Journal notes" |
|
4 | notes: "Journal notes" | |
5 | id: 1 |
|
5 | id: 1 | |
6 | journalized_type: Issue |
|
6 | journalized_type: Issue |
@@ -22,7 +22,7 require 'projects_controller' | |||||
22 | class ProjectsController; def rescue_action(e) raise e end; end |
|
22 | class ProjectsController; def rescue_action(e) raise e end; end | |
23 |
|
23 | |||
24 | class ProjectsControllerTest < Test::Unit::TestCase |
|
24 | class ProjectsControllerTest < Test::Unit::TestCase | |
25 | fixtures :projects, :users, :roles, :members, :issues, :enabled_modules, :enumerations |
|
25 | fixtures :projects, :users, :roles, :members, :issues, :journals, :journal_details, :trackers, :issue_statuses, :enabled_modules, :enumerations | |
26 |
|
26 | |||
27 | def setup |
|
27 | def setup | |
28 | @controller = ProjectsController.new |
|
28 | @controller = ProjectsController.new | |
@@ -93,6 +93,24 class ProjectsControllerTest < Test::Unit::TestCase | |||||
93 | assert_response :success |
|
93 | assert_response :success | |
94 | assert_template 'activity' |
|
94 | assert_template 'activity' | |
95 | assert_not_nil assigns(:events_by_day) |
|
95 | assert_not_nil assigns(:events_by_day) | |
|
96 | ||||
|
97 | assert_tag :tag => "h3", | |||
|
98 | :content => /#{2.days.ago.to_date.day}/, | |||
|
99 | :sibling => { :tag => "ul", | |||
|
100 | :child => { :tag => "li", | |||
|
101 | :child => { :tag => "p", | |||
|
102 | :content => /(#{IssueStatus.find(2).name})/, | |||
|
103 | } | |||
|
104 | } | |||
|
105 | } | |||
|
106 | assert_tag :tag => "h3", | |||
|
107 | :content => /#{3.day.ago.to_date.day}/, | |||
|
108 | :sibling => { :tag => "ul", :child => { :tag => "li", | |||
|
109 | :child => { :tag => "p", | |||
|
110 | :content => /#{Issue.find(1).subject}/, | |||
|
111 | } | |||
|
112 | } | |||
|
113 | } | |||
96 | end |
|
114 | end | |
97 |
|
115 | |||
98 | def test_archive |
|
116 | def test_archive |
@@ -1,107 +1,116 | |||||
1 | # redMine - project management software |
|
1 | # redMine - project management software | |
2 | # Copyright (C) 2006-2007 Jean-Philippe Lang |
|
2 | # Copyright (C) 2006-2007 Jean-Philippe Lang | |
3 | # |
|
3 | # | |
4 | # This program is free software; you can redistribute it and/or |
|
4 | # This program is free software; you can redistribute it and/or | |
5 | # modify it under the terms of the GNU General Public License |
|
5 | # modify it under the terms of the GNU General Public License | |
6 | # as published by the Free Software Foundation; either version 2 |
|
6 | # as published by the Free Software Foundation; either version 2 | |
7 | # of the License, or (at your option) any later version. |
|
7 | # of the License, or (at your option) any later version. | |
8 | # |
|
8 | # | |
9 | # This program is distributed in the hope that it will be useful, |
|
9 | # This program is distributed in the hope that it will be useful, | |
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | # GNU General Public License for more details. |
|
12 | # GNU General Public License for more details. | |
13 | # |
|
13 | # | |
14 | # You should have received a copy of the GNU General Public License |
|
14 | # You should have received a copy of the GNU General Public License | |
15 | # along with this program; if not, write to the Free Software |
|
15 | # along with this program; if not, write to the Free Software | |
16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
17 |
|
17 | |||
18 | require File.dirname(__FILE__) + '/../test_helper' |
|
18 | require File.dirname(__FILE__) + '/../test_helper' | |
19 |
|
19 | |||
20 | class ProjectTest < Test::Unit::TestCase |
|
20 | class ProjectTest < Test::Unit::TestCase | |
21 | fixtures :projects |
|
21 | fixtures :projects, :issues, :issue_statuses, :journals, :journal_details | |
22 |
|
22 | |||
23 | def setup |
|
23 | def setup | |
24 | @ecookbook = Project.find(1) |
|
24 | @ecookbook = Project.find(1) | |
25 | @ecookbook_sub1 = Project.find(3) |
|
25 | @ecookbook_sub1 = Project.find(3) | |
26 | end |
|
26 | end | |
27 |
|
27 | |||
28 | def test_truth |
|
28 | def test_truth | |
29 | assert_kind_of Project, @ecookbook |
|
29 | assert_kind_of Project, @ecookbook | |
30 | assert_equal "eCookbook", @ecookbook.name |
|
30 | assert_equal "eCookbook", @ecookbook.name | |
31 | end |
|
31 | end | |
32 |
|
32 | |||
33 | def test_update |
|
33 | def test_update | |
34 | assert_equal "eCookbook", @ecookbook.name |
|
34 | assert_equal "eCookbook", @ecookbook.name | |
35 | @ecookbook.name = "eCook" |
|
35 | @ecookbook.name = "eCook" | |
36 | assert @ecookbook.save, @ecookbook.errors.full_messages.join("; ") |
|
36 | assert @ecookbook.save, @ecookbook.errors.full_messages.join("; ") | |
37 | @ecookbook.reload |
|
37 | @ecookbook.reload | |
38 | assert_equal "eCook", @ecookbook.name |
|
38 | assert_equal "eCook", @ecookbook.name | |
39 | end |
|
39 | end | |
40 |
|
40 | |||
41 | def test_validate |
|
41 | def test_validate | |
42 | @ecookbook.name = "" |
|
42 | @ecookbook.name = "" | |
43 | assert !@ecookbook.save |
|
43 | assert !@ecookbook.save | |
44 | assert_equal 1, @ecookbook.errors.count |
|
44 | assert_equal 1, @ecookbook.errors.count | |
45 | assert_equal "activerecord_error_blank", @ecookbook.errors.on(:name) |
|
45 | assert_equal "activerecord_error_blank", @ecookbook.errors.on(:name) | |
46 | end |
|
46 | end | |
47 |
|
47 | |||
48 | def test_public_projects |
|
48 | def test_public_projects | |
49 | public_projects = Project.find(:all, :conditions => ["is_public=?", true]) |
|
49 | public_projects = Project.find(:all, :conditions => ["is_public=?", true]) | |
50 | assert_equal 3, public_projects.length |
|
50 | assert_equal 3, public_projects.length | |
51 | assert_equal true, public_projects[0].is_public? |
|
51 | assert_equal true, public_projects[0].is_public? | |
52 | end |
|
52 | end | |
53 |
|
53 | |||
54 | def test_archive |
|
54 | def test_archive | |
55 | user = @ecookbook.members.first.user |
|
55 | user = @ecookbook.members.first.user | |
56 | @ecookbook.archive |
|
56 | @ecookbook.archive | |
57 | @ecookbook.reload |
|
57 | @ecookbook.reload | |
58 |
|
58 | |||
59 | assert !@ecookbook.active? |
|
59 | assert !@ecookbook.active? | |
60 | assert !user.projects.include?(@ecookbook) |
|
60 | assert !user.projects.include?(@ecookbook) | |
61 | # Subproject are also archived |
|
61 | # Subproject are also archived | |
62 | assert !@ecookbook.children.empty? |
|
62 | assert !@ecookbook.children.empty? | |
63 | assert @ecookbook.active_children.empty? |
|
63 | assert @ecookbook.active_children.empty? | |
64 | end |
|
64 | end | |
65 |
|
65 | |||
66 | def test_unarchive |
|
66 | def test_unarchive | |
67 | user = @ecookbook.members.first.user |
|
67 | user = @ecookbook.members.first.user | |
68 | @ecookbook.archive |
|
68 | @ecookbook.archive | |
69 | # A subproject of an archived project can not be unarchived |
|
69 | # A subproject of an archived project can not be unarchived | |
70 | assert !@ecookbook_sub1.unarchive |
|
70 | assert !@ecookbook_sub1.unarchive | |
71 |
|
71 | |||
72 | # Unarchive project |
|
72 | # Unarchive project | |
73 | assert @ecookbook.unarchive |
|
73 | assert @ecookbook.unarchive | |
74 | @ecookbook.reload |
|
74 | @ecookbook.reload | |
75 | assert @ecookbook.active? |
|
75 | assert @ecookbook.active? | |
76 | assert user.projects.include?(@ecookbook) |
|
76 | assert user.projects.include?(@ecookbook) | |
77 | # Subproject can now be unarchived |
|
77 | # Subproject can now be unarchived | |
78 | @ecookbook_sub1.reload |
|
78 | @ecookbook_sub1.reload | |
79 | assert @ecookbook_sub1.unarchive |
|
79 | assert @ecookbook_sub1.unarchive | |
80 | end |
|
80 | end | |
81 |
|
81 | |||
82 | def test_destroy |
|
82 | def test_destroy | |
83 | @ecookbook.destroy |
|
83 | @ecookbook.destroy | |
84 | assert_raise(ActiveRecord::RecordNotFound) { Project.find(@ecookbook.id) } |
|
84 | assert_raise(ActiveRecord::RecordNotFound) { Project.find(@ecookbook.id) } | |
85 | end |
|
85 | end | |
86 |
|
86 | |||
87 | def test_subproject_ok |
|
87 | def test_subproject_ok | |
88 | sub = Project.find(2) |
|
88 | sub = Project.find(2) | |
89 | sub.parent = @ecookbook |
|
89 | sub.parent = @ecookbook | |
90 | assert sub.save |
|
90 | assert sub.save | |
91 | assert_equal @ecookbook.id, sub.parent.id |
|
91 | assert_equal @ecookbook.id, sub.parent.id | |
92 | @ecookbook.reload |
|
92 | @ecookbook.reload | |
93 | assert_equal 3, @ecookbook.children.size |
|
93 | assert_equal 3, @ecookbook.children.size | |
94 | end |
|
94 | end | |
95 |
|
95 | |||
96 | def test_subproject_invalid |
|
96 | def test_subproject_invalid | |
97 | sub = Project.find(2) |
|
97 | sub = Project.find(2) | |
98 | sub.parent = @ecookbook_sub1 |
|
98 | sub.parent = @ecookbook_sub1 | |
99 | assert !sub.save |
|
99 | assert !sub.save | |
100 | end |
|
100 | end | |
101 |
|
101 | |||
102 | def test_subproject_invalid_2 |
|
102 | def test_subproject_invalid_2 | |
103 | sub = @ecookbook |
|
103 | sub = @ecookbook | |
104 | sub.parent = Project.find(2) |
|
104 | sub.parent = Project.find(2) | |
105 | assert !sub.save |
|
105 | assert !sub.save | |
106 | end |
|
106 | end | |
107 | end |
|
107 | ||
|
108 | def test_issues_status_changes | |||
|
109 | journals = @ecookbook.issues_status_changes 3.days.ago.to_date, Date.today | |||
|
110 | assert_equal 1, journals.size | |||
|
111 | assert_kind_of Journal, journals.first | |||
|
112 | ||||
|
113 | journals = @ecookbook.issues_status_changes 30.days.ago.to_date, 10.days.ago.to_date | |||
|
114 | assert_equal 0, journals.size | |||
|
115 | end | |||
|
116 | end |
General Comments 0
You need to be logged in to leave comments.
Login now