merging develop

This commit is contained in:
Jonathan Kolyer 2014-04-30 14:21:23 +00:00
commit 2ee96c49ec
41 changed files with 803 additions and 199 deletions

View File

@ -147,3 +147,8 @@ email_change_default_sender.sql
affiliate_partners.sql affiliate_partners.sql
chat_messages.sql chat_messages.sql
session_ratings.sql session_ratings.sql
diagnostics.sql
user_mods.sql
connection_stale_expire.sql
rename_chat_messages.sql
fix_connection_fields.sql

View File

@ -0,0 +1,2 @@
ALTER TABLE connections ADD COLUMN stale_time INTEGER NOT NULL DEFAULT 40;
ALTER TABLE connections ADD COLUMN expire_time INTEGER NOT NULL DEFAULT 60;

11
db/up/diagnostics.sql Normal file
View File

@ -0,0 +1,11 @@
CREATE TABLE diagnostics
(
id VARCHAR(64) NOT NULL DEFAULT uuid_generate_v4(),
user_id VARCHAR(64) NOT NULL REFERENCES users (id) ON DELETE CASCADE,
type VARCHAR(255) NOT NULL,
creator VARCHAR(255) NOT NULL,
data TEXT,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX diagnostics_type_idx ON diagnostics(type);

View File

@ -0,0 +1,8 @@
ALTER TABLE connections ALTER COLUMN user_id SET NOT NULL;
ALTER TABLE connections ALTER COLUMN ip_address SET NOT NULL;
ALTER TABLE connections DROP COLUMN latitude;
ALTER TABLE connections DROP COLUMN longitude;
ALTER TABLE connections DROP COLUMN countrycode;
ALTER TABLE connections DROP COLUMN region;
ALTER TABLE connections DROP COLUMN city;

View File

@ -0,0 +1,2 @@
-- Rename columns .
ALTER TABLE chat_messages RENAME COLUMN messsage TO message;

1
db/up/user_mods.sql Normal file
View File

@ -0,0 +1 @@
ALTER TABLE users ADD COLUMN mods JSON;

View File

@ -141,6 +141,7 @@ require "jam_ruby/models/email_error"
require "jam_ruby/app/mailers/async_mailer" require "jam_ruby/app/mailers/async_mailer"
require "jam_ruby/app/mailers/batch_mailer" require "jam_ruby/app/mailers/batch_mailer"
require "jam_ruby/models/affiliate_partner" require "jam_ruby/models/affiliate_partner"
require "jam_ruby/models/chat_message"
include Jampb include Jampb

View File

@ -75,28 +75,13 @@ module JamRuby
if location.nil? if location.nil?
# todo what's a better default location? # todo what's a better default location?
locidispid = 0 locidispid = 0
latitude = 0.0
longitude = 0.0
countrycode = 'US'
region = 'TX'
city = 'Austin'
else else
locidispid = locid*1000000+ispid locidispid = locid*1000000+ispid
latitude = location.latitude
longitude = location.longitude
countrycode = location.countrycode
region = location.region
city = location.city
end end
conn.ip_address = ip_address conn.ip_address = ip_address
conn.addr = addr conn.addr = addr
conn.locidispid = locidispid conn.locidispid = locidispid
conn.latitude = latitude
conn.longitude = longitude
conn.countrycode = countrycode
conn.region = region
conn.city = city
conn.save!(validate: false) conn.save!(validate: false)
end end
@ -230,24 +215,14 @@ SQL
if location.nil? if location.nil?
# todo what's a better default location? # todo what's a better default location?
locidispid = 0 locidispid = 0
latitude = 0.0
longitude = 0.0
countrycode = 'US'
region = 'TX'
city = 'Austin'
else else
locidispid = locid*1000000+ispid locidispid = locid*1000000+ispid
latitude = location.latitude
longitude = location.longitude
countrycode = location.countrycode
region = location.region
city = location.city
end end
lock_connections(conn) lock_connections(conn)
conn.exec("INSERT INTO connections (user_id, client_id, ip_address, client_type, addr, locidispid, latitude, longitude, countrycode, region, city, aasm_state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)", conn.exec("INSERT INTO connections (user_id, client_id, ip_address, client_type, addr, locidispid, aasm_state) VALUES ($1, $2, $3, $4, $5, $6, $7)",
[user_id, client_id, ip_address, client_type, addr, locidispid, latitude, longitude, countrycode, region, city, Connection::CONNECT_STATE.to_s]).clear [user_id, client_id, ip_address, client_type, addr, locidispid, Connection::CONNECT_STATE.to_s]).clear
# we just created a new connection-if this is the first time the user has shown up, we need to send out a message to his friends # we just created a new connection-if this is the first time the user has shown up, we need to send out a message to his friends
conn.exec("SELECT count(user_id) FROM connections WHERE user_id = $1", [user_id]) do |result| conn.exec("SELECT count(user_id) FROM connections WHERE user_id = $1", [user_id]) do |result|
@ -369,23 +344,21 @@ SQL
end end
end end
# if a blk is passed in, upon success, it will be called and you can issue notifications def join_music_session(user, client_id, music_session, as_musician, tracks)
# within the connection table lock
def join_music_session(user, client_id, music_session, as_musician, tracks, &blk)
connection = nil connection = nil
user_id = user.id
music_session_id = music_session.id
ConnectionManager.active_record_transaction do |connection_manager| ConnectionManager.active_record_transaction do |connection_manager|
db_conn = connection_manager.pg_conn db_conn = connection_manager.pg_conn
connection = Connection.find_by_client_id_and_user_id!(client_id, user_id) connection = Connection.find_by_client_id_and_user_id!(client_id, user.id)
connection.music_session_id = music_session_id
connection.as_musician = as_musician connection.join_the_session(music_session, as_musician, tracks)
connection.joining_session = true # connection.music_session_id = music_session.id
connection.joined_session_at = Time.now # connection.as_musician = as_musician
associate_tracks(connection, tracks) # connection.joining_session = true
connection.save # connection.joined_session_at = Time.now
# associate_tracks(connection, tracks)
# connection.save
if connection.errors.any? if connection.errors.any?
raise ActiveRecord::Rollback raise ActiveRecord::Rollback
@ -419,7 +392,7 @@ SQL
end end
# can throw exception if the session is deleted just before this # can throw exception if the session is deleted just before this
conn.exec("UPDATE connections SET music_session_id = NULL, joined_session_at = NULL, as_musician = NULL WHERE client_id = $1 AND user_id =$2", [client_id, user_id]) do |result| conn.exec("UPDATE connections SET music_session_id = NULL, joined_session_at = NULL, as_musician = NULL WHERE client_id = $1 AND user_id = $2 AND music_session_id = $3", [client_id, user_id, music_session_id]) do |result|
if result.cmd_tuples == 1 if result.cmd_tuples == 1
@log.debug("disassociated music_session with connection for client_id=#{client_id}, user_id=#{user_id}") @log.debug("disassociated music_session with connection for client_id=#{client_id}, user_id=#{user_id}")
@ -442,23 +415,23 @@ SQL
conn.exec("LOCK connections IN EXCLUSIVE MODE").clear conn.exec("LOCK connections IN EXCLUSIVE MODE").clear
end end
def associate_tracks(connection, tracks) # def associate_tracks(connection, tracks)
@log.debug "Tracks:" # @log.debug "Tracks:"
@log.debug tracks # @log.debug tracks
connection.tracks.clear() # connection.tracks.clear()
#
unless tracks.nil? # unless tracks.nil?
tracks.each do |track| # tracks.each do |track|
instrument = Instrument.find(track["instrument_id"]) # instrument = Instrument.find(track["instrument_id"])
t = Track.new # t = Track.new
t.instrument = instrument # t.instrument = instrument
t.connection = connection # t.connection = connection
t.sound = track["sound"] # t.sound = track["sound"]
t.client_track_id = track["client_track_id"] # t.client_track_id = track["client_track_id"]
t.save # t.save
connection.tracks << t # connection.tracks << t
end # end
end # end
end # end
end end
end end

View File

@ -12,7 +12,7 @@ require 'jam_ruby'
module JamWebEventMachine module JamWebEventMachine
@@log = Logging.logger[JamWebEventMachine] @@log = Logging.logger[JamWebEventMachine]
# starts amqp & eventmachine up first. # starts amqp & eventmachine up first.
# and then calls your block. # and then calls your block.
# After the supplied block is done, # After the supplied block is done,
@ -36,8 +36,9 @@ module JamWebEventMachine
end end
def self.run_em(calling_thread = nil) def self.run_em(calling_thread = nil, semaphore = nil, ran = {})
semaphore.lock if semaphore
EM.run do EM.run do
# this is global because we need to check elsewhere if we are currently connected to amqp before signalling success with some APIs, such as 'create session' # this is global because we need to check elsewhere if we are currently connected to amqp before signalling success with some APIs, such as 'create session'
$amqp_connection_manager = AmqpConnectionManager.new(true, 4, :host => APP_CONFIG.rabbitmq_host, :port => APP_CONFIG.rabbitmq_port) $amqp_connection_manager = AmqpConnectionManager.new(true, 4, :host => APP_CONFIG.rabbitmq_host, :port => APP_CONFIG.rabbitmq_port)
@ -54,6 +55,8 @@ module JamWebEventMachine
end end
end end
ran[:ran] = true
semaphore.unlock if semaphore
calling_thread.wakeup if calling_thread calling_thread.wakeup if calling_thread
end end
end end
@ -65,12 +68,18 @@ module JamWebEventMachine
end end
def self.run def self.run
return if defined?(Rails::Console)
ran = {}
semaphore = Mutex.new
current = Thread.current current = Thread.current
Thread.new do Thread.new do
run_em(current) run_em(current, semaphore, ran)
end end
Thread.stop semaphore.synchronize {
unless ran[:ran]
semaphore.sleep(10)
end
}
end end
def self.start def self.start

View File

@ -1,26 +1,55 @@
module JamRuby module JamRuby
class ChatMessage < ActiveRecord::Base class ChatMessage < ActiveRecord::Base
self.table_name = 'chat_messages'
self.primary_key = 'id' self.primary_key = 'id'
default_scope order('created_at DESC') default_scope order('created_at DESC')
belongs_to :user, :class_name => "JamRuby::User", :foreign_key => "user_id" attr_accessible :user_id, :message, :music_session_id
belongs_to :session, :class_name => "JamRuby::MusicSession", :foreign_key => "session_id"
belongs_to :user
belongs_to :music_session
validates :message, length: {minimum: 1, maximum: 255}, no_profanity: true validates :message, length: {minimum: 1, maximum: 255}, no_profanity: true
def self.send_chat_msg(music_session, chat_msg, user) class << self
msg = @@message_factory.chat_message(
music_session.id, @@mq_router = MQRouter.new
user.name, @@message_factory = MessageFactory.new
user.id,
chat_msg.message, def index(user, params = {})
chat_msg.id, limit = params[:limit]
chat_msg.created_at limit ||= 20
) limit = limit.to_i
start = params[:start].presence
start = start.to_i || 0
query = ChatMessage.offset(start).limit(limit)
if query.length == 0
[query, nil]
elsif query.length < limit
[query, nil]
else
[query, start + limit]
end
end
def send_chat_msg(music_session, chat_msg, user, client_id)
msg = @@message_factory.chat_message(
music_session.id,
user.name,
user.id,
chat_msg.message,
chat_msg.id,
chat_msg.created_at.utc.iso8601
)
@@mq_router.server_publish_to_session(music_session, msg, sender = {:client_id => client_id})
end
@@mq_router.server_publish_to_session(music_session, msg, sender = {:client_id => chat_msg.user_id})
end end
end end

View File

@ -68,6 +68,13 @@ module JamRuby
def can_join_music_session def can_join_music_session
# puts "can_join_music_session: #{music_session_id} was #{music_session_id_was}" if music_session_id_changed?
if music_session_id_changed? and !(music_session_id_was.nil? or music_session_id_was.blank?)
errors.add(:music_session, ValidationMessages::CANT_JOIN_MULTIPLE_SESSIONS)
return false
end
if music_session.nil? if music_session.nil?
errors.add(:music_session, ValidationMessages::MUSIC_SESSION_MUST_BE_SPECIFIED) errors.add(:music_session, ValidationMessages::MUSIC_SESSION_MUST_BE_SPECIFIED)
return false return false
@ -139,14 +146,35 @@ module JamRuby
true true
end end
def join_the_session(music_session, as_musician) def join_the_session(music_session, as_musician, tracks)
self.music_session = music_session self.music_session_id = music_session.id
self.as_musician = as_musician self.as_musician = as_musician
self.joining_session = true self.joining_session = true
self.joined_session_at = Time.now self.joined_session_at = Time.now
self.save! associate_tracks(tracks) unless tracks.nil?
self.save
end end
def associate_tracks(tracks)
# @log.debug "Tracks:"
# @log.debug tracks
unless tracks.nil?
self.tracks.clear()
tracks.each do |track|
t = Track.new
t.instrument = Instrument.find(track["instrument_id"])
t.connection = self
t.sound = track["sound"]
t.client_track_id = track["client_track_id"]
t.save # todo what if it fails?
self.tracks << t
end
end
end
private private
def require_at_least_one_track_when_in_session def require_at_least_one_track_when_in_session

View File

@ -22,6 +22,7 @@ module JamRuby
has_many :fan_invitations, :foreign_key => "music_session_id", :inverse_of => :music_session, :class_name => "JamRuby::FanInvitation" has_many :fan_invitations, :foreign_key => "music_session_id", :inverse_of => :music_session, :class_name => "JamRuby::FanInvitation"
has_many :invited_fans, :through => :fan_invitations, :class_name => "JamRuby::User", :foreign_key => "receiver_id", :source => :receiver has_many :invited_fans, :through => :fan_invitations, :class_name => "JamRuby::User", :foreign_key => "receiver_id", :source => :receiver
has_many :recordings, :class_name => "JamRuby::Recording", :inverse_of => :music_session has_many :recordings, :class_name => "JamRuby::Recording", :inverse_of => :music_session
has_many :chats, :class_name => "JamRuby::ChatMessages", :foreign_key => "session_id"
belongs_to :band, :inverse_of => :music_sessions, :class_name => "JamRuby::Band", :foreign_key => "band_id" belongs_to :band, :inverse_of => :music_sessions, :class_name => "JamRuby::Band", :foreign_key => "band_id"
after_create :started_session after_create :started_session

View File

@ -61,6 +61,9 @@ module JamRuby
has_many :notifications, :class_name => "JamRuby::Notification", :foreign_key => "target_user_id" has_many :notifications, :class_name => "JamRuby::Notification", :foreign_key => "target_user_id"
has_many :inverse_notifications, :through => :notifications, :class_name => "JamRuby::User" has_many :inverse_notifications, :through => :notifications, :class_name => "JamRuby::User"
# chats
has_many :chats, :class_name => "JamRuby::ChatMessage", :foreign_key => "user_id"
# friends # friends
has_many :friendships, :class_name => "JamRuby::Friendship", :foreign_key => "user_id" has_many :friendships, :class_name => "JamRuby::Friendship", :foreign_key => "user_id"
has_many :friends, :through => :friendships, :class_name => "JamRuby::User" has_many :friends, :through => :friendships, :class_name => "JamRuby::User"

View File

@ -91,11 +91,6 @@ FactoryGirl.define do
as_musician true as_musician true
addr 0 addr 0
locidispid 0 locidispid 0
latitude 0.0
longitude 0.0
countrycode 'US'
region 'TX'
city 'Austin'
client_type 'client' client_type 'client'
end end

View File

@ -78,11 +78,6 @@ describe ConnectionManager do
cc.ip_address.should eql("1.1.1.1") cc.ip_address.should eql("1.1.1.1")
cc.addr.should == 0x01010101 cc.addr.should == 0x01010101
cc.locidispid.should == 17192000002 cc.locidispid.should == 17192000002
cc.latitude.should == 30.2076
cc.longitude.should == -97.8587
cc.city.should eql('Austin')
cc.region.should eql('TX')
cc.countrycode.should eql('US')
count = @connman.delete_connection(client_id) count = @connman.delete_connection(client_id)
count.should == 0 count.should == 0
@ -113,11 +108,6 @@ describe ConnectionManager do
cc.ip_address.should eql("1.1.1.1") cc.ip_address.should eql("1.1.1.1")
cc.addr.should == 0x01010101 cc.addr.should == 0x01010101
cc.locidispid.should == 17192000002 cc.locidispid.should == 17192000002
cc.latitude.should == 30.2076
cc.longitude.should == -97.8587
cc.city.should eql('Austin')
cc.region.should eql('TX')
cc.countrycode.should eql('US')
@connman.reconnect(cc, nil, "33.1.2.3") @connman.reconnect(cc, nil, "33.1.2.3")
@ -126,11 +116,6 @@ describe ConnectionManager do
cc.ip_address.should eql("33.1.2.3") cc.ip_address.should eql("33.1.2.3")
cc.addr.should == 0x21010203 cc.addr.should == 0x21010203
cc.locidispid.should == 30350000003 cc.locidispid.should == 30350000003
cc.latitude.should == 29.7633
cc.longitude.should == -95.3633
cc.city.should eql('Houston')
cc.region.should eql('TX')
cc.countrycode.should eql('US')
count = @connman.delete_connection(client_id) count = @connman.delete_connection(client_id)
count.should == 0 count.should == 0
@ -490,34 +475,57 @@ describe ConnectionManager do
end end
it "join_music_session fails if user has music_session already active" do it "join_music_session fails if user has music_session already active" do
# there are two different problems: user can only be in one active music_session at a time,
# and a connection can only point to one active music_session at a time. this is a test of
# the former but we need a test of the latter, too.
pending pending
end
it "join_music_session fails if connection has music_session already active" do
# there are two different problems: user can only be in one active music_session at a time,
# and a connection can only point to one active music_session at a time. this is a test of
# the latter but we need a test of the former, too.
user_id = create_user("test", "user11", "user11@jamkazam.com") user_id = create_user("test", "user11", "user11@jamkazam.com")
user = User.find(user_id) user = User.find(user_id)
music_session = MusicSession.find(create_music_session(user_id))
client_id = Faker::Number.number(20) client_id1 = Faker::Number.number(20)
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client') @connman.create_connection(user_id, client_id1, "1.1.1.1", 'client')
connection = @connman.join_music_session(user, client_id, music_session, true, TRACKS) music_session1 = MusicSession.find(create_music_session(user_id))
connection1 = @connman.join_music_session(user, client_id1, music_session1, true, TRACKS)
client_id = Faker::Number.number(20) connection1.errors.size.should == 0
@connman.create_connection(user_id, client_id, Faker::Internet.ip_v4_address, 'client')
music_session = MusicSession.find(create_music_session(user_id))
connection = @connman.join_music_session(user, client_id, music_session, true, TRACKS)
connection.errors.size.should == 1 music_session2 = MusicSession.find(create_music_session(user_id))
connection.errors.get(:music_session).should == [ValidationMessages::CANT_JOIN_MULTIPLE_SESSIONS] connection2 = @connman.join_music_session(user, client_id1, music_session2, true, TRACKS)
user.update_attribute(:admin, true) connection2.errors.size.should == 1
client_id = Faker::Number.number(20) connection2.errors.get(:music_session).should == [ValidationMessages::CANT_JOIN_MULTIPLE_SESSIONS]
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client')
music_session = MusicSession.find(create_music_session(user_id)) # client_id2 = Faker::Number.number(20)
connection = @connman.join_music_session(user, client_id, music_session, true, TRACKS) # @connman.create_connection(user_id, client_id2, "2.2.2.2", 'client')
client_id = Faker::Number.number(20) # music_session2 = MusicSession.find(create_music_session(user_id))
@connman.create_connection(user_id, client_id, Faker::Internet.ip_v4_address, 'client') # connection2 = @connman.join_music_session(user, client_id2, music_session2, true, TRACKS)
music_session = MusicSession.find(create_music_session(user_id)) #
connection = @connman.join_music_session(user, client_id, music_session, true, TRACKS) # connection2.errors.size.should == 1
connection.errors.size.should == 0 # connection2.errors.get(:music_session).should == [ValidationMessages::CANT_JOIN_MULTIPLE_SESSIONS]
#
# user.update_attribute(:admin, true)
# client_id = Faker::Number.number(20)
# @connman.create_connection(user_id, client_id, "1.1.1.1", 'client')
# music_session = MusicSession.find(create_music_session(user_id))
# connection = @connman.join_music_session(user, client_id, music_session, true, TRACKS)
# client_id = Faker::Number.number(20)
# @connman.create_connection(user_id, client_id, Faker::Internet.ip_v4_address, 'client')
# music_session = MusicSession.find(create_music_session(user_id))
# connection = @connman.join_music_session(user, client_id, music_session, true, TRACKS)
# connection.errors.size.should == 0
end end
end end

View File

@ -21,7 +21,7 @@ describe ClaimedRecording do
@music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true) @music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true)
# @music_session.connections << @connection # @music_session.connections << @connection
@music_session.save @music_session.save
@connection.join_the_session(@music_session, true) @connection.join_the_session(@music_session, true, nil)
@recording = Recording.start(@music_session, @user) @recording = Recording.start(@music_session, @user)
@recording.stop @recording.stop
@recording.reload @recording.reload

