Merge branch 'develop' of bitbucket.org:jamkazam/jam-cloud into develop
This commit is contained in:
commit
21a101cc56
|
|
@ -142,3 +142,4 @@ order_event_session.sql
|
|||
emails.sql
|
||||
email_batch.sql
|
||||
user_progress_tracking2.sql
|
||||
bands_did_session.sql
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE bands ADD COLUMN did_real_session boolean default false;
|
||||
|
||||
|
|
@ -54,7 +54,8 @@ group :test do
|
|||
gem 'spork', '0.9.0'
|
||||
gem 'database_cleaner', '0.7.0'
|
||||
gem 'faker'
|
||||
gem 'resque_spec'
|
||||
gem 'resque_spec', :path => "/home/jam/src/resque_spec/"
|
||||
gem 'timecop'
|
||||
end
|
||||
|
||||
# Specify your gem's dependencies in jam_ruby.gemspec
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ require "jam_ruby/resque/scheduled/audiomixer_retry"
|
|||
require "jam_ruby/resque/scheduled/icecast_config_retry"
|
||||
require "jam_ruby/resque/scheduled/icecast_source_check"
|
||||
require "jam_ruby/resque/scheduled/cleanup_facebook_signup"
|
||||
require "jam_ruby/resque/google_analytics_event"
|
||||
require "jam_ruby/mq_router"
|
||||
require "jam_ruby/base_manager"
|
||||
require "jam_ruby/connection_manager"
|
||||
|
|
|
|||
|
|
@ -263,6 +263,12 @@ module JamRuby
|
|||
name
|
||||
end
|
||||
|
||||
def in_real_session?(session)
|
||||
b_members = self.users.sort_by(&:id).map(&:id)
|
||||
s_members = session.users.sort_by(&:id).map(&:id)
|
||||
(b_members - s_members).blank?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def require_at_least_one_genre
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ module JamRuby
|
|||
validate :can_join_music_session, :if => :joining_session?
|
||||
after_save :require_at_least_one_track_when_in_session, :if => :joining_session?
|
||||
after_create :did_create
|
||||
after_save :report_add_participant
|
||||
|
||||
include AASM
|
||||
IDLE_STATE = :idle
|
||||
|
|
@ -127,6 +128,17 @@ module JamRuby
|
|||
self.user.update_lat_lng(self.ip_address) if self.user && self.ip_address
|
||||
end
|
||||
|
||||
def report_add_participant
|
||||
if self.music_session_id_changed? &&
|
||||
self.music_session.present? &&
|
||||
self.connected? &&
|
||||
self.as_musician? &&
|
||||
0 < (count = self.music_session.connected_participant_count)
|
||||
GoogleAnalyticsEvent.report_session_participant(count)
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
def require_at_least_one_track_when_in_session
|
||||
if tracks.count == 0
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ module JamRuby
|
|||
has_many :recordings, :class_name => "JamRuby::Recording", :inverse_of => :music_session
|
||||
belongs_to :band, :inverse_of => :music_sessions, :class_name => "JamRuby::Band", :foreign_key => "band_id"
|
||||
|
||||
after_create :started_session
|
||||
|
||||
validate :require_at_least_one_genre, :limit_max_genres
|
||||
after_save :sync_music_session_history
|
||||
|
||||
|
|
@ -401,6 +403,18 @@ module JamRuby
|
|||
self.save!(:validate => false)
|
||||
end
|
||||
|
||||
def connected_participant_count
|
||||
Connection.where(:music_session_id => self.id,
|
||||
:aasm_state => Connection::CONNECT_STATE.to_s,
|
||||
:as_musician => true)
|
||||
.count
|
||||
end
|
||||
|
||||
def started_session
|
||||
GoogleAnalyticsEvent.track_session_duration(self)
|
||||
GoogleAnalyticsEvent.track_band_real_session(self)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def require_at_least_one_genre
|
||||
|
|
|
|||
|
|
@ -146,6 +146,8 @@ module JamRuby
|
|||
recording.band = music_session.band
|
||||
|
||||
if recording.save
|
||||
GoogleAnalyticsEvent.report_band_recording(recording.band)
|
||||
|
||||
music_session.connections.each do |connection|
|
||||
connection.tracks.each do |track|
|
||||
recording.recorded_tracks << RecordedTrack.create_from_track(track, recording)
|
||||
|
|
|
|||
|
|
@ -1,43 +1,107 @@
|
|||
class GoogleAnalyticsEvent
|
||||
require 'resque'
|
||||
|
||||
@queue = 'google_analytics_event'
|
||||
module JamRuby
|
||||
class GoogleAnalyticsEvent
|
||||
|
||||
@@log = Logging.logger[GoogleAnalyticsEvent]
|
||||
@queue = :google_analytics_event
|
||||
|
||||
def self.perform(category, action)
|
||||
CAT_SESS_SIZE = 'SessionSize'
|
||||
ACTION_SESS_SIZE = 'Size'
|
||||
CAT_SESS_DUR = 'SessionDuration'
|
||||
ACTION_SESS_DUR = 'Duration'
|
||||
CAT_BAND = 'Band'
|
||||
ACTION_BAND_SESS = 'Session'
|
||||
ACTION_BAND_REC = 'Recording'
|
||||
|
||||
@@log.info("starting (#{category}, #{action})")
|
||||
@@log = Logging.logger[GoogleAnalyticsEvent]
|
||||
|
||||
run(category, action)
|
||||
SESSION_INTERVALS = [1, 5, 10, 15, 30, 45, 60, 90, 120, 180] # minutes
|
||||
QUEUE_BAND_TRACKER = :band_tracker
|
||||
QUEUE_SESSION_TRACKER = :session_tracker
|
||||
|
||||
@@log.info("done (#{category}, #{action})")
|
||||
class SessionDurationTracker
|
||||
@queue = QUEUE_SESSION_TRACKER
|
||||
|
||||
end
|
||||
|
||||
def self.enqueue(category, event)
|
||||
begin
|
||||
Resque.enqueue(AudioMixer, category, event)
|
||||
true
|
||||
rescue
|
||||
# implies redis is down. but since there is no retry logic with this, we should at least log a warn in case we've configured something wrong
|
||||
@@log.warn("unable to enqueue")
|
||||
false
|
||||
def self.perform(args={})
|
||||
session_id, interval_idx = args['session_id'], args['interval_idx'].to_i
|
||||
return unless session_id && session = MusicSession.find(session_id)
|
||||
GoogleAnalyticsEvent.enqueue(CAT_SESS_DUR, ACTION_SESS_DUR, SESSION_INTERVALS[interval_idx])
|
||||
interval_idx += 1
|
||||
|
||||
if SESSION_INTERVALS.count-1 > interval_idx
|
||||
next_time = session.created_at + SESSION_INTERVALS[interval_idx].minutes
|
||||
Resque.enqueue_at(next_time, self, :session_id => session_id, :interval_idx => interval_idx)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.run(category, action)
|
||||
def self.track_session_duration(session)
|
||||
Resque.enqueue_at(SESSION_INTERVALS[0].minute.from_now,
|
||||
SessionDurationTracker,
|
||||
:session_id => session.id,
|
||||
:interval_idx => 0)
|
||||
end
|
||||
|
||||
raise "no google analytics tracking ID" unless APP_CONFIG.ga_ua
|
||||
class BandSessionTracker
|
||||
@queue = QUEUE_BAND_TRACKER
|
||||
|
||||
params = {
|
||||
def self.perform(session_id)
|
||||
return unless session = MusicSession.find(session_id)
|
||||
band = session.band
|
||||
if band.in_real_session?(session)
|
||||
band.update_attribute(:did_real_session, true)
|
||||
GoogleAnalyticsEvent.enqueue(CAT_BAND, ACTION_BAND_SESS, nil)
|
||||
end if band
|
||||
end
|
||||
end
|
||||
|
||||
BAND_SESSION_MIN_DURATION = 15 # minutes
|
||||
|
||||
def self.track_band_real_session(session)
|
||||
if session.band && !session.band.did_real_session?
|
||||
Resque.enqueue_at(BAND_SESSION_MIN_DURATION.minutes.from_now,
|
||||
BandSessionTracker,
|
||||
session.id)
|
||||
end
|
||||
end
|
||||
|
||||
def self.report_band_recording(band)
|
||||
if band && 1 == Recording.where(:band_id => band.id).count
|
||||
self.enqueue(CAT_BAND, ACTION_BAND_REC)
|
||||
end
|
||||
end
|
||||
|
||||
def self.report_session_participant(participant_count)
|
||||
self.enqueue(CAT_SESS_SIZE, ACTION_SESS_SIZE, participant_count)
|
||||
end
|
||||
|
||||
def self.enqueue(category, event, data=nil)
|
||||
begin
|
||||
Resque.enqueue(GoogleAnalyticsEvent, category, event, data)
|
||||
true
|
||||
rescue
|
||||
# implies redis is down. but since there is no retry logic with this, we should at least log a warn in case we've configured something wrong
|
||||
@@log.warn("unable to enqueue")
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def self.perform(category, action, data)
|
||||
@@log.info("starting (#{category}, #{action})")
|
||||
raise "no google analytics tracking ID" unless APP_CONFIG.ga_ua
|
||||
params = {
|
||||
v: APP_CONFIG.ga_ua_version,
|
||||
tid: APP_CONFIG.ga_ua,
|
||||
cid: APP_CONFIG.ga_anonymous_client_id,
|
||||
t: "event",
|
||||
ec: category,
|
||||
ea: action
|
||||
}
|
||||
ea: action,
|
||||
el: 'data',
|
||||
ev: data.to_s
|
||||
}
|
||||
RestClient.post(APP_CONFIG.ga_endpoint, params: params, timeout: 8, open_timeout: 8)
|
||||
@@log.info("done (#{category}, #{action})")
|
||||
end
|
||||
|
||||
RestClient.post(APP_CONFIG.ga_endpoint, params: params, timeout: 8, open_timeout: 8)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ FactoryGirl.define do
|
|||
|
||||
association :owner, factory: :user
|
||||
association :music_session, factory: :music_session
|
||||
association :band, factory: :band
|
||||
|
||||
factory :recording_with_track do
|
||||
before(:create) { |recording|
|
||||
|
|
|
|||
|
|
@ -0,0 +1,105 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe GoogleAnalyticsEvent do
|
||||
|
||||
let(:ga) { GoogleAnalyticsEvent.new }
|
||||
|
||||
describe "track band analytics" do
|
||||
it 'reports first recording' do
|
||||
ResqueSpec.reset!
|
||||
user = FactoryGirl.create(:user)
|
||||
band = FactoryGirl.create(:band)
|
||||
music_session = FactoryGirl.create(:music_session,
|
||||
:creator => user,
|
||||
:musician_access => true,
|
||||
:band => band)
|
||||
recording = Recording.start(music_session, user)
|
||||
expect(Recording.where(:band_id => band.id).count).to eq(1)
|
||||
|
||||
GoogleAnalyticsEvent.should have_queued(GoogleAnalyticsEvent::CAT_BAND,
|
||||
GoogleAnalyticsEvent::ACTION_BAND_REC,
|
||||
nil)
|
||||
end
|
||||
|
||||
it 'reports first real session' do
|
||||
ResqueSpec.reset!
|
||||
JamRuby::GoogleAnalyticsEvent::BandSessionTracker.should have_schedule_size_of(0)
|
||||
user = FactoryGirl.create(:user)
|
||||
user1 = FactoryGirl.create(:user)
|
||||
band = FactoryGirl.create(:band)
|
||||
band.users << user
|
||||
band.users << user1
|
||||
band.reload
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user,
|
||||
:musician_access => true, :band => band)
|
||||
expect(band.band_musicians.count).to eq(2)
|
||||
expect(band.did_real_session).to eq(false)
|
||||
connection = FactoryGirl.create(:connection, :user => user, :as_musician => true,
|
||||
:aasm_state => Connection::CONNECT_STATE.to_s,
|
||||
:music_session => music_session)
|
||||
connection = FactoryGirl.create(:connection, :user => user1, :as_musician => true,
|
||||
:aasm_state => Connection::CONNECT_STATE.to_s,
|
||||
:music_session => music_session)
|
||||
music_session.reload
|
||||
expect(music_session.connected_participant_count).to eq(2)
|
||||
expect(band.did_real_session).to eq(false)
|
||||
|
||||
ResqueSpec.queues["#{GoogleAnalyticsEvent::QUEUE_BAND_TRACKER}_scheduled"].select do |qq|
|
||||
qq[:class] == GoogleAnalyticsEvent::BandSessionTracker.name
|
||||
end.count.should eq(1)
|
||||
# GoogleAnalyticsEvent::BandSessionTracker.should have_schedule_size_of_at_least(1)
|
||||
GoogleAnalyticsEvent.should_not have_queued(GoogleAnalyticsEvent::CAT_BAND, GoogleAnalyticsEvent::ACTION_BAND_SESS, nil)
|
||||
Timecop.freeze((GoogleAnalyticsEvent::BAND_SESSION_MIN_DURATION + 1).minutes.from_now)
|
||||
|
||||
qname = "#{ResqueSpec.queue_name(JamRuby::GoogleAnalyticsEvent::BandSessionTracker)}_scheduled"
|
||||
expect(ResqueSpec.peek(qname).present?).to eq(true)
|
||||
ResqueSpec.perform_next(qname)
|
||||
GoogleAnalyticsEvent.should have_queued(GoogleAnalyticsEvent::CAT_BAND,
|
||||
GoogleAnalyticsEvent::ACTION_BAND_SESS,
|
||||
nil)
|
||||
band.reload
|
||||
expect(band.did_real_session).to eq(true)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "track session analytics" do
|
||||
before :each do
|
||||
ResqueSpec.reset!
|
||||
end
|
||||
it 'reports size increment' do
|
||||
user = FactoryGirl.create(:user)
|
||||
music_session = FactoryGirl.create(:music_session,
|
||||
:creator => user,
|
||||
:musician_access => true)
|
||||
connection = FactoryGirl.create(:connection, :user => user,
|
||||
:as_musician => true,
|
||||
:aasm_state => Connection::CONNECT_STATE.to_s,
|
||||
:music_session => music_session)
|
||||
GoogleAnalyticsEvent.should have_queued(GoogleAnalyticsEvent::CAT_SESS_SIZE,
|
||||
GoogleAnalyticsEvent::ACTION_SESS_SIZE,
|
||||
music_session.connected_participant_count)
|
||||
end
|
||||
|
||||
it 'reports duration' do
|
||||
user = FactoryGirl.create(:user)
|
||||
JamRuby::GoogleAnalyticsEvent::SessionDurationTracker.should have_schedule_size_of(0)
|
||||
music_session = FactoryGirl.create(:music_session,
|
||||
:creator => user,
|
||||
:musician_access => true)
|
||||
GoogleAnalyticsEvent::SessionDurationTracker.should have_schedule_size_of(1)
|
||||
|
||||
GoogleAnalyticsEvent::SESSION_INTERVALS.each do |interval|
|
||||
Timecop.travel((interval + 1).minutes.from_now)
|
||||
qname = "#{ResqueSpec.queue_name(JamRuby::GoogleAnalyticsEvent::SessionDurationTracker)}_scheduled"
|
||||
next unless ResqueSpec.peek(qname).present?
|
||||
ResqueSpec.perform_next(qname)
|
||||
GoogleAnalyticsEvent.should have_queued(GoogleAnalyticsEvent::CAT_SESS_DUR,
|
||||
GoogleAnalyticsEvent::ACTION_SESS_DUR,
|
||||
interval)
|
||||
end
|
||||
GoogleAnalyticsEvent.should have_queue_size_of(GoogleAnalyticsEvent::SESSION_INTERVALS.count - 1)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -26,6 +26,9 @@ require 'spork'
|
|||
require 'database_cleaner'
|
||||
require 'factories'
|
||||
|
||||
require 'timecop'
|
||||
require 'resque_spec/scheduler'
|
||||
|
||||
# uncomment this to see active record logs
|
||||
#ActiveRecord::Base.logger = Logger.new(STDOUT) if defined?(ActiveRecord::Base)
|
||||
|
||||
|
|
@ -68,6 +71,7 @@ Spork.prefork do
|
|||
#
|
||||
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
||||
RSpec.configure do |config|
|
||||
|
||||
config.color_enabled = true
|
||||
config.treat_symbols_as_metadata_keys_with_true_values = true
|
||||
config.run_all_when_everything_filtered = true
|
||||
|
|
@ -105,6 +109,32 @@ Spork.prefork do
|
|||
# the seed, which is printed after each run.
|
||||
# --seed 1234
|
||||
config.order = 'random'
|
||||
|
||||
REDIS_PID = "#{Rails.root}/tmp/pids/redis-test.pid"
|
||||
REDIS_CACHE_PATH = "#{Rails.root}/tmp/cache/"
|
||||
config.before(:suite) do
|
||||
redis_options = {
|
||||
"--daemonize" => 'yes',
|
||||
"--pidfile" => REDIS_PID,
|
||||
"--port" => 9736,
|
||||
"--timeout" => 300,
|
||||
"--save 900" => 1,
|
||||
"--save 300" => 1,
|
||||
"--save 60" => 10000,
|
||||
"--dbfilename" => "dump.rdb",
|
||||
"--dir" => REDIS_CACHE_PATH,
|
||||
"--loglevel" => "debug",
|
||||
"--logfile" => "stdout",
|
||||
"--databases" => 16
|
||||
}.map { |k, v| "#{k} #{v}" }.join(" ")
|
||||
`redis-server #{redis_options}`
|
||||
end
|
||||
config.after(:suite) do
|
||||
%x{
|
||||
cat #{REDIS_PID} | xargs kill -QUIT
|
||||
rm -f #{REDIS_CACHE_PATH}dump.rdb
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@
|
|||
instrumentHtml = '<td><div class="nowrap">';
|
||||
$.each(val.instrument_ids, function(index, val) {
|
||||
instrumentHtml += '<img src="' + context.JK.getInstrumentIcon24(val) + '" width="24" height="24" /> ';
|
||||
})
|
||||
});
|
||||
instrumentHtml += '</div></td>';
|
||||
|
||||
musicianHtml += instrumentHtml;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
background-color:#242323;
|
||||
border:solid 1px #ed3618;
|
||||
position:absolute;
|
||||
z-index:999;
|
||||
z-index:1100;
|
||||
|
||||
|
||||
&.musician-bubble {
|
||||
|
|
|
|||
|
|
@ -16,16 +16,16 @@ describe "Bands", :js => true, :type => :feature, :capybara_feature => true do
|
|||
#end
|
||||
end
|
||||
|
||||
let(:fan) { FactoryGirl.create(:fan) }
|
||||
let(:user) { FactoryGirl.create(:user) }
|
||||
let(:finder) { FactoryGirl.create(:user) }
|
||||
|
||||
before(:each) do
|
||||
UserMailer.deliveries.clear
|
||||
navigate_band_setup
|
||||
end
|
||||
|
||||
def navigate_band_setup
|
||||
sign_in_poltergeist(user)
|
||||
def navigate_band_setup login=user
|
||||
sign_in_poltergeist(login)
|
||||
wait_until_curtain_gone
|
||||
find('div.homecard.profile').trigger(:click)
|
||||
find('#profile-bands-link').trigger(:click)
|
||||
|
|
@ -33,26 +33,143 @@ describe "Bands", :js => true, :type => :feature, :capybara_feature => true do
|
|||
expect(page).to have_selector('#band-setup-title')
|
||||
end
|
||||
|
||||
it "have validation errors shown, but then can navigate past and eventually save" do
|
||||
find('#btn-band-setup-next').trigger(:click)
|
||||
find('#tdBandName .error-text li', text: "can't be blank")
|
||||
find('#tdBandBiography .error-text li', text: "can't be blank")
|
||||
find('#tdBandGenres .error-text li', text: "At least 1 genre is required.")
|
||||
def complete_band_setup_form(band, biography, params={})
|
||||
navigate_band_setup unless URI.parse(current_url).fragment == '/band/setup/new'
|
||||
params['band-name'] ||= band || "Default band name"
|
||||
params['band-biography'] ||= biography || "Default band biography"
|
||||
|
||||
within('#band-setup-form') do
|
||||
fill_in "band-name", with: "The Band"
|
||||
fill_in "band-biography", with: "Biography"
|
||||
params.each do |field, value|
|
||||
fill_in field, with: "#{value}"
|
||||
end
|
||||
first('#band-genres input[type="checkbox"]').trigger(:click)
|
||||
end
|
||||
|
||||
sleep 1 # work around race condition
|
||||
find('#btn-band-setup-next').trigger(:click)
|
||||
find('h2', text: 'Step 2: Add Band Members')
|
||||
|
||||
find('#btn-band-setup-save').trigger(:click)
|
||||
find('#band-profile-name', text: "The Band")
|
||||
find('#band-profile-biography', text: "Biography")
|
||||
end
|
||||
|
||||
context "band profile - new band setup" do
|
||||
it "displays 'Set up your band' link to user" do
|
||||
sign_in_poltergeist user
|
||||
view_profile_of user
|
||||
find('#profile-bands-link').trigger(:click)
|
||||
expect(page).to have_selector('#band-setup-link')
|
||||
end
|
||||
|
||||
it "does not display band setup link when viewed by other user" do
|
||||
in_client(fan) do
|
||||
sign_in_poltergeist fan
|
||||
view_profile_of user
|
||||
find('#profile-bands-link').trigger(:click)
|
||||
|
||||
expect(page).to_not have_selector('#band-setup-link')
|
||||
end
|
||||
end
|
||||
|
||||
it "indicates required fields and user may eventually complete" do
|
||||
navigate_band_setup
|
||||
find('#btn-band-setup-next').trigger(:click)
|
||||
expect(page).to have_selector('#tdBandName .error-text li', text: "can't be blank")
|
||||
expect(page).to have_selector('#tdBandBiography .error-text li', text: "can't be blank")
|
||||
expect(page).to have_selector('#tdBandGenres .error-text li', text: "At least 1 genre is required.")
|
||||
|
||||
complete_band_setup_form("Band name", "Band biography")
|
||||
|
||||
expect(page).to have_selector('#band-profile-name', text: "Band name")
|
||||
expect(page).to have_selector('#band-profile-biography', text: "Band biography")
|
||||
|
||||
end
|
||||
|
||||
it "limits genres to 3" do
|
||||
navigate_band_setup
|
||||
within('#band-setup-form') do
|
||||
fill_in 'band-name', with: "whatever"
|
||||
fill_in 'band-biography', with: "a good story"
|
||||
all('#band-genres input[type="checkbox"]').each_with_index do |cb, i|
|
||||
cb.trigger(:click) unless i > 3
|
||||
end
|
||||
end
|
||||
sleep 1
|
||||
find('#btn-band-setup-next').trigger(:click)
|
||||
expect(page).to have_selector('#tdBandGenres .error-text li', text: "No more than 3 genres are allowed.")
|
||||
end
|
||||
|
||||
it "handles max-length field input" do
|
||||
pending "update this after VRFS-1610 is resolved"
|
||||
max = {
|
||||
name: 1024,
|
||||
bio: 4000,
|
||||
website: 1024 # unsure what the max is, see VRFS-1610
|
||||
}
|
||||
navigate_band_setup
|
||||
band_name = 'a'*(max[:name] + 1)
|
||||
band_bio = 'b'*(max[:bio] + 1)
|
||||
band_website = 'c'*(max[:website] + 1)
|
||||
complete_band_setup_form(band_name, band_bio, 'band-website' => band_website)
|
||||
|
||||
expect(page).to have_selector('#band-profile-name', text: band_name.slice(0, max[:name]))
|
||||
expect(page).to have_selector('#band-profile-biography', text: band_bio.slice(0, max[:bio]))
|
||||
end
|
||||
|
||||
it "handles special characters in text fields" do
|
||||
pending "update this after VRFS-1609 is resolved"
|
||||
navigate_band_setup
|
||||
band_name = garbage(3) + ' ' + garbage(50)
|
||||
band_bio = garbage(500)
|
||||
band_website = garbage(500)
|
||||
complete_band_setup_form(band_name, band_bio, 'band-website' => band_website)
|
||||
|
||||
expect(page).to have_selector('#band-profile-name', text: band_name)
|
||||
expect(page).to have_selector('#band-profile-biography', text: band_bio)
|
||||
end
|
||||
|
||||
it "another user receives invite notification during Band Setup"
|
||||
end
|
||||
|
||||
|
||||
context "about view" do
|
||||
it "displays the band's information to another user"
|
||||
#photo
|
||||
#name
|
||||
#website address
|
||||
#country, state, city
|
||||
#biography/description
|
||||
#genres chosen
|
||||
#number of followers, recordings, sessions
|
||||
#actions: follow button
|
||||
|
||||
it "allows a user to follow the band"
|
||||
end
|
||||
|
||||
context "members view" do
|
||||
it "photo and name links to the musician's profile page"
|
||||
it "displays photo, name, location, instruments played"
|
||||
it "displays a hover bubble containing more info on musician"
|
||||
it "displays any pending band invitations when viewed by current band member"
|
||||
|
||||
end
|
||||
|
||||
context "history view" do
|
||||
it "shows public info"
|
||||
it "does not show private info to non-band user"
|
||||
it "shows private info to band user"
|
||||
end
|
||||
|
||||
context "social view" do
|
||||
it "displays musicians and fans who follow band"
|
||||
end
|
||||
|
||||
context "band profile - editing" do
|
||||
it "about page shows the current band's info when 'Edit Profile' is clicked"
|
||||
it "members page shows 'Edit Members' button and user can remove member"
|
||||
it "non-member cannot Edit Profile"
|
||||
it "non-member cannot Edit Members"
|
||||
end
|
||||
|
||||
it "band shows up in sidebar search result"
|
||||
end
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -415,6 +415,13 @@ def assert_all_tracks_seen(users=[])
|
|||
end
|
||||
end
|
||||
|
||||
def view_profile_of user
|
||||
id = user.kind_of?(JamRuby::User) ? user.id : user
|
||||
# assume some user signed in already (allows reuse in multi-user tests)
|
||||
visit "/client#/profile/#{id}"
|
||||
wait_until_curtain_gone
|
||||
end
|
||||
|
||||
def show_user_menu
|
||||
page.execute_script("$('ul.shortcuts').show()")
|
||||
#page.execute_script("JK.UserDropdown.menuHoverIn()")
|
||||
|
|
@ -430,4 +437,15 @@ def send_key(selector, keycode = 13)
|
|||
keypress_script = "var e = $.Event('keyup', { keyCode: #{keycode} }); jQuery('#{selector}').trigger(e);"
|
||||
page.driver.execute_script(keypress_script)
|
||||
|
||||
end
|
||||
|
||||
def special_characters
|
||||
["?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}"]
|
||||
end
|
||||
|
||||
def garbage length
|
||||
output = ''
|
||||
length.times { output << special_characters.sample }
|
||||
output.gsub!(/<[\/|!|\?]/, '/<') # security risk -- avoids inputting tags until VRFS-1609 resolved
|
||||
output.slice(0, length)
|
||||
end
|
||||
Loading…
Reference in New Issue