require 'spec_helper'

describe ApiRecordingsController, type: :controller do
  render_views

  describe "recording with backing track" do

    before(:each) do
      @user = FactoryGirl.create(:user)
      @instrument = FactoryGirl.create(:instrument, :description => 'a great instrument')
      @music_session = FactoryGirl.create(:active_music_session, :creator => @user, :musician_access => true)
      @connection = FactoryGirl.create(:connection, :user => @user, :music_session => @music_session)
      @track = FactoryGirl.create(:track, :connection => @connection, :instrument => @instrument)
      @backing_track = FactoryGirl.create(:backing_track, :connection => @connection)
      controller.current_user = @user
    end

    describe "start" do
      it "should work" do
        post :start, {:format => 'json', :music_session_id => @music_session.id}
        response.should be_success
        response_body = JSON.parse(response.body)
        response_body['id'].should_not be_nil
        recording = Recording.find(response_body['id'])
      end

      it "should not allow multiple starts" do
        post :start, {:format => 'json', :music_session_id => @music_session.id}
        post :start, {:format => 'json', :music_session_id => @music_session.id}
        response.status.should == 422
        response_body = JSON.parse(response.body)
        response_body["errors"]["music_session"][0].should == ValidationMessages::ALREADY_BEING_RECORDED
      end

      it "should not allow start while playback ongoing" do
        recording = Recording.start(@music_session, @user)
        recording.stop
        recording.reload
        claimed_recording = recording.claim(@user, "name", "description", Genre.first, true)
        @music_session.claimed_recording_start(@user, claimed_recording)
        @music_session.errors.any?.should be false
        post :start, {:format => 'json', :music_session_id => @music_session.id}
        response.status.should == 422
        response_body = JSON.parse(response.body)
        response_body["errors"]["music_session"][0].should == ValidationMessages::ALREADY_PLAYBACK_RECORDING
      end

      it "should not allow start by somebody not in the music session" do
        user2 = FactoryGirl.create(:user)
        controller.current_user = user2
        post :start, {:format => 'json', :music_session_id => @music_session.id}
        response.status.should == 403
      end
    end

    describe "get" do
      it "should work" do
        post :start, {:format => 'json', :music_session_id => @music_session.id}
        response.should be_success
        response_body = JSON.parse(response.body)
        response_body['id'].should_not be_nil
        recordingId = response_body['id']
        get :show, {:format => 'json', :id => recordingId}
        response.should be_success
        response_body = JSON.parse(response.body)
        response_body['id'].should == recordingId
      end

    end

    describe "stop" do
      it "should work" do
        post :start, {:format => 'json', :music_session_id => @music_session.id}
        response_body = JSON.parse(response.body)
        recording = Recording.find(response_body['id'])
        post :stop, {:format => 'json', :id => recording.id}
        response.should be_success
        response_body = JSON.parse(response.body)
        response_body['id'].should_not be_nil
        Recording.find(response_body['id']).id.should == recording.id
      end

      it "should not allow stop on a session not being recorded" do
        post :start, {:format => 'json', :music_session_id => @music_session.id}
        response_body = JSON.parse(response.body)
        recording = Recording.find(response_body['id'])
        post :stop, {:format => 'json', :id => recording.id}
        post :stop, {:format => 'json', :id => recording.id}
        response.status.should == 422
        response_body = JSON.parse(response.body)
      end

      it "should not allow stop on a session requested by a different member" do

        post :start, {:format => 'json', :music_session_id => @music_session.id}
        response_body = JSON.parse(response.body)
        recording = Recording.find(response_body['id'])
        user2 = FactoryGirl.create(:user)
        controller.current_user = user2
        post :stop, {:format => 'json', :id => recording.id}
        response.status.should == 403
      end
    end

    describe "download track" do
      let(:mix) { FactoryGirl.create(:mix) }

      it "should only allow a user to download a track if they have claimed the recording" do
        post :start, {:format => 'json', :music_session_id => @music_session.id}
        response_body = JSON.parse(response.body)
        recording = Recording.find(response_body['id'])
        post :stop, {:format => 'json', :id => recording.id}
        response.should be_success
      end


      it "is possible" do
        mix.touch
        recorded_track = mix.recording.recorded_tracks[0]
        controller.current_user = mix.recording.owner
        get :download, {id: recorded_track.recording.id, track_id: recorded_track.client_track_id}
        response.status.should == 302

        recorded_track.reload
        recorded_track.download_count.should == 1

        get :download, {id: recorded_track.recording.id, track_id: recorded_track.client_track_id}
        response.status.should == 302

        recorded_track.reload
        recorded_track.download_count.should == 2
      end


      it "prevents download after limit is reached" do
        mix.touch
        recorded_track = mix.recording.recorded_tracks[0]
        recorded_track.download_count = APP_CONFIG.max_audio_downloads
        recorded_track.save!
        controller.current_user = recorded_track.user
        get :download, {format: 'json', id: recorded_track.recording.id, track_id: recorded_track.client_track_id}
        response.status.should == 404
        JSON.parse(response.body, symbolize_names: true)[:message].should == "download limit surpassed"
      end


      it "lets admins surpass limit" do
        mix.touch
        recorded_track = mix.recording.recorded_tracks[0]
        recorded_track.download_count = APP_CONFIG.max_audio_downloads
        recorded_track.save!
        recorded_track.user.admin = true
        recorded_track.user.save!

        controller.current_user = recorded_track.user
        get :download, {format: 'json', id: recorded_track.recording.id, track_id: recorded_track.client_track_id}
        response.status.should == 302
        recorded_track.reload
        recorded_track.download_count.should == 101
      end
    end

    describe "download backing track" do
      let(:mix) { FactoryGirl.create(:mix) }

      it "should only allow a user to download a track if they have claimed the recording" do
        post :start, {:format => 'json', :music_session_id => @music_session.id}
        response_body = JSON.parse(response.body)
        recording = Recording.find(response_body['id'])
        post :stop, {:format => 'json', :id => recording.id}
        response.should be_success
      end


      it "is possible" do
        mix.touch
        recorded_track = mix.recording.recorded_tracks[0]
        controller.current_user = mix.recording.owner
        get :download, {id: recorded_track.recording.id, track_id: recorded_track.client_track_id}
        response.status.should == 302

        recorded_track.reload
        recorded_track.download_count.should == 1

        get :download, {id: recorded_track.recording.id, track_id: recorded_track.client_track_id}
        response.status.should == 302

        recorded_track.reload
        recorded_track.download_count.should == 2
      end


      it "prevents download after limit is reached" do
        mix.touch
        recorded_track = mix.recording.recorded_tracks[0]
        recorded_track.download_count = APP_CONFIG.max_audio_downloads
        recorded_track.save!
        controller.current_user = recorded_track.user
        get :download, {format: 'json', id: recorded_track.recording.id, track_id: recorded_track.client_track_id}
        response.status.should == 404
        JSON.parse(response.body, symbolize_names: true)[:message].should == "download limit surpassed"
      end


      it "lets admins surpass limit" do
        mix.touch
        recorded_track = mix.recording.recorded_tracks[0]
        recorded_track.download_count = APP_CONFIG.max_audio_downloads
        recorded_track.save!
        recorded_track.user.admin = true
        recorded_track.user.save!

        controller.current_user = recorded_track.user
        get :download, {format: 'json', id: recorded_track.recording.id, track_id: recorded_track.client_track_id}
        response.status.should == 302
        recorded_track.reload
        recorded_track.download_count.should == 101
      end
    end
  end

  describe "recording with jam track" do

    before(:each) do
      @user = FactoryGirl.create(:user)
      @instrument = FactoryGirl.create(:instrument, :description => 'a great instrument')
      @music_session = FactoryGirl.create(:active_music_session, :creator => @user, :musician_access => true)
      @connection = FactoryGirl.create(:connection, :user => @user, :music_session => @music_session)
      @track = FactoryGirl.create(:track, :connection => @connection, :instrument => @instrument)
      @jam_track = FactoryGirl.create(:jam_track)
      @jam_track.reload

      # make sure the jam track is opened
      @music_session.jam_track = @jam_track
      @music_session.jam_track_initiator = @user
      @music_session.save!
      controller.current_user = @user
    end

    describe "start" do
      it "should work" do
        post :start, {:format => 'json', :music_session_id => @music_session.id}
        response.should be_success
        response_body = JSON.parse(response.body)
        response_body['id'].should_not be_nil
        recording = Recording.find(response_body['id'])
        recorded_jam_track_track = response_body["recorded_jam_track_tracks"][0]
        recorded_jam_track_track["id"].should eq(@jam_track.jam_track_tracks[0].id)
        recorded_jam_track_track["timeline"].should eq([])
      end
    end
  end
end

