diff --git a/ruby/lib/jam_ruby/models/music_session.rb b/ruby/lib/jam_ruby/models/music_session.rb index ba059a3c9..1a082c3cd 100644 --- a/ruby/lib/jam_ruby/models/music_session.rb +++ b/ruby/lib/jam_ruby/models/music_session.rb @@ -397,7 +397,7 @@ module JamRuby def language_description if self.language.blank? - self.language = "en" + self.language = "eng" # iso-639-3 end iso639Details = ISO_639.find_by_code(self.language) diff --git a/ruby/spec/factories.rb b/ruby/spec/factories.rb index 0513e8f68..7ee7c6137 100644 --- a/ruby/spec/factories.rb +++ b/ruby/spec/factories.rb @@ -58,7 +58,7 @@ FactoryGirl.define do legal_terms true genre JamRuby::Genre.first band nil - language 'en' + language 'eng' end diff --git a/ruby/spec/jam_ruby/models/active_music_session_spec.rb b/ruby/spec/jam_ruby/models/active_music_session_spec.rb index 79a0992d6..c7d4d276c 100644 --- a/ruby/spec/jam_ruby/models/active_music_session_spec.rb +++ b/ruby/spec/jam_ruby/models/active_music_session_spec.rb @@ -403,8 +403,8 @@ describe ActiveMusicSession do let(:searcher_2) { FactoryGirl.create(:user, last_jam_locidispid: 3, last_jam_audio_latency: 14) } let(:searcher_conn_2) { FactoryGirl.create(:connection, user: searcher_2, ip_address: '9.9.9.9', locidispid: 3, addr:3) } - let!(:music_session_1) { FactoryGirl.create(:active_music_session, :creator => creator_1, genre: Genre.find('african'), language: 'en', description: "Bunny Jumps" ) } - let!(:music_session_2) { FactoryGirl.create(:active_music_session, :creator => creator_2, genre: Genre.find('ambient'), language: 'es', description: "Play with us as we jam to beatles and bunnies") } + let!(:music_session_1) { FactoryGirl.create(:active_music_session, :creator => creator_1, genre: Genre.find('african'), language: 'eng', description: "Bunny Jumps" ) } + let!(:music_session_2) { FactoryGirl.create(:active_music_session, :creator => creator_2, genre: Genre.find('ambient'), language: 'spa', description: "Play with us as we jam to beatles and bunnies") } let(:good_network_score) { 20 } let(:fair_network_score) { 30 } @@ -459,14 +459,14 @@ describe ActiveMusicSession do music_sessions.length.should == 2 # get only english - music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id, lang: 'en') + music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id, lang: 'eng') music_sessions.length.should == 1 - music_sessions[0].language.should == 'en' + music_sessions[0].language.should == 'eng' # get only ambient - music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id, lang: 'es') + music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id, lang: 'spa') music_sessions.length.should == 1 - music_sessions[0].language.should == 'es' + music_sessions[0].language.should == 'spa' end it "keyword" do diff --git a/ruby/spec/jam_ruby/models/music_session_spec.rb b/ruby/spec/jam_ruby/models/music_session_spec.rb index 89c379190..9176ed777 100644 --- a/ruby/spec/jam_ruby/models/music_session_spec.rb +++ b/ruby/spec/jam_ruby/models/music_session_spec.rb @@ -314,8 +314,8 @@ describe MusicSession do let!(:searcher_2) { FactoryGirl.create(:user, last_jam_locidispid: 3, last_jam_audio_latency: 14) } let!(:searcher_conn_2) { FactoryGirl.create(:connection, user: searcher_2, ip_address: '9.9.9.9', locidispid: 3, addr:3) } - let!(:music_session_1) { FactoryGirl.create(:music_session, creator: creator_1, genre: Genre.find('african'), language: 'en', description: "Bunny Jumps") } - let!(:music_session_2) { FactoryGirl.create(:music_session, creator: creator_2, genre: Genre.find('ambient'), language: 'es', description: "Play with us as we jam to beatles and bunnies") } + let!(:music_session_1) { FactoryGirl.create(:music_session, creator: creator_1, genre: Genre.find('african'), language: 'eng', description: "Bunny Jumps") } + let!(:music_session_2) { FactoryGirl.create(:music_session, creator: creator_2, genre: Genre.find('ambient'), language: 'spa', description: "Play with us as we jam to beatles and bunnies") } let!(:music_session_3) { FactoryGirl.create(:music_session, creator: creator_3) } let(:good_network_score) { 20 } @@ -399,8 +399,8 @@ describe MusicSession do let(:searcher_2) { FactoryGirl.create(:user, last_jam_locidispid: 3, last_jam_audio_latency: 14) } let(:searcher_conn_2) { FactoryGirl.create(:connection, user: searcher_2, ip_address: '9.9.9.9', locidispid: 3, addr:3) } - let!(:music_session_1) { FactoryGirl.create(:music_session, :creator => creator_1, genre: Genre.find('african'), language: 'en', description: "Bunny Jumps" ) } - let!(:music_session_2) { FactoryGirl.create(:music_session, :creator => creator_2, genre: Genre.find('ambient'), language: 'es', description: "Play with us as we jam to beatles and bunnies") } + let!(:music_session_1) { FactoryGirl.create(:music_session, :creator => creator_1, genre: Genre.find('african'), language: 'eng', description: "Bunny Jumps" ) } + let!(:music_session_2) { FactoryGirl.create(:music_session, :creator => creator_2, genre: Genre.find('ambient'), language: 'spa', description: "Play with us as we jam to beatles and bunnies") } let(:good_network_score) { 20 } let(:fair_network_score) { 30 } @@ -448,14 +448,14 @@ describe MusicSession do music_sessions.length.should == 2 # get only english - music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, lang: 'en') + music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, lang: 'eng') music_sessions.length.should == 1 - music_sessions[0].language.should == 'en' + music_sessions[0].language.should == 'eng' # get only ambient - music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, lang: 'es') + music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, lang: 'spa') music_sessions.length.should == 1 - music_sessions[0].language.should == 'es' + music_sessions[0].language.should == 'spa' end it "keyword" do @@ -498,7 +498,6 @@ describe MusicSession do music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, day: (Date.today + 1).to_s, timezone_offset: DateTime.now.offset.numerator) music_sessions.length.should == 1 music_sessions[0].should == music_session_1 - end end end diff --git a/web/app/assets/javascripts/findSession.js b/web/app/assets/javascripts/findSession.js index c246e5fd2..ca7d3bbe3 100644 --- a/web/app/assets/javascripts/findSession.js +++ b/web/app/assets/javascripts/findSession.js @@ -160,7 +160,6 @@ clearResults(); buildQuery(); loadSessions(); - context.JK.guardAgainstBrowser(app); } function clearResults() { diff --git a/web/app/assets/javascripts/layout.js b/web/app/assets/javascripts/layout.js index e087a2820..ccbff33e1 100644 --- a/web/app/assets/javascripts/layout.js +++ b/web/app/assets/javascripts/layout.js @@ -644,7 +644,7 @@ function showDialog(dialog, options) { if (dialogEvent(dialog, 'beforeShow', options) === false) { - return; + return null; } var $overlay = $('.dialog-overlay') diff --git a/web/app/assets/javascripts/networkTestHelper.js b/web/app/assets/javascripts/networkTestHelper.js index c93b5dce4..098764b4e 100644 --- a/web/app/assets/javascripts/networkTestHelper.js +++ b/web/app/assets/javascripts/networkTestHelper.js @@ -17,6 +17,7 @@ var PAYLOAD_SIZE = 100; var MINIMUM_ACCEPTABLE_SESSION_SIZE = 2; + var gearUtils = context.JK.GearUtils; var rest = context.JK.Rest(); var logger = context.JK.logger; var $step = null; @@ -201,6 +202,7 @@ storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror); } else if(reason == "server_comm_timeout") { + gearUtils.skipNetworkTest(); context.JK.alertSupportedNeeded("Communication with the JamKazam network service has timed out." + appendContextualStatement()); renderStopTest('', ''); storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror); @@ -211,11 +213,13 @@ storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror); } else if(reason == "invalid_response") { + gearUtils.skipNetworkTest(); context.JK.alertSupportedNeeded("The JamKazam client software had an unexpected problem while scoring your Internet connection.

