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],