Fix some whitespace complaints.
authorTom Clegg <tom@curoverse.com>
Fri, 28 Mar 2014 00:30:08 +0000 (20:30 -0400)
committerTom Clegg <tom@curoverse.com>
Fri, 28 Mar 2014 00:30:08 +0000 (20:30 -0400)
apps/workbench/app/views/pipeline_instances/_show_components.html.erb
doc/sdk/cli/index.html.textile.liquid
doc/user/tutorials/tutorial-firstscript.html.textile.liquid
sdk/cli/bin/arv-run-pipeline-instance
services/api/app/controllers/arvados/v1/jobs_controller.rb
services/api/app/controllers/arvados/v1/users_controller.rb
services/api/app/models/user.rb
services/api/script/setup-new-user.rb
services/api/test/functional/arvados/v1/users_controller_test.rb
services/api/test/unit/user_test.rb

index 69dd62ec08d088078bfe75fb9ca0d69914384d98..eafaf8d1db0792c2ca5ff3ccf06f0a269b1167c7 100644 (file)
@@ -38,7 +38,7 @@
     <% render_pipeline_jobs.each do |pj| %>
     <tr>
       <td>
-        <% job_status = render(partial: 'job_status_label', 
+        <% job_status = render(partial: 'job_status_label',
                                locals: { :j => pj[:job], :title => pj[:name] }) %>
         <% if pj[:job].andand[:uuid] %>
           <%= link_to(job_status, job_url(id: pj[:job][:uuid])) %>
@@ -51,7 +51,7 @@
       </td><td>
         <%= pj[:progress_bar] %>
       </td><td>
-        <%= render(partial: 'job_status_label', 
+        <%= render(partial: 'job_status_label',
                                locals: { :j => pj[:job] }) %>
       </td><td>
         <%= link_to_if_arvados_object pj[:output] %>
@@ -71,7 +71,7 @@ setInterval(function(){$('a.refresh').click()}, 15000);
 
 <% content_for :tab_line_buttons do %>
   <%= form_tag @object, :method => :put do |f| %>
-    
+
     <%= hidden_field @object.class.to_s.underscore.singularize.to_sym, :active, :value => false %>
 
     <%= button_tag "Stop pipeline", {class: 'btn btn-primary pull-right', id: "run-pipeline-button"} %>
@@ -86,7 +86,7 @@ setInterval(function(){$('a.refresh').click()}, 15000);
 
   <% content_for :tab_line_buttons do %>
     <%= form_tag @object, :method => :put do |f| %>
-      
+
       <%= hidden_field @object.class.to_s.underscore.singularize.to_sym, :active, :value => true %>
 
       <%= button_tag "Run pipeline", {class: 'btn btn-primary pull-right', id: "run-pipeline-button"} %>
@@ -94,5 +94,5 @@ setInterval(function(){$('a.refresh').click()}, 15000);
   <% end %>
 
   <%= render partial: 'pipeline_templates/show_components_template', locals: {:template => template, :obj => @object} %>
-  
+
 <% end %>
index 3b630791730e02e690a3a0f4f1451db3b32387e7..73acddcf1e63326e22f73c7038c196a90c36530d 100644 (file)
@@ -58,4 +58,3 @@ $ <code class="userinput">gem build arvados-cli.gemspec</code>
 $ <code class="userinput">sudo gem install arvados-cli-*.gem</code>
 </pre>
 </notextile>
-
index e2d7a8793bd12b91c217eada7a95ced8b941e658..03c76f6e46ec77c7bb36bdf91d7800aeda6505dd 100644 (file)
@@ -129,7 +129,7 @@ EOF
 * The component is listed with a human-readable name (@"do_hash"@ in this example)
 * @"script"@ specifies the name of the script to run.  The script is searched for in the "crunch_scripts/" subdirectory of the @git@ checkout specified by @"script_version"@.
 * @"repository"@ is the git repository to search for the script version.  You can access a list of available @git@ repositories on the Arvados workbench under "Compute %(rarr)&rarr;% Code repositories":https://{{site.arvados_workbench_host}}//repositories .
-* @"script_version"@ specifies the version of the script that you wish to run.  This can be in the form of an explicit @git@ revision hash, a tag, or a branch (in which case it will take the HEAD of the specified branch).  Arvados logs the script version that was used in the run, enabling you to go back and re-run any past job with the guarantee that the exact same code will be used as was used in the previous run.  
+* @"script_version"@ specifies the version of the script that you wish to run.  This can be in the form of an explicit @git@ revision hash, a tag, or a branch (in which case it will take the HEAD of the specified branch).  Arvados logs the script version that was used in the run, enabling you to go back and re-run any past job with the guarantee that the exact same code will be used as was used in the previous run.
 * @"script_parameters"@ describes the parameters for the script.  In this example, there is one parameter called @input@ which is @required@ and is a @Collection@.
 * @"output_is_persistent"@ indicates whether the output of the job is considered valuable. If this value is false (or not given), the output will be treated as intermediate data and eventually deleted to reclaim disk space.
 
index 090be61ba49c873ac85bdb7c9973794252a8c70a..8a164929e1bd4987ec9ab94162ffaba31d39f9bf 100755 (executable)
@@ -455,7 +455,7 @@ class WhRunPipelineInstance
           if (c[:job][:running] or
               not (c[:job][:finished_at] or c[:job][:cancelled_at]))
             # Job is running so update copy of job record
-            c[:job] = JobCache.get(c[:job][:uuid])            
+            c[:job] = JobCache.get(c[:job][:uuid])
           end
 
           if c[:job][:success]
@@ -547,7 +547,7 @@ class WhRunPipelineInstance
         end
       end
     end
-    
+
     if ended == @components.length or failed > 0
       @instance[:active] = false
       @instance[:success] = (succeeded == @components.length)
index b35bc4e44f8f38edb57c659ba2f21e84c12f05d2..178b48f173d58e47b5c590149d8b7f966b872dec 100644 (file)
@@ -6,11 +6,11 @@ class Arvados::V1::JobsController < ApplicationController
   skip_before_filter :render_404_if_no_object, :only => :queue
 
   def create
-    [:repository, :script, :script_version, :script_parameters].each do |r|    
+    [:repository, :script, :script_version, :script_parameters].each do |r|
       if !resource_attrs[r]
         return render json: {
           :error => "#{r} attribute must be specified"
-        }, status: :unprocessable_entity      
+        }, status: :unprocessable_entity
       end
     end
 
@@ -26,8 +26,8 @@ class Arvados::V1::JobsController < ApplicationController
       Job.readable_by(current_user).where(script: resource_attrs[:script],
                                           script_version: r).
         each do |j|
-        if j.nondeterministic != true and 
-            j.success != false and 
+        if j.nondeterministic != true and
+            j.success != false and
             j.script_parameters == resource_attrs[:script_parameters]
           # Record the first job in the list
           if !@object
index c5fc38d89ac2a2b030c25053b6a6948997cdc5e7..fe2d0da5d808f2645b4d327cabeabc26c875c1be 100644 (file)
@@ -4,7 +4,7 @@ class Arvados::V1::UsersController < ApplicationController
   skip_before_filter :render_404_if_no_object, only:
     [:activate, :event_stream, :current, :system, :setup]
   before_filter :admin_required, only: [:setup, :unsetup]
-  
+
   def current
     @object = current_user
     show
@@ -29,7 +29,7 @@ class Arvados::V1::UsersController < ApplicationController
       end
     end
   end
-      
+
   def event_stream
     channel = current_user.andand.uuid
     if current_user.andand.is_admin
index c09b67cdb403538ff4d18d29ddf6f60d2bfdb35a..0539247b92ccf070568ac1a88138c9d9d37e68d8 100644 (file)
@@ -134,7 +134,7 @@ class User < ArvadosModel
     end
 
     return [oid_login_perm] + user.setup_repo_vm_links(repo_name, vm_uuid)
-  end 
+  end
 
   # create links
   def setup_repo_vm_links(repo_name, vm_uuid)
@@ -143,7 +143,7 @@ class User < ArvadosModel
     group_perm = create_user_group_link
 
     return [repo_perm, vm_login_perm, group_perm, self].compact
-  end 
+  end
 
   # delete user signatures, login, repo, and vm perms, and mark as inactive
   def unsetup
@@ -185,7 +185,7 @@ class User < ArvadosModel
     # mark the user as inactive
     self.is_active = false
     self.save!
-  end 
+  end
 
   protected
 
@@ -276,7 +276,7 @@ class User < ArvadosModel
                               link_class: 'permission',
                               name: 'can_write')
       if repo_perms.any?