View File

@ -10,7 +10,7 @@ describe Mix do
@music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true) @music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true)
# @music_session.connections << @connection # @music_session.connections << @connection
@music_session.save @music_session.save
@connection.join_the_session(@music_session, true) @connection.join_the_session(@music_session, true, nil)
@recording = Recording.start(@music_session, @user) @recording = Recording.start(@music_session, @user)
@recording.stop @recording.stop
@recording.claim(@user, "name", "description", Genre.first, true) @recording.claim(@user, "name", "description", Genre.first, true)

View File

@ -398,7 +398,7 @@ describe MusicSession do
@music_session = FactoryGirl.create(:music_session, :creator => @user1, :musician_access => true) @music_session = FactoryGirl.create(:music_session, :creator => @user1, :musician_access => true)
# @music_session.connections << @connection # @music_session.connections << @connection
@music_session.save! @music_session.save!
@connection.join_the_session(@music_session, true) @connection.join_the_session(@music_session, true, nil)
end end
describe "not recording" do describe "not recording" do

View File

@ -115,7 +115,7 @@ describe 'Musician search' do
music_session = FactoryGirl.create(:music_session, :creator => usr, :musician_access => true) music_session = FactoryGirl.create(:music_session, :creator => usr, :musician_access => true)
# music_session.connections << connection # music_session.connections << connection
music_session.save music_session.save
connection.join_the_session(music_session, true) connection.join_the_session(music_session, true, nil)
recording = Recording.start(music_session, usr) recording = Recording.start(music_session, usr)
recording.stop recording.stop
recording.reload recording.reload
@ -130,7 +130,7 @@ describe 'Musician search' do
music_session = FactoryGirl.create(:music_session, :creator => usr, :musician_access => true) music_session = FactoryGirl.create(:music_session, :creator => usr, :musician_access => true)
# music_session.connections << connection # music_session.connections << connection
music_session.save music_session.save
connection.join_the_session(music_session, true) connection.join_the_session(music_session, true, nil)
end end
context 'musician stat counters' do context 'musician stat counters' do

