jam-cloud/ruby/spec/jam_ruby/models/musician_search_model_spec.rb

307 lines
12 KiB
Ruby

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
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
# 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
User.delete_all
@users = []
today = Date.today
MusicianSearch::AGE_COUNTS.each_with_index do |age, idx|
age = 0==idx ? MusicianSearch::AGE_COUNTS[1] : age
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[1]
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[2]
end
end
it "filters by multiple ages" do
ages = MusicianSearch::AGE_COUNTS[1..3]
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.delete_all
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(per_page: User.musicians.count).count).to eq(User.musicians.count)
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.delete_all
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(per_page: User.musicians.count).count).to eq(User.musicians.count)
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
User.delete_all
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
User.delete_all
MusicianSearch::INTEREST_VALS[1..-1].each do |val|
user_types.each { |utype| FactoryGirl.create(utype, val => true) }
end
end
it "get expected number per interest" do
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 }
]
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(:each) do
create_phony_database
end
it "sorts by distance" do
search.update_json_value(MusicianSearch::KEY_SORT_ORDER, MusicianSearch::SORT_VALS[1])
results = 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
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" 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)
expect(results[1].id).to eq(@user2.id)
expect(results[2].id).to eq(@user3.id)
expect(results[3].id).to eq(@user4.id)
end
end
describe "produces accurate query description" do
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[1],MusicianSearch::AGE_COUNTS[2]])
expect(search.description).to match(/; Ages = #{MusicianSearch::AGES[MusicianSearch::AGE_COUNTS[1]]}, #{MusicianSearch::AGES[MusicianSearch::AGE_COUNTS[2]]}/)
end
it 'has correct description for instruments' do
instrs = Instrument.limit(2).order(:description)
instjson = [{ instrument_id: instrs[0].id, proficiency_level: 2 },
{ instrument_id: instrs[1].id, proficiency_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