--- /dev/null
+<%
+ profile_config = Rails.configuration.user_profile_form_fields
+ current_user_profile = current_user.prefs[:profile]
+ show_save_button = false
+
+ profile_message = Rails.configuration.user_profile_form_message ? Rails.configuration.user_profile_form_message : 'You can manage your profile using this page. Any feilds in red are required and missing. Please fill in those fields before you can accesse Arvados Workbench.'
+
+ missing_required = missing_required_profile?
+
+ profile_url = '/users/'+current_user.uuid+'/profile'
+ target = request.url.partition('?target=')[-1]
+ target = request.url if target.empty?
+ return_to_url = (request.url.ends_with? profile_url) ? profile_url : profile_url+'?target='+target
+%>
+
+<div>
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ <h4 class="panel-title">
+ Profile
+ </h4>
+ </div>
+ <div class="panel-body">
+ <% if !missing_required && params.andand.keys.include?('target') %>
+ <div class="rounded" style="border-width: 1px; border-style: dotted; border-color: lightgray;">
+ <p style="margin: 8px;">Thank you for filling in your profile. If you are done updating your profile,
+ you can now access Arvados Workbench by clicking on this button.
+ <form action="<%=target%>">
+ <input style="margin-left: 8px;" class="btn btn-primary" type="submit" value="Access Arvados Workbench">
+ </form>
+ </p>
+ </div>
+ <% else %>
+ <div class="rounded" style="border-width: 1px; border-style: dotted; border-color: lightgray;">
+ <p style="margin: 8px;"> <%=raw(profile_message)%> </p>
+ </div>
+ <% end %>
+
+ <div class="rounded" style="border-width: 1px; border-style: dotted; border-color: lightgray;">
+ <%= form_tag "/users/#{current_user.uuid}", {method: 'patch', id: 'save_profile_form', name: 'save_profile_form', class: 'form-horizontal'} do %>
+ <%= hidden_field_tag :return_to, return_to_url %>
+ <div class="form-group">
+ <label for="email" class="col-sm-3 control-label"> Email </label>
+ <div class="col-sm-8">
+ <p class="form-control-static" id="email" name="email"><%=current_user.email%></p>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="first_name" class="col-sm-3 control-label"> First name </label>
+ <div class="col-sm-8">
+ <p class="form-control-static" id="first_name" name="first_name"><%=current_user.first_name%></p>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="last_name" class="col-sm-3 control-label"> Last name </label>
+ <div class="col-sm-8">
+ <p class="form-control-static" id="last_name" name="last_name"><%=current_user.last_name%></p>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="identity_url" class="col-sm-3 control-label"> Identity URL </label>
+ <div class="col-sm-8">
+ <p class="form-control-static" id="identity_url" name="identity_url"><%=current_user.andand.identity_url%></p>
+ </div>
+ </div>
+
+ <% profile_config.kind_of?(Array) && profile_config.andand.each do |entry| %>
+ <% if entry['key'] %>
+ <%
+ show_save_button = true
+ label = entry['required'] ? '* ' : ''
+ label += entry['form_field_title']
+ value = current_user_profile[entry['key'].to_sym] if current_user_profile
+ %>
+ <div class="form-group">
+ <label for="<%=entry['key']%>"
+ class="col-sm-3 control-label"
+ style=<%="color:red" if entry['required']&&(!value||value.empty?)%>> <%=label%>
+ </label>
+ <% if entry['type'] == 'select' %>
+ <div class="col-sm-8">
+ <select class="form-control" name="user[prefs][:profile][:<%=entry['key']%>]">
+ <% entry['options'].each do |option| %>
+ <option value="<%=option%>" <%='selected' if option==value%>><%=option%></option>
+ <% end %>
+ </select>
+ </div>
+ <% else %>
+ <div class="col-sm-8">
+ <input type="text" class="form-control" name="user[prefs][:profile][:<%=entry['key']%>]" placeholder="<%=entry['form_field_description']%>" value="<%=value%>" ></input>
+ </div>
+ <% end %>
+ </div>
+ <% end %>
+ <% end %>
+
+ <% if show_save_button %>
+ <div class="form-group">
+ <div class="col-sm-offset-3 col-sm-8">
+ <button type="submit" class="btn btn-primary">Save profile</button>
+ </div>
+ </div>
+ <% end %>
+ <% end %>
+ </div>
+ </div>
+ </div>
+</div>
--- /dev/null
+require 'integration_helper'
+require 'selenium-webdriver'
+require 'headless'
+
+class ApplicationLayoutTest < ActionDispatch::IntegrationTest
+ setup do
+ headless = Headless.new
+ headless.start
+ Capybara.current_driver = :selenium
+
+ @user_profile_form_fields = Rails.configuration.user_profile_form_fields
+ end
+
+ teardown do
+ Rails.configuration.user_profile_form_fields = @user_profile_form_fields
+ end
+
+ def verify_homepage_with_profile user, invited, has_profile
+ profile_config = Rails.configuration.user_profile_form_fields
+
+ if !user
+ assert page.has_text? 'Please log in'
+ assert page.has_text? 'The "Log in" button below will show you a Google sign-in page'
+ assert page.has_no_text? 'My projects'
+ assert page.has_link? "Log in to #{Rails.configuration.site_name}"
+ elsif profile_config && !has_profile && user['is_active']
+ add_profile user
+ elsif user['is_active']
+ assert page.has_text? 'My projects'
+ assert page.has_text? 'Projects shared with me'
+ assert page.has_no_text? 'Save profile'
+ elsif invited
+ assert page.has_text? 'Please check the box below to indicate that you have read and accepted the user agreement'
+ assert page.has_no_text? 'Save profile'
+ else
+ assert page.has_text? 'Your account is inactive'
+ assert page.has_no_text? 'Save profile'
+ end
+
+ within('.navbar-fixed-top') do
+ if !user
+ assert page.has_link? 'Log in'
+ else
+ # my account menu
+ assert page.has_link? "#{user['email']}"
+ find('a', text: "#{user['email']}").click
+ within('.dropdown-menu') do
+ if !invited
+ page.has_no_link? ('Not active')
+ else
+ page.has_no_link? ('Sign agreements')
+ page.has_link? ('Manage account')
+
+ if profile_config
+ page.has_link? ('Manage profile')
+ else
+ page.has_no_link? ('Manage profile')
+ end
+ end
+ page.has_link? ('Log out')
+ end
+ end
+ end
+ end
+
+ # test the help menu
+ def check_help_menu
+ within('.navbar-fixed-top') do
+ page.find("#arv-help").click
+ within('.dropdown-menu') do
+ assert page.has_link? 'Tutorials and User guide'
+ assert page.has_link? 'API Reference'
+ assert page.has_link? 'SDK Reference'
+ end
+ end
+ end
+
+ def verify_system_menu user
+ if user && user['is_active']
+ look_for_add_new = nil
+ within('.navbar-fixed-top') do
+ page.find("#system-menu").click
+ if user['is_admin']
+ within('.dropdown-menu') do
+ assert page.has_text? 'Groups'
+ assert page.has_link? 'Repositories'
+ assert page.has_link? 'Virtual machines'
+ assert page.has_link? 'SSH keys'
+ assert page.has_link? 'API tokens'
+ find('a', text: 'Users').click
+ look_for_add_new = 'Add a new user'
+ end
+ else
+ within('.dropdown-menu') do
+ assert page.has_no_text? 'Users'
+ assert page.has_no_link? 'Repositories'
+ assert page.has_no_link? 'Virtual machines'
+ assert page.has_no_link? 'SSH keys'
+ assert page.has_no_link? 'API tokens'
+
+ find('a', text: 'Groups').click
+ look_for_add_new = 'Add a new group'
+ end
+ end
+ end
+ if look_for_add_new
+ assert page.has_text? look_for_add_new
+ end
+ else
+ assert page.has_no_link? '#system-menu'
+ end
+ end
+
+ # test manage_account page
+ def verify_manage_account user
+ if user && user['is_active']
+ within('.navbar-fixed-top') do
+ find('a', text: "#{user['email']}").click
+ within('.dropdown-menu') do
+ find('a', text: 'Manage account').click
+ end
+ end
+
+ # now in manage account page
+ assert page.has_text? 'Virtual Machines'
+ assert page.has_text? 'Repositories'
+ assert page.has_text? 'SSH Keys'
+ assert page.has_text? 'Current Token'
+
+ assert page.has_text? 'The Arvados API token is a secret key that enables the Arvados SDKs to access Arvados'
+
+ click_link 'Add new SSH key'
+
+ within '.modal-content' do
+ assert page.has_text? 'Public Key'
+ assert page.has_button? 'Cancel'
+ assert page.has_button? 'Submit'
+
+ page.find_field('public_key').set 'first test with an incorrect ssh key value'
+ click_button 'Submit'
+ assert page.has_text? 'Public key does not appear to be a valid ssh-rsa or dsa public key'
+
+ public_key_str = api_fixture('authorized_keys')['active']['public_key']
+ page.find_field('public_key').set public_key_str
+ page.find_field('name').set 'added_in_test'
+ click_button 'Submit'
+ assert page.has_text? 'Public key already exists in the database, use a different key.'
+
+ new_key = SSHKey.generate
+ page.find_field('public_key').set new_key.ssh_public_key
+ page.find_field('name').set 'added_in_test'
+ click_button 'Submit'
+ end
+ end
+
+ # key must be added. look for it in the refreshed page
+ assert page.has_text? 'added_in_test'
+ end
+
+ # Check manage profile page and add missing profile to the user
+ def add_profile user
+ assert page.has_no_text? 'My projects'
+ assert page.has_no_text? 'Projects shared with me'
+
+ assert page.has_text? 'Profile'
+ assert page.has_text? 'First name'
+ assert page.has_text? 'Last name'
+ assert page.has_text? 'Identity URL'
+ assert page.has_text? 'Email'
+ assert page.has_text? user['email']
+
+ # Using the default profile which has message and one required field
+
+ # Save profile without filling in the required field. Expect to be back in this profile page again
+ click_button "Save profile"
+ assert page.has_text? 'Profile'
+ assert page.has_text? 'First name'
+ assert page.has_text? 'Last name'
+ assert page.has_text? 'Save profile'
+
+ # This time fill in required field and then save. Expect to go to requested page after that.
+ profile_message = Rails.configuration.user_profile_form_message
+ required_field_title = ''
+ required_field_key = ''
+ profile_config = Rails.configuration.user_profile_form_fields
+ profile_config.andand.each do |entry|
+ if entry['required']
+ required_field_key = entry['key']
+ required_field_title = entry['form_field_title']
+ end
+ end
+
+ assert page.has_text? profile_message[0,25]
+ assert page.has_text? required_field_title
+ page.find_field('user[prefs][:profile][:'+required_field_key+']').set 'value to fill required field'
+
+ click_button "Save profile"
+ # profile saved and in profile page now with success
+ assert page.has_text? 'Thank you for filling in your profile'
+ click_button 'Access Arvados Workbench'
+
+ # profile saved and in home page now
+ assert page.has_text? 'My projects'
+ assert page.has_text? 'Projects shared with me'
+ end
+
+ # test the search box
+ def verify_search_box user
+ if user && user['is_active']
+ # let's search for a valid uuid
+ within('.navbar-fixed-top') do
+ page.find_field('search').set user['uuid']
+ page.find('.glyphicon-search').click
+ end
+
+ # we should now be in the user's page as a result of search
+ assert page.has_text? user['first_name']
+
+ # let's search again for an invalid valid uuid
+ within('.navbar-fixed-top') do
+ search_for = String.new user['uuid']
+ search_for[0]='1'
+ page.find_field('search').set search_for
+ page.find('.glyphicon-search').click
+ end
+
+ # we should see 'not found' error page
+ assert page.has_text? 'Not Found'
+
+ # let's search for the anonymously accessible project
+ publicly_accessible_project = api_fixture('groups')['anonymously_accessible_project']
+
+ within('.navbar-fixed-top') do
+ # search again for the anonymously accessible project
+ page.find_field('search').set publicly_accessible_project['name'][0,10]
+ page.find('.glyphicon-search').click
+ end
+
+ within '.modal-content' do
+ assert page.has_text? 'All projects'
+ assert page.has_text? 'Search'
+ assert page.has_text? 'Cancel'
+ assert_selector('div', text: publicly_accessible_project['name'])
+ find(:xpath, '//div[./span[contains(.,publicly_accessible_project["uuid"])]]').click
+
+ click_button 'Show'
+ end
+
+ # seeing "Unrestricted public data" now
+ assert page.has_text? publicly_accessible_project['name']
+ assert page.has_text? publicly_accessible_project['description']
+ end
+ end
+
+ [
+ [nil, nil, false, false],
+ ['inactive', api_fixture('users')['inactive'], true, false],
+ ['inactive_uninvited', api_fixture('users')['inactive_uninvited'], false, false],
+ ['active', api_fixture('users')['active'], true, true],
+ ['admin', api_fixture('users')['admin'], true, true],
+ ['active_no_prefs', api_fixture('users')['active_no_prefs'], true, false],
+ ['active_no_prefs_profile', api_fixture('users')['active_no_prefs_profile'], true, false],
+ ].each do |token, user, invited, has_profile|
+ test "visit home page when profile is configured for user #{token}" do
+ # Our test config enabled profile by default. So, no need to update config
+ if !token
+ visit ('/')
+ else
+ visit page_with_token(token)
+ end
+
+ verify_homepage_with_profile user, invited, has_profile
+ end
+ end
+
+ [
+ [nil, nil, false, false],
+ ['inactive', api_fixture('users')['inactive'], true, false],
+ ['inactive_uninvited', api_fixture('users')['inactive_uninvited'], false, false],
+ ['active', api_fixture('users')['active'], true, true],
+ ['admin', api_fixture('users')['admin'], true, true],
+ ['active_no_prefs', api_fixture('users')['active_no_prefs'], true, false],
+ ['active_no_prefs_profile', api_fixture('users')['active_no_prefs_profile'], true, false],
+ ].each do |token, user, invited, has_profile|
+ test "visit home page when profile not configured for user #{token}" do
+ Rails.configuration.user_profile_form_fields = false
+
+ if !token
+ visit ('/')
+ else
+ visit page_with_token(token)
+ end
+
+ verify_homepage_with_profile user, invited, has_profile
+ end
+ end
+
+ [
+ [nil, nil, false, false],
+ ['inactive', api_fixture('users')['inactive'], true, false],
+ ['inactive_uninvited', api_fixture('users')['inactive_uninvited'], false, false],
+ ['active', api_fixture('users')['active'], true, true],
+ ['admin', api_fixture('users')['admin'], true, true],
+ ['active_no_prefs', api_fixture('users')['active_no_prefs'], true, false],
+ ['active_no_prefs_profile', api_fixture('users')['active_no_prefs_profile'], true, false],
+ ].each do |token, user, invited, has_profile|
+ test "check help for user #{token}" do
+ Rails.configuration.user_profile_form_fields = false
+
+ if !token
+ visit ('/')
+ else
+ visit page_with_token(token)
+ end
+
+ check_help_menu
+ end
+ end
+
+ [
+ ['active', api_fixture('users')['active'], true, true],
+ ['admin', api_fixture('users')['admin'], true, true],
+ ].each do |token, user|
+ test "test system menu for user #{token}" do
+ visit page_with_token(token)
+ verify_system_menu user
+ end
+ end
+
+ [
+ ['active', api_fixture('users')['active'], true, true],
+ ['admin', api_fixture('users')['admin'], true, true],
+ ].each do |token, user|
+ test "test manage account for user #{token}" do
+ visit page_with_token(token)
+ verify_manage_account user
+ end
+ end
+
+ [
+ ['active', api_fixture('users')['active'], true, true],
+ ['admin', api_fixture('users')['admin'], true, true],
+ ].each do |token, user|
+ test "test search for user #{token}" do
+ visit page_with_token(token)
+ verify_search_box user
+ end
+ end
+
+end