require 'spec_helper' describe ApiMusicSessionsController, type: :controller do render_views let(:tracks) { [{'sound' => 'mono', 'client_track_id' => 'abc', 'instrument_id' => 'piano'}] } let(:user) { FactoryGirl.create(:user, last_jam_locidispid: 1) } let(:conn) { FactoryGirl.create(:connection, :user => user, ip_address: '1.1.1.1', locidispid:1, addr:1) } let(:other) { FactoryGirl.create(:user, last_jam_locidispid: 2) } let(:other_conn) { FactoryGirl.create(:connection, user: other, ip_address: '2.2.2.2', locidispid:2, addr:2) } let(:third_user) { FactoryGirl.create(:user) } let(:network_score) { 20 } before(:each) do controller.current_user = user ActiveMusicSession.delete_all MusicSession.delete_all Score.delete_all Score.connection.execute('delete from current_network_scores').check end describe "ams_index" do it "no results" do get :ams_index, {client_id: conn.client_id} response.should be_success json = JSON.parse(response.body, :symbolize_names => true) json[:sessions].length.should == 0 end it "just self" do # create a session with self in it ams = FactoryGirl.create(:active_music_session, creator: user) conn.join_the_session(ams.music_session, true, tracks, user, 10) conn.errors.any?.should be false get :ams_index, {client_id: conn.client_id} json = JSON.parse(response.body, :symbolize_names => true) json[:sessions].length.should == 1 json[:sessions][0][:active_music_session][:participants][0][:user][:full_score].should be_nil end it "someone else with no score with self" do #pending "this test works by itself or only others in the same spec but fails when run with some other tests from other specs" # create a session with someone else in it, but no score ams = FactoryGirl.create(:active_music_session, creator: other) other_conn.join_the_session(ams.music_session, true, tracks, user, 10) other_conn.errors.any?.should be false get :ams_index, {client_id: conn.client_id} json = JSON.parse(response.body, :symbolize_names => true) json[:sessions].length.should == 1 json[:sessions][0][:active_music_session][:participants][0][:user][:full_score].should be_nil end it "someone else with a score with a self" do # create a session with someone else in it, but no score ams = FactoryGirl.create(:active_music_session, creator: other) other_conn.join_the_session(ams.music_session, true, tracks, other, 10) other_conn.errors.any?.should be false Score.createx(conn.locidispid, conn.client_id, conn.addr, other_conn.locidispid, other_conn.client_id, other_conn.addr, network_score, nil, nil, {auserid: user.id, buserid: other.id}) get :ams_index, {client_id: conn.client_id} json = JSON.parse(response.body, :symbolize_names => true) json[:sessions].length.should == 1 json[:sessions][0][:active_music_session][:participants] json[:sessions][0][:active_music_session][:participants][0][:user][:full_score].should == 35 # 5 + 20 + 10 end it "someone else with a score with a self, and another with an approved RSVP" do # create a session with someone else in it, but no score ams = FactoryGirl.create(:active_music_session, creator: other) other_conn.join_the_session(ams.music_session, true, tracks, other, 10) other_conn.errors.any?.should be false # we need to make sure that third_user, (the RSVP user) has a locidispid matching the searching user third_user.last_jam_audio_latency = 10 # RSVP's are an 'offline' search, meaning they use user.last_jam_audio_latency instead of connection.last_jam_audio_latency third_user.last_jam_locidispid = conn.locidispid third_user.save! Score.createx(conn.locidispid, conn.client_id, conn.addr, other_conn.locidispid, other_conn.client_id, other_conn.addr, network_score, nil, nil, {auserid: user.id, buserid: other.id}) # set up a second RSVP (other than the creators, pointing to the third_user) rsvp_slot = FactoryGirl.create(:rsvp_slot, music_session: ams.music_session, instrument: Instrument.find('piano')) rsvp_request = FactoryGirl.create(:rsvp_request, user: third_user) rsvp_request_rsvp_slot = FactoryGirl.create(:rsvp_request_rsvp_slot, chosen:true, rsvp_request: rsvp_request, rsvp_slot:rsvp_slot) get :ams_index, {client_id: conn.client_id} json = JSON.parse(response.body, :symbolize_names => true) json[:sessions].length.should == 1 json[:sessions][0][:active_music_session][:participants][0][:user][:full_score].should_not be_nil json[:sessions][0][:approved_rsvps].length.should == 2 if json[:sessions][0][:approved_rsvps][0][:id] == third_user.id found_third_user = json[:sessions][0][:approved_rsvps][0] found_creator = json[:sessions][0][:approved_rsvps][1] found_creator[:id].should == other.id else found_third_user = json[:sessions][0][:approved_rsvps][1] found_creator = json[:sessions][0][:approved_rsvps][0] found_third_user[:id].should == third_user.id found_creator[:id].should == other.id end found_third_user[:full_score].should == nil found_creator[:full_score].should == ((network_score + user.last_jam_audio_latency + other.last_jam_audio_latency )).ceil end end describe "sms_index" do xit "no results" do get :sms_index, {client_id: conn.client_id} response.should be_success json = JSON.parse(response.body, :symbolize_names => true) json[:sessions].length.should == 0 end xit "just self" do # create a session with self in it sms = FactoryGirl.create(:music_session, creator: user) get :sms_index, {client_id: conn.client_id} json = JSON.parse(response.body, :symbolize_names => true) json[:sessions].length.should == 1 json[:sessions][0][:approved_rsvps][0][:id].should == user.id json[:sessions][0][:approved_rsvps][0][:full_score].should be_nil # you don't get scores to self end xit "someone else with no score with self" do #pending "this test works by itself or only others in the same spec but fails when run with some other tests from other specs" # create a session with someone else in it, but no score sms = FactoryGirl.create(:music_session, creator: other) get :sms_index, {client_id: conn.client_id} json = JSON.parse(response.body, :symbolize_names => true) json[:sessions].length.should == 1 json[:sessions][0][:approved_rsvps][0][:id].should == other.id json[:sessions][0][:approved_rsvps][0][:full_score].should be_nil # there is no score with 'other ' end xit "scores with invitees and RSVP's" do # create a session with someone else in it, but no score sms = FactoryGirl.create(:music_session, creator: other) Score.createx(conn.locidispid, conn.client_id, conn.addr, other_conn.locidispid, other_conn.client_id, other_conn.addr, network_score, nil, nil, {auserid: user.id, buserid: other.id}) invitee = FactoryGirl.create(:user, last_jam_audio_latency: 30, last_jam_locidispid: 3) FactoryGirl.create(:friendship, user: other, friend: invitee) FactoryGirl.create(:friendship, user: invitee, friend: other) FactoryGirl.create(:invitation, sender:other, receiver:invitee, music_session: sms) Score.createx(invitee.last_jam_locidispid, 'immaterial', 1, conn.locidispid, conn.client_id, conn.addr, network_score, nil, nil, {auserid: invitee.id, buserid: user.id}) get :sms_index, {client_id: conn.client_id} json = JSON.parse(response.body, :symbolize_names => true) json[:sessions].length.should == 1 json[:sessions][0][:approved_rsvps][0][:id].should == other.id json[:sessions][0][:approved_rsvps][0][:full_score].should == ((network_score + user.last_jam_audio_latency + other.last_jam_audio_latency)).ceil json[:sessions][0][:invitations][0][:receiver_id].should == invitee.id json[:sessions][0][:invitations][0][:full_score].should == nil end end describe "open_jam_track" do let(:ams) { FactoryGirl.create(:active_music_session, creator: user) } let(:jam_track) { FactoryGirl.create(:jam_track)} it "does not allow someone to open a track unless they are in the session" do post :jam_track_open, {:format => 'json', id: ams.id, jam_track_id: jam_track.id} response.status.should == 403 end it "does not allow someone to open a track unless they own the jam track" do conn.join_the_session(ams.music_session, true, tracks, user, 10) post :jam_track_open, {:format => 'json', id: ams.id, jam_track_id: jam_track.id} response.status.should == 403 end it "allows someone who owns the jam track to open it" do # put the connection of the user into the session, so th conn.join_the_session(ams.music_session, true, tracks, user, 10) FactoryGirl.create(:jam_track_right, jam_track: jam_track, user: user) post :jam_track_open, {:format => 'json', id: ams.id, jam_track_id: jam_track.id} response.status.should == 200 end it "does not allow someone to close a track unless they are in the session" do post :jam_track_close, {:format => 'json', id: ams.id} response.status.should == 403 end it "allows the jam track to be closed" do # put the connection of the user into the session, so th conn.join_the_session(ams.music_session, true, tracks, user, 10) FactoryGirl.create(:jam_track_right, jam_track: jam_track, user: user) post :jam_track_open, {:format => 'json', id: ams.id, jam_track_id: jam_track.id} response.status.should == 200 post :jam_track_close, {:format => 'json', id: ams.id} response.status.should == 200 end it "show.rabl shows jam track info when open" do conn.join_the_session(ams.music_session, true, tracks, user, 10) FactoryGirl.create(:jam_track_right, jam_track: jam_track, user: user) post :jam_track_open, {:format => 'json', id: ams.id, jam_track_id: jam_track.id} # check the show.rabl for jam_track info get :show, {:format => 'json', id: ams.id} json = JSON.parse(response.body, :symbolize_names => true) json[:jam_track].should_not be_nil json[:jam_track][:id].should == jam_track.id end end describe "open_backing_track" do let(:ams) { FactoryGirl.create(:active_music_session, creator: user) } let(:backing_track) { "foo.mp3"} it "does not allow someone to open a track unless they are in the session" do post :backing_track_open, {:format => 'json', id: ams.id, backing_track_path: backing_track} response.status.should == 403 end it "does not allow someone to open a track unless they own the backing track" do pending "connection with client to determine ownership" conn.join_the_session(ams.music_session, true, tracks, user, 10) post :backing_track_open, {:format => 'json', id: ams.id, backing_track_path: backing_track} response.status.should == 403 end it "allows someone who owns the backing track to open it" do # put the connection of the user into the session, so th conn.join_the_session(ams.music_session, true, tracks, user, 10) post :backing_track_open, {:format => 'json', id: ams.id, backing_track_path: backing_track} response.status.should == 200 end it "does not allow someone to close a track unless they are in the session" do post :backing_track_close, {:format => 'json', id: ams.id} response.status.should == 403 end it "allows the backing track to be closed" do # put the connection of the user into the session, so th conn.join_the_session(ams.music_session, true, tracks, user, 10) post :backing_track_open, {:format => 'json', id: ams.id, backing_track_path: backing_track} response.status.should == 200 post :backing_track_close, {:format => 'json', id: ams.id} response.status.should == 200 end end describe "open_metronome" do let(:ams) { FactoryGirl.create(:active_music_session, creator: user) } let(:metronome) { "foo.mp3"} it "does not allow someone to open a track unless they are in the session" do post :metronome_open, {:format => 'json', id: ams.id, metronome_path: metronome} response.status.should == 403 end it "can open it" do conn.join_the_session(ams.music_session, true, tracks, user, 10) post :metronome_open, {:format => 'json', id: ams.id, metronome_path: metronome} response.status.should == 200 end it "does not allow someone to close a metronome" do post :metronome_close, {:format => 'json', id: ams.id} response.status.should == 403 end it "does allow someone who joied to close a metronome" do conn.join_the_session(ams.music_session, true, tracks, user, 10) post :metronome_close, {:format => 'json', id: ams.id} response.status.should == 200 end it "allows the metronome to be closed" do # put the connection of the user into the session, so th conn.join_the_session(ams.music_session, true, tracks, user, 10) post :metronome_open, {:format => 'json', id: ams.id, metronome_path: metronome} response.status.should == 200 post :metronome_close, {:format => 'json', id: ams.id} response.status.should == 200 end end describe "auth" do let(:ams) { FactoryGirl.create(:active_music_session, creator: user) } let(:temp_token) { FactoryGirl.create(:temp_token, user: user) } let(:another_user) { FactoryGirl.create(:user) } before(:each) do conn.join_the_session(ams.music_session, true, tracks, user, 10) conn.errors.any?.should be false end it "routes correctly" do expect(get: "/api/sessions/#{ams.id}/auth?token=#{temp_token.token}&participants=2").to route_to( controller: "api_music_sessions", action: "auth", session_id: ams.id, token: temp_token.token, participants: "2" ) end it "returns 403 for invalid token" do get :auth, session_id: ams.id, token: 'invalid_token', participants: 2 expect(response).to have_http_status(403) expect(response.body).to eq({ code: "invalid_token", message: "No token found for 'invalid_token'" }.to_json) end it "returns 403 if user is not in music session" do ams.users.delete(user) get :auth, session_id: ams.id, token: temp_token.token, participants: 2 expect(response).to have_http_status(403) expect(response.body).to eq({ code: "not_in_session", message: "Not a member of the session" }.to_json) end it "returns 404 if token is valid, but session can't be found" do get :auth, session_id: "bad_session_id", token: temp_token.token, participants: 2 expect(response).to have_http_status(404) expect(response.body).to eq({ code: "session_ended", message: "The session is over" }.to_json) end it "token expired" do TempToken.where(token: temp_token.token).update_all(expired_at: 1.day.ago) get :auth, session_id: ams.id, token: temp_token.token, participants: 2 expect(response).to have_http_status(403) expect(response.body).to eq({ code: "expired_token", message: "The token has expired" }.to_json) end it "returns 200 ok for valid params" do get :auth, session_id: ams.id, token: temp_token.token, participants: 2 expect(response).to have_http_status(200) expect(response.body).to eq({ name: user.name, user_id: user.id }.to_json) end end end