View File

@ -80,7 +80,7 @@ describe Recording do
@track2 = FactoryGirl.create(:track, :connection => @connection2, :instrument => @instrument2) @track2 = FactoryGirl.create(:track, :connection => @connection2, :instrument => @instrument2)
# @music_session.connections << @connection2 # @music_session.connections << @connection2
@connection2.join_the_session(@music_session, true) @connection2.join_the_session(@music_session, true, nil)
@recording = Recording.start(@music_session, @user) @recording = Recording.start(@music_session, @user)
@user.recordings.length.should == 0 @user.recordings.length.should == 0
@ -179,7 +179,7 @@ describe Recording do
@track = FactoryGirl.create(:track, :connection => @connection2, :instrument => @instrument) @track = FactoryGirl.create(:track, :connection => @connection2, :instrument => @instrument)
# @music_session.connections << @connection2 # @music_session.connections << @connection2
@music_session.save @music_session.save
@connection2.join_the_session(@music_session, true) @connection2.join_the_session(@music_session, true, nil)
@recording = Recording.start(@music_session, @user) @recording = Recording.start(@music_session, @user)
@recording.stop @recording.stop
@recording.reload @recording.reload

View File

@ -4,7 +4,7 @@ describe Track do
let (:user) {FactoryGirl.create(:user) } let (:user) {FactoryGirl.create(:user) }
let (:music_session) { FactoryGirl.create(:music_session, :creator => user)} let (:music_session) { FactoryGirl.create(:music_session, :creator => user)}
let (:connection) { FactoryGirl.create(:connection, :music_session => music_session) } let (:connection) { FactoryGirl.create(:connection, :user => user, :music_session => music_session) }
let (:track) { FactoryGirl.create(:track, :connection => connection)} let (:track) { FactoryGirl.create(:track, :connection => connection)}
let (:track2) { FactoryGirl.create(:track, :connection => connection)} let (:track2) { FactoryGirl.create(:track, :connection => connection)}
let (:msuh) {FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => user, :client_id => connection.client_id) } let (:msuh) {FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => user, :client_id => connection.client_id) }

