@@ -0,0 +1,59 | |||
|
1 | class ActivitiesController < ApplicationController | |
|
2 | menu_item :activity | |
|
3 | before_filter :find_optional_project | |
|
4 | accept_key_auth :index | |
|
5 | ||
|
6 | def index | |
|
7 | @days = Setting.activity_days_default.to_i | |
|
8 | ||
|
9 | if params[:from] | |
|
10 | begin; @date_to = params[:from].to_date + 1; rescue; end | |
|
11 | end | |
|
12 | ||
|
13 | @date_to ||= Date.today + 1 | |
|
14 | @date_from = @date_to - @days | |
|
15 | @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1') | |
|
16 | @author = (params[:user_id].blank? ? nil : User.active.find(params[:user_id])) | |
|
17 | ||
|
18 | @activity = Redmine::Activity::Fetcher.new(User.current, :project => @project, | |
|
19 | :with_subprojects => @with_subprojects, | |
|
20 | :author => @author) | |
|
21 | @activity.scope_select {|t| !params["show_#{t}"].nil?} | |
|
22 | @activity.scope = (@author.nil? ? :default : :all) if @activity.scope.empty? | |
|
23 | ||
|
24 | events = @activity.events(@date_from, @date_to) | |
|
25 | ||
|
26 | if events.empty? || stale?(:etag => [events.first, User.current]) | |
|
27 | respond_to do |format| | |
|
28 | format.html { | |
|
29 | @events_by_day = events.group_by(&:event_date) | |
|
30 | render :layout => false if request.xhr? | |
|
31 | } | |
|
32 | format.atom { | |
|
33 | title = l(:label_activity) | |
|
34 | if @author | |
|
35 | title = @author.name | |
|
36 | elsif @activity.scope.size == 1 | |
|
37 | title = l("label_#{@activity.scope.first.singularize}_plural") | |
|
38 | end | |
|
39 | render_feed(events, :title => "#{@project || Setting.app_title}: #{title}") | |
|
40 | } | |
|
41 | end | |
|
42 | end | |
|
43 | ||
|
44 | rescue ActiveRecord::RecordNotFound | |
|
45 | render_404 | |
|
46 | end | |
|
47 | ||
|
48 | private | |
|
49 | ||
|
50 | # TODO: refactor, duplicated in projects_controller | |
|
51 | def find_optional_project | |
|
52 | return true unless params[:id] | |
|
53 | @project = Project.find(params[:id]) | |
|
54 | authorize | |
|
55 | rescue ActiveRecord::RecordNotFound | |
|
56 | render_404 | |
|
57 | end | |
|
58 | ||
|
59 | end |
@@ -0,0 +1,87 | |||
|
1 | require File.dirname(__FILE__) + '/../test_helper' | |
|
2 | ||
|
3 | class ActivitiesControllerTest < ActionController::TestCase | |
|
4 | fixtures :all | |
|
5 | ||
|
6 | def test_project_index | |
|
7 | get :index, :id => 1, :with_subprojects => 0 | |
|
8 | assert_response :success | |
|
9 | assert_template 'index' | |
|
10 | assert_not_nil assigns(:events_by_day) | |
|
11 | ||
|
12 | assert_tag :tag => "h3", | |
|
13 | :content => /#{2.days.ago.to_date.day}/, | |
|
14 | :sibling => { :tag => "dl", | |
|
15 | :child => { :tag => "dt", | |
|
16 | :attributes => { :class => /issue-edit/ }, | |
|
17 | :child => { :tag => "a", | |
|
18 | :content => /(#{IssueStatus.find(2).name})/, | |
|
19 | } | |
|
20 | } | |
|
21 | } | |
|
22 | end | |
|
23 | ||
|
24 | def test_previous_project_index | |
|
25 | get :index, :id => 1, :from => 3.days.ago.to_date | |
|
26 | assert_response :success | |
|
27 | assert_template 'index' | |
|
28 | assert_not_nil assigns(:events_by_day) | |
|
29 | ||
|
30 | assert_tag :tag => "h3", | |
|
31 | :content => /#{3.day.ago.to_date.day}/, | |
|
32 | :sibling => { :tag => "dl", | |
|
33 | :child => { :tag => "dt", | |
|
34 | :attributes => { :class => /issue/ }, | |
|
35 | :child => { :tag => "a", | |
|
36 | :content => /#{Issue.find(1).subject}/, | |
|
37 | } | |
|
38 | } | |
|
39 | } | |
|
40 | end | |
|
41 | ||
|
42 | def test_global_index | |
|
43 | get :index | |
|
44 | assert_response :success | |
|
45 | assert_template 'index' | |
|
46 | assert_not_nil assigns(:events_by_day) | |
|
47 | ||
|
48 | assert_tag :tag => "h3", | |
|
49 | :content => /#{5.day.ago.to_date.day}/, | |
|
50 | :sibling => { :tag => "dl", | |
|
51 | :child => { :tag => "dt", | |
|
52 | :attributes => { :class => /issue/ }, | |
|
53 | :child => { :tag => "a", | |
|
54 | :content => /#{Issue.find(5).subject}/, | |
|
55 | } | |
|
56 | } | |
|
57 | } | |
|
58 | end | |
|
59 | ||
|
60 | def test_user_index | |
|
61 | get :index, :user_id => 2 | |
|
62 | assert_response :success | |
|
63 | assert_template 'index' | |
|
64 | assert_not_nil assigns(:events_by_day) | |
|
65 | ||
|
66 | assert_tag :tag => "h3", | |
|
67 | :content => /#{3.day.ago.to_date.day}/, | |
|
68 | :sibling => { :tag => "dl", | |
|
69 | :child => { :tag => "dt", | |
|
70 | :attributes => { :class => /issue/ }, | |
|
71 | :child => { :tag => "a", | |
|
72 | :content => /#{Issue.find(1).subject}/, | |
|
73 | } | |
|
74 | } | |
|
75 | } | |
|
76 | end | |
|
77 | ||
|
78 | def test_index_atom_feed | |
|
79 | get :index, :format => 'atom' | |
|
80 | assert_response :success | |
|
81 | assert_template 'common/feed.atom.rxml' | |
|
82 | assert_tag :tag => 'entry', :child => { | |
|
83 | :tag => 'link', | |
|
84 | :attributes => {:href => 'http://test.host/issues/11'}} | |
|
85 | end | |
|
86 | ||
|
87 | end |
@@ -17,17 +17,15 | |||
|
17 | 17 | |
|
18 | 18 | class ProjectsController < ApplicationController |
|
19 | 19 | menu_item :overview |
|
20 | menu_item :activity, :only => :activity | |
|
21 | 20 | menu_item :roadmap, :only => :roadmap |
|
22 | 21 | menu_item :files, :only => [:list_files, :add_file] |
|
23 | 22 | menu_item :settings, :only => :settings |
|
24 | 23 | |
|
25 |
before_filter :find_project, :except => [ :index, :list, :add, :copy |
|
|
26 | before_filter :find_optional_project, :only => :activity | |
|
27 | before_filter :authorize, :except => [ :index, :list, :add, :copy, :archive, :unarchive, :destroy, :activity ] | |
|
24 | before_filter :find_project, :except => [ :index, :list, :add, :copy ] | |
|
25 | before_filter :authorize, :except => [ :index, :list, :add, :copy, :archive, :unarchive, :destroy] | |
|
28 | 26 | before_filter :authorize_global, :only => :add |
|
29 | 27 | before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ] |
|
30 |
accept_key_auth |
|
|
28 | accept_key_auth :index | |
|
31 | 29 | |
|
32 | 30 | after_filter :only => [:add, :edit, :archive, :unarchive, :destroy] do |controller| |
|
33 | 31 | if controller.request.post? |
@@ -313,48 +311,6 class ProjectsController < ApplicationController | |||
|
313 | 311 | @versions.reject! {|version| !project_ids.include?(version.project_id) && @issues_by_version[version].blank?} |
|
314 | 312 | end |
|
315 | 313 | |
|
316 | def activity | |
|
317 | @days = Setting.activity_days_default.to_i | |
|
318 | ||
|
319 | if params[:from] | |
|
320 | begin; @date_to = params[:from].to_date + 1; rescue; end | |
|
321 | end | |
|
322 | ||
|
323 | @date_to ||= Date.today + 1 | |
|
324 | @date_from = @date_to - @days | |
|
325 | @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1') | |
|
326 | @author = (params[:user_id].blank? ? nil : User.active.find(params[:user_id])) | |
|
327 | ||
|
328 | @activity = Redmine::Activity::Fetcher.new(User.current, :project => @project, | |
|
329 | :with_subprojects => @with_subprojects, | |
|
330 | :author => @author) | |
|
331 | @activity.scope_select {|t| !params["show_#{t}"].nil?} | |
|
332 | @activity.scope = (@author.nil? ? :default : :all) if @activity.scope.empty? | |
|
333 | ||
|
334 | events = @activity.events(@date_from, @date_to) | |
|
335 | ||
|
336 | if events.empty? || stale?(:etag => [events.first, User.current]) | |
|
337 | respond_to do |format| | |
|
338 | format.html { | |
|
339 | @events_by_day = events.group_by(&:event_date) | |
|
340 | render :layout => false if request.xhr? | |
|
341 | } | |
|
342 | format.atom { | |
|
343 | title = l(:label_activity) | |
|
344 | if @author | |
|
345 | title = @author.name | |
|
346 | elsif @activity.scope.size == 1 | |
|
347 | title = l("label_#{@activity.scope.first.singularize}_plural") | |
|
348 | end | |
|
349 | render_feed(events, :title => "#{@project || Setting.app_title}: #{title}") | |
|
350 | } | |
|
351 | end | |
|
352 | end | |
|
353 | ||
|
354 | rescue ActiveRecord::RecordNotFound | |
|
355 | render_404 | |
|
356 | end | |
|
357 | ||
|
358 | 314 | private |
|
359 | 315 | def find_optional_project |
|
360 | 316 | return true unless params[:id] |
|
1 | NO CONTENT: file renamed from app/views/projects/activity.rhtml to app/views/activities/index.html.erb |
@@ -30,11 +30,11 | |||
|
30 | 30 | </table> |
|
31 | 31 | |
|
32 | 32 | <% other_formats_links do |f| %> |
|
33 |
<%= f.link_to 'Atom', :url => {:controller => ' |
|
|
33 | <%= f.link_to 'Atom', :url => {:controller => 'activities', :action => 'index', :id => @project, :show_messages => 1, :key => User.current.rss_key} %> | |
|
34 | 34 | <% end %> |
|
35 | 35 | |
|
36 | 36 | <% content_for :header_tags do %> |
|
37 |
<%= auto_discovery_link_tag(:atom, {:controller => ' |
|
|
37 | <%= auto_discovery_link_tag(:atom, {:controller => 'activities', :action => 'index', :id => @project, :format => 'atom', :show_messages => 1, :key => User.current.rss_key}) %> | |
|
38 | 38 | <% end %> |
|
39 | 39 | |
|
40 | 40 | <% html_title l(:label_board_plural) %> |
@@ -6,7 +6,7 | |||
|
6 | 6 | <%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'add'}, :class => 'icon icon-add') + ' |' if User.current.allowed_to?(:add_project, nil, :global => true) %> |
|
7 | 7 | <%= link_to(l(:label_issue_view_all), { :controller => 'issues' }) + ' |' if User.current.allowed_to?(:view_issues, nil, :global => true) %> |
|
8 | 8 | <%= link_to(l(:label_overall_spent_time), { :controller => 'time_entries' }) + ' |' if User.current.allowed_to?(:view_time_entries, nil, :global => true) %> |
|
9 |
<%= link_to l(:label_overall_activity), { :controller => ' |
|
|
9 | <%= link_to l(:label_overall_activity), { :controller => 'activities', :action => 'index' }%> | |
|
10 | 10 | </div> |
|
11 | 11 | |
|
12 | 12 | <h2><%=l(:label_project_plural)%></h2> |
@@ -74,7 +74,7 | |||
|
74 | 74 | <% end %> |
|
75 | 75 | |
|
76 | 76 | <% content_for :header_tags do %> |
|
77 |
<%= auto_discovery_link_tag(:atom, {:action => ' |
|
|
77 | <%= auto_discovery_link_tag(:atom, {:controller => 'activities', :action => 'index', :id => @project, :format => 'atom', :key => User.current.rss_key}) %> | |
|
78 | 78 | <% end %> |
|
79 | 79 | |
|
80 | 80 | <% html_title(l(:label_overview)) -%> |
@@ -35,7 +35,7 | |||
|
35 | 35 | <div class="splitcontentright"> |
|
36 | 36 | |
|
37 | 37 | <% unless @events_by_day.empty? %> |
|
38 |
<h3><%= link_to l(:label_activity), :controller => ' |
|
|
38 | <h3><%= link_to l(:label_activity), :controller => 'activities', :action => 'index', :id => nil, :user_id => @user, :from => @events_by_day.keys.first %></h3> | |
|
39 | 39 | |
|
40 | 40 | <p> |
|
41 | 41 | <%=l(:label_reported_issues)%>: <%= Issue.count(:conditions => ["author_id=?", @user.id]) %> |
@@ -57,11 +57,11 | |||
|
57 | 57 | </div> |
|
58 | 58 | |
|
59 | 59 | <% other_formats_links do |f| %> |
|
60 |
<%= f.link_to 'Atom', :url => {:controller => ' |
|
|
60 | <%= f.link_to 'Atom', :url => {:controller => 'activities', :action => 'index', :id => nil, :user_id => @user, :key => User.current.rss_key} %> | |
|
61 | 61 | <% end %> |
|
62 | 62 | |
|
63 | 63 | <% content_for :header_tags do %> |
|
64 |
<%= auto_discovery_link_tag(:atom, :controller => ' |
|
|
64 | <%= auto_discovery_link_tag(:atom, :controller => 'activities', :action => 'index', :user_id => @user, :format => :atom, :key => User.current.rss_key) %> | |
|
65 | 65 | <% end %> |
|
66 | 66 | <% end %> |
|
67 | 67 | <%= call_hook :view_account_right_bottom, :user => @user %> |
@@ -34,6 +34,6 | |||
|
34 | 34 | <% content_for :header_tags do %> |
|
35 | 35 | <%= auto_discovery_link_tag(:atom, {:controller => 'news', :action => 'index', :key => User.current.rss_key, :format => 'atom'}, |
|
36 | 36 | :title => "#{Setting.app_title}: #{l(:label_news_latest)}") %> |
|
37 |
<%= auto_discovery_link_tag(:atom, {:controller => ' |
|
|
37 | <%= auto_discovery_link_tag(:atom, {:controller => 'activities', :action => 'index', :key => User.current.rss_key, :format => 'atom'}, | |
|
38 | 38 | :title => "#{Setting.app_title}: #{l(:label_activity)}") %> |
|
39 | 39 | <% end %> |
@@ -23,11 +23,11 | |||
|
23 | 23 | |
|
24 | 24 | <% unless @pages.empty? %> |
|
25 | 25 | <% other_formats_links do |f| %> |
|
26 |
<%= f.link_to 'Atom', :url => {:controller => ' |
|
|
26 | <%= f.link_to 'Atom', :url => {:controller => 'activities', :action => 'index', :id => @project, :show_wiki_edits => 1, :key => User.current.rss_key} %> | |
|
27 | 27 | <%= f.link_to('HTML', :url => {:action => 'special', :page => 'export'}) if User.current.allowed_to?(:export_wiki_pages, @project) %> |
|
28 | 28 | <% end %> |
|
29 | 29 | <% end %> |
|
30 | 30 | |
|
31 | 31 | <% content_for :header_tags do %> |
|
32 |
<%= auto_discovery_link_tag(:atom, :controller => ' |
|
|
32 | <%= auto_discovery_link_tag(:atom, :controller => 'activities', :action => 'index', :id => @project, :show_wiki_edits => 1, :format => 'atom', :key => User.current.rss_key) %> | |
|
33 | 33 | <% end %> |
@@ -187,7 +187,7 ActionController::Routing::Routes.draw do |map| | |||
|
187 | 187 | project_views.connect 'projects/:project_id/issues/:copy_from/copy', :controller => 'issues', :action => 'new' |
|
188 | 188 | end |
|
189 | 189 | |
|
190 |
projects.with_options :action => ' |
|
|
190 | projects.with_options :controller => 'activities', :action => 'index', :conditions => {:method => :get} do |activity| | |
|
191 | 191 | activity.connect 'projects/:id/activity' |
|
192 | 192 | activity.connect 'projects/:id/activity.:format' |
|
193 | 193 | activity.connect 'activity', :id => nil |
@@ -44,7 +44,7 end | |||
|
44 | 44 | |
|
45 | 45 | # Permissions |
|
46 | 46 | Redmine::AccessControl.map do |map| |
|
47 |
map.permission :view_project, {:projects => [:show, :activit |
|
|
47 | map.permission :view_project, {:projects => [:show], :activities => [:index]}, :public => true | |
|
48 | 48 | map.permission :search_project, {:search => :index}, :public => true |
|
49 | 49 | map.permission :add_project, {:projects => :add}, :require => :loggedin |
|
50 | 50 | map.permission :edit_project, {:projects => [:settings, :edit]}, :require => :member |
@@ -185,7 +185,7 end | |||
|
185 | 185 | |
|
186 | 186 | Redmine::MenuManager.map :project_menu do |menu| |
|
187 | 187 | menu.push :overview, { :controller => 'projects', :action => 'show' } |
|
188 |
menu.push :activity, { :controller => ' |
|
|
188 | menu.push :activity, { :controller => 'activities', :action => 'index' } | |
|
189 | 189 | menu.push :roadmap, { :controller => 'projects', :action => 'roadmap' }, |
|
190 | 190 | :if => Proc.new { |p| p.shared_versions.any? } |
|
191 | 191 | menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural |
@@ -400,87 +400,6 class ProjectsControllerTest < ActionController::TestCase | |||
|
400 | 400 | assert assigns(:versions).include?(Version.find(4)), "Shared version not found" |
|
401 | 401 | assert assigns(:versions).include?(@subproject_version), "Subproject version not found" |
|
402 | 402 | end |
|
403 | def test_project_activity | |
|
404 | get :activity, :id => 1, :with_subprojects => 0 | |
|
405 | assert_response :success | |
|
406 | assert_template 'activity' | |
|
407 | assert_not_nil assigns(:events_by_day) | |
|
408 | ||
|
409 | assert_tag :tag => "h3", | |
|
410 | :content => /#{2.days.ago.to_date.day}/, | |
|
411 | :sibling => { :tag => "dl", | |
|
412 | :child => { :tag => "dt", | |
|
413 | :attributes => { :class => /issue-edit/ }, | |
|
414 | :child => { :tag => "a", | |
|
415 | :content => /(#{IssueStatus.find(2).name})/, | |
|
416 | } | |
|
417 | } | |
|
418 | } | |
|
419 | end | |
|
420 | ||
|
421 | def test_previous_project_activity | |
|
422 | get :activity, :id => 1, :from => 3.days.ago.to_date | |
|
423 | assert_response :success | |
|
424 | assert_template 'activity' | |
|
425 | assert_not_nil assigns(:events_by_day) | |
|
426 | ||
|
427 | assert_tag :tag => "h3", | |
|
428 | :content => /#{3.day.ago.to_date.day}/, | |
|
429 | :sibling => { :tag => "dl", | |
|
430 | :child => { :tag => "dt", | |
|
431 | :attributes => { :class => /issue/ }, | |
|
432 | :child => { :tag => "a", | |
|
433 | :content => /#{Issue.find(1).subject}/, | |
|
434 | } | |
|
435 | } | |
|
436 | } | |
|
437 | end | |
|
438 | ||
|
439 | def test_global_activity | |
|
440 | get :activity | |
|
441 | assert_response :success | |
|
442 | assert_template 'activity' | |
|
443 | assert_not_nil assigns(:events_by_day) | |
|
444 | ||
|
445 | assert_tag :tag => "h3", | |
|
446 | :content => /#{5.day.ago.to_date.day}/, | |
|
447 | :sibling => { :tag => "dl", | |
|
448 | :child => { :tag => "dt", | |
|
449 | :attributes => { :class => /issue/ }, | |
|
450 | :child => { :tag => "a", | |
|
451 | :content => /#{Issue.find(5).subject}/, | |
|
452 | } | |
|
453 | } | |
|
454 | } | |
|
455 | end | |
|
456 | ||
|
457 | def test_user_activity | |
|
458 | get :activity, :user_id => 2 | |
|
459 | assert_response :success | |
|
460 | assert_template 'activity' | |
|
461 | assert_not_nil assigns(:events_by_day) | |
|
462 | ||
|
463 | assert_tag :tag => "h3", | |
|
464 | :content => /#{3.day.ago.to_date.day}/, | |
|
465 | :sibling => { :tag => "dl", | |
|
466 | :child => { :tag => "dt", | |
|
467 | :attributes => { :class => /issue/ }, | |
|
468 | :child => { :tag => "a", | |
|
469 | :content => /#{Issue.find(1).subject}/, | |
|
470 | } | |
|
471 | } | |
|
472 | } | |
|
473 | end | |
|
474 | ||
|
475 | def test_activity_atom_feed | |
|
476 | get :activity, :format => 'atom' | |
|
477 | assert_response :success | |
|
478 | assert_template 'common/feed.atom.rxml' | |
|
479 | assert_tag :tag => 'entry', :child => { | |
|
480 | :tag => 'link', | |
|
481 | :attributes => {:href => 'http://test.host/issues/11'}} | |
|
482 | end | |
|
483 | ||
|
484 | 403 | def test_archive |
|
485 | 404 | @request.session[:user_id] = 1 # admin |
|
486 | 405 | post :archive, :id => 1 |
@@ -19,8 +19,8 require "#{File.dirname(__FILE__)}/../test_helper" | |||
|
19 | 19 | |
|
20 | 20 | class RoutingTest < ActionController::IntegrationTest |
|
21 | 21 | context "activities" do |
|
22 |
should_route :get, "/activity", :controller => ' |
|
|
23 |
should_route :get, "/activity.atom", :controller => ' |
|
|
22 | should_route :get, "/activity", :controller => 'activities', :action => 'index', :id => nil | |
|
23 | should_route :get, "/activity.atom", :controller => 'activities', :action => 'index', :id => nil, :format => 'atom' | |
|
24 | 24 | end |
|
25 | 25 | |
|
26 | 26 | context "attachments" do |
@@ -175,8 +175,8 class RoutingTest < ActionController::IntegrationTest | |||
|
175 | 175 | should_route :get, "/projects/33/files", :controller => 'projects', :action => 'list_files', :id => '33' |
|
176 | 176 | should_route :get, "/projects/33/files/new", :controller => 'projects', :action => 'add_file', :id => '33' |
|
177 | 177 | should_route :get, "/projects/33/roadmap", :controller => 'projects', :action => 'roadmap', :id => '33' |
|
178 |
should_route :get, "/projects/33/activity", :controller => ' |
|
|
179 |
should_route :get, "/projects/33/activity.atom", :controller => ' |
|
|
178 | should_route :get, "/projects/33/activity", :controller => 'activities', :action => 'index', :id => '33' | |
|
179 | should_route :get, "/projects/33/activity.atom", :controller => 'activities', :action => 'index', :id => '33', :format => 'atom' | |
|
180 | 180 | |
|
181 | 181 | should_route :post, "/projects/new", :controller => 'projects', :action => 'add' |
|
182 | 182 | should_route :post, "/projects.xml", :controller => 'projects', :action => 'add', :format => 'xml' |
General Comments 0
You need to be logged in to leave comments.
Login now