* VRFS-34 and VRFS-61; session.tracks and instrument listing

This commit is contained in:
Seth Call 2012-11-03 22:22:35 -05:00
parent 36f14c19d1
commit 5d1f65d027
11 changed files with 291 additions and 61 deletions

View File

@ -13,7 +13,7 @@ gem 'bootstrap-will_paginate', '0.0.6'
gem 'uuidtools', '2.1.2'
gem 'ruby-protocol-buffers', '1.2.2'
gem 'pg_migrate','0.1.5' #:path => "#{workspace}/pg_migrate_ruby"
#gem 'pg_migrate','0.1.6' #:path => "#{workspace}/pg_migrate_ruby"
gem 'jam_db', :path => "#{workspace}/jam-db/target/ruby_package"
gem 'jam_ruby', :path => "#{workspace}/jam-ruby"
gem 'jampb', :path => "#{workspace}/jam-pb/target/ruby/jampb"

View File

@ -78,7 +78,7 @@ Message from Seth on sequence for creating/joining sessions:
var options = [];
var optionTemplate = $('#template-genre-option').html();
$.each(response, function() {
var d = {value: this.description, label: this.description};
var d = {value: this.id, label: this.description};
var opt = context.JK.fillTemplate(optionTemplate, d);
options.push(opt);
});

View File

@ -0,0 +1,19 @@
class ApiInstrumentsController < ApplicationController
# have to be signed in currently to see this screen
before_filter :signed_in_user
#respond_to :json, :xml
respond_to :html
def index
@instruments = Instrument.where('instruments.popularity > 0').order('instruments.popularity DESC, instruments.description ASC')
end
def show
@instrument = Instrument.find(params[:id])
gon.instrument_id = @instrument.id
gon.description = @instrument.description
end
end

View File

@ -31,8 +31,8 @@ class ApiMusicSessionsController < ApiController
genres = params[:genres]
unless genres.nil?
genres.each do |genre|
loaded_genre = Genre.find_by_description!(genre)
genres.each do |genre_id|
loaded_genre = Genre.find(genre_id)
@music_session.genres << loaded_genre
end
end
@ -42,6 +42,18 @@ class ApiMusicSessionsController < ApiController
unless @music_session.errors.any?
# auto-join this user into the newly created session
connection_manager.join_music_session(current_user.id, client_id, @music_session.id)
@connection = Connection.find_by_client_id(client_id)
tracks = params[:tracks]
associate_tracks(@connection, tracks)
@connection.save
if @connection.errors.any?
# rollback the transaction to make sure nothing is disturbed in the database
raise ActiveRecord::Rollback
end
else
# rollback the transaction to make sure nothing is disturbed in the database
raise ActiveRecord::Rollback
@ -52,6 +64,10 @@ class ApiMusicSessionsController < ApiController
# we have to do this because api_session_detail_url will fail with a bad @music_session
response.status = :unprocessable_entity
respond_with @music_session
elsif @connection.errors.any?
# we have to do this because api_session_detail_url will fail with a bad @music_session
response.status = :unprocessable_entity
respond_with @connection
else
respond_with @music_session, responder: ApiResponder, :location => api_session_detail_url(@music_session)
end
@ -87,17 +103,18 @@ class ApiMusicSessionsController < ApiController
ConnectionManager.active_record_transaction do |connection_manager|
@music_session = MusicSession.find(params[:id])
client_id = params[:client_id]
connection_manager.join_music_session(current_user.id, client_id, @music_session.id)
@connection = Connection.find_by_client_id(client_id)
tracks = params[:tracks]
associate_tracks(@connection, tracks)
@connection.save
end
# send out notification to queue to the rest of the session
# TODO: also this isn't necessarily a user leaving; it's a client leaving'
user_joined = @message_factory.user_joined_music_session(@music_session.id, current_user.id, current_user.name)
@mq_router.user_publish_to_session(@music_session, current_user, user_joined, sender = {:client_id => @connection.client_id})
@mq_router.server_publish_to_session(@music_session, user_joined, sender = {:client_id => @connection.client_id})
respond_with @connection, responder: ApiResponder, :location => api_session_participant_detail_url(@connection.client_id)
end
@ -126,10 +143,26 @@ class ApiMusicSessionsController < ApiController
unless @music_session.nil?
# send out notification to queue to the rest of the session
# TODO: we should rename the notification to music_session_participants_change or something
user_joined = @message_factory.user_joined_music_session(@music_session.id, current_user.id, current_user.name)
@mq_router.user_publish_to_session(@music_session, current_user, user_joined, sender = {:client_id => @connection.client_id})
# TODO: also this isn't necessarily a user leaving; it's a client leaving'
user_left = @message_factory.user_left_music_session(@music_session.id, current_user.id, current_user.name)
@mq_router.server_publish_to_session(@music_session, user_left, sender = {:client_id => @connection.client_id})
end
respond_with @connection, responder: ApiResponder
end
private
def associate_tracks(connection, tracks)
unless tracks.nil?
tracks.each do |track|
instrument = Instrument.find(track["instrument_id"])
connection_track = ConnectionTrack.new
connection_track.instrument = instrument
connection_track.connection = connection
connection_track.sound = track["sound"]
connection_track.save
connection.connection_tracks << connection_track
end
end
end
end

