* all tests pass; but need to now rename music session tables to match class names...

This commit is contained in:
Seth Call 2014-05-06 16:17:26 -05:00
parent f3d39a351d
commit 732fd66f0e
49 changed files with 464 additions and 392 deletions

View File

@ -3,33 +3,45 @@ ALTER TABLE users ADD COLUMN audio_latency double precision;
ALTER TABLE music_sessions_history ADD COLUMN scheduled_start TIMESTAMP WITH TIME ZONE;
ALTER TABLE music_sessions_history ADD COLUMN scheduled_duration INTERVAL;
ALTER TABLE music_sessions_history ADD COLUMN musician_access BOOLEAN NOT NULL;
ALTER TABLE music_sessions_history ADD COLUMN approval_required BOOLEAN NOT NULL;
ALTER TABLE music_sessions_history ADD COLUMN fan_chat BOOLEAN NOT NULL;
ALTER TABLE music_sessions_history ADD COLUMN genre_id VARCHAR(64) NOT NULL REFERENCES genres(id);
ALTER TABLE music_sessions_history ADD COLUMN legal_policy VARCHAR(255) NOT NULL;
ALTER TABLE music_sessions_history ADD COLUMN language VARCHAR(255) NOT NULL;
ALTER TABLE music_sessions_history ADD COLUMN name TEXT NOT NULL;
ALTER TABLE music_sessions_history ADD COLUMN musician_access BOOLEAN NOT NULL DEFAULT TRUE;
ALTER TABLE music_sessions_history ADD COLUMN approval_required BOOLEAN NOT NULL DEFAULT FALSE;
ALTER TABLE music_sessions_history ADD COLUMN fan_chat BOOLEAN NOT NULL DEFAULT TRUE;
ALTER TABLE music_sessions_history ADD COLUMN genre_id VARCHAR(64) REFERENCES genres(id);
ALTER TABLE music_sessions_history ADD COLUMN legal_policy VARCHAR(255) NOT NULL DEFAULT 'standard';
ALTER TABLE music_sessions_history ADD COLUMN language VARCHAR(255) NOT NULL DEFAULT 'en';
ALTER TABLE music_sessions_history ADD COLUMN name TEXT;
UPDATE music_sessions_history SET name = description;
ALTER TABLE music_sessions_history ALTER COLUMN name SET NOT NULL;
-- production db has some null genres on older sessions
UPDATE music_sessions_history SET genres = 'rock' where genres = '';
UPDATE music_sessions_history SET genre_id = genres;
ALTER TABLE music_sessions_history ALTER COLUMN genre_id SET NOT NULL;
ALTER TABLE music_sessions_history DROP COLUMN genres;
ALTER TABLE music_sessions_likers ADD COLUMN music_session_id2 VARCHAR(64) REFERENCES music_sessions_history(id) ON DELETE CASCADE;
UPDATE music_sessions_likers SET music_session_id2 = music_session_id;
-- production db has some bad data
DELETE from music_sessions_likers where music_session_id NOT IN (select id from music_sessions_history);
UPDATE music_sessions_likers SET music_session_id2 = music_session_id;
ALTER TABLE music_sessions_likers DROP COLUMN music_session_id;
ALTER TABLE music_sessions_likers RENAME COLUMN music_session_id2 to music_session_id;
ALTER TABLE music_sessions_comments ADD COLUMN music_session_id2 VARCHAR(64) REFERENCES music_sessions_history(id) ON DELETE CASCADE;
UPDATE music_sessions_comments SET music_session_id2 = music_session_id;
-- production db has some bad data
DELETE from music_sessions_comments where music_session_id NOT IN (select id from music_sessions_history);
UPDATE music_sessions_comments SET music_session_id2 = music_session_id;
ALTER TABLE music_sessions_comments DROP COLUMN music_session_id;
ALTER TABLE music_sessions_comments RENAME COLUMN music_session_id2 to music_session_id;
ALTER TABLE music_sessions_user_history ADD COLUMN music_session_id2 VARCHAR(64) REFERENCES music_sessions_history(id) ON DELETE CASCADE;
UPDATE music_sessions_user_history SET music_session_id2 = music_session_id;
-- production db has some bad data
DELETE from music_sessions_user_history where music_session_id NOT IN (select id from music_sessions_history);
UPDATE music_sessions_user_history SET music_session_id2 = music_session_id;
ALTER TABLE music_sessions_user_history DROP COLUMN music_session_id;
ALTER TABLE music_sessions_user_history RENAME COLUMN music_session_id2 to music_session_id;
ALTER TABLE music_sessions_history DROP COLUMN music_session_id;
ALTER TABLE music_sessions DROP COLUMN musician_access;
ALTER TABLE music_sessions DROP COLUMN fan_access;
ALTER TABLE music_sessions DROP COLUMN description;
@ -37,6 +49,8 @@ ALTER TABLE music_sessions DROP COLUMN fan_chat;
ALTER TABLE music_sessions DROP COLUMN approval_required;
ALTER TABLE music_sessions DROP COLUMN band_id;
ALTER TABLE music_sessions_history ALTER COLUMN music_session_id DROP NOT NULL;
CREATE TABLE rsvp_slots (
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4() NOT NULL,
instrument_id VARCHAR(64) REFERENCES instruments (id),

View File

@ -39,7 +39,7 @@ module JamRuby
# this simulates music_session destroy callbacks with activerecord
def before_destroy_music_session(music_session_id)
music_session = MusicSession.find_by_id(music_session_id)
music_session = ActiveMusicSession.find_by_id(music_session_id)
music_session.before_destroy if music_session
end

View File

@ -33,7 +33,7 @@ end
class NoProfanityValidator < ActiveModel::EachValidator
# implement the method called during validation
def validate_each(record, attribute, value)
record.errors[attribute] << 'cannot contain profanity' if Profanity.is_profane?(value)
record.errors[attribute] << 'cannot contain profanity' if JamRuby::Profanity.is_profane?(value)
end
end

View File

@ -2,21 +2,24 @@ module JamRuby
class ActiveMusicSession < ActiveRecord::Base
self.primary_key = 'id'
self.table_name = 'music_sessions'
attr_accessor :legal_terms, :max_score
belongs_to :claimed_recording, :class_name => "JamRuby::ClaimedRecording", :foreign_key => "claimed_recording_id", :inverse_of => :playing_sessions
belongs_to :claimed_recording_initiator, :class_name => "JamRuby::User", :inverse_of => :playing_claimed_recordings, :foreign_key => "claimed_recording_initiator_id"
has_one :music_session, :class_name => "JamRuby::MusicSession", :foreign_key => 'id'
has_one :music_session, :class_name => "JamRuby::MusicSession", :foreign_key => 'music_session_id'
has_one :mount, :class_name => "JamRuby::IcecastMount", :inverse_of => :music_session, :foreign_key => 'music_session_id'
belongs_to :creator, :class_name => 'JamRuby::User', :foreign_key => :user_id
has_many :connections, :class_name => "JamRuby::Connection"
has_many :connections, :class_name => "JamRuby::Connection", foreign_key: :music_session_id
has_many :users, :through => :connections, :class_name => "JamRuby::User"
has_many :recordings, :class_name => "JamRuby::Recording", :inverse_of => :music_session
has_many :recordings, :class_name => "JamRuby::Recording", :inverse_of => :music_session, foreign_key: :music_session_id
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"
validates :creator, :presence => true
validate :creator_is_musician
validate :no_new_playback_while_playing
after_create :started_session
@ -24,10 +27,6 @@ module JamRuby
JamRuby::MusicSession.removed_music_session(obj.id)
end
validate :creator_is_musician
validate :no_new_playback_while_playing
#default_scope :select => "*, 0 as score"
def attributes
@ -88,7 +87,15 @@ module JamRuby
my_bands_only = options[:my_bands_only].nil? ? false : options[:my_bands_only]
as_musician = options[:as_musician].nil? ? true : options[:as_musician]
query = MusicSession
query = ActiveMusicSession
.joins(
%Q{
INNER JOIN
music_sessions_history
ON
music_sessions.id = music_sessions_history.id
}
)
.joins(
%Q{
INNER JOIN
@ -146,9 +153,9 @@ module JamRuby
query = query.where("(music_sessions.created_at < icecast_servers.config_updated_at)")
end
query = query.where("music_sessions.description like '%#{keyword}%'") unless keyword.nil?
query = query.where("music_sessions_history.description like '%#{keyword}%'") unless keyword.nil?
query = query.where("connections.user_id" => participants.split(',')) unless participants.nil?
query = query.joins(:genres).where("genres.id" => genres.split(',')) unless genres.nil?
query = query.where("music_sessions_history.genre_id in (?)", genres) unless genres.nil?
if my_bands_only
query = query.joins(
@ -192,7 +199,7 @@ module JamRuby
connection = Connection.where(client_id: client_id).first!
locidispid = connection.locidispid
query = MusicSession
query = ActiveMusicSession
.select("music_sessions.*, max(coalesce(current_scores.score, 1000)) as max_score") # 1000 is higher than the allowed max of 999
.joins(
%Q{
@ -387,6 +394,10 @@ module JamRuby
self.save
end
def invitations
music_session.invitations
end
def invited_musicians
music_session.invited_musicians
end
@ -423,12 +434,12 @@ module JamRuby
music_session.fan_chat
end
def approval_required
music_session.approval_required
def band
music_session.band
end
def creator
music_session.creator
def approval_required
music_session.approval_required
end
def tick_track_changes
@ -444,6 +455,12 @@ module JamRuby
end
def started_session
raise "active_music_sessions.id must be set by caller" unless self.id
# associate this active_music_session with the music_session formally
session = MusicSession.find(self.id)
session.active_music_session = self
session.save!
GoogleAnalyticsEvent.track_session_duration(self)
GoogleAnalyticsEvent.track_band_real_session(self)
end

View File

@ -44,8 +44,7 @@ module JamRuby
has_many :invitations, :inverse_of => :band, :class_name => "JamRuby::BandInvitation", :foreign_key => "band_id"
# music_sessions
has_many :music_sessions, :class_name => "JamRuby::ActiveMusicSession", :foreign_key => "band_id"
has_many :music_session, :class_name => "JamRuby::MusicSession", :foreign_key => "band_id", :inverse_of => :band
has_many :music_sessions, :class_name => "JamRuby::MusicSession", foreign_key: :band_id, :inverse_of => :band
# events
has_many :event_sessions, :class_name => "JamRuby::EventSession"
@ -54,19 +53,19 @@ module JamRuby
acts_as_mappable
def liker_count
return self.likers.size
self.likers.size
end
def follower_count
return self.followers.size
self.followers.size
end
def recording_count
return self.recordings.size
self.recordings.size
end
def session_count
return self.music_sessions.size
self.music_sessions.size
end
def recent_history

View File

@ -11,6 +11,7 @@ module JamRuby
belongs_to :user
belongs_to :music_session
validates :user, presence: true
validates :message, length: {minimum: 1, maximum: 255}, no_profanity: true
class << self

View File

@ -9,7 +9,7 @@ module JamRuby
self.primary_key = 'id'
belongs_to :user, :class_name => "JamRuby::User"
belongs_to :music_session, :class_name => "JamRuby::ActiveMusicSession"
belongs_to :music_session, :class_name => "JamRuby::ActiveMusicSession", foreign_key: :music_session_id
has_many :tracks, :class_name => "JamRuby::Track", :inverse_of => :connection, :foreign_key => 'connection_id', :dependent => :delete_all

View File

@ -7,6 +7,10 @@ module JamRuby
has_many :band_genres, class_name: "JamRuby::BandGenre"
has_many :bands, class_name: "JamRuby::Band", :through => :band_genres
# music sessions
has_many :music_sessions, :class_name => "JamRuby::MusicSession"
# genres
has_and_belongs_to_many :recordings, :class_name => "JamRuby::Recording", :join_table => "recordings_genres"

View File

@ -76,7 +76,7 @@ module JamRuby
end
# creates a templated
def self.build_session_mount(music_session, icecast_server)
def self.build_session_mount(music_session, active_music_session, icecast_server)
# only public sessions get mounts currently
return nil unless music_session.fan_access
@ -84,7 +84,7 @@ module JamRuby
mount = nil
if icecast_server && icecast_server.mount_template_id
# we have a server with an associated mount_template; we can create a mount automatically
mount = icecast_server.mount_template.build_session_mount(music_session)
mount = icecast_server.mount_template.build_session_mount(music_session, active_music_session)
mount.server = icecast_server
end
mount

View File

@ -44,7 +44,7 @@ module JamRuby
end
# pick a server that's in the same group as the user that is under the least load
def build_session_mount(music_session)
def build_session_mount(music_session, active_music_session)
mount = IcecastMount.new
mount.authentication = authentication
mount.mount_template = self
@ -55,7 +55,7 @@ module JamRuby
mount.stream_name = "JamKazam music session created by #{music_session.creator.name}"
mount.stream_description = music_session.description
mount.stream_url = "http://www.jamkazam.com" ## TODO/XXX, the jamkazam url should be the page hosting the widget
mount.genre = music_session.genres.map {|genre| genre.description}.join(',')
mount.genre = music_session.genre.description
mount
end
end

View File

@ -7,20 +7,11 @@ module JamRuby
self.primary_key = 'id'
belongs_to(:creator,
:class_name => 'JamRuby::User',
:foreign_key => :user_id,
:inverse_of => :music_session_histories)
belongs_to :creator,:class_name => 'JamRuby::User', :foreign_key => :user_id, :inverse_of => :music_session_histories
belongs_to(:band,
:class_name => 'JamRuby::Band',
:foreign_key => :band_id,
:foreign_key => :band_id,
:inverse_of => :music_session)
belongs_to :band, :class_name => 'JamRuby::Band', :foreign_key => :band_id, :inverse_of => :music_sessions
belongs_to(:active_music_session,
:class_name => 'JamRuby::ActiveMusicSession',
:foreign_key => 'id')
belongs_to :active_music_session, :class_name => 'JamRuby::ActiveMusicSession', foreign_key: :music_session_id
has_many :music_session_user_histories, :class_name => "JamRuby::MusicSessionUserHistory", :foreign_key => "music_session_id", :dependent => :delete_all
has_many :comments, :class_name => "JamRuby::MusicSessionComment", :foreign_key => "music_session_id"
@ -28,13 +19,14 @@ module JamRuby
has_many :plays, :class_name => "JamRuby::PlayablePlay", :as => :playable, :dependent => :destroy
has_one :share_token, :class_name => "JamRuby::ShareToken", :inverse_of => :shareable, :foreign_key => 'shareable_id'
has_one :feed, :class_name => "JamRuby::Feed", :inverse_of => :music_session, :foreign_key => 'music_session_id', :dependent => :destroy
belongs_to :genre, :class_name => "JamRuby::Genre", :inverse_of => :music_sessions, :foreign_key => 'genre_id'
has_many :join_requests, :foreign_key => "music_session_id", :inverse_of => :music_session, :class_name => "JamRuby::JoinRequest", :foreign_key => "music_session_id"
has_many :invitations, :foreign_key => "music_session_id", :inverse_of => :music_session, :class_name => "JamRuby::Invitation", :foreign_key => "music_session_id"
has_many :invited_musicians, :through => :invitations, :class_name => "JamRuby::User", :foreign_key => "receiver_id", :source => :receiver
has_many :fan_invitations, :foreign_key => "music_session_id", :inverse_of => :music_session, :class_name => "JamRuby::FanInvitation", :foreign_key => "music_session_id"
has_many :invited_fans, :through => :fan_invitations, :class_name => "JamRuby::User", :foreign_key => "receiver_id", :source => :receiver
validates :genre, :presence => true
validates :description, :presence => true, :no_profanity => true
validates :fan_chat, :inclusion => {:in => [true, false]}
validates :fan_access, :inclusion => {:in => [true, false]}
@ -43,9 +35,7 @@ module JamRuby
validates :legal_terms, :inclusion => {:in => [true]}, :on => :create
validates :creator, :presence => true
validate :creator_is_musician
validate :require_at_least_one_genre, :limit_max_genres
before_save :sync_music_session
before_create :generate_share_token
before_create :add_to_feed
@ -115,7 +105,7 @@ module JamRuby
.joins(:music_session_user_histories)
.group("users.id")
.order("users.id")
.where(%Q{ music_sessions_user_history.music_session_id = '#{music_session_id}'})
.where(%Q{ music_sessions_user_history.music_session_id = '#{id}'})
end
# returns one user history per user, with instruments all crammed together, and with total duration
@ -127,7 +117,7 @@ module JamRuby
music_sessions_user_history.user_id, music_sessions_user_history.music_session_id, users.first_name, users.last_name, users.photo_url")
.group("music_sessions_user_history.user_id, music_sessions_user_history.music_session_id, users.first_name, users.last_name, users.photo_url")
.order("music_sessions_user_history.user_id")
.where(%Q{ music_sessions_user_history.music_session_id = '#{music_session_id}'})
.where(%Q{ music_sessions_user_history.music_session_id = '#{id}'})
end
def duration_minutes
@ -137,13 +127,13 @@ module JamRuby
def music_session_user_histories
@msuh ||= JamRuby::MusicSessionUserHistory
.where(:music_session_id => self.music_session_id)
.where(:music_session_id => self.id)
.order('created_at DESC')
end
def comments
@comments ||= JamRuby::MusicSessionComment
.where(:music_session_id => self.music_session_id)
.where(:music_session_id => self.id)
.order('created_at DESC')
end
@ -156,15 +146,15 @@ module JamRuby
# which means are currently in the music_session, or, rsvp'ed, or creator
def part_of_session? user
# XXX check RSVP'ed
user == self.creator || (music_session ? music_session.users.exists? : false)
user == self.creator || (active_music_session ? active_music_session.users.exists?(user) : false)
end
def is_over?
music_session.nil? || !session_removed_at.nil?
active_music_session.nil?
end
def has_mount?
music_session && music_session.mount
active_music_session && active_music_session.mount
end
def recordings
@ -189,7 +179,7 @@ module JamRuby
def self.removed_music_session(session_id)
hist = self
.where(:music_session_id => session_id)
.where(:id => session_id)
.limit(1)
.first
@ -204,26 +194,6 @@ module JamRuby
private
def sync_music_session
MusicSession.save(self)
end
def require_at_least_one_genre
unless skip_genre_validation
if self.genres.length < Limits::MIN_GENRES_PER_SESSION
errors.add(:genres, ValidationMessages::SESSION_GENRE_MINIMUM_NOT_MET)
end
end
end
def limit_max_genres
unless skip_genre_validation
if self.genres.length > Limits::MAX_GENRES_PER_SESSION
errors.add(:genres, ValidationMessages::SESSION_GENRE_LIMIT_EXCEEDED)
end
end
end
def generate_share_token
token = loop do
@ -238,5 +208,11 @@ module JamRuby
self.share_token.shareable_type = "session"
end
def creator_is_musician
unless creator && creator.musician?
errors.add(:creator, ValidationMessages::MUST_BE_A_MUSICIAN)
end
end
end
end

View File

@ -16,7 +16,7 @@ module JamRuby
belongs_to :owner, :class_name => "JamRuby::User", :inverse_of => :owned_recordings, :foreign_key => 'owner_id'
belongs_to :band, :class_name => "JamRuby::Band", :inverse_of => :recordings
belongs_to :music_session, :class_name => "JamRuby::ActiveMusicSession", :inverse_of => :recordings
belongs_to :music_session, :class_name => "JamRuby::ActiveMusicSession", :inverse_of => :recordings, foreign_key: :music_session_id
accepts_nested_attributes_for :recorded_tracks, :mixes, :claimed_recordings, allow_destroy: true

View File

@ -300,8 +300,8 @@ module JamRuby
sel_str = 'bands.*'
case ordering = self.order_param(params)
when :plays # FIXME: double counting?
sel_str = "COUNT(records)+COUNT(sessions) AS play_count, #{sel_str}"
rel = rel.joins("LEFT JOIN music_sessions AS sessions ON sessions.band_id = bands.id")
sel_str = "COUNT(records)+COUNT(msh) AS play_count, #{sel_str}"
rel = rel.joins("LEFT JOIN music_sessions_history AS msh ON msh.band_id = bands.id")
.joins("LEFT JOIN recordings AS records ON records.band_id = bands.id")
.group("bands.id")
.order("play_count DESC, bands.created_at DESC")

View File

@ -688,15 +688,7 @@ module JamRuby
unless user.nil?
# only save genre id and description
genres = []
unless music_session.genres.nil?
music_session.genres.each do |genre|
g = Hash.new
g["id"] = genre.id
g["description"] = genre.description
genres << g
end
end
genres = [{id: music_session.genre.id, description: music_session.genre.description}]
# only save invitation receiver id and name
invitees = []
@ -709,7 +701,7 @@ module JamRuby
end
end
session_settings = { :band_id => music_session.band_id,
session_settings = { :band_id => music_session.band_id,
:musician_access => music_session.musician_access,
:approval_required => music_session.approval_required,
:fan_chat => music_session.fan_chat,

View File

@ -47,7 +47,7 @@ module JamRuby
@queue = QUEUE_BAND_TRACKER
def self.perform(session_id)
return unless session = MusicSession.find(session_id)
return unless session = ActiveMusicSession.find(session_id)
band = session.band
if band.in_real_session?(session)
band.update_attribute(:did_real_session, true)

View File

@ -31,13 +31,23 @@ FactoryGirl.define do
factory :single_user_session do
after(:create) do |user, evaluator|
music_session = FactoryGirl.create(:active_music_session, :creator => user)
connection = FactoryGirl.create(:connection, :user => user, :music_session => music_session)
active_music_session = FactoryGirl.create(:active_music_session, :creator => user)
connection = FactoryGirl.create(:connection, :user => user, :music_session => active_music_session)
end
end
end
factory :music_session_no_history, :class => JamRuby::ActiveMusicSession do
factory :musician_instrument, :class => JamRuby::MusicianInstrument do
instrument { JamRuby::Instrument.find('electric guitar') }
proficiency_level 1
priority 0
end
factory :active_music_session_no_user_history, :class => JamRuby::ActiveMusicSession do
association :creator, factory: :user
ignore do
name "My Music Session"
description "Come Music Session"
@ -46,14 +56,15 @@ FactoryGirl.define do
approval_required false
musician_access true
legal_terms true
genres [JamRuby::Genre.first]
creator FactoryGirl.create(:user)
genre JamRuby::Genre.first
band nil
end
before(:create) do |session, evaluator|
music_session = FactoryGirl.create(:music_session_history, name: evaluator.name, description: evaluator.description, fan_chat: evaluator.fan_chat,
fan_access: evaluator.fan_access, approval_required: evaluator.approval_required, musician_access: evaluator.musician_access,
genre: evaluator.genres.first, creator: evaluator.creator)
fan_access: evaluator.fan_access, approval_required: evaluator.approval_required, musician_access: evaluator.musician_access,
genre: evaluator.genre, creator: evaluator.creator, band: evaluator.band)
session.id = music_session.id
end
@ -68,17 +79,18 @@ FactoryGirl.define do
end
end
# this creates a music_session, and an active_music_session, in one go
factory :music_session_history, :class => JamRuby::MusicSession do
ignore do
music_session nil
end
sequence(:name) { |n| "Music Session #{n}" }
sequence(:description) { |n| "Music Session Description #{n}" }
fan_chat true
fan_access true
music_session_id { music_session.id }
description { music_session.description }
user_id { music_session.user_id }
band_id { music_session.band_id }
approval_required false
musician_access true
legal_terms true
language 'english'
legal_policy 'standard'
genre JamRuby::Genre.first
association :creator, :factory => :user
end
factory :music_session_user_history, :class => JamRuby::MusicSessionUserHistory do
@ -162,7 +174,7 @@ FactoryGirl.define do
factory :recording, :class => JamRuby::Recording do
association :owner, factory: :user
association :music_session, factory: :music_session
association :music_session, factory: :active_music_session
association :band, factory: :band
factory :recording_with_track do
@ -204,12 +216,6 @@ FactoryGirl.define do
}
end
factory :musician_instrument, :class => JamRuby::MusicianInstrument do
instrument { Instrument.find('electric guitar') }
proficiency_level 1
priority 0
end
factory :invited_user, :class => JamRuby::InvitedUser do
sequence(:email) { |n| "user#{n}@someservice.com" }
autofriend false
@ -313,7 +319,7 @@ FactoryGirl.define do
association :mount_template, :factory => :icecast_mount_template
factory :iceast_mount_with_music_session do
association :music_session, :factory => :music_session
association :music_session, :factory => :active_music_session
end
end
end

View File

@ -263,8 +263,8 @@ describe Feed do
feeds, start = Feed.index(claimed_recording1.user)
feeds.length.should == 1
claimed_recording1.recording.music_session.fan_access = false
claimed_recording1.recording.music_session.save!
claimed_recording1.recording.music_session.music_session.fan_access = false
claimed_recording1.recording.music_session.music_session.save!
feeds, start = Feed.index(claimed_recording1.user)
feeds.length.should == 0

View File

@ -3,15 +3,49 @@ require 'spec_helper'
describe MusicSession do
let(:creator) {FactoryGirl.create(:user)}
let(:some_user) { FactoryGirl.create(:user) }
let(:music_session) { FactoryGirl.create(:music_session_no_history) }
let(:music_session) { FactoryGirl.create(:active_music_session_no_user_history) }
let(:user_history1) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => music_session.creator, :created_at => 2.days.ago, :session_removed_at => 1.days.ago) }
let(:user_history2) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => some_user, :created_at => 2.days.ago, :session_removed_at => 1.days.ago) }
let(:user_history3) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => music_session.creator, :created_at => 3.days.ago, :session_removed_at => 2.days.ago) }
let(:user_history4) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => some_user, :created_at => 3.days.ago, :session_removed_at => 2.days.ago) }
it "create" do
music_session.music_session.description.should eql(music_session.description)
describe "validations" do
it "genre must be set" do
music_session = FactoryGirl.build(:music_session_history)
music_session.genre = nil
music_session.save.should be_false
music_session.errors[:genre].should == ["can't be blank"]
end
it "updates the fields of a music session properly" do
genre1 = FactoryGirl.create(:genre)
genre2 = FactoryGirl.create(:genre)
genre3 = FactoryGirl.create(:genre)
genre4 = FactoryGirl.create(:genre)
creator = FactoryGirl.create(:user)
session = FactoryGirl.create(:music_session_history, :creator => creator, :description => "Session", :genre => genre3)
session.update_attributes({:description => "Session2", :genre => genre1})
session.reload
session.description.should == "Session2"
session.genre.should == genre1
end
it "must have legal_terms accepted" do
user1 = FactoryGirl.create(:user)
music_session = FactoryGirl.build(:music_session_history, :creator => user1, legal_terms: false)
music_session.save
music_session.valid?.should be_false
music_session.errors["legal_terms"].should == ["is not included in the list"]
end
it "cannot have profanity in the description" do
user1 = FactoryGirl.create(:user)
music_session = FactoryGirl.build(:music_session_history, :creator => user1, legal_terms: false, :description => "fuck you")
music_session.save
music_session.valid?.should be_false
end
end
it "unique users" do

