Added issues status changes on the activity view (initial patch by Cyril Mougel).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@892 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
a069c4afcf
commit
fa95501fe5
|
@ -405,6 +405,7 @@ class ProjectsController < ApplicationController
|
|||
|
||||
if @scope.include?('issues')
|
||||
@events += @project.issues.find(:all, :include => [:author, :tracker], :conditions => ["#{Issue.table_name}.created_on>=? and #{Issue.table_name}.created_on<=?", @date_from, @date_to] )
|
||||
@events += @project.issues_status_changes(@date_from, @date_to)
|
||||
end
|
||||
|
||||
if @scope.include?('news')
|
||||
|
|
|
@ -29,12 +29,19 @@ class Journal < ActiveRecord::Base
|
|||
:project_key => "#{Issue.table_name}.project_id",
|
||||
:date_column => "#{Issue.table_name}.created_on"
|
||||
|
||||
acts_as_event :title => Proc.new {|o| "#{o.issue.tracker.name} ##{o.issue.id}: #{o.issue.subject}"},
|
||||
acts_as_event :title => Proc.new {|o| "#{o.issue.tracker.name} ##{o.issue.id}: #{o.issue.subject}" + ((s = o.new_status) ? " (#{s})" : '') },
|
||||
:description => :notes,
|
||||
:author => :user,
|
||||
:url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue.id}}
|
||||
|
||||
def save
|
||||
# Do not save an empty journal
|
||||
(details.empty? && notes.blank?) ? false : super
|
||||
end
|
||||
|
||||
# Returns the new status if the journal contains a status change, otherwise nil
|
||||
def new_status
|
||||
c = details.detect {|detail| detail.prop_key == 'status_id'}
|
||||
(c && c.value) ? IssueStatus.find_by_id(c.value.to_i) : nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -75,7 +75,17 @@ class Project < ActiveRecord::Base
|
|||
yield
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Return all issues status changes for the project between the 2 given dates
|
||||
def issues_status_changes(from, to)
|
||||
Journal.find(:all, :include => [:issue, :details, :user],
|
||||
:conditions => ["#{Journal.table_name}.journalized_type = 'Issue'" +
|
||||
" AND #{Issue.table_name}.project_id = ?" +
|
||||
" AND #{JournalDetail.table_name}.prop_key = 'status_id'" +
|
||||
" AND #{Journal.table_name}.created_on BETWEEN ? AND ?",
|
||||
id, from, to+1])
|
||||
end
|
||||
|
||||
# returns latest created projects
|
||||
# non public projects will be returned only if user is a member of those
|
||||
def self.latest(user=nil, count=5)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| %>
|
||||
<li><p><%= e.event_datetime.strftime("%H:%M") %> <%= link_to truncate(e.event_title, 100), e.event_url %><br />
|
||||
<% unless e.event_description.blank? %><em><%= truncate(e.event_description, 500) %></em><br /><% end %>
|
||||
<span class="author"><%= e.event_author if e.respond_to?(:author) %></span></p></li>
|
||||
<span class="author"><%= e.event_author if e.respond_to?(:event_author) %></span></p></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
issues_001:
|
||||
created_on: 2006-07-19 21:02:17 +02:00
|
||||
created_on: <%= 3.days.ago.to_date.to_s(:db) %>
|
||||
project_id: 1
|
||||
updated_on: 2006-07-19 21:04:30 +02:00
|
||||
updated_on: <%= 1.day.ago.to_date.to_s(:db) %>
|
||||
priority_id: 4
|
||||
subject: Can't print recipes
|
||||
id: 1
|
||||
|
@ -55,4 +55,4 @@ issues_004:
|
|||
assigned_to_id:
|
||||
author_id: 2
|
||||
status_id: 1
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
journals_001:
|
||||
created_on: 2007-01-26 19:58:40 +01:00
|
||||
created_on: <%= 2.days.ago.to_date.to_s(:db) %>
|
||||
notes: "Journal notes"
|
||||
id: 1
|
||||
journalized_type: Issue
|
||||
|
|
|
@ -22,7 +22,7 @@ require 'projects_controller'
|
|||
class ProjectsController; def rescue_action(e) raise e end; end
|
||||
|
||||
class ProjectsControllerTest < Test::Unit::TestCase
|
||||
fixtures :projects, :users, :roles, :members, :issues, :enabled_modules, :enumerations
|
||||
fixtures :projects, :users, :roles, :members, :issues, :journals, :journal_details, :trackers, :issue_statuses, :enabled_modules, :enumerations
|
||||
|
||||
def setup
|
||||
@controller = ProjectsController.new
|
||||
|
@ -93,6 +93,24 @@ class ProjectsControllerTest < Test::Unit::TestCase
|
|||
assert_response :success
|
||||
assert_template 'activity'
|
||||
assert_not_nil assigns(:events_by_day)
|
||||
|
||||
assert_tag :tag => "h3",
|
||||
:content => /#{2.days.ago.to_date.day}/,
|
||||
:sibling => { :tag => "ul",
|
||||
:child => { :tag => "li",
|
||||
:child => { :tag => "p",
|
||||
:content => /(#{IssueStatus.find(2).name})/,
|
||||
}
|
||||
}
|
||||
}
|
||||
assert_tag :tag => "h3",
|
||||
:content => /#{3.day.ago.to_date.day}/,
|
||||
:sibling => { :tag => "ul", :child => { :tag => "li",
|
||||
:child => { :tag => "p",
|
||||
:content => /#{Issue.find(1).subject}/,
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def test_archive
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
# redMine - project management software
|
||||
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class JournalTest < Test::Unit::TestCase
|
||||
fixtures :issues, :issue_statuses, :journals, :journal_details
|
||||
|
||||
def setup
|
||||
@journal = Journal.find 1
|
||||
end
|
||||
|
||||
def test_journalized_is_an_issue
|
||||
issue = @journal.issue
|
||||
assert_kind_of Issue, issue
|
||||
assert_equal 1, issue.id
|
||||
end
|
||||
|
||||
def test_new_status
|
||||
status = @journal.new_status
|
||||
assert_not_nil status
|
||||
assert_kind_of IssueStatus, status
|
||||
assert_equal 2, status.id
|
||||
end
|
||||
end
|
|
@ -1,107 +1,116 @@
|
|||
# redMine - project management software
|
||||
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class ProjectTest < Test::Unit::TestCase
|
||||
fixtures :projects
|
||||
|
||||
def setup
|
||||
@ecookbook = Project.find(1)
|
||||
@ecookbook_sub1 = Project.find(3)
|
||||
end
|
||||
|
||||
def test_truth
|
||||
assert_kind_of Project, @ecookbook
|
||||
assert_equal "eCookbook", @ecookbook.name
|
||||
end
|
||||
|
||||
def test_update
|
||||
assert_equal "eCookbook", @ecookbook.name
|
||||
@ecookbook.name = "eCook"
|
||||
assert @ecookbook.save, @ecookbook.errors.full_messages.join("; ")
|
||||
@ecookbook.reload
|
||||
assert_equal "eCook", @ecookbook.name
|
||||
end
|
||||
|
||||
def test_validate
|
||||
@ecookbook.name = ""
|
||||
assert !@ecookbook.save
|
||||
assert_equal 1, @ecookbook.errors.count
|
||||
assert_equal "activerecord_error_blank", @ecookbook.errors.on(:name)
|
||||
end
|
||||
|
||||
def test_public_projects
|
||||
public_projects = Project.find(:all, :conditions => ["is_public=?", true])
|
||||
assert_equal 3, public_projects.length
|
||||
assert_equal true, public_projects[0].is_public?
|
||||
end
|
||||
|
||||
def test_archive
|
||||
user = @ecookbook.members.first.user
|
||||
@ecookbook.archive
|
||||
@ecookbook.reload
|
||||
|
||||
assert !@ecookbook.active?
|
||||
assert !user.projects.include?(@ecookbook)
|
||||
# Subproject are also archived
|
||||
assert !@ecookbook.children.empty?
|
||||
assert @ecookbook.active_children.empty?
|
||||
end
|
||||
|
||||
def test_unarchive
|
||||
user = @ecookbook.members.first.user
|
||||
@ecookbook.archive
|
||||
# A subproject of an archived project can not be unarchived
|
||||
assert !@ecookbook_sub1.unarchive
|
||||
|
||||
# Unarchive project
|
||||
assert @ecookbook.unarchive
|
||||
@ecookbook.reload
|
||||
assert @ecookbook.active?
|
||||
assert user.projects.include?(@ecookbook)
|
||||
# Subproject can now be unarchived
|
||||
@ecookbook_sub1.reload
|
||||
assert @ecookbook_sub1.unarchive
|
||||
end
|
||||
|
||||
def test_destroy
|
||||
@ecookbook.destroy
|
||||
assert_raise(ActiveRecord::RecordNotFound) { Project.find(@ecookbook.id) }
|
||||
end
|
||||
|
||||
def test_subproject_ok
|
||||
sub = Project.find(2)
|
||||
sub.parent = @ecookbook
|
||||
assert sub.save
|
||||
assert_equal @ecookbook.id, sub.parent.id
|
||||
@ecookbook.reload
|
||||
assert_equal 3, @ecookbook.children.size
|
||||
end
|
||||
|
||||
def test_subproject_invalid
|
||||
sub = Project.find(2)
|
||||
sub.parent = @ecookbook_sub1
|
||||
assert !sub.save
|
||||
end
|
||||
|
||||
def test_subproject_invalid_2
|
||||
sub = @ecookbook
|
||||
sub.parent = Project.find(2)
|
||||
assert !sub.save
|
||||
end
|
||||
end
|
||||
# redMine - project management software
|
||||
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class ProjectTest < Test::Unit::TestCase
|
||||
fixtures :projects, :issues, :issue_statuses, :journals, :journal_details
|
||||
|
||||
def setup
|
||||
@ecookbook = Project.find(1)
|
||||
@ecookbook_sub1 = Project.find(3)
|
||||
end
|
||||
|
||||
def test_truth
|
||||
assert_kind_of Project, @ecookbook
|
||||
assert_equal "eCookbook", @ecookbook.name
|
||||
end
|
||||
|
||||
def test_update
|
||||
assert_equal "eCookbook", @ecookbook.name
|
||||
@ecookbook.name = "eCook"
|
||||
assert @ecookbook.save, @ecookbook.errors.full_messages.join("; ")
|
||||
@ecookbook.reload
|
||||
assert_equal "eCook", @ecookbook.name
|
||||
end
|
||||
|
||||
def test_validate
|
||||
@ecookbook.name = ""
|
||||
assert !@ecookbook.save
|
||||
assert_equal 1, @ecookbook.errors.count
|
||||
assert_equal "activerecord_error_blank", @ecookbook.errors.on(:name)
|
||||
end
|
||||
|
||||
def test_public_projects
|
||||
public_projects = Project.find(:all, :conditions => ["is_public=?", true])
|
||||
assert_equal 3, public_projects.length
|
||||
assert_equal true, public_projects[0].is_public?
|
||||
end
|
||||
|
||||
def test_archive
|
||||
user = @ecookbook.members.first.user
|
||||
@ecookbook.archive
|
||||
@ecookbook.reload
|
||||
|
||||
assert !@ecookbook.active?
|
||||
assert !user.projects.include?(@ecookbook)
|
||||
# Subproject are also archived
|
||||
assert !@ecookbook.children.empty?
|
||||
assert @ecookbook.active_children.empty?
|
||||
end
|
||||
|
||||
def test_unarchive
|
||||
user = @ecookbook.members.first.user
|
||||
@ecookbook.archive
|
||||
# A subproject of an archived project can not be unarchived
|
||||
assert !@ecookbook_sub1.unarchive
|
||||
|
||||
# Unarchive project
|
||||
assert @ecookbook.unarchive
|
||||
@ecookbook.reload
|
||||
assert @ecookbook.active?
|
||||
assert user.projects.include?(@ecookbook)
|
||||
# Subproject can now be unarchived
|
||||
@ecookbook_sub1.reload
|
||||
assert @ecookbook_sub1.unarchive
|
||||
end
|
||||
|
||||
def test_destroy
|
||||
@ecookbook.destroy
|
||||
assert_raise(ActiveRecord::RecordNotFound) { Project.find(@ecookbook.id) }
|
||||
end
|
||||
|
||||
def test_subproject_ok
|
||||
sub = Project.find(2)
|
||||
sub.parent = @ecookbook
|
||||
assert sub.save
|
||||
assert_equal @ecookbook.id, sub.parent.id
|
||||
@ecookbook.reload
|
||||
assert_equal 3, @ecookbook.children.size
|
||||
end
|
||||
|
||||
def test_subproject_invalid
|
||||
sub = Project.find(2)
|
||||
sub.parent = @ecookbook_sub1
|
||||
assert !sub.save
|
||||
end
|
||||
|
||||
def test_subproject_invalid_2
|
||||
sub = @ecookbook
|
||||
sub.parent = Project.find(2)
|
||||
assert !sub.save
|
||||
end
|
||||
|
||||
def test_issues_status_changes
|
||||
journals = @ecookbook.issues_status_changes 3.days.ago.to_date, Date.today
|
||||
assert_equal 1, journals.size
|
||||
assert_kind_of Journal, journals.first
|
||||
|
||||
journals = @ecookbook.issues_status_changes 30.days.ago.to_date, 10.days.ago.to_date
|
||||
assert_equal 0, journals.size
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue