@@ -19,6 +19,7 class WatchersController < ApplicationController | |||||
19 | before_filter :find_project |
|
19 | before_filter :find_project | |
20 | before_filter :require_login, :check_project_privacy, :only => [:watch, :unwatch] |
|
20 | before_filter :require_login, :check_project_privacy, :only => [:watch, :unwatch] | |
21 | before_filter :authorize, :only => [:new, :destroy] |
|
21 | before_filter :authorize, :only => [:new, :destroy] | |
|
22 | accept_api_auth :create, :destroy | |||
22 |
|
23 | |||
23 | def watch |
|
24 | def watch | |
24 | if @watched.respond_to?(:visible?) && !@watched.visible?(User.current) |
|
25 | if @watched.respond_to?(:visible?) && !@watched.visible?(User.current) | |
@@ -36,15 +37,19 class WatchersController < ApplicationController | |||||
36 | end |
|
37 | end | |
37 |
|
38 | |||
38 | def create |
|
39 | def create | |
39 | if params[:watcher].is_a?(Hash) && request.post? |
|
40 | user_ids = [] | |
40 | user_ids = params[:watcher][:user_ids] || [params[:watcher][:user_id]] |
|
41 | if params[:watcher].is_a?(Hash) | |
41 | user_ids.each do |user_id| |
|
42 | user_ids << (params[:watcher][:user_ids] || params[:watcher][:user_id]) | |
42 | Watcher.create(:watchable => @watched, :user_id => user_id) |
|
43 | else | |
|
44 | user_ids << params[:user_id] | |||
43 |
|
|
45 | end | |
|
46 | user_ids.flatten.compact.uniq.each do |user_id| | |||
|
47 | Watcher.create(:watchable => @watched, :user_id => user_id) | |||
44 | end |
|
48 | end | |
45 | respond_to do |format| |
|
49 | respond_to do |format| | |
46 | format.html { redirect_to_referer_or {render :text => 'Watcher added.', :layout => true}} |
|
50 | format.html { redirect_to_referer_or {render :text => 'Watcher added.', :layout => true}} | |
47 | format.js |
|
51 | format.js | |
|
52 | format.api { render_api_ok } | |||
48 | end |
|
53 | end | |
49 | end |
|
54 | end | |
50 |
|
55 | |||
@@ -56,10 +61,11 class WatchersController < ApplicationController | |||||
56 | end |
|
61 | end | |
57 |
|
62 | |||
58 | def destroy |
|
63 | def destroy | |
59 |
@watched.set_watcher(User.find(params[:user_id]), false) |
|
64 | @watched.set_watcher(User.find(params[:user_id]), false) | |
60 | respond_to do |format| |
|
65 | respond_to do |format| | |
61 | format.html { redirect_to :back } |
|
66 | format.html { redirect_to :back } | |
62 | format.js |
|
67 | format.js | |
|
68 | format.api { render_api_ok } | |||
63 | end |
|
69 | end | |
64 | end |
|
70 | end | |
65 |
|
71 |
@@ -64,4 +64,10 api.issue do | |||||
64 | end |
|
64 | end | |
65 | end |
|
65 | end | |
66 | end if include_in_api_response?('journals') |
|
66 | end if include_in_api_response?('journals') | |
|
67 | ||||
|
68 | api.array :watchers do | |||
|
69 | @issue.watcher_users.each do |user| | |||
|
70 | api.user :id => user.id, :name => user.name | |||
|
71 | end | |||
|
72 | end if include_in_api_response?('watchers') && User.current.allowed_to?(:view_issue_watchers, @issue.project) | |||
67 | end |
|
73 | end |
@@ -84,6 +84,9 RedmineApp::Application.routes.draw do | |||||
84 | match 'watchers/watch', :controller=> 'watchers', :action => 'watch', :via => :post |
|
84 | match 'watchers/watch', :controller=> 'watchers', :action => 'watch', :via => :post | |
85 | match 'watchers/unwatch', :controller=> 'watchers', :action => 'unwatch', :via => :post |
|
85 | match 'watchers/unwatch', :controller=> 'watchers', :action => 'unwatch', :via => :post | |
86 | match 'watchers/autocomplete_for_user', :controller=> 'watchers', :action => 'autocomplete_for_user', :via => :get |
|
86 | match 'watchers/autocomplete_for_user', :controller=> 'watchers', :action => 'autocomplete_for_user', :via => :get | |
|
87 | # Specific routes for issue watchers API | |||
|
88 | post 'issues/:object_id/watchers', :to => 'watchers#create', :object_type => 'issue' | |||
|
89 | delete 'issues/:object_id/watchers/:user_id' => 'watchers#destroy', :object_type => 'issue' | |||
87 |
|
90 | |||
88 | resources :projects do |
|
91 | resources :projects do | |
89 | member do |
|
92 | member do |
@@ -453,6 +453,21 class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base | |||||
453 | end |
|
453 | end | |
454 | end |
|
454 | end | |
455 |
|
455 | |||
|
456 | test "GET /issues/:id.xml?include=watchers should include watchers" do | |||
|
457 | Watcher.create!(:user_id => 3, :watchable => Issue.find(1)) | |||
|
458 | ||||
|
459 | get '/issues/1.xml?include=watchers', {}, credentials('jsmith') | |||
|
460 | ||||
|
461 | assert_response :ok | |||
|
462 | assert_equal 'application/xml', response.content_type | |||
|
463 | assert_select 'issue' do | |||
|
464 | assert_select 'watchers', Issue.find(1).watchers.count | |||
|
465 | assert_select 'watchers' do | |||
|
466 | assert_select 'user[id=3]' | |||
|
467 | end | |||
|
468 | end | |||
|
469 | end | |||
|
470 | ||||
456 | context "POST /issues.xml" do |
|
471 | context "POST /issues.xml" do | |
457 | should_allow_api_authentication( |
|
472 | should_allow_api_authentication( | |
458 | :post, |
|
473 | :post, | |
@@ -478,6 +493,18 class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base | |||||
478 | end |
|
493 | end | |
479 | end |
|
494 | end | |
480 |
|
495 | |||
|
496 | test "POST /issues.xml with watcher_user_ids should create issue with watchers" do | |||
|
497 | assert_difference('Issue.count') do | |||
|
498 | post '/issues.xml', | |||
|
499 | {:issue => {:project_id => 1, :subject => 'Watchers', | |||
|
500 | :tracker_id => 2, :status_id => 3, :watcher_user_ids => [3, 1]}}, credentials('jsmith') | |||
|
501 | assert_response :created | |||
|
502 | end | |||
|
503 | issue = Issue.order('id desc').first | |||
|
504 | assert_equal 2, issue.watchers.size | |||
|
505 | assert_equal [1, 3], issue.watcher_user_ids.sort | |||
|
506 | end | |||
|
507 | ||||
481 | context "POST /issues.xml with failure" do |
|
508 | context "POST /issues.xml with failure" do | |
482 | should "have an errors tag" do |
|
509 | should "have an errors tag" do | |
483 | assert_no_difference('Issue.count') do |
|
510 | assert_no_difference('Issue.count') do | |
@@ -720,6 +747,30 class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base | |||||
720 | end |
|
747 | end | |
721 | end |
|
748 | end | |
722 |
|
749 | |||
|
750 | test "POST /issues/:id/watchers.xml should add watcher" do | |||
|
751 | assert_difference 'Watcher.count' do | |||
|
752 | post '/issues/1/watchers.xml', {:user_id => 3}, credentials('jsmith') | |||
|
753 | ||||
|
754 | assert_response :ok | |||
|
755 | assert_equal '', response.body | |||
|
756 | end | |||
|
757 | watcher = Watcher.order('id desc').first | |||
|
758 | assert_equal Issue.find(1), watcher.watchable | |||
|
759 | assert_equal User.find(3), watcher.user | |||
|
760 | end | |||
|
761 | ||||
|
762 | test "DELETE /issues/:id/watchers/:user_id.xml should remove watcher" do | |||
|
763 | Watcher.create!(:user_id => 3, :watchable => Issue.find(1)) | |||
|
764 | ||||
|
765 | assert_difference 'Watcher.count', -1 do | |||
|
766 | delete '/issues/1/watchers/3.xml', {}, credentials('jsmith') | |||
|
767 | ||||
|
768 | assert_response :ok | |||
|
769 | assert_equal '', response.body | |||
|
770 | end | |||
|
771 | assert_equal false, Issue.find(1).watched_by?(User.find(3)) | |||
|
772 | end | |||
|
773 | ||||
723 | def test_create_issue_with_uploaded_file |
|
774 | def test_create_issue_with_uploaded_file | |
724 | set_tmp_attachments_directory |
|
775 | set_tmp_attachments_directory | |
725 | # upload the file |
|
776 | # upload the file |
@@ -47,5 +47,15 class RoutingWatchersTest < ActionController::IntegrationTest | |||||
47 | { :method => 'post', :path => "/watchers/unwatch" }, |
|
47 | { :method => 'post', :path => "/watchers/unwatch" }, | |
48 | { :controller => 'watchers', :action => 'unwatch' } |
|
48 | { :controller => 'watchers', :action => 'unwatch' } | |
49 | ) |
|
49 | ) | |
|
50 | assert_routing( | |||
|
51 | { :method => 'post', :path => "/issues/12/watchers.xml" }, | |||
|
52 | { :controller => 'watchers', :action => 'create', | |||
|
53 | :object_type => 'issue', :object_id => '12', :format => 'xml' } | |||
|
54 | ) | |||
|
55 | assert_routing( | |||
|
56 | { :method => 'delete', :path => "/issues/12/watchers/3.xml" }, | |||
|
57 | { :controller => 'watchers', :action => 'destroy', | |||
|
58 | :object_type => 'issue', :object_id => '12', :user_id => '3', :format => 'xml'} | |||
|
59 | ) | |||
50 | end |
|
60 | end | |
51 | end |
|
61 | end |
General Comments 0
You need to be logged in to leave comments.
Login now