View File

@ -8,14 +8,6 @@ describe ActiveMusicSession do
IcecastMount.delete_all
end
describe "validations" do
it "genre must be set" do
music_session = FactoryGirl.build(:music_session)
music_session.genres = []
music_session.save.should be_false
music_session.errors[:genres].should == [ValidationMessages::SESSION_GENRE_MINIMUM_NOT_MET]
end
end
it 'can grant access to valid user' do
user1 = FactoryGirl.create(:user) # in the jam session
@ -89,7 +81,8 @@ describe ActiveMusicSession do
music_session.can_see?(user3).should == false
end
=begin
#XXX These tests should use nindex
describe "index" do
it "orders two sessions by created_at starting with most recent" do
creator = FactoryGirl.create(:user)
@ -310,7 +303,7 @@ describe ActiveMusicSession do
end
end
=end
describe "nindex" do
it "nindex orders two sessions by created_at starting with most recent" do
creator = FactoryGirl.create(:user)
@ -341,20 +334,6 @@ describe ActiveMusicSession do
end
end
it "updates the fields of a music session properly" do
genre1 = FactoryGirl.create(:genre)
genre2 = FactoryGirl.create(:genre)
genre3 = FactoryGirl.create(:genre)
genre4 = FactoryGirl.create(:genre)
creator = FactoryGirl.create(:user)
session = FactoryGirl.create(:active_music_session, :creator => creator, :description => "Session", :genres => [genre3,genre4])
session.update_attributes({:description => "Session2", :genre => [genre1, genre2]})
session.genres = [genre1, genre2]
session.reload
session.description.should == "Session2"
session.genres.length.should == 2
session.genres[0].id.should == genre1.id
end
it 'uninvited users cant join approval-required sessions without invitation' do
user1 = FactoryGirl.create(:user) # in the jam session
@ -367,24 +346,10 @@ describe ActiveMusicSession do
end
it "must have legal_terms accepted" do
user1 = FactoryGirl.create(:user)
music_session = FactoryGirl.build(:music_session, :creator => user1, :legal_terms=> false)
music_session.save
music_session.valid?.should be_false
music_session.errors["legal_terms"].should == ["is not included in the list"]
end
it "cannot have profanity in the description" do
user1 = FactoryGirl.create(:user)
music_session = FactoryGirl.build(:music_session, :creator => user1, :legal_terms=> false, :description => "fuck you")
music_session.save
music_session.valid?.should be_false
end
it "is_recording? returns false if not recording" do
user1 = FactoryGirl.create(:user)
music_session = FactoryGirl.build(:music_session, :creator => user1)
music_session = FactoryGirl.build(:active_music_session, :creator => user1)
music_session.is_recording?.should be_false
end
@ -500,14 +465,5 @@ describe ActiveMusicSession do
@music_session.get_connection_ids(exclude_client_id: @connection2.client_id, as_musician: true).should == [@connection1.client_id]
end
end
describe "autosave of music session history" do
it "is created on initial music session create" do
music_session = FactoryGirl.create(:active_music_session)
history = MusicSession.find(music_session.id)
history.genres.should == music_session.genres.first.id
end
end
end

