PageRenderTime 90ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/spec/features/admin/admin_users_spec.rb

https://gitlab.com/habukagumba/gitlab-ce
Ruby | 510 lines | 386 code | 124 blank | 0 comment | 0 complexity | 5cc6a6596b430b83f274e8296ffde6e9 MD5 | raw file
  1. require 'spec_helper'
  2. describe "Admin::Users" do
  3. let!(:user) do
  4. create(:omniauth_user, provider: 'twitter', extern_uid: '123456')
  5. end
  6. let!(:current_user) { create(:admin) }
  7. before do
  8. sign_in(current_user)
  9. end
  10. describe "GET /admin/users" do
  11. before do
  12. visit admin_users_path
  13. end
  14. it "is ok" do
  15. expect(current_path).to eq(admin_users_path)
  16. end
  17. it "has users list" do
  18. expect(page).to have_content(current_user.email)
  19. expect(page).to have_content(current_user.name)
  20. expect(page).to have_content(user.email)
  21. expect(page).to have_content(user.name)
  22. expect(page).to have_link('Block', href: block_admin_user_path(user))
  23. expect(page).to have_button('Delete user')
  24. expect(page).to have_button('Delete user and contributions')
  25. end
  26. describe 'Two-factor Authentication filters' do
  27. it 'counts users who have enabled 2FA' do
  28. create(:user, :two_factor)
  29. visit admin_users_path
  30. page.within('.filter-two-factor-enabled small') do
  31. expect(page).to have_content('1')
  32. end
  33. end
  34. it 'filters by users who have enabled 2FA' do
  35. user = create(:user, :two_factor)
  36. visit admin_users_path
  37. click_link '2FA Enabled'
  38. expect(page).to have_content(user.email)
  39. end
  40. it 'counts users who have not enabled 2FA' do
  41. visit admin_users_path
  42. page.within('.filter-two-factor-disabled small') do
  43. expect(page).to have_content('2') # Including admin
  44. end
  45. end
  46. it 'filters by users who have not enabled 2FA' do
  47. visit admin_users_path
  48. click_link '2FA Disabled'
  49. expect(page).to have_content(user.email)
  50. end
  51. end
  52. end
  53. describe "GET /admin/users/new" do
  54. let(:user_username) { 'bang' }
  55. before do
  56. visit new_admin_user_path
  57. fill_in "user_name", with: "Big Bang"
  58. fill_in "user_username", with: user_username
  59. fill_in "user_email", with: "bigbang@mail.com"
  60. end
  61. it "creates new user" do
  62. expect { click_button "Create user" }.to change {User.count}.by(1)
  63. end
  64. it "applies defaults to user" do
  65. click_button "Create user"
  66. user = User.find_by(username: 'bang')
  67. expect(user.projects_limit)
  68. .to eq(Gitlab.config.gitlab.default_projects_limit)
  69. expect(user.can_create_group)
  70. .to eq(Gitlab.config.gitlab.default_can_create_group)
  71. end
  72. it "creates user with valid data" do
  73. click_button "Create user"
  74. user = User.find_by(username: 'bang')
  75. expect(user.name).to eq('Big Bang')
  76. expect(user.email).to eq('bigbang@mail.com')
  77. end
  78. it "calls send mail" do
  79. expect_any_instance_of(NotificationService).to receive(:new_user)
  80. click_button "Create user"
  81. end
  82. it "sends valid email to user with email & password" do
  83. perform_enqueued_jobs do
  84. click_button "Create user"
  85. end
  86. user = User.find_by(username: 'bang')
  87. email = ActionMailer::Base.deliveries.last
  88. expect(email.subject).to have_content('Account was created')
  89. expect(email.text_part.body).to have_content(user.email)
  90. expect(email.text_part.body).to have_content('password')
  91. end
  92. context 'username contains spaces' do
  93. let(:user_username) { 'Bing bang' }
  94. it "doesn't create the user and shows an error message" do
  95. expect { click_button "Create user" }.to change {User.count}.by(0)
  96. expect(page).to have_content('The form contains the following error')
  97. expect(page).to have_content('Username can contain only letters, digits')
  98. end
  99. end
  100. context 'with new users set to external enabled' do
  101. context 'with regex to match internal user email address set', :js do
  102. before do
  103. stub_application_setting(user_default_external: true)
  104. stub_application_setting(user_default_internal_regex: '.internal@')
  105. visit new_admin_user_path
  106. end
  107. def expects_external_to_be_checked
  108. expect(find('#user_external')).to be_checked
  109. end
  110. def expects_external_to_be_unchecked
  111. expect(find('#user_external')).not_to be_checked
  112. end
  113. def expects_warning_to_be_hidden
  114. expect(find('#warning_external_automatically_set', visible: :all)[:class]).to include 'hidden'
  115. end
  116. def expects_warning_to_be_shown
  117. expect(find('#warning_external_automatically_set')[:class]).not_to include 'hidden'
  118. end
  119. it 'automatically unchecks external for matching email' do
  120. expects_external_to_be_checked
  121. expects_warning_to_be_hidden
  122. fill_in 'user_email', with: 'test.internal@domain.ch'
  123. expects_external_to_be_unchecked
  124. expects_warning_to_be_shown
  125. fill_in 'user_email', with: 'test@domain.ch'
  126. expects_external_to_be_checked
  127. expects_warning_to_be_hidden
  128. uncheck 'user_external'
  129. expects_warning_to_be_hidden
  130. end
  131. end
  132. end
  133. end
  134. describe "GET /admin/users/:id" do
  135. it "has user info" do
  136. visit admin_users_path
  137. click_link user.name
  138. expect(page).to have_content(user.email)
  139. expect(page).to have_content(user.name)
  140. expect(page).to have_content(user.id)
  141. expect(page).to have_link('Block user', href: block_admin_user_path(user))
  142. expect(page).to have_button('Delete user')
  143. expect(page).to have_button('Delete user and contributions')
  144. end
  145. describe 'Impersonation' do
  146. let(:another_user) { create(:user) }
  147. before do
  148. visit admin_user_path(another_user)
  149. end
  150. context 'before impersonating' do
  151. it 'shows impersonate button for other users' do
  152. expect(page).to have_content('Impersonate')
  153. end
  154. it 'does not show impersonate button for admin itself' do
  155. visit admin_user_path(current_user)
  156. expect(page).not_to have_content('Impersonate')
  157. end
  158. it 'does not show impersonate button for blocked user' do
  159. another_user.block
  160. visit admin_user_path(another_user)
  161. expect(page).not_to have_content('Impersonate')
  162. another_user.activate
  163. end
  164. end
  165. context 'when impersonating' do
  166. before do
  167. click_link 'Impersonate'
  168. end
  169. it 'logs in as the user when impersonate is clicked' do
  170. expect(page.find(:css, '.header-user .profile-link')['data-user']).to eql(another_user.username)
  171. end
  172. it 'sees impersonation log out icon' do
  173. icon = first('.fa.fa-user-secret')
  174. expect(icon).not_to be nil
  175. end
  176. it 'logs out of impersonated user back to original user' do
  177. find(:css, 'li.impersonation a').click
  178. expect(page.find(:css, '.header-user .profile-link')['data-user']).to eq(current_user.username)
  179. end
  180. it 'is redirected back to the impersonated users page in the admin after stopping' do
  181. find(:css, 'li.impersonation a').click
  182. expect(current_path).to eq("/admin/users/#{another_user.username}")
  183. end
  184. end
  185. context 'when impersonating a user with an expired password' do
  186. before do
  187. another_user.update(password_expires_at: Time.now - 5.minutes)
  188. click_link 'Impersonate'
  189. end
  190. it 'does not redirect to password change page' do
  191. expect(current_path).to eq('/')
  192. end
  193. it 'is redirected back to the impersonated users page in the admin after stopping' do
  194. find(:css, 'li.impersonation a').click
  195. expect(current_path).to eq("/admin/users/#{another_user.username}")
  196. end
  197. end
  198. end
  199. describe 'Two-factor Authentication status' do
  200. it 'shows when enabled' do
  201. user.update_attribute(:otp_required_for_login, true)
  202. visit admin_user_path(user)
  203. expect_two_factor_status('Enabled')
  204. end
  205. it 'shows when disabled' do
  206. visit admin_user_path(user)
  207. expect_two_factor_status('Disabled')
  208. end
  209. def expect_two_factor_status(status)
  210. page.within('.two-factor-status') do
  211. expect(page).to have_content(status)
  212. end
  213. end
  214. end
  215. end
  216. describe "GET /admin/users/:id/edit" do
  217. before do
  218. visit admin_users_path
  219. click_link "edit_user_#{user.id}"
  220. end
  221. it "has user edit page" do
  222. expect(page).to have_content('Name')
  223. expect(page).to have_content('Password')
  224. end
  225. describe "Update user" do
  226. before do
  227. fill_in "user_name", with: "Big Bang"
  228. fill_in "user_email", with: "bigbang@mail.com"
  229. fill_in "user_password", with: "AValidPassword1"
  230. fill_in "user_password_confirmation", with: "AValidPassword1"
  231. choose "user_access_level_admin"
  232. click_button "Save changes"
  233. end
  234. it "shows page with new data" do
  235. expect(page).to have_content('bigbang@mail.com')
  236. expect(page).to have_content('Big Bang')
  237. end
  238. it "changes user entry" do
  239. user.reload
  240. expect(user.name).to eq('Big Bang')
  241. expect(user.admin?).to be_truthy
  242. expect(user.password_expires_at).to be <= Time.now
  243. end
  244. end
  245. describe 'update username to non ascii char' do
  246. it do
  247. fill_in 'user_username', with: '\u3042\u3044'
  248. click_button('Save')
  249. page.within '#error_explanation' do
  250. expect(page).to have_content('Username')
  251. end
  252. expect(page).to have_selector(%(form[action="/admin/users/#{user.username}"]))
  253. end
  254. end
  255. end
  256. describe "GET /admin/users/:id/projects" do
  257. let(:group) { create(:group) }
  258. let!(:project) { create(:project, group: group) }
  259. before do
  260. group.add_developer(user)
  261. visit projects_admin_user_path(user)
  262. end
  263. it "lists group projects" do
  264. within(:css, '.append-bottom-default + .card') do
  265. expect(page).to have_content 'Group projects'
  266. expect(page).to have_link group.name, href: admin_group_path(group)
  267. end
  268. end
  269. it 'allows navigation to the group details' do
  270. within(:css, '.append-bottom-default + .card') do
  271. click_link group.name
  272. end
  273. within(:css, 'h3.page-title') do
  274. expect(page).to have_content "Group: #{group.name}"
  275. end
  276. expect(page).to have_content project.name
  277. end
  278. it 'shows the group access level' do
  279. within(:css, '.append-bottom-default + .card') do
  280. expect(page).to have_content 'Developer'
  281. end
  282. end
  283. it 'allows group membership to be revoked', :js do
  284. page.within(first('.group_member')) do
  285. accept_confirm { find('.btn-remove').click }
  286. end
  287. wait_for_requests
  288. expect(page).not_to have_selector('.group_member')
  289. end
  290. end
  291. describe 'show breadcrumbs' do
  292. it do
  293. visit admin_user_path(user)
  294. check_breadcrumb(user.name)
  295. visit projects_admin_user_path(user)
  296. check_breadcrumb(user.name)
  297. visit keys_admin_user_path(user)
  298. check_breadcrumb(user.name)
  299. visit admin_user_impersonation_tokens_path(user)
  300. check_breadcrumb(user.name)
  301. visit admin_user_identities_path(user)
  302. check_breadcrumb(user.name)
  303. visit new_admin_user_identity_path(user)
  304. check_breadcrumb("New Identity")
  305. visit admin_user_identities_path(user)
  306. find('.table').find(:link, 'Edit').click
  307. check_breadcrumb("Edit Identity")
  308. end
  309. end
  310. describe 'show user attributes' do
  311. it do
  312. visit admin_users_path
  313. click_link user.name
  314. expect(page).to have_content 'Account'
  315. expect(page).to have_content 'Personal projects limit'
  316. end
  317. end
  318. describe 'remove users secondary email', :js do
  319. let!(:secondary_email) do
  320. create :email, email: 'secondary@example.com', user: user
  321. end
  322. it do
  323. visit admin_user_path(user.username)
  324. expect(page).to have_content("Secondary email: #{secondary_email.email}")
  325. accept_confirm { find("#remove_email_#{secondary_email.id}").click }
  326. expect(page).not_to have_content(secondary_email.email)
  327. end
  328. end
  329. describe 'show user keys' do
  330. let!(:key1) do
  331. create(:key, user: user, title: "ssh-rsa Key1", key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC4FIEBXGi4bPU8kzxMefudPIJ08/gNprdNTaO9BR/ndy3+58s2HCTw2xCHcsuBmq+TsAqgEidVq4skpqoTMB+Uot5Uzp9z4764rc48dZiI661izoREoKnuRQSsRqUTHg5wrLzwxlQbl1MVfRWQpqiz/5KjBC7yLEb9AbusjnWBk8wvC1bQPQ1uLAauEA7d836tgaIsym9BrLsMVnR4P1boWD3Xp1B1T/ImJwAGHvRmP/ycIqmKdSpMdJXwxcb40efWVj0Ibbe7ii9eeoLdHACqevUZi6fwfbymdow+FeqlkPoHyGg3Cu4vD/D8+8cRc7mE/zGCWcQ15Var83Tczour Key1")
  332. end
  333. let!(:key2) do
  334. create(:key, user: user, title: "ssh-rsa Key2", key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDQSTWXhJAX/He+nG78MiRRRn7m0Pb0XbcgTxE0etArgoFoh9WtvDf36HG6tOSg/0UUNcp0dICsNAmhBKdncp6cIyPaXJTURPRAGvhI0/VDk4bi27bRnccGbJ/hDaUxZMLhhrzY0r22mjVf8PF6dvv5QUIQVm1/LeaWYsHHvLgiIjwrXirUZPnFrZw6VLREoBKG8uWvfSXw1L5eapmstqfsME8099oi+vWLR8MgEysZQmD28M73fgW4zek6LDQzKQyJx9nB+hJkKUDvcuziZjGmRFlNgSA2mguERwL1OXonD8WYUrBDGKroIvBT39zS5d9tQDnidEJZ9Y8gv5ViYP7x Key2")
  335. end
  336. it do
  337. visit admin_users_path
  338. click_link user.name
  339. click_link 'SSH keys'
  340. expect(page).to have_content(key1.title)
  341. expect(page).to have_content(key2.title)
  342. click_link key2.title
  343. expect(page).to have_content(key2.title)
  344. expect(page).to have_content(key2.key)
  345. click_link 'Remove'
  346. expect(page).not_to have_content(key2.title)
  347. end
  348. end
  349. describe 'show user identities' do
  350. it 'shows user identities' do
  351. visit admin_user_identities_path(user)
  352. expect(page).to have_content(user.name)
  353. expect(page).to have_content('twitter')
  354. end
  355. end
  356. describe 'update user identities' do
  357. before do
  358. allow(Gitlab::Auth::OAuth::Provider).to receive(:providers).and_return([:twitter, :twitter_updated])
  359. end
  360. it 'modifies twitter identity' do
  361. visit admin_user_identities_path(user)
  362. find('.table').find(:link, 'Edit').click
  363. fill_in 'identity_extern_uid', with: '654321'
  364. select 'twitter_updated', from: 'identity_provider'
  365. click_button 'Save changes'
  366. expect(page).to have_content(user.name)
  367. expect(page).to have_content('twitter_updated')
  368. expect(page).to have_content('654321')
  369. end
  370. end
  371. describe 'remove user with identities' do
  372. it 'removes user with twitter identity' do
  373. visit admin_user_identities_path(user)
  374. click_link 'Delete'
  375. expect(page).to have_content(user.name)
  376. expect(page).not_to have_content('twitter')
  377. end
  378. end
  379. def check_breadcrumb(content)
  380. expect(find('.breadcrumbs-sub-title')).to have_content(content)
  381. end
  382. end