Reason: " + attempt.backend_data.reason + '.'); renderStopTest('', ''); storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror); } else if(reason == 'no_servers') { + gearUtils.skipNetworkTest(); context.JK.alertSupportedNeeded("No network test servers are available." + appendContextualStatement()); renderStopTest('', ''); testedSuccessfully = true; @@ -227,18 +231,21 @@ storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.noNetwork); } else if(reason == "rest_api_error") { + gearUtils.skipNetworkTest(); context.JK.alertSupportedNeeded("Unable to acquire a network test server." + appendContextualStatement()); testedSuccessfully = true; renderStopTest('', ''); storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror); } else if(reason == "timeout") { + gearUtils.skipNetworkTest(); context.JK.alertSupportedNeeded("Communication with the JamKazam network service timed out." + appendContextualStatement()); testedSuccessfully = true; renderStopTest('', ''); storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror); } else { + gearUtils.skipNetworkTest(); context.JK.alertSupportedNeeded("The JamKazam client software had a logic error while scoring your Internet connection."); renderStopTest('', ''); storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror); diff --git a/web/app/assets/javascripts/scheduled_session.js b/web/app/assets/javascripts/scheduled_session.js index 6b17e425a..136ea47a9 100644 --- a/web/app/assets/javascripts/scheduled_session.js +++ b/web/app/assets/javascripts/scheduled_session.js @@ -5,6 +5,7 @@ context.JK = context.JK || {}; context.JK.CreateScheduledSession = function(app) { + var gearUtils = context.JK.GearUtils; var logger = context.JK.logger; var rest = JK.Rest(); var invitationDialog = null; @@ -188,9 +189,7 @@ function beforeShowStep5() { var startType = null; - if (createSessionSettings.createType == 'start-scheduled' || - createSessionSettings.createType == 'immediately' || - createSessionSettings.createType == 'quick-start') { + if (willOptionStartSession()) { startType = 'Now!'; createSessionSettings.startType = "START SESSION"; } @@ -305,6 +304,10 @@ if (createSessionSettings.createType == 'start-scheduled') { var session = scheduledSessions[createSessionSettings.selectedSessionId]; + if(session == null) { + // TODO: notify user they need to pick session? Or maybe it should be grayed out. + return false; + } var moveToFinish = function() { app.layout.closeDialog('confirm'); createSessionSettings.startDate = new Date(session.scheduled_start).toDateString(); @@ -488,7 +491,24 @@ function beforeMoveStep5() { } + function startSessionClicked() { + + if(willOptionStartSession()) { + gearUtils.guardAgainstInvalidConfiguration(app) + .fail(function() { + app.notify( + { title: "Unable to Start New Session", + text: "You can only start a session once you have working audio gear and a tested internet connection." + }) + }) + .done(function(){ + startSession(); + }); + } + } + function startSession() { + var data = {}; if (createSessionSettings.createType == 'start-scheduled') { @@ -563,22 +583,15 @@ }); } - var tracks = context.JK.TrackHelpers.getUserTracks(context.jamClient); - if(tracks.length == 0) { - logger.error("we should never have 0 tracks and have gotten this far. Launch FTUE is the best we can do right now") - // If user hasn't completed FTUE - do so now. - app.afterFtue = function() { startSession(); }; - app.layout.startNewFtue(); - return false; - } - var joinSession = function(sessionId) { + var tracks = context.JK.TrackHelpers.getUserTracks(context.jamClient); + var options = {}; options.client_id = app.clientId; options.session_id = sessionId; options.as_musician = true; options.tracks = tracks; - rest.joinSession(options) + rest.joinSession(options) .done(function(response) { var invitationCount = data.invitations.length; @@ -600,16 +613,18 @@ app.notifyServerError(jqXHR, "Unable to Create Session"); } }) + }; if (createSessionSettings.createType == 'start-scheduled') { joinSession(createSessionSettings.selectedSessionId); + $('#create-session-buttons .btn-next').off('click'); } else { rest.createScheduledSession(data) .done(function(response) { + $('#create-session-buttons .btn-next').off('click'); var newSessionId = response.id; - $(".btn-next").off('click'); if (createSessionSettings.createType == 'quick-start' || createSessionSettings.createType == "immediately") { joinSession(newSessionId); @@ -734,7 +749,7 @@ if (step == STEP_SELECT_CONFIRM) { $btnNext.html(createSessionSettings.startType); - $btnNext.on('click', startSession); + $btnNext.on('click', startSessionClicked); } else $btnNext.on('click', next); @@ -764,7 +779,20 @@ return false; } + // will this option result in a session being started? + function willOptionStartSession() { + return createSessionSettings.createType == 'start-scheduled' || + createSessionSettings.createType == 'immediately' || + createSessionSettings.createType == 'quick-start'; + } + function next(event) { + if(willOptionStartSession()) { + if(!context.JK.guardAgainstBrowser(app)) { + return false; + } + } + var valid = beforeMoveStep(); if (!valid) { return false; @@ -820,7 +848,7 @@ } function afterShow() { - context.JK.guardAgainstBrowser(app); + } function getFormattedTime(date, change) { diff --git a/web/app/assets/javascripts/session.js b/web/app/assets/javascripts/session.js index fd5bc3bee..eb996e4ed 100644 --- a/web/app/assets/javascripts/session.js +++ b/web/app/assets/javascripts/session.js @@ -4,6 +4,7 @@ context.JK = context.JK || {}; context.JK.SessionScreen = function(app) { + var gearUtils = context.JK.GearUtils; var logger = context.JK.logger; var self = this; var sessionModel = null; @@ -114,6 +115,8 @@ checkForCurrentUser(); } + + function afterShow(data) { if(!context.JK.JamServer.connected) { @@ -123,14 +126,14 @@ return; } - if (!context.JK.hasOneConfiguredDevice() || context.JK.TrackHelpers.getUserTracks(context.jamClient).length == 0) { - app.afterFtue = function() { initializeSession(); }; - app.cancelFtue = function() { promptLeave = false; window.location = '/client#/home' }; - app.layout.startNewFtue(); - } - else { + gearUtils.guardAgainstInvalidConfiguration(app) + .fail(function() { + promptLeave = false; + window.location = '/client#/home' + }) + .done(function(){ initializeSession(); - } + }) } function notifyWithUserInfo(title , text, clientId) { diff --git a/web/app/assets/javascripts/sessionList.js b/web/app/assets/javascripts/sessionList.js index c02313117..2487ab74f 100644 --- a/web/app/assets/javascripts/sessionList.js +++ b/web/app/assets/javascripts/sessionList.js @@ -4,6 +4,7 @@ context.JK = context.JK || {}; context.JK.SessionList = function(app) { + var gearUtils = context.JK.GearUtils; var logger = context.JK.logger; var rest = context.JK.Rest(); var ui = new context.JK.UIHelper(app); @@ -89,18 +90,25 @@ // wire up the Join Link to the T&Cs dialog var $parentRow = $('tr[id=' + session.id + ']', tbGroup); $('.join-link', $parentRow).click(function(evt) { + if(!context.JK.guardAgainstBrowser(app)) { + return false; + } + if (!context.JK.JamServer.connected) { app.notifyAlert("Not Connected", 'To create or join a session, you must be connected to the server.'); return false; } - // If no FTUE, show that first. - if (!context.JK.hasOneConfiguredDevice() || context.JK.TrackHelpers.getUserTracks(context.jamClient).length == 0) { - app.afterFtue = function() { joinClick(session.id); }; - app.layout.startNewFtue(); - } - else { - joinClick(session.id); - } + + gearUtils.guardAgainstInvalidConfiguration(app) + .fail(function() { + app.notify( + { title: "Unable to Join Session", + text: "You can only join a session once you have working audio gear and a tested internet connection." + }) + }) + .done(function(){ + joinClick(session.id); + }) return false; }); diff --git a/web/app/assets/javascripts/utils.js b/web/app/assets/javascripts/utils.js index 586186111..302d5be57 100644 --- a/web/app/assets/javascripts/utils.js +++ b/web/app/assets/javascripts/utils.js @@ -937,7 +937,9 @@ context.JK.guardAgainstBrowser = function(app, args) { if(!gon.isNativeClient) { app.layout.showDialog('launch-app-dialog', args) + return false; } + return true; } /* diff --git a/web/app/assets/javascripts/wizard/gear_utils.js b/web/app/assets/javascripts/wizard/gear_utils.js index 30ba2e686..6eb7aa2eb 100644 --- a/web/app/assets/javascripts/wizard/gear_utils.js +++ b/web/app/assets/javascripts/wizard/gear_utils.js @@ -13,6 +13,11 @@ var ASSIGNMENT = context.JK.ASSIGNMENT; var VOICE_CHAT = context.JK.VOICE_CHAT; var AUDIO_DEVICE_BEHAVIOR = context.JK.AUDIO_DEVICE_BEHAVIOR; + var EVENTS = context.JK.EVENTS; + + gearUtils.SKIPPED_NETWORK_TEST = -1; // we store a negative 1 to mean that we let the user skip. + + gearUtils.skippedNetworkTest = false; // we allow someone to play in session (for one client run) if it's our fault they can't network test score // checks if it's an assigned OUTPUT or ASSIGNED CHAT gearUtils.isChannelAssigned = function (channel) { @@ -271,4 +276,88 @@ app.notifyServerError(jqXHR, "Unable to sync audio latency") }); } + + // if the user has a good user network score, immediately returns with a resolved deferred object. + // if not, the user will have the network test dialog prompted... once it's closed, then you'll be told reject() if score is still bad, or resolve() if now good + gearUtils.guardAgainstBadNetworkScore = function(app) { + var deferred = new $.Deferred(); + + if (!gearUtils.validNetworkScore()) { + // invalid network test score. They have to score to move on + app.layout.showDialog('network-test').one(EVENTS.DIALOG_CLOSED, function() { + if(gearUtils.validNetworkScore()) { + deferred.resolve(); + } + else { + deferred.reject(); + } + }); + } + else { + deferred.resolve(); + } + return deferred; + } + + // XXX this isn't quite right... it needs to check if a good device is *active* + // but seen too many problems so far with the backend not reporting any profile active + gearUtils.hasGoodActiveProfile = function(app) { + return context.JK.hasOneConfiguredDevice() && context.JK.TrackHelpers.getUserTracks(context.jamClient).length > 0 + } + + // if the user does not have a currently active, good profile, then they are made to deal with it + gearUtils.guardAgainstInvalidGearConfiguration = function(app) { + var deferred = new $.Deferred(); + + if (!gearUtils.hasGoodActiveProfile()) { + app.layout.showDialog('gear-wizard').one(EVENTS.DIALOG_CLOSED, function() { + if(gearUtils.hasGoodActiveProfile() && gearUtils.validNetworkScore()) { + deferred.resolve(); + } + else { + deferred.reject(); + } + }); + } + else { + deferred.resolve(); + } + + return deferred; + } + + // tests both device config, and network score + gearUtils.guardAgainstInvalidConfiguration = function(app) { + var deferred = new $.Deferred(); + gearUtils.guardAgainstInvalidGearConfiguration(app) + .fail(function() { + deferred.reject(); + }) + .done(function() { + gearUtils.guardAgainstBadNetworkScore(app) + .fail(function() { + deferred.reject(); + }) + .done(function() { + deferred.resolve(); + }) + }) + + return deferred; + } + + gearUtils.skipNetworkTest = function() { + context.jamClient.SetNetworkTestScore(gearUtils.SKIPPED_NETWORK_TEST); + gearUtils.skippedNetworkTest = true; + } + + gearUtils.isNetworkTestSkipped = function() { + return gearUtils.skippedNetworkTest; + } + + gearUtils.validNetworkScore = function() { + return gearUtils.skippedNetworkTest || context.jamClient.GetNetworkTestScore() >= 2; + } + + })(window, jQuery); \ No newline at end of file diff --git a/web/app/controllers/api_music_sessions_controller.rb b/web/app/controllers/api_music_sessions_controller.rb index bf592658a..f3ffeea07 100644 --- a/web/app/controllers/api_music_sessions_controller.rb +++ b/web/app/controllers/api_music_sessions_controller.rb @@ -171,7 +171,7 @@ class ApiMusicSessionsController < ApiController @music_session.music_session, params[:name], params[:description], - params[:genre], + params[:genre] ? Genre.find(params[:genre]) : nil, params[:language], params[:musician_access], params[:approval_required], diff --git a/web/spec/factories.rb b/web/spec/factories.rb index 06710e39d..2e6aa6b64 100644 --- a/web/spec/factories.rb +++ b/web/spec/factories.rb @@ -77,7 +77,7 @@ FactoryGirl.define do legal_terms true genre JamRuby::Genre.first band nil - language 'en' + language 'eng' end diff --git a/web/spec/features/launch_app_spec.rb b/web/spec/features/launch_app_spec.rb index e351c7e48..b759aea49 100644 --- a/web/spec/features/launch_app_spec.rb +++ b/web/spec/features/launch_app_spec.rb @@ -1,15 +1,25 @@ require 'spec_helper' -describe "Reset Password", :js => true, :type => :feature, :capybara_feature => true do +describe "Launch App", :js => true, :type => :feature, :capybara_feature => true do subject { page } let(:user) { FactoryGirl.create(:user) } + let(:ams) { FactoryGirl.create(:active_music_session, creator: user) } + + before(:each) do + ActiveMusicSession.delete_all + MusicSession.delete_all + end share_examples_for :launch_not_supported do |options| it "should indicate not supported" do sign_in_poltergeist user + ams.touch if options[:need_session] visit options[:screen_path] + if options[:actions] + options[:actions].call(page) + end should have_selector('h1', text: 'Application Notice') if options[:gear_modal] && options[:gear_modal] == true should have_selector('p', text: 'To configure your audio gear, you must use the JamKazam application. Please download and install the application if you have not done so already.') @@ -25,7 +35,11 @@ describe "Reset Password", :js => true, :type => :feature, :capybara_feature => share_examples_for :launch_supported do |options| it "should indicate supported" do sign_in_poltergeist user + ams.touch if options[:need_session] visit options[:screen_path] + if options[:actions] + options[:actions].call(page) + end should have_selector('h1', text: 'Application Notice') if options[:gear_modal] && options[:gear_modal] == true should have_selector('p', text: 'To configure your audio gear, you must use the JamKazam application.') @@ -38,12 +52,15 @@ describe "Reset Password", :js => true, :type => :feature, :capybara_feature => end describe "unsupported" do + before do # emulate mac safari page.driver.headers = { 'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.74.9 (KHTML, like Gecko) Version/7.0.2 Safari/537.74.9'} end - it_behaves_like :launch_not_supported, screen_path: '/client#/createSession' - it_behaves_like :launch_not_supported, screen_path: '/client#/findSession' + it_behaves_like :launch_not_supported, screen_path: '/client#/createSession', actions: lambda { |page| page.find('li[create-type="quick-start"] ins').trigger(:click); page.find('.btn-next').trigger(:click) } + it_behaves_like :launch_not_supported, screen_path: '/client#/createSession', actions: lambda { |page| page.find('li[create-type="immediately"] ins').trigger(:click); page.find('.btn-next').trigger(:click) } + it_behaves_like :launch_not_supported, screen_path: '/client#/createSession', actions: lambda { |page| page.find('li[create-type="start-scheduled"] ins').trigger(:click); page.find('.btn-next').trigger(:click) } + it_behaves_like :launch_not_supported, screen_path: '/client#/findSession', actions: lambda { |page| page.find('.join-link').trigger(:click) }, need_session: true it_behaves_like :launch_not_supported, screen_path: '/client#/account/audio', gear_modal: true end @@ -52,8 +69,10 @@ describe "Reset Password", :js => true, :type => :feature, :capybara_feature => # emulate chrome page.driver.headers = { 'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36'} end - it_behaves_like :launch_supported, screen_path: '/client#/createSession' - it_behaves_like :launch_supported, screen_path: '/client#/findSession' + it_behaves_like :launch_supported, screen_path: '/client#/createSession', actions: lambda { |page| page.find('li[create-type="quick-start"] ins').trigger(:click); page.find('.btn-next').trigger(:click) } + it_behaves_like :launch_supported, screen_path: '/client#/createSession', actions: lambda { |page| page.find('li[create-type="immediately"] ins').trigger(:click); page.find('.btn-next').trigger(:click) } + it_behaves_like :launch_supported, screen_path: '/client#/createSession', actions: lambda { |page| page.find('li[create-type="start-scheduled"] ins').trigger(:click); page.find('.btn-next').trigger(:click) } + it_behaves_like :launch_supported, screen_path: '/client#/findSession', actions: lambda { |page| page.find('.join-link').trigger(:click) }, need_session: true it_behaves_like :launch_supported, screen_path: '/client#/account/audio', gear_modal: true end end diff --git a/web/spec/features/session_info_spec.rb b/web/spec/features/session_info_spec.rb index 9edef164a..9bbb07cba 100644 --- a/web/spec/features/session_info_spec.rb +++ b/web/spec/features/session_info_spec.rb @@ -85,7 +85,7 @@ describe "Session Info", :js => true, :type => :feature, :capybara_feature => tr if options[:show_cta] find('#btn-action', :text => options[:button_text]) else - expect {find('#btn-action')}.to raise_error(Capybara::ElementNotFound) + should_not have_selector('#btn-action', :text => options[:button_text]) end # session details @@ -124,66 +124,56 @@ describe "Session Info", :js => true, :type => :feature, :capybara_feature => tr @music_session.save # attempt to access with musician who was invited but didn't RSVP - sign_in_poltergeist(@session_invitee) - visit @url + fast_signin(@session_invitee, @url) ensure_success({:show_cta => true, :button_text => 'RSVP NOW!'}) - sign_out_poltergeist + fast_signout # attempt to access with musician who wasn't invited - sign_in_poltergeist(@non_session_invitee) - visit @url + fast_signin(@non_session_invitee, @url) ensure_success({:show_cta => true, :button_text => 'RSVP NOW!'}) - sign_out_poltergeist + fast_signout # attempt to access with musician who RSVP'ed but wasn't approved - sign_in_poltergeist(@rsvp_declined_user) - visit @url + fast_signin(@rsvp_declined_user, @url) ensure_success({:show_cta => false}) - sign_out_poltergeist + fast_signout # attempt to access with musician who RSVP'ed and was approved - sign_in_poltergeist(@rsvp_approved_user) - visit @url + fast_signin(@rsvp_approved_user, @url) ensure_success({:show_cta => true, :button_text => 'CANCEL RSVP'}) - sign_out_poltergeist + fast_signout # attempt to access with session creator - sign_in_poltergeist(@session_creator) - visit @url + fast_signin(@session_creator, @url) ensure_success({:show_cta => false}) - sign_out_poltergeist + fast_signout end it "should render only for session invitees for sessions with closed RSVPs before session starts" do # attempt to access with musician who was invited but didn't RSVP - sign_in_poltergeist(@session_invitee) - visit @url + fast_signin(@session_invitee, @url) ensure_success({:show_cta => true, :button_text => 'RSVP NOW!'}) - sign_out_poltergeist + fast_signout # attempt to access with musician who wasn't invited - sign_in_poltergeist(@non_session_invitee) - visit @url + fast_signin(@non_session_invitee, @url) ensure_failure # NON-INVITEE SHOULD NOT BE ABLE TO VIEW FOR CLOSED RSVPs - sign_out_poltergeist + fast_signout # attempt to access with musician who RSVP'ed but wasn't approved - sign_in_poltergeist(@rsvp_declined_user) - visit @url + fast_signin(@rsvp_declined_user, @url) ensure_success({:show_cta => false}) - sign_out_poltergeist + fast_signout # attempt to access with musician who RSVP'ed and was approved - sign_in_poltergeist(@rsvp_approved_user) - visit @url + fast_signin(@rsvp_approved_user, @url) ensure_success({:show_cta => true, :button_text => 'CANCEL RSVP'}) - sign_out_poltergeist + fast_signout # attempt to access with session creator - sign_in_poltergeist(@session_creator) - visit @url + fast_signin(@session_creator, @url) ensure_success({:show_cta => false}) - sign_out_poltergeist + fast_signout end ########### AFTER SESSION STARTS ########### @@ -196,100 +186,85 @@ describe "Session Info", :js => true, :type => :feature, :capybara_feature => tr @music_session.save! # attempt to access with musician who was invited but didn't RSVP - sign_in_poltergeist(@session_invitee) - visit @url + fast_signin(@session_invitee, @url) ensure_failure - sign_out_poltergeist + fast_signout # attempt to access with musician who wasn't invited - sign_in_poltergeist(@non_session_invitee) - visit @url + fast_signin(@non_session_invitee, @url) ensure_failure - sign_out_poltergeist + fast_signout # attempt to access with musician who RSVP'ed but wasn't approved - sign_in_poltergeist(@rsvp_declined_user) - visit @url + fast_signin(@rsvp_declined_user, @url) ensure_failure - sign_out_poltergeist + fast_signout # attempt to access with musician who RSVP'ed and was approved - sign_in_poltergeist(@rsvp_approved_user) - visit @url + fast_signin(@rsvp_approved_user, @url) ensure_success({:show_cta => true, :button_text => 'CANCEL RSVP'}) - sign_out_poltergeist + fast_signout # attempt to access with session creator - sign_in_poltergeist(@session_creator) - visit @url + fast_signin(@session_creator, @url) ensure_success({:show_cta => false}) - sign_out_poltergeist + fast_signout end # musician_access = true, approval_required = false it "should allow anyone to view for 'at will' option after session starts" do # attempt to access with musician who was invited but didn't RSVP - sign_in_poltergeist(@session_invitee) - visit @url + fast_signin(@session_invitee, @url) ensure_success({:show_cta => true, :button_text => 'RSVP NOW!'}) - sign_out_poltergeist + fast_signout # attempt to access with musician who wasn't invited - sign_in_poltergeist(@non_session_invitee) - visit @url + fast_signin(@non_session_invitee, @url) ensure_failure # NON-INVITEE SHOULD NOT BE ABLE TO VIEW FOR CLOSED RSVPs - sign_out_poltergeist + fast_signout # attempt to access with musician who RSVP'ed but wasn't approved - sign_in_poltergeist(@rsvp_declined_user) - visit @url + fast_signin(@rsvp_declined_user, @url) ensure_success({:show_cta => false}) - sign_out_poltergeist + fast_signout # attempt to access with musician who RSVP'ed and was approved - sign_in_poltergeist(@rsvp_approved_user) - visit @url + fast_signin(@rsvp_approved_user, @url) ensure_success({:show_cta => true, :button_text => 'CANCEL RSVP'}) - sign_out_poltergeist + fast_signout # attempt to access with session creator - sign_in_poltergeist(@session_creator) - visit @url + fast_signin(@session_creator, @url) ensure_success({:show_cta => false}) - sign_out_poltergeist + fast_signout end # musician_access = true, approval_required = true it "should allow anyone to view for 'join by approval' option after session starts" do # attempt to access with musician who was invited but didn't RSVP - sign_in_poltergeist(@session_invitee) - visit @url + fast_signin(@session_invitee, @url) ensure_success({:show_cta => true, :button_text => 'RSVP NOW!'}) - sign_out_poltergeist + fast_signout # attempt to access with musician who wasn't invited - sign_in_poltergeist(@non_session_invitee) - visit @url + fast_signin(@non_session_invitee, @url) ensure_failure # NON-INVITEE SHOULD NOT BE ABLE TO VIEW FOR CLOSED RSVPs - sign_out_poltergeist + fast_signout # attempt to access with musician who RSVP'ed but wasn't approved - sign_in_poltergeist(@rsvp_declined_user) - visit @url + fast_signin(@rsvp_declined_user, @url) ensure_success({:show_cta => false}) - sign_out_poltergeist + fast_signout # attempt to access with musician who RSVP'ed and was approved - sign_in_poltergeist(@rsvp_approved_user) - visit @url + fast_signin(@rsvp_approved_user, @url) ensure_success({:show_cta => true, :button_text => 'CANCEL RSVP'}) - sign_out_poltergeist + fast_signout # attempt to access with session creator - sign_in_poltergeist(@session_creator) - visit @url + fast_signin(@session_creator, @url) ensure_success({:show_cta => false}) - sign_out_poltergeist + fast_signout end it "should show no call to action button if user has not RSVPed and all slots are taken" do @@ -299,10 +274,9 @@ describe "Session Info", :js => true, :type => :feature, :capybara_feature => tr # approve slot 2 as well to make all slots taken for this session RsvpRequest.update({:id => @rsvp1.id, :session_id => @music_session.id, :rsvp_responses => [{:request_slot_id => rs2.id, :accept => true}]}, @session_creator) - sign_in_poltergeist(@session_invitee) - visit @url + fast_signin(@session_invitee, @url) expect {find('#btn-action')}.to raise_error(Capybara::ElementNotFound) - sign_out_poltergeist + fast_signout end end diff --git a/web/spec/managers/music_session_manager_spec.rb b/web/spec/managers/music_session_manager_spec.rb index 94b7e4411..5f8cf03fa 100644 --- a/web/spec/managers/music_session_manager_spec.rb +++ b/web/spec/managers/music_session_manager_spec.rb @@ -27,13 +27,13 @@ describe MusicSessionManager do it "updates a session properly" do active_music_session = @music_session_manager.create(music_session, @user, @connection.client_id, "description", true, false, true, true, @band, [@genre], @tracks, true, 10) - @music_session_manager.update(music_session, "updated description", nil, nil, nil, nil, nil) + @music_session_manager.update(music_session, nil, "updated description", nil, nil, nil, nil, nil, nil) music_session.reload music_session.description.should == "updated description" # Verify that this didnt change music_session.approval_required.should == false genre2 = FactoryGirl.create(:genre) - @music_session_manager.update(music_session, nil, [@genre, genre2], nil, nil, nil, nil) + @music_session_manager.update(music_session, nil, nil, @genre, nil, nil, nil, nil, nil) music_session.reload music_session.description.should == "updated description" music_session.genre.should == @genre diff --git a/web/spec/requests/active_music_sessions_api_spec.rb b/web/spec/requests/active_music_sessions_api_spec.rb index 6a6296952..a7821bd4e 100755 --- a/web/spec/requests/active_music_sessions_api_spec.rb +++ b/web/spec/requests/active_music_sessions_api_spec.rb @@ -182,7 +182,7 @@ describe "Active Music Session API ", :type => :api do end it "updated genres" do - put "/api/sessions/#{music_session.id}.json", {:genres => ["jazz"]}.to_json, "CONTENT_TYPE" => 'application/json' + put "/api/sessions/#{music_session.id}.json", {:genre => "jazz"}.to_json, "CONTENT_TYPE" => 'application/json' last_response.status.should eql(204) get "/api/sessions/#{music_session.id}.json", "CONTENT_TYPE" => 'application/json' updated_session = JSON.parse(last_response.body) diff --git a/web/spec/support/utilities.rb b/web/spec/support/utilities.rb index a3239bfe3..2c8737e06 100644 --- a/web/spec/support/utilities.rb +++ b/web/spec/support/utilities.rb @@ -100,7 +100,6 @@ def sign_in_poltergeist(user, options = {}) validate = true if validate.nil? visit signin_path - fill_in "Email Address:", with: user.email fill_in "Password:", with: user.password click_button "SIGN IN" @@ -110,6 +109,17 @@ def sign_in_poltergeist(user, options = {}) page.should have_no_selector('.no-websocket-connection') if validate end +# skip the typical login form, which redirects to /client (sloooow). Just sets the cookie, and puts you where you want to be +def fast_signin(user, url) + page.driver.set_cookie(:remember_token, user.remember_token) + visit url +end + +#skip the 'hunt' for Sign Out, and redirect after. Just empty cookie, and go to '/' +def fast_signout + page.driver.set_cookie(:remember_token, '') + visit '/' +end def sign_out() if Capybara.javascript_driver == :poltergeist