Add/remove issue watchers via the REST API (#6727).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@11290 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
f2fd78f7b8
commit
a0158eff96
|
@ -19,6 +19,7 @@ class WatchersController < ApplicationController
|
||||||
before_filter :find_project
|
before_filter :find_project
|
||||||
before_filter :require_login, :check_project_privacy, :only => [:watch, :unwatch]
|
before_filter :require_login, :check_project_privacy, :only => [:watch, :unwatch]
|
||||||
before_filter :authorize, :only => [:new, :destroy]
|
before_filter :authorize, :only => [:new, :destroy]
|
||||||
|
accept_api_auth :create, :destroy
|
||||||
|
|
||||||
def watch
|
def watch
|
||||||
if @watched.respond_to?(:visible?) && !@watched.visible?(User.current)
|
if @watched.respond_to?(:visible?) && !@watched.visible?(User.current)
|
||||||
|
@ -36,15 +37,19 @@ class WatchersController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
if params[:watcher].is_a?(Hash) && request.post?
|
user_ids = []
|
||||||
user_ids = params[:watcher][:user_ids] || [params[:watcher][:user_id]]
|
if params[:watcher].is_a?(Hash)
|
||||||
user_ids.each do |user_id|
|
user_ids << (params[:watcher][:user_ids] || params[:watcher][:user_id])
|
||||||
Watcher.create(:watchable => @watched, :user_id => user_id)
|
else
|
||||||
end
|
user_ids << params[:user_id]
|
||||||
|
end
|
||||||
|
user_ids.flatten.compact.uniq.each do |user_id|
|
||||||
|
Watcher.create(:watchable => @watched, :user_id => user_id)
|
||||||
end
|
end
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { redirect_to_referer_or {render :text => 'Watcher added.', :layout => true}}
|
format.html { redirect_to_referer_or {render :text => 'Watcher added.', :layout => true}}
|
||||||
format.js
|
format.js
|
||||||
|
format.api { render_api_ok }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -56,10 +61,11 @@ class WatchersController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@watched.set_watcher(User.find(params[:user_id]), false) if request.post?
|
@watched.set_watcher(User.find(params[:user_id]), false)
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { redirect_to :back }
|
format.html { redirect_to :back }
|
||||||
format.js
|
format.js
|
||||||
|
format.api { render_api_ok }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -64,4 +64,10 @@ api.issue do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end if include_in_api_response?('journals')
|
end if include_in_api_response?('journals')
|
||||||
|
|
||||||
|
api.array :watchers do
|
||||||
|
@issue.watcher_users.each do |user|
|
||||||
|
api.user :id => user.id, :name => user.name
|
||||||
|
end
|
||||||
|
end if include_in_api_response?('watchers') && User.current.allowed_to?(:view_issue_watchers, @issue.project)
|
||||||
end
|
end
|
||||||
|
|
|
@ -84,6 +84,9 @@ RedmineApp::Application.routes.draw do
|
||||||
match 'watchers/watch', :controller=> 'watchers', :action => 'watch', :via => :post
|
match 'watchers/watch', :controller=> 'watchers', :action => 'watch', :via => :post
|
||||||
match 'watchers/unwatch', :controller=> 'watchers', :action => 'unwatch', :via => :post
|
match 'watchers/unwatch', :controller=> 'watchers', :action => 'unwatch', :via => :post
|
||||||
match 'watchers/autocomplete_for_user', :controller=> 'watchers', :action => 'autocomplete_for_user', :via => :get
|
match 'watchers/autocomplete_for_user', :controller=> 'watchers', :action => 'autocomplete_for_user', :via => :get
|
||||||
|
# Specific routes for issue watchers API
|
||||||
|
post 'issues/:object_id/watchers', :to => 'watchers#create', :object_type => 'issue'
|
||||||
|
delete 'issues/:object_id/watchers/:user_id' => 'watchers#destroy', :object_type => 'issue'
|
||||||
|
|
||||||
resources :projects do
|
resources :projects do
|
||||||
member do
|
member do
|
||||||
|
|
|
@ -453,6 +453,21 @@ class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "GET /issues/:id.xml?include=watchers should include watchers" do
|
||||||
|
Watcher.create!(:user_id => 3, :watchable => Issue.find(1))
|
||||||
|
|
||||||
|
get '/issues/1.xml?include=watchers', {}, credentials('jsmith')
|
||||||
|
|
||||||
|
assert_response :ok
|
||||||
|
assert_equal 'application/xml', response.content_type
|
||||||
|
assert_select 'issue' do
|
||||||
|
assert_select 'watchers', Issue.find(1).watchers.count
|
||||||
|
assert_select 'watchers' do
|
||||||
|
assert_select 'user[id=3]'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "POST /issues.xml" do
|
context "POST /issues.xml" do
|
||||||
should_allow_api_authentication(
|
should_allow_api_authentication(
|
||||||
:post,
|
:post,
|
||||||
|
@ -478,6 +493,18 @@ class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "POST /issues.xml with watcher_user_ids should create issue with watchers" do
|
||||||
|
assert_difference('Issue.count') do
|
||||||
|
post '/issues.xml',
|
||||||
|
{:issue => {:project_id => 1, :subject => 'Watchers',
|
||||||
|
:tracker_id => 2, :status_id => 3, :watcher_user_ids => [3, 1]}}, credentials('jsmith')
|
||||||
|
assert_response :created
|
||||||
|
end
|
||||||
|
issue = Issue.order('id desc').first
|
||||||
|
assert_equal 2, issue.watchers.size
|
||||||
|
assert_equal [1, 3], issue.watcher_user_ids.sort
|
||||||
|
end
|
||||||
|
|
||||||
context "POST /issues.xml with failure" do
|
context "POST /issues.xml with failure" do
|
||||||
should "have an errors tag" do
|
should "have an errors tag" do
|
||||||
assert_no_difference('Issue.count') do
|
assert_no_difference('Issue.count') do
|
||||||
|
@ -720,6 +747,30 @@ class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "POST /issues/:id/watchers.xml should add watcher" do
|
||||||
|
assert_difference 'Watcher.count' do
|
||||||
|
post '/issues/1/watchers.xml', {:user_id => 3}, credentials('jsmith')
|
||||||
|
|
||||||
|
assert_response :ok
|
||||||
|
assert_equal '', response.body
|
||||||
|
end
|
||||||
|
watcher = Watcher.order('id desc').first
|
||||||
|
assert_equal Issue.find(1), watcher.watchable
|
||||||
|
assert_equal User.find(3), watcher.user
|
||||||
|
end
|
||||||
|
|
||||||
|
test "DELETE /issues/:id/watchers/:user_id.xml should remove watcher" do
|
||||||
|
Watcher.create!(:user_id => 3, :watchable => Issue.find(1))
|
||||||
|
|
||||||
|
assert_difference 'Watcher.count', -1 do
|
||||||
|
delete '/issues/1/watchers/3.xml', {}, credentials('jsmith')
|
||||||
|
|
||||||
|
assert_response :ok
|
||||||
|
assert_equal '', response.body
|
||||||
|
end
|
||||||
|
assert_equal false, Issue.find(1).watched_by?(User.find(3))
|
||||||
|
end
|
||||||
|
|
||||||
def test_create_issue_with_uploaded_file
|
def test_create_issue_with_uploaded_file
|
||||||
set_tmp_attachments_directory
|
set_tmp_attachments_directory
|
||||||
# upload the file
|
# upload the file
|
||||||
|
|
|
@ -47,5 +47,15 @@ class RoutingWatchersTest < ActionController::IntegrationTest
|
||||||
{ :method => 'post', :path => "/watchers/unwatch" },
|
{ :method => 'post', :path => "/watchers/unwatch" },
|
||||||
{ :controller => 'watchers', :action => 'unwatch' }
|
{ :controller => 'watchers', :action => 'unwatch' }
|
||||||
)
|
)
|
||||||
|
assert_routing(
|
||||||
|
{ :method => 'post', :path => "/issues/12/watchers.xml" },
|
||||||
|
{ :controller => 'watchers', :action => 'create',
|
||||||
|
:object_type => 'issue', :object_id => '12', :format => 'xml' }
|
||||||
|
)
|
||||||
|
assert_routing(
|
||||||
|
{ :method => 'delete', :path => "/issues/12/watchers/3.xml" },
|
||||||
|
{ :controller => 'watchers', :action => 'destroy',
|
||||||
|
:object_type => 'issue', :object_id => '12', :user_id => '3', :format => 'xml'}
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue