Merge branch 'develop' of bitbucket.org:jamkazam/jam-cloud into develop

This commit is contained in:
Seth Call 2014-01-15 22:20:29 +00:00
commit 7d90425864
19 changed files with 488 additions and 418 deletions

View File

@ -14,6 +14,7 @@ module JamRuby
validates :biography, no_profanity: true
before_save :check_lat_lng
before_save :check_website_url
# musicians
has_many :band_musicians, :class_name => "JamRuby::BandMusician"
@ -111,23 +112,6 @@ module JamRuby
return recordings
end
def self.search(query, options = { :limit => 10 })
# only issue search if at least 2 characters are specified
if query.nil? || query.length < 2
return []
end
# create 'anded' statement
query = Search.create_tsquery(query)
if query.nil? || query.length == 0
return []
end
return Band.where("name_tsv @@ to_tsquery('jamenglish', ?)", query).limit(options[:limit])
end
# helper method for creating / updating a Band
def self.save(id, name, website, biography, city, state, country, genres, user_id, photo_url, logo_url)
user = User.find(user_id)
@ -254,6 +238,14 @@ module JamRuby
false
end
def check_website_url
if website_changed? && self.website.present?
self.website.strip!
self.website = "http://#{self.website}" unless self.website =~ /^http/
end
true
end
private
def self.validate_genres(genres, is_nil_ok)
if is_nil_ok && genres.nil?

View File

@ -1,73 +1,64 @@
module JamRuby
# not a active_record model; just a search result
# not a active_record model; just a search result container
class Search
attr_accessor :bands, :musicians, :fans, :recordings, :friends, :search_type
attr_accessor :bands_filter, :musicians_filter
attr_accessor :results, :search_type
attr_accessor :user_counters, :page_num, :page_count
LIMIT = 10
# performs a site-white search
def self.search(query, user_id = nil)
SEARCH_TEXT_TYPES = [:musicians, :bands, :fans]
SEARCH_TEXT_TYPE_ID = :search_text_type
users = User.search(query, :limit => LIMIT)
bands = Band.search(query, :limit => LIMIT)
# NOTE: I removed recordings from search here. This is because we switched
# to "claimed_recordings" so it's not clear what should be searched.
friends = Friendship.search(query, user_id, :limit => LIMIT)
return Search.new(users + bands + friends)
def self.band_search(txt, user = nil)
self.text_search({ SEARCH_TEXT_TYPE_ID => :bands, :query => txt }, user)
end
# performs a friend search scoped to a specific user
# def self.search_by_user(query, user_id)
# friends = Friendship.search(query, user_id, :limit => LIMIT)
# return Search.new(friends)
# end
def self.fan_search(txt, user = nil)
self.text_search({ SEARCH_TEXT_TYPE_ID => :fans, :query => txt }, user)
end
def self.musician_search(txt, user = nil)
self.text_search({ SEARCH_TEXT_TYPE_ID => :musicians, :query => txt }, user)
end
def self.text_search(params, user = nil)
srch = Search.new
unless (params.blank? || params[:query].blank? || 2 > params[:query].length)
srch.text_search(params, user)
end
srch
end
def text_search(params, user = nil)
tsquery = Search.create_tsquery(params[:query])
return [] if tsquery.blank?
rel = case params[SEARCH_TEXT_TYPE_ID].to_s
when 'bands'
@search_type = :bands
Band.scoped
when 'fans'
@search_type = :fans
User.fans
else
@search_type = :musicians
User.musicians
end
@results = rel.where("(name_tsv @@ to_tsquery('jamenglish', ?))", tsquery).limit(10)
@results
end
# search_results - results from a Tire search across band/user/recording
def initialize(search_results=nil)
@bands = []
@musicians = []
@fans = []
@recordings = []
@friends = []
@musicians_filter = []
@bands_filter = []
if search_results.nil?
return
end
search_results.take(LIMIT).each do |result|
if result.class == User
if result.musician
@musicians.push(result)
else
@fans.push(result)
end
elsif result.class == Band
@bands.push(result)
elsif result.class == Recording
@recordings.push(result)
elsif result.class == Friendship
@friends.push(result.friend)
else
raise Exception, "unknown class #{result.class} returned in search results"
end
end
@results = []
self
end
def self.create_tsquery(query)
# empty queries don't hit back to elasticsearch
if query.nil? || query.length == 0
return nil
end
return nil if query.blank?
search_terms = query.split
if search_terms.length == 0
return nil
end
return nil if search_terms.length == 0
args = nil
search_terms.each do |search_term|
@ -76,15 +67,11 @@ module JamRuby
else
args = args + " & " + search_term
end
end
args = args + ":*"
return args
args
end
attr_accessor :user_counters, :page_num, :page_count
PARAM_MUSICIAN = :srch_m
PARAM_BAND = :srch_b
@ -105,7 +92,7 @@ module JamRuby
ordering.blank? ? keys[0] : keys.detect { |oo| oo.to_s == ordering }
end
def self.musician_search(params={}, current_user=nil)
def self.musician_filter(params={}, current_user=nil)
rel = User.musicians
unless (instrument = params[:instrument]).blank?
rel = rel.joins("RIGHT JOIN musicians_instruments AS minst ON minst.user_id = users.id")
@ -140,6 +127,7 @@ module JamRuby
objs = rel.all
srch = Search.new
srch.search_type = :musicians_filter
srch.page_num, srch.page_count = page, objs.total_pages
srch.musician_results_for_user(objs, current_user)
end
@ -159,14 +147,14 @@ module JamRuby
COUNT_SESSION = :count_session
COUNTERS = [COUNT_FRIEND, COUNT_FOLLOW, COUNT_RECORD, COUNT_SESSION]
def musician_results_for_user(results, user)
@search_type, @musicians_filter = PARAM_MUSICIAN, results
def musician_results_for_user(_results, user)
@results = _results
if user
@user_counters = results.inject({}) { |hh,val| hh[val.id] = []; hh }
mids = "'#{@musicians_filter.map(&:id).join("','")}'"
@user_counters = @results.inject({}) { |hh,val| hh[val.id] = []; hh }
mids = "'#{@results.map(&:id).join("','")}'"
# this gets counts for each search result on friends/follows/records/sessions
results.each do |uu|
@results.each do |uu|
counters = { }
counters[COUNT_FRIEND] = Friendship.where(:user_id => uu.id).count
counters[COUNT_FOLLOW] = UserFollowing.where(:user_id => uu.id).count
@ -204,6 +192,26 @@ module JamRuby
public
def musicians_text_search?
:musicians == @search_type
end
def fans_text_search?
:fans == @search_type
end
def bands_text_search?
:bands == @search_type
end
def musicians_filter_search?
:musicians_filter == @search_type
end
def bands_filter_search?
:band_filter == @search_type
end
def follow_count(musician)
_count(musician, COUNT_FOLLOW)
end
@ -247,7 +255,7 @@ module JamRuby
end
end
def self.band_search(params={}, current_user=nil)
def self.band_filter(params={}, current_user=nil)
rel = Band.scoped
unless (genre = params[:genre]).blank?
@ -282,18 +290,19 @@ module JamRuby
objs = rel.all
srch = Search.new
srch.search_type = :band_filter
srch.page_num, srch.page_count = page, objs.total_pages
srch.band_results_for_user(objs, current_user)
end
def band_results_for_user(results, user)
@search_type, @bands_filter = PARAM_BAND, results
def band_results_for_user(_results, user)
@results = _results
if user
@user_counters = results.inject({}) { |hh,val| hh[val.id] = []; hh }
mids = "'#{@bands_filter.map(&:id).join("','")}'"
@user_counters = @results.inject({}) { |hh,val| hh[val.id] = []; hh }
mids = "'#{@results.map(&:id).join("','")}'"
# this gets counts for each search result
results.each do |bb|
@results.each do |bb|
counters = { }
counters[COUNT_FOLLOW] = BandFollowing.where(:band_id => bb.id).count
counters[COUNT_RECORD] = Recording.where(:band_id => bb.id).count