View File

@ -3,7 +3,7 @@ require 'spec_helper'
describe MusicSessionUserHistory do
let(:some_user) { FactoryGirl.create(:user) }
let(:music_session) { FactoryGirl.create(:music_session_no_history) }
let(:music_session) { FactoryGirl.create(:active_music_session_no_user_history) }
let(:user_history1) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => music_session.creator) }
let(:user_history2) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => some_user) }
@ -136,10 +136,7 @@ describe MusicSessionUserHistory do
user_history1.end_history
user_history1.max_concurrent_connections.should == 3
end
end
end

View File

@ -179,51 +179,42 @@
// Defaulting to 1st instrument in profile always at the moment.
data.tracks = tracks;
var jsonData = JSON.stringify(data);
$('#btn-create-session').addClass('button-disabled');
$('#btn-create-session').bind('click', false);
var url = "/api/sessions";
$.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json',
url: url,
processData:false,
data: jsonData,
success: function(response) {
var newSessionId = response.id;
var invitationCount = inviteMusiciansUtil.createInvitations(newSessionId, function() {
context.location = '/client#/session/' + newSessionId;
});
// Re-loading the session settings will cause the form to reset with the right stuff in it.
// This is an extra xhr call, but it keeps things to a single codepath
loadSessionSettings();
$('#btn-create-session').removeClass('button-disabled');
$('#btn-create-session').unbind('click', false);
rest.legacyCreateSession(data)
.done(function(response) {
var newSessionId = response.id;
var invitationCount = inviteMusiciansUtil.createInvitations(newSessionId, function() {
context.location = '/client#/session/' + newSessionId;
});
// Re-loading the session settings will cause the form to reset with the right stuff in it.
// This is an extra xhr call, but it keeps things to a single codepath
loadSessionSettings();
$('#btn-create-session').removeClass('button-disabled');
$('#btn-create-session').unbind('click', false);
context.JK.GA.trackSessionCount(data.musician_access, data.fan_access, invitationCount);
context.JK.GA.trackSessionMusicians(context.JK.GA.SessionCreationTypes.create);
},
error: function(jqXHR) {
var handled = false;
if(jqXHR.status = 422) {
var response = JSON.parse(jqXHR.responseText);
if(response["errors"] && response["errors"]["tracks"] && response["errors"]["tracks"][0] == "Please select at least one track") {
app.notifyAlert("No Inputs Configured", $('<span>You will need to reconfigure your audio device.</span>'));
handled = true;
}
}
if(!handled) {
app.notifyServerError(jqXHR, "Unable to Create Session");
}
$('#btn-create-session').removeClass('button-disabled');
$('#btn-create-session').unbind('click', false);
context.JK.GA.trackSessionCount(data.musician_access, data.fan_access, invitationCount);
context.JK.GA.trackSessionMusicians(context.JK.GA.SessionCreationTypes.create);
})
.fail(function(jqXHR) {
var handled = false;
if(jqXHR.status = 422) {
var response = JSON.parse(jqXHR.responseText);
if(response["errors"] && response["errors"]["tracks"] && response["errors"]["tracks"][0] == "Please select at least one track") {
app.notifyAlert("No Inputs Configured", $('<span>You will need to reconfigure your audio device.</span>'));
handled = true;
}
}
});
if(!handled) {
app.notifyServerError(jqXHR, "Unable to Create Session");
}
$('#btn-create-session').removeClass('button-disabled');
$('#btn-create-session').unbind('click', false);
})
return false;
}