-        logger.warn "User already has repository access " + 
+        logger.warn "User already has repository access " +
             repo_perms.collect { |p| p[:uuid] }.inspect
         return repo_perms.first
       end
@@ -299,9 +299,9 @@ class User < ArvadosModel
   # create login permission for the given vm_uuid, if it does not already exist
   def create_vm_login_permission_link(vm_uuid, repo_name)
     begin
-              
+
       # vm uuid is optional
-      if vm_uuid 
+      if vm_uuid
         vm = VirtualMachine.where(uuid: vm_uuid).first
 
         if not vm
@@ -309,7 +309,7 @@ class User < ArvadosModel
           raise "No vm found for #{vm_uuid}"
         end
       else
-        return 
+        return
       end
 
       logger.info { "vm uuid: " + vm[:uuid] }
@@ -363,7 +363,7 @@ class User < ArvadosModel
                                  link_class: 'permission',
                                  name: 'can_read')
         logger.info { "group permission: " + group_perm[:uuid] }
-      else 
+      else
         group_perm = group_perms.first
       end
 
index 19f5aeb7b78803e7009600480e60c046e6739ca8..ebff19263e92129e04d93d7aa5898ddb7ac0dd89 100755 (executable)
@@ -24,7 +24,7 @@ claim the account.
 end
 
 log.level = (ENV['DEBUG'] || opts.debug) ? Logger::DEBUG : Logger::WARN
