You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

watchers_controller_test.rb 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. # frozen_string_literal: true
  2. # Redmine - project management software
  3. # Copyright (C) 2006-2021 Jean-Philippe Lang
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU General Public License
  7. # as published by the Free Software Foundation; either version 2
  8. # of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. require File.expand_path('../../test_helper', __FILE__)
  19. class WatchersControllerTest < Redmine::ControllerTest
  20. fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules,
  21. :issues, :trackers, :projects_trackers, :issue_statuses, :enumerations, :watchers,
  22. :boards, :messages, :wikis, :wiki_pages
  23. def setup
  24. User.current = nil
  25. end
  26. def test_watch_a_single_object_as_html
  27. @request.session[:user_id] = 3
  28. assert_difference('Watcher.count') do
  29. post :watch, :params => {:object_type => 'issue', :object_id => '1'}
  30. assert_response :success
  31. assert_include 'Watcher added', response.body
  32. end
  33. assert Issue.find(1).watched_by?(User.find(3))
  34. end
  35. def test_watch_a_single_object
  36. @request.session[:user_id] = 3
  37. assert_difference('Watcher.count') do
  38. post :watch, :params => {:object_type => 'issue', :object_id => '1'}, :xhr => true
  39. assert_response :success
  40. assert_include '$(".issue-1-watcher")', response.body
  41. end
  42. assert Issue.find(1).watched_by?(User.find(3))
  43. end
  44. def test_watch_a_collection_with_a_single_object
  45. @request.session[:user_id] = 3
  46. assert_difference('Watcher.count') do
  47. post :watch, :params => {:object_type => 'issue', :object_id => ['1']}, :xhr => true
  48. assert_response :success
  49. assert_include '$(".issue-1-watcher")', response.body
  50. end
  51. assert Issue.find(1).watched_by?(User.find(3))
  52. end
  53. def test_watch_a_collection_with_multiple_objects
  54. @request.session[:user_id] = 3
  55. assert_difference('Watcher.count', 2) do
  56. post :watch, :params => {:object_type => 'issue', :object_id => ['1', '3']}, :xhr => true
  57. assert_response :success
  58. assert_include '$(".issue-bulk-watcher")', response.body
  59. end
  60. assert Issue.find(1).watched_by?(User.find(3))
  61. assert Issue.find(3).watched_by?(User.find(3))
  62. end
  63. def test_watch_a_news_module_should_add_watcher
  64. @request.session[:user_id] = 7
  65. assert_not_nil m = Project.find(1).enabled_module('news')
  66. assert_difference 'Watcher.count' do
  67. post :watch, :params => {:object_type => 'enabled_module', :object_id => m.id.to_s}, :xhr => true
  68. assert_response :success
  69. end
  70. assert m.reload.watched_by?(User.find(7))
  71. end
  72. def test_watch_a_private_news_module_without_permission_should_fail
  73. @request.session[:user_id] = 7
  74. assert_not_nil m = Project.find(2).enabled_module('news')
  75. assert_no_difference 'Watcher.count' do
  76. post :watch, :params => {:object_type => 'enabled_module', :object_id => m.id.to_s}, :xhr => true
  77. assert_response 403
  78. end
  79. end
  80. def test_watch_should_be_denied_without_permission
  81. Role.find(2).remove_permission! :view_issues
  82. @request.session[:user_id] = 3
  83. assert_no_difference('Watcher.count') do
  84. post :watch, :params => {:object_type => 'issue', :object_id => '1'}, :xhr => true
  85. assert_response 403
  86. end
  87. end
  88. def test_watch_invalid_class_should_respond_with_404
  89. @request.session[:user_id] = 3
  90. assert_no_difference('Watcher.count') do
  91. post :watch, :params => {:object_type => 'foo', :object_id => '1'}, :xhr => true
  92. assert_response 404
  93. end
  94. end
  95. def test_watch_invalid_object_should_respond_with_404
  96. @request.session[:user_id] = 3
  97. assert_no_difference('Watcher.count') do
  98. post :watch, :params => {:object_type => 'issue', :object_id => '999'}, :xhr => true
  99. assert_response 404
  100. end
  101. end
  102. def test_unwatch_as_html
  103. @request.session[:user_id] = 3
  104. assert_difference('Watcher.count', -1) do
  105. delete :unwatch, :params => {:object_type => 'issue', :object_id => '2'}
  106. assert_response :success
  107. assert_include 'Watcher removed', response.body
  108. end
  109. assert !Issue.find(1).watched_by?(User.find(3))
  110. end
  111. def test_unwatch
  112. @request.session[:user_id] = 3
  113. assert_difference('Watcher.count', -1) do
  114. delete :unwatch, :params => {:object_type => 'issue', :object_id => '2'}, :xhr => true
  115. assert_response :success
  116. assert_include '$(".issue-2-watcher")', response.body
  117. end
  118. assert !Issue.find(1).watched_by?(User.find(3))
  119. end
  120. def test_unwatch_a_collection_with_multiple_objects
  121. @request.session[:user_id] = 3
  122. Watcher.create!(:user_id => 3, :watchable => Issue.find(1))
  123. Watcher.create!(:user_id => 3, :watchable => Issue.find(3))
  124. assert_difference('Watcher.count', -2) do
  125. delete :unwatch, :params => {:object_type => 'issue', :object_id => ['1', '3']}, :xhr => true
  126. assert_response :success
  127. assert_include '$(".issue-bulk-watcher")', response.body
  128. end
  129. assert !Issue.find(1).watched_by?(User.find(3))
  130. assert !Issue.find(3).watched_by?(User.find(3))
  131. end
  132. def test_new
  133. @request.session[:user_id] = 2
  134. get :new, :params => {:object_type => 'issue', :object_id => '2'}, :xhr => true
  135. assert_response :success
  136. assert_match /ajax-modal/, response.body
  137. end
  138. def test_new_for_message
  139. @request.session[:user_id] = 2
  140. get :new, :params => {:object_type => 'message', :object_id => '1'}, :xhr => true
  141. assert_response :success
  142. assert_match /ajax-modal/, response.body
  143. end
  144. def test_new_for_wiki_page
  145. @request.session[:user_id] = 2
  146. get :new, :params => {:object_type => 'wiki_page', :object_id => '1'}, :xhr => true
  147. assert_response :success
  148. assert_match /ajax-modal/, response.body
  149. end
  150. def test_new_with_multiple_objects
  151. @request.session[:user_id] = 2
  152. get :new, :params => {:object_type => 'issue', :object_id => ['1', '2']}, :xhr => true
  153. assert_response :success
  154. assert_match /ajax-modal/, response.body
  155. end
  156. def test_new_for_new_record_with_project_id
  157. @request.session[:user_id] = 2
  158. get :new, :params => {:project_id => 1}, :xhr => true
  159. assert_response :success
  160. assert_match /ajax-modal/, response.body
  161. end
  162. def test_new_for_new_record_with_project_identifier
  163. @request.session[:user_id] = 2
  164. get :new, :params => {:project_id => 'ecookbook'}, :xhr => true
  165. assert_response :success
  166. assert_match /ajax-modal/, response.body
  167. end
  168. def test_create_as_html
  169. @request.session[:user_id] = 2
  170. assert_difference('Watcher.count') do
  171. post :create, :params => {
  172. :object_type => 'issue', :object_id => '2',
  173. :watcher => {:user_id => '4'}
  174. }
  175. assert_response :success
  176. assert_include 'Watcher added', response.body
  177. end
  178. assert Issue.find(2).watched_by?(User.find(4))
  179. end
  180. def test_create_group_as_html
  181. @request.session[:user_id] = 2
  182. assert_difference('Watcher.count') do
  183. post :create, :params => {
  184. :object_type => 'issue', :object_id => '2',
  185. :watcher => {:user_id => '10'}
  186. }
  187. assert_response :success
  188. assert_include 'Watcher added', response.body
  189. end
  190. assert Issue.find(2).watched_by?(Group.find(10))
  191. end
  192. def test_create
  193. @request.session[:user_id] = 2
  194. assert_difference('Watcher.count') do
  195. post :create, :params => {
  196. :object_type => 'issue', :object_id => '2',
  197. :watcher => {:user_id => '4'}
  198. }, :xhr => true
  199. assert_response :success
  200. assert_match /watchers/, response.body
  201. assert_match /ajax-modal/, response.body
  202. end
  203. assert Issue.find(2).watched_by?(User.find(4))
  204. end
  205. def test_create_for_message
  206. @request.session[:user_id] = 2
  207. assert_difference('Watcher.count') do
  208. post :create, :params => {
  209. :object_type => 'message', :object_id => '1',
  210. :watcher => {:user_id => '4'}
  211. }, :xhr => true
  212. assert_response :success
  213. assert_match /watchers/, response.body
  214. assert_match /ajax-modal/, response.body
  215. end
  216. assert Message.find(1).watched_by?(User.find(4))
  217. end
  218. def test_create_for_wiki_page
  219. @request.session[:user_id] = 2
  220. assert_difference('Watcher.count') do
  221. post :create, :params => {
  222. :object_type => 'wiki_page', :object_id => '1',
  223. :watcher => {:user_id => '4'}
  224. }, :xhr => true
  225. assert_response :success
  226. assert_match /watchers/, response.body
  227. assert_match /ajax-modal/, response.body
  228. end
  229. assert WikiPage.find(1).watched_by?(User.find(4))
  230. end
  231. def test_create_with_mutiple_users
  232. @request.session[:user_id] = 2
  233. assert_difference('Watcher.count', 3) do
  234. post :create, :params => {
  235. :object_type => 'issue', :object_id => '2',
  236. :watcher => {:user_ids => ['4', '7', '10']}
  237. }, :xhr => true
  238. assert_response :success
  239. assert_match /watchers/, response.body
  240. assert_match /ajax-modal/, response.body
  241. end
  242. issue = Issue.find(2)
  243. assert issue.watched_by?(User.find(4))
  244. assert issue.watched_by?(User.find(7))
  245. assert issue.watched_by?(Group.find(10))
  246. end
  247. def test_create_for_message_with_mutiple_users
  248. @request.session[:user_id] = 2
  249. assert_difference('Watcher.count', 3) do
  250. post :create, :params => {
  251. :object_type => 'message', :object_id => '1',
  252. :watcher => {:user_ids => ['4', '7', '10']}
  253. }, :xhr => true
  254. assert_response :success
  255. assert_match /watchers/, response.body
  256. assert_match /ajax-modal/, response.body
  257. end
  258. message = Message.find(1)
  259. assert message.watched_by?(User.find(4))
  260. assert message.watched_by?(User.find(7))
  261. assert message.watched_by?(Group.find(10))
  262. end
  263. def test_create_for_wiki_page_with_mutiple_users
  264. @request.session[:user_id] = 2
  265. assert_difference('Watcher.count', 3) do
  266. post :create, :params => {
  267. :object_type => 'wiki_page', :object_id => '1',
  268. :watcher => {:user_ids => ['4', '7', '10']}
  269. }, :xhr => true
  270. assert_response :success
  271. assert_match /watchers/, response.body
  272. assert_match /ajax-modal/, response.body
  273. end
  274. wiki_page = WikiPage.find(1)
  275. assert wiki_page.watched_by?(User.find(4))
  276. assert wiki_page.watched_by?(User.find(7))
  277. assert wiki_page.watched_by?(Group.find(10))
  278. end
  279. def test_create_with_mutiple_objects
  280. @request.session[:user_id] = 2
  281. assert_difference('Watcher.count', 6) do
  282. post :create, :params => {
  283. :object_type => 'issue', :object_id => ['1', '2'],
  284. :watcher => {:user_ids => ['4', '7', '10']}
  285. }, :xhr => true
  286. assert_response :success
  287. assert_match /watchers/, response.body
  288. assert_match /ajax-modal/, response.body
  289. end
  290. issue1 = Issue.find(1)
  291. issue2 = Issue.find(2)
  292. user4 = User.find(4)
  293. user7 = User.find(7)
  294. group10 = Group.find(10)
  295. assert issue1.watched_by?(user4)
  296. assert issue2.watched_by?(user4)
  297. assert issue1.watched_by?(user7)
  298. assert issue2.watched_by?(user7)
  299. assert issue1.watched_by?(group10)
  300. assert issue2.watched_by?(group10)
  301. end
  302. def test_autocomplete_on_watchable_creation
  303. @request.session[:user_id] = 2
  304. group = Group.generate!(:name => 'Group Minimum')
  305. get :autocomplete_for_user, :params => {:q => 'mi', :project_id => 'ecookbook'}, :xhr => true
  306. assert_response :success
  307. assert_select 'input', :count => 5
  308. assert_select 'input[name=?][value="1"]', 'watcher[user_ids][]'
  309. assert_select 'input[name=?][value="2"]', 'watcher[user_ids][]'
  310. assert_select 'input[name=?][value="8"]', 'watcher[user_ids][]'
  311. assert_select 'input[name=?][value="9"]', 'watcher[user_ids][]'
  312. assert_select %(input[name=?][value="#{group.id}"]), 'watcher[user_ids][]'
  313. end
  314. def test_search_non_member_on_create
  315. @request.session[:user_id] = 2
  316. project = Project.find_by_name("ecookbook")
  317. user = User.generate!(:firstname => 'issue15622')
  318. membership = user.membership(project)
  319. assert_nil membership
  320. get :autocomplete_for_user, :params => {:q => 'issue15622', :project_id => 'ecookbook'}, :xhr => true
  321. assert_response :success
  322. assert_select 'input', :count => 1
  323. end
  324. def test_autocomplete_on_watchable_update
  325. @request.session[:user_id] = 2
  326. get :autocomplete_for_user, :params => {
  327. :object_type => 'issue', :object_id => '2',
  328. :project_id => 'ecookbook', :q => 'mi'
  329. }, :xhr => true
  330. assert_response :success
  331. assert_select 'input', :count => 3
  332. assert_select 'input[name=?][value="2"]', 'watcher[user_ids][]'
  333. assert_select 'input[name=?][value="8"]', 'watcher[user_ids][]'
  334. assert_select 'input[name=?][value="9"]', 'watcher[user_ids][]'
  335. end
  336. def test_search_and_add_non_member_on_update
  337. @request.session[:user_id] = 2
  338. project = Project.find_by_name("ecookbook")
  339. user = User.generate!(:firstname => 'issue15622')
  340. membership = user.membership(project)
  341. assert_nil membership
  342. get :autocomplete_for_user, :params => {
  343. :object_type => 'issue', :object_id => '2',
  344. :project_id => 'ecookbook', :q => 'issue15622'
  345. }, :xhr => true
  346. assert_response :success
  347. assert_select 'input', :count => 1
  348. assert_difference('Watcher.count', 1) do
  349. post :create, :params => {
  350. :object_type => 'issue', :object_id => '2',
  351. :watcher => {:user_ids => ["#{user.id}"]}
  352. }, :xhr => true
  353. assert_response :success
  354. assert_match /watchers/, response.body
  355. assert_match /ajax-modal/, response.body
  356. end
  357. assert Issue.find(2).watched_by?(user)
  358. end
  359. def test_autocomplete_for_user_should_return_visible_users
  360. Role.update_all :users_visibility => 'members_of_visible_projects'
  361. hidden = User.generate!(:lastname => 'autocomplete_hidden')
  362. visible = User.generate!(:lastname => 'autocomplete_visible')
  363. User.add_to_project(visible, Project.find(1))
  364. @request.session[:user_id] = 2
  365. get :autocomplete_for_user, :params => {:q => 'autocomp', :project_id => 'ecookbook'}, :xhr => true
  366. assert_response :success
  367. assert_include visible.name, response.body
  368. assert_not_include hidden.name, response.body
  369. end
  370. def test_autocomplete_for_user_should_not_return_users_without_object_visibility
  371. @request.session[:user_id] = 1
  372. get :autocomplete_for_user, :params => {
  373. q: 'rober',
  374. project_id: 'onlinestore',
  375. object_id: '4',
  376. object_type: 'issue'
  377. }, :xhr => true
  378. assert_response :success
  379. assert response.body.blank?
  380. end
  381. def test_append
  382. @request.session[:user_id] = 2
  383. assert_no_difference 'Watcher.count' do
  384. post :append, :params => {
  385. :watcher => {:user_ids => ['4', '7']}, :project_id => 'ecookbook'
  386. }, :xhr => true
  387. assert_response :success
  388. assert_include 'watchers_inputs', response.body
  389. assert_include 'issue[watcher_user_ids][]', response.body
  390. end
  391. end
  392. def test_append_without_user_should_render_nothing
  393. @request.session[:user_id] = 2
  394. post :append, :params => {:project_id => 'ecookbook'}, :xhr => true
  395. assert_response :success
  396. assert response.body.blank?
  397. end
  398. def test_destroy_as_html
  399. @request.session[:user_id] = 2
  400. assert_difference('Watcher.count', -1) do
  401. delete :destroy, :params => {
  402. :object_type => 'issue', :object_id => '2', :user_id => '3'
  403. }
  404. assert_response :success
  405. assert_include 'Watcher removed', response.body
  406. end
  407. assert !Issue.find(2).watched_by?(User.find(3))
  408. end
  409. def test_destroy_group_as_html
  410. @request.session[:user_id] = 2
  411. issue = Issue.find(2)
  412. group = Group.find(10)
  413. issue.add_watcher(group)
  414. assert issue.watched_by?(group)
  415. assert_difference('Watcher.count', -1) do
  416. delete :destroy, :params => {
  417. :object_type => 'issue', :object_id => '2', :user_id => '10'
  418. }
  419. assert_response :success
  420. assert_include 'Watcher removed', response.body
  421. end
  422. issue.reload
  423. assert !issue.watched_by?(group)
  424. end
  425. def test_destroy
  426. @request.session[:user_id] = 2
  427. assert_difference('Watcher.count', -1) do
  428. delete :destroy, :params => {
  429. :object_type => 'issue', :object_id => '2', :user_id => '3'
  430. }, :xhr => true
  431. assert_response :success
  432. assert_match /watchers/, response.body
  433. end
  434. assert !Issue.find(2).watched_by?(User.find(3))
  435. end
  436. def test_destroy_for_meessage
  437. @request.session[:user_id] = 2
  438. message = Message.find(1)
  439. user = User.find(1)
  440. assert message.watched_by?(user)
  441. assert_difference('Watcher.count', -1) do
  442. delete :destroy, :params => {
  443. :object_type => 'message', :object_id => '1', :user_id => '1'
  444. }, :xhr => true
  445. assert_response :success
  446. assert_match /watchers/, response.body
  447. end
  448. message.reload
  449. assert !message.watched_by?(user)
  450. end
  451. def test_destroy_for_wiki_page
  452. @request.session[:user_id] = 2
  453. wiki_page = WikiPage.find(1)
  454. user = User.find(1)
  455. assert wiki_page.watched_by?(user)
  456. assert_difference('Watcher.count', -1) do
  457. delete :destroy, :params => {
  458. :object_type => 'wiki_page', :object_id => '1', :user_id => '1'
  459. }, :xhr => true
  460. assert_response :success
  461. assert_match /watchers/, response.body
  462. end
  463. wiki_page.reload
  464. assert !wiki_page.watched_by?(user)
  465. end
  466. def test_destroy_locked_user
  467. user = User.find(3)
  468. user.lock!
  469. assert user.reload.locked?
  470. @request.session[:user_id] = 2
  471. assert_difference('Watcher.count', -1) do
  472. delete :destroy, :params => {
  473. :object_type => 'issue', :object_id => '2', :user_id => '3'
  474. }, :xhr => true
  475. assert_response :success
  476. assert_match /watchers/, response.body
  477. end
  478. assert !Issue.find(2).watched_by?(User.find(3))
  479. end
  480. def test_destroy_invalid_user_should_respond_with_404
  481. @request.session[:user_id] = 2
  482. assert_no_difference('Watcher.count') do
  483. delete :destroy, :params => {
  484. :object_type => 'issue', :object_id => '2', :user_id => '999'
  485. }
  486. assert_response 404
  487. end
  488. end
  489. end