View File

@ -34,6 +34,16 @@
});
}
function legacyCreateSession(options) {
return $.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json',
url: "/api/sessions/legacy",
processData:false,
data: JSON.stringify(options)});
}
function findSessions(query) {
return $.ajax({
type: "GET",
@ -970,6 +980,7 @@
// Expose publics
this.initialize = initialize;
this.legacyCreateSession = legacyCreateSession;
this.getUserDetail = getUserDetail;
this.getCities = getCities;
this.getRegions = getRegions;

View File

@ -32,7 +32,7 @@ class ApiInvitationsController < ApiController
end
def create
music_session = ActiveMusicSession.find(params[:music_session])
music_session = MusicSession.find(params[:music_session])
receiver = User.find(params[:receiver])
sender = current_user
join_request = JoinRequest.find(params[:join_request]) unless params[:join_request].nil?

View File

@ -14,7 +14,7 @@ class ApiJoinRequestsController < ApiController
end
def create
music_session = ActiveMusicSession.find(params[:music_session])
music_session = MusicSession.find(params[:music_session])
text = params[:text]
sender = current_user

View File

@ -60,39 +60,68 @@ class ApiMusicSessionsController < ApiController
limit: params[:limit])
end
def create
def create_legacy
client_id = params[:client_id]
if client_id.nil?
raise JamArgumentError, "client_id must be specified"
end
if !params[:intellectual_property]
unless params[:intellectual_property]
raise JamArgumentError, "You must agree to the intellectual property terms"
end
band = Band.find(params[:band]) unless params[:band].nil?
@music_session = MusicSessionManager.new.create(
current_user,
client_id,
params[:description],
params[:musician_access],
params[:approval_required],
params[:fan_chat],
params[:fan_access],
band,
params[:genres],
params[:tracks],
params[:legal_terms])
# creating the MusicSession right here was added as part of the scheduled sessions changes
# Why? The new order of things is to always have a MusicSession before a ActiveMusicSession
# So, we have to make MusicSession, and pass in it's .id to MusicSessionManager.new.create()
# so that the ActiveMusicSession can have the same .id as the MusicSession
history = MusicSession.new
history.name = params[:description][0..40]
history.description = params[:description]
history.musician_access = params[:musician_access]
history.approval_required = params[:approval_required]
history.fan_chat = params[:fan_chat]
history.fan_access = params[:fan_access]
history.band = band
history.genre_id = (params[:genres].length > 0 ? params[:genres][0] : nil) if params[:genres]
history.legal_terms = params[:legal_terms]
history.language = 'english'
history.legal_policy = 'standard'
history.creator = current_user
history.save
if @music_session.errors.any?
# we have to do this because api_session_detail_url will fail with a bad @music_session
if history.errors.any?
@music_session = history
response.status = :unprocessable_entity
respond_with @music_session
else
respond_with @music_session, responder: ApiResponder, :location => api_session_detail_url(@music_session)
history.reload # to get .id back
@music_session = MusicSessionManager.new.create(
history,
current_user,
client_id,
params[:description],
params[:musician_access],
params[:approval_required],
params[:fan_chat],
params[:fan_access],
band,
params[:genres],
params[:tracks],
params[:legal_terms])
if @music_session.errors.any?
response.status = :unprocessable_entity
respond_with @music_session
else
respond_with @music_session, responder: ApiResponder, :location => api_session_detail_url(@music_session)
end
end
end
def show
@ -103,7 +132,7 @@ class ApiMusicSessionsController < ApiController
def update
@music_session = MusicSessionManager.new.update(
@music_session,
@music_session.music_session,
params[:description],
params[:genres],
params[:musician_access],

View File

@ -1,10 +1,10 @@
module FeedsHelper
def session_artist_name(music_session)
(music_session.band.nil? ? nil : music_session.band.name) || music_session.user.name
(music_session.band.nil? ? nil : music_session.band.name) || music_session.creator.name
end
def session_artist_id(music_session)
(music_session.band.nil? ? nil : music_session.band.id) || music_session.user.id
(music_session.band.nil? ? nil : music_session.band.id) || music_session.creator.id
end
def session_artist_hoveraction(music_session)
@ -16,7 +16,7 @@ module FeedsHelper
end
def session_avatar(music_session)
image_tag resolve_avatarables(music_session.band, music_session.user)
image_tag resolve_avatarables(music_session.band, music_session.creator)
end
def session_duration_value(music_session)
@ -36,7 +36,7 @@ module FeedsHelper
'SESSION ENDED'
else
if music_session.fan_access
if music_session.music_session && music_session.music_session.mount
if music_session.active_music_session && music_session.active_music_session.mount
'SESSION IN PROGRESS'
else
'BROADCASTING OFFLINE' # if you see this in development, you need to set up icecast. If you see this in production, it's not healthy
@ -53,9 +53,7 @@ module FeedsHelper
# grabs 1st genre
def session_genre(music_session)
genres_array = music_session.genres.nil? ? [] : music_session.genres.split(MusicSession::SEPARATOR)
genre = genres_array.length > 0 ? Genre.find_by_id(genres_array[0]) : nil
genre.nil? ? '' : genre.description
music_session.genre.description
end
def recording_artist_name(recording)

View File

@ -27,7 +27,7 @@ module MusicSessionHelper
if sharer && unique_users.exists?(sharer)
"LIVE SESSION: #{sharer.name}#{additional_member_count(unique_users)}"
else
"LIVE SESSION: #{music_session.user.name}#{additional_member_count(unique_users)}"
"LIVE SESSION: #{music_session.creator.name}#{additional_member_count(unique_users)}"
end
end

View File

@ -12,7 +12,7 @@ glue :music_session do
node do |history|
{
helpers: {
avatar: asset_path(resolve_avatarables(history.band, history.user)),
avatar: asset_path(resolve_avatarables(history.band, history.creator)),
artist_name: session_artist_name(history),
artist_id: session_artist_id(history),
artist_datakey: session_artist_datakey(history),
@ -27,7 +27,7 @@ glue :music_session do
}
end
child(:user => :creator) {
child(:creator => :creator) {
attributes :id, :first_name, :last_name, :photo_url
}
@ -60,7 +60,7 @@ glue :music_session do
attributes :id, :name, :location, :photo_url
}
child(:music_session => :music_session) do
child(:active_music_session => :music_session) do
# only show mount info if fan_access is public. Eventually we'll also need to show this in other scenarios, like if invited
child({:mount => :mount}, :if => lambda { |music_session| music_session.fan_access}) {
attributes :id, :name, :sourced, :listeners, :bitrate, :subtype, :url

View File

@ -0,0 +1,3 @@
object @music_session
extends "api_music_sessions/show"

View File

@ -0,0 +1,3 @@
object @music_session
extends "api_music_sessions/show"

View File

@ -0,0 +1,3 @@
object @music_session
extends "api_music_sessions/show"

View File

@ -8,7 +8,7 @@ node :share_url do |history|
end
end
child(:user => :creator) {
child(:creator => :creator) {
attributes :name, :photo_url
}

View File

@ -16,7 +16,7 @@ else
attributes :id, :description, :musician_access, :approval_required, :fan_access, :fan_chat, :band_id, :user_id, :claimed_recording_initiator_id, :track_changes_counter, :max_score
node :genres do |item|
item.genres.map(&:description)
[item.genre.description] # XXX: need to return single genre; not array
end
if :is_recording?

View File

@ -30,13 +30,13 @@
<%= @music_session.band.name %>
<% else %>
<div class="landing-avatar">
<% unless @music_session.user.photo_url.blank? %>
<%= image_tag "#{@music_session.user.photo_url}", {:alt => ""} %>
<% unless @music_session.creator.photo_url.blank? %>
<%= image_tag "#{@music_session.creator.photo_url}", {:alt => ""} %>
<% else %>
<%= image_tag "shared/avatar_generic.png", {:alt => ""} %>
<% end %>
</div>
<%= @music_session.user.name %>
<%= @music_session.creator.name %>
<% end %>
</div>
@ -56,9 +56,9 @@
<div class="recording-controls <%= @music_session.is_over? ? 'ended' : 'inprogress' %>" data-music-session="<%=@music_session.id %>">
<a class="left play-button" href="#">
<%= image_tag 'content/icon_playbutton.png', width:20, height:20, class:'play-icon' %>
<% if @music_session.music_session && @music_session.music_session.mount %>
<% if @music_session.active_music_session && @music_session.active_music_session.mount %>
<audio preload="none">
<source src="<%= @music_session.music_session.mount.url %>" type="<%= @music_session.music_session.mount.resolve_string(:mime_type) %>">
<source src="<%= @music_session.active_music_session.mount.url %>" type="<%= @music_session.active_music_session.mount.resolve_string(:mime_type) %>">
</audio>
<% end %>
</a>
@ -66,7 +66,7 @@
<%= session_duration(@music_session, class: 'session-duration tick-duration recording-current', 'data-created-at' => @music_session.created_at.to_i) %>
</div>
<div class="left white"><%= @music_session.genres.split('|').first.capitalize unless @music_session.genres.blank? %></div>
<div class="left white"><%= @music_session.genre.description %></div>
<div class="right white">
<span id="spnCommentCount"><%= @music_session.comment_count %></span>
@ -111,7 +111,7 @@
<% unless @music_session.band.nil? %>
<%= render :partial => "shared/landing_sidebar", :locals => {:user => @music_session.band, :recent_history => @music_session.band.recent_history} %>
<% else %>
<%= render :partial => "shared/landing_sidebar", :locals => {:user => @music_session.user, :recent_history => @music_session.user.recent_history} %>
<%= render :partial => "shared/landing_sidebar", :locals => {:user => @music_session.creator, :recent_history => @music_session.creator.recent_history} %>
<% end %>
<% else %>
<%= render :partial => "shared/cta_sidebar" %>

View File

@ -1,4 +1,4 @@
- if feed_item.music_session
= render :partial => "feed_music_session", locals: { feed_item: feed_item.music_session }
= render :partial => "feed_music_session", locals: { feed_item: feed_item.music_session}
- else
= render :partial => "feed_recording", locals: { feed_item: feed_item.recording }

View File

@ -22,7 +22,7 @@
= image_tag 'content/icon_playbutton.png', width:20, height:20, class:'play-icon'
- if feed_item.has_mount?
%audio{preload: 'none'}
%source{src: feed_item.music_session.mount.url, type: feed_item.music_session.mount.resolve_string(:mime_type)}
%source{src: feed_item.active_music_session.mount.url, type: feed_item.active_music_session.mount.resolve_string(:mime_type)}
%span.session-status
= session_text(feed_item)
/ current playback time

View File

@ -25,7 +25,7 @@
= image_tag 'content/icon_playbutton.png', width:20, height:20, class:'play-icon'
= "{% if(data.feed_item['has_mount?']) { %}"
%audio{preload: 'none'}
%source{src: '{{data.feed_item.music_session.mount.url}}', type: '{{data.feed_item.music_session.mount.mime_type}}'}
%source{src: '{{data.feed_item.active_music_session.mount.url}}', type: '{{data.feed_item.active_music_session.mount.mime_type}}'}
= '{% } %}'
%span.session-status
= '{{data.feed_item.helpers.status}}'

View File

@ -149,7 +149,7 @@ SampleApp::Application.routes.draw do
match '/sessions/:id' => 'api_music_sessions#update', :via => :put
match '/sessions' => 'api_music_sessions#index', :via => :get
match '/sessions/nindex/:client_id' => 'api_music_sessions#nindex', :via => :get
match '/sessions' => 'api_music_sessions#create', :via => :post
match '/sessions/legacy' => 'api_music_sessions#create_legacy', :via => :post
match '/sessions/:id/perf' => 'api_music_sessions#perf_upload', :via => :put
match '/sessions/:id/comments' => 'api_music_sessions#add_comment', :via => :post
match '/sessions/:id/likes' => 'api_music_sessions#add_like', :via => :post

View File

@ -9,7 +9,7 @@ MusicSessionManager < BaseManager
@log = Logging.logger[self]
end
def create(user, client_id, description, musician_access, approval_required, fan_chat, fan_access, band, genres, tracks, legal_terms)
def create(music_session, user, client_id, description, musician_access, approval_required, fan_chat, fan_access, band, genres, tracks, legal_terms)
return_value = nil
time = Benchmark.realtime do
@ -21,56 +21,42 @@ MusicSessionManager < BaseManager
icecast_server.lock! if icecast_server
# check if we are connected to rabbitmq
music_session = ActiveMusicSession.new
music_session.id = SecureRandom.uuid
music_session.creator = user
music_session.description = description
music_session.musician_access = musician_access
music_session.approval_required = approval_required
music_session.fan_chat = fan_chat
music_session.fan_access = fan_access
music_session.band = band
music_session.legal_terms = legal_terms
unless genres.nil?
genres.each do |genre_id|
loaded_genre = Genre.find(genre_id)
music_session.genres << loaded_genre
end
end
active_music_session = ActiveMusicSession.new
active_music_session.id = music_session.id # copy the .id from music_session to active_music_session
active_music_session.creator = user
if fan_access
# create an icecast mount since regular users can listen in to the broadcast
music_session.mount = IcecastMount.build_session_mount(music_session, icecast_server)
active_music_session.mount = IcecastMount.build_session_mount(music_session, active_music_session, icecast_server)
end
music_session.save
active_music_session.save
unless music_session.errors.any?
unless active_music_session.errors.any?
# save session parameters for next session
User.save_session_settings(user, music_session)
# auto-join this user into the newly created session
as_musician = true
connection = ConnectionManager.new.join_music_session(user, client_id, music_session, as_musician, tracks)
connection = ConnectionManager.new.join_music_session(user, client_id, active_music_session, as_musician, tracks)
unless connection.errors.any?
user.update_progression_field(:first_music_session_at)
MusicSessionUserHistory.save(music_session.id, user.id, client_id, tracks)
MusicSessionUserHistory.save(active_music_session.id, user.id, client_id, tracks)
# only send this notification if it's a band session
unless band.nil?
Notification.send_band_session_join(music_session, band)
Notification.send_band_session_join(active_music_session, band)
end
return_value = music_session
return_value = active_music_session
else
return_value = connection
# rollback the transaction to make sure nothing is disturbed in the database
raise ActiveRecord::Rollback
end
else
return_value = music_session
return_value = active_music_session
# rollback the transaction to make sure nothing is disturbed in the database
raise ActiveRecord::Rollback
end
@ -87,26 +73,13 @@ MusicSessionManager < BaseManager
# Update the session. If a field is left out (meaning, it's set to nil), it's not updated.
def update(music_session, description, genres, musician_access, approval_required, fan_chat, fan_access)
update = {}
update[:description] = description unless description.nil?
update[:musician_access] = musician_access unless musician_access.nil?
update[:approval_required] = approval_required unless approval_required.nil?
update[:fan_chat] = fan_chat unless fan_chat.nil?
update[:fan_access] = fan_access unless fan_access.nil?
# Do I have to do this the way he did above? Not sure. Probably yes.
genre_array = []
if genres.nil?
music_session.skip_genre_validation = true
else
genres.each do |genre_id|
loaded_genre = Genre.find(genre_id)
genre_array << loaded_genre
end
update[:genres] = genre_array
end
music_session.update_attributes(update)
music_session.description = description unless description.nil?
music_session.musician_access = musician_access unless musician_access.nil?
music_session.approval_required = approval_required unless approval_required.nil?
music_session.fan_chat = fan_chat unless fan_chat.nil?
music_session.fan_access = fan_access unless fan_access.nil?
music_session.genre = Genre.find_by_id(genres[0]) if genres && genres.length > 0
music_session.save
music_session
end

View File

@ -117,8 +117,8 @@ describe ApiFeedsController do
describe "user targetting" do
it "user viewing own profile" do
music_session.fan_access = false
music_session.save!
music_session.music_session.fan_access = false
music_session.music_session.save!
controller.current_user = music_session.creator
get :index, { user: music_session.creator.id }
@ -127,8 +127,8 @@ describe ApiFeedsController do
end
it "user viewing someone else's profile" do
music_session.fan_access = false
music_session.save!
music_session.music_session.fan_access = false
music_session.music_session.save!
controller.current_user = user2
music_session.music_session.reload
music_session.music_session.fan_access.should be_false

View File

@ -38,7 +38,7 @@ FactoryGirl.define do
factory :user_two_instruments do
before(:create) do |user|
user.musician_instruments << FactoryGirl.create(:musician_instrument, user: user, instrument: Instrument.find('drums'), proficiency_level: 2, priority:1 )
user.musician_instruments << FactoryGirl.create(:musician_instrument, user: user, instrument: JamRuby::Instrument.find('drums'), proficiency_level: 2, priority:1 )
end
end
@ -50,27 +50,67 @@ FactoryGirl.define do
end
end
factory :musician_instrument, :class=> JamRuby::MusicianInstrument do
instrument { Instrument.find('electric guitar') }
proficiency_level 1
priority 0
end
factory :invited_user, :class => JamRuby::InvitedUser do
sequence(:email) { |n| "user#{n}@someservice.com" }
autofriend false
end
factory :music_session, :class => JamRuby::ActiveMusicSession do
sequence(:description) { |n| "Music Session #{n}" }
factory :active_music_session_no_user_history, :class => JamRuby::ActiveMusicSession do
association :creator, factory: :user
ignore do
name "My Music Session"
description "Come Music Session"
fan_chat true
fan_access true
approval_required false
musician_access true
legal_terms true
genre JamRuby::Genre.first
band nil
end
before(:create) do |session, evaluator|
music_session = FactoryGirl.create(:music_session_history, name: evaluator.name, description: evaluator.description, fan_chat: evaluator.fan_chat,
fan_access: evaluator.fan_access, approval_required: evaluator.approval_required, musician_access: evaluator.musician_access,
genre: evaluator.genre, creator: evaluator.creator, band: evaluator.band)
session.id = music_session.id
end
factory :active_music_session do
after(:create) { |session|
FactoryGirl.create(:music_session_user_history, :history => session.music_session, :user => session.creator)
}
factory :music_session_with_mount do
association :mount, :factory => :icecast_mount
end
end
end
factory :music_session_history, :class => JamRuby::MusicSession do
sequence(:name) { |n| "Music Session #{n}" }
sequence(:description) { |n| "Music Session Description #{n}" }
fan_chat true
fan_access true
approval_required false
musician_access true
legal_terms true
genres [JamRuby::Genre.first]
language 'english'
legal_policy 'standard'
genre JamRuby::Genre.first
association :creator, :factory => :user
after(:create) { |session|
FactoryGirl.create(:music_session_user_history, :history => session.music_session, :user => session.creator)
}
end
factory :music_session_user_history, :class => JamRuby::MusicSessionUserHistory do
ignore do
history nil
@ -136,12 +176,6 @@ FactoryGirl.define do
size { 20 }
end
factory :musician_instrument, :class=> JamRuby::MusicianInstrument do
instrument { Instrument.find('electric guitar') }
proficiency_level 1
priority 0
end
factory :track, :class => JamRuby::Track do
sound "mono"
sequence(:client_track_id) { |n| "client_track_id_seq_#{n}"}
@ -165,7 +199,7 @@ FactoryGirl.define do
factory :recording, :class => JamRuby::Recording do
association :owner, factory: :user
association :music_session, factory: :music_session
association :music_session, factory: :active_music_session
factory :recording_with_track do
before(:create) { |recording|

View File

@ -102,7 +102,6 @@ describe "Events", :js => true, :type => :feature, :capybara_feature => true, :s
visit "/events/so_latency"
# then end it, and see session_ended
music_session = music_session.music_session
music_session.session_removed_at = Time.now
music_session.save!
visit "/events/so_latency"

View File

@ -194,7 +194,7 @@ describe "Welcome", :js => true, :type => :feature, :capybara_feature => true d
find('.feed-entry.music-session-history-entry .description', text: MusicSession1.description)
find('.feed-entry.music-session-history-entry .session-status', text: 'BROADCASTING OFFLINE')
find('.feed-entry.music-session-history-entry .session-controls.inprogress', text: 'BROADCASTING OFFLINE')
find('.feed-entry.music-session-history-entry .artist', text: MusicSession1.user.name)
find('.feed-entry.music-session-history-entry .artist', text: MusicSession1.creator.name)
should_not have_selector('.feed-entry.music-session-history-entry .musician-detail')
find('.feed-entry.recording-entry .name', text: claimedRecording1.name)

View File

@ -54,7 +54,7 @@ describe MusicSessionHelper do
music_session = FactoryGirl.create(:active_music_session, creator: FactoryGirl.create(:user))
result = helper.title_for_music_session(music_session.music_session)
result.start_with?("LIVE SESSION").should be_true
result.end_with?(music_session.music_session.user.name).should be_true
result.end_with?(music_session.music_session.creator.name).should be_true
end
end

View File

@ -2,6 +2,8 @@ require 'spec_helper'
describe MusicSessionManager do
let (:music_session) { FactoryGirl.create(:music_session_history) }
before(:each) do
@music_session_manager = MusicSessionManager.new(:conn => @conn)
end
@ -18,13 +20,13 @@ describe MusicSessionManager do
end
it "creates a session properly" do
music_session = @music_session_manager.create(@user, @connection.client_id, "description", true, false, true, true, @band, [@genre], @tracks, true)
active_music_session = @music_session_manager.create(music_session, @user, @connection.client_id, "description", true, false, true, true, @band, [@genre], @tracks, true)
ActiveMusicSession.find(music_session.id) # shouldn't throw an exception
ActiveMusicSession.find(active_music_session.id) # shouldn't throw an exception
end
it "updates a session properly" do
music_session = @music_session_manager.create(@user, @connection.client_id, "description", true, false, true, true, @band, [@genre], @tracks, true)
active_music_session = @music_session_manager.create(music_session, @user, @connection.client_id, "description", true, false, true, true, @band, [@genre], @tracks, true)
@music_session_manager.update(music_session, "updated description", nil, nil, nil, nil, nil)
music_session.reload
music_session.description.should == "updated description"
@ -34,17 +36,16 @@ describe MusicSessionManager do
@music_session_manager.update(music_session, nil, [@genre, genre2], nil, nil, nil, nil)
music_session.reload
music_session.description.should == "updated description"
music_session.genres.count.should == 2
music_session.genres.should == [@genre, genre2]
music_session.genre.should == @genre
end
it "deletes a session properly" do
music_session = @music_session_manager.create(@user, @connection.client_id, "description", true, false, true, true, @band, [@genre], @tracks, true)
music_session_user_history = MusicSession.find_by_music_session_id(music_session.id)
music_session_user_history.should_not be_nil
music_session.destroy
music_session_user_history.reload
music_session_user_history.session_removed_at.should_not == nil
active_music_session = @music_session_manager.create(music_session, @user, @connection.client_id, "description", true, false, true, true, @band, [@genre], @tracks, true)
music_session = MusicSession.find_by_music_session_id(active_music_session.id)
music_session.should_not be_nil
active_music_session.destroy
music_session.reload
music_session.session_removed_at.should_not == nil
end
end

View File

@ -72,7 +72,7 @@ describe "Invitation API ", :type => :api do
FactoryGirl.create(:connection, :user => user, :music_session => music_session)
FactoryGirl.create(:friendship, :user => user, :friend => other_user)
FactoryGirl.create(:friendship, :user => other_user, :friend => user)
invitation = FactoryGirl.create(:invitation, :sender => user, :receiver => other_user, :music_session => music_session)
invitation = FactoryGirl.create(:invitation, :sender => user, :receiver => other_user, :music_session => music_session.music_session)
# see that there are no invitations sent to us
get '/api/invitations.json'
@ -86,7 +86,7 @@ describe "Invitation API ", :type => :api do
response[0]["id"].should == invitation.id
# create an invitation the other way
invitation = FactoryGirl.create(:invitation, :sender => other_user, :receiver => user, :music_session => music_session)
invitation = FactoryGirl.create(:invitation, :sender => other_user, :receiver => user, :music_session => music_session.music_session)
# see that there is one invitations sent to us
get '/api/invitations.json'
response = JSON.parse(last_response.body)
@ -103,7 +103,7 @@ describe "Invitation API ", :type => :api do
FactoryGirl.create(:connection, :user => user, :music_session => music_session)
FactoryGirl.create(:friendship, :user => user, :friend => other_user)
FactoryGirl.create(:friendship, :user => other_user, :friend => user)
invitation = FactoryGirl.create(:invitation, :sender => user, :receiver => other_user, :music_session => music_session)
invitation = FactoryGirl.create(:invitation, :sender => user, :receiver => other_user, :music_session => music_session.music_session)
post '/api/invitations.json', {:music_session => music_session.id, :receiver => other_user.id}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(409)
@ -121,7 +121,7 @@ describe "Invitation API ", :type => :api do
FactoryGirl.create(:connection, :user => user, :music_session => music_session)
FactoryGirl.create(:friendship, :user => user, :friend => other_user)
FactoryGirl.create(:friendship, :user => other_user, :friend => user)
invitation = FactoryGirl.create(:invitation, :sender => user, :receiver => other_user, :music_session => music_session)
invitation = FactoryGirl.create(:invitation, :sender => user, :receiver => other_user, :music_session => music_session.music_session)
# refind the invitation to make sure the db serves it up
Invitation.find_by_id(invitation.id).should_not == nil
@ -133,25 +133,6 @@ describe "Invitation API ", :type => :api do
Invitation.find_by_id(invitation.id).should == nil
end
it "should delete by deletion of music session" do
other_user = FactoryGirl.create(:user) # in the music session
# starting condition; valid session and current user is already in it
music_session = FactoryGirl.create(:active_music_session, :creator => user)
FactoryGirl.create(:connection, :user => other_user, :music_session => music_session)
FactoryGirl.create(:connection, :user => user, :music_session => music_session)
FactoryGirl.create(:friendship, :user => user, :friend => other_user)
FactoryGirl.create(:friendship, :user => other_user, :friend => user)
invitation = FactoryGirl.create(:invitation, :sender => user, :receiver => other_user, :music_session => music_session)
# refind the invitation to make sure the db serves it up
Invitation.find_by_id(invitation.id).should_not == nil
music_session.destroy
# and then verify that the invitation is gone
Invitation.find_by_id(invitation.id).should == nil
end
it "should not allow query of invitations not belonging to current user" do
other_user = FactoryGirl.create(:user) # in the music session
@ -162,7 +143,7 @@ describe "Invitation API ", :type => :api do
FactoryGirl.create(:connection, :user => other_user2, :music_session => music_session)
FactoryGirl.create(:friendship, :user => other_user2, :friend => other_user)
FactoryGirl.create(:friendship, :user => other_user, :friend => other_user2)
invitation = FactoryGirl.create(:invitation, :sender => other_user2, :receiver => other_user, :music_session => music_session)
invitation = FactoryGirl.create(:invitation, :sender => other_user2, :receiver => other_user, :music_session => music_session.music_session)
# then check that there is one invitation sent by us
get '/api/invitations.json?sender=' + other_user.id

View File

@ -38,7 +38,7 @@ describe "Music Session API ", :type => :api do
it "should create session" do
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1", :client_id => "1")
post '/api/sessions.json', defopts.merge({:client_id => client.client_id}).to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions/legacy.json', defopts.merge({:client_id => client.client_id}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
# now fetch it's data
@ -184,7 +184,7 @@ describe "Music Session API ", :type => :api do
it "should add/remove member from session" do
# create the session
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', defopts.merge({:client_id => client.client_id}).to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions/legacy.json', defopts.merge({:client_id => client.client_id}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
# now fetch it's data
@ -219,7 +219,7 @@ describe "Music Session API ", :type => :api do
user2 = FactoryGirl.create(:user)
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
client2 = FactoryGirl.create(:connection, :user => user2, :ip_address => "2.2.2.2")
post '/api/sessions.json', defopts.merge({:client_id => client.client_id}).to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions/legacy.json', defopts.merge({:client_id => client.client_id}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
# now fetch it's data
@ -284,24 +284,25 @@ describe "Music Session API ", :type => :api do
# create the session
original_count = ActiveMusicSession.all().length
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', defopts.merge({:client_id => client.client_id, :genres => nil}).to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions/legacy.json', defopts.merge({:client_id => client.client_id, :genres => nil}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(422)
ActiveMusicSession.all().length.should == original_count
end
it "should error with invalid genre specified" do
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', defopts.merge({ :client_id => client.client_id, :genres => ["Junk"]}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(404)
post '/api/sessions/legacy.json', defopts.merge({ :client_id => client.client_id, :genres => ["Junk"]}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(422)
JSON.parse(last_response.body)["errors"]["genre"].should == ["can't be blank"]
end
it "should error with no track specified" do
original_count = ActiveMusicSession.all().length
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', defopts.merge({:client_id => client.client_id, :tracks => nil}).to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions/legacy.json', defopts.merge({:client_id => client.client_id, :tracks => nil}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(422)
JSON.parse(last_response.body)["errors"]["tracks"][0].should == ValidationMessages::SELECT_AT_LEAST_ONE
JSON.parse(last_response.body)["errors"]["tracks"].should == [ValidationMessages::SELECT_AT_LEAST_ONE]
# check that the transaction was rolled back
ActiveMusicSession.all().length.should == original_count
@ -311,7 +312,7 @@ describe "Music Session API ", :type => :api do
original_count = ActiveMusicSession.all().length
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', defopts.merge({:client_id => client.client_id, :tracks => [{"instrument_id" => "mom", "sound" => "mono", "client_track_id" => "client_track_guid"}]}).to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions/legacy.json', defopts.merge({:client_id => client.client_id, :tracks => [{"instrument_id" => "mom", "sound" => "mono", "client_track_id" => "client_track_guid"}]}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(404)
# check that the transaction was rolled back
@ -322,7 +323,7 @@ describe "Music Session API ", :type => :api do
original_count = ActiveMusicSession.all().length
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', defopts.merge({:client_id => client.client_id, :tracks => [{"instrument_id" => "electric guitar", "sound" => "mom", "client_track_id" => "client_track_guid"}]}).to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions/legacy.json', defopts.merge({:client_id => client.client_id, :tracks => [{"instrument_id" => "electric guitar", "sound" => "mom", "client_track_id" => "client_track_guid"}]}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(422)
JSON.parse(last_response.body)["errors"]["tracks"][0].should == "is invalid"
@ -338,7 +339,7 @@ describe "Music Session API ", :type => :api do
user2 = FactoryGirl.create(:user) # in the music session
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', defopts.merge({:client_id => client.client_id, :musician_access => false}).to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions/legacy.json', defopts.merge({:client_id => client.client_id, :musician_access => false}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
session = JSON.parse(last_response.body)
@ -366,7 +367,7 @@ describe "Music Session API ", :type => :api do
user2 = FactoryGirl.create(:user) # in the music session
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', defopts.merge({:client_id => client.client_id, :musician_access => false}).to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions/legacy.json', defopts.merge({:client_id => client.client_id, :musician_access => false}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
session = JSON.parse(last_response.body)
@ -400,7 +401,7 @@ describe "Music Session API ", :type => :api do
user2 = FactoryGirl.create(:user) # in the music session
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1", :client_id => "3")
post '/api/sessions.json', defopts.merge({:client_id => client.client_id, :musician_access => false}).to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions/legacy.json', defopts.merge({:client_id => client.client_id, :musician_access => false}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
session = JSON.parse(last_response.body)
@ -429,7 +430,7 @@ describe "Music Session API ", :type => :api do
it "join_requests don't show up in session listing" do
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', defopts.merge({:client_id => client.client_id}).to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions/legacy.json', defopts.merge({:client_id => client.client_id}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
location_header = last_response.headers["Location"]
@ -479,7 +480,7 @@ describe "Music Session API ", :type => :api do
it "should now allow join of approval_required=true session" do
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', defopts.merge({:client_id => client.client_id, :approval_required => true}).to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions/legacy.json', defopts.merge({:client_id => client.client_id, :approval_required => true}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
# now fetch it's data
@ -526,7 +527,7 @@ describe "Music Session API ", :type => :api do
# https://jamkazam.atlassian.net/browse/VRFS-254
user.admin = true
client = FactoryGirl.create(:connection, :user => user)
post '/api/sessions.json', defopts.merge({:client_id => client.client_id}).to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions/legacy.json', defopts.merge({:client_id => client.client_id}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
# now fetch it's data
@ -570,7 +571,7 @@ describe "Music Session API ", :type => :api do
# 1st user joins
login(user)
post '/api/sessions.json', defopts.merge({:client_id => client.client_id}).to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions/legacy.json', defopts.merge({:client_id => client.client_id}).to_json, "CONTENT_TYPE" => 'application/json'
location_header = last_response.headers["Location"]
get location_header
music_session = JSON.parse(last_response.body)
@ -591,7 +592,7 @@ describe "Music Session API ", :type => :api do
server = FactoryGirl.create(:icecast_server_minimal)
user2 = FactoryGirl.create(:user) # in the music session
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.10", :client_id => "mount_info")
post '/api/sessions.json', defopts.merge({:client_id => client.client_id, :fan_access => true}).to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions/legacy.json', defopts.merge({:client_id => client.client_id, :fan_access => true}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
session = JSON.parse(last_response.body)
music_session = ActiveMusicSession.find(session["id"])
@ -601,8 +602,8 @@ describe "Music Session API ", :type => :api do
session["mount"]["sourced"].should == music_session.mount.sourced
# set gfan_access to false, which should cause the mount info to hide
music_session.fan_access = false
music_session.save!
music_session.music_session.fan_access = false
music_session.music_session.save!
get "/api/sessions/#{session["id"]}.json"
last_response.status.should eql(200)

View File

@ -76,7 +76,7 @@ describe "User Progression", :type => :api do
it "joined any session" do
user.first_music_session_at.should be_nil
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1", :client_id => "1.1")
post '/api/sessions.json', defopts.merge({:client_id => client.client_id}).to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions/legacy.json', defopts.merge({:client_id => client.client_id}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
user.reload
user.first_music_session_at.should_not be_nil
@ -100,7 +100,7 @@ describe "User Progression", :type => :api do
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1", :client_id => "1_1")
client2 = FactoryGirl.create(:connection, :user => user2, :ip_address => "1.1.1.2", :client_id => "1_2")
client3 = FactoryGirl.create(:connection, :user => user3, :ip_address => "1.1.1.3", :client_id => "1_3")
post '/api/sessions.json', defopts.merge({:client_id => client.client_id}).to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions/legacy.json', defopts.merge({:client_id => client.client_id}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
music_session = JSON.parse(last_response.body)

View File

@ -22,14 +22,63 @@ FactoryGirl.define do
end
end
factory :music_session, :class => JamRuby::ActiveMusicSession do
sequence(:description) { |n| "Jam Session #{n}" }
fan_chat true
factory :active_music_session_no_user_history, :class => JamRuby::ActiveMusicSession do
association :creator, factory: :user
ignore do
name "My Music Session"
description "Come Music Session"
fan_chat true
fan_access true
approval_required false
musician_access true
legal_terms true
genre JamRuby::Genre.first
band nil
end
before(:create) do |session, evaluator|
music_session = FactoryGirl.create(:music_session_history, name: evaluator.name, description: evaluator.description, fan_chat: evaluator.fan_chat,
fan_access: evaluator.fan_access, approval_required: evaluator.approval_required, musician_access: evaluator.musician_access,
genre: evaluator.genre, creator: evaluator.creator, band: evaluator.band)
session.id = music_session.id
end
factory :active_music_session do
after(:create) { |session|
FactoryGirl.create(:music_session_user_history, :history => session.music_session, :user => session.creator)
}
end
end
factory :music_session_history, :class => JamRuby::MusicSession do
sequence(:name) { |n| "Music Session #{n}" }
sequence(:description) { |n| "Music Session Description #{n}" }
fan_chat true
fan_access true
approval_required false
musician_access true
legal_terms true
genres [JamRuby::Genre.first]
language 'english'
legal_policy 'standard'
genre JamRuby::Genre.first
association :creator, :factory => :user
end
factory :music_session_user_history, :class => JamRuby::MusicSessionUserHistory do
ignore do
history nil
user nil
end
instruments 'guitar'
music_session_id { history.id }
user_id { user.id }
sequence(:client_id) { |n| "Connection #{n}" }
end
factory :connection, :class => JamRuby::Connection do