View File

@ -157,7 +157,7 @@ describe AudioMixer do
@music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true) @music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true)
# @music_session.connections << @connection # @music_session.connections << @connection
@music_session.save @music_session.save
@connection.join_the_session(@music_session, true) @connection.join_the_session(@music_session, true, nil)
@recording = Recording.start(@music_session, @user) @recording = Recording.start(@music_session, @user)
@recording.stop @recording.stop
@recording.claim(@user, "name", "description", Genre.first, true) @recording.claim(@user, "name", "description", Genre.first, true)

View File

@ -0,0 +1,346 @@
(function(context,$) {
"use strict";
context.JK = context.JK || {};
context.JK.ChatPanel = function(app) {
var logger = context.JK.logger;
var rest = context.JK.Rest();
var $panel = null;
var $contents = null;
var $count = null;
var $chatMessages = null;
var $chatMessagesScroller = null;
var $sendChatMessageBtn = null;
var $chatSender = null;
var $form = null;
var $textBox = null;
var $sessionId = null;
var $errorMsg = null;
var sendingMessage = false;
var showing = false;
var fullyInitialized = false;
var renderQueue = [];
var sidebar = null;
var user = null;
var currentPage = 0;
var LIMIT = 20;
var next = null;
function reset() {
fullyInitialized = false;
renderQueue = [];
sendingMessage = false;
$chatMessages.empty();
$textBox.val('');
}
function buildMessage() {
var message = {};
message['message'] = $textBox.val();
message['music_session'] = $sessionId;
message['client_id'] = context.JK.clientId;
return message;
}
function sendMessage() {
if(!context.JK.JamServer.connected) {
return false;
}
var msg = $textBox.val();
if(!msg || msg == '') {
// don't bother the server with empty messages
return false;
}
if(!sendingMessage) {
sendingMessage = true;
rest.createChatMessage(buildMessage())
.done(function() {
$textBox.val('');
renderMessage(msg, user.id, user.name, new Date().toISOString(), true);
})
.fail(function(jqXHR) {
app.notifyServerError(jqXHR, 'Unable to Send Chat Message');
})
.always(function() {
sendingMessage = false;
})
}
return false;
}
function scrollToBottom(instant) {
$chatMessagesScroller.animate({scrollTop: $chatMessagesScroller[0].scrollHeight}, instant ? 0 : 'slow');
}
function renderMessage(msg, senderId, senderName, sent, append) {
var options = {
msg: msg,
sender: senderId == user.id ? 'me' : senderName,
sent: sent
};
var txt = $(context._.template($('#template-chat-message').html(), options, { variable: 'data' }));
txt.find('.timeago').timeago();
if(append) {
$chatMessages.append(txt);
scrollToBottom();
}
else {
$chatMessages.prepend(txt);
}
}
function drainQueue() {
context._.each(renderQueue, function(msg) {
renderMessage(msg.message, msg.user_id, msg.user_name, msg.sent, true);
});
renderQueue = [];
}
// we handled the notification, meaning the dialog showed this message as a chat message
function handledNotification(payload) {
return showing && payload.description == "TEXT_MESSAGE";
}
function pasteIntoInput(el, text) {
el.focus();
if (typeof el.selectionStart == "number"
&& typeof el.selectionEnd == "number") {
var val = el.value;
var selStart = el.selectionStart;
el.value = val.slice(0, selStart) + text + val.slice(el.selectionEnd);
el.selectionEnd = el.selectionStart = selStart + text.length;
} else if (typeof document.selection != "undefined") {
var textRange = document.selection.createRange();
textRange.text = text;
textRange.collapse(false);
textRange.select();
}
}
function handleEnter(evt) {
if (evt.keyCode == 13 && evt.shiftKey) {
evt.preventDefault();
pasteIntoInput(this, "\n");
}
else if(evt.keyCode == 13 && !evt.shiftKey){
sendMessage();
return false;
}
}
function events(bind) {
if (bind) {
$form.submit(sendMessage);
$textBox.keydown(handleEnter);
$sendChatMessageBtn.click(sendMessage);
registerChatMessage(bind);
}
else {
$form.submit(null);
$textBox.keydown(null);
$sendChatMessageBtn.click(null);
}
}
// called from sidebar when messages come in
function chatMessageReceived(payload) {
if(fullyInitialized) {
if (isChatPanelVisible()) {
renderMessage(payload.msg, payload.sender_id, payload.sender_name, payload.created_at, true);
}
else {
highlightCount();
incrementChatCount();
renderQueue.push({message: payload.msg, user_id: payload.sender_id, user_name: payload.sender_name, sent: payload.created_at});
context.jamClient.UserAttention(true);
}
}
else {
renderQueue.push({message: payload.msg, user_id: payload.sender_id, user_name: payload.sender_name, sent: payload.created_at});
}
}
function registerChatMessage(bind) {
if (bind && bind == true) {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.CHAT_MESSAGE, function(header, payload) {
logger.debug("Handling CHAT_MESSAGE msg " + JSON.stringify(payload));
chatMessageReceived(payload);
handledNotification(payload);
});
}
else {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.CHAT_MESSAGE, null);
}
}
function opened() {
lowlightCount();
setCount(0);
drainQueue();
}
function sessionStarted(e, data) {
$sessionId = data.session.id;
// open chat panel
$chatSender.show();
$chatMessagesScroller.show();
$errorMsg.hide();
$panel.find('.panel-header').trigger('click');
$panel.on('open', opened);
$panel.find('.btn-next-pager').attr('href', '/api/sessions/' + $sessionId + '/chats?page=1');
reset();
// load previous chat messages
rest.getChatMessages(buildQuery())
.done(function (response) {
handleChatResponse(response);
scrollToBottom(true);
showing = true;
fullyInitialized = true;
drainQueue();
})
.fail(function (jqXHR) {
app.notifyServerError(jqXHR, 'Unable to Load Session Conversations')
});
events(true);
}
function sessionStopped(e, data) {
// open chat panel
$chatSender.hide();
$chatMessagesScroller.hide();
$errorMsg.show();
reset();
events(false);
}
function isChatPanelVisible() {
return $contents.is(':visible');
}
function incrementChatCount() {
var count = parseInt($count.text());
setCount(count + 1);
}
function setCount(count) {
$count.text(count);
}
function lowlightCount() {
$count.removeClass('highlighted');
}
function highlightCount() {
$count.addClass('highlighted');
}
function buildQuery() {
var query = {type: 'CHAT_MESSAGE', music_session: $sessionId, limit:LIMIT, page:currentPage};
if(next) {
query.start = next;
}
return query;
}
function renderChats(chats) {
context._.each(chats, function (chatMessage) {
renderMessage(chatMessage.message, chatMessage.user_id, chatMessage.user.name, chatMessage.created_at);
});
}
function handleChatResponse(response) {
next = response.next;
renderChats(response.chats);
if(response.next == null) {
// if we less results than asked for, end searching
$chatMessagesScroller.infinitescroll('pause');
logger.debug("end of chatss");
if(currentPage > 0) {
// there are bugs with infinitescroll not removing the 'loading'.
// it's most noticeable at the end of the list, so whack all such entries
$('.infinite-scroll-loader').remove();
}
}
else {
currentPage++;
buildQuery();
// registerInfiniteScroll();
}
}
function registerInfiniteScroll() {
$chatMessagesScroller.infinitescroll({
behavior: 'local',
navSelector: '.chat-sender .btn-next-pager',
nextSelector: '.chat-sender .btn-next-pager',
binder: $chatMessagesScroller,
dataType: 'json',
appendCallback: false,
prefill: false,
bufferPx: 100,
loading: {
msg: $('<div class="infinite-scroll-loader">Loading ...</div>'),
img: '/assets/shared/spinner-32.gif'
},
path: function(page) {
return '/api/sessions/' + $sessionId + '/chats?' + $.param(buildQuery());
}
},function(json, opts) {
handleChatResponse(json);
});
$chatMessagesScroller.infinitescroll('resume');
}
function initialize(sidebarInstance) {
sidebar = sidebarInstance;
$panel = $('[layout-id="panelChat"]');
$contents = $panel.find('.chatcontents');
$chatMessagesScroller = $panel.find('.chat-list-scroller');
$count = $panel.find('#sidebar-chat-count');
$chatMessages = $panel.find('.previous-chat-list');
$sendChatMessageBtn = $panel.find('.btn-send-chat-message');
$chatSender = $panel.find('.chat-sender');
$form = $panel.find('.chat-message-form');
$textBox = $form.find('textarea');
$errorMsg = $panel.find('.chat-status');
$errorMsg.show();
$chatSender.hide();
$chatMessagesScroller.hide();
app.user()
.done(function (userDetail) {
user = userDetail;
});
}
this.initialize = initialize;
this.sessionStarted = sessionStarted;
this.sessionStopped = sessionStopped;
this.registerChatMessage = registerChatMessage;
};
return this;
})(window,jQuery);

