require 'spec_helper' require 'time_difference' describe 'Musician Search Model' do let!(:searcher) { FactoryGirl.create(:austin_user) } let!(:search) { MusicianSearch.create_search(searcher) } let!(:austin_user) { FactoryGirl.create(:austin_user) } let!(:dallas_user) { FactoryGirl.create(:dallas_user) } let!(:miami_user) { FactoryGirl.create(:miami_user) } let!(:seattle_user) { FactoryGirl.create(:seattle_user) } let!(:user_types) { [:austin_user, :dallas_user, :miami_user, :seattle_user] } describe "creates search obj" do before(:all) do User.delete_all Score.connection.execute('delete from current_network_scores').check Score.connection.execute('delete from scores').check end it "associates to user" do expect(search.user).to eq(searcher) searcher.reload expect(searcher.musician_search).to eq(search) end it "sets json" do search.update_json_value(MusicianSearch::KEY_GIGS, MusicianSearch::GIG_COUNTS[1]) expect(search.json[MusicianSearch::KEY_GIGS]).to eq(MusicianSearch::GIG_COUNTS[1]) end end describe "filtering criteria" do before(:all) do User.delete_all end # it "filters musicians" do # expect(search.do_search(per_page: User.musicians.count).count).to eq(User.musicians.count) # end describe "filters by age" do before(:all) do @users = [] today = Date.today MusicianSearch::AGE_COUNTS.each_with_index do |age, idx| dd = today - age.years - 1.day @users << FactoryGirl.create(:austin_user, :birth_date => dd) @users << FactoryGirl.create(:dallas_user, :birth_date => dd) @users << FactoryGirl.create(:miami_user, :birth_date => dd) @users << FactoryGirl.create(:seattle_user, :birth_date => dd) end end it "filters by one age" do age = MusicianSearch::AGE_COUNTS[0] search.update_json_value(MusicianSearch::KEY_AGES, [age]) today = Date.today.to_time search.do_search.all.each do |uu| diff = TimeDifference.between(uu.birth_date.to_time, today).in_years expect(diff).to be >= age expect(diff).to be < MusicianSearch::AGE_COUNTS[1] end end it "filters by multiple ages" do ages = MusicianSearch::AGE_COUNTS[0..2] search.update_json_value(MusicianSearch::KEY_AGES, ages[0..1]) today = Date.today.to_time search.do_search.all.each do |uu| diff = TimeDifference.between(uu.birth_date.to_time, today).in_years expect(diff).to be >= ages.first expect(diff).to be < ages.last end end it "skips filtering by ages" do search.update_json_value(MusicianSearch::KEY_AGES, [MusicianSearch::ANY_VAL_INT]) search.do_search.to_sql =~ /(birth_date)/ expect($1).to eq(nil) end end describe "filtering by gig" do before(:all) do user_types.each do |utype| FactoryGirl.create(utype, :concert_count => MusicianSearch::GIG_COUNTS[1]) end end it "ignores gig count if any selected" do search.update_json_value(MusicianSearch::KEY_GIGS, MusicianSearch::GIG_COUNTS[0]) expect(search.do_search.count).to eq(User.musicians.count - 1) # searcher is musician end it "filters by gig count" do search.update_json_value(MusicianSearch::KEY_GIGS, MusicianSearch::GIG_COUNTS[1]) expect(search.do_search.count).to eq(user_types.count) end end describe "filtering by studio" do before(:all) do user_types.each do |utype| FactoryGirl.create(utype, :studio_session_count => MusicianSearch::STUDIO_COUNTS[1]) end end it "ignores studio count if any selected" do search.update_json_value(MusicianSearch::KEY_STUDIOS, MusicianSearch::STUDIO_COUNTS[0]) expect(search.do_search.count).to eq(User.musicians.count - 1) end it "filters by studio count" do search.update_json_value(MusicianSearch::KEY_STUDIOS, MusicianSearch::STUDIO_COUNTS[1]) expect(search.do_search.count).to eq(user_types.count) end end describe "filters skills" do before(:all) do MusicianSearch::SKILL_VALS.each do |val| user_types.each { |utype| FactoryGirl.create(utype, :skill_level => val) } end end it "get expected number per skill" do search.update_json_value(MusicianSearch::KEY_SKILL, MusicianSearch::SKILL_VALS[1]) expect(search.do_search.count).to eq(user_types.count) end end describe "filters interests" do before(:all) do end it "get expected number per interest" do MusicianSearch::INTEREST_VALS[1..-1].each do |val| user_types.each { |utype| FactoryGirl.create(utype, val => true, :paid_sessions_hourly_rate=>2300, :paid_sessions_daily_rate=>15000) } end search.update_json_value(MusicianSearch::KEY_INTERESTS, MusicianSearch::INTEREST_VALS[1]) expect(search.do_search.count).to eq(user_types.count) end end describe "filters genres" do before(:all) do user_types.each do |utype| uu = FactoryGirl.create(utype) uu.update_genres([Genre.first.id, Genre.last.id], GenrePlayer::PROFILE) end end it "gets expected number of users" do search.update_json_value(MusicianSearch::KEY_GENRES, [Genre.first.id, Genre.last.id]) expect(search.do_search.count).to eq(user_types.count) end end describe "filters instruments" do before(:all) do instruments = Instrument.first(user_types.count).collect do |inst| { instrument_id: inst.id, proficiency_level: 2, priority: 1 } end user_types[0..2].each do |utype| uu = FactoryGirl.create(utype) uu.update_instruments(instruments) end end it "gets expected number of users" do instjson = [{ instrument_id: Instrument.first.id, proficiency_level: 2 }, { instrument_id: Instrument.first(2)[1].id, proficiency_level: 2 }, { instrument_id: 'foo', proficiency_level: 2 }, ] search.update_json_value(MusicianSearch::KEY_INSTRUMENTS, instjson) expect(search.do_search.count).to eq(3) end end end describe "sort order by distance" do before(:all) do User.delete_all end before(:each) do create_phony_database end it "sorts by distance" do musician_search = MusicianSearch.create_search(searcher) musician_search.update_json_value(MusicianSearch::KEY_SORT_ORDER, MusicianSearch::SORT_VALS[1]) results = musician_search.do_search expect(results[0].id).to eq(austin_user.id) expect(results[1].id).to eq(dallas_user.id) expect(results[2].id).to eq(miami_user.id) expect(results[3].id).to eq(seattle_user.id) end end describe "sort order by latency" do before(:each) do User.delete_all Score.delete_all t = Time.now - 10.minute @user1 = FactoryGirl.create(:user, created_at: t+1.minute, last_jam_locidispid: 1) @user2 = FactoryGirl.create(:user, created_at: t+2.minute, last_jam_locidispid: 2) @user3 = FactoryGirl.create(:user, created_at: t+3.minute, last_jam_locidispid: 3) @user4 = FactoryGirl.create(:user, created_at: t+4.minute, last_jam_locidispid: 4) @user5 = FactoryGirl.create(:user, created_at: t+5.minute, last_jam_locidispid: 5) @user6 = FactoryGirl.create(:user, created_at: t+6.minute) # not geocoded @user7 = FactoryGirl.create(:user, created_at: t+7.minute, musician: false) # not musician @musicians = [] @musicians << @user1 @musicians << @user2 @musicians << @user3 @musicians << @user4 @musicians << @user5 @musicians << @user6 # from these scores: # user1 has scores other users in user1 location, and with user2, user3, user4 # user2 has scores with users in user3 and user4 location # Score.delete_all # Score.connection.execute('delete from current_network_scores').check Score.createx(1, 'a', 1, 1, 'a', 1, 10) Score.createx(1, 'a', 1, 2, 'b', 2, 20) Score.createx(1, 'a', 1, 3, 'c', 3, 30) Score.createx(1, 'a', 1, 4, 'd', 4, 40) Score.createx(2, 'b', 2, 3, 'c', 3, 15) Score.createx(2, 'b', 2, 4, 'd', 4, 70) end it "sorts by latency", intermittent: true do search.update_json_value(MusicianSearch::KEY_SORT_ORDER, MusicianSearch::SORT_VALS[0]) results = search.do_search expect(results[0].id).to eq(@user1.id) # HAS FAILED HERE TOO expect(results[1].id).to eq(@user2.id) expect(results[2].id).to eq(@user3.id) # HAS FAILED INTERMITTENTLY expect(results[3].id).to eq(@user4.id) end end describe "produces accurate query description" do before(:all) do User.delete_all end it 'has default description' do expect(search.description).to match(/^Click search button to look for musicians/) end it 'has correct sort order description' do search.update_json_value(MusicianSearch::KEY_SORT_ORDER, MusicianSearch::SORT_VALS[1]) str = MusicianSearch::SORT_ORDERS[search.json_value(MusicianSearch::KEY_SORT_ORDER)] expect(search.description).to match(/^Current Search: Sort = #{str}$/) end it 'has correct description for single-valued selections' do selections = [{ key: MusicianSearch::KEY_INTERESTS, value: MusicianSearch::INTEREST_VALS[1], lookup: MusicianSearch::INTERESTS, description: 'Interest' }, { key: MusicianSearch::KEY_SKILL, value: MusicianSearch::SKILL_VALS[1], lookup: MusicianSearch::SKILL_LEVELS, description: 'Skill' }, { key: MusicianSearch::KEY_STUDIOS, value: MusicianSearch::STUDIO_COUNTS[1], lookup: MusicianSearch::STUDIOS_LABELS, description: 'Studio Sessions' }, { key: MusicianSearch::KEY_GIGS, value: MusicianSearch::GIG_COUNTS[1], lookup: MusicianSearch::GIG_LABELS, description: 'Concert Gigs' }] selections.each do |hash| search.update_json_value(hash[:key], hash[:value]) json_val = search.json_value(hash[:key]) expect(search.description).to match(/ #{hash[:description]} = #{hash[:lookup][json_val]}/) end end it 'has correct description for genres' do search.update_json_value(MusicianSearch::KEY_GENRES, [Genre.first.id, Genre.last.id]) expect(search.description).to match(/ Genres = #{Genre.first.description}, #{Genre.last.description}/) end it 'has correct description for ages' do search.update_json_value(MusicianSearch::KEY_AGES, [MusicianSearch::AGE_COUNTS[0],MusicianSearch::AGE_COUNTS[1]]) expect(search.description).to match(/ Ages = #{MusicianSearch::AGES[MusicianSearch::AGE_COUNTS[0]]}, #{MusicianSearch::AGES[MusicianSearch::AGE_COUNTS[1]]}/) end it 'has correct description for instruments' do instrs = Instrument.limit(2).order(:description) instjson = [{ id: instrs[0].id, level: 2 }, { id: instrs[1].id, level: 1 } ] search.update_json_value(MusicianSearch::KEY_INSTRUMENTS, instjson) instr_descrip = "#{instrs[0].description} / #{MusicianSearch::INSTRUMENT_PROFICIENCY[2]}, #{instrs[1].description} / #{MusicianSearch::INSTRUMENT_PROFICIENCY[1]}" expect(search.description).to match(/ Instruments = #{Regexp.escape(instr_descrip)}/) end end end