From f33d05d99c88969bc529b42ddf4cd22185ccbf1e Mon Sep 17 00:00:00 2001 From: Seth Call Date: Thu, 14 Mar 2013 23:23:37 -0500 Subject: [PATCH] * VRFS-259: beta signup --- Gemfile | 1 + app/assets/javascripts/signup.js | 114 ++++++-- app/assets/stylesheets/client/ftue.css.scss | 8 + .../api_maxmind_requests_controller.rb | 2 +- app/controllers/users_controller.rb | 120 ++++++++- app/views/users/already_signed_up.html.erb | 19 ++ app/views/users/email_sent.html.erb | 3 +- app/views/users/new.html.erb | 252 ++++++++++-------- app/views/users/signup_confirm.html.erb | 4 +- config/initializers/dev_users.rb | 1 + config/routes.rb | 3 +- lib/managers/max_mind_manager.rb | 12 +- lib/managers/user_manager.rb | 14 +- spec/factories.rb | 20 +- spec/features/signup_spec.rb | 135 ++++++++++ spec/managers/user_manager_spec.rb | 141 +++++++++- spec/requests/users_api_spec.rb | 17 -- spec/spec_helper.rb | 13 +- 18 files changed, 687 insertions(+), 192 deletions(-) create mode 100644 app/views/users/already_signed_up.html.erb create mode 100644 spec/features/signup_spec.rb diff --git a/Gemfile b/Gemfile index d14e02d67..00289cb90 100644 --- a/Gemfile +++ b/Gemfile @@ -44,6 +44,7 @@ gem 'filepicker-rails', '0.0.2' gem 'aws-sdk', '1.8.0' gem 'aasm', '3.0.16' gem 'carrierwave' +gem 'devise', '>= 1.1.2' #group :libv8 do # gem 'libv8', "~> 3.11.8" #end diff --git a/app/assets/javascripts/signup.js b/app/assets/javascripts/signup.js index 7dea14c00..fe06a7b42 100644 --- a/app/assets/javascripts/signup.js +++ b/app/assets/javascripts/signup.js @@ -2,32 +2,75 @@ var signup = {} + // register form elements relating to location to update appropriately as the user makes changes + signup.handle_location_changes = function handle_location_changes() { + + var country_select = $('#country_select') + var region_select = $('#region_select') + var city_select = $('#city_select') + + country_select.change(function() { + var selected_country = $(this).val() + if(selected_country) { + // set region disabled while updating + region_select.attr('disabled', true); + + $.ajax('/api/regions', { + data : { country: selected_country }, + dataType : 'json' + }).done(regions_done).fail(regions_fail).always(function() { region_select.attr('disabled', false) }) + } + }) + + function regions_done(data) { + region_select.children().remove() + + region_select.append("") + + $(data.regions).each(function(index, item) { + region_select.append("") + }) + } + + function regions_fail() { + alert("something went wrong in looking up regions") + } + + region_select.change(function() { + var selected_country = country_select.val() + var selected_region = $(this).val() + + // only update + if(selected_country && selected_region) { + // set city disabled while updating + city_select.attr('disabled', true); + + $.ajax('/api/cities', { + data : { country: selected_country, region: selected_region }, + dataType : 'json' + }).done(cities_done).fail(cities_fail).always(function() { city_select.attr('disabled', false) }) + } + }) + + + + function cities_done(data) { + city_select.children().remove() + + city_select.append("") + + $(data.cities).each(function(index, item) { + city_select.append("") + }) + } + + function cities_fail() { + alert("something went wrong in looking up cities") + } + } + signup.handle_completion_submit = function handle_completion_submit() { - function completion_done(data) { - // we can redirect on to client - window.location.href = '/client' - - } - - function completion_fail(xhr, status) { - // if status = 422, then we can display errors - if(xhr.status == 422) { - data = JSON.parse(xhr.responseText) - var errors = $('#errors') - errors.children().remove() - var list = $("") - errors.append(list) - $(data).each(function(i) { - list.append("
  • " + this + "
  • ") - }) - } - else { - alert("something went wrong with the service. please try again later") - } - } - - // based on rails date_select element, gather up birth_date selected by the user. // returns null if any field (day/month/year) is left blank function gather_birth_date() { @@ -92,6 +135,29 @@ return false; }) + function completion_done(data) { + // we can redirect on to client + window.location.href = '/client' + + } + + function completion_fail(xhr, status) { + // if status = 422, then we can display errors + if(xhr.status == 422) { + data = JSON.parse(xhr.responseText) + var errors = $('#errors') + errors.children().remove() + var list = $("") + errors.append(list) + $(data).each(function(i) { + list.append("
  • " + this + "
  • ") + }) + } + else { + alert("something went wrong with the service. please try again later") + } + } + } window.signup = signup diff --git a/app/assets/stylesheets/client/ftue.css.scss b/app/assets/stylesheets/client/ftue.css.scss index e061e0743..8bb1f2b58 100644 --- a/app/assets/stylesheets/client/ftue.css.scss +++ b/app/assets/stylesheets/client/ftue.css.scss @@ -185,3 +185,11 @@ table.audiogeartable { right:16px; } /* End Jeff's CSS */ + +/* Added to deal with invitation codes */ +.ftue-invited { + width:750px; + padding:25px; + font-size:15px; + color:#aaa; +} diff --git a/app/controllers/api_maxmind_requests_controller.rb b/app/controllers/api_maxmind_requests_controller.rb index b9b65254e..bcfcac159 100644 --- a/app/controllers/api_maxmind_requests_controller.rb +++ b/app/controllers/api_maxmind_requests_controller.rb @@ -1,4 +1,4 @@ -class ApiMaxMindRequestsController < ApiController +class ApiMaxmindRequestsController < ApiController respond_to :json diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 6fd38b19e..564bf6363 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -18,10 +18,29 @@ class UsersController < ApplicationController end def new + @invited_user = load_invited_user(params) + + if !@invited_user.nil? && @invited_user.accepted + # short-circuit out if this invitation is already accepted + render "already_signed_up" + return + end + @signup_postback = load_postback(@invited_user) + load_location(request.remote_ip) + @user = User.new + + # preseed the form with the invited email as a convenience to the user + unless @invited_user.nil? + @user.email = @invited_user.email + end end def create + + @invited_user = load_invited_user(params) + @signup_postback = load_postback(@invited_user) + @user = User.new # check recaptcha; if any errors seen, contribute it to the model @@ -29,25 +48,48 @@ class UsersController < ApplicationController render 'new' return end - + + instruments = fixup_instruments(params[:jam_ruby_user][:instruments]) + + birth_date = fixup_birthday(params[:jam_ruby_user]["birth_date(2i)"], params[:jam_ruby_user]["birth_date(3i)"], params[:jam_ruby_user]["birth_date(1i)"]) + location = { :country => params[:jam_ruby_user][:country], :state => params[:jam_ruby_user][:state], :city => params[:jam_ruby_user][:city]} + terms_of_service = params[:jam_ruby_user][:terms_of_service].nil? ? false : true + subscribe_email = params[:jam_ruby_user][:subscribe_email].nil? ? false : true + + @user = UserManager.new.signup(request.remote_ip, params[:jam_ruby_user][:first_name], params[:jam_ruby_user][:last_name], params[:jam_ruby_user][:email], params[:jam_ruby_user][:password], params[:jam_ruby_user][:password_confirmation], - params[:jam_ruby_user][:instruments], - params[:jam_ruby_user][:photo_url], + terms_of_service, + subscribe_email, + instruments, + birth_date, + location, + nil, # we don't accept photo url on the signup form yet + @invited_user, ApplicationHelper.base_uri(request) + "/confirm") # check for errors if @user.errors.any? # render any @user.errors on error + load_location(request.remote_ip, location) render 'new' else - # if success, redirect to 'email_sent' page - flash[:success] = "Please check your email and confirm your signup" - redirect_to :email_sent + if @user.email_confirmed + # If the user came here as a result of an invite, then they are trusted, + # and we know that their email must be valid because that's how they got the invite + # and log them in immediately + sign_in @user + redirect_to :client + else + # If this is a normal signup, then the user needs to verify email + # if success, redirect to 'email_sent' page + flash[:success] = "Please check your email and confirm your signup" + redirect_to :email_sent + end end end @@ -133,4 +175,70 @@ class UsersController < ApplicationController redirect_to(root_url) unless current_user.admin? end + # the User Model expects instruments in a different format than the form submits it + # so we have to fix it up. + def fixup_instruments(original_instruments) + # if an instrument is selected by the user in the form, it'll show up in this array + instruments = [] + + # ok, sweep through all the fields submitted, looking for selected instruments. + # also, make up priority because we don't ask for it (but users can fix it later on their profile) + priority = 0 + original_instruments.each do |key, value| + logger.debug("key #{key} value:#{value}") + if !value["selected"].nil? + instruments << { :instrument_id => key, :proficiency_level => value["proficiency"].to_i, :priority => priority } + priority = priority + 1 + end + end + + return instruments + end + + # the User Model expects instruments in a different format than the form submits it + # so we have to fix it up. + def fixup_birthday(month, day, year) + if month.blank? || day.blank? || year.blank? + # invalid birthdate, so return nil + return nil + end + + return Date.new(year.to_i, month.to_i, day.to_i) + end + + def load_invited_user(params) + # check if this an anonymous request, or result of invitation code + invitation_code = params[:invitation_code] + + invited_user = nil + unless invitation_code.nil? + # we only want to find invitations that have not been accepted + invited_user = InvitedUser.find_by_invitation_code(invitation_code) + end + return invited_user + end + + def load_location(remote_ip, location = nil) + @location = location + + if @location.nil? + @location = MaxMindManager.lookup(remote_ip) + end + + @location[:country] = "United States" if @location[:country].nil? + + # right now we only accept US signups for beta + @countries = MaxMindManager.countries() + # populate regions based on current country + @regions = MaxMindManager.regions(@location[:country]) + @cities = @location[:state].nil? ? [] : MaxMindManager.cities(@location[:country], @location[:state]) + end + + def load_postback(invited_user) + if invited_user.nil? + signup_url + else + signup_url + "?invitation_code=" + invited_user.invitation_code + end + end end diff --git a/app/views/users/already_signed_up.html.erb b/app/views/users/already_signed_up.html.erb new file mode 100644 index 000000000..51a1a6c82 --- /dev/null +++ b/app/views/users/already_signed_up.html.erb @@ -0,0 +1,19 @@ +<% provide(:title, 'Already Signed Up') %> +<%= javascript_include_tag "jquery" %> +<%= javascript_include_tag "signup" %> + +
    + +
    +

    You have already signed up with this invitation

    +
    + +
    + Since you already have an account, you can go <%= link_to "sign in", signin_path %> +
    +
    + + + \ No newline at end of file diff --git a/app/views/users/email_sent.html.erb b/app/views/users/email_sent.html.erb index 83d199210..9bda28190 100644 --- a/app/views/users/email_sent.html.erb +++ b/app/views/users/email_sent.html.erb @@ -1,8 +1,7 @@ <% provide(:title, 'Confirmation Email Sent') %> -

    Confirm Email Next

    - Do it. +
    \ No newline at end of file diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb index 286023744..098cd2618 100644 --- a/app/views/users/new.html.erb +++ b/app/views/users/new.html.erb @@ -1,117 +1,161 @@ <% provide(:title, 'Sign up') %> +<%= javascript_include_tag "jquery" %> +<%= javascript_include_tag "signup" %>
    - - -
    -

    create a jamkazam account

    -
    - - -
    - <%= form_for(@user) do |f| %> - - -
    - <%= render 'shared/error_messages', object: f.object %> - - - - - - - - - - - - - + + <% unless @invited_user.nil? %> + <% if @invited_user.sender.nil? %> +
    +

    you've been invited to join jamkazam

    +
    - - - - - - -
    <%= f.label :first_name, "First Name" %>
    - <%= f.text_field :first_name %>
    <%= f.label :last_name, "Last Name" %>
    - <%= f.text_field :last_name %>
    <%= f.label :email %>
    - <%= f.text_field :email %>
    Country:
    -
    State/Province:
    -
    City:
    -
    <%= f.label :password %>
    - <%= f.password_field :password %>
    <%= f.label :password_confirmation, "Verify Password" %>
    - <%= f.password_field :password_confirmation %>
    I will accept email from JamKazam about this service.
    -
    - I have read and agree to the JamKazam terms of service.
    - -
    - - -
    - - -

    +
    + Signup and you can starting jamming, too. +
    - What instruments can you play? - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Acoustic Guitar
    Bass Guitar
    Electric Guitar
    Drums/Percussion
    Computer
    Keyboard/Piano
    Violin
    -
    -
    - <% if Rails.application.config.recaptcha_enable %> - <%= recaptcha_tags %> - <% end %> + <% else %> +
    +

    you've been invited by <%= @invited_user.sender_display_name %> to join jamkazam

    +
    + +
    + Signup and you can starting jamming, too. +
    +<% end %> + <% end %> + +
    +

    create a jamkazam account

    +
    + + +
    + <%= form_for(@user, :url => @signup_postback) do |f| %> + + +
    + <%= render 'shared/error_messages', object: f.object %> + + + + + + + + + + + + + + + + + + + + + + + +
    <%= f.label :first_name, "First Name" %> +
    + <%= f.text_field :first_name %>
    <%= f.label :last_name, "Last Name" %> +
    + <%= f.text_field :last_name %>
    <%= f.label :email %> +
    + <%= f.text_field :email %>
    Country:
    + +
    State/Province:
    +
    City:
    +
    <%= f.label :password %> +
    + <%= f.password_field :password %>
    <%= f.label :password_confirmation, "Verify Password" %> +
    + <%= f.password_field :password_confirmation %>
    + I will accept email from JamKazam about this service.
    +
    + I have read and agree to the JamKazam terms of service. +
    + +
    - - <%= f.submit "CREATE ACCOUNT", class: "right button-orange" %>

    - - -
    -
    - + - <% end %> -
    - + +

    -
    - + What instruments can you play? + +
    + + <% Instrument.standard_list.each do |instrument| %> + + + + + <% end %> +
    <%= instrument.description %>
    +
    +
    + <% if Rails.application.config.recaptcha_enable %> + <%= recaptcha_tags %> + <% end %> + + + + <%= f.submit "CREATE ACCOUNT", class: "right button-orange" %> +

    + + +
    + +
    + + + <% end %> + + + + + + + \ No newline at end of file diff --git a/app/views/users/signup_confirm.html.erb b/app/views/users/signup_confirm.html.erb index 78da6c6a0..8c0ef92e9 100644 --- a/app/views/users/signup_confirm.html.erb +++ b/app/views/users/signup_confirm.html.erb @@ -57,7 +57,7 @@ <%= f.label :password_confirmation, "Verify Password" %>
    <%= f.password_field :password_confirmation %> - + I will accept email from JamKazam about this service.
    diff --git a/config/initializers/dev_users.rb b/config/initializers/dev_users.rb index 967d22dd1..988dbc397 100644 --- a/config/initializers/dev_users.rb +++ b/config/initializers/dev_users.rb @@ -10,6 +10,7 @@ if Rails.env == "development" && Rails.application.config.bootstrap_dev_users User.create_dev_user("Nat", "Meo", "nat@jamkazam.com", "jam123", "Raleigh", "Virginia", "US", nil, nil) User.create_dev_user("Jonathon", "Wilson", "jonathon@jamkazam.com", "jam123", "Bozeman", "Montana", "US", [{:instrument_id => "keyboard", :proficiency_level => 4, :priority => 1}], 'http://www.jamkazam.com/assets/avatars/avatar_jonathon.jpg') User.create_dev_user("Jonathan", "Kolyer", "jonathan@jamkazam.com", "jam123", "San Francisco", "CA", "US", nil, nil) + User.create_dev_user("Oswald", "Becca", "os@jamkazam.com", "jam123", "Austin", "TX", "US", nil, nil) User.create_dev_user("Ben", "Johns", "benjohns1@gmail.com", "jam123", "Bozeman", "Montana", "US", [{:instrument_id => "saxophone", :proficiency_level => 4, :priority => 1}], 'http://www.jamkazam.com/assets/avatars/avatar_ben.jpg') User.create_dev_user("Craig", "Hall", "craighall@bresnan.net", "jam123", "Bozeman", "Montana", "US", [{:instrument_id => "bass guitar", :proficiency_level => 4, :priority => 1}], 'http://www.jamkazam.com/assets/avatars/avatar_craig.jpg') end diff --git a/config/routes.rb b/config/routes.rb index d36bb7bb4..1effbc6a8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -17,7 +17,8 @@ SampleApp::Application.routes.draw do # This page is still here, and is under test. Keep a route to it. match '/oldhome', to: 'static_pages#home' - match '/signup', to: 'users#new' + match '/signup', to: 'users#new', :via => 'get' + match '/signup', to: 'users#create', :via => 'post' match '/email_sent', to: 'users#email_sent' match '/signin', to: 'sessions#new' match '/signout', to: 'sessions#destroy', via: :delete diff --git a/lib/managers/max_mind_manager.rb b/lib/managers/max_mind_manager.rb index 987515c6e..1785c7690 100644 --- a/lib/managers/max_mind_manager.rb +++ b/lib/managers/max_mind_manager.rb @@ -32,7 +32,17 @@ class MaxMindManager < BaseManager } end - + + def self.countries() + ActiveRecord::Base.connection_pool.with_connection do |connection| + pg_conn = connection.instance_variable_get("@connection") + pg_conn.exec("SELECT DISTINCT country FROM max_mind ORDER BY country ASC").map do |tuple| + tuple["country"] + end + end + end + + def self.regions(country) ActiveRecord::Base.connection_pool.with_connection do |connection| pg_conn = connection.instance_variable_get("@connection") diff --git a/lib/managers/user_manager.rb b/lib/managers/user_manager.rb index 0892fc934..8194ab059 100644 --- a/lib/managers/user_manager.rb +++ b/lib/managers/user_manager.rb @@ -10,8 +10,8 @@ class UserManager < BaseManager # Note that almost everything can be nil here. This is because when users sign up via social media, # we don't know much about them. - def signup(remote_ip, first_name, last_name, email, password = nil, password_confirmation = nil, - instruments = nil, photo_url = nil, signup_confirm_url = nil) + def signup(remote_ip, first_name, last_name, email, password = nil, password_confirmation = nil, terms_of_service = nil, subscribe_email = nil, + instruments = nil, birth_date = nil, location = nil, photo_url = nil, invited_user = nil, signup_confirm_url = nil) @user = User.new @@ -20,7 +20,10 @@ class UserManager < BaseManager raise PermissionError, "Signups are currently disabled" end - location_hash = MaxMindManager.lookup(remote_ip); + # a user should be able to specify their location, but if they don't, we'll best effort it + if location.nil? + location = MaxMindManager.lookup(remote_ip) + end # TODO: figure out why can't user verify_recaptcha here # ALSO: make sure we dont do the recaptcha stuff if used facebook. @@ -30,9 +33,8 @@ class UserManager < BaseManager # return @user # @user.errors.any? is true now #else # sends email to email account for confirmation - @user = User.signup(first_name, last_name, email, password, password_confirmation, - location_hash[:city], location_hash[:state], location_hash[:country], - instruments, photo_url, signup_confirm_url) + @user = User.signup(first_name, last_name, email, password, password_confirmation, terms_of_service, subscribe_email, + location, instruments, birth_date, photo_url, invited_user, signup_confirm_url) return @user #end diff --git a/spec/factories.rb b/spec/factories.rb index 02865fcab..4d6a27e2e 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -12,6 +12,8 @@ FactoryGirl.define do city "Apex" state "NC" country "USA" + terms_of_service true + factory :admin do admin true @@ -27,18 +29,6 @@ FactoryGirl.define do connection = FactoryGirl.create(:connection, :user => user, :music_session => music_session) end end - - factory :invited_user do - administratively_created true - first_name nil - last_name nil - email_confirmed false - city nil - state nil - country nil - musician true - sequence(:signup_token) { |n| n } - end end factory :fan, :class => JamRuby::User do @@ -52,6 +42,12 @@ FactoryGirl.define do city "Apex" state "NC" country "USA" + terms_of_service true + end + + factory :invited_user, :class => JamRuby::InvitedUser do + sequence(:email) { |n| "user#{n}@someservice.com" } + autofriend false end factory :music_session, :class => JamRuby::MusicSession do diff --git a/spec/features/signup_spec.rb b/spec/features/signup_spec.rb new file mode 100644 index 000000000..e30334b8f --- /dev/null +++ b/spec/features/signup_spec.rb @@ -0,0 +1,135 @@ +require 'spec_helper' + +describe "Signup" do + + subject { page } + + before(:each) do + UserMailer.deliveries.clear + end + + describe "signup page" do + before { visit signup_path } + + it { should have_selector('h1', text: 'create a jamkazam account') } + + describe "with valid information" do + before do + fill_in "jam_ruby_user[first_name]", with: "Mike" + fill_in "jam_ruby_user[last_name]", with: "Jones" + fill_in "jam_ruby_user[email]", with: "noone@jamkazam.com" + fill_in "jam_ruby_user[password]", with: "jam123" + fill_in "jam_ruby_user[password_confirmation]", with: "jam123" + check("jam_ruby_user[instruments][drums][selected]") + check("jam_ruby_user[terms_of_service]") + click_button "CREATE ACCOUNT" + end + + # Successful signup with no invitation tells you to go sign up + it { expect(first('title').native.text).to eq "Jamkazam | Confirmation Email Sent" } + it { should have_selector('div.alert.alert-success', text: "Please check your email and confirm your signup") } + it { User.find_by_email('noone@jamkazam.com').musician_instruments.length.should == 1 } + # an email is sent on no-invite signup + it { UserMailer.deliveries.length.should == 1 } + end + + describe "with service invite" do + before do + @invited_user = FactoryGirl.create(:invited_user, :email => "noone@jamkazam.com") + visit "#{signup_path}?invitation_code=#{@invited_user.invitation_code}" + + fill_in "jam_ruby_user[first_name]", with: "Mike" + fill_in "jam_ruby_user[last_name]", with: "Jones" + fill_in "jam_ruby_user[email]", with: "noone@jamkazam.com" + fill_in "jam_ruby_user[password]", with: "jam123" + fill_in "jam_ruby_user[password_confirmation]", with: "jam123" + check("jam_ruby_user[instruments][drums][selected]") + check("jam_ruby_user[terms_of_service]") + click_button "CREATE ACCOUNT" + end + + # Successful sign-in goes to the client + it { expect(first('title').native.text).to eq "Jamkazam" } + it { should have_selector('h1', text: "Audio Gear Setup") } + + # there is no email sent though when you signup based on an invite (because you just left your email to get here) + it { UserMailer.deliveries.length.should == 0 } + end + + describe "with user invite and autofriend" do + before do + @user = FactoryGirl.create(:user) + @invited_user = FactoryGirl.create(:invited_user, :sender => @user, :autofriend => true, :email => "noone@jamkazam.com") + visit "#{signup_path}?invitation_code=#{@invited_user.invitation_code}" + + fill_in "jam_ruby_user[first_name]", with: "Mike" + fill_in "jam_ruby_user[last_name]", with: "Jones" + fill_in "jam_ruby_user[email]", with: "noone@jamkazam.com" + fill_in "jam_ruby_user[password]", with: "jam123" + fill_in "jam_ruby_user[password_confirmation]", with: "jam123" + check("jam_ruby_user[instruments][drums][selected]") + check("jam_ruby_user[terms_of_service]") + click_button "CREATE ACCOUNT" + end + + # Successful sign-in goes to the client + it { expect(first('title').native.text).to eq "Jamkazam" } + it { should have_selector('h1', text: "Audio Gear Setup") } + it { @user.friends?(User.find_by_email("noone@jamkazam.com")) } + it { User.find_by_email("noone@jamkazam.com").friends?(@user) } + end + + describe "can't signup to the same invite twice" do + before do + @invited_user = FactoryGirl.create(:invited_user, :email => "noone@jamkazam.com") + visit "#{signup_path}?invitation_code=#{@invited_user.invitation_code}" + + fill_in "jam_ruby_user[first_name]", with: "Mike" + fill_in "jam_ruby_user[last_name]", with: "Jones" + fill_in "jam_ruby_user[email]", with: "noone@jamkazam.com" + fill_in "jam_ruby_user[password]", with: "jam123" + fill_in "jam_ruby_user[password_confirmation]", with: "jam123" + check("jam_ruby_user[instruments][drums][selected]") + check("jam_ruby_user[terms_of_service]") + click_button "CREATE ACCOUNT" + expect(first('title').native.text).to eq "Jamkazam" + should have_selector('h1', text: "Audio Gear Setup") + visit "#{signup_path}?invitation_code=#{@invited_user.invitation_code}" + end + + it { should have_selector('h1', text: "You have already signed up with this invitation") } + + end + + describe "can signup with an email different than the one used to invite" do + before do + @invited_user = FactoryGirl.create(:invited_user, :email => "what@jamkazam.com") + visit "#{signup_path}?invitation_code=#{@invited_user.invitation_code}" + + fill_in "jam_ruby_user[first_name]", with: "Mike" + fill_in "jam_ruby_user[last_name]", with: "Jones" + fill_in "jam_ruby_user[email]", with: "noone@jamkazam.com" + fill_in "jam_ruby_user[password]", with: "jam123" + fill_in "jam_ruby_user[password_confirmation]", with: "jam123" + check("jam_ruby_user[instruments][drums][selected]") + check("jam_ruby_user[terms_of_service]") + click_button "CREATE ACCOUNT" + end + + it { expect(first('title').native.text).to eq "Jamkazam | Confirmation Email Sent" } + it { should have_selector('div.alert.alert-success', text: "Please check your email and confirm your signup") } + it { User.find_by_email('noone@jamkazam.com').musician_instruments.length.should == 1 } + it { User.find_by_email('what@jamkazam.com').should be_nil } + # an email is sent when you invite but use a different email than the one used to invite + it { UserMailer.deliveries.length.should == 1 } + it { + visit "#{signup_path}?invitation_code=#{@invited_user.invitation_code}" + should have_selector('h1', text: "You have already signed up with this invitation") + } + + end + + + end + +end diff --git a/spec/managers/user_manager_spec.rb b/spec/managers/user_manager_spec.rb index 68d5e0259..db07fca55 100644 --- a/spec/managers/user_manager_spec.rb +++ b/spec/managers/user_manager_spec.rb @@ -7,11 +7,13 @@ describe UserManager do before(:each) do @user_manager = UserManager.new(:conn => @conn) UserMailer.deliveries.clear + @location = { :country => "United States", :state => "Arkansas", :city => "Little Rock" } + @instruments = [ { :instrument_id=>"electric guitar", :proficiency_level => '1', :priority=>0 }] end describe "signup" do it "signup successfully" do - @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", [ { :instrument_id=>"electric guitar", :proficiency_level => '1', :priority=>0 }], nil, "http://localhost:3000/confirm" ) + @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, nil, nil, nil, "http://localhost:3000/confirm" ) @user.errors.any?.should be_false @user.first_name.should == "bob" @@ -28,18 +30,18 @@ describe UserManager do end it "signup successfully with instruments" do - @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", - [{ :instrument_id => "electric guitar", :proficiency_level => 3, :priority => 0}], nil, "http://localhost:3000/confirm") + @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, + @instruments, nil, nil, nil, nil, "http://localhost:3000/confirm") @user.errors.any?.should be_false @user.instruments.length.should == 1 musician_instrument = @user.musician_instruments[0] musician_instrument.instrument.should == Instrument.find("electric guitar") - musician_instrument.proficiency_level.should == 3 + musician_instrument.proficiency_level.should == 1 end it "doesnt fail if ip address is nil" do - @user = @user_manager.signup(nil, "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", [ { :instrument_id=>"electric guitar", :proficiency_level => '1', :priority=>0 }], nil, "http://localhost:3000/confirm" ) + @user = @user_manager.signup(nil, "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, nil, nil, nil, "http://localhost:3000/confirm" ) @user.errors.any?.should be_false @user.city.should be_nil @@ -51,7 +53,7 @@ describe UserManager do MaxMindManager.active_record_transaction do |manager| manager.create_phony_database() end - @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", [ { :instrument_id=>"electric guitar", :proficiency_level => '1', :priority=>0 }], nil, "http://localhost:3000/confirm" ) + @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, nil, nil, nil, "http://localhost:3000/confirm" ) @user.errors.any?.should be_false @user.city.should == 'City 127' @@ -59,38 +61,73 @@ describe UserManager do @user.country.should == 'United States' end + it "accepts location if specified" do + MaxMindManager.active_record_transaction do |manager| + manager.create_phony_database() + end + @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, @location, nil, nil, "http://localhost:3000/confirm" ) + + @user.errors.any?.should be_false + @user.city.should == 'Little Rock' + @user.state.should == 'Arkansas' + @user.country.should == 'United States' + end + + it "accepts a nil location, if specified" do + MaxMindManager.active_record_transaction do |manager| + manager.create_phony_database() + end + @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, {}, nil, nil, "http://localhost:3000/confirm" ) + + @user.errors.any?.should be_false + @user.city.should be_nil + @user.state.should be_nil + @user.country.should be_nil + end + + + it "accepts birth_date if specified" do + MaxMindManager.active_record_transaction do |manager| + manager.create_phony_database() + end + @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, Date.new(2001, 1, 1), nil, nil, nil, "http://localhost:3000/confirm" ) + + @user.errors.any?.should be_false + @user.birth_date.should == Date.new(2001, 1, 1) + end + it "duplicate signup failure" do - @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", [ { :instrument_id=>"electric guitar", :proficiency_level => '1', :priority=>0 }], nil, "http://localhost:3000/confirm") + @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, nil, nil, nil, "http://localhost:3000/confirm") UserMailer.deliveries.length.should == 1 @user.errors.any?.should be_false # exactly the same parameters; should dup on email, and send no email - @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", [ { :instrument_id=>"electric guitar", :proficiency_level => '1', :priority=>0 }], nil, "http://localhost:3000/confirm") + @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, nil, nil, nil, "http://localhost:3000/confirm") UserMailer.deliveries.length.should == 1 @user.errors.any?.should be_true @user.errors[:email][0].should == "has already been taken" end it "fail on no username" do - @user = @user_manager.signup("127.0.0.1", "", "", "bob@jamkazam.com", "foobar", "foobar", [ { :instrument_id=>"electric guitar", :proficiency_level => '1', :priority=>0 }], nil, "http://localhost:3000/confirm") + @user = @user_manager.signup("127.0.0.1", "", "", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, nil, nil, nil, "http://localhost:3000/confirm") UserMailer.deliveries.length.should == 0 @user.errors.any?.should be_true @user.errors[:first_name][0].should == "can't be blank" end it "fail on no email" do - @user = @user_manager.signup("127.0.0.1", "murp", "blurp", "", "foobar", "foobar", [ { :instrument_id=>"electric guitar", :proficiency_level => '1', :priority=>0 }], nil, "http://localhost:3000/confirm" ) + @user = @user_manager.signup("127.0.0.1", "murp", "blurp", "", "foobar", "foobar", true, nil, @instruments, nil, nil, nil, nil, "http://localhost:3000/confirm" ) UserMailer.deliveries.length.should == 0 @user.errors.any?.should be_true @user.errors[:email][0].should == "can't be blank" end - + end describe "signup_confirm" do it "fail on no username" do - @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", [ { :instrument_id=>"electric guitar", :proficiency_level => '1', :priority=>0 }], nil, "http://localhost:3000/confirm" ) + @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, nil, nil, nil, "http://localhost:3000/confirm" ) @user = @user_manager.signup_confirm(@user.signup_token) @user.email_confirmed.should be_true end @@ -107,4 +144,84 @@ describe UserManager do @user_manager.signup_confirm(nil).should be_nil end end + + it "signup successfully with due to service (not from any particular user) invitation" do + + @invitation = FactoryGirl.create(:invited_user) + + @invitation.accepted.should be_false + + @user = @user_manager.signup("127.0.0.1", "bob", "smith", @invitation.email, "foobar", "foobar", true, nil, + @instruments, nil, nil, nil, @invitation, "http://localhost:3000/confirm") + + @user.errors.any?.should be_false + @user.email_confirmed.should be_true + @user.signup_token.should be_nil + @invitation.errors.any?.should be_false + @invitation.accepted.should be_true + + UserMailer.deliveries.length.should == 0 # no emails should be sent, in this case + + end + + it "signup successfully with due to user invitation with no autofriend" do + + @some_user = FactoryGirl.create(:user) + @invitation = FactoryGirl.create(:invited_user, :sender => @some_user) + @invitation.accepted.should be_false + + + @user = @user_manager.signup("127.0.0.1", "bob", "smith", @invitation.email, "foobar", "foobar", true, nil, + @instruments, nil, nil, nil, @invitation, "http://localhost:3000/confirm") + + @user.errors.any?.should be_false + @user.email_confirmed.should be_true + @user.signup_token.should be_nil + @invitation.errors.any?.should be_false + @invitation.accepted.should be_true + + UserMailer.deliveries.length.should == 0 # no emails should be sent, in this case + end + + it "signup successfully with due to user invitation with autofriend" do + + @some_user = FactoryGirl.create(:user) + @invitation = FactoryGirl.create(:invited_user, :sender => @some_user, :autofriend => true) + @invitation.accepted.should be_false + + + @user = @user_manager.signup("127.0.0.1", "bob", "smith", @invitation.email, "foobar", "foobar", true, nil, + @instruments, nil, nil, nil, @invitation, "http://localhost:3000/confirm") + + @user.errors.any?.should be_false + @user.email_confirmed.should be_true + @user.signup_token.should be_nil + @invitation.errors.any?.should be_false + @invitation.accepted.should be_true + @user.friends?(@some_user).should be_true + @user.friends?(@some_user).should be_true + + UserMailer.deliveries.length.should == 0 # no emails should be sent, in this case + end + + it "signup successfully with due to user invitation with autofriend, but uses another email" do + + @some_user = FactoryGirl.create(:user) + @invitation = FactoryGirl.create(:invited_user, :sender => @some_user, :autofriend => true) + @invitation.accepted.should be_false + + + @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, + @instruments, nil, nil, nil, @invitation, "http://localhost:3000/confirm") + + @user.errors.any?.should be_false + @user.email_confirmed.should be_false + @user.signup_token.should_not be_nil + @invitation.errors.any?.should be_false + @invitation.accepted.should be_true + @user.friends?(@some_user).should be_true + @user.friends?(@some_user).should be_true + + UserMailer.deliveries.length.should == 1 # no emails should be sent, in this case + end end diff --git a/spec/requests/users_api_spec.rb b/spec/requests/users_api_spec.rb index aa366d32e..6b962011a 100644 --- a/spec/requests/users_api_spec.rb +++ b/spec/requests/users_api_spec.rb @@ -889,22 +889,5 @@ describe "User API", :type => :api do last_response = update_band_invitation(recipient, recipient, invitation["id"], false) end end - - # test the 'complete' method in the controlle - describe "complete" do - - it "should allow minimal required input" do - # create an invited user, essentially defining only email and signup_token - invited_user = FactoryGirl.create(:invited_user) - create_complete(invited_user, - :first_name => "Ricky", - :last_name => "Bobby", - :password=>"jam123", - :password_confirmation => "jam123", - :instruments => [ { :instrument_id=>"electric guitar", :proficiency_level => '1', :priority=>0 }]) - - last_response.status.should == 200 - end - end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4a99c97a1..6c4b5c503 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -6,17 +6,22 @@ require 'spork' require 'active_record' require 'action_mailer' require 'jam_db' -require 'jam_ruby' require "#{File.dirname(__FILE__)}/spec_db" + +# recreate test database and migrate it +db_config = YAML::load(File.open('config/database.yml'))["test"] +# initialize ActiveRecord's db connection\ +SpecDb::recreate_database(db_config) +ActiveRecord::Base.establish_connection(YAML::load(File.open('config/database.yml'))["test"]) + +require 'jam_ruby' + include JamRuby # put ActionMailer into test mode ActionMailer::Base.delivery_method = :test -# recreate test database and migrate it -db_config = YAML::load(File.open('config/database.yml'))["test"] -SpecDb::recreate_database(db_config) Spork.prefork do # Loading more in this block will cause your tests to run faster. However,