View File

@ -588,6 +588,10 @@
} }
function UserAttention(option) {
}
// passed an array of recording objects from the server // passed an array of recording objects from the server
function GetLocalRecordingState(recordings) { function GetLocalRecordingState(recordings) {
var result = { recordings:[]}; var result = { recordings:[]};
@ -754,6 +758,8 @@
this.OnLoggedIn = OnLoggedIn; this.OnLoggedIn = OnLoggedIn;
this.OnLoggedOut = OnLoggedOut; this.OnLoggedOut = OnLoggedOut;
this.UserAttention = UserAttention;
// Recording Playback // Recording Playback
this.GetLocalRecordingState = GetLocalRecordingState; this.GetLocalRecordingState = GetLocalRecordingState;
this.OpenRecording = OpenRecording; this.OpenRecording = OpenRecording;

View File

@ -944,19 +944,21 @@
}); });
} }
function createChatMessage(session_id, options) { function createChatMessage(options) {
return $.ajax({ return $.ajax({
type: "POST", type: "POST",
url: '/api/sessions/' + session_id + '/chat?' + $.param(options), url: '/api/chat?' + $.param(options),
dataType: "json", dataType: "json",
contentType: 'application/json' contentType: 'application/json'
}); });
} }
function getChatMessages(session_id, options) { function getChatMessages(options) {
var musciSessionId = options["music_session"];
delete options["music_session"];
return $.ajax({ return $.ajax({
type: "GET", type: "GET",
url: '/api/sessions/' + session_id + '/chats' + $.param(options), url: '/api/sessions/' + musciSessionId + '/chats?' + $.param(options),
dataType: "json", dataType: "json",
contentType: 'application/json' contentType: 'application/json'
}); });

View File

@ -95,9 +95,24 @@
notificationPanel.initialize(me, textMessageDialog); notificationPanel.initialize(me, textMessageDialog);
} }
// session events for chat
function registerSessionEvents() {
$(document).on('jamkazam.session_started', function(e, data){
chatPanel.sessionStarted(e, data);
return false;
});
$(document).on('jamkazam.session_stopped', function(e, data) {
chatPanel.sessionStopped(e, data);
return false;
});
}
function initializeChatPanel() { function initializeChatPanel() {
// chatPanel = new context.JK.ChatPanel(app); chatPanel = new context.JK.ChatPanel(app);
// chatPanel.initialize(me, textMessageDialog); chatPanel.initialize(me);
registerSessionEvents();
} }
function search(query) { function search(query) {

View File

@ -172,29 +172,66 @@
font-size: 100%; font-size: 100%;
} }
.chat-fixed { .chatcontents {
position:static; position: relative;
} }
.chat-select {
font-size:12px; .chat-list-scroller {
text-align:center; position: relative;
display: block;
overflow: auto;
margin: 0px 15px;
height: 210px;
}
.btn-send-chat-message {
margin-top: 5px;
margin-right: 30px;
}
#new-chat-message {
width: 90%;
height: 40px;
}
.chat-status {
line-height: 20px;
text-align: center;
padding: 10px;
}
.chat-message {
margin:5px 0;
.chat-message-sender {
font-weight:bold;
margin-right:10px;
color: #020C81;
&:after {
content:':'
}
}
.chat-message-text {
line-height:18px;
white-space:pre-line;
color: #D5E2E4;
}
.chat-message-timestamp {
margin-top:4px; margin-top:4px;
} color:#AAA;
display:block;
.chat-select select {
font-size:12px; font-size:12px;
color:$ColorSidebarText; }
background-color:shade($ColorElementPrimary, 20);
border:none;
} }
.chat-text { .chat-sender {
float:left; width: 100%;
width:180px; position: absolute;
font-size:11px; bottom: 10px;
margin-top:5px; padding: 0px 15px;
margin-bottom:5px;
color:#D5E2E4;
} }
em { em {

View File

@ -7,18 +7,21 @@ class ApiChatsController < ApiController
def create def create
@chat_msg = ChatMessage.new @chat_msg = ChatMessage.new
@chat_msg.user_id = current_user.id @chat_msg.user_id = current_user.id
@chat_msg.session_id = params[:music_session] @chat_msg.music_session_id = @music_session.id
@chat_msg.message = params[:msg] @chat_msg.message = params[:message]
if @chat_msg.save if @chat_msg.save
ChatMessage.send_chat_msg @music_session, @chat_msg, current_user ChatMessage.send_chat_msg @music_session, @chat_msg, current_user, params[:client_id]
end end
respond_with_model(@chat_msg) respond_with_model(@chat_msg)
end end
def index def index
@chat_msgs = ChatMessage.find_by_session_id(params[:music_session]) data = ChatMessage.index(current_user, params)
.paginate(page: params[:page], per_page: pararms[:per_page] || 20) @chats = data[0]
@next = data[1]
render "api_chats/index", :layout => nil
end end
def check_session def check_session

View File

@ -0,0 +1,7 @@
node :next do |page|
@next
end
node :chats do |page|
partial "api_chats/show", object: @chats
end

View File

@ -0,0 +1,11 @@
object @chat
attributes :message, :user_id, :session_id, :created_at
node :user do |c|
user_data = {}
if c.user_id
user_data[:name] = c.user.name
end
user_data
end

View File

@ -93,7 +93,6 @@
</div> </div>
<!-- Chat --> <!-- Chat -->
<!--
<div layout="panel" layout-id="panelChat"> <div layout="panel" layout-id="panelChat">
<div layout-panel="collapsed"> <div layout-panel="collapsed">
</div> </div>
@ -101,24 +100,26 @@
<div layout-panel="header" class="panel-header"> <div layout-panel="header" class="panel-header">
<h2>chat<div id="sidebar-chat-count" class="badge">0</div></h2> <h2>chat<div id="sidebar-chat-count" class="badge">0</div></h2>
</div> </div>
<div layout-panel="contents" class="panelcontents"> <div layout-panel="contents" class="chatcontents">
<div class="chat-fixed"> <div class="chat-status">
<input id="chat-input" type="text" placeholder="enter message" /><br /> <span>Chat is available during session is connected.</span>
</div>
<div class="chat-select">Send to: <div class="chat-list-scroller">
<select id="sidebar-chat-friend-list"> <div class="previous-chat-list">
<option>Everyone</option> </div>
<option>All Musicians</option> </div>
<option>All Fans</option> <div class="chat-sender">
</select> <form class="chat-message-form">
<textarea name="chat-message" id="new-chat-message" placeholder="enter message"></textarea>
</form>
<div class="right">
<%= link_to 'NEXT', '#', class: 'btn-next-pager' %>
<%= link_to 'SEND', '#', class: 'button-orange btn-send-chat-message' %>
</div> </div>
</div> </div>
<ul id="sidebar-chat-list">
</ul>
</div> </div>
</div> </div>
</div> </div>
-->
<!-- Notifications --> <!-- Notifications -->
<div layout="panel" layout-id="panelNotifications"> <div layout="panel" layout-id="panelNotifications">
@ -220,20 +221,17 @@
<div id="div-actions"> <div id="div-actions">
<a id="btn-notification-action" class="button-orange smallbutton right"></a> <a id="btn-notification-action" class="button-orange smallbutton right"></a>
</div> </div>
<br/ > <br/>
<br clear="all" /> <br clear="all" />
</li> </li>
</script> </script>
<!-- Chat panel template --> <!-- Chat panel template -->
<script type="text/template" id="template-chat-panel"> <script type="text/template" id="template-chat-message">
<li> <div class="chat-message">
<div class="avatar-small"><img src="{avatar_url}" /></div> <span class="chat-message-sender">{{data.sender}}</span>
<div class="chat-text"> <span class="chat-message-text">{{data.msg}}</span>
<strong>{label}:</strong>&nbsp;{text} <time class="chat-message-timestamp timeago" datetime="{{data.sent}}">{{data.sent}}</time>
<em>({date})</em> </div>
</div>
<br clear="all" />
</li>
</script> </script>

View File

@ -260,8 +260,8 @@ SampleApp::Application.routes.draw do
match '/users/:id/share/recording/:provider' => 'api_users#share_recording', :via => :get match '/users/:id/share/recording/:provider' => 'api_users#share_recording', :via => :get
# session chat # session chat
match '/sessions/:id/chat' => 'api_chats#create', :via => :post match '/chat' => 'api_chats#create', :via => :post
match '/sessions/:id/chats' => 'api_chats#index', :via => :get match '/sessions/:music_session/chats' => 'api_chats#index', :via => :get
# user recordings # user recordings
# match '/users/:id/recordings' => 'api_users#recording_index', :via => :get # match '/users/:id/recordings' => 'api_users#recording_index', :via => :get

View File

@ -11,7 +11,7 @@ describe ApiClaimedRecordingsController do
@music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true) @music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true)
# @music_session.connections << @connection # @music_session.connections << @connection
@music_session.save @music_session.save
@connection.join_the_session(@music_session, true) @connection.join_the_session(@music_session, true, nil)
@recording = Recording.start(@music_session, @user) @recording = Recording.start(@music_session, @user)
@recording.stop @recording.stop
@recording.reload @recording.reload

