Commit 05702e4a65b0a4d79d836a4919eff54ab174e9d1
Committed by
Luciano Prestes
1 parent
79818886
Exists in
staging
and in
42 other branches
Suggest available username
(ActionItem3009) Signed-off-by: Alex Campelo <campelo.al1@gmail.com> Signed-off-by: Gustavo Jaruga <darksshades@gmail.com> Signed-off-by: David Carlos <ddavidcarlos1392@gmail.com> Signed-off-by: Arhur Del Esposte <arthurmde@gmail.com> Signed-off-by: Luciano Prestes <lucianopcbr@gmail.com> Signed-off-by: Fabio Teixeira <fabio1079@gmail.com>
Showing
7 changed files
with
100 additions
and
22 deletions
Show diff stats
app/controllers/public/account_controller.rb
| ... | ... | @@ -250,15 +250,19 @@ class AccountController < ApplicationController |
| 250 | 250 | end |
| 251 | 251 | end |
| 252 | 252 | |
| 253 | - def check_url | |
| 253 | + def check_valid_name | |
| 254 | 254 | @identifier = params[:identifier] |
| 255 | 255 | valid = Person.is_available?(@identifier, environment) |
| 256 | 256 | if valid |
| 257 | 257 | @status = _('This login name is available') |
| 258 | 258 | @status_class = 'validated' |
| 259 | - else | |
| 259 | + elsif !@identifier.empty? | |
| 260 | + @suggested_usernames = suggestion_based_on_username(@identifier) | |
| 260 | 261 | @status = _('This login name is unavailable') |
| 261 | 262 | @status_class = 'invalid' |
| 263 | + else | |
| 264 | + @status_class = 'invalid' | |
| 265 | + @status = _('This field can\'t be blank') | |
| 262 | 266 | end |
| 263 | 267 | render :partial => 'identifier_status' |
| 264 | 268 | end | ... | ... |
app/helpers/account_helper.rb
| ... | ... | @@ -12,4 +12,17 @@ module AccountHelper |
| 12 | 12 | _('Checking if e-mail address is already taken...') |
| 13 | 13 | end |
| 14 | 14 | end |
| 15 | + | |
| 16 | + def suggestion_based_on_username(requested_username) | |
| 17 | + return "" if requested_username.empty? | |
| 18 | + usernames = [] | |
| 19 | + 3.times do | |
| 20 | + begin | |
| 21 | + valid_name = requested_username + rand(1000).to_s | |
| 22 | + end while (usernames.include?(valid_name) && Person.is_available?(valid_name, environment)) | |
| 23 | + usernames += [valid_name] | |
| 24 | + end | |
| 25 | + usernames | |
| 26 | + end | |
| 27 | + | |
| 15 | 28 | end | ... | ... |
app/views/account/_identifier_status.rhtml
| 1 | 1 | <div class='status-identifier'> |
| 2 | + <% if @suggested_usernames %> | |
| 3 | + <% @status += '<br>' + _('Available: ') if not @suggested_usernames.empty? %> | |
| 4 | + <% @suggested_usernames.each do |username| %> | |
| 5 | + <% @status += "<a href='#' class='suggested_usernames'>" + username + '</a> ' %> | |
| 6 | + <%end%> | |
| 7 | + <% end %> | |
| 8 | + | |
| 9 | + | |
| 2 | 10 | <p><span class='<%= @status_class %>'><%= @status %></span></p> |
| 3 | 11 | <script type="text/javascript"> |
| 4 | 12 | jQuery('#user_login').removeClass('<%= validation_classes %>'); |
| 5 | 13 | jQuery('#user_login').addClass('<%= @status_class %>'); |
| 14 | + jQuery('.suggested_usernames').click(function(e) { | |
| 15 | + e.preventDefault(); | |
| 16 | + | |
| 17 | + fill_username(this.innerHTML); | |
| 18 | + }); | |
| 6 | 19 | </script> |
| 7 | 20 | -</div> |
| 21 | +</div> | |
| 8 | 22 | \ No newline at end of file | ... | ... |
app/views/account/_signup_form.rhtml
| ... | ... | @@ -40,15 +40,7 @@ |
| 40 | 40 | <br style="clear: both;" /> |
| 41 | 41 | </div> |
| 42 | 42 | </div> |
| 43 | - <%= observe_field 'user_login', | |
| 44 | - :url => { :action => 'check_url' }, | |
| 45 | - :with => 'identifier', | |
| 46 | - :update => 'url-check', | |
| 47 | - :loading => "jQuery('#user_login').removeClass('#{validation_classes}').addClass('checking'); | |
| 48 | - jQuery('#url-check').html('<p><span class=\"checking\">#{checking_message(:url)}</span></p>');", | |
| 49 | - :complete => "jQuery('#user_login').removeClass('checking')" | |
| 50 | - %> | |
| 51 | - | |
| 43 | + <%= javascript_include_tag "signup_form" %> | |
| 52 | 44 | <div id='signup-password'> |
| 53 | 45 | <%= required f.password_field(:password, :id => 'user_pw') %> |
| 54 | 46 | <%= content_tag(:small,_('Choose a password that you can remember easily. It must have at least 4 characters.'), :id => 'password-balloon') %> |
| ... | ... | @@ -182,4 +174,9 @@ jQuery(function($) { |
| 182 | 174 | else $(this).addClass('validated'); |
| 183 | 175 | }); |
| 184 | 176 | }); |
| 177 | + | |
| 178 | +function fill_username(element){ | |
| 179 | + jQuery('#url-check').html('<p><span class=\"checking\"><%= _('This login name is available') %></span></p>') | |
| 180 | + jQuery('#user_login').val(element).addClass('validated').removeClass('invalid') | |
| 181 | +} | |
| 185 | 182 | </script> | ... | ... |
features/signup.feature
| ... | ... | @@ -29,13 +29,32 @@ Feature: signup |
| 29 | 29 | And I press "Log in" |
| 30 | 30 | Then I should be logged in as "josesilva" |
| 31 | 31 | |
| 32 | + @selenium | |
| 33 | + Scenario: show error message if username is already used | |
| 34 | + Given I am on the homepage | |
| 35 | + When I follow "Login" | |
| 36 | + And I follow "New user" | |
| 37 | + And I fill in the following within ".no-boxes": | |
| 38 | + | e-Mail | josesilva@example.com | | |
| 39 | + | Username | josesilva | | |
| 40 | + | Password | secret | | |
| 41 | + | Password confirmation | secret | | |
| 42 | + | Full name | José da Silva | | |
| 43 | + And wait for the captcha signup time | |
| 44 | + And I press "Create my account" | |
| 45 | + Then I should receive an e-mail on josesilva@example.com | |
| 46 | + And I go to signup page | |
| 47 | + And I fill in "Username" with "josesilva" | |
| 48 | + And I fill in "e-Mail" with "josesilva1" | |
| 49 | + Then I should see "This login name is unavailable" | |
| 50 | + | |
| 32 | 51 | Scenario: be redirected if user goes to signup page and is logged |
| 33 | 52 | Given the following users |
| 34 | 53 | | login | name | |
| 35 | - | joaosilva | Joao Silva | | |
| 36 | - Given I am logged in as "joaosilva" | |
| 37 | - And I go to signup page | |
| 38 | - Then I should be on joaosilva's control panel | |
| 54 | + | joaosilva | joao silva | | |
| 55 | + Given i am logged in as "joaosilva" | |
| 56 | + And i go to signup page | |
| 57 | + Then i should be on joaosilva's control panel | |
| 39 | 58 | |
| 40 | 59 | @selenium |
| 41 | 60 | Scenario: user cannot register without a name | ... | ... |
| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | +function verifyLoginLoad() { | |
| 2 | + jQuery('#user_login').removeClass('available unavailable valid validated invalid checking').addClass('checking'); | |
| 3 | + jQuery('#url-check').html('<p><span class="checking">Checking availability of login name...</span></p>'); | |
| 4 | +} | |
| 5 | + | |
| 6 | +function verifyLoginAjax(value) { | |
| 7 | + verifyLoginLoad(); | |
| 8 | + | |
| 9 | + jQuery.get( | |
| 10 | + "/account/check_valid_name", | |
| 11 | + {'identifier': encodeURIComponent(value)}, | |
| 12 | + function(request){ | |
| 13 | + jQuery('#user_login').removeClass('checking'); | |
| 14 | + jQuery("#url-check").html(request); | |
| 15 | + } | |
| 16 | + ); | |
| 17 | +} | |
| 18 | + | |
| 19 | +jQuery(document).ready(function(){ | |
| 20 | + jQuery("#user_login").blur(function(){ | |
| 21 | + verifyLoginAjax(this.value); | |
| 22 | + }); | |
| 23 | +}); | |
| 0 | 24 | \ No newline at end of file | ... | ... |
test/functional/account_controller_test.rb
| ... | ... | @@ -8,7 +8,6 @@ class AccountControllerTest < ActionController::TestCase |
| 8 | 8 | # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead |
| 9 | 9 | # Then, you can remove it from this and the units test. |
| 10 | 10 | include AuthenticatedTestHelper |
| 11 | - | |
| 12 | 11 | all_fixtures |
| 13 | 12 | |
| 14 | 13 | def teardown |
| ... | ... | @@ -17,8 +16,8 @@ class AccountControllerTest < ActionController::TestCase |
| 17 | 16 | |
| 18 | 17 | def setup |
| 19 | 18 | @controller = AccountController.new |
| 20 | - @request = ActionController::TestRequest.new | |
| 21 | - @response = ActionController::TestResponse.new | |
| 19 | + @request = ActionController::TestRequest.new | |
| 20 | + @response = ActionController::TestResponse.new | |
| 22 | 21 | disable_signup_bot_check |
| 23 | 22 | end |
| 24 | 23 | |
| ... | ... | @@ -36,6 +35,16 @@ class AccountControllerTest < ActionController::TestCase |
| 36 | 35 | assert_response :redirect |
| 37 | 36 | end |
| 38 | 37 | |
| 38 | + should 'return empty string if suggest_based_on_username argument is empty' do | |
| 39 | + result = @controller.suggestion_based_on_username("") | |
| 40 | + assert_equal(result.empty?,true) | |
| 41 | + end | |
| 42 | + | |
| 43 | + should 'return a list with three possible usernames suggestion' do | |
| 44 | + result = @controller.suggestion_based_on_username("teste") | |
| 45 | + assert_equal(result.uniq.size,3) | |
| 46 | + end | |
| 47 | + | |
| 39 | 48 | should 'display notice message if the login fail' do |
| 40 | 49 | @controller.stubs(:logged_in?).returns(false) |
| 41 | 50 | post :login, :user => {:login => 'quire', :password => 'quire'} |
| ... | ... | @@ -646,18 +655,18 @@ class AccountControllerTest < ActionController::TestCase |
| 646 | 655 | assert_redirected_to :controller => 'home', :action => 'index' |
| 647 | 656 | end |
| 648 | 657 | |
| 649 | - should 'check_url is available on environment' do | |
| 658 | + should 'check_valid_name is available on environment' do | |
| 650 | 659 | env = fast_create(Environment, :name => 'Environment test') |
| 651 | 660 | @controller.expects(:environment).returns(env).at_least_once |
| 652 | 661 | profile = create_user('mylogin').person |
| 653 | - get :check_url, :identifier => 'mylogin' | |
| 662 | + get :check_valid_name, :identifier => 'mylogin' | |
| 654 | 663 | assert_equal 'validated', assigns(:status_class) |
| 655 | 664 | end |
| 656 | 665 | |
| 657 | 666 | should 'check if url is not available on environment' do |
| 658 | 667 | @controller.expects(:environment).returns(Environment.default).at_least_once |
| 659 | 668 | profile = create_user('mylogin').person |
| 660 | - get :check_url, :identifier => 'mylogin' | |
| 669 | + get :check_valid_name, :identifier => 'mylogin' | |
| 661 | 670 | assert_equal 'invalid', assigns(:status_class) |
| 662 | 671 | end |
| 663 | 672 | ... | ... |