diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index e7d288088..cca0137e7 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -35,6 +35,7 @@
//= require users
//= require votes
//= require annotatable
+//= require registration_form
var initialize_modules = function() {
@@ -48,6 +49,7 @@ var initialize_modules = function() {
App.PreventDoubleSubmission.initialize();
App.IeAlert.initialize();
App.Annotatable.initialize();
+ App.RegistrationForm.initialize();
};
$(function(){
diff --git a/app/assets/javascripts/registration_form.js.coffee b/app/assets/javascripts/registration_form.js.coffee
new file mode 100644
index 000000000..0588f59be
--- /dev/null
+++ b/app/assets/javascripts/registration_form.js.coffee
@@ -0,0 +1,25 @@
+App.RegistrationForm =
+
+ initialize: ->
+
+ registrationForm = $("form#new_user[action=\"/users\"]")
+ usernameInput = $("input#user_username")
+
+ clearUsernameMessage = ->
+ $("small").remove()
+
+ showUsernameMessage = (response) ->
+ klass = if response.available then "error no-error" else "error error"
+ usernameInput.after $("#{response.message}")
+
+ validateUsername = (username) ->
+ request = $.post "/user/registrations/check_username?username=#{username}"
+ request.done (response) ->
+ showUsernameMessage(response)
+
+
+ if registrationForm.length > 0
+ usernameInput.on "focusout", ->
+ clearUsernameMessage()
+ username = usernameInput.val();
+ validateUsername(username) if username != ""
diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss
index 650621624..f2e1be3d1 100644
--- a/app/assets/stylesheets/layout.scss
+++ b/app/assets/stylesheets/layout.scss
@@ -843,6 +843,11 @@ span.error, small.error {
color: $alert-color;
}
+span.error, small.no-error {
+ background: $success-bg;
+ color: $success-color;
+}
+
.error small.error {
background: $alert-bg;
color: $alert-color;
diff --git a/app/controllers/users/registrations_controller.rb b/app/controllers/users/registrations_controller.rb
index a707d7e75..d14cff907 100644
--- a/app/controllers/users/registrations_controller.rb
+++ b/app/controllers/users/registrations_controller.rb
@@ -36,6 +36,14 @@ class Users::RegistrationsController < Devise::RegistrationsController
end
end
+ def check_username
+ if User.find_by_username params[:username]
+ render json: {available: false, message: t("devise_views.users.registrations.new.username_is_not_available")}
+ else
+ render json: {available: true, message: t("devise_views.users.registrations.new.username_is_available")}
+ end
+ end
+
private
def sign_up_params
diff --git a/config/locales/devise_views.en.yml b/config/locales/devise_views.en.yml
index 508cfd820..688f8697a 100755
--- a/config/locales/devise_views.en.yml
+++ b/config/locales/devise_views.en.yml
@@ -71,6 +71,8 @@ en:
organization_signup_link: "Sign up here"
terms: "By registering you accept the %{terms}"
terms_link: "terms and conditions of use"
+ username_is_available: "The username chosen is available."
+ username_is_not_available: "The username chosen is not available."
success:
title: "Modify your email"
thank_you_html: "Thank you for registering for the website. You must now confirm your email address."
diff --git a/config/locales/devise_views.es.yml b/config/locales/devise_views.es.yml
index 83aea1d48..89c3745d8 100644
--- a/config/locales/devise_views.es.yml
+++ b/config/locales/devise_views.es.yml
@@ -71,6 +71,8 @@ es:
organization_signup_link: "Regístrate aquí"
terms: "Al registrarte aceptas las %{terms}"
terms_link: "condiciones de uso"
+ username_is_available: "El nombre de usuario elegido está disponible."
+ username_is_not_available: "El nombre de usuario elegido no está disponible."
success:
title: "Revisa tu correo"
thank_you_html: "Gracias por registrarte en la web. Ahora debes confirmar tu correo."
diff --git a/config/routes.rb b/config/routes.rb
index bfdecc59f..2ca63dd42 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -19,7 +19,7 @@ Rails.application.routes.draw do
devise_scope :user do
patch '/user/confirmation', to: 'users/confirmations#update', as: :update_user_confirmation
-
+ post '/user/registrations/check_username', to: 'users/registrations#check_username'
get 'users/sign_up/success', to: 'users/registrations#success'
get 'users/registrations/delete_form', to: 'users/registrations#delete_form'
delete 'users/registrations', to: 'users/registrations#delete'
diff --git a/spec/controllers/users/registrations_controller_spec.rb b/spec/controllers/users/registrations_controller_spec.rb
new file mode 100644
index 000000000..6f4c22488
--- /dev/null
+++ b/spec/controllers/users/registrations_controller_spec.rb
@@ -0,0 +1,34 @@
+require 'rails_helper'
+
+describe Users::RegistrationsController do
+
+ describe "POST check_username" do
+
+ before(:each) do
+ @request.env["devise.mapping"] = Devise.mappings[:user]
+ end
+
+ context "when username is available" do
+ it "should return true with no error message" do
+ post :check_username, username: "available username"
+
+ data = JSON.parse response.body, symbolize_names: true
+ expect(data[:available]).to be true
+ expect(data[:message]).to eq I18n.t("devise_views.users.registrations.new.username_is_available")
+ end
+ end
+
+ context "when username is not available" do
+ it "should return true with no error message" do
+ user = create(:user)
+ post :check_username, username: user.username
+
+ data = JSON.parse response.body, symbolize_names: true
+ expect(data[:available]).to be false
+ expect(data[:message]).to eq I18n.t("devise_views.users.registrations.new.username_is_not_available")
+ end
+ end
+
+ end
+
+end
diff --git a/spec/features/registration_form_spec.rb b/spec/features/registration_form_spec.rb
new file mode 100644
index 000000000..875e2b344
--- /dev/null
+++ b/spec/features/registration_form_spec.rb
@@ -0,0 +1,27 @@
+require 'rails_helper'
+
+feature 'Registration form' do
+
+ scenario 'username is not available', :js do
+ user = create(:user)
+
+ visit new_user_registration_path
+ expect(page).to_not have_content I18n.t("devise_views.users.registrations.new.username_is_not_available")
+
+ fill_in "user_username", with: user.username
+ check 'user_terms_of_service'
+
+ expect(page).to have_content I18n.t("devise_views.users.registrations.new.username_is_not_available")
+ end
+
+ scenario 'username is available', :js do
+ visit new_user_registration_path
+ expect(page).to_not have_content I18n.t("devise_views.users.registrations.new.username_is_available")
+
+ fill_in "user_username", with: "available username"
+ check 'user_terms_of_service'
+
+ expect(page).to have_content I18n.t("devise_views.users.registrations.new.username_is_available")
+ end
+
+end