View File

@ -89,11 +89,6 @@ FactoryGirl.define do
as_musician true as_musician true
addr 0 addr 0
locidispid 0 locidispid 0
latitude 0.0
longitude 0.0
countrycode 'US'
region 'TX'
city 'Austin'
client_type 'client' client_type 'client'
end end

View File

@ -0,0 +1,103 @@
require 'spec_helper'
describe "Chat Message", :js => true, :type => :feature, :capybara_feature => true do
before(:all) do
Capybara.default_wait_time = 15
end
let(:user1) { FactoryGirl.create(:user) }
let(:user2) { FactoryGirl.create(:user) }
before(:each) do
UserMailer.deliveries.clear
MusicSession.delete_all
ChatMessage.delete_all
end
# what are all the ways to be in a session?
describe "join session" do
it "on try to send chat before joining session" do
description = "Try to send chat message before joining session!"
create_session(creator: user1, description: description)
in_client(user2) do
sign_in_poltergeist(user1)
find("[layout-id=\"panelChat\"] .panel-header").trigger(:click)
find(".chat-status", text: 'Chat is available during session is connected.')
end
end
it "on join a session" do
description = "Find chat panel expanded when join session"
create_session(creator: user1, description: description)
join_session(user2, description: description)
find(".chatcontents").should be_visible
find("[layout-id=\"panelChat\"] .chat-sender").should be_visible
end
end
describe "sidebar session chat behavior" do
it "send a message" do
description = "Find chat panel expanded when join session"
create_session(creator: user1, description: description)
join_session(user2, description: description)
in_client(user1) do
send_chat_message("Hey, I am #{user1.id}")
find('.chat-message-text', text: "Hey, I am #{user1.id}")
end
in_client(user2) do
find('.chat-message-text', text: "Hey, I am #{user1.id}")
send_chat_message("Received, I am #{user2.id}")
end
in_client(user1) do
find('.chat-message-text', text: "Received, I am #{user2.id}")
end
end
it "shows error with a notify" do
description = "Find chat panel expanded when join session"
create_session(creator: user1, description: description)
join_session(user2, description: description)
in_client(user2) do
chat_max = 256
chat_msg = 'a' * (chat_max + 1)
send_chat_message(chat_msg)
find('#notification').should have_text("Unable to Send Chat Message")
end
end
it "shows badge if not on chat panel" do
description = "Find chat panel expanded when join session"
create_session(creator: user1, description: description)
join_session(user2, description: description)
in_client(user1) do
find("[layout-id=\"panelFriends\"] .panel-header").trigger(:click)
end
in_client(user2) do
send_chat_message("Detect badge information")
end
in_client(user1) do
find('#sidebar-chat-count.badge.highlighted', text: "1")
find("[layout-id=\"panelChat\"] .panel-header").trigger(:click)
find('.chat-message-text', text: "Detect badge information")
end
end
end
end

