3889: minor test assertion updates
[arvados.git] / services / api / test / functional / arvados / v1 / users_controller_test.rb
1 require 'test_helper'
2
3 class Arvados::V1::UsersControllerTest < ActionController::TestCase
4   include CurrentApiClient
5
6   setup do
7     @all_links_at_start = Link.all
8     @vm_uuid = virtual_machines(:testvm).uuid
9   end
10
11   test "activate a user after signing UA" do
12     authorize_with :inactive_but_signed_user_agreement
13     post :activate, id: users(:inactive_but_signed_user_agreement).uuid
14     assert_response :success
15     assert_not_nil assigns(:object)
16     me = JSON.parse(@response.body)
17     assert_equal true, me['is_active']
18   end
19
20   test "refuse to activate a user before signing UA" do
21     act_as_system_user do
22     required_uuids = Link.where("owner_uuid = ? and link_class = ? and name = ? and tail_uuid = ? and head_uuid like ?",
23                                 system_user_uuid,
24                                 'signature',
25                                 'require',
26                                 system_user_uuid,
27                                 Collection.uuid_like_pattern).
28       collect(&:head_uuid)
29
30       assert required_uuids.length > 0
31
32       signed_uuids = Link.where(owner_uuid: system_user_uuid,
33                                 link_class: 'signature',
34                                 name: 'click',
35                                 tail_uuid: users(:inactive).uuid,
36                                 head_uuid: required_uuids).
37                           collect(&:head_uuid)
38
39       assert_equal 0, signed_uuids.length
40     end
41
42     authorize_with :inactive
43     assert_equal false, users(:inactive).is_active
44
45     post :activate, id: users(:inactive).uuid
46     assert_response 403
47
48     resp = json_response
49     assert resp['errors'].first.include? 'Cannot activate without user agreements'
50     assert_nil resp['is_active']
51   end
52
53   test "activate an already-active user" do
54     authorize_with :active
55     post :activate, id: users(:active).uuid
56     assert_response :success
57     me = JSON.parse(@response.body)
58     assert_equal true, me['is_active']
59   end
60
61   test "respond 401 if given token exists but user record is missing" do
62     authorize_with :valid_token_deleted_user
63     get :current, {format: :json}
64     assert_response 401
65   end
66
67   test "create new user with user as input" do
68     authorize_with :admin
69     post :create, user: {
70       first_name: "test_first_name",
71       last_name: "test_last_name",
72       email: "foo@example.com"
73     }
74     assert_response :success
75     created = JSON.parse(@response.body)
76     assert_equal 'test_first_name', created['first_name']
77     assert_not_nil created['uuid'], 'expected uuid for the newly created user'
78     assert_not_nil created['email'], 'expected non-nil email'
79     assert_nil created['identity_url'], 'expected no identity_url'
80   end
81
82   test "create user with user, vm and repo as input" do
83     authorize_with :admin
84     repo_name = 'test_repo'
85
86     post :setup, {
87       repo_name: repo_name,
88       openid_prefix: 'https://www.google.com/accounts/o8/id',
89       user: {
90         uuid: 'zzzzz-tpzed-abcdefghijklmno',
91         first_name: "in_create_test_first_name",
92         last_name: "test_last_name",
93         email: "foo@example.com"
94       }
95     }
96     assert_response :success
97     response_items = JSON.parse(@response.body)['items']
98
99     created = find_obj_in_resp response_items, 'User', nil
100
101     assert_equal 'in_create_test_first_name', created['first_name']
102     assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
103     assert_equal 'zzzzz-tpzed-abcdefghijklmno', created['uuid']
104     assert_not_nil created['email'], 'expected non-nil email'
105     assert_nil created['identity_url'], 'expected no identity_url'
106
107     # arvados#user, repo link and link add user to 'All users' group
108     verify_num_links @all_links_at_start, 4
109
110     verify_link response_items, 'arvados#user', true, 'permission', 'can_login',
111         created['uuid'], created['email'], 'arvados#user', false, 'User'
112
113     verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
114         repo_name, created['uuid'], 'arvados#repository', true, 'Repository'
115
116     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
117         'All users', created['uuid'], 'arvados#group', true, 'Group'
118
119     verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
120         nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
121
122     verify_system_group_permission_link_for created['uuid']
123   end
124
125   test "setup user with bogus uuid and expect error" do
126     authorize_with :admin
127
128     post :setup, {
129       uuid: 'bogus_uuid',
130       repo_name: 'test_repo',
131       vm_uuid: @vm_uuid
132     }
133     response_body = JSON.parse(@response.body)
134     response_errors = response_body['errors']
135     assert_not_nil response_errors, 'Expected error in response'
136     assert (response_errors.first.include? 'Path not found'), 'Expected 404'
137   end
138
139   test "setup user with bogus uuid in user and expect error" do
140     authorize_with :admin
141
142     post :setup, {
143       user: {uuid: 'bogus_uuid'},
144       repo_name: 'test_repo',
145       vm_uuid: @vm_uuid,
146       openid_prefix: 'https://www.google.com/accounts/o8/id'
147     }
148     response_body = JSON.parse(@response.body)
149     response_errors = response_body['errors']
150     assert_not_nil response_errors, 'Expected error in response'
151     assert (response_errors.first.include? 'ArgumentError: Require user email'),
152       'Expected RuntimeError'
153   end
154
155   test "setup user with no uuid and user, expect error" do
156     authorize_with :admin
157
158     post :setup, {
159       repo_name: 'test_repo',
160       vm_uuid: @vm_uuid,
161       openid_prefix: 'https://www.google.com/accounts/o8/id'
162     }
163     response_body = JSON.parse(@response.body)
164     response_errors = response_body['errors']
165     assert_not_nil response_errors, 'Expected error in response'
166     assert (response_errors.first.include? 'Required uuid or user'),
167         'Expected ArgumentError'
168   end
169
170   test "setup user with no uuid and email, expect error" do
171     authorize_with :admin
172
173     post :setup, {
174       user: {},
175       repo_name: 'test_repo',
176       vm_uuid: @vm_uuid,
177       openid_prefix: 'https://www.google.com/accounts/o8/id'
178     }
179     response_body = JSON.parse(@response.body)
180     response_errors = response_body['errors']
181     assert_not_nil response_errors, 'Expected error in response'
182     assert (response_errors.first.include? '<ArgumentError: Require user email'),
183         'Expected ArgumentError'
184   end
185
186   test "invoke setup with existing uuid, vm and repo and verify links" do
187     authorize_with :admin
188     inactive_user = users(:inactive)
189
190     post :setup, {
191       uuid: users(:inactive).uuid,
192       repo_name: 'test_repo',
193       vm_uuid: @vm_uuid
194     }
195
196     assert_response :success
197
198     response_items = JSON.parse(@response.body)['items']
199     resp_obj = find_obj_in_resp response_items, 'User', nil
200
201     assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
202     assert_equal inactive_user['uuid'], resp_obj['uuid']
203     assert_equal inactive_user['email'], resp_obj['email'],
204         'expecting inactive user email'
205
206     # expect repo and vm links
207     verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
208         'test_repo', resp_obj['uuid'], 'arvados#repository', true, 'Repository'
209
210     verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
211         @vm_uuid, resp_obj['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
212   end
213
214   test "invoke setup with existing uuid in user, verify response" do
215     authorize_with :admin
216     inactive_user = users(:inactive)
217
218     post :setup, {
219       user: {uuid: inactive_user['uuid']},
220       openid_prefix: 'https://www.google.com/accounts/o8/id'
221     }
222
223     assert_response :success
224
225     response_items = JSON.parse(@response.body)['items']
226     resp_obj = find_obj_in_resp response_items, 'User', nil
227
228     assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
229     assert_equal inactive_user['uuid'], resp_obj['uuid']
230     assert_equal inactive_user['email'], resp_obj['email'],
231         'expecting inactive user email'
232   end
233
234   test "invoke setup with existing uuid but different email, expect original email" do
235     authorize_with :admin
236     inactive_user = users(:inactive)
237
238     post :setup, {
239       uuid: inactive_user['uuid'],
240       user: {email: 'junk_email'}
241     }
242
243     assert_response :success
244
245     response_items = JSON.parse(@response.body)['items']
246     resp_obj = find_obj_in_resp response_items, 'User', nil
247
248     assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
249     assert_equal inactive_user['uuid'], resp_obj['uuid']
250     assert_equal inactive_user['email'], resp_obj['email'],
251         'expecting inactive user email'
252   end
253
254   test "setup user with valid email and repo as input" do
255     authorize_with :admin
256
257     post :setup, {
258       repo_name: 'test_repo',
259       user: {email: 'foo@example.com'},
260       openid_prefix: 'https://www.google.com/accounts/o8/id'
261     }
262
263     assert_response :success
264     response_items = JSON.parse(@response.body)['items']
265     response_object = find_obj_in_resp response_items, 'User', nil
266     assert_not_nil response_object['uuid'], 'expected uuid for the new user'
267     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
268
269     # four extra links; system_group, login, group and repo perms
270     verify_num_links @all_links_at_start, 4
271   end
272
273   test "setup user with fake vm and expect error" do
274     authorize_with :admin
275
276     post :setup, {
277       repo_name: 'test_repo',
278       vm_uuid: 'no_such_vm',
279       user: {email: 'foo@example.com'},
280       openid_prefix: 'https://www.google.com/accounts/o8/id'
281     }
282
283     response_body = JSON.parse(@response.body)
284     response_errors = response_body['errors']
285     assert_not_nil response_errors, 'Expected error in response'
286     assert (response_errors.first.include? "No vm found for no_such_vm"),
287           'Expected RuntimeError: No vm found for no_such_vm'
288   end
289
290   test "setup user with valid email, repo and real vm as input" do
291     authorize_with :admin
292
293     post :setup, {
294       repo_name: 'test_repo',
295       openid_prefix: 'https://www.google.com/accounts/o8/id',
296       vm_uuid: @vm_uuid,
297       user: {email: 'foo@example.com'}
298     }
299
300     assert_response :success
301     response_items = JSON.parse(@response.body)['items']
302     response_object = find_obj_in_resp response_items, 'User', nil
303     assert_not_nil response_object['uuid'], 'expected uuid for the new user'
304     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
305
306     # five extra links; system_group, login, group, vm, repo
307     verify_num_links @all_links_at_start, 5
308   end
309
310   test "setup user with valid email, no vm and no repo as input" do
311     authorize_with :admin
312
313     post :setup, {
314       user: {email: 'foo@example.com'},
315       openid_prefix: 'https://www.google.com/accounts/o8/id'
316     }
317
318     assert_response :success
319     response_items = JSON.parse(@response.body)['items']
320     response_object = find_obj_in_resp response_items, 'User', nil
321     assert_not_nil response_object['uuid'], 'expected uuid for new user'
322     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
323
324     # three extra links; system_group, login, and group
325     verify_num_links @all_links_at_start, 3
326
327     verify_link response_items, 'arvados#user', true, 'permission', 'can_login',
328         response_object['uuid'], response_object['email'], 'arvados#user', false, 'User'
329
330     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
331         'All users', response_object['uuid'], 'arvados#group', true, 'Group'
332
333     verify_link response_items, 'arvados#repository', false, 'permission', 'can_manage',
334         'test_repo', response_object['uuid'], 'arvados#repository', true, 'Repository'
335
336     verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
337         nil, response_object['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
338   end
339
340   test "setup user with email, first name, repo name and vm uuid" do
341     authorize_with :admin
342
343     post :setup, {
344       openid_prefix: 'https://www.google.com/accounts/o8/id',
345       repo_name: 'test_repo',
346       vm_uuid: @vm_uuid,
347       user: {
348         first_name: 'test_first_name',
349         email: 'foo@example.com'
350       }
351     }
352
353     assert_response :success
354     response_items = JSON.parse(@response.body)['items']
355     response_object = find_obj_in_resp response_items, 'User', nil
356     assert_not_nil response_object['uuid'], 'expected uuid for new user'
357     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
358     assert_equal 'test_first_name', response_object['first_name'],
359         'expecting first name'
360
361     # five extra links; system_group, login, group, repo and vm
362     verify_num_links @all_links_at_start, 5
363   end
364
365   test "setup user with an existing user email and check different object is created" do
366     authorize_with :admin
367     inactive_user = users(:inactive)
368
369     post :setup, {
370       openid_prefix: 'https://www.google.com/accounts/o8/id',
371       repo_name: 'test_repo',
372       user: {
373         email: inactive_user['email']
374       }
375     }
376
377     assert_response :success
378     response_items = JSON.parse(@response.body)['items']
379     response_object = find_obj_in_resp response_items, 'User', nil
380     assert_not_nil response_object['uuid'], 'expected uuid for new user'
381     assert_not_equal response_object['uuid'], inactive_user['uuid'],
382         'expected different uuid after create operation'
383     assert_equal inactive_user['email'], response_object['email'], 'expected given email'
384     # system_group, openid, group, and repo. No vm link.
385     verify_num_links @all_links_at_start, 4
386   end
387
388   test "setup user with openid prefix" do
389     authorize_with :admin
390
391     post :setup, {
392       repo_name: 'test_repo',
393       openid_prefix: 'http://www.example.com/account',
394       user: {
395         first_name: "in_create_test_first_name",
396         last_name: "test_last_name",
397         email: "foo@example.com"
398       }
399     }
400
401     assert_response :success
402
403     response_items = JSON.parse(@response.body)['items']
404     created = find_obj_in_resp response_items, 'User', nil
405
406     assert_equal 'in_create_test_first_name', created['first_name']
407     assert_not_nil created['uuid'], 'expected uuid for new user'
408     assert_not_nil created['email'], 'expected non-nil email'
409     assert_nil created['identity_url'], 'expected no identity_url'
410
411     # verify links
412     # four new links: system_group, arvados#user, repo, and 'All users' group.
413     verify_num_links @all_links_at_start, 4
414
415     verify_link response_items, 'arvados#user', true, 'permission', 'can_login',
416         created['uuid'], created['email'], 'arvados#user', false, 'User'
417
418     verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
419         'test_repo', created['uuid'], 'arvados#repository', true, 'Repository'
420
421     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
422         'All users', created['uuid'], 'arvados#group', true, 'Group'
423
424     verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
425         nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
426   end
427
428   test "invoke setup with no openid prefix, expect error" do
429     authorize_with :admin
430
431     post :setup, {
432       repo_name: 'test_repo',
433       user: {
434         first_name: "in_create_test_first_name",
435         last_name: "test_last_name",
436         email: "foo@example.com"
437       }
438     }
439
440     response_body = JSON.parse(@response.body)
441     response_errors = response_body['errors']
442     assert_not_nil response_errors, 'Expected error in response'
443     assert (response_errors.first.include? 'openid_prefix parameter is missing'),
444         'Expected ArgumentError'
445   end
446
447   test "setup user with user, vm and repo and verify links" do
448     authorize_with :admin
449
450     post :setup, {
451       user: {
452         first_name: "in_create_test_first_name",
453         last_name: "test_last_name",
454         email: "foo@example.com"
455       },
456       vm_uuid: @vm_uuid,
457       repo_name: 'test_repo',
458       openid_prefix: 'https://www.google.com/accounts/o8/id'
459     }
460
461     assert_response :success
462
463     response_items = JSON.parse(@response.body)['items']
464     created = find_obj_in_resp response_items, 'User', nil
465
466     assert_equal 'in_create_test_first_name', created['first_name']
467     assert_not_nil created['uuid'], 'expected uuid for new user'
468     assert_not_nil created['email'], 'expected non-nil email'
469     assert_nil created['identity_url'], 'expected no identity_url'
470
471     # five new links: system_group, arvados#user, repo, vm and 'All
472     # users' group link
473     verify_num_links @all_links_at_start, 5
474
475     verify_link response_items, 'arvados#user', true, 'permission', 'can_login',
476         created['uuid'], created['email'], 'arvados#user', false, 'User'
477
478     verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
479         'test_repo', created['uuid'], 'arvados#repository', true, 'Repository'
480
481     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
482         'All users', created['uuid'], 'arvados#group', true, 'Group'
483
484     verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
485         @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
486   end
487
488   test "create user as non admin user and expect error" do
489     authorize_with :active
490
491     post :create, {
492       user: {email: 'foo@example.com'}
493     }
494
495     response_body = JSON.parse(@response.body)
496     response_errors = response_body['errors']
497     assert_not_nil response_errors, 'Expected error in response'
498     assert (response_errors.first.include? 'PermissionDenied'),
499           'Expected PermissionDeniedError'
500   end
501
502   test "setup user as non admin user and expect error" do
503     authorize_with :active
504
505     post :setup, {
506       openid_prefix: 'https://www.google.com/accounts/o8/id',
507       user: {email: 'foo@example.com'}
508     }
509
510     response_body = JSON.parse(@response.body)
511     response_errors = response_body['errors']
512     assert_not_nil response_errors, 'Expected error in response'
513     assert (response_errors.first.include? 'Forbidden'),
514           'Expected Forbidden error'
515   end
516
517   test "setup active user with repo and no vm" do
518     authorize_with :admin
519     active_user = users(:active)
520
521     # invoke setup with a repository
522     post :setup, {
523       repo_name: 'new_repo',
524       uuid: active_user['uuid']
525     }
526
527     assert_response :success
528
529     response_items = JSON.parse(@response.body)['items']
530     created = find_obj_in_resp response_items, 'User', nil
531
532     assert_equal active_user[:email], created['email'], 'expected input email'
533
534      # verify links
535     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
536         'All users', created['uuid'], 'arvados#group', true, 'Group'
537
538     verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
539         'new_repo', created['uuid'], 'arvados#repository', true, 'Repository'
540
541     verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
542         nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
543   end
544
545   test "setup active user with vm and no repo" do
546     authorize_with :admin
547     active_user = users(:active)
548
549     # invoke setup with a repository
550     post :setup, {
551       vm_uuid: @vm_uuid,
552       uuid: active_user['uuid'],
553       email: 'junk_email'
554     }
555
556     assert_response :success
557
558     response_items = JSON.parse(@response.body)['items']
559     created = find_obj_in_resp response_items, 'User', nil
560
561     assert_equal active_user['email'], created['email'], 'expected original email'
562
563     # verify links
564     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
565         'All users', created['uuid'], 'arvados#group', true, 'Group'
566
567     verify_link response_items, 'arvados#repository', false, 'permission', 'can_manage',
568         'new_repo', created['uuid'], 'arvados#repository', true, 'Repository'
569
570     verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
571         @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
572   end
573
574   test "unsetup active user" do
575     active_user = users(:active)
576     assert_not_nil active_user['uuid'], 'expected uuid for the active user'
577     assert active_user['is_active'], 'expected is_active for active user'
578
579     verify_link_existence active_user['uuid'], active_user['email'],
580           false, true, false, true, true
581
582     authorize_with :admin
583
584     # now unsetup this user
585     post :unsetup, id: active_user['uuid']
586     assert_response :success
587
588     response_user = JSON.parse(@response.body)
589     assert_not_nil response_user['uuid'], 'expected uuid for the upsetup user'
590     assert_equal active_user['uuid'], response_user['uuid'], 'expected uuid not found'
591     assert !response_user['is_active'], 'expected user to be inactive'
592     assert !response_user['is_invited'], 'expected user to be uninvited'
593
594     verify_link_existence response_user['uuid'], response_user['email'],
595           false, false, false, false, false
596
597     active_user = User.find_by_uuid(users(:active).uuid)
598     readable_groups = active_user.groups_i_can(:read)
599     all_users_group = Group.all.collect(&:uuid).select { |g| g.match /-f+$/ }
600     refute_includes(readable_groups, all_users_group,
601                     "active user can read All Users group after being deactivated")
602     assert_equal(false, active_user.is_invited,
603                  "active user is_invited after being deactivated & reloaded")
604   end
605
606   test "setup user with send notification param false and verify no email" do
607     authorize_with :admin
608
609     post :setup, {
610       openid_prefix: 'http://www.example.com/account',
611       send_notification_email: 'false',
612       user: {
613         email: "foo@example.com"
614       }
615     }
616
617     assert_response :success
618     response_items = JSON.parse(@response.body)['items']
619     created = find_obj_in_resp response_items, 'User', nil
620     assert_not_nil created['uuid'], 'expected uuid for the new user'
621     assert_equal created['email'], 'foo@example.com', 'expected given email'
622
623     setup_email = ActionMailer::Base.deliveries.last
624     assert_nil setup_email, 'expected no setup email'
625   end
626
627   test "setup user with send notification param true and verify email" do
628     authorize_with :admin
629
630     post :setup, {
631       openid_prefix: 'http://www.example.com/account',
632       send_notification_email: 'true',
633       user: {
634         email: "foo@example.com"
635       }
636     }
637
638     assert_response :success
639     response_items = JSON.parse(@response.body)['items']
640     created = find_obj_in_resp response_items, 'User', nil
641     assert_not_nil created['uuid'], 'expected uuid for the new user'
642     assert_equal created['email'], 'foo@example.com', 'expected given email'
643
644     setup_email = ActionMailer::Base.deliveries.last
645     assert_not_nil setup_email, 'Expected email after setup'
646
647     assert_equal Rails.configuration.user_notifier_email_from, setup_email.from[0]
648     assert_equal 'foo@example.com', setup_email.to[0]
649     assert_equal 'Welcome to Curoverse', setup_email.subject
650     assert (setup_email.body.to_s.include? 'Your Arvados account has been set up'),
651         'Expected Your Arvados account has been set up in email body'
652     assert (setup_email.body.to_s.include? 'foo@example.com'),
653         'Expected user email in email body'
654     assert (setup_email.body.to_s.include? Rails.configuration.workbench_address),
655         'Expected workbench url in email body'
656   end
657
658   test "non-admin user can get basic information about readable users" do
659     authorize_with :spectator
660     get(:index)
661     check_non_admin_index
662     check_readable_users_index [:spectator], [:inactive, :active]
663   end
664
665   test "non-admin user gets only safe attributes from users#show" do
666     g = act_as_system_user do
667       create :group
668     end
669     users = create_list :active_user, 2, join_groups: [g]
670     token = create :token, user: users[0]
671     authorize_with_token token
672     get :show, id: users[1].uuid
673     check_non_admin_show
674   end
675
676   [2, 4].each do |limit|
677     test "non-admin user can limit index to #{limit}" do
678       g = act_as_system_user do
679         create :group
680       end
681       users = create_list :active_user, 4, join_groups: [g]
682       token = create :token, user: users[0]
683
684       authorize_with_token token
685       get(:index, limit: limit)
686       check_non_admin_index
687       assert_equal(limit, json_response["items"].size,
688                    "non-admin index limit was ineffective")
689     end
690   end
691
692   test "admin has full index powers" do
693     authorize_with :admin
694     check_inactive_user_findable
695   end
696
697   test "reader token can grant admin index powers" do
698     authorize_with :spectator
699     check_inactive_user_findable(reader_tokens: [api_token(:admin)])
700   end
701
702   test "admin can filter on user.is_active" do
703     authorize_with :admin
704     get(:index, filters: [["is_active", "=", "true"]])
705     assert_response :success
706     check_readable_users_index [:active, :spectator], [:inactive]
707   end
708
709   test "admin can search where user.is_active" do
710     authorize_with :admin
711     get(:index, where: {is_active: true})
712     assert_response :success
713     check_readable_users_index [:active, :spectator], [:inactive]
714   end
715
716   test "update active_no_prefs user profile and expect notification email" do
717     authorize_with :admin
718
719     put :update, {
720       id: users(:active_no_prefs).uuid,
721       user: {
722         prefs: {:profile => {'organization' => 'example.com'}}
723       }
724     }
725     assert_response :success
726
727     found_email = false
728     ActionMailer::Base.deliveries.andand.each do |email|
729       if email.subject == "Profile created by #{users(:active_no_prefs).email}"
730         found_email = true
731         break
732       end
733     end
734     assert_equal true, found_email, 'Expected email after creating profile'
735   end
736
737   test "update active_no_prefs_profile user profile and expect notification email" do
738     authorize_with :admin
739
740     user = {}
741     user[:prefs] = users(:active_no_prefs_profile).prefs
742     user[:prefs][:profile] = {:profile => {'organization' => 'example.com'}}
743     put :update, {
744       id: users(:active_no_prefs_profile).uuid,
745       user: user
746     }
747     assert_response :success
748
749     found_email = false
750     ActionMailer::Base.deliveries.andand.each do |email|
751       if email.subject == "Profile created by #{users(:active_no_prefs_profile).email}"
752         found_email = true
753         break
754       end
755     end
756     assert_equal true, found_email, 'Expected email after creating profile'
757   end
758
759   test "update active user profile and expect no notification email" do
760     authorize_with :admin
761
762     put :update, {
763       id: users(:active).uuid,
764       user: {
765         prefs: {:profile => {'organization' => 'anotherexample.com'}}
766       }
767     }
768     assert_response :success
769
770     found_email = false
771     ActionMailer::Base.deliveries.andand.each do |email|
772       if email.subject == "Profile created by #{users(:active).email}"
773         found_email = true
774         break
775       end
776     end
777     assert_equal false, found_email, 'Expected no email after updating profile'
778   end
779
780
781   NON_ADMIN_USER_DATA = ["uuid", "kind", "is_active", "email", "first_name",
782                          "last_name"].sort
783
784   def check_non_admin_index
785     assert_response :success
786     response_items = json_response["items"]
787     assert_not_nil response_items
788     response_items.each do |user_data|
789       check_non_admin_item user_data
790       assert(user_data["is_active"], "non-admin index returned inactive user")
791     end
792   end
793
794   def check_non_admin_show
795     assert_response :success
796     check_non_admin_item json_response
797   end
798
799   def check_non_admin_item user_data
800     assert_equal(NON_ADMIN_USER_DATA, user_data.keys.sort,
801                  "data in response had missing or extra attributes")
802     assert_equal("arvados#user", user_data["kind"])
803   end
804
805
806   def check_readable_users_index expect_present, expect_missing
807     response_uuids = json_response["items"].map { |u| u["uuid"] }
808     expect_present.each do |user_key|
809       assert_includes(response_uuids, users(user_key).uuid,
810                       "#{user_key} missing from index")
811     end
812     expect_missing.each do |user_key|
813       refute_includes(response_uuids, users(user_key).uuid,
814                       "#{user_key} included in index")
815     end
816   end
817
818   def check_inactive_user_findable(params={})
819     inactive_user = users(:inactive)
820     get(:index, params.merge(filters: [["email", "=", inactive_user.email]]))
821     assert_response :success
822     user_list = json_response["items"]
823     assert_equal(1, user_list.andand.count)
824     # This test needs to check a column non-admins have no access to,
825     # to ensure that admins see all user information.
826     assert_equal(inactive_user.identity_url, user_list.first["identity_url"],
827                  "admin's filtered index did not return inactive user")
828   end
829
830   def verify_num_links (original_links, expected_additional_links)
831     links_now = Link.all
832     assert_equal expected_additional_links, Link.all.size-original_links.size,
833         "Expected #{expected_additional_links.inspect} more links"
834   end
835
836   def find_obj_in_resp (response_items, object_type, head_kind=nil)
837     return_obj = nil
838     response_items
839     response_items.each { |x|
840       if !x
841         next
842       end
843
844       if object_type == 'User'
845         if ArvadosModel::resource_class_for_uuid(x['uuid']) == User
846           return_obj = x
847           break
848         end
849       else  # looking for a link
850         if x['head_uuid'] and ArvadosModel::resource_class_for_uuid(x['head_uuid']).kind == head_kind
851           return_obj = x
852           break
853         end
854       end
855     }
856     return return_obj
857   end
858
859   def verify_link(response_items, link_object_name, expect_link, link_class,
860         link_name, head_uuid, tail_uuid, head_kind, fetch_object, class_name)
861
862     link = find_obj_in_resp response_items, 'Link', link_object_name
863
864     if !expect_link
865       assert_nil link, "Expected no link for #{link_object_name}"
866       return
867     end
868
869     assert_not_nil link, "Expected link for #{link_object_name}"
870
871     if fetch_object
872       object = Object.const_get(class_name).where(name: head_uuid)
873       assert [] != object, "expected #{class_name} with name #{head_uuid}"
874       head_uuid = object.first[:uuid]
875     end
876     assert_equal link_class, link['link_class'],
877         "did not find expected link_class for #{link_object_name}"
878
879     assert_equal link_name, link['name'],
880         "did not find expected link_name for #{link_object_name}"
881
882     assert_equal tail_uuid, link['tail_uuid'],
883         "did not find expected tail_uuid for #{link_object_name}"
884
885     assert_equal head_kind, link['head_kind'],
886         "did not find expected head_kind for #{link_object_name}"
887
888     assert_equal head_uuid, link['head_uuid'],
889         "did not find expected head_uuid for #{link_object_name}"
890   end
891
892   def verify_link_existence uuid, email, expect_oid_login_perms,
893       expect_repo_perms, expect_vm_perms, expect_group_perms, expect_signatures
894     # verify that all links are deleted for the user
895     oid_login_perms = Link.where(tail_uuid: email,
896                                  link_class: 'permission',
897                                  name: 'can_login').where("head_uuid like ?", User.uuid_like_pattern)
898     if expect_oid_login_perms
899       assert oid_login_perms.any?, "expected oid_login_perms"
900     else
901       assert !oid_login_perms.any?, "expected all oid_login_perms deleted"
902     end
903
904     repo_perms = Link.where(tail_uuid: uuid,
905                             link_class: 'permission',
906                             name: 'can_manage').where("head_uuid like ?", Repository.uuid_like_pattern)
907     if expect_repo_perms
908       assert repo_perms.any?, "expected repo_perms"
909     else
910       assert !repo_perms.any?, "expected all repo_perms deleted"
911     end
912
913     vm_login_perms = Link.
914       where(tail_uuid: uuid,
915             link_class: 'permission',
916             name: 'can_login').
917       where("head_uuid like ?",
918             VirtualMachine.uuid_like_pattern).
919       where('uuid <> ?',
920             links(:auto_setup_vm_login_username_can_login_to_test_vm).uuid)
921     if expect_vm_perms
922       assert vm_login_perms.any?, "expected vm_login_perms"
923     else
924       assert !vm_login_perms.any?, "expected all vm_login_perms deleted"
925     end
926
927     group = Group.where(name: 'All users').select do |g|
928       g[:uuid].match /-f+$/
929     end.first
930     group_read_perms = Link.where(tail_uuid: uuid,
931                                   head_uuid: group[:uuid],
932                                   link_class: 'permission',
933                                   name: 'can_read')
934     if expect_group_perms
935       assert group_read_perms.any?, "expected all users group read perms"
936     else
937       assert !group_read_perms.any?, "expected all users group perm deleted"
938     end
939
940     signed_uuids = Link.where(link_class: 'signature',
941                               tail_uuid: uuid)
942
943     if expect_signatures
944       assert signed_uuids.any?, "expected signatures"
945     else
946       assert !signed_uuids.any?, "expected all signatures deleted"
947     end
948
949   end
950
951   def verify_system_group_permission_link_for user_uuid
952     assert_equal 1, Link.where(link_class: 'permission',
953                                name: 'can_manage',
954                                tail_uuid: system_group_uuid,
955                                head_uuid: user_uuid).count
956   end
957 end