Refactor user notification tests
[arvados.git] / services / api / test / unit / user_test.rb
1 require 'test_helper'
2
3 class UserTest < ActiveSupport::TestCase
4   include CurrentApiClient
5
6   test "check non-admin active user properties" do
7     @active_user = users(:active)     # get the active user
8     assert !@active_user.is_admin, 'is_admin should not be set for a non-admin user'
9     assert @active_user.is_active, 'user should be active'
10     assert @active_user.is_invited, 'is_invited should be set'
11     assert_not_nil @active_user.prefs, "user's preferences should be non-null, but may be size zero"
12     assert (@active_user.can? :read=>"#{@active_user.uuid}"), "user should be able to read own object"
13     assert (@active_user.can? :write=>"#{@active_user.uuid}"), "user should be able to write own object"
14     assert (@active_user.can? :manage=>"#{@active_user.uuid}"), "user should be able to manage own object"
15
16     assert @active_user.groups_i_can(:read).size > 0, "active user should be able read at least one group"
17
18     # non-admin user cannot manage or write other user objects
19     @uninvited_user = users(:inactive_uninvited)     # get the uninvited user
20     assert !(@active_user.can? :read=>"#{@uninvited_user.uuid}")
21     assert !(@active_user.can? :write=>"#{@uninvited_user.uuid}")
22     assert !(@active_user.can? :manage=>"#{@uninvited_user.uuid}")
23   end
24
25   test "check admin user properties" do
26     @admin_user = users(:admin)     # get the admin user
27     assert @admin_user.is_admin, 'is_admin should be set for admin user'
28     assert @admin_user.is_active, 'admin user cannot be inactive'
29     assert @admin_user.is_invited, 'is_invited should be set'
30     assert_not_nil @admin_user.uuid.size, "user's uuid should be non-null"
31     assert_not_nil @admin_user.prefs, "user's preferences should be non-null, but may be size zero"
32     assert @admin_user.identity_url.size > 0, "user's identity url is expected"
33     assert @admin_user.can? :read=>"#{@admin_user.uuid}"
34     assert @admin_user.can? :write=>"#{@admin_user.uuid}"
35     assert @admin_user.can? :manage=>"#{@admin_user.uuid}"
36
37     assert @admin_user.groups_i_can(:read).size > 0, "admin active user should be able read at least one group"
38     assert @admin_user.groups_i_can(:write).size > 0, "admin active user should be able write to at least one group"
39     assert @admin_user.groups_i_can(:manage).size > 0, "admin active user should be able manage at least one group"
40
41     # admin user can also write or manage other users
42     @uninvited_user = users(:inactive_uninvited)     # get the uninvited user
43     assert @admin_user.can? :read=>"#{@uninvited_user.uuid}"
44     assert @admin_user.can? :write=>"#{@uninvited_user.uuid}"
45     assert @admin_user.can? :manage=>"#{@uninvited_user.uuid}"
46   end
47
48   test "check inactive and uninvited user properties" do
49     @uninvited_user = users(:inactive_uninvited)     # get the uninvited user
50     assert !@uninvited_user.is_admin, 'is_admin should not be set for a non-admin user'
51     assert !@uninvited_user.is_active, 'user should be inactive'
52     assert !@uninvited_user.is_invited, 'is_invited should not be set'
53     assert @uninvited_user.can? :read=>"#{@uninvited_user.uuid}"
54     assert @uninvited_user.can? :write=>"#{@uninvited_user.uuid}"
55     assert @uninvited_user.can? :manage=>"#{@uninvited_user.uuid}"
56
57     assert @uninvited_user.groups_i_can(:read).size == 0, "inactive and uninvited user should not be able read any groups"
58     assert @uninvited_user.groups_i_can(:write).size == 0, "inactive and uninvited user should not be able write to any groups"
59     assert @uninvited_user.groups_i_can(:manage).size == 0, "inactive and uninvited user should not be able manage any groups"
60   end
61
62   test "find user method checks" do
63     User.find(:all).each do |user|
64       assert_not_nil user.uuid, "non-null uuid expected for " + user.full_name
65     end
66
67     user = users(:active)     # get the active user
68
69     found_user = User.find(user.id)   # find a user by the row id
70
71     assert_equal found_user.full_name, user.first_name + ' ' + user.last_name
72     assert_equal found_user.identity_url, user.identity_url
73   end
74
75   test "full name should not contain spurious whitespace" do
76     set_user_from_auth :admin
77
78     user = User.create ({uuid: 'zzzzz-tpzed-abcdefghijklmno', email: 'foo@example.com' })
79
80     assert_equal '', user.full_name
81
82     user.first_name = 'John'
83     user.last_name = 'Smith'
84
85     assert_equal user.first_name + ' ' + user.last_name, user.full_name
86   end
87
88   test "create new user" do
89     set_user_from_auth :admin
90
91     @all_users = User.find(:all)
92
93     user = User.new
94     user.first_name = "first_name_for_newly_created_user"
95     user.save
96
97     # verify there is one extra user in the db now
98     # the API server also auto-creates the root system user after the first user
99     # is created, hence the test for the delta of 2.
100     assert_equal @all_users.size+2, User.find(:all).size
101
102     user = User.find(user.id)   # get the user back
103     assert_equal(user.first_name, 'first_name_for_newly_created_user')
104     assert_not_nil user.uuid, 'uuid should be set for newly created user'
105     assert_nil user.email, 'email should be null for newly created user, because it was not passed in'
106     assert_nil user.identity_url, 'identity_url should be null for newly created user, because it was not passed in'
107
108     user.first_name = 'first_name_for_newly_created_user_updated'
109     user.save
110     user = User.find(user.id)   # get the user back
111     assert_equal(user.first_name, 'first_name_for_newly_created_user_updated')
112   end
113
114   test "create new user with notifications" do
115     set_user_from_auth :admin
116
117     user_notification_helper true, 'active-notify-address@example.com', 'inactive-notify-address@example.com'
118     user_notification_helper true, 'active-notify-address@example.com', []
119     user_notification_helper true, [], []
120     user_notification_helper false, 'active-notify-address@example.com', 'inactive-notify-address@example.com'
121     user_notification_helper false, [], 'inactive-notify-address@example.com'
122     user_notification_helper false, [], []
123   end
124
125   test "update existing user" do
126     set_user_from_auth :active    # set active user as current user
127
128     @active_user = users(:active)     # get the active user
129
130     @active_user.first_name = "first_name_changed"
131     @active_user.save
132
133     @active_user = User.find(@active_user.id)   # get the user back
134     assert_equal(@active_user.first_name, 'first_name_changed')
135
136     # admin user also should be able to update the "active" user info
137     set_user_from_auth :admin # set admin user as current user
138     @active_user.first_name = "first_name_changed_by_admin_for_active_user"
139     @active_user.save
140
141     @active_user = User.find(@active_user.id)   # get the user back
142     assert_equal(@active_user.first_name, 'first_name_changed_by_admin_for_active_user')
143   end
144
145   test "delete a user and verify" do
146     @active_user = users(:active)     # get the active user
147     active_user_uuid = @active_user.uuid
148
149     set_user_from_auth :admin
150     @active_user.delete
151
152     found_deleted_user = false
153     User.find(:all).each do |user|
154       if user.uuid == active_user_uuid
155         found_deleted_user = true
156         break
157       end
158     end
159     assert !found_deleted_user, "found deleted user: "+active_user_uuid
160
161   end
162
163   test "create new user as non-admin user" do
164     set_user_from_auth :active
165
166     begin
167       user = User.new
168       user.save
169     rescue ArvadosModel::PermissionDeniedError => e
170     end
171     assert (e.message.include? 'PermissionDeniedError'),
172         'Expected PermissionDeniedError'
173   end
174
175   test "setup new user" do
176     set_user_from_auth :admin
177
178     email = 'foo@example.com'
179     openid_prefix = 'http://openid/prefix'
180
181     user = User.create ({uuid: 'zzzzz-tpzed-abcdefghijklmno', email: email})
182
183     vm = VirtualMachine.create
184
185     response = User.setup user, openid_prefix, 'test_repo', vm.uuid
186
187     resp_user = find_obj_in_resp response, 'User'
188     verify_user resp_user, email
189
190     oid_login_perm = find_obj_in_resp response, 'Link', 'arvados#user'
191
192     verify_link oid_login_perm, 'permission', 'can_login', resp_user[:email],
193         resp_user[:uuid]
194
195     assert_equal openid_prefix, oid_login_perm[:properties]['identity_url_prefix'],
196         'expected identity_url_prefix not found for oid_login_perm'
197
198     group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
199     verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
200
201     repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository'
202     verify_link repo_perm, 'permission', 'can_write', resp_user[:uuid], nil
203
204     vm_perm = find_obj_in_resp response, 'Link', 'arvados#virtualMachine'
205     verify_link vm_perm, 'permission', 'can_login', resp_user[:uuid], vm.uuid
206   end
207
208   test "setup new user with junk in database" do
209     set_user_from_auth :admin
210
211     email = 'foo@example.com'
212     openid_prefix = 'http://openid/prefix'
213
214     user = User.create ({uuid: 'zzzzz-tpzed-abcdefghijklmno', email: email})
215
216     vm = VirtualMachine.create
217
218     # Set up the bogus Link
219     bad_uuid = 'zzzzz-tpzed-xyzxyzxyzxyzxyz'
220
221     resp_link = Link.create ({tail_uuid: email, link_class: 'permission',
222         name: 'can_login', head_uuid: bad_uuid})
223     resp_link.save(validate: false)
224
225     verify_link resp_link, 'permission', 'can_login', email, bad_uuid
226
227     response = User.setup user, openid_prefix, 'test_repo', vm.uuid
228
229     resp_user = find_obj_in_resp response, 'User'
230     verify_user resp_user, email
231
232     oid_login_perm = find_obj_in_resp response, 'Link', 'arvados#user'
233
234     verify_link oid_login_perm, 'permission', 'can_login', resp_user[:email],
235         resp_user[:uuid]
236
237     assert_equal openid_prefix, oid_login_perm[:properties]['identity_url_prefix'],
238         'expected identity_url_prefix not found for oid_login_perm'
239
240     group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
241     verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
242
243     repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository'
244     verify_link repo_perm, 'permission', 'can_write', resp_user[:uuid], nil
245
246     vm_perm = find_obj_in_resp response, 'Link', 'arvados#virtualMachine'
247     verify_link vm_perm, 'permission', 'can_login', resp_user[:uuid], vm.uuid
248   end
249
250
251
252   test "setup new user in multiple steps" do
253     set_user_from_auth :admin
254
255     email = 'foo@example.com'
256     openid_prefix = 'http://openid/prefix'
257
258     user = User.create ({uuid: 'zzzzz-tpzed-abcdefghijklmno', email: email})
259
260     response = User.setup user, openid_prefix
261
262     resp_user = find_obj_in_resp response, 'User'
263     verify_user resp_user, email
264
265     oid_login_perm = find_obj_in_resp response, 'Link', 'arvados#user'
266     verify_link oid_login_perm, 'permission', 'can_login', resp_user[:email],
267         resp_user[:uuid]
268     assert_equal openid_prefix, oid_login_perm[:properties]['identity_url_prefix'],
269         'expected identity_url_prefix not found for oid_login_perm'
270
271     group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
272     verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
273
274     # invoke setup again with repo_name
275     response = User.setup user, openid_prefix, 'test_repo'
276     resp_user = find_obj_in_resp response, 'User', nil
277     verify_user resp_user, email
278     assert_equal user.uuid, resp_user[:uuid], 'expected uuid not found'
279
280     group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
281     verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
282
283     repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository'
284     verify_link repo_perm, 'permission', 'can_write', resp_user[:uuid], nil
285
286     # invoke setup again with a vm_uuid
287     vm = VirtualMachine.create
288
289     response = User.setup user, openid_prefix, 'test_repo', vm.uuid
290
291     resp_user = find_obj_in_resp response, 'User', nil
292     verify_user resp_user, email
293     assert_equal user.uuid, resp_user[:uuid], 'expected uuid not found'
294
295     group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
296     verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
297
298     repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository'
299     verify_link repo_perm, 'permission', 'can_write', resp_user[:uuid], nil
300
301     vm_perm = find_obj_in_resp response, 'Link', 'arvados#virtualMachine'
302     verify_link vm_perm, 'permission', 'can_login', resp_user[:uuid], vm.uuid
303   end
304
305   def find_obj_in_resp (response_items, object_type, head_kind=nil)
306     return_obj = nil
307     response_items.each { |x|
308       if !x
309         next
310       end
311
312       if object_type == 'User'
313         if ArvadosModel::resource_class_for_uuid(x['uuid']) == User
314           return_obj = x
315           break
316         end
317       else  # looking for a link
318         if ArvadosModel::resource_class_for_uuid(x['head_uuid']).kind == head_kind
319           return_obj = x
320           break
321         end
322       end
323     }
324     return return_obj
325   end
326
327   def verify_user (resp_user, email)
328     assert_not_nil resp_user, 'expected user object'
329     assert_not_nil resp_user['uuid'], 'expected user object'
330     assert_equal email, resp_user['email'], 'expected email not found'
331
332   end
333
334   def verify_link (link_object, link_class, link_name, tail_uuid, head_uuid)
335     assert_not_nil link_object, "expected link for #{link_class} #{link_name}"
336     assert_not_nil link_object[:uuid],
337         "expected non-nil uuid for link for #{link_class} #{link_name}"
338     assert_equal link_class, link_object[:link_class],
339         "expected link_class not found for #{link_class} #{link_name}"
340     assert_equal link_name, link_object[:name],
341         "expected link_name not found for #{link_class} #{link_name}"
342     assert_equal tail_uuid, link_object[:tail_uuid],
343         "expected tail_uuid not found for #{link_class} #{link_name}"
344     if head_uuid
345       assert_equal head_uuid, link_object[:head_uuid],
346           "expected head_uuid not found for #{link_class} #{link_name}"
347     end
348   end
349
350   def user_notification_helper (active, active_recipients, inactive_recipients)
351     Rails.configuration.new_user_notification_recipients = active_recipients
352     Rails.configuration.new_inactive_user_notification_recipients = inactive_recipients
353
354     assert_equal active_recipients, Rails.configuration.new_user_notification_recipients
355     assert_equal inactive_recipients, Rails.configuration.new_inactive_user_notification_recipients
356
357     ActionMailer::Base.deliveries = []
358
359     user = User.new
360     user.first_name = "first_name_for_newly_created_user"
361     user.is_active = active
362     user.save
363
364     new_user_email = nil
365     new_inactive_user_email = nil
366
367     ActionMailer::Base.deliveries.each do |d|
368       if d.subject == "#{Rails.configuration.email_subject_prefix}New user notification" then
369         new_user_email = d
370       elsif d.subject == "#{Rails.configuration.email_subject_prefix}New inactive user notification" then
371         new_inactive_user_email = d
372       end
373     end
374
375     if not active
376       if not inactive_recipients.empty? then
377         assert_not_nil new_inactive_user_email, 'Expected new inactive user email after setup'
378         assert_equal Rails.configuration.user_notifier_email_from, new_inactive_user_email.from[0]
379         assert_equal inactive_recipients, new_inactive_user_email.to[0]
380         assert_equal "#{Rails.configuration.email_subject_prefix}New inactive user notification", new_inactive_user_email.subject
381       else
382         assert_nil new_inactive_user_email, 'Did not expect new inactive user email after setup'
383       end
384     end
385
386     if active
387       assert_nil new_inactive_user_email, 'Expected email after setup'
388       if not active_recipients.empty? then
389         assert_not_nil new_user_email, 'Expected new user email after setup'
390         assert_equal Rails.configuration.user_notifier_email_from, new_user_email.from[0]
391         assert_equal active_recipients, new_user_email.to[0]
392         assert_equal "#{Rails.configuration.email_subject_prefix}New user notification", new_user_email.subject
393       else
394         assert_nil new_user_email, 'Did not expect new user email after setup'
395       end
396     end
397     ActionMailer::Base.deliveries = []
398
399   end
400
401 end