View File

@ -65,7 +65,7 @@ describe "social metadata" do
ms = FactoryGirl.create(:music_session, :creator => user, :musician_access => true) ms = FactoryGirl.create(:music_session, :creator => user, :musician_access => true)
# ms.connections << connection # ms.connections << connection
ms.save! ms.save!
connection.join_the_session(ms, true) connection.join_the_session(ms, true, nil)
ms ms
} }
@ -93,7 +93,7 @@ describe "social metadata" do
@music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true) @music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true)
# @music_session.connections << @connection # @music_session.connections << @connection
@music_session.save @music_session.save
@connection.join_the_session(@music_session, true) @connection.join_the_session(@music_session, true, nil)
@recording = Recording.start(@music_session, @user) @recording = Recording.start(@music_session, @user)
@recording.stop @recording.stop
@recording.reload @recording.reload

View File

@ -10,7 +10,7 @@ describe MusicSessionHelper do
@music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true) @music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true)
# @music_session.connections << @connection # @music_session.connections << @connection
@music_session.save @music_session.save
@connection.join_the_session(@music_session, true) @connection.join_the_session(@music_session, true, nil)
@recording = Recording.start(@music_session, @user) @recording = Recording.start(@music_session, @user)
@recording.stop @recording.stop
@recording.reload @recording.reload

