jam-cloud/spec/jam_ruby/models/recording_spec.rb

285 lines
12 KiB
Ruby

require 'spec_helper'
describe Recording do
before do
S3Manager.set_unit_test
@user = FactoryGirl.create(:user)
@connection = FactoryGirl.create(:connection, :user => @user)
@instrument = FactoryGirl.create(:instrument, :description => 'a great instrument')
@track = FactoryGirl.create(:track, :connection => @connection, :instrument => @instrument)
@music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true)
@music_session.connections << @connection
@music_session.save
end
it "should not start a recording if the music session doesnt exist" do
expect { Recording.start("bad_music_session_id", @user) }.to raise_error
end
it "should set up the recording properly when recording is started with 1 user in the session" do
@music_session.recording.should == nil
@recording = Recording.start(@music_session.id, @user)
@music_session.reload
@music_session.recording.should == @recording
@recording.owner_id.should == @user.id
@recorded_tracks = RecordedTrack.where(:recording_id => @recording.id)
@recorded_tracks.length.should == 1
@recorded_tracks.first.instrument_id == @track.instrument_id
@recorded_tracks.first.user_id == @track.connection.user_id
end
it "should not start a recording if the session is already being recorded" do
Recording.start(@music_session.id, @user)
expect { Recording.start(@music_session.id, @user) }.to raise_error
end
it "should return the state to normal properly when you stop a recording" do
@recording = Recording.start(@music_session.id, @user)
@recording.stop
@music_session.reload
@music_session.recording.should == nil
@recording.reload
@recording.music_session.should == nil
end
it "should error when you stop a recording twice" do
@recording = Recording.start(@music_session.id, @user)
@recording.stop
expect { @recording.stop }.to raise_error
end
it "should be able to start, stop then start a recording again for the same music session" do
@recording = Recording.start(@music_session.id, @user)
@recording.stop
@recording2 = Recording.start(@music_session.id, @user)
@music_session.recording.should == @recording2
end
it "should NOT attach the recording to all users in a the music session when recording started" do
@user2 = FactoryGirl.create(:user)
@connection2 = FactoryGirl.create(:connection, :user => @user2)
@instrument2 = FactoryGirl.create(:instrument, :description => 'a great instrument')
@track2 = FactoryGirl.create(:track, :connection => @connection2, :instrument => @instrument2)
@music_session.connections << @connection2
@recording = Recording.start(@music_session.id, @user)
@user.recordings.length.should == 0
#@user.recordings.first.should == @recording
@user2.recordings.length.should == 0
#@user2.recordings.first.should == @recording
end
it "should report correctly whether its tracks have been uploaded" do
@recording = Recording.start(@music_session.id, @user)
@recording.uploaded?.should == false
@recording.stop
@recording.reload
@recording.uploaded?.should == false
@recording.recorded_tracks.first.fully_uploaded = true
@recording.uploaded?.should == true
end
it "should destroy a recording and all its recorded tracks properly" do
@recording = Recording.start(@music_session.id, @user)
@recording.stop
@recording.reload
@recorded_track = @recording.recorded_tracks.first
@recording.destroy
expect { Recording.find(@recording.id) }.to raise_error
expect { RecordedTracks.find(@recorded_track.id) }.to raise_error
end
it "should allow a user to claim a recording" do
@recording = Recording.start(@music_session.id, @user)
@recording.stop
@recording.reload
@genre = FactoryGirl.create(:genre)
@recording.claim(@user, "name", @genre, true, true)
@recording.reload
@recording.users.length.should == 1
@recording.users.first.should == @user
@user.recordings.length.should == 1
@user.recordings.first.should == @recording
@recording.claimed_recordings.length.should == 1
@claimed_recording = @recording.claimed_recordings.first
@claimed_recording.name.should == "name"
@claimed_recording.genre.should == @genre
@claimed_recording.is_public.should == true
@claimed_recording.is_downloadable.should == true
end
it "should fail if a user who was not in the session claims a recording" do
@recording = Recording.start(@music_session.id, @user)
@recording.stop
@recording.reload
user2 = FactoryGirl.create(:user)
expect { @recording.claim(user2) }.to raise_error
end
it "should fail if a user tries to claim a recording twice" do
@recording = Recording.start(@music_session.id, @user)
@recording.stop
@recording.reload
@genre = FactoryGirl.create(:genre)
@recording.claim(@user, "name", @genre, true, true)
@recording.reload
expect { @recording.claim(@user, "name", @genre, true, true) }.to raise_error
end
it "should allow editing metadata for claimed recordings" do
@recording = Recording.start(@music_session.id, @user)
@recording.stop
@recording.reload
@genre = FactoryGirl.create(:genre)
@claimed_recording = @recording.claim(@user, "name", @genre, true, true)
@genre2 = FactoryGirl.create(:genre)
@claimed_recording.update_fields(@user, :name => "name2", :genre => @genre2.id, :is_public => false, :is_downloadable => false)
@claimed_recording.reload
@claimed_recording.name.should == "name2"
@claimed_recording.genre.should == @genre2
@claimed_recording.is_public.should == false
@claimed_recording.is_downloadable.should == false
end
it "should only allow the owner to edit a claimed recording" do
@recording = Recording.start(@music_session.id, @user)
@recording.stop
@recording.reload
@genre = FactoryGirl.create(:genre)
@claimed_recording = @recording.claim(@user, "name", @genre, true, true)
@user2 = FactoryGirl.create(:user)
expect { @claimed_recording.update_fields(@user2, "name2") }.to raise_error
end
it "should record the duration of the recording properly" do
@recording = Recording.start(@music_session.id, @user)
@recording.duration.should be_nil
@recording.stop
@recording.reload
@recording.duration.should_not be_nil
# Note: it will be 0 since this was fast. You can see something non-zero by just
# inserting a sleep here.
# puts @recording.duration
end
it "should only destroy a single claimed_recording if there are more than one" do
@user2 = FactoryGirl.create(:user)
@connection2 = FactoryGirl.create(:connection, :user => @user2)
@track = FactoryGirl.create(:track, :connection => @connection2, :instrument => @instrument)
@music_session.connections << @connection2
@music_session.save
@recording = Recording.start(@music_session.id, @user)
@recording.stop
@recording.reload
@genre = FactoryGirl.create(:genre)
@claimed_recording = @recording.claim(@user, "name", @genre, true, true)
expect { @claimed_recordign.discard(@user2) }.to raise_error
@claimed_recording = @recording.claim(@user2, "name2", @genre, true, true)
@claimed_recording.discard(@user2)
@recording.reload
@recording.claimed_recordings.length.should == 1
end
it "should destroy the entire recording if there was only one claimed_recording which is discarded" do
@recording = Recording.start(@music_session.id, @user)
@recording.stop
@recording.reload
@genre = FactoryGirl.create(:genre)
@claimed_recording = @recording.claim(@user, "name", @genre, true, true)
@claimed_recording.discard(@user)
expect { Recording.find(@recording.id) }.to raise_error
expect { ClaimedRecording.find(@claimed_recording.id) }.to raise_error
end
it "should return a file list for a user properly" do
@recording = Recording.start(@music_session.id, @user)
@recording.stop
@recording.reload
@genre = FactoryGirl.create(:genre)
@recording.claim(@user, "Recording", @genre, true, true)
Recording.list(@user)["downloads"].length.should == 0
Recording.list(@user)["uploads"].length.should == 1
file = Recording.list(@user)["uploads"].first
@recorded_track = @recording.recorded_tracks.first
file.should == @recorded_track.filename
@recorded_track.upload_start(25000, "md5hash")
@recorded_track.upload_complete
Recording.list(@user)["downloads"].length.should == 1
Recording.list(@user)["uploads"].length.should == 0
file = Recording.list(@user)["downloads"].first
file[:type].should == "recorded_track"
file[:id].should == @recorded_track.id
file[:length].should == 25000
file[:md5].should == "md5hash"
file[:url].should == S3Manager.url(S3Manager.hashed_filename('recorded_track', @recorded_track.id))
# Note that the recording should automatically schedule a mix when the upload completes
@recording.mixes.length.should == 1
@mix = Mix.next('server')
@mix.should_not be_nil
@mix.finish(50000, "md5hash")
Recording.list(@user)["downloads"].length.should == 2
Recording.list(@user)["uploads"].length.should == 0
file = Recording.list(@user)["downloads"].last
file[:type].should == "mix"
file[:id].should == @mix.id
file[:length].should == 50000
file[:md5].should == "md5hash"
file[:url].should == S3Manager.url(S3Manager.hashed_filename('mix', @mix.id))
end
it "should create a base mix manifest properly" do
@user2 = FactoryGirl.create(:user)
@connection2 = FactoryGirl.create(:connection, :user => @user)
@instrument2 = FactoryGirl.create(:instrument, :description => 'a great instrument')
@track2 = FactoryGirl.create(:track, :connection => @connection2, :instrument => @instrument2)
@music_session.connections << @connection2
@music_session.save
@recording = Recording.start(@music_session.id, @user)
#sleep 4
@recording.stop
@recording.recorded_tracks.length.should == 2
@recorded_track = @recording.recorded_tracks.first
@recorded_track.upload_start(25000, "md5hash")
@recorded_track.upload_complete
@recorded_track2 = @recording.recorded_tracks.last
@recorded_track2.upload_start(50000, "md5hash2")
@recorded_track2.upload_complete
mix_manifest = @recording.base_mix_manifest
mix_manifest.should_not be_nil
files = mix_manifest["files"]
files.should_not be_nil
files.length.should == 2
files.first["codec"].should == "vorbis"
files.first["offset"].should == 0
files.first["url"].should == @recording.recorded_tracks.first.url
files.last["codec"].should == "vorbis"
files.last["offset"].should == 0
files.last["url"].should == @recording.recorded_tracks.last.url
timeline = mix_manifest["timeline"]
timeline.should_not be_nil
timeline.length.should == 2
timeline.first["timestamp"].should == 0
timeline.first["end"].should be_nil
mix = timeline.first["mix"]
mix.should_not be_nil
mix.length.should == 2
mix.first["balance"].should == 0
mix.first["level"].should == 100
mix.last["balance"].should == 0
mix.last["level"].should == 100
timeline.last["timestamp"].should == @recording.duration
timeline.last["end"].should == true
end
end