View File

@ -140,6 +140,7 @@ module JamRuby
validate :update_email_case_insensitive_uniqueness, :if => :updating_email
scope :musicians, where(:musician => true)
scope :fans, where(:musician => false)
scope :geocoded_users, where(['lat IS NOT NULL AND lng IS NOT NULL'])
scope :musicians_geocoded, musicians.geocoded_users
@ -924,31 +925,6 @@ module JamRuby
end
end
def self.search(query, options = { :limit => 10 })
# only issue search if at least 2 characters are specified
if query.nil? || query.length < 2
return []
end
# save query for use in instrument search
search_criteria = query
# create 'anded' statement
query = Search.create_tsquery(query)
if query.nil? || query.length == 0
return []
end
# remove email_confirmed restriction due to VRFS-378
# .where("email_confirmed = true AND (name_tsv @@ to_tsquery('jamenglish', ?) OR users.id in (select user_id from musicians_instruments where instrument_id like '%#{search_criteria.downcase}%'))", query)
return query = User
.where("(name_tsv @@ to_tsquery('jamenglish', ?) OR users.id in (select user_id from musicians_instruments where instrument_id like '%#{search_criteria.downcase}%'))", query)
.limit(options[:limit])
end
def provides_location?
!self.city.blank? && (!self.state.blank? || !self.country.blank?)
end

View File

