jam-cloud/web/spec/requests/music_sessions_api_spec.rb

600 lines
27 KiB
Ruby
Executable File

require 'spec_helper'
describe "Music Session API ", :type => :api do
include Rack::Test::Methods
subject { page }
def login(user)
post '/sessions', "session[email]" => user.email, "session[password]" => user.password
rack_mock_session.cookie_jar["remember_token"].should == user.remember_token
end
def make_friends(user1, user2)
Friendship.save(user1, user2)
end
describe "profile page" do
let(:user) { FactoryGirl.create(:user) }
# defopts are used to setup default options for the session
let(:defopts) { { :description => "a session", :fan_chat => true, :fan_access => true, :approval_required => false, :genres => ["classical"], :musician_access => true, :tracks => [{"instrument_id" => "electric guitar", "sound" => "mono"}], :legal_terms => true, :intellectual_property => true} }
before do
#sign_in user
MusicSession.delete_all
login(user)
end
it "should list no sessions" do
get '/api/sessions.json'
last_response.body.should eql('[]')
end
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'
last_response.status.should eql(201)
# now fetch it's data
location_header = last_response.headers["Location"]
get location_header
music_session = JSON.parse(last_response.body)
get '/api/sessions.json'
music_sessions = JSON.parse(last_response.body)
music_session = music_sessions[0]
music_session["id"].should == music_sessions[0]["id"]
music_session["musician_access"].should be_true
music_session["invitations"].should == []
music_session["join_requests"].should == []
music_session["approval_required"].should be_false
music_session["fan_chat"].should be_true
music_session["fan_access"].should be_true
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"
# test session settings
get '/api/users/' + user.id + '/session_settings.json'
session_settings = JSON.parse(last_response.body)
session_settings["musician_access"].should be_true
session_settings["approval_required"].should be_false
session_settings["fan_chat"].should be_true
session_settings["fan_access"].should be_true
# test session history
get '/api/users/' + user.id + '/session_history.json'
last_response.status.should == 200
session_history = JSON.parse(last_response.body)
session_history[0]["user_id"].to_s.should == user.id
session_history[0]["band_id"].should == music_session["band_id"]
session_history[0]["description"].should == music_session["description"]
get '/api/users/' + user.id + '/session_history/' + music_session["id"] + '/users.json'
# test Track-specific APIs
get "/api/sessions/#{music_session["id"]}/tracks.json", "CONTENT_TYPE" => 'application/json'
last_response.status.should == 200
tracks = JSON.parse(last_response.body)
tracks.size.should == 1
tracks[0]["instrument_id"].should == "electric guitar"
tracks[0]["sound"].should == "mono"
# change instrument
post "/api/sessions/#{music_session["id"]}/tracks/#{tracks[0]["id"]}.json", { :instrument_id => "drums" }.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should == 200
# get individual track
get "/api/sessions/#{music_session["id"]}/tracks/#{tracks[0]["id"]}.json", "CONTENT_TYPE" => 'application/json'
last_response.status.should == 200
updated_track = JSON.parse(last_response.body)
updated_track["instrument_id"].should == "drums"
updated_track["sound"].should == "mono"
# change sound
post "/api/sessions/#{music_session["id"]}/tracks/#{tracks[0]["id"]}.json", { :sound => "stereo" }.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should == 200
# get individual track
get "/api/sessions/#{music_session["id"]}/tracks/#{tracks[0]["id"]}.json", "CONTENT_TYPE" => 'application/json'
last_response.status.should == 200
updated_track = JSON.parse(last_response.body)
updated_track["instrument_id"].should == "drums"
updated_track["sound"].should == "stereo"
# create a 2nd track for this session
conn_id = updated_track["connection_id"]
post "/api/sessions/#{music_session["id"]}/tracks.json", { :connection_id => "#{conn_id}", :instrument_id => "electric guitar", :sound => "mono" }.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should == 201
get "/api/sessions/#{music_session["id"]}/tracks.json", "CONTENT_TYPE" => 'application/json'
last_response.status.should == 200
tracks = JSON.parse(last_response.body)
tracks.size.should == 2
# invalid track ID
get "/api/sessions/#{music_session["id"]}/tracks/1234.json", "CONTENT_TYPE" => 'application/json'
last_response.status.should == 404
# delete track
delete "/api/sessions/#{music_session["id"]}/tracks/#{tracks[0]["id"]}.json"
last_response.status.should == 204
# get tracks again
get "/api/sessions/#{music_session["id"]}/tracks.json", "CONTENT_TYPE" => 'application/json'
last_response.status.should == 200
tracks = JSON.parse(last_response.body)
tracks.size.should == 1
end
describe "update music session properties" do
let(:user) { FactoryGirl.create(:user) }
let(:music_session) { music_session = FactoryGirl.create(:music_session, :creator => user, :description => "My Session") }
let(:client) { FactoryGirl.create(:connection, :user => user) }
it "successful" do
put "/api/sessions/#{music_session.id}.json", {:description => "you!", :musician_access => false, :fan_chat => false, :fan_access => false, :approval_required => true}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(204)
get "/api/sessions/#{music_session.id}.json", "CONTENT_TYPE" => 'application/json'
updated_session = JSON.parse(last_response.body)
updated_session["description"].should == "you!"
updated_session["musician_access"].should be_false
updated_session["fan_chat"].should be_false
updated_session["fan_access"].should be_false
updated_session["approval_required"].should be_true
end
it "string boolean value" do
put "/api/sessions/#{music_session.id}.json", {:musician_access => "false"}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(204)
get "/api/sessions/#{music_session.id}.json", "CONTENT_TYPE" => 'application/json'
updated_session = JSON.parse(last_response.body)
updated_session["musician_access"].should be_false
end
it "empty description not allowed" do
put "/api/sessions/#{music_session.id}.json", {:description => ""}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(422)
end
it "updated genres" do
put "/api/sessions/#{music_session.id}.json", {:genres => ["jazz"]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(204)
get "/api/sessions/#{music_session.id}.json", "CONTENT_TYPE" => 'application/json'
updated_session = JSON.parse(last_response.body)
updated_session["genres"].should == ["Jazz"]
end
end
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'
last_response.status.should eql(201)
# now fetch it's data
location_header = last_response.headers["Location"]
get location_header + ".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 that musician should have the same IP address
musician["ip_address"].should == client.ip_address
# and that musician should have the correct IP address
musician["client_id"].should == client.client_id
# now delete that musician
delete "/api/participants/#{musician["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 add a second member to the session" 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'
last_response.status.should eql(201)
# now fetch it's data
music_session_uri = last_response.headers["Location"]
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 == 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, :as_musician => true, :tracks => [{"instrument_id" => "bass guitar", "sound" => "mono"}]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
# now fetch it's data
location_header = last_response.headers["Location"]
login(user2)
get location_header + ".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
login(user2)
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
login(user2)
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', defopts.merge({:client_id => client.client_id, :genres => nil}).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', defopts.merge({ :client_id => client.client_id, :genres => ["Junk"]}).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', 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"]["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', defopts.merge({:client_id => client.client_id, :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', defopts.merge({:client_id => client.client_id, :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"]["tracks"][0].should == "is invalid"
# check that the transaction was rolled back
MusicSession.all().length.should == original_count
end
it "can see user_id of friend in session" do
pending
# create the session
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'
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)
login(user2)
get '/api/sessions.json'
last_response.status.should eql(200)
music_sessions = JSON.parse(last_response.body)
music_session = music_sessions[0]
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")
post '/api/sessions.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)
FactoryGirl.create(:friendship, :user => user, :friend => user2)
FactoryGirl.create(:friendship, :user => user2, :friend => user)
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)
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
# and see the user_id because they are friends
participant["user"]["id"].should == user.id
end
it "can't join closed music session with no invitation" 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 => "3")
post '/api/sessions.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)
client2 = FactoryGirl.create(:connection, :user => user2)
FactoryGirl.create(:friendship, :user => user, :friend => user2)
FactoryGirl.create(:friendship, :user => user2, :friend => user)
# users are friends, but no invitation... so we shouldn't be able to join as user 2
login(user2)
post "/api/sessions/#{session["id"]}/participants.json", { :client_id => client2.client_id, :as_musician => true, :tracks => [{"instrument_id" => "bass guitar", "sound" => "mono"}] }.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(422)
join_response = JSON.parse(last_response.body)
join_response["errors"]["musician_access"].should == [Connection::INVITE_REQUIRED]
# but let's make sure if we then invite, that we can then join'
login(user)
post '/api/invitations.json', { :music_session => session["id"], :receiver => user2.id }.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
login(user2)
post "/api/sessions/#{session["id"]}/participants.json", { :client_id => client2.client_id, :as_musician => true, :tracks => [{"instrument_id" => "bass guitar", "sound" => "mono"}] }.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
end
it "join_requests don't show up in session listing" 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'
last_response.status.should eql(201)
location_header = last_response.headers["Location"]
get location_header
music_session = JSON.parse(last_response.body)
get '/api/sessions.json'
music_sessions = JSON.parse(last_response.body)
music_session = music_sessions[0]
music_session["id"].should == music_session["id"]
music_session["join_requests"].should == []
user2 = FactoryGirl.create(:user) # in the music session
login(user2)
# create join request
post '/api/join_requests.json', { :music_session => music_session["id"], :text => "lemme in" }.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should == 201
location_header = last_response.headers["Location"]
login(user2)
get location_header + ".json", "CONTENT_TYPE" => 'application/json'
join_request = JSON.parse(last_response.body)
# now join_requests should still be empty, because we don't share join_requests to people outside the session
login(user2)
get '/api/sessions.json'
music_sessions = JSON.parse(last_response.body)
music_session = music_sessions[0]
music_session["id"].should == music_session["id"]
music_session["join_requests"].should be_nil
login(user)
# but for people in the session, they can see the join_requests!
get '/api/sessions.json'
music_sessions = JSON.parse(last_response.body)
music_session = music_sessions[0]
music_session["id"].should == music_session["id"]
music_session["join_requests"].length.should == 1
music_session["join_requests"][0]["id"].should == join_request["id"]
end
it "should now allow join of approval_required=true 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, :approval_required => true}).to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
# now fetch it's data
location_header = last_response.headers["Location"]
get location_header
music_session = JSON.parse(last_response.body)
# try to add 2nd user to session - should fail because approval is required
user2 = FactoryGirl.create(:user)
client2 = FactoryGirl.create(:connection, :user => user2, :ip_address => "2.2.2.2")
login(user2)
post "/api/sessions/#{music_session["id"]}/participants.json", { :client_id => client2.client_id, :as_musician => true, :tracks => [{"instrument_id" => "bass guitar", "sound" => "mono"}]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(422)
rejected_join_attempt = JSON.parse(last_response.body)
rejected_join_attempt["errors"]["approval_required"] = [Connection::INVITE_REQUIRED]
# now send up a join_request to try and get in
login(user2)
post '/api/join_requests.json', { :music_session => music_session["id"], :text => "lemme in" }.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should == 201
location_header = last_response.headers["Location"]
login(user2)
get location_header + ".json", "CONTENT_TYPE" => 'application/json'
join_request = JSON.parse(last_response.body)
# pop back to user1 and allow user2 to get in
login(user)
post '/api/invitations.json', {:music_session => music_session["id"], :receiver => user2.id, :join_request => join_request["id"]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
# finally, go back to user2 and attempt to join again
login(user2)
post "/api/sessions/#{music_session["id"]}/participants.json", { :client_id => client2.client_id, :as_musician => true, :tracks => [{"instrument_id" => "bass guitar", "sound" => "mono"}]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
end
it "should allow create session and join session for creator" do
# this test was created to stop duplication of tracks
# but ultimately it should be fine to create a session, and then 'join' it with no ill effects
# https://jamkazam.atlassian.net/browse/VRFS-254
client = FactoryGirl.create(:connection, :user => user)
post '/api/sessions.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
location_header = last_response.headers["Location"]
get location_header
music_session = JSON.parse(last_response.body)
get "/api/sessions/#{music_session["id"]}.json"
last_response.status.should eql(200)
music_session["participants"].length.should == 1
participant = music_session["participants"][0]
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"
post "/api/sessions/#{music_session["id"]}/participants.json", { :client_id => client.client_id, :as_musician => true, :tracks => [{"instrument_id" => "electric guitar", "sound" => "mono"}]}.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should eql(201)
get "/api/sessions/#{music_session["id"]}.json"
music_session = JSON.parse(last_response.body)
music_session["participants"].length.should == 1
participant = music_session["participants"][0]
participant["client_id"].should == client.client_id
participant["tracks"].length.should == 1 # there should only be one track, still
track = participant["tracks"][0]
track["instrument_id"].should == "electric guitar"
track["sound"].should == "mono"
end
end
it "Finds a single open session" do
creator = FactoryGirl.create(:user)
session = FactoryGirl.create(:music_session, :creator => creator, :description => "My Session")
client = FactoryGirl.create(:connection, :user => creator, :music_session => session)
user = FactoryGirl.create(:user)
login(user)
get '/api/sessions', "CONTENT_TYPE" => "application/json"
last_response.status.should == 200
sessions = JSON.parse(last_response.body)
sessions.length.should == 1
sessions.first["description"].should == "My Session"
end
it "prepare for perf data upload" do
user = FactoryGirl.create(:user)
client = FactoryGirl.create(:connection, :user => user)
music_session = FactoryGirl.create(:music_session, :creator => user, :description => "My Session")
msuh = FactoryGirl.create(:music_session_user_history, :music_session_id => music_session.id, :client_id => client.client_id, :user_id => user.id)
put "/api/sessions/#{music_session.id}/perf.json?client_id=#{client.client_id}", "CONTENT_TYPE" => "application/json"
last_response.status.should == 302
redirect = last_response.headers["Location"]
put redirect + '.json', "CONTENT_TYPE" => 'application/json'
last_response.status.should == 200
body = JSON.parse(last_response.body)
perf_data_id = body["id"]
music_session_perf_data = MusicSessionPerfData.find(perf_data_id)
music_session_perf_data.should_not be_nil
music_session_perf_data.music_session_user_history.should == MusicSessionUserHistory.find_by_client_id(client.client_id)
end
end