8784: Fix test for latest firefox.
[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 but different email, expect original email" do
218     authorize_with :admin
219     inactive_user = users(:inactive)
220
221     post :setup, {
222       uuid: inactive_user['uuid'],
223       user: {email: 'junk_email'}
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 "setup user with valid email and repo as input" do
238     authorize_with :admin
239
240     post :setup, {
241       repo_name: 'usertestrepo',
242       user: {email: 'foo@example.com'},
243       openid_prefix: 'https://www.google.com/accounts/o8/id'
244     }
245
246     assert_response :success
247     response_items = JSON.parse(@response.body)['items']
248     response_object = find_obj_in_resp response_items, 'User', nil
249     assert_not_nil response_object['uuid'], 'expected uuid for the new user'
250     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
251
252     # four extra links; system_group, login, group and repo perms
253     verify_links_added 4
254   end
255
256   test "setup user with fake vm and expect error" do
257     authorize_with :admin
258
259     post :setup, {
260       repo_name: 'usertestrepo',
261       vm_uuid: 'no_such_vm',
262       user: {email: 'foo@example.com'},
263       openid_prefix: 'https://www.google.com/accounts/o8/id'
264     }
265
266     response_body = JSON.parse(@response.body)
267     response_errors = response_body['errors']
268     assert_not_nil response_errors, 'Expected error in response'
269     assert (response_errors.first.include? "No vm found for no_such_vm"),
270           'Expected RuntimeError: No vm found for no_such_vm'
271   end
272
273   test "setup user with valid email, repo and real vm as input" do
274     authorize_with :admin
275
276     post :setup, {
277       repo_name: 'usertestrepo',
278       openid_prefix: 'https://www.google.com/accounts/o8/id',
279       vm_uuid: @vm_uuid,
280       user: {email: 'foo@example.com'}
281     }
282
283     assert_response :success
284     response_items = JSON.parse(@response.body)['items']
285     response_object = find_obj_in_resp response_items, 'User', nil
286     assert_not_nil response_object['uuid'], 'expected uuid for the new user'
287     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
288
289     # five extra links; system_group, login, group, vm, repo
290     verify_links_added 5
291   end
292
293   test "setup user with valid email, no vm and no repo as input" do
294     authorize_with :admin
295
296     post :setup, {
297       user: {email: 'foo@example.com'},
298       openid_prefix: 'https://www.google.com/accounts/o8/id'
299     }
300
301     assert_response :success
302     response_items = JSON.parse(@response.body)['items']
303     response_object = find_obj_in_resp response_items, 'User', nil
304     assert_not_nil response_object['uuid'], 'expected uuid for new user'
305     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
306
307     # three extra links; system_group, login, and group
308     verify_links_added 3
309
310     verify_link response_items, 'arvados#user', true, 'permission', 'can_login',
311         response_object['uuid'], response_object['email'], 'arvados#user', false, 'User'
312
313     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
314         'All users', response_object['uuid'], 'arvados#group', true, 'Group'
315
316     verify_link response_items, 'arvados#repository', false, 'permission', 'can_manage',
317         'foo/usertestrepo', response_object['uuid'], 'arvados#repository', true, 'Repository'
318
319     verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
320         nil, response_object['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
321   end
322
323   test "setup user with email, first name, repo name and vm uuid" do
324     authorize_with :admin
325
326     post :setup, {
327       openid_prefix: 'https://www.google.com/accounts/o8/id',
328       repo_name: 'usertestrepo',
329       vm_uuid: @vm_uuid,
330       user: {
331         first_name: 'test_first_name',
332         email: 'foo@example.com'
333       }
334     }
335
336     assert_response :success
337     response_items = JSON.parse(@response.body)['items']
338     response_object = find_obj_in_resp response_items, 'User', nil
339     assert_not_nil response_object['uuid'], 'expected uuid for new user'
340     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
341     assert_equal 'test_first_name', response_object['first_name'],
342         'expecting first name'
343
344     # five extra links; system_group, login, group, repo and vm
345     verify_links_added 5
346   end
347
348   test "setup user with an existing user email and check different object is created" do
349     authorize_with :admin
350     inactive_user = users(:inactive)
351
352     post :setup, {
353       openid_prefix: 'https://www.google.com/accounts/o8/id',
354       repo_name: 'usertestrepo',
355       user: {
356         email: inactive_user['email']
357       }
358     }
359
360     assert_response :success
361     response_items = JSON.parse(@response.body)['items']
362     response_object = find_obj_in_resp response_items, 'User', nil
363     assert_not_nil response_object['uuid'], 'expected uuid for new user'
364     assert_not_equal response_object['uuid'], inactive_user['uuid'],
365         'expected different uuid after create operation'
366     assert_equal inactive_user['email'], response_object['email'], 'expected given email'
367     # system_group, openid, group, and repo. No vm link.
368     verify_links_added 4
369   end
370
371   test "setup user with openid prefix" do
372     authorize_with :admin
373
374     post :setup, {
375       repo_name: 'usertestrepo',
376       openid_prefix: 'http://www.example.com/account',
377       user: {
378         first_name: "in_create_test_first_name",
379         last_name: "test_last_name",
380         email: "foo@example.com"
381       }
382     }
383
384     assert_response :success
385
386     response_items = JSON.parse(@response.body)['items']
387     created = find_obj_in_resp response_items, 'User', nil
388
389     assert_equal 'in_create_test_first_name', created['first_name']
390     assert_not_nil created['uuid'], 'expected uuid for new user'
391     assert_not_nil created['email'], 'expected non-nil email'
392     assert_nil created['identity_url'], 'expected no identity_url'
393
394     # verify links
395     # four new links: system_group, arvados#user, repo, and 'All users' group.
396     verify_links_added 4
397
398     verify_link response_items, 'arvados#user', true, 'permission', 'can_login',
399         created['uuid'], created['email'], 'arvados#user', false, 'User'
400
401     verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
402         'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
403
404     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
405         'All users', created['uuid'], 'arvados#group', true, 'Group'
406
407     verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
408         nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
409   end
410
411   test "invoke setup with no openid prefix, expect error" do
412     authorize_with :admin
413
414     post :setup, {
415       repo_name: 'usertestrepo',
416       user: {
417         first_name: "in_create_test_first_name",
418         last_name: "test_last_name",
419         email: "foo@example.com"
420       }
421     }
422
423     response_body = JSON.parse(@response.body)
424     response_errors = response_body['errors']
425     assert_not_nil response_errors, 'Expected error in response'
426     assert (response_errors.first.include? 'openid_prefix parameter is missing'),
427         'Expected ArgumentError'
428   end
429
430   test "setup user with user, vm and repo and verify links" do
431     authorize_with :admin
432
433     post :setup, {
434       user: {
435         first_name: "in_create_test_first_name",
436         last_name: "test_last_name",
437         email: "foo@example.com"
438       },
439       vm_uuid: @vm_uuid,
440       repo_name: 'usertestrepo',
441       openid_prefix: 'https://www.google.com/accounts/o8/id'
442     }
443
444     assert_response :success
445
446     response_items = JSON.parse(@response.body)['items']
447     created = find_obj_in_resp response_items, 'User', nil
448
449     assert_equal 'in_create_test_first_name', created['first_name']
450     assert_not_nil created['uuid'], 'expected uuid for new user'
451     assert_not_nil created['email'], 'expected non-nil email'
452     assert_nil created['identity_url'], 'expected no identity_url'
453
454     # five new links: system_group, arvados#user, repo, vm and 'All
455     # users' group link
456     verify_links_added 5
457
458     verify_link response_items, 'arvados#user', true, 'permission', 'can_login',
459         created['uuid'], created['email'], 'arvados#user', false, 'User'
460
461     verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
462         'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
463
464     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
465         'All users', created['uuid'], 'arvados#group', true, 'Group'
466
467     verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
468         @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
469   end
470
471   test "create user as non admin user and expect error" do
472     authorize_with :active
473
474     post :create, {
475       user: {email: 'foo@example.com'}
476     }
477
478     response_body = JSON.parse(@response.body)
479     response_errors = response_body['errors']
480     assert_not_nil response_errors, 'Expected error in response'
481     assert (response_errors.first.include? 'PermissionDenied'),
482           'Expected PermissionDeniedError'
483   end
484
485   test "setup user as non admin user and expect error" do
486     authorize_with :active
487
488     post :setup, {
489       openid_prefix: 'https://www.google.com/accounts/o8/id',
490       user: {email: 'foo@example.com'}
491     }
492
493     response_body = JSON.parse(@response.body)
494     response_errors = response_body['errors']
495     assert_not_nil response_errors, 'Expected error in response'
496     assert (response_errors.first.include? 'Forbidden'),
497           'Expected Forbidden error'
498   end
499
500   test "setup active user with repo and no vm" do
501     authorize_with :admin
502     active_user = users(:active)
503
504     # invoke setup with a repository
505     post :setup, {
506       repo_name: 'usertestrepo',
507       uuid: active_user['uuid']
508     }
509
510     assert_response :success
511
512     response_items = JSON.parse(@response.body)['items']
513     created = find_obj_in_resp response_items, 'User', nil
514
515     assert_equal active_user[:email], created['email'], 'expected input email'
516
517      # verify links
518     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
519         'All users', created['uuid'], 'arvados#group', true, 'Group'
520
521     verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
522         'active/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
523
524     verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
525         nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
526   end
527
528   test "setup active user with vm and no repo" do
529     authorize_with :admin
530     active_user = users(:active)
531     repos_query = Repository.where(owner_uuid: active_user.uuid)
532     repo_link_query = Link.where(tail_uuid: active_user.uuid,
533                                  link_class: "permission", name: "can_manage")
534     repos_count = repos_query.count
535     repo_link_count = repo_link_query.count
536
537     # invoke setup with a repository
538     post :setup, {
539       vm_uuid: @vm_uuid,
540       uuid: active_user['uuid'],
541       email: 'junk_email'
542     }
543
544     assert_response :success
545
546     response_items = JSON.parse(@response.body)['items']
547     created = find_obj_in_resp response_items, 'User', nil
548
549     assert_equal active_user['email'], created['email'], 'expected original email'
550
551     # verify links
552     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
553         'All users', created['uuid'], 'arvados#group', true, 'Group'
554
555     assert_equal(repos_count, repos_query.count)
556     assert_equal(repo_link_count, repo_link_query.count)
557
558     verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
559         @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
560   end
561
562   test "unsetup active user" do
563     active_user = users(:active)
564     assert_not_nil active_user['uuid'], 'expected uuid for the active user'
565     assert active_user['is_active'], 'expected is_active for active user'
566
567     verify_link_existence active_user['uuid'], active_user['email'],
568           false, true, true, true, true
569
570     authorize_with :admin
571
572     # now unsetup this user
573     post :unsetup, id: active_user['uuid']
574     assert_response :success
575
576     response_user = JSON.parse(@response.body)
577     assert_not_nil response_user['uuid'], 'expected uuid for the upsetup user'
578     assert_equal active_user['uuid'], response_user['uuid'], 'expected uuid not found'
579     assert !response_user['is_active'], 'expected user to be inactive'
580     assert !response_user['is_invited'], 'expected user to be uninvited'
581
582     verify_link_existence response_user['uuid'], response_user['email'],
583           false, false, false, false, false
584
585     active_user = User.find_by_uuid(users(:active).uuid)
586     readable_groups = active_user.groups_i_can(:read)
587     all_users_group = Group.all.collect(&:uuid).select { |g| g.match(/-f+$/) }
588     refute_includes(readable_groups, all_users_group,
589                     "active user can read All Users group after being deactivated")
590     assert_equal(false, active_user.is_invited,
591                  "active user is_invited after being deactivated & reloaded")
592   end
593
594   test "setup user with send notification param false and verify no email" do
595     authorize_with :admin
596
597     post :setup, {
598       openid_prefix: 'http://www.example.com/account',
599       send_notification_email: 'false',
600       user: {
601         email: "foo@example.com"
602       }
603     }
604
605     assert_response :success
606     response_items = JSON.parse(@response.body)['items']
607     created = find_obj_in_resp response_items, 'User', nil
608     assert_not_nil created['uuid'], 'expected uuid for the new user'
609     assert_equal created['email'], 'foo@example.com', 'expected given email'
610
611     setup_email = ActionMailer::Base.deliveries.last
612     assert_nil setup_email, 'expected no setup email'
613   end
614
615   test "setup user with send notification param true and verify email" do
616     authorize_with :admin
617
618     post :setup, {
619       openid_prefix: 'http://www.example.com/account',
620       send_notification_email: 'true',
621       user: {
622         email: "foo@example.com"
623       }
624     }
625
626     assert_response :success
627     response_items = JSON.parse(@response.body)['items']
628     created = find_obj_in_resp response_items, 'User', nil
629     assert_not_nil created['uuid'], 'expected uuid for the new user'
630     assert_equal created['email'], 'foo@example.com', 'expected given email'
631
632     setup_email = ActionMailer::Base.deliveries.last
633     assert_not_nil setup_email, 'Expected email after setup'
634
635     assert_equal Rails.configuration.user_notifier_email_from, setup_email.from[0]
636     assert_equal 'foo@example.com', setup_email.to[0]
637     assert_equal 'Welcome to Curoverse - shell account enabled', setup_email.subject
638     assert (setup_email.body.to_s.include? 'Your Arvados shell account has been set up'),
639         'Expected Your Arvados shell account has been set up in email body'
640     assert (setup_email.body.to_s.include? "#{Rails.configuration.workbench_address}users/#{created['uuid']}/virtual_machines"), 'Expected virtual machines url in email body'
641   end
642
643   test "setup inactive user by changing is_active to true" do
644     authorize_with :admin
645     active_user = users(:active)
646
647     # invoke setup with a repository
648     put :update, {
649           id: active_user['uuid'],
650           user: {
651             is_active: true,
652           }
653         }
654     assert_response :success
655     assert_equal active_user['uuid'], json_response['uuid']
656     updated = User.where(uuid: active_user['uuid']).first
657     assert_equal(true, updated.is_active)
658     assert_equal({read: true}, updated.group_permissions[all_users_group_uuid])
659   end
660
661   test "non-admin user can get basic information about readable users" do
662     authorize_with :spectator
663     get(:index)
664     check_non_admin_index
665     check_readable_users_index [:spectator], [:inactive, :active]
666   end
667
668   test "non-admin user gets only safe attributes from users#show" do
669     g = act_as_system_user do
670       create :group
671     end
672     users = create_list :active_user, 2, join_groups: [g]
673     token = create :token, user: users[0]
674     authorize_with_token token
675     get :show, id: users[1].uuid
676     check_non_admin_show
677   end
678
679   [2, 4].each do |limit|
680     test "non-admin user can limit index to #{limit}" do
681       g = act_as_system_user do
682         create :group
683       end
684       users = create_list :active_user, 4, join_groups: [g]
685       token = create :token, user: users[0]
686
687       authorize_with_token token
688       get(:index, limit: limit)
689       check_non_admin_index
690       assert_equal(limit, json_response["items"].size,
691                    "non-admin index limit was ineffective")
692     end
693   end
694
695   test "admin has full index powers" do
696     authorize_with :admin
697     check_inactive_user_findable
698   end
699
700   test "reader token can grant admin index powers" do
701     authorize_with :spectator
702     check_inactive_user_findable(reader_tokens: [api_token(:admin)])
703   end
704
705   test "admin can filter on user.is_active" do
706     authorize_with :admin
707     get(:index, filters: [["is_active", "=", "true"]])
708     assert_response :success
709     check_readable_users_index [:active, :spectator], [:inactive]
710   end
711
712   test "admin can search where user.is_active" do
713     authorize_with :admin
714     get(:index, where: {is_active: true})
715     assert_response :success
716     check_readable_users_index [:active, :spectator], [:inactive]
717   end
718
719   test "update active_no_prefs user profile and expect notification email" do
720     authorize_with :admin
721
722     put :update, {
723       id: users(:active_no_prefs).uuid,
724       user: {
725         prefs: {:profile => {'organization' => 'example.com'}}
726       }
727     }
728     assert_response :success
729
730     found_email = false
731     ActionMailer::Base.deliveries.andand.each do |email|
732       if email.subject == "Profile created by #{users(:active_no_prefs).email}"
733         found_email = true
734         break
735       end
736     end
737     assert_equal true, found_email, 'Expected email after creating profile'
738   end
739
740   test "update active_no_prefs_profile user profile and expect notification email" do
741     authorize_with :admin
742
743     user = {}
744     user[:prefs] = users(:active_no_prefs_profile_no_getting_started_shown).prefs
745     user[:prefs][:profile] = {:profile => {'organization' => 'example.com'}}
746     put :update, {
747       id: users(:active_no_prefs_profile_no_getting_started_shown).uuid,
748       user: user
749     }
750     assert_response :success
751
752     found_email = false
753     ActionMailer::Base.deliveries.andand.each do |email|
754       if email.subject == "Profile created by #{users(:active_no_prefs_profile_no_getting_started_shown).email}"
755         found_email = true
756         break
757       end
758     end
759     assert_equal true, found_email, 'Expected email after creating profile'
760   end
761
762   test "update active user profile and expect no notification email" do
763     authorize_with :admin
764
765     put :update, {
766       id: users(:active).uuid,
767       user: {
768         prefs: {:profile => {'organization' => 'anotherexample.com'}}
769       }
770     }
771     assert_response :success
772
773     found_email = false
774     ActionMailer::Base.deliveries.andand.each do |email|
775       if email.subject == "Profile created by #{users(:active).email}"
776         found_email = true
777         break
778       end
779     end
780     assert_equal false, found_email, 'Expected no email after updating profile'
781   end
782
783   test "user API response includes writable_by" do
784     authorize_with :active
785     get :current
786     assert_response :success
787     assert_includes(json_response["writable_by"], users(:active).uuid,
788                     "user's writable_by should include self")
789     assert_includes(json_response["writable_by"], users(:active).owner_uuid,
790                     "user's writable_by should include its owner_uuid")
791   end
792
793
794   NON_ADMIN_USER_DATA = ["uuid", "kind", "is_active", "email", "first_name",
795                          "last_name"].sort
796
797   def check_non_admin_index
798     assert_response :success
799     response_items = json_response["items"]
800     assert_not_nil response_items
801     response_items.each do |user_data|
802       check_non_admin_item user_data
803       assert(user_data["is_active"], "non-admin index returned inactive user")
804     end
805   end
806
807   def check_non_admin_show
808     assert_response :success
809     check_non_admin_item json_response
810   end
811
812   def check_non_admin_item user_data
813     assert_equal(NON_ADMIN_USER_DATA, user_data.keys.sort,
814                  "data in response had missing or extra attributes")
815     assert_equal("arvados#user", user_data["kind"])
816   end
817
818
819   def check_readable_users_index expect_present, expect_missing
820     response_uuids = json_response["items"].map { |u| u["uuid"] }
821     expect_present.each do |user_key|
822       assert_includes(response_uuids, users(user_key).uuid,
823                       "#{user_key} missing from index")
824     end
825     expect_missing.each do |user_key|
826       refute_includes(response_uuids, users(user_key).uuid,
827                       "#{user_key} included in index")
828     end
829   end
830
831   def check_inactive_user_findable(params={})
832     inactive_user = users(:inactive)
833     get(:index, params.merge(filters: [["email", "=", inactive_user.email]]))
834     assert_response :success
835     user_list = json_response["items"]
836     assert_equal(1, user_list.andand.count)
837     # This test needs to check a column non-admins have no access to,
838     # to ensure that admins see all user information.
839     assert_equal(inactive_user.identity_url, user_list.first["identity_url"],
840                  "admin's filtered index did not return inactive user")
841   end
842
843   def verify_links_added more
844     assert_equal @initial_link_count+more, Link.count,
845         "Started with #{@initial_link_count} links, expected #{more} more"
846   end
847
848   def find_obj_in_resp (response_items, object_type, head_kind=nil)
849     return_obj = nil
850     response_items.each { |x|
851       if !x
852         next
853       end
854
855       if object_type == 'User'
856         if ArvadosModel::resource_class_for_uuid(x['uuid']) == User
857           return_obj = x
858           break
859         end
860       else  # looking for a link
861         if x['head_uuid'] and ArvadosModel::resource_class_for_uuid(x['head_uuid']).kind == head_kind
862           return_obj = x
863           break
864         end
865       end
866     }
867     return return_obj
868   end
869 end