@ -25,15 +25,15 @@ describe 'Band search' do
it "finds all bands" do
# expects all the bands
num = Band.count
results = Search.band_search({ :per_page => num })
expect(results.bands_filter.count).to eq(num)
results = Search.band_filter({ :per_page => num })
expect(results.results.count).to eq(num)
end
it "finds bands with proper ordering" do
# the ordering should be create_at since no followers exist
expect(BandFollower.count).to eq(0)
results = Search.band_search({ :per_page => Band.count })
results.bands_filter.each_with_index do |uu, idx|
results = Search.band_filter({ :per_page => Band.count })
results.results.each_with_index do |uu, idx|
expect(uu.id).to eq(@bands.reverse[idx].id)
end
end
@ -53,11 +53,11 @@ describe 'Band search' do
# refresh the order to ensure it works right
@band2.followers.concat(users[1..-1])
results = Search.band_search({ :per_page => @bands.size }, users[0])
expect(results.bands_filter[0].id).to eq(@band2.id)
results = Search.band_filter({ :per_page => @bands.size }, users[0])
expect(results.results[0].id).to eq(@band2.id)
# check the follower count for given entry
expect(results.bands_filter[0].search_follow_count.to_i).not_to eq(0)
expect(results.results[0].search_follow_count.to_i).not_to eq(0)
# check the follow relationship between current_user and result
expect(results.is_follower?(@band2)).to be true
end
@ -65,8 +65,8 @@ describe 'Band search' do
it 'paginates properly' do
# make sure pagination works right
params = { :per_page => 2, :page => 1 }
results = Search.band_search(params)
expect(results.bands_filter.count).to be 2
results = Search.band_filter(params)
expect(results.results.count).to be 2
end
end
@ -87,8 +87,8 @@ describe 'Band search' do
# establish sorting order
@band1.followers.concat(users)
results = Search.band_search({},@band1)
uu = results.bands_filter.detect { |mm| mm.id == @band1.id }
results = Search.band_filter({},@band1)
uu = results.results.detect { |mm| mm.id == @band1.id }
expect(uu).to_not be_nil
expect(results.follow_count(uu)).to eq(users.count)
end
@ -96,8 +96,8 @@ describe 'Band search' do
it "session stat shows session count" do
make_session(@band1)
@band1.reload
results = Search.band_search({},@band1)
uu = results.bands_filter.detect { |mm| mm.id == @band1.id }
results = Search.band_filter({},@band1)
uu = results.results.detect { |mm| mm.id == @band1.id }
expect(uu).to_not be_nil
expect(results.session_count(uu)).to be 1
end
@ -112,9 +112,9 @@ describe 'Band search' do
make_session(@band2)
make_session(@band1)
# order results by num recordings
results = Search.band_search({ :orderby => 'plays' })
expect(results.bands_filter[0].id).to eq(@band2.id)
expect(results.bands_filter[1].id).to eq(@band1.id)
results = Search.band_filter({ :orderby => 'plays' })
expect(results.results[0].id).to eq(@band2.id)
expect(results.results[1].id).to eq(@band1.id)
end
it "by now playing" do
@ -122,18 +122,18 @@ describe 'Band search' do
session = make_session(@band3)
FactoryGirl.create(:music_session_history, :music_session => session)
results = Search.band_search({ :orderby => 'playing' })
expect(results.bands_filter.count).to be 1
expect(results.bands_filter.first.id).to eq(@band3.id)
results = Search.band_filter({ :orderby => 'playing' })
expect(results.results.count).to be 1
expect(results.results.first.id).to eq(@band3.id)
# should get 2 results with 2 active sessions
# sort order should be created_at DESC
session = make_session(@band4)
FactoryGirl.create(:music_session_history, :music_session => session)
results = Search.band_search({ :orderby => 'playing' })
expect(results.bands_filter.count).to be 2
expect(results.bands_filter[0].id).to eq(@band4.id)
expect(results.bands_filter[1].id).to eq(@band3.id)
results = Search.band_filter({ :orderby => 'playing' })
expect(results.results.count).to be 2
expect(results.results[0].id).to eq(@band4.id)
expect(results.results[1].id).to eq(@band3.id)
end
end
@ -146,40 +146,40 @@ describe 'Band search' do
@band1.reload
ggg = @band1.genres.detect { |gg| gg.id == genre.id }
expect(ggg).to_not be_nil
results = Search.band_search({ :genre => ggg.id })
results.bands_filter.each do |rr|
results = Search.band_filter({ :genre => ggg.id })
results.results.each do |rr|
expect(rr.genres.detect { |gg| gg.id==ggg.id }.id).to eq(genre.id)
end
expect(results.bands_filter.count).to be 1
expect(results.results.count).to be 1
end
it "finds bands within a given distance of given location" do
num = Band.count
expect(@band1.lat).to_not be_nil
# short distance
results = Search.band_search({ :per_page => num,
results = Search.band_filter({ :per_page => num,
:distance => 10,
:city => 'Apex' }, @band1)
expect(results.bands_filter.count).to be num
expect(results.results.count).to be num
# long distance
results = Search.band_search({ :per_page => num,
results = Search.band_filter({ :per_page => num,
:distance => 1000,
:city => 'Miami',
:state => 'FL' }, @band1)
expect(results.bands_filter.count).to be num
expect(results.results.count).to be num
end
it "finds bands within a given distance of bands location" do
expect(@band1.lat).to_not be_nil
# uses the location of @band1
results = Search.band_search({ :distance => 10, :per_page => Band.count }, @band1)
expect(results.bands_filter.count).to be Band.count
results = Search.band_filter({ :distance => 10, :per_page => Band.count }, @band1)
expect(results.results.count).to be Band.count
end
it "finds no bands within a given distance of location" do
expect(@band1.lat).to_not be_nil
results = Search.band_search({ :distance => 10, :city => 'San Francisco' }, @band1)
expect(results.bands_filter.count).to be 0
results = Search.band_filter({ :distance => 10, :city => 'San Francisco' }, @band1)
expect(results.results.count).to be 0
end
end

View File

@ -13,7 +13,7 @@ describe User do
end
it "should allow search of one band with an exact match" do
ws = Band.search("Example Band")
ws = Search.band_search("Example Band").results
ws.length.should == 1
band_result = ws[0]
band_result.name.should == @band.name
@ -22,61 +22,61 @@ describe User do
end
it "should allow search of one band with partial matches" do
ws = Band.search("Ex")
ws = Search.band_search("Ex").results
ws.length.should == 1
ws[0].id.should == @band.id
ws = Band.search("Exa")
ws = Search.band_search("Exa").results
ws.length.should == 1
ws[0].id.should == @band.id
ws = Band.search("Exam")
ws = Search.band_search("Exam").results
ws.length.should == 1
ws[0].id.should == @band.id
ws = Band.search("Examp")
ws = Search.band_search("Examp").results
ws.length.should == 1
ws[0].id.should == @band.id
ws = Band.search("Exampl")
ws = Search.band_search("Exampl").results
ws.length.should == 1
ws[0].id.should == @band.id
ws = Band.search("Example")
ws = Search.band_search("Example").results
ws.length.should == 1
ws[0].id.should == @band.id
ws = Band.search("Ba")
ws = Search.band_search("Ba").results
ws.length.should == 1
ws[0].id.should == @band.id
ws = Band.search("Ban")
ws = Search.band_search("Ban").results
ws.length.should == 1
ws[0].id.should == @band.id
end
it "should not match mid-word searchs" do
ws = Band.search("xa")
ws = Search.band_search("xa").results
ws.length.should == 0
ws = Band.search("le")
ws = Search.band_search("le").results
ws.length.should == 0
end
it "should delete band" do
ws = Band.search("Example Band")
ws = Search.band_search("Example Band").results
ws.length.should == 1
band_result = ws[0]
band_result.id.should == @band.id
@band.destroy # delete doesn't work; you have to use destroy.
ws = Band.search("Example Band")
ws = Search.band_search("Example Band").results
ws.length.should == 0
end
it "should update band" do
ws = Band.search("Example Band")
ws = Search.band_search("Example Band").results
ws.length.should == 1
band_result = ws[0]
band_result.id.should == @band.id
@ -84,10 +84,10 @@ describe User do
@band.name = "bonus-stuff"
@band.save
ws = Band.search("Example Band")
ws = Search.band_search("Example Band").results
ws.length.should == 0
ws = Band.search("Bonus")
ws = Search.band_search("Bonus").results
ws.length.should == 1
band_result = ws[0]
band_result.id.should == @band.id
@ -96,7 +96,7 @@ describe User do
it "should tokenize correctly" do
@band2 = Band.save(nil, "Peach pit", "www.bands.com", "zomg we rock", "Apex", "NC", "US", ["hip hop"], user.id, nil, nil)
ws = Band.search("pea")
ws = Search.band_search("pea").results
ws.length.should == 1
user_result = ws[0]
user_result.id.should == @band2.id
@ -105,12 +105,12 @@ describe User do
it "should not return anything with a 1 character search" do
@band2 = Band.save(nil, "Peach pit", "www.bands.com", "zomg we rock", "Apex", "NC", "US", ["hip hop"], user.id, nil, nil)
ws = Band.search("pe")
ws = Search.band_search("pe").results
ws.length.should == 1
user_result = ws[0]
user_result.id.should == @band2.id
ws = Band.search("p")
ws = Search.band_search("p").results
ws.length.should == 0
end
end

View File

@ -0,0 +1,15 @@
require 'spec_helper'
describe Band do
let(:band) { FactoryGirl.create(:band) }
describe 'website update' do
it 'should have http prefix on website url' do
band.website = 'example.com'
band.save!
expect(band.website).to match(/^http:\/\/example.com$/)
end
end
end

View File

@ -17,15 +17,16 @@ describe 'Musician search' do
it "finds all musicians" do
# expects all the users
num = User.musicians.count
results = Search.musician_search({ :per_page => num })
expect(results.musicians_filter.count).to eq(num)
results = Search.musician_filter({ :per_page => num })
expect(results.results.count).to eq(num)
expect(results.search_type).to be(:musicians_filter)
end
it "finds musicians with proper ordering" do
# the ordering should be create_at since no followers exist
expect(UserFollower.count).to eq(0)
results = Search.musician_search({ :per_page => User.musicians.count })
results.musicians_filter.each_with_index do |uu, idx|
results = Search.musician_filter({ :per_page => User.musicians.count })
results.results.each_with_index do |uu, idx|
expect(uu.id).to eq(@users.reverse[idx].id)
end
end
@ -40,11 +41,11 @@ describe 'Musician search' do
# refresh the order to ensure it works right
@user2.followers.concat([@user3, @user4, @user2])
results = Search.musician_search({ :per_page => @users.size }, @user3)
expect(results.musicians_filter[0].id).to eq(@user2.id)
results = Search.musician_filter({ :per_page => @users.size }, @user3)
expect(results.results[0].id).to eq(@user2.id)
# check the follower count for given entry
expect(results.musicians_filter[0].search_follow_count.to_i).not_to eq(0)
expect(results.results[0].search_follow_count.to_i).not_to eq(0)
# check the follow relationship between current_user and result
expect(results.is_follower?(@user2)).to be true
end
@ -52,8 +53,8 @@ describe 'Musician search' do
it 'paginates properly' do
# make sure pagination works right
params = { :per_page => 2, :page => 1 }
results = Search.musician_search(params)
expect(results.musicians_filter.count).to be 2
results = Search.musician_filter(params)
expect(results.results.count).to be 2
end
end
@ -95,8 +96,8 @@ describe 'Musician search' do
# create friendship record
Friendship.save(@user1.id, @user2.id)
# search on user2
results = Search.musician_search({}, @user2)
friend = results.musicians_filter.detect { |mm| mm.id == @user1.id }
results = Search.musician_filter({}, @user2)
friend = results.results.detect { |mm| mm.id == @user1.id }
expect(friend).to_not be_nil
expect(results.friend_count(friend)).to be 1
@user1.reload
@ -114,8 +115,8 @@ describe 'Musician search' do
expect(recording.claimed_recordings.length).to be 1
expect(@user1.recordings.detect { |rr| rr == recording }).to_not be_nil
results = Search.musician_search({},@user1)
uu = results.musicians_filter.detect { |mm| mm.id == @user1.id }
results = Search.musician_filter({},@user1)
uu = results.results.detect { |mm| mm.id == @user1.id }
expect(uu).to_not be_nil
expect(results.record_count(uu)).to be 1
@ -129,29 +130,29 @@ describe 'Musician search' do
it "by plays" do
make_recording(@user1)
# order results by num recordings
results = Search.musician_search({ :orderby => 'plays' }, @user2)
expect(results.musicians_filter[0].id).to eq(@user1.id)
results = Search.musician_filter({ :orderby => 'plays' }, @user2)
expect(results.results[0].id).to eq(@user1.id)
# add more data and make sure order still correct
make_recording(@user2); make_recording(@user2)
results = Search.musician_search({ :orderby => 'plays' }, @user2)
expect(results.musicians_filter[0].id).to eq(@user2.id)
results = Search.musician_filter({ :orderby => 'plays' }, @user2)
expect(results.results[0].id).to eq(@user2.id)
end
it "by now playing" do
# should get 1 result with 1 active session
make_session(@user3)
results = Search.musician_search({ :orderby => 'playing' }, @user2)
expect(results.musicians_filter.count).to be 1
expect(results.musicians_filter.first.id).to eq(@user3.id)
results = Search.musician_filter({ :orderby => 'playing' }, @user2)
expect(results.results.count).to be 1
expect(results.results.first.id).to eq(@user3.id)
# should get 2 results with 2 active sessions
# sort order should be created_at DESC
make_session(@user4)
results = Search.musician_search({ :orderby => 'playing' }, @user2)
expect(results.musicians_filter.count).to be 2
expect(results.musicians_filter[0].id).to eq(@user4.id)
expect(results.musicians_filter[1].id).to eq(@user3.id)
results = Search.musician_filter({ :orderby => 'playing' }, @user2)
expect(results.results.count).to be 2
expect(results.results[0].id).to eq(@user4.id)
expect(results.results[1].id).to eq(@user3.id)
end
end
@ -165,40 +166,40 @@ describe 'Musician search' do
@user1.reload
ii = @user1.instruments.detect { |inst| inst.id == 'tuba' }
expect(ii).to_not be_nil
results = Search.musician_search({ :instrument => ii.id })
results.musicians_filter.each do |rr|
results = Search.musician_filter({ :instrument => ii.id })
results.results.each do |rr|
expect(rr.instruments.detect { |inst| inst.id=='tuba' }.id).to eq(ii.id)
end
expect(results.musicians_filter.count).to be 1
expect(results.results.count).to be 1
end
it "finds musicians within a given distance of given location" do
num = User.musicians.count
expect(@user1.lat).to_not be_nil
# short distance
results = Search.musician_search({ :per_page => num,
results = Search.musician_filter({ :per_page => num,
:distance => 10,
:city => 'Apex' }, @user1)
expect(results.musicians_filter.count).to be num
expect(results.results.count).to be num
# long distance
results = Search.musician_search({ :per_page => num,
results = Search.musician_filter({ :per_page => num,
:distance => 1000,
:city => 'Miami',
:state => 'FL' }, @user1)
expect(results.musicians_filter.count).to be num
expect(results.results.count).to be num
end
it "finds musicians within a given distance of users location" do
expect(@user1.lat).to_not be_nil
# uses the location of @user1
results = Search.musician_search({ :distance => 10, :per_page => User.musicians.count }, @user1)
expect(results.musicians_filter.count).to be User.musicians.count
results = Search.musician_filter({ :distance => 10, :per_page => User.musicians.count }, @user1)
expect(results.results.count).to be User.musicians.count
end
it "finds no musicians within a given distance of location" do
expect(@user1.lat).to_not be_nil
results = Search.musician_search({ :distance => 10, :city => 'San Francisco' }, @user1)
expect(results.musicians_filter.count).to be 0
results = Search.musician_filter({ :distance => 10, :city => 'San Francisco' }, @user1)
expect(results.results.count).to be 0
end
end

View File

@ -9,7 +9,8 @@ describe User do
end
it "should allow search of one user" do
ws = User.search("Example User")
uu = FactoryGirl.create(:user, :musician => false)
ws = Search.musician_search("Example User").results
ws.length.should == 1
user_result = ws[0]
user_result.first_name.should == @user.first_name
@ -19,20 +20,27 @@ describe User do
user_result.musician.should == true
end
it "should allow search of one fan" do
uu = FactoryGirl.create(:user, :musician => false)
ws = Search.fan_search(uu.name).results
expect(ws.length).to be(1)
expect(ws[0].id).to eq(uu.id)
end
it "should delete user" do
ws = User.search("Example User")
ws = Search.musician_search("Example User").results
ws.length.should == 1
user_result = ws[0]
user_result.id.should == @user.id
@user.destroy
ws = User.search("Example User")
ws = Search.musician_search("Example User").results
ws.length.should == 0
end
it "should update user" do
ws = User.search("Example User")
ws = Search.musician_search("Example User").results
ws.length.should == 1
user_result = ws[0]
user_result.id.should == @user.id
@ -41,10 +49,10 @@ describe User do
@user.last_name = "more-junk"
@user.save
ws = User.search("Example User")
ws = Search.musician_search("Example User").results
ws.length.should == 0
ws = User.search("Bonus")
ws = Search.musician_search("Bonus").results
ws.length.should == 1
user_result = ws[0]
user_result.id.should == @user.id
@ -55,7 +63,7 @@ describe User do
@user2 = FactoryGirl.create(:user, first_name: "peaches", last_name: "test", email: "peach@example.com",
password: "foobar", password_confirmation: "foobar", musician: true, email_confirmed: true,
city: "Apex", state: "NC", country: "US")
ws = User.search("pea")
ws = Search.musician_search("pea").results
ws.length.should == 1
user_result = ws[0]
user_result.id.should == @user2.id
@ -65,14 +73,14 @@ describe User do
@user3 = FactoryGirl.create(:user, first_name: "unconfirmed", last_name: "unconfirmed", email: "unconfirmed@example.com",
password: "foobar", password_confirmation: "foobar", musician: true, email_confirmed: false,
city: "Apex", state: "NC", country: "US")
ws = User.search("unconfirmed")
ws = Search.musician_search("unconfirmed").results
ws.length.should == 1
# Ok, confirm the user, and see them show up
@user3.email_confirmed = true
@user3.save
ws = User.search("unconfirmed")
ws = Search.musician_search("unconfirmed").results
ws.length.should == 1
user_result = ws[0]
user_result.id.should == @user3.id

View File

@ -113,7 +113,7 @@
players += context.JK.fillTemplate(pTemplate, playerVals);
}
var actionVals = {
profile_url: "/#/profile/" + bb.id,
profile_url: bb.website,
button_follow: bb['is_following'] ? '' : 'button-orange',
button_message: 'button-orange'
};

View File

@ -8,6 +8,20 @@
var instrument_logo_map = context.JK.getInstrumentIconMap24();
function initializeSearchNavLinks() {
$('.search-nav').click(function() {
$('.search-nav.active').removeClass('active');
$(this).addClass('active');
setTimeout(search, 100);
context.JK.Sidebar.searchTypeSelection($(this).data('search_text_type'));
});
}
context.JK.SearchResultScreen.searchTypeSelection = function(typeSelection) {
$('.search-nav.active').removeClass('active');
$('.search-result-header a[data-search_text_type='+typeSelection+']').addClass('active');
}
function beforeShow(data) {
var query = data.query;
}
@ -15,20 +29,31 @@
function afterShow(data) {
}
function search(evt) {
evt.stopPropagation();
function selectedSearchType() {
var srchtype = $('.search-nav.active').data('search_text_type');
if (srchtype === undefined) {
srchtype = $('#search_text_type').val();
}
return srchtype;
}
function search(evt) {
if (evt) {
evt.stopPropagation();
}
$('#search-results').empty();
var query = $('#search-input').val();
context.location = '#/searchResults/:' + query;
if (query) {
context.location = '#/searchResults/:' + query;
} else {
query = $('#query').html();
}
logger.debug('query=' + query);
if (query !== '') {
$('#query').html(query + "\"");
context.JK.search(query, app, onSearchSuccess);
}
else {
$('#query').html(query);
query += '&search_text_type='+selectedSearchType();
context.JK.search(query, app, context.JK.SearchResultScreen.onSearchSuccess);
} else {
$('#result-count').html('');
$('#query').html('');
}
@ -36,68 +61,147 @@
return false;
}
function onSearchSuccess(response) {
function resultDivVisibility(val, isSidebar) {
if (isSidebar) {
$('div[layout=sidebar user-id=' + val.id + '].sidebar-search-connected').hide();
$('div[layout=sidebar user-id=' + val.id + '].sidebar-search-result').show();
} else {
$('div[user-id=' + val.id + '].search-connected').hide();
$('div[user-id=' + val.id + '].search-result').show();
}
}
// TODO: generalize this for each search result type (band, musician, recordings, et. al.)
$.each(response.musicians, function(index, val) {
// fill in template for Connect pre-click
var template = $('#template-search-result').html();
var searchResultHtml = context.JK.fillTemplate(template, {
userId: val.id,
avatar_url: context.JK.resolveAvatarUrl(val.photo_url),
profile_url: "/#/profile/" + val.id,
userName: val.name,
location: val.location,
instruments: getInstrumentHtml(val.instruments)
});
$('#search-results').append(searchResultHtml);
// fill in template for Connect post-click
template = $('#template-invitation-sent').html();
var invitationSentHtml = context.JK.fillTemplate(template, {
userId: val.id,
first_name: val.first_name,
profile_url: "/#/profile/" + val.id
});
$('#search-results').append(invitationSentHtml);
// initialize visibility of the divs
$('div[user-id=' + val.id + '].search-connected').hide();
$('div[user-id=' + val.id + '].search-result').show();
// wire up button click handler if search result is not a friend or the current user
if (!val.is_friend && val.id !== context.JK.currentUserId) {
$('div[user-id=' + val.id + ']').find('.btn-connect-friend').click(sendFriendRequest);
}
else {
$('div[user-id=' + val.id + ']').find('.btn-connect-friend').hide();
}
});
var resultCount = response.musicians.length;
$('#result-count').html(resultCount);
if (resultCount === 1) {
$('#result-count').append(" Result for \"");
}
else {
$('#result-count').append(" Results for \"");
}
context.JK.SearchResultScreen.onSearchSuccess = function(response) {
searchResults(response, true);
searchResults(response, false);
}
function friendRequestCallback(userId) {
// toggle the pre-click and post-click divs
$('div[user-id=' + userId + '].search-connected').show();
$('div[user-id=' + userId + '].search-result').hide();
}
function searchResults(response, isSidebar) {
var resultCount=0;
var selector, template_name;
selector = isSidebar ? '#sidebar-search-results' : '#search-results';
$(selector).html('');
function sendFriendRequest(evt) {
if (response.search_type === 'musicians') {
resultCount = response.musicians.length;
// TODO: generalize this for each search result type (band, musician, et. al.)
template_name = isSidebar ? "#template-musicians-sidebar-search-result" : "#template-musicians-search-result";
$.each(response.musicians, function(index, val) {
// fill in template for Connect pre-click
var args = {
userId: val.id,
avatar_url: context.JK.resolveAvatarUrl(val.photo_url),
profile_url: "/#/profile/" + val.id,
userName: val.name,
location: val.location,
instruments: getInstrumentHtml(val.instruments)
};
selector = isSidebar ? '#sidebar-search-results' : '#search-results';
$(selector).append(context.JK.fillTemplate($(template_name).html(), args));
// fill in template for Connect post-click
selector = isSidebar ? '#template-sidebar-invitation-sent' : '#template-invitation-sent';
var invitationSentHtml = context.JK.fillTemplate($(selector).html(), {
userId: val.id,
first_name: val.first_name,
profile_url: "/#/profile/" + val.id
});
selector = isSidebar ? '#sidebar-search-results' : '#search-results';
$(selector).append(invitationSentHtml);
// wire up button click handler if search result is not a friend or the current use
if (isSidebar) {
var $sidebar = $('div[layout=sidebar] div[user-id=' + val.id + ']');
if (!val.is_friend && val.id !== context.JK.currentUserId) {
$sidebar.find('.btn-connect-friend').click(sendFriendRequest);
} else {
// hide the button if the search result is already a friend
$sidebar.find('.btn-connect-friend').hide();
}
} else {
if (!val.is_friend && val.id !== context.JK.currentUserId) {
$('div[user-id=' + val.id + ']').find('.btn-connect-friend').click(sendFriendRequest);
} else {
$('div[user-id=' + val.id + ']').find('.btn-connect-friend').hide();
}
}
resultDivVisibility(val, isSidebar);
});
} else if (response.search_type === 'bands') {
resultCount = response.bands.length;
template_name = isSidebar ? "#template-bands-sidebar-search-result" : "#template-bands-search-result";
$.each(response.bands, function(index, val) {
// fill in template for Connect pre-click
var searchResultHtml = context.JK.fillTemplate($(template_name).html(), {
bandId: val.id,
avatar_url: context.JK.resolveAvatarUrl(val.photo_url),
band_url: val.website,
bandName: val.name,
location: val.location
});
selector = isSidebar ? '#sidebar-search-results' : '#search-results';
$(selector).append(searchResultHtml);
resultDivVisibility(val, isSidebar);
});
} else if (response.search_type === 'fans') {
resultCount = response.fans.length;
template_name = isSidebar ? "#template-fans-sidebar-search-result" : "#template-fans-search-result";
$.each(response.fans, function(index, val) {
// fill in template for Connect pre-click
var searchResultHtml = context.JK.fillTemplate($(template_name).html(), {
userId: val.id,
avatar_url: context.JK.resolveAvatarUrl(val.photo_url),
profile_url: "/#/profile/" + val.id,
userName: val.name,
location: val.location
});
selector = isSidebar ? '#sidebar-search-results' : '#search-results';
$(selector).append(searchResultHtml);
resultDivVisibility(val, isSidebar);
});
}
if (isSidebar) {
// show header
$('#sidebar-search-header').show();
// hide panels
$('[layout-panel="contents"]').hide();
$('[layout-panel="contents"]').css({"height": "1px"});
// resize search results area
$('#sidebar-search-results').height(context.JK.Sidebar.getHeight() + 'px');
} else {
$('#result-count').html(resultCount);
if (resultCount === 1) {
$('#result-count').append(" Result for: ");
} else {
$('#result-count').append(" Results for: ");
}
}
};
function friendRequestCallbackSidebar(userId) {
// toggle the pre-click and post-click divs
$('div[layout=sidebar] div[user-id=' + userId + '].sidebar-search-connected').show();
$('div[layout=sidebar] div[user-id=' + userId + '].sidebar-search-result').hide();
}
function friendRequestCallbackSearchResults(userId) {
// toggle the pre-click and post-click divs
$('div[user-id=' + userId + '].search-connected').show();
$('div[user-id=' + userId + '].search-result').hide();
}
function sendFriendRequest(evt) {
evt.stopPropagation();
var userId = $(this).parent().attr('user-id');
context.JK.sendFriendRequest(app, userId, friendRequestCallback);
}
if ($(this).closest('#sidebar-search-results')) {
context.JK.sendFriendRequest(app, userId, friendRequestCallbackSidebar);
} else {
context.JK.sendFriendRequest(app, userId, friendRequestCallbackSearchResults);
}
}
function getInstrumentHtml(instruments) {
var instrumentLogoHtml = '';
@ -124,6 +228,7 @@
};
app.bindScreen('searchResults', screenBindings);
events();
initializeSearchNavLinks();
};
};

View File

@ -9,6 +9,18 @@
var rest = context.JK.Rest();
var invitationDialog = null;
function initializeSearchPanel() {
$('#search_text_type').change(function() {
searchForInput();
context.JK.SearchResultScreen.searchTypeSelection($('#search_text_type').val());
});
}
context.JK.Sidebar.searchTypeSelection = function(typeSelection) {
$('#search_text_type').val(typeSelection);
emptySearchResults();
}
function initializeFriendsPanel() {
/////////////////////////////////////////////////////////////
@ -253,66 +265,13 @@
}
function search(query) {
logger.debug('query=' + query);
if (query !== '') {
context.JK.search(query, app, onSearchSuccess);
context.JK.search(query, app, context.JK.SearchResultScreen.onSearchSuccess);
}
}
function onSearchSuccess(response) {
// TODO: generalize this for each search result type (band, musician, recordings, et. al.)
$.each(response.musicians, function(index, val) {
// fill in template for Connect pre-click
var template = $('#template-sidebar-search-result').html();
var searchResultHtml = context.JK.fillTemplate(template, {
userId: val.id,
avatar_url: context.JK.resolveAvatarUrl(val.photo_url),
profile_url: "/#/profile/" + val.id,
userName: val.name,
location: val.location
});
$('#sidebar-search-results').append(searchResultHtml);
// fill in template for Connect post-click
template = $('#template-sidebar-invitation-sent').html();
var invitationSentHtml = context.JK.fillTemplate(template, {
userId: val.id,
first_name: val.first_name,
profile_url: "/#/profile/" + val.id
});
$('#sidebar-search-results').append(invitationSentHtml);
// initialize visibility of the divs
$('div[layout=sidebar] div[user-id=' + val.id + '].sidebar-search-connected').hide();
$('div[layout=sidebar] div[user-id=' + val.id + '].sidebar-search-result').show();
// wire up button click handler if search result is not a friend or the current user
var $sidebar = $('div[layout=sidebar] div[user-id=' + val.id + ']');
if (!val.is_friend && val.id !== context.JK.currentUserId) {
$sidebar.find('.btn-connect-friend').click(sendFriendRequest);
}
// hide the button if the search result is already a friend
else {
$sidebar.find('.btn-connect-friend').hide();
}
});
// show header
$('#sidebar-search-header').show();
// hide panels
$('[layout-panel="contents"]').hide();
$('[layout-panel="contents"]').css({"height": "1px"});
// resize search results area
$('#sidebar-search-results').height(getHeight() + 'px');
}
function getHeight() {
context.JK.Sidebar.getHeight = function() {
// TODO: refactor this - copied from layout.js
var sidebarHeight = $(context).height() - 75 - 2 * 60 + $('[layout-sidebar-expander]').height();
var combinedHeaderHeight = $('[layout-panel="contents"]').length * 36;
@ -325,7 +284,7 @@
function showFriendsPanel() {
var $expandedPanelContents = $('[layout-id="panelFriends"] [layout-panel="contents"]');
var expandedPanelHeight = getHeight();
var expandedPanelHeight = context.JK.Sidebar.getHeight();
// hide all other contents
$('[layout-panel="contents"]').hide();
@ -336,18 +295,6 @@
$expandedPanelContents.animate({"height": expandedPanelHeight + "px"}, 400);
}
function friendRequestCallback(userId) {
// toggle the pre-click and post-click divs
$('div[layout=sidebar] div[user-id=' + userId + '].sidebar-search-connected').show();
$('div[layout=sidebar] div[user-id=' + userId + '].sidebar-search-result').hide();
}
function sendFriendRequest(evt) {
evt.stopPropagation();
var userId = $(this).parent().attr('user-id');
context.JK.sendFriendRequest(app, userId, friendRequestCallback);
}
function hideSearchResults() {
emptySearchResults();
$('#search-input').val('');
@ -413,6 +360,21 @@
function inviteHoverOut() {
$('.invitation-button-holder').slideUp();
}
function searchForInput() {
var query = $('#search-input').val();
// logger.debug("query=" + query);
if (query === '') {
return hideSearchResults();
}
if (query.length > 2) {
// FIXME: this is in searchResults
$('#query').html(query);
query += '&search_text_type='+$('#search_text_type').val();
emptySearchResults();
search(query);
}
}
function events() {
$('#search-input').keyup(function(evt) {
@ -421,24 +383,12 @@
if (evt.which === 13) {
return hideSearchResults();
}
// ESCAPE KEY
if (evt.which === 27) {
return hideSearchResults();
}
var query = $('#search-input').val();
logger.debug("query=" + query);
if (query === '') {
return hideSearchResults();
}
if (query.length > 2) {
emptySearchResults();
search(query);
}
}, 1000);
searchForInput();
}, 500);
});
$('#sidebar-search-expand').click(function(evt) {
@ -924,6 +874,7 @@
this.initialize = function(invitationDialogInstance) {
events();
initializeSearchPanel();
initializeFriendsPanel();
initializeChatPanel();
initializeNotificationsPanel();

View File

@ -287,6 +287,7 @@
}
context.JK.search = function(query, app, callback) {
logger.debug("search: "+query)
$.ajax({
type: "GET",
dataType: "json",

View File

@ -4,6 +4,7 @@
background-color:#4c4c4c;
min-height:20px;
overflow-x:hidden;
margin-top: 30px;
}
a.search-nav {

View File

@ -6,18 +6,17 @@ class ApiSearchController < ApiController
respond_to :json
def index
if 1 == params[Search::PARAM_MUSICIAN].to_i
if 1 == params[Search::PARAM_MUSICIAN].to_i || 1 == params[Search::PARAM_BAND].to_i
query = params.clone
query[:remote_ip] = request.remote_ip
@search = Search.musician_search(query, current_user)
respond_with @search, responder: ApiResponder, :status => 200
elsif 1 == params[Search::PARAM_BAND].to_i
query = params.clone
query[:remote_ip] = request.remote_ip
@search = Search.band_search(query, current_user)
if 1 == params[Search::PARAM_MUSICIAN].to_i
@search = Search.musician_filter(query, current_user)
else
@search = Search.band_filter(query, current_user)
end
respond_with @search, responder: ApiResponder, :status => 200
else
@search = Search.search(params[:query], current_user.id)
@search = Search.text_search(params, current_user)
end
end
end

View File

@ -1,13 +1,15 @@
object @search
if @search.bands.present?
child(:bands => :bands) {
attributes :id, :name, :location, :photo_url, :logo_url
node :search_type do |ss| ss.search_type end
if @search.bands_text_search?
child(:results => :bands) {
attributes :id, :name, :location, :photo_url, :logo_url, :website
}
end
if @search.musicians.present?
child(:musicians => :musicians) {
if @search.musicians_text_search?
child(:results => :musicians) {
attributes :id, :first_name, :last_name, :name, :location, :photo_url
node :is_friend do |musician|
@ -20,7 +22,7 @@ if @search.musicians.present?
}
end
if @search.musicians_filter.present?
if @search.musicians_filter_search?
node :city do |user|
current_user.try(:location)
@ -30,7 +32,7 @@ if @search.musicians_filter.present?
@search.page_count
end
child(:musicians_filter => :musicians) {
child(:results => :musicians) {
attributes :id, :first_name, :last_name, :name, :city, :state, :country, :email, :online, :musician, :photo_url, :biography
node :is_friend do |musician|
@ -58,14 +60,14 @@ if @search.musicians_filter.present?
}
end
if @search.bands_filter.present?
if @search.bands_filter_search?
node :page_count do |foo|
@search.page_count
end
child(:bands_filter => :bands) {
attributes :id, :name, :city, :state, :country, :email, :photo_url, :biography, :logo_url
child(:results => :bands) {
attributes :id, :name, :city, :state, :country, :email, :photo_url, :biography, :logo_url, :website
node :is_following do |band|
@search.is_follower?(band)
@ -88,8 +90,8 @@ if @search.bands_filter.present?
}
end
unless @search.fans.nil? || @search.fans.size == 0
child(:fans => :fans) {
if @search.fans_text_search?
child(:results => :fans) {
attributes :id, :first_name, :last_name, :name, :location, :photo_url
node :is_friend do |fan|
@ -98,14 +100,3 @@ unless @search.fans.nil? || @search.fans.size == 0
}
end
unless @search.recordings.nil? || @search.recordings.size == 0
child(:recordings => :recordings) {
attributes :id, :name
}
end
unless @search.friends.nil? || @search.friends.size == 0
child(:friends => :friends) {
attributes :id, :first_name, :last_name, :name, :location, :email, :online, :photo_url, :musician
}
end

View File

@ -12,10 +12,9 @@
<span id="result-count"></span><span id="query"></span>
</div>
<div class="left ml35">
<a id="musician-search" href="#" class="search-nav active">MUSICIANS</a>
<a id="band-search" href="#" class="search-nav">BANDS</a>
<a id="fan-search" href="#" class="search-nav">FANS</a>
<a id="recording-search" href="#" class="search-nav">RECORDINGS</a>
<a data-search_text_type='musicians' id="musician-search-result" href="#" class="search-nav active">MUSICIANS</a>
<a data-search_text_type='bands' id="band-search-result" href="#" class="search-nav">BANDS</a>
<a data-search_text_type='fans' id="fan-search-result" href="#" class="search-nav">FANS</a>
</div>
</div>
<div class="content-scroller">
@ -24,7 +23,7 @@
</div>
</div>
<script type="text/template" id="template-search-result">
<script type="text/template" id="template-musicians-search-result">
<div user-id="{userId}" class="search-result">
<a href="#" class="avatar-small"><img src="{avatar_url}" /></a>
<div class="search-result-name"><a href="{profile_url}">{userName}</a><br />
@ -49,3 +48,24 @@
</div>
</div>
</script>
<script type="text/template" id="template-bands-search-result">
<div user-id="{bandId}" class="search-result">
<a href="#" class="avatar-small"><img src="{avatar_url}" /></a>
<div class="search-result-name"><a href="{band_url}">{bandName}</a><br />
<span class="search-result-location">{location}</span>
</div>
<br clear="left" />
</div>
</script>
<script type="text/template" id="template-fans-search-result">
<div user-id="{userId}" class="search-result">
<a href="#" class="avatar-small"><img src="{avatar_url}" /></a>
<div class="search-result-name"><a href="{profile_url}">{userName}</a><br />
<span class="search-result-location">{location}</span>
</div>
<br clear="left" />
</div>
</script>

View File

@ -25,13 +25,7 @@
</div>
<!-- search filter dropdown -->
<div class="right">
Show:
<select>
<option>Musicians</option>
<option>Bands</option>
<option>Fans</option>
<option>Recordings</option>
</select>
Show:&nbsp;<%= select_tag(Search::SEARCH_TEXT_TYPE_ID, options_for_select(Search::SEARCH_TEXT_TYPES.collect { |ii| [ii.to_s.titleize, ii] })) %>
</div>
</div>
</div>
@ -130,7 +124,7 @@
</div>
<!-- Search result template -->
<script type="text/template" id="template-sidebar-search-result">
<script type="text/template" id="template-musicians-sidebar-search-result">
<div user-id="{userId}" class="sidebar-search-result">
<a class="avatar-small"><img src="{avatar_url}" /></a>
<div class="result-name"><a href="{profile_url}">{userName}</a><br />
@ -140,6 +134,23 @@
<br clear="all" />
</div>
</script>
<script type="text/template" id="template-bands-sidebar-search-result">
<div band-id="{bandId}" class="sidebar-search-result">
<a class="avatar-small"><img src="{avatar_url}" /></a>
<div class="result-name"><a href="{band_url}">{bandName}</a><br />
<span class="result-location">{location}</span>
</div><br />
</div>
</script>
<script type="text/template" id="template-fans-sidebar-search-result">
<div user-id="{userId}" class="sidebar-search-result">
<a class="avatar-small"><img src="{avatar_url}" /></a>
<div class="result-name"><a href="{profile_url}">{userName}</a><br />
<span class="result-location">{location}</span>
</div><br />
<br clear="all" />
</div>
</script>
<!-- Friend panel template -->
<script type="text/template" id="template-friend-panel">
@ -200,4 +211,4 @@
</div>
<br clear="all" />
</li>
</script>
</script>

View File

@ -59,7 +59,7 @@ describe "Musician Search API", :type => :api do
it "gets no musicians for unused instruments" do
get_query({:instrument => 'tuba'})
good_response
expect(json.count).to be 0
expect(json.count).to eq(0)
end
end

View File

@ -16,7 +16,7 @@ describe "Search API", :type => :api do
it "empty search" do
get '/api/search.json'
last_response.status.should == 200
JSON.parse(last_response.body).should eql(JSON.parse('{}'))
JSON.parse(last_response.body).should eql({'search_type'=>nil})
end
it "simple search" do
@ -25,25 +25,15 @@ describe "Search API", :type => :api do
@band = Band.save(nil, "Peach pit", "www.bands.com", "zomg we rock", "Apex", "NC", "US", ["hip hop"], user.id, nil, nil)
@band2 = Band.save(nil, "Peach", "www.bands2.com", "zomg we rock", "Apex", "NC", "US", ["hip hop"], user.id, nil, nil)
get '/api/search.json?query=peach'
get '/api/search.json?query=peach&search_text_type=bands'
last_response.status.should == 200
response = JSON.parse(last_response.body)
response["musicians"].length.should == 1
musician = response["musicians"][0]
musician["id"].should == @musician.id
response["fans"].length.should == 1
fan = response["fans"][0]
fan["id"].should == @fan.id
response["bands"].length.should == 2
bands = response["bands"]
bands = [bands[0]["id"], bands[1]["id"]]
bands.should include(@band.id)
bands.should include(@band2.id)
response["recordings"].should == nil
end
end
end