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