diff --git a/app/controllers/rb_application_controller.rb b/app/controllers/rb_application_controller.rb
index 4316ebdc7c..891ca6186c 100644
--- a/app/controllers/rb_application_controller.rb
+++ b/app/controllers/rb_application_controller.rb
@@ -17,7 +17,8 @@ class RbApplicationController < ApplicationController
elsif ['rb_queries',
'rb_master_backlogs',
'rb_calendars',
- 'rb_server_variables'].include? params[:controller]
+ 'rb_server_variables',
+ 'rb_updated_items'].include? params[:controller]
Project.find(params[:id])
elsif params[:project_id]
diff --git a/app/controllers/rb_changes_controller.rb b/app/controllers/rb_changes_controller.rb
deleted file mode 100644
index ad4dedce64..0000000000
--- a/app/controllers/rb_changes_controller.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class RbChangesController < RbApplicationController
- unloadable
-
- def show
- # Gather all that has changed in the project (params[:id]) since params[:last_update]
-
- respond_to do |format|
- format.html
- end
- end
-end
\ No newline at end of file
diff --git a/app/controllers/rb_updated_items_controller.rb b/app/controllers/rb_updated_items_controller.rb
new file mode 100644
index 0000000000..47ad3c6b8f
--- /dev/null
+++ b/app/controllers/rb_updated_items_controller.rb
@@ -0,0 +1,27 @@
+class RbUpdatedItemsController < RbApplicationController
+ unloadable
+
+ # Returns all models that have changed since params[:since]
+ # params[:only] limits the types of models that the method
+ # should return
+ def show
+ only = (params[:only] ? params[:only].split(/, ?/).map{|v| v.to_sym} : [:sprints, :stories, :tasks, :impediments])
+ @items = HashWithIndifferentAccess.new
+
+ if only.include? :stories
+ @items[:stories] = Story.find_all_updated_since(params[:since], @project.id)
+ end
+
+ if only.include? :tasks
+ @items[:tasks] = Task.find_all_updated_since(params[:since], @project.id)
+ end
+
+ if only.include? :impediments
+ @items[:impediments] = Task.find_all_updated_since(params[:since], @project.id, true)
+ end
+
+ respond_to do |format|
+ format.html { render :layout => false }
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/models/story.rb b/app/models/story.rb
index e849f32b97..2603d5f7a6 100755
--- a/app/models/story.rb
+++ b/app/models/story.rb
@@ -33,6 +33,12 @@ class Story < Issue
return s
end
+ def self.find_all_updated_since(since, project_id)
+ find(:all,
+ :conditions => ["project_id=(?) AND updated_on > ? AND tracker_id in (?)", project_id, since, trackers],
+ :order => "updated_on ASC")
+ end
+
def self.trackers
trackers = Setting.plugin_redmine_backlogs[:story_trackers]
return [] if trackers == '' or trackers.nil?
diff --git a/app/models/task.rb b/app/models/task.rb
index 1137af10c3..ad0d655a56 100755
--- a/app/models/task.rb
+++ b/app/models/task.rb
@@ -30,6 +30,12 @@ class Task < Issue
return task
end
+ def self.find_all_updated_since(since, project_id, find_impediments = false)
+ find(:all,
+ :conditions => ["project_id=(?) AND updated_on > ? AND tracker_id in (?) and parent_id IS #{ find_impediments ? '' : 'NOT' } NULL", project_id, since, tracker],
+ :order => "updated_on ASC")
+ end
+
def update_with_relationships(params, is_impediment = false)
attribs = params.clone.delete_if {|k,v| !Task::SAFE_ATTRIBUTES.include?(k) }
attribs[:remaining_hours] = 0 if IssueStatus.find(params[:status_id]).is_closed?
diff --git a/app/views/rb_updated_items/show.html.erb b/app/views/rb_updated_items/show.html.erb
new file mode 100644
index 0000000000..6d6ce137e7
--- /dev/null
+++ b/app/views/rb_updated_items/show.html.erb
@@ -0,0 +1,9 @@
+
+<%= render :partial => "rb_stories/story", :collection => @items[:stories] %>
+
+
+<%= render :partial => "rb_tasks/task", :collection => @items[:tasks] %>
+
+
+<%= render :partial => "rb_impediments/impediment", :collection => @items[:impediments] %>
+
\ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index 0f6c146765..78ba34fbb8 100755
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -3,6 +3,7 @@ ActionController::Routing::Routes.draw do |map|
# Use rb/ as a URL 'namespace.' We're using a slightly different URL pattern
# From Redmine so namespacing avoids any further problems down the line
map.resource :rb, :only => :none do |rb|
+ rb.resources :updated_items, :only => :sghow, :controller => :rb_updated_items
rb.resources :queries, :only => :show, :controller => :rb_queries
rb.resources :wikis, :only => [:show, :edit], :controller => :rb_wikis
rb.resources :statistics, :only => :show, :controller => :rb_statistics
diff --git a/features/scrum_master.feature b/features/scrum_master.feature
index cecb4a0de7..843052c10e 100644
--- a/features/scrum_master.feature
+++ b/features/scrum_master.feature
@@ -107,3 +107,4 @@ Feature: Scrum Master
When I edit the sprint notes
Then the request should complete successfully
Then the wiki page Sprint 001 should contain Sprint Template
+
diff --git a/features/step_definitions/_then_steps.rb b/features/step_definitions/_then_steps.rb
index f4390d8532..c77fd932d3 100755
--- a/features/step_definitions/_then_steps.rb
+++ b/features/step_definitions/_then_steps.rb
@@ -31,9 +31,9 @@ Then /^show me the list of sprints$/ do
sprints = Sprint.find(:all, :conditions => "project_id=#{@project.id}")
puts "\n"
- puts "\t| #{'id'.ljust(3)} | #{'name'.ljust(18)} | #{'sprint_start_date'.ljust(18)} | #{'effective_date'.ljust(18)} |"
- sprints.each do |sprint|
- puts "\t| #{sprint.id.to_s.ljust(3)} | #{sprint.name.to_s.ljust(18)} | #{sprint.sprint_start_date.to_s.ljust(18)} | #{sprint.effective_date.to_s.ljust(18)} |"
+ puts "\t| #{'id'.ljust(3)} | #{'name'.ljust(18)} | #{'sprint_start_date'.ljust(18)} | #{'effective_date'.ljust(18)} | #{'updated_on'.ljust(20)}"
+ sprints.each do |sprint|
+ puts "\t| #{sprint.id.to_s.ljust(3)} | #{sprint.name.to_s.ljust(18)} | #{sprint.sprint_start_date.to_s.ljust(18)} | #{sprint.effective_date.to_s.ljust(18)} | #{sprint.updated_on.to_s.ljust(20)} |"
end
puts "\n\n"
end
@@ -75,6 +75,10 @@ Then /^the server should return an update error$/ do
page.driver.response.status.should == 400
end
+Then /^the server should return (\d+) updated (.+)$/ do |count, object_type|
+ page.all("##{object_type.pluralize} .#{object_type.singularize}").length.should == count.to_i
+end
+
Then /^the sprint named (.+) should have (\d+) impediment named (.+)$/ do |sprint_name, count, impediment_subject|
sprints = Sprint.find(:all, :conditions => { :name => sprint_name })
sprints.length.should == 1
diff --git a/features/step_definitions/_when_steps.rb b/features/step_definitions/_when_steps.rb
index cd17c942df..5f08f72263 100644
--- a/features/step_definitions/_when_steps.rb
+++ b/features/step_definitions/_when_steps.rb
@@ -115,3 +115,7 @@ When /^I edit the sprint notes$/ do
visit url_for(:controller => 'rb_wikis', :action => 'edit', :id => @sprint.id)
end
+When /^the browser fetches (.+) updated since (\d+) (\w+) (.+)$/ do |object_type, how_many, period, direction|
+ date = eval("#{ how_many }.#{ period }.#{ direction=='from now' ? 'from_now' : 'ago' }")
+ visit url_for(:controller => 'rb_updated_items', :action => :show, :id => @project.id, :only => object_type, :since => date.strftime("%B %d, %Y %H:%M:%S") + '.' + (date.to_f % 1).to_s.split('.')[1])
+end
diff --git a/features/team_member.feature b/features/team_member.feature
index 3f14a79953..652544a26e 100755
--- a/features/team_member.feature
+++ b/features/team_member.feature
@@ -21,7 +21,11 @@ Feature: Team Member
And the project has the following tasks:
| subject | parent |
| Task 1 | Story 1 |
-
+ And the project has the following impediments:
+ | subject | sprint | blocks |
+ | Impediment 1 | Sprint 001 | Story 1 |
+ | Impediment 2 | Sprint 001 | Story 2 |
+
Scenario: Create a task for a story
Given I am viewing the taskboard for Sprint 001
And I want to create a task for Story 1
@@ -55,4 +59,28 @@ Feature: Team Member
Given I am viewing the master backlog
When I view the stories in the issues tab
Then I should see the Issues page
-
\ No newline at end of file
+
+ Scenario: Fetch the updated stories
+ Given I am viewing the master backlog
+ When the browser fetches stories updated since 1 week ago
+ Then the request should complete successfully
+ And the server should return 4 updated stories
+
+ Scenario: Fetch the updated tasks
+ Given I am viewing the taskboard for Sprint 001
+ When the browser fetches tasks updated since 1 week ago
+ Then the request should complete successfully
+ And the server should return 1 updated task
+
+ Scenario: Fetch the updated impediments
+ Given I am viewing the taskboard for Sprint 001
+ When the browser fetches impediments updated since 1 week ago
+ Then the request should complete successfully
+ And the server should return 2 updated impediments
+
+ Scenario: Fetch zero updated impediments
+ Given I am viewing the taskboard for Sprint 001
+ When the browser fetches impediments updated since 1 week from now
+ Then the request should complete successfully
+ And the server should return 0 updated impediments
+
\ No newline at end of file
diff --git a/init.rb b/init.rb
index 695de7a6b4..075f012a9d 100755
--- a/init.rb
+++ b/init.rb
@@ -41,7 +41,8 @@ Redmine::Plugin.register :redmine_backlogs do
:rb_calendars => :show,
:rb_queries => :show,
:rb_server_variables => :show,
- :rb_burndown_charts => :show
+ :rb_burndown_charts => :show,
+ :rb_updated_items => :show
}
# Sprint permissions
@@ -50,7 +51,8 @@ Redmine::Plugin.register :redmine_backlogs do
:rb_tasks => [:index, :show],
:rb_impediments => [:index, :show],
:rb_server_variables => :show,
- :rb_burndown_charts => :show
+ :rb_burndown_charts => :show,
+ :rb_updated_items => :show
}
permission :update_sprints, {
:rb_sprints => [:edit, :update],