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.

users_controller_test.rb 30KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009
  1. # frozen_string_literal: true
  2. # Redmine - project management software
  3. # Copyright (C) 2006-2022 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 UsersControllerTest < Redmine::ControllerTest
  20. include Redmine::I18n
  21. fixtures :users, :user_preferences, :email_addresses, :projects, :members, :member_roles, :roles,
  22. :custom_fields, :custom_values, :groups_users,
  23. :auth_sources,
  24. :enabled_modules,
  25. :issues, :issue_statuses,
  26. :trackers
  27. def setup
  28. User.current = nil
  29. @request.session[:user_id] = 1 # admin
  30. end
  31. def test_index
  32. get :index
  33. assert_response :success
  34. assert_select 'table.users'
  35. assert_select 'tr.user.active'
  36. assert_select 'tr.user.locked', 0
  37. end
  38. def test_index_with_status_filter
  39. get :index, :params => {:status => 3}
  40. assert_response :success
  41. assert_select 'tr.user.active', 0
  42. assert_select 'tr.user.locked'
  43. end
  44. def test_index_with_name_filter
  45. get :index, :params => {:name => 'john'}
  46. assert_response :success
  47. assert_select 'tr.user td.username', :text => 'jsmith'
  48. assert_select 'tr.user', 1
  49. end
  50. def test_index_with_group_filter
  51. get :index, :params => {:group_id => '10'}
  52. assert_response :success
  53. assert_select 'tr.user', Group.find(10).users.count
  54. assert_select 'select[name=group_id]' do
  55. assert_select 'option[value="10"][selected=selected]'
  56. end
  57. end
  58. def test_index_should_not_show_2fa_filter_and_column_if_disabled
  59. with_settings twofa: "0" do
  60. get :index
  61. assert_response :success
  62. assert_select "select#twofa", 0
  63. assert_select 'td.twofa', 0
  64. end
  65. end
  66. def test_index_filter_by_twofa_yes
  67. with_settings twofa: "1" do
  68. user = User.find(1)
  69. user.twofa_totp_key = "AVYA3RARZ3GY3VWT7MIEJ72I5TTJRO3X"
  70. user.twofa_scheme = "totp"
  71. user.save
  72. get :index, :params => {:twofa => '1'}
  73. assert_response :success
  74. assert_select "select#twofa", 1
  75. assert_select 'tr.user', 1
  76. assert_select 'td.twofa.tick .icon-checked'
  77. end
  78. end
  79. def test_index_filter_by_twofa_no
  80. with_settings twofa: "1" do
  81. user = User.find(1)
  82. user.twofa_totp_key = "AVYA3RARZ3GY3VWT7MIEJ72I5TTJRO3X"
  83. user.twofa_scheme = "totp"
  84. user.save
  85. get :index, :params => {:twofa => '0'}
  86. assert_response :success
  87. assert_select "select#twofa", 1
  88. assert_select "td.twofa.tick" do
  89. assert_select "span.icon-checked", 0
  90. end
  91. end
  92. end
  93. def test_index_csv
  94. with_settings :default_language => 'en' do
  95. user = User.logged.status(1).first
  96. user.update(passwd_changed_on: Time.current.last_month, twofa_scheme: 'totp')
  97. get :index, params: {format: 'csv'}
  98. assert_response :success
  99. assert_equal User.logged.status(1).count, response.body.chomp.split("\n").size - 1
  100. assert_include format_time(user.updated_on), response.body.split("\n").second
  101. assert_include format_time(user.passwd_changed_on), response.body.split("\n").second
  102. # status
  103. assert_include 'active', response.body.split("\n").second
  104. assert_not_include 'locked', response.body.split("\n").second
  105. # twofa_scheme
  106. assert_include 'Authenticator app', response.body.split("\n").second
  107. assert_include 'disabled', response.body.split("\n").third
  108. assert_equal 'text/csv; header=present', @response.media_type
  109. end
  110. end
  111. def test_index_csv_with_custom_field_columns
  112. float_custom_field = UserCustomField.generate!(:name => 'float field', :field_format => 'float')
  113. date_custom_field = UserCustomField.generate!(:name => 'date field', :field_format => 'date')
  114. user = User.last
  115. user.custom_field_values = {float_custom_field.id.to_s => 2.1, date_custom_field.id.to_s => '2020-01-10'}
  116. user.save
  117. User.find(@request.session[:user_id]).update(:language => nil)
  118. with_settings :default_language => 'fr' do
  119. get :index, :params => {:name => user.lastname, :format => 'csv'}
  120. assert_response :success
  121. assert_include 'float field;date field', response.body
  122. assert_include '2,10;10/01/2020', response.body
  123. assert_equal 'text/csv; header=present', @response.media_type
  124. end
  125. end
  126. def test_index_csv_with_status_filter
  127. with_settings :default_language => 'en' do
  128. get :index, :params => {:status => 3, :format => 'csv'}
  129. assert_response :success
  130. assert_equal User.logged.status(3).count, response.body.chomp.split("\n").size - 1
  131. assert_include 'locked', response.body
  132. assert_not_include 'active', response.body
  133. assert_equal 'text/csv; header=present', @response.media_type
  134. end
  135. end
  136. def test_index_csv_with_name_filter
  137. get :index, :params => {:name => 'John', :format => 'csv'}
  138. assert_response :success
  139. assert_equal User.logged.like('John').count, response.body.chomp.split("\n").size - 1
  140. assert_include 'John', response.body
  141. assert_equal 'text/csv; header=present', @response.media_type
  142. end
  143. def test_index_csv_with_group_filter
  144. get :index, :params => {:group_id => '10', :format => 'csv'}
  145. assert_response :success
  146. assert_equal Group.find(10).users.count, response.body.chomp.split("\n").size - 1
  147. assert_equal 'text/csv; header=present', @response.media_type
  148. end
  149. def test_show
  150. @request.session[:user_id] = nil
  151. get :show, :params => {:id => 2}
  152. assert_response :success
  153. assert_select 'h2', :text => /John Smith/
  154. # groups block should not be rendeder for users which are not part of any group
  155. assert_select 'div#groups', 0
  156. end
  157. def test_show_should_display_visible_custom_fields
  158. @request.session[:user_id] = nil
  159. UserCustomField.find_by_name('Phone number').update_attribute :visible, true
  160. get :show, :params => {:id => 2}
  161. assert_response :success
  162. assert_select 'li.cf_4.string_cf', :text => /Phone number/
  163. end
  164. def test_show_should_not_display_hidden_custom_fields
  165. @request.session[:user_id] = nil
  166. UserCustomField.find_by_name('Phone number').update_attribute :visible, false
  167. get :show, :params => {:id => 2}
  168. assert_response :success
  169. assert_select 'li', :text => /Phone number/, :count => 0
  170. end
  171. def test_show_should_not_fail_when_custom_values_are_nil
  172. user = User.find(2)
  173. # Create a custom field to illustrate the issue
  174. custom_field = CustomField.create!(:name => 'Testing', :field_format => 'text')
  175. custom_value = user.custom_values.build(:custom_field => custom_field).save!
  176. get :show, :params => {:id => 2}
  177. assert_response :success
  178. end
  179. def test_show_inactive
  180. @request.session[:user_id] = nil
  181. get :show, :params => {:id => 5}
  182. assert_response 404
  183. end
  184. def test_show_inactive_by_admin
  185. @request.session[:user_id] = 1
  186. get :show, :params => {:id => 5}
  187. assert_response 200
  188. assert_select 'h2', :text => /Dave2 Lopper2/
  189. end
  190. def test_show_user_who_is_not_visible_should_return_404
  191. Role.anonymous.update! :users_visibility => 'members_of_visible_projects'
  192. user = User.generate!
  193. @request.session[:user_id] = nil
  194. get :show, :params => {:id => user.id}
  195. assert_response 404
  196. end
  197. def test_show_displays_memberships_based_on_project_visibility
  198. @request.session[:user_id] = 1
  199. get :show, :params => {:id => 2}
  200. assert_response :success
  201. assert_select 'table.list.projects>tbody' do
  202. assert_select 'tr:nth-of-type(1)' do
  203. assert_select 'td:nth-of-type(1)>span>a', :text => 'eCookbook'
  204. assert_select 'td:nth-of-type(2)', :text => 'Manager'
  205. end
  206. assert_select 'tr:nth-of-type(2)' do
  207. assert_select 'td:nth-of-type(1)>span>a', :text => 'Private child of eCookbook'
  208. assert_select 'td:nth-of-type(2)', :text => 'Manager'
  209. end
  210. assert_select 'tr:nth-of-type(3)' do
  211. assert_select 'td:nth-of-type(1)>span>a', :text => 'OnlineStore'
  212. assert_select 'td:nth-of-type(2)', :text => 'Developer'
  213. end
  214. end
  215. end
  216. def test_show_current_should_require_authentication
  217. @request.session[:user_id] = nil
  218. get :show, :params => {:id => 'current'}
  219. assert_response 302
  220. end
  221. def test_show_current
  222. @request.session[:user_id] = 2
  223. get :show, :params => {:id => 'current'}
  224. assert_response :success
  225. assert_select 'h2', :text => /John Smith/
  226. end
  227. def test_show_issues_counts
  228. @request.session[:user_id] = 2
  229. get :show, :params => {:id => 2}
  230. assert_select 'table.list.issue-report>tbody' do
  231. assert_select 'tr:nth-of-type(1)' do
  232. assert_select 'td:nth-of-type(1)>a', :text => 'Assigned issues'
  233. assert_select 'td:nth-of-type(2)>a', :text => '1' # open
  234. assert_select 'td:nth-of-type(3)>a', :text => '0' # closed
  235. assert_select 'td:nth-of-type(4)>a', :text => '1' # total
  236. end
  237. assert_select 'tr:nth-of-type(2)' do
  238. assert_select 'td:nth-of-type(1)>a', :text => 'Reported issues'
  239. assert_select 'td:nth-of-type(2)>a', :text => '11' # open
  240. assert_select 'td:nth-of-type(3)>a', :text => '2' # closed
  241. assert_select 'td:nth-of-type(4)>a', :text => '13' # total
  242. end
  243. end
  244. end
  245. def test_show_user_should_list_user_groups
  246. @request.session[:user_id] = 1
  247. get :show, :params => {:id => 8}
  248. assert_select 'div#groups', 1 do
  249. assert_select 'h3', :text => 'Groups'
  250. assert_select 'li', 2
  251. assert_select 'a[href=?]', '/groups/10/edit', :text => 'A Team'
  252. assert_select 'a[href=?]', '/groups/11/edit', :text => 'B Team'
  253. end
  254. end
  255. def test_show_should_list_all_emails
  256. EmailAddress.create!(user_id: 3, address: 'dlopper@example.net')
  257. EmailAddress.create!(user_id: 3, address: 'dlopper@example.org')
  258. @request.session[:user_id] = 1
  259. get :show, params: {id: 3}
  260. assert_select 'li', text: /Email:/ do
  261. assert_select 'a:nth-of-type(1)', text: 'dlopper@somenet.foo'
  262. assert_select 'a:nth-of-type(2)', text: 'dlopper@example.net'
  263. assert_select 'a:nth-of-type(3)', text: 'dlopper@example.org'
  264. end
  265. end
  266. def test_new
  267. get :new
  268. assert_response :success
  269. assert_select 'input[name=?]', 'user[login]'
  270. assert_select 'label[for=?]>span.required', 'user_password', 1
  271. end
  272. def test_create
  273. assert_difference 'User.count' do
  274. assert_difference 'ActionMailer::Base.deliveries.size' do
  275. post :create, :params => {
  276. :user => {
  277. :firstname => 'John',
  278. :lastname => 'Doe',
  279. :login => 'jdoe',
  280. :password => 'secret123',
  281. :password_confirmation => 'secret123',
  282. :mail => 'jdoe@gmail.com',
  283. :mail_notification => 'none'
  284. },
  285. :send_information => '1'
  286. }
  287. end
  288. end
  289. user = User.order('id DESC').first
  290. assert_redirected_to :controller => 'users', :action => 'edit', :id => user.id
  291. assert_equal 'John', user.firstname
  292. assert_equal 'Doe', user.lastname
  293. assert_equal 'jdoe', user.login
  294. assert_equal 'jdoe@gmail.com', user.mail
  295. assert_equal 'none', user.mail_notification
  296. assert user.check_password?('secret123')
  297. mail = ActionMailer::Base.deliveries.last
  298. assert_not_nil mail
  299. assert_equal [user.mail], mail.to
  300. assert_mail_body_match 'secret', mail
  301. end
  302. def test_create_with_preferences
  303. assert_difference 'User.count' do
  304. post :create, :params => {
  305. :user => {
  306. :firstname => 'John',
  307. :lastname => 'Doe',
  308. :login => 'jdoe',
  309. :password => 'secret123',
  310. :password_confirmation => 'secret123',
  311. :mail => 'jdoe@gmail.com',
  312. :mail_notification => 'none'
  313. },
  314. :pref => {
  315. 'hide_mail' => '1',
  316. 'time_zone' => 'Paris',
  317. 'comments_sorting' => 'desc',
  318. 'warn_on_leaving_unsaved' => '0',
  319. 'textarea_font' => 'proportional',
  320. 'history_default_tab' => 'history'
  321. }
  322. }
  323. end
  324. user = User.order('id DESC').first
  325. assert_equal 'jdoe', user.login
  326. assert_equal true, user.pref.hide_mail
  327. assert_equal 'Paris', user.pref.time_zone
  328. assert_equal 'desc', user.pref[:comments_sorting]
  329. assert_equal '0', user.pref[:warn_on_leaving_unsaved]
  330. assert_equal 'proportional', user.pref[:textarea_font]
  331. assert_equal 'history', user.pref[:history_default_tab]
  332. end
  333. def test_create_with_generate_password_should_email_the_password
  334. assert_difference 'User.count' do
  335. post :create, :params => {
  336. :user => {
  337. :login => 'randompass',
  338. :firstname => 'Random',
  339. :lastname => 'Pass',
  340. :mail => 'randompass@example.net',
  341. :language => 'en',
  342. :generate_password => '1',
  343. :password => '',
  344. :password_confirmation => ''
  345. },
  346. :send_information => 1
  347. }
  348. end
  349. user = User.order('id DESC').first
  350. assert_equal 'randompass', user.login
  351. mail = ActionMailer::Base.deliveries.last
  352. assert_not_nil mail
  353. m = mail_body(mail).match(/Password: ([a-zA-Z0-9]+)/)
  354. assert m
  355. password = m[1]
  356. assert user.check_password?(password)
  357. end
  358. def test_create_and_continue
  359. post :create, :params => {
  360. :user => {
  361. :login => 'randompass',
  362. :firstname => 'Random',
  363. :lastname => 'Pass',
  364. :mail => 'randompass@example.net',
  365. :generate_password => '1'
  366. },
  367. :continue => '1'
  368. }
  369. assert_redirected_to '/users/new?user%5Bgenerate_password%5D=1'
  370. end
  371. def test_create_with_failure
  372. assert_no_difference 'User.count' do
  373. post :create, :params => {:user => {:login => 'foo'}}
  374. end
  375. assert_response :success
  376. assert_select_error /Email cannot be blank/
  377. end
  378. def test_create_with_failure_sould_preserve_preference
  379. assert_no_difference 'User.count' do
  380. post :create, :params => {
  381. :user => {
  382. :login => 'foo'
  383. },
  384. :pref => {
  385. 'no_self_notified' => '1',
  386. 'hide_mail' => '1',
  387. 'time_zone' => 'Paris',
  388. 'comments_sorting' => 'desc',
  389. 'warn_on_leaving_unsaved' => '0'
  390. }
  391. }
  392. end
  393. assert_response :success
  394. assert_select 'select#pref_time_zone option[selected=selected]', :text => /Paris/
  395. assert_select 'input#pref_no_self_notified[value="1"][checked=checked]'
  396. end
  397. def test_create_admin_should_send_security_notification
  398. ActionMailer::Base.deliveries.clear
  399. post :create, :params => {
  400. :user => {
  401. :firstname => 'Edgar',
  402. :lastname => 'Schmoe',
  403. :login => 'eschmoe',
  404. :password => 'secret123',
  405. :password_confirmation => 'secret123',
  406. :mail => 'eschmoe@example.foo',
  407. :admin => '1'
  408. }
  409. }
  410. assert_not_nil (mail = ActionMailer::Base.deliveries.last)
  411. assert_mail_body_match '0.0.0.0', mail
  412. assert_mail_body_match(
  413. I18n.t(
  414. :mail_body_security_notification_add,
  415. field: I18n.t(:field_admin),
  416. value: 'eschmoe'
  417. ),
  418. mail
  419. )
  420. assert_select_email do
  421. assert_select 'a[href^=?]', 'http://localhost:3000/users', :text => 'Users'
  422. end
  423. # All admins should receive this
  424. User.where(admin: true, status: Principal::STATUS_ACTIVE).each do |admin|
  425. assert_not_nil(
  426. ActionMailer::Base.deliveries.detect do |mail|
  427. [mail.to].flatten.include?(admin.mail)
  428. end
  429. )
  430. end
  431. end
  432. def test_create_non_admin_should_not_send_security_notification
  433. ActionMailer::Base.deliveries.clear
  434. post :create, :params => {
  435. :user => {
  436. :firstname => 'Edgar',
  437. :lastname => 'Schmoe',
  438. :login => 'eschmoe',
  439. :password => 'secret123',
  440. :password_confirmation => 'secret123',
  441. :mail => 'eschmoe@example.foo',
  442. :admin => '0'
  443. }
  444. }
  445. assert_nil ActionMailer::Base.deliveries.last
  446. end
  447. def test_edit
  448. with_settings :gravatar_enabled => '1' do
  449. get :edit, :params => {:id => 2}
  450. end
  451. assert_response :success
  452. assert_select 'h2>a+img.gravatar'
  453. assert_select 'input[name=?][value=?]', 'user[login]', 'jsmith'
  454. assert_select 'label[for=?]>span.required', 'user_password', 0
  455. end
  456. def test_edit_registered_user
  457. assert User.find(2).register!
  458. get :edit, :params => {:id => 2}
  459. assert_response :success
  460. assert_select 'a', :text => 'Activate'
  461. end
  462. def test_edit_should_be_denied_for_anonymous
  463. assert User.find(6).anonymous?
  464. get :edit, :params => {:id => 6}
  465. assert_response 404
  466. end
  467. def test_edit_user_with_full_text_formatting_custom_field_should_not_fail
  468. field = UserCustomField.find(4)
  469. field.update_attribute :text_formatting, 'full'
  470. get :edit, :params => {:id => 2}
  471. assert_response :success
  472. end
  473. def test_update
  474. ActionMailer::Base.deliveries.clear
  475. put :update, :params => {
  476. :id => 2,
  477. :user => {:firstname => 'Changed', :mail_notification => 'only_assigned'},
  478. :pref => {:hide_mail => '1', :comments_sorting => 'desc'}
  479. }
  480. user = User.find(2)
  481. assert_equal 'Changed', user.firstname
  482. assert_equal 'only_assigned', user.mail_notification
  483. assert_equal true, user.pref[:hide_mail]
  484. assert_equal 'desc', user.pref[:comments_sorting]
  485. assert ActionMailer::Base.deliveries.empty?
  486. end
  487. def test_update_with_failure
  488. assert_no_difference 'User.count' do
  489. put :update, :params => {
  490. :id => 2,
  491. :user => {:firstname => ''}
  492. }
  493. end
  494. assert_response :success
  495. assert_select_error /First name cannot be blank/
  496. end
  497. def test_update_with_group_ids_should_assign_groups
  498. put :update, :params => {
  499. :id => 2,
  500. :user => {:group_ids => ['10']}
  501. }
  502. user = User.find(2)
  503. assert_equal [10], user.group_ids
  504. end
  505. def test_update_with_activation_should_send_a_notification
  506. u = User.new(:firstname => 'Foo', :lastname => 'Bar',
  507. :mail => 'foo.bar@somenet.foo', :language => 'fr')
  508. u.login = 'foo'
  509. u.status = User::STATUS_REGISTERED
  510. u.save!
  511. ActionMailer::Base.deliveries.clear
  512. put(
  513. :update,
  514. :params => {
  515. :id => u.id,
  516. :user => {:status => User::STATUS_ACTIVE}
  517. }
  518. )
  519. assert u.reload.active?
  520. mail = ActionMailer::Base.deliveries.last
  521. assert_not_nil mail
  522. assert_equal ['foo.bar@somenet.foo'], mail.to
  523. assert_mail_body_match ll('fr', :notice_account_activated), mail
  524. end
  525. def test_update_with_password_change_should_send_a_notification
  526. ActionMailer::Base.deliveries.clear
  527. put(
  528. :update,
  529. :params => {
  530. :id => 2,
  531. :user => {
  532. :password => 'newpass123',
  533. :password_confirmation => 'newpass123'
  534. },
  535. :send_information => '1'
  536. }
  537. )
  538. u = User.find(2)
  539. assert u.check_password?('newpass123')
  540. mail = ActionMailer::Base.deliveries.last
  541. assert_not_nil mail
  542. assert_equal [u.mail], mail.to
  543. assert_mail_body_match 'newpass123', mail
  544. end
  545. def test_update_with_password_change_by_admin_should_send_a_security_notification
  546. ActionMailer::Base.deliveries.clear
  547. user = User.find_by(login: 'jsmith')
  548. put :update, :params => {
  549. :id => user.id,
  550. :user => {:password => 'newpass123', :password_confirmation => 'newpass123'}
  551. }
  552. assert_equal 1, ActionMailer::Base.deliveries.size
  553. mail = ActionMailer::Base.deliveries.last
  554. assert_equal [user.mail], mail.to
  555. assert_match 'Security notification', mail.subject
  556. assert_mail_body_match 'Your password has been changed.', mail
  557. end
  558. def test_update_with_generate_password_should_email_the_password
  559. ActionMailer::Base.deliveries.clear
  560. put(
  561. :update,
  562. :params => {
  563. :id => 2,
  564. :user => {
  565. :generate_password => '1',
  566. :password => '',
  567. :password_confirmation => ''
  568. },
  569. :send_information => '1'
  570. }
  571. )
  572. mail = ActionMailer::Base.deliveries.last
  573. assert_not_nil mail
  574. u = User.find(2)
  575. assert_equal [u.mail], mail.to
  576. m = mail_body(mail).match(/Password: ([a-zA-Z0-9]+)/)
  577. assert m
  578. password = m[1]
  579. assert u.check_password?(password)
  580. end
  581. def test_update_without_generate_password_should_not_change_password
  582. put(
  583. :update,
  584. :params => {
  585. :id => 2,
  586. :user => {
  587. :firstname => 'changed',
  588. :generate_password => '0',
  589. :password => '',
  590. :password_confirmation => ''
  591. },
  592. :send_information => '1'
  593. }
  594. )
  595. user = User.find(2)
  596. assert_equal 'changed', user.firstname
  597. assert user.check_password?('jsmith')
  598. end
  599. def test_update_user_switchin_from_auth_source_to_password_authentication
  600. # Configure as auth source
  601. u = User.find(2)
  602. u.auth_source = AuthSource.find(1)
  603. u.save!
  604. put :update, :params => {
  605. :id => u.id,
  606. :user => {:auth_source_id => '', :password => 'newpass123', :password_confirmation => 'newpass123'}
  607. }
  608. assert_nil u.reload.auth_source
  609. assert u.check_password?('newpass123')
  610. end
  611. def test_update_notified_project
  612. get :edit, :params => {:id => 2}
  613. assert_response :success
  614. u = User.find(2)
  615. assert_equal [1, 2, 5], u.projects.collect{|p| p.id}.sort
  616. assert_equal [1, 2, 5], u.notified_projects_ids.sort
  617. assert_select 'input[name=?][value=?]', 'user[notified_project_ids][]', '1'
  618. assert_equal 'all', u.mail_notification
  619. put :update, :params => {
  620. :id => 2,
  621. :user => {
  622. :mail_notification => 'selected',
  623. :notified_project_ids => [1, 2]
  624. }
  625. }
  626. u = User.find(2)
  627. assert_equal 'selected', u.mail_notification
  628. assert_equal [1, 2], u.notified_projects_ids.sort
  629. end
  630. def test_update_status_should_not_update_attributes
  631. user = User.find(2)
  632. user.pref[:no_self_notified] = '1'
  633. user.pref.save
  634. put :update, :params => {
  635. :id => 2,
  636. :user => {:status => 3}
  637. }
  638. assert_response 302
  639. user = User.find(2)
  640. assert_equal 3, user.status
  641. assert_equal '1', user.pref[:no_self_notified]
  642. end
  643. def test_update_assign_admin_should_send_security_notification
  644. ActionMailer::Base.deliveries.clear
  645. put :update, :params => {
  646. :id => 2,
  647. :user => {:admin => 1}
  648. }
  649. assert_not_nil (mail = ActionMailer::Base.deliveries.last)
  650. assert_mail_body_match(
  651. I18n.t(
  652. :mail_body_security_notification_add,
  653. field: I18n.t(:field_admin),
  654. value: User.find(2).login
  655. ),
  656. mail
  657. )
  658. # All admins should receive this
  659. User.where(admin: true, status: Principal::STATUS_ACTIVE).each do |admin|
  660. assert_not_nil(
  661. ActionMailer::Base.deliveries.detect do |mail|
  662. [mail.to].flatten.include?(admin.mail)
  663. end
  664. )
  665. end
  666. end
  667. def test_update_unassign_admin_should_send_security_notification
  668. user = User.find(2)
  669. user.admin = true
  670. user.save!
  671. ActionMailer::Base.deliveries.clear
  672. put :update, :params => {
  673. :id => user.id,
  674. :user => {:admin => 0}
  675. }
  676. assert_not_nil (mail = ActionMailer::Base.deliveries.last)
  677. assert_mail_body_match(
  678. I18n.t(
  679. :mail_body_security_notification_remove,
  680. field: I18n.t(:field_admin),
  681. value: user.login
  682. ),
  683. mail
  684. )
  685. # All admins should receive this
  686. User.where(admin: true, status: Principal::STATUS_ACTIVE).each do |admin|
  687. assert_not_nil(
  688. ActionMailer::Base.deliveries.detect do |mail|
  689. [mail.to].flatten.include?(admin.mail)
  690. end
  691. )
  692. end
  693. end
  694. def test_update_lock_admin_should_send_security_notification
  695. user = User.find(2)
  696. user.admin = true
  697. user.save!
  698. ActionMailer::Base.deliveries.clear
  699. put :update, :params => {
  700. :id => 2,
  701. :user => {:status => Principal::STATUS_LOCKED}
  702. }
  703. assert_not_nil (mail = ActionMailer::Base.deliveries.last)
  704. assert_mail_body_match(
  705. I18n.t(
  706. :mail_body_security_notification_remove,
  707. field: I18n.t(:field_admin),
  708. value: User.find(2).login
  709. ),
  710. mail
  711. )
  712. # All admins should receive this
  713. User.where(admin: true, status: Principal::STATUS_ACTIVE).each do |admin|
  714. assert_not_nil(
  715. ActionMailer::Base.deliveries.detect do |mail|
  716. [mail.to].flatten.include?(admin.mail)
  717. end
  718. )
  719. end
  720. # if user is already locked, destroying should not send a second mail
  721. # (for active admins see furtherbelow)
  722. ActionMailer::Base.deliveries.clear
  723. delete :destroy, :params => {:id => 1, :confirm => User.find(1).login}
  724. assert_nil ActionMailer::Base.deliveries.last
  725. end
  726. def test_update_unlock_admin_should_send_security_notification
  727. user = User.find(5) # already locked
  728. user.admin = true
  729. user.save!
  730. ActionMailer::Base.deliveries.clear
  731. put :update, :params => {
  732. :id => user.id,
  733. :user => {:status => Principal::STATUS_ACTIVE}
  734. }
  735. assert_not_nil (mail = ActionMailer::Base.deliveries.last)
  736. assert_mail_body_match(
  737. I18n.t(
  738. :mail_body_security_notification_add,
  739. field: I18n.t(:field_admin),
  740. value: user.login
  741. ),
  742. mail
  743. )
  744. # All admins should receive this
  745. User.where(admin: true, status: Principal::STATUS_ACTIVE).each do |admin|
  746. assert_not_nil(
  747. ActionMailer::Base.deliveries.detect do |mail|
  748. [mail.to].flatten.include?(admin.mail)
  749. end
  750. )
  751. end
  752. end
  753. def test_update_admin_unrelated_property_should_not_send_security_notification
  754. ActionMailer::Base.deliveries.clear
  755. put :update, :params => {
  756. :id => 1,
  757. :user => {:firstname => 'Jimmy'}
  758. }
  759. assert_nil ActionMailer::Base.deliveries.last
  760. end
  761. def test_update_should_be_denied_for_anonymous
  762. assert User.find(6).anonymous?
  763. put :update, :params => {:id => 6}
  764. assert_response 404
  765. end
  766. def test_update_with_blank_email_should_not_raise_exception
  767. assert_no_difference 'User.count' do
  768. with_settings :gravatar_enabled => '1' do
  769. put :update, :params => {
  770. :id => 2,
  771. :user => {:mail => ''}
  772. }
  773. end
  774. end
  775. assert_response :success
  776. assert_select_error /Email cannot be blank/
  777. end
  778. def test_destroy
  779. assert_difference 'User.count', -1 do
  780. delete :destroy, :params => {:id => 2, :confirm => User.find(2).login}
  781. end
  782. assert_redirected_to '/users'
  783. assert_nil User.find_by_id(2)
  784. end
  785. def test_destroy_with_lock_param_should_lock_instead
  786. assert_no_difference 'User.count' do
  787. delete :destroy, :params => {:id => 2, :lock => 'lock'}
  788. end
  789. assert_redirected_to '/users'
  790. assert User.find_by_id(2).locked?
  791. end
  792. def test_destroy_should_require_confirmation
  793. assert_no_difference 'User.count' do
  794. delete :destroy, :params => {:id => 2}
  795. end
  796. assert_response :success
  797. assert_select '.warning', :text => /Are you sure you want to delete this user/
  798. end
  799. def test_destroy_should_require_correct_confirmation
  800. assert_no_difference 'User.count' do
  801. delete :destroy, :params => {:id => 2, :confirm => 'wrong'}
  802. end
  803. assert_response :success
  804. assert_select '.warning', :text => /Are you sure you want to delete this user/
  805. end
  806. def test_destroy_should_be_denied_for_non_admin_users
  807. @request.session[:user_id] = 3
  808. assert_no_difference 'User.count' do
  809. delete :destroy, :params => {:id => 2, :confirm => User.find(2).login}
  810. end
  811. assert_response 403
  812. end
  813. def test_destroy_should_be_denied_for_anonymous
  814. assert User.find(6).anonymous?
  815. assert_no_difference 'User.count' do
  816. delete :destroy, :params => {:id => 6, :confirm => User.find(6).login}
  817. end
  818. assert_response 404
  819. end
  820. def test_destroy_should_redirect_to_back_url_param
  821. assert_difference 'User.count', -1 do
  822. delete :destroy, :params => {:id => 2,
  823. :confirm => User.find(2).login,
  824. :back_url => '/users?name=foo'}
  825. end
  826. assert_redirected_to '/users?name=foo'
  827. end
  828. def test_destroy_active_admin_should_send_security_notification
  829. user = User.find(2)
  830. user.admin = true
  831. user.save!
  832. ActionMailer::Base.deliveries.clear
  833. delete :destroy, :params => {:id => user.id, :confirm => user.login}
  834. assert_not_nil (mail = ActionMailer::Base.deliveries.last)
  835. assert_mail_body_match(
  836. I18n.t(
  837. :mail_body_security_notification_remove,
  838. field: I18n.t(:field_admin),
  839. value: user.login
  840. ),
  841. mail
  842. )
  843. # All admins should receive this
  844. User.where(admin: true, status: Principal::STATUS_ACTIVE).each do |admin|
  845. assert_not_nil(
  846. ActionMailer::Base.deliveries.detect do |mail|
  847. [mail.to].flatten.include?(admin.mail)
  848. end
  849. )
  850. end
  851. end
  852. def test_destroy_without_unsubscribe_is_denied
  853. user = User.find(2)
  854. user.update(admin: true) # Create other admin so self can be deleted
  855. @request.session[:user_id] = user.id
  856. with_settings unsubscribe: 0 do
  857. assert_no_difference 'User.count' do
  858. delete :destroy, params: {id: user.id}
  859. end
  860. assert_response 422
  861. end
  862. end
  863. def test_destroy_last_admin_is_denied
  864. user = User.find(1)
  865. @request.session[:user_id] = user.id
  866. with_settings unsubscribe: 1 do
  867. assert_no_difference 'User.count' do
  868. delete :destroy, params: {id: user.id}
  869. end
  870. assert_response 422
  871. end
  872. end
  873. end