-    
+
 if ARGV.count != 3
   Trollop::die "required arguments are missing"
 end
@@ -39,8 +39,8 @@ begin
   found_user = arv.user.get(uuid: user_arg)
 rescue Arvados::TransactionFailedError
   found = arv.user.list(where: {email: user_arg})[:items]
-    
-  if found.count == 0 
+
+  if found.count == 0
     if !user_arg.match(/\w\@\w+\.\w+/)
       abort "About to create new user, but #{user_arg.inspect} " +
                "does not look like an email address. Stop."
index b15b99b2bca7c11c38ffdb92860e5731ffbfa04b..6f41902312fff19db3940922d137f37ee9e565ba 100644 (file)
@@ -66,7 +66,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
       repo_name: repo_name,
       openid_prefix: 'https://www.google.com/accounts/o8/id',
       user: {
-        uuid: "this_is_agreeable",        
+        uuid: "this_is_agreeable",
         first_name: "in_create_test_first_name",
         last_name: "test_last_name",
         email: "foo@example.com"
@@ -80,7 +80,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
     assert_equal 'this_is_agreeable', created['uuid']
     assert_not_nil created['email'], 'expected non-nil email'
-    assert_nil created['identity_url'], 'expected no identity_url' 
+    assert_nil created['identity_url'], 'expected no identity_url'
 
     # arvados#user, repo link and link add user to 'All users' group
     verify_num_links @all_links_at_start, 3
@@ -198,7 +198,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     get :current
     assert_response :success
     inactive_user = JSON.parse(@response.body)
-    
+
     authorize_with :admin
 
     post :setup, {
@@ -214,7 +214,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
 
     assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
     assert_equal inactive_user['uuid'], resp_obj['uuid']
-    assert_equal inactive_user['email'], resp_obj['email'], 
+    assert_equal inactive_user['email'], resp_obj['email'],
         'expecting inactive user email'
 
     # expect repo and vm links
@@ -230,7 +230,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     get :current
     assert_response :success
     inactive_user = JSON.parse(@response.body)
-    
+
     authorize_with :admin
 
     post :setup, {
@@ -245,7 +245,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
 
     assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
     assert_equal inactive_user['uuid'], resp_obj['uuid']
-    assert_equal inactive_user['email'], resp_obj['email'], 
+    assert_equal inactive_user['email'], resp_obj['email'],
         'expecting inactive user email'
   end
 
@@ -254,7 +254,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     get :current
     assert_response :success
     inactive_user = JSON.parse(@response.body)
-    
+
     authorize_with :admin
 
     post :setup, {
@@ -269,7 +269,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
 
     assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
     assert_equal inactive_user['uuid'], resp_obj['uuid']
-    assert_equal inactive_user['email'], resp_obj['email'], 
+    assert_equal inactive_user['email'], resp_obj['email'],
         'expecting inactive user email'
   end
 
@@ -305,7 +305,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     response_body = JSON.parse(@response.body)
     response_errors = response_body['errors']
     assert_not_nil response_errors, 'Expected error in response'
-    assert (response_errors.first.include? "No vm found for no_such_vm"), 
+    assert (response_errors.first.include? "No vm found for no_such_vm"),
           'Expected RuntimeError: No vm found for no_such_vm'
   end
 
@@ -337,7 +337,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
       openid_prefix: 'https://www.google.com/accounts/o8/id'
     }
 
-    assert_response :success    
+    assert_response :success
     response_items = JSON.parse(@response.body)['items']
     response_object = find_obj_in_resp response_items, 'User', nil
     assert_not_nil response_object['uuid'], 'expected uuid for new user'
@@ -365,7 +365,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     response_object = find_obj_in_resp response_items, 'User', nil
     assert_not_nil response_object['uuid'], 'expected uuid for new user'
     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
-    assert_equal 'test_first_name', response_object['first_name'], 
+    assert_equal 'test_first_name', response_object['first_name'],
         'expecting first name'
 
     # four extra links; login link, group link, repo link and vm link
@@ -399,7 +399,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     assert_response :success
     response_items = JSON.parse(@response.body)['items']
     response_object2 = find_obj_in_resp response_items, 'User', nil
-    assert_not_equal response_object['uuid'], response_object2['uuid'], 
+    assert_not_equal response_object['uuid'], response_object2['uuid'],
         'expected same uuid as first create operation'
     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
 
@@ -428,7 +428,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     assert_equal 'in_create_test_first_name', created['first_name']
     assert_not_nil created['uuid'], 'expected uuid for new user'
     assert_not_nil created['email'], 'expected non-nil email'
-    assert_nil created['identity_url'], 'expected no identity_url' 
+    assert_nil created['identity_url'], 'expected no identity_url'
 
     # verify links
     # 3 new links: arvados#user, repo, and 'All users' group.
@@ -488,7 +488,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     assert_equal 'in_create_test_first_name', created['first_name']
     assert_not_nil created['uuid'], 'expected uuid for new user'
     assert_not_nil created['email'], 'expected non-nil email'
-    assert_nil created['identity_url'], 'expected no identity_url' 
+    assert_nil created['identity_url'], 'expected no identity_url'
 
     # expect 4 new links: arvados#user, repo, vm and 'All users' group link
     verify_num_links @all_links_at_start, 4
@@ -502,7 +502,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
         'All users', created['uuid'], 'arvados#group', true, 'Group'
 
-    verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login', 
+    verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
         @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
   end
 
@@ -516,7 +516,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     response_body = JSON.parse(@response.body)
     response_errors = response_body['errors']
     assert_not_nil response_errors, 'Expected error in response'
-    assert (response_errors.first.include? 'PermissionDenied'), 
+    assert (response_errors.first.include? 'PermissionDenied'),
           'Expected PermissionDeniedError'
   end
 
@@ -531,7 +531,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     response_body = JSON.parse(@response.body)
     response_errors = response_body['errors']
     assert_not_nil response_errors, 'Expected error in response'
-    assert (response_errors.first.include? 'Forbidden'), 
+    assert (response_errors.first.include? 'Forbidden'),
           'Expected Forbidden error'
   end
 
@@ -661,7 +661,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     created2 = JSON.parse(@response.body)
     assert_not_nil created2['uuid'], 'expected uuid for the newly created user'
     assert_equal created['uuid'], created2['uuid'], 'expected uuid not found'
-    
+
     verify_link_existence created['uuid'], created['email'], false, false, false, false
   end
 
@@ -724,7 +724,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
 
     link = find_obj_in_resp response_items, 'Link', link_object_name
 
-    if !expect_link 
+    if !expect_link
       assert_nil link, "Expected no link for #{link_object_name}"
       return
     end
@@ -738,16 +738,16 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     end
     assert_equal link['link_class'], link_class,
         "did not find expected link_class for #{link_object_name}"
+
     assert_equal link['name'], link_name,
         "did not find expected link_name for #{link_object_name}"
+
     assert_equal link['tail_uuid'], tail_uuid,
         "did not find expected tail_uuid for #{link_object_name}"
+
     assert_equal link['head_kind'], head_kind,
         "did not find expected head_kind for #{link_object_name}"
+
     assert_equal link['head_uuid'], head_uuid,
         "did not find expected head_uuid for #{link_object_name}"
   end
@@ -788,7 +788,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     signed_uuids = Link.where(link_class: 'signature',
                                   tail_kind: 'arvados#user',
                                   tail_uuid: uuid)
-          
+
     if expect_signatures
       assert signed_uuids.any?, "expected singnatures"
     else
index 82f61e0109663ddb34c9850653978c5280db0d59..9f78b1a3650320c29c37cc9d002d0e2cac484c41 100644 (file)
@@ -1,7 +1,281 @@
 require 'test_helper'
 
 class UserTest < ActiveSupport::TestCase
-  # test "the truth" do
-  #   assert true
-  # end
+
+  # The fixture services/api/test/fixtures/users.yml serves as the input for this test case
+  setup do
+    @all_users = User.find(:all)
+
+    @all_users.each do |user|
+      if user.is_admin && user.is_active
+        @admin_user = user
+      elsif user.is_active && !user.is_admin
+        @active_user = user
+      elsif !user.is_active && !user.is_invited
+        @uninvited_user = user
+      end
+    end
+  end
+
+  test "check non-admin active user properties" do
+    assert !@active_user.is_admin, 'is_admin should not be set for a non-admin user'
+    assert @active_user.is_active, 'user should be active'
+    assert @active_user.is_invited, 'is_invited should be set'
+    assert_not_nil @active_user.prefs, "user's preferences should be non-null, but may be size zero"
+    assert (@active_user.can? :read=>"#{@active_user.uuid}"), "user should be able to read own object"
+    assert (@active_user.can? :write=>"#{@active_user.uuid}"), "user should be able to write own object"
+    assert (@active_user.can? :manage=>"#{@active_user.uuid}"), "user should be able to manage own object"
+
+    assert @active_user.groups_i_can(:read).size > 0, "active user should be able read at least one group"
+
+    # non-admin user cannot manage or write other user objects
+    assert !(@active_user.can? :read=>"#{@uninvited_user.uuid}")
+    assert !(@active_user.can? :write=>"#{@uninvited_user.uuid}")
+    assert !(@active_user.can? :manage=>"#{@uninvited_user.uuid}")
+  end
+
+  test "check admin user properties" do
+    assert @admin_user.is_admin, 'is_admin should be set for admin user'
+    assert @admin_user.is_active, 'admin user cannot be inactive'
+    assert @admin_user.is_invited, 'is_invited should be set'
+    assert_not_nil @admin_user.uuid.size, "user's uuid should be non-null"
+    assert_not_nil @admin_user.prefs, "user's preferences should be non-null, but may be size zero"
+    assert @admin_user.identity_url.size > 0, "user's identity url is expected"
+    assert @admin_user.can? :read=>"#{@admin_user.uuid}"
+    assert @admin_user.can? :write=>"#{@admin_user.uuid}"
+    assert @admin_user.can? :manage=>"#{@admin_user.uuid}"
+
+    assert @admin_user.groups_i_can(:read).size > 0, "admin active user should be able read at least one group"
+    assert @admin_user.groups_i_can(:write).size > 0, "admin active user should be able write to at least one group"
+    assert @admin_user.groups_i_can(:manage).size > 0, "admin active user should be able manage at least one group"
+
+    # admin user can also write or manage other users
+    assert @admin_user.can? :read=>"#{@uninvited_user.uuid}"
+    assert @admin_user.can? :write=>"#{@uninvited_user.uuid}"
+    assert @admin_user.can? :manage=>"#{@uninvited_user.uuid}"
+  end
+
+  test "check inactive and uninvited user properties" do
+    assert !@uninvited_user.is_admin, 'is_admin should not be set for a non-admin user'
+    assert !@uninvited_user.is_active, 'user should be inactive'
+    assert !@uninvited_user.is_invited, 'is_invited should not be set'
+    assert @uninvited_user.can? :read=>"#{@uninvited_user.uuid}"
+    assert @uninvited_user.can? :write=>"#{@uninvited_user.uuid}"
+    assert @uninvited_user.can? :manage=>"#{@uninvited_user.uuid}"
+
+    assert @uninvited_user.groups_i_can(:read).size == 0, "inactive and uninvited user should not be able read any groups"
+    assert @uninvited_user.groups_i_can(:write).size == 0, "inactive and uninvited user should not be able write to any groups"
+    assert @uninvited_user.groups_i_can(:manage).size == 0, "inactive and uninvited user should not be able manage any groups"
+  end
+
+  test "find user method checks" do
+    User.find(:all).each do |user|
+      assert_not_nil user.uuid, "non-null uuid expected for " + user.full_name
+    end
+
+    user = users(:active)     # get the active user
+
+    found_user = User.find(user.id)   # find a user by the row id
+
+    assert_equal found_user.full_name, user.first_name + ' ' + user.last_name
+    assert_equal found_user.identity_url, user.identity_url
+  end
+
+  test "create new user" do
+    Thread.current[:user] = @admin_user   # set admin user as the current user
+
+    user = User.new
+    user.first_name = "first_name_for_newly_created_user"
+    user.save
+
+    # verify there is one extra user in the db now
+    assert (User.find(:all).size == @all_users.size+1)
+
+    user = User.find(user.id)   # get the user back
+    assert_equal(user.first_name, 'first_name_for_newly_created_user')
+    assert_not_nil user.uuid, 'uuid should be set for newly created user'
+    assert_nil user.email, 'email should be null for newly created user, because it was not passed in'
+    assert_nil user.identity_url, 'identity_url should be null for newly created user, because it was not passed in'
+
+    user.first_name = 'first_name_for_newly_created_user_updated'
+    user.save
+    user = User.find(user.id)   # get the user back
+    assert_equal(user.first_name, 'first_name_for_newly_created_user_updated')
+  end
+
+  test "update existing user" do
+    Thread.current[:user] = @active_user    # set active user as current user
+    @active_user.first_name = "first_name_changed"
+    @active_user.save
+
+    @active_user = User.find(@active_user.id)   # get the user back
+    assert_equal(@active_user.first_name, 'first_name_changed')
+
+    # admin user also should be able to update the "active" user info
+    Thread.current[:user] = @admin_user # set admin user as current user
+    @active_user.first_name = "first_name_changed_by_admin_for_active_user"
+    @active_user.save
+
+    @active_user = User.find(@active_user.id)   # get the user back
+    assert_equal(@active_user.first_name, 'first_name_changed_by_admin_for_active_user')
+  end
+
+  test "delete a user and verify" do
+    active_user_uuid = @active_user.uuid
+
+    Thread.current[:user] = @admin_user
+    @active_user.delete
+
+    found_deleted_user = false
+    User.find(:all).each do |user|
+      if user.uuid == active_user_uuid
+        found_deleted_user = true
+        break
+      end
+    end
+    assert !found_deleted_user, "found deleted user: "+active_user_uuid
+
+  end
+
+  test "create new user as non-admin user" do
+    Thread.current[:user] = @active_user
+
+    begin
+      user = User.new
+      user.save
+    rescue ArvadosModel::PermissionDeniedError => e
+    end
+    assert (e.message.include? 'PermissionDeniedError'),
+        'Expected PermissionDeniedError'
+  end
+
+  test "setup new user" do
+    Thread.current[:user] = @admin_user
+
+    email = 'foo@example.com'
+    openid_prefix = 'http://openid/prefix'
+
+    user = User.new
+    user.email = email
+    user.uuid = 'abcdefghijklmnop'
+
+    vm = VirtualMachine.create
+
+    response = User.setup user, openid_prefix, 'test_repo', vm.uuid
+
+    resp_user = find_obj_in_resp response, 'User'
+    verify_user resp_user, email
+
+    oid_login_perm = find_obj_in_resp response, 'Link', 'arvados#user'
+    verify_link oid_login_perm, 'permission', 'can_login', resp_user[:email],
+        resp_user[:uuid]
+    assert_equal openid_prefix, oid_login_perm[:properties][:identity_url_prefix],
+        'expected identity_url_prefix not found for oid_login_perm'
+
+    group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
+    verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
+
+    repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository'
+    verify_link repo_perm, 'permission', 'can_write', resp_user[:uuid], nil
+
+    vm_perm = find_obj_in_resp response, 'Link', 'arvados#virtualMachine'
+    verify_link vm_perm, 'permission', 'can_login', resp_user[:uuid], vm.uuid
+  end
+
+  test "setup new user in multiple steps" do
+    Thread.current[:user] = @admin_user
+
+    email = 'foo@example.com'
+    openid_prefix = 'http://openid/prefix'
+
+    user = User.new
+    user.email = email
+    user.uuid = 'abcdefghijklmnop'
+
+    response = User.setup user, openid_prefix
+
+    resp_user = find_obj_in_resp response, 'User'
+    verify_user resp_user, email
+
+    oid_login_perm = find_obj_in_resp response, 'Link', 'arvados#user'
+    verify_link oid_login_perm, 'permission', 'can_login', resp_user[:email],
+        resp_user[:uuid]
+    assert_equal openid_prefix, oid_login_perm[:properties][:identity_url_prefix],
+        'expected identity_url_prefix not found for oid_login_perm'
+
+    group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
+    verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
+
+    # invoke setup again with repo_name
+    response = User.setup user, openid_prefix, 'test_repo'
+    resp_user = find_obj_in_resp response, 'User', nil
+    verify_user resp_user, email
+    assert_equal user.uuid, resp_user[:uuid], 'expected uuid not found'
+
+    group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
+    verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
+
+    repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository'
+    verify_link repo_perm, 'permission', 'can_write', resp_user[:uuid], nil
+
+    # invoke setup again with a vm_uuid
+    vm = VirtualMachine.create
+
+    response = User.setup user, openid_prefix, 'test_repo', vm.uuid
+
+    resp_user = find_obj_in_resp response, 'User', nil
+    verify_user resp_user, email
+    assert_equal user.uuid, resp_user[:uuid], 'expected uuid not found'
+
+    group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
+    verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
+
+    repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository'
+    verify_link repo_perm, 'permission', 'can_write', resp_user[:uuid], nil
+
+    vm_perm = find_obj_in_resp response, 'Link', 'arvados#virtualMachine'
+    verify_link vm_perm, 'permission', 'can_login', resp_user[:uuid], vm.uuid
+  end
+
+  def find_obj_in_resp (response, object_type, head_kind=nil)
+    return_obj = nil
+    response.each { |x|
+      if x.class.name == object_type
+        if head_kind
+          if x.head_kind == head_kind
+            return_obj = x
+            break
+          end
+        else
+          return_obj = x
+          break
+        end
+      end
+    }
+    return return_obj
+  end
+
+  def verify_user (resp_user, email)
+    assert_not_nil resp_user, 'expected user object'
+    assert_not_nil resp_user['uuid'], 'expected user object'
+    assert_equal email, resp_user['email'], 'expected email not found'
+
+  end
+
+  def verify_link (link_object, link_class, link_name, tail_uuid, head_uuid)
+    assert_not_nil link_object, 'expected link for #{link_class} #{link_name}'
+    assert_not_nil link_object[:uuid],
+        'expected non-nil uuid for link for #{link_class} #{link_name}'
+    assert_equal link_class, link_object[:link_class],
+        'expected link_class not found for #{link_class} #{link_name}'
+    assert_equal link_name, link_object[:name],
+        'expected link_name not found for #{link_class} #{link_name}'
+    assert_equal tail_uuid, link_object[:tail_uuid],
+        'expected tail_uuid not found for #{link_class} #{link_name}'
+    if head_uuid
+      assert_equal head_uuid, link_object[:head_uuid],
+          'expected head_uuid not found for #{link_class} #{link_name}'
+    end
+  end
+
 end