View File

@ -700,7 +700,7 @@ describe "Music Session API ", :type => :api do
music_session = FactoryGirl.create(:music_session, :creator => user, :musician_access => true) music_session = FactoryGirl.create(:music_session, :creator => user, :musician_access => true)
# music_session.connections << connection # music_session.connections << connection
music_session.save music_session.save
connection.join_the_session(music_session, true) connection.join_the_session(music_session, true, nil)
recording = Recording.start(music_session, user) recording = Recording.start(music_session, user)
recording.stop recording.stop
recording.reload recording.reload

View File

@ -985,7 +985,7 @@ describe "User API", :type => :api do
ms = FactoryGirl.create(:music_session, :creator => user, :musician_access => true) ms = FactoryGirl.create(:music_session, :creator => user, :musician_access => true)
# ms.connections << connection # ms.connections << connection
ms.save! ms.save!
connection.join_the_session(ms, true) connection.join_the_session(ms, true, nil)
ms } ms }
it "fetches facebook successfully" do it "fetches facebook successfully" do
@ -1122,7 +1122,7 @@ describe "User API", :type => :api do
@music_session = FactoryGirl.create(:music_session, :creator => user, :musician_access => true) @music_session = FactoryGirl.create(:music_session, :creator => user, :musician_access => true)
# @music_session.connections << @connection # @music_session.connections << @connection
@music_session.save @music_session.save
@connection.join_the_session(@music_session, true) @connection.join_the_session(@music_session, true, nil)
@recording = Recording.start(@music_session, user) @recording = Recording.start(@music_session, user)
@recording.stop @recording.stop
@recording.reload @recording.reload

View File

@ -71,6 +71,16 @@ def send_text_message(msg, options={})
end end
end end
# sends a chat message during session
def send_chat_message(msg)
find("[layout-id=\"panelChat\"] .chat-sender").should be_visible
within("[layout-id=\"panelChat\"] .chat-sender form.chat-message-form") do
fill_in 'new-chat-message', with: msg
end
find("[layout-id=\"panelChat\"] .chat-sender .btn-send-chat-message").trigger(:click)
end
def open_notifications def open_notifications
find("#{NOTIFICATION_PANEL} .panel-header").trigger(:click) find("#{NOTIFICATION_PANEL} .panel-header").trigger(:click)
end end

View File

@ -35,11 +35,6 @@ FactoryGirl.define do
factory :connection, :class => JamRuby::Connection do factory :connection, :class => JamRuby::Connection do
addr 0 addr 0
locidispid 0 locidispid 0
latitude 0.0
longitude 0.0
countrycode 'US'
region 'TX'
city 'Austin'
ip_address '1.1.1.1' ip_address '1.1.1.1'
as_musician true as_musician true
client_type 'client' client_type 'client'