require 'spec_helper'

describe PerformanceSample do

  shared_examples_for :performance_sample_specs do
    let(:claimed_recording) { FactoryGirl.create(:claimed_recording) }

    describe "index" do

      before(:all) do
        PerformanceSample.delete_all

        @player1_sample1 = PerformanceSample.new(:player_id => player1.id, :service_type => "jamkazam", :claimed_recording_id => claimed_recording.id)
        @player1_sample1.save!

        @player1_sample2 = PerformanceSample.new(:player_id => player1.id, :service_type => "youtube", :service_id => "12345")
        @player1_sample2.save!

        @player2_sample1 = PerformanceSample.new(:player_id => player2.id, :service_type => "soundcloud", :service_id => "67890")
        @player2_sample1.save!
      end

      context "when request is valid" do
        it "should return all records for user" do
          sample = PerformanceSample.index({:id => player1.id})
          sample.count.should == 2

          sample = PerformanceSample.index({:id => player2.id})
          sample.count.should == 1
        end
      end

      context "when request is invalid" do
        it "should raise error when options are missing" do
          lambda{PerformanceSample.index}.should raise_error(JamArgumentError)
        end

        it "should raise error when user id is missing" do
          lambda{PerformanceSample.index({:id => ""})}.should raise_error(JamArgumentError)
        end
      end
    end

    describe "create" do

      before(:all) do
        PerformanceSample.delete_all
      end

      context "when request is valid" do
        it "should save successfully" do
          PerformanceSample.create(player1, {:player_id => player1.id, :service_type => "youtube", :service_id => "12345"})

          # make sure we can save a second PerformanceSample for same user and type
          PerformanceSample.create(player1, {:player_id => player1.id, :service_type => "youtube", :service_id => "67890"})
        end
      end

      context "when request is not valid" do
        it "should raise JamPermissionError if requester id does not match id in request" do
          lambda{PerformanceSample.create(player1, {:player_id => player2.id, :service_type => "soundcloud", :service_id => "12345"})}.should raise_error(JamPermissionError)
        end

        it "should raise error if service type is missing" do
          lambda{PerformanceSample.create(player1, {:player_id => player1.id, :service_id => "12345"})}.should raise_error(StateError)
        end

        it "should raise error if service id is missing for non-JamKazam sample" do
          lambda{PerformanceSample.create(player1, {:player_id => player1.id, :service_type => "youtube"})}.should raise_error(StateError)
        end

        it "should raise error if recording id is missing for JamKazam sample" do
          lambda{PerformanceSample.create(player1, {:player_id => player1.id, :service_type => "jamkazam"})}.should raise_error(StateError)
        end

        it "should not allow duplicate type/service id combination for non-JamKazam sample" do
          PerformanceSample.create(player1, {:player_id => player1.id, :service_type => "youtube", :service_id => "12345"})
          lambda{PerformanceSample.create(player1, {:player_id => player1.id, :service_type => "youtube", :service_id => "12345"})}.should raise_error(ConflictError)
        end

        it "should not allow duplicate type/recording id combination for JamKazam sample" do
          PerformanceSample.create(player1, {:player_id => player1.id, :service_type => "jamkazam", :claimed_recording_id => claimed_recording.id})
          lambda{PerformanceSample.create(player1, {:player_id => player1.id, :service_type => "jamkazam", :claimed_recording_id => claimed_recording.id})}.should raise_error(ConflictError)
        end
      end
    end


    describe "destroy" do

      before(:all) do
        PerformanceSample.delete_all
        @user_sample = PerformanceSample.new(:player_id => player1.id, :service_type => "soundcloud", :service_id => "12345")
        @user_sample.save!
      end

      context "when request is valid" do
        it "should destroy successfully" do
          ps_list = PerformanceSample.index({:id => player1.id})
          ps_list.count.should == 1
          ps_list.first.service_type.should == "soundcloud"
          ps_list.first.service_id.should == "12345"

          PerformanceSample.delete(player1, {:player_id => player1.id, :id => @user_sample.id})

          ps_list = PerformanceSample.index({:id => player1.id})
          ps_list.count.should == 0
        end
      end

      context "when request is not valid" do
        it "should raise JamPermissionError if requester id does not match id in request" do
          lambda{PerformanceSample.delete(player2, {:player_id => player1.id, :id => @user_sample.id})}.should raise_error(JamPermissionError)
        end

        it "should raise error if user sample id is missing" do
          lambda{PerformanceSample.delete(player1, {:player_id => player1.id})}.should raise_error(StateError)
        end
      end
    end
  end

  describe "with a user" do
    it_should_behave_like :performance_sample_specs do
      let(:player1) { FactoryGirl.create(:user) }
      let(:player2) { FactoryGirl.create(:user) }
    end

    after(:all) {
      User.delete_all
      RecordedTrack.delete_all
      ClaimedRecording.delete_all
      Recording.delete_all
      ActiveMusicSession.delete_all
      MusicSession.delete_all
    }
  end

  describe "with a band" do
    it_should_behave_like :performance_sample_specs do
      let(:player1) { FactoryGirl.create(:band) }
      let(:player2) { FactoryGirl.create(:band) }
    end

    after(:all) {
      Band.delete_all
      RecordedTrack.delete_all
      ClaimedRecording.delete_all
      Recording.delete_all
      ActiveMusicSession.delete_all
      MusicSession.delete_all
    }
  end
end