View File

@ -0,0 +1,3 @@
object @instruments
extends "api_instruments/show"

View File

@ -0,0 +1,3 @@
object @instrument
attributes :id, :description, :popularity

View File

@ -1,3 +1,9 @@
object @connection
attributes :ip_address, :client_id
node(:user_id, :if => lambda { |connection| connection.user.friends?(current_user) }) do |connection|
connection.user_id
end
child(:connection_tracks => :tracks) {
attributes :id, :instrument_id, :sound
}

View File

@ -12,6 +12,9 @@ child(:connections => :participants) {
node(:user_id, :if => lambda { |connection| connection.user.friends?(current_user) }) do |connection|
connection.user_id
end
child(:connection_tracks => :tracks) {
attributes :id, :instrument_id, :sound
}
}
child(:invitations => :invitations) {

View File

@ -80,5 +80,10 @@ SampleApp::Application.routes.draw do
match '/invitations/:id' => 'api_invitations#delete', :via => :delete
match '/invitations' => 'api_invitations#index', :via => :get
match '/invitations' => 'api_invitations#create', :via => :post
# invitations
match '/instruments/:id' => 'api_instruments#show', :via => :get, :as => 'api_instrument_detail'
match '/instruments' => 'api_instruments#index', :via => :get
end
end

View File

@ -0,0 +1,52 @@
require 'spec_helper'
describe "Instruments API ", :type => :api do
include Rack::Test::Methods
describe "profile page" do
let(:user) { FactoryGirl.create(:user) }
before do
post '/sessions', "session[email]" => user.email, "session[password]" => user.password
rack_mock_session.cookie_jar["remember_token"].should == user.remember_token
end
it "list instruments" do
get '/api/instruments.json'
instruments = JSON.parse(last_response.body)
found_high = false
found_mid = false
found_low = false
found_user = false
found_junk = false
instruments.each do |instrument|
if instrument["popularity"] == 3
found_mid.should == false
found_low.should == false
found_high = true
elsif instrument["popularity"] == 2
found_high.should == true
found_low.should == false
found_mid = true
elsif instrument["popularity"] == 1
found_high.should == true
found_mid.should == true
found_low = true
elsif instrument["popularity"] == 0
found_user = true
else
found_junk = true
end
end
found_high.should == true
found_mid.should == true
found_low.should == true
found_user.should == false
found_junk.should == false
end
end
end

View File

@ -26,11 +26,8 @@ describe "Music Session API ", :type => :api do
end
it "should create session" do
# create the session
# create a client connection
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1", :client_id => "1")
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :genres => ["Classical"], :musician_access => true}.to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :genres => ["classical"], :musician_access => true, :tracks => [{"instrument_id" => "electric guitar", "sound" => "mono"}]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
# now fetch it's data
@ -38,13 +35,19 @@ describe "Music Session API ", :type => :api do
music_session = JSON.parse(last_response.body)
get '/api/sessions.json'
list = JSON.parse(last_response.body)
list[0]["id"].should == music_session["id"]
list[0]["musician_access"].should == true
list[0]["invitations"].should == []
list[0]["participants"].length.should == 1
list[0]["participants"][0].should == {"ip_address" => "1.1.1.1", "client_id" => "1"}
music_sessions = JSON.parse(last_response.body)
music_session = music_sessions[0]
music_session["id"].should == music_session["id"]
music_session["musician_access"].should == true
music_session["invitations"].should == []
music_session["participants"].length.should == 1
participant = music_session["participants"][0]
participant["ip_address"].should == client.ip_address
participant["client_id"].should == client.client_id
participant["tracks"].length.should == 1
track = participant["tracks"][0]
track["instrument_id"].should == "electric guitar"
track["sound"].should == "mono"
end
@ -55,8 +58,8 @@ describe "Music Session API ", :type => :api do
list.length.should == 0
# create the session
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1", :client_id => "2")
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :genres => ["Classical"], :musician_access => true}.to_json, "CONTENT_TYPE" => 'application/json'
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :genres => ["classical"], :musician_access => true, :tracks => [{"instrument_id" => "electric guitar", "sound" => "mono"}]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
# now fetch it's data
@ -78,14 +81,13 @@ 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", :client_id => "3")
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :genres => ["Classical"], :musician_access => true}.to_json, "CONTENT_TYPE" => 'application/json'
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :genres => ["classical"], :musician_access => true, :tracks => [{"instrument_id" => "electric guitar", "sound" => "mono"}]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
# now fetch it's data
get last_response.headers["Location"] + ".json", "CONTENT_TYPE" => 'application/json'
music_session = JSON.parse(last_response.body)
# and the creator should be in the session
@ -93,10 +95,10 @@ describe "Music Session API ", :type => :api do
musician = music_session["participants"][0]
# and that musician should have the same IP address
musician["ip_address"].should == "1.1.1.1"
musician["ip_address"].should == client.ip_address
# and that musician should have the correct IP address
musician["client_id"].should == "3"
musician["client_id"].should == client.client_id
# now delete that musician
delete "/api/participants/#{musician["client_id"]}.json", '', "CONTENT_TYPE" => 'application/json'
@ -106,27 +108,121 @@ describe "Music Session API ", :type => :api do
# we auto-delete sessions when the last person leaves
get "/api/sessions/#{music_session["id"]}.json"
last_response.status.should eql(404)
end
it "should error with no genre specified" do
# create the session
original_count = MusicSession.all().length
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1", :client_id => "3")
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :musician_access => true}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(422)
MusicSession.all().length.should == original_count
it "should add a second member to the second" 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', { :description => "a session", :client_id => client.client_id, :genres => ["classical"], :musician_access => true, :tracks => [{"instrument_id" => "electric guitar", "sound" => "mono"}]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
end
# now fetch it's data
music_session_uri = last_response.headers["Location"]
get music_session_uri + ".json", "CONTENT_TYPE" => 'application/json'
it "should error with invalid genre specified" do
# create the session
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1", :client_id => "3")
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :genres => ["Junk"], :musician_access => true}.to_json, "CONTENT_TYPE" => 'application/json'
music_session = JSON.parse(last_response.body)
# and the creator should be in the session
music_session["participants"].length.should == 1
musician = music_session["participants"][0]
# and should have tracks
musician["tracks"].length.should == 1
musician["tracks"][0]["instrument_id"].should == 'electric guitar'
musician["tracks"][0]["sound"].should == 'mono'
musician["ip_address"].should == client.ip_address
musician["client_id"].should == client.client_id
login(user2)
post "/api/sessions/#{music_session["id"]}/participants.json", { :client_id => client2.client_id, :tracks => [{"instrument_id" => "bass guitar", "sound" => "mono"}]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
# now fetch it's data
get last_response.headers["Location"] + ".json", "CONTENT_TYPE" => 'application/json'
participant = JSON.parse(last_response.body)
# and the creator should be in the session
# and should have tracks
participant["tracks"].length.should == 1
participant["tracks"][0]["instrument_id"].should == 'bass guitar'
participant["tracks"][0]["sound"].should == 'mono'
participant["ip_address"].should == client2.ip_address
participant["client_id"].should == client2.client_id
# refetch the session and make sure both participnats are accounted for
get music_session_uri + ".json", "CONTENT_TYPE" => 'application/json'
music_session = JSON.parse(last_response.body)
# and the creator should be in the session
music_session["participants"].length.should == 2
login(user)
delete "/api/participants/#{client.client_id}.json", '', "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(204)
login(user2)
delete "/api/participants/#{client2.client_id}.json", '', "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(204)
# re-fetch the session now that there is not a musician;
# we auto-delete sessions when the last person leaves
get "/api/sessions/#{music_session["id"]}.json"
last_response.status.should eql(404)
end
it "should error with no genre specified" do
# create the session
original_count = MusicSession.all().length
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :musician_access => true, :tracks => [{"instrument_id" => "electric guitar", "sound" => "mono"}]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(422)
MusicSession.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', { :description => "a session", :client_id => client.client_id, :genres => ["Junk"], :musician_access => true, :tracks => [{"instrument_id" => "electric guitar", "sound" => "mono"}]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(404)
end
it "should error with no track specified" do
original_count = MusicSession.all().length
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :musician_access => true, :genres => ["classical"]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(422)
JSON.parse(last_response.body)["errors"]["genres"][0].should == Connection::SELECT_AT_LEAST_ONE
# check that the transaction was rolled back
MusicSession.all().length.should == original_count
end
it "should error with invalid track specified" do
original_count = MusicSession.all().length
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :genres => ["classical"], :musician_access => true, :tracks => [{"instrument_id" => "mom", "sound" => "mono"}]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(404)
# check that the transaction was rolled back
MusicSession.all().length.should == original_count
end
it "should error with invalid sound specified" do
original_count = MusicSession.all().length
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :genres => ["classical"], :musician_access => true, :tracks => [{"instrument_id" => "electric guitar", "sound" => "mom"}]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(422)
JSON.parse(last_response.body)["errors"]["connection_tracks"][0].should == "is invalid"
# check that the transaction was rolled back
MusicSession.all().length.should == original_count
end
@ -134,9 +230,9 @@ describe "Music Session API ", :type => :api do
# create the session
user2 = FactoryGirl.create(:user) # in the music session
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1", :client_id => "6")
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :genres => ["Classical"], :musician_access => false}.to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :genres => ["classical"], :musician_access => false, :tracks => [{"instrument_id" => "electric guitar", "sound" => "mono"}]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
session = JSON.parse(last_response.body)
@ -146,42 +242,52 @@ describe "Music Session API ", :type => :api do
login(user2)
get '/api/sessions.json'
last_response.status.should eql(200)
list = JSON.parse(last_response.body)
music_sessions = JSON.parse(last_response.body)
music_session = music_sessions[0]
list[0]["id"].should == session["id"]
list[0]["musician_access"].should == false
list[0]["invitations"].should == []
list[0]["participants"].length.should == 1
list[0]["participants"][0].should == {"ip_address" => "1.1.1.1", "client_id" => "6", "user_id" => user.id}
music_session["id"].should == session["id"]
music_session["musician_access"].should == false
music_session["invitations"].should == []
music_session["participants"].length.should == 1
participant = music_session["participants"][0]
participant["ip_address"].should == client.ip_address
participant["client_id"].should == client.client_id
participant["user_id"].should == user.id
end
it "can see invitation_id associatied with hidden session" do
# create the session
user2 = FactoryGirl.create(:user) # in the music session
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1", :client_id => "7")
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1")
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :genres => ["Classical"], :musician_access => false}.to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :genres => ["classical"], :musician_access => false, :tracks => [{"instrument_id" => "electric guitar", "sound" => "mono"}]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
session = JSON.parse(last_response.body)
FactoryGirl.create(:friendship, :user => user, :friend => user2)
FactoryGirl.create(:friendship, :user => user2, :friend => user)
invitation = FactoryGirl.create(:invitation, :sender => user, :receiver => user2, :music_session_id => session["id"] )
invitation_model = FactoryGirl.create(:invitation, :sender => user, :receiver => user2, :music_session_id => session["id"] )
login(user2)
get '/api/sessions.json'
last_response.status.should eql(200)
list = JSON.parse(last_response.body)
music_sessions = JSON.parse(last_response.body)
music_session = music_sessions[0]
music_session["id"].should == session["id"]
music_session["musician_access"].should == false
# we should be able to see the invitation
music_session["invitations"].length.should == 1
invitation = music_session["invitations"][0]
invitation["id"].should == invitation_model.id
music_session["participants"].length.should == 1
participant = music_session["participants"][0]
participant["client_id"].should == client.client_id
list[0]["id"].should == session["id"]
list[0]["musician_access"].should == false
list[0]["invitations"].length.should == 1
list[0]["invitations"][0]["id"].should == invitation.id
list[0]["participants"].length.should == 1
list[0]["participants"][0].should == {"ip_address" => "1.1.1.1", "client_id" => "7", "user_id" => user.id}
# and see the user_id because they are friends
participant["user_id"].should == user.id
end
@ -193,7 +299,7 @@ describe "Music Session API ", :type => :api do
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1", :client_id => "3")
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :genres => ["Classical"], :musician_access => false}.to_json, "CONTENT_TYPE" => 'application/json'
post '/api/sessions.json', { :description => "a session", :client_id => client.client_id, :genres => ["classical"], :musician_access => false, :tracks => [{"instrument_id" => "electric guitar", "sound" => "mono"}]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
session = JSON.parse(last_response.body)