Merge branch 'musicians_page' into develop
This commit is contained in:
commit
743048e95b
|
|
@ -37,7 +37,7 @@ end
|
|||
|
||||
group :test do
|
||||
gem "factory_girl", '4.1.0'
|
||||
gem "rspec", "2.10.0"
|
||||
gem "rspec", "2.11"
|
||||
gem 'spork', '0.9.0'
|
||||
gem 'database_cleaner', '0.7.0'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -83,9 +83,10 @@ module JamRuby
|
|||
|
||||
attr_accessor :user_counters, :page_num, :page_count
|
||||
|
||||
PARAM_MUSICIAN = :search_m
|
||||
PARAM_MUSICIAN = :srch_m
|
||||
|
||||
M_PER_PAGE = 10
|
||||
M_MILES_DEFAULT = 500
|
||||
|
||||
M_ORDER_FOLLOWS = ['Most Followed', :followed]
|
||||
M_ORDER_PLAYS = ['Most Plays', :plays]
|
||||
|
|
@ -99,21 +100,20 @@ module JamRuby
|
|||
end
|
||||
|
||||
def self.musician_search(params={}, current_user=nil)
|
||||
rel = User.where(:musician => true)
|
||||
rel = User.musicians
|
||||
unless (instrument = params[:instrument]).blank?
|
||||
rel = rel.joins("RIGHT JOIN musicians_instruments AS minst ON minst.user_id = users.id")
|
||||
.where(['minst.instrument_id = ? AND users.id IS NOT NULL', instrument])
|
||||
end
|
||||
|
||||
location_distance, location_city = params[:distance], params[:city]
|
||||
distance, latlng = nil, []
|
||||
if location_distance && location_city
|
||||
if geo = MaxMindGeo.where(:city => params[:city]).limit(1).first
|
||||
citylatlng = [geo.lat, geo.lng]
|
||||
rel = rel.within(location_distance, :origin => citylatlng)
|
||||
distance, latlng = location_distance, [geo.lat, geo.lng]
|
||||
end
|
||||
elsif current_user
|
||||
latlng = []
|
||||
if current_user.lat.nil?
|
||||
if current_user.lat.nil? || current_user.lng.nil?
|
||||
if params[:remote_ip]
|
||||
if geo = MaxMindGeo.ip_lookup(params[:remote_ip])
|
||||
latlng = [geo.lat, geo.lng] if geo.lat && geo.lng
|
||||
|
|
@ -122,16 +122,15 @@ module JamRuby
|
|||
else
|
||||
latlng = [current_user.lat, current_user.lng]
|
||||
end
|
||||
distance = location_distance || 50
|
||||
unless latlng.blank?
|
||||
rel = rel.where(['lat IS NOT NULL AND lng IS NOT NULL'])
|
||||
.within(distance, :origin => latlng)
|
||||
end
|
||||
distance = location_distance || M_MILES_DEFAULT
|
||||
end
|
||||
unless latlng.blank?
|
||||
rel = rel.where(['lat IS NOT NULL AND lng IS NOT NULL'])
|
||||
.within(distance, :origin => latlng)
|
||||
end
|
||||
|
||||
sel_str = 'users.*'
|
||||
case ordering = self.musician_order_param(params)
|
||||
when :plays
|
||||
when :plays # FIXME: double counting?
|
||||
sel_str = "COUNT(records)+COUNT(sessions) AS play_count, #{sel_str}"
|
||||
rel = rel.joins("LEFT JOIN music_sessions AS sessions ON sessions.user_id = users.id")
|
||||
rel = rel.joins("LEFT JOIN recordings AS records ON records.owner_id = users.id")
|
||||
|
|
@ -150,7 +149,7 @@ module JamRuby
|
|||
end
|
||||
|
||||
rel = rel.select(sel_str)
|
||||
perpage = params[:per_page] || M_PER_PAGE
|
||||
perpage = [params[:per_page] || M_PER_PAGE, 100].min
|
||||
page = [params[:page].to_i, 1].max
|
||||
rel = rel.paginate(:page => page, :per_page => perpage)
|
||||
rel.includes([:instruments, :followings, :friends])
|
||||
|
|
@ -205,6 +204,8 @@ module JamRuby
|
|||
self
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def _count(musician, key)
|
||||
if mm = @user_counters[musician.id]
|
||||
return mm.detect { |ii| ii.is_a?(Hash) }[key]
|
||||
|
|
@ -212,6 +213,8 @@ module JamRuby
|
|||
0
|
||||
end
|
||||
|
||||
public
|
||||
|
||||
def follow_count(musician)
|
||||
_count(musician, COUNT_FOLLOW)
|
||||
end
|
||||
|
|
@ -247,5 +250,17 @@ module JamRuby
|
|||
false
|
||||
end
|
||||
|
||||
def self.new_musicians(since_date=Time.now - 1.week, max_count=100, radius=M_MILES_DEFAULT)
|
||||
return unless block_given?
|
||||
User.where(['lat IS NOT NULL AND lng IS NOT NULL']).find_each do |usr|
|
||||
rel = User.musicians
|
||||
.where(['created_at >= ? AND users.id != ?', since_date, usr.id])
|
||||
.within(radius, :origin => [usr.lat, usr.lng])
|
||||
.order('created_at DESC')
|
||||
.limit(max_count)
|
||||
yield(rel) if 0 < rel.count
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -138,6 +138,9 @@ module JamRuby
|
|||
validate :email_case_insensitive_uniqueness
|
||||
validate :update_email_case_insensitive_uniqueness, :if => :updating_email
|
||||
|
||||
scope :musicians, where(:musician => true)
|
||||
scope :musicians_geocoded, where(['musician = ? AND lat IS NOT NULL AND lng IS NOT NULL',true])
|
||||
|
||||
def user_progression_fields
|
||||
@user_progression_fields ||= Set.new ["first_downloaded_client_at", "first_ran_client_at", "first_music_session_at", "first_real_music_session_at", "first_good_music_session_at", "first_certified_gear_at", "first_invited_at", "first_friended_at", "first_social_promoted_at" ]
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,171 +1,218 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe User do
|
||||
describe 'Musician search' do
|
||||
|
||||
before(:each) do
|
||||
@geocode1 = FactoryGirl.create(:geocoder)
|
||||
@geocode2 = FactoryGirl.create(:geocoder)
|
||||
params = {
|
||||
first_name: "Example",
|
||||
last_name: "User",
|
||||
email: "user1@example.com",
|
||||
password: "foobar",
|
||||
password_confirmation: "foobar",
|
||||
musician: true,
|
||||
email_confirmed: true,
|
||||
city: "Apex",
|
||||
state: "NC",
|
||||
country: "US"
|
||||
}
|
||||
@users = []
|
||||
@users << @user1 = FactoryGirl.create(:user, params)
|
||||
params[:email] = "user2@example.com"
|
||||
@users << @user2 = FactoryGirl.create(:user, params)
|
||||
params[:email] = "user3@example.com"
|
||||
@users << @user3 = FactoryGirl.create(:user, params)
|
||||
params[:email] = "user4@example.com"
|
||||
@users << @user4 = FactoryGirl.create(:user, params)
|
||||
@users << @user1 = FactoryGirl.create(:user)
|
||||
@users << @user2 = FactoryGirl.create(:user)
|
||||
@users << @user3 = FactoryGirl.create(:user)
|
||||
@users << @user4 = FactoryGirl.create(:user)
|
||||
end
|
||||
|
||||
it "should find all musicians sorted by followers with pagination" do
|
||||
# establish sorting order
|
||||
@user4.followers.concat([@user2, @user3, @user4])
|
||||
@user3.followers.concat([@user3, @user4])
|
||||
@user2.followers.concat([@user1])
|
||||
@user4.followers.count.should == 3
|
||||
context 'default filter settings' do
|
||||
|
||||
UserFollower.count.should == 6
|
||||
|
||||
# get all the users in correct order
|
||||
params = { :per_page => @users.size }
|
||||
results = Search.musician_search(params)
|
||||
results.musicians.count.should == @users.size
|
||||
|
||||
results.musicians.each_with_index do |uu, idx|
|
||||
uu.id.should == @users.reverse[idx].id
|
||||
it "finds all musicians" do
|
||||
# expects all the users
|
||||
num = User.musicians.count
|
||||
results = Search.musician_search({ :per_page => num })
|
||||
expect(results.musicians.count).to eq(num)
|
||||
end
|
||||
|
||||
# refresh the order to ensure it works right
|
||||
@user2.followers.concat([@user3, @user4, @user2])
|
||||
results = Search.musician_search(params, @user3)
|
||||
results.musicians[0].id.should == @user2.id
|
||||
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.each_with_index do |uu, idx|
|
||||
expect(uu.id).to eq(@users.reverse[idx].id)
|
||||
end
|
||||
end
|
||||
|
||||
# check the follower count for given entry
|
||||
results.musicians[0].search_follow_count.to_i.should_not == 0
|
||||
# check the follow relationship between current_user and result
|
||||
results.is_follower?(@user2).should == true
|
||||
it "sorts musicians by followers" do
|
||||
# establish sorting order
|
||||
@user4.followers.concat([@user2, @user3, @user4])
|
||||
@user3.followers.concat([@user3, @user4])
|
||||
@user2.followers.concat([@user1])
|
||||
expect(@user4.followers.count).to be 3
|
||||
expect(UserFollower.count).to be 6
|
||||
|
||||
# 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[0].id).to eq(@user2.id)
|
||||
|
||||
# check the follower count for given entry
|
||||
expect(results.musicians[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
|
||||
|
||||
it 'paginates properly' do
|
||||
# make sure pagination works right
|
||||
params = { :per_page => 2, :page => 1 }
|
||||
results = Search.musician_search(params)
|
||||
expect(results.musicians.count).to be 2
|
||||
end
|
||||
|
||||
# make sure pagination works right
|
||||
params = { :per_page => 2, :page => 1 }
|
||||
results = Search.musician_search(params)
|
||||
results.musicians.count.should == 2
|
||||
end
|
||||
|
||||
it "should have friends counter " do
|
||||
Friendship.save(@user1.id, @user2.id)
|
||||
results = Search.musician_search({}, @user2)
|
||||
friend = results.musicians.detect { |mm| mm.id == @user1.id }
|
||||
friend.should_not == nil
|
||||
results.friend_count(friend).should == 1
|
||||
@user1.reload
|
||||
friend.friends?(@user2).should == true
|
||||
results.is_friend?(@user1).should == true
|
||||
end
|
||||
|
||||
def make_recording(uu)
|
||||
connection = FactoryGirl.create(:connection, :user => uu)
|
||||
def make_recording(usr)
|
||||
connection = FactoryGirl.create(:connection, :user => usr)
|
||||
instrument = FactoryGirl.create(:instrument, :description => 'a great instrument')
|
||||
track = FactoryGirl.create(:track, :connection => connection, :instrument => instrument)
|
||||
music_session = FactoryGirl.create(:music_session, :creator => uu, :musician_access => true)
|
||||
music_session = FactoryGirl.create(:music_session, :creator => usr, :musician_access => true)
|
||||
music_session.connections << connection
|
||||
music_session.save
|
||||
recording = Recording.start(music_session, uu)
|
||||
recording = Recording.start(music_session, usr)
|
||||
recording.stop
|
||||
recording.reload
|
||||
genre = FactoryGirl.create(:genre)
|
||||
recording.claim(uu, "name", "description", genre, true, true)
|
||||
recording.claim(usr, "name", "description", genre, true, true)
|
||||
recording.reload
|
||||
recording
|
||||
end
|
||||
|
||||
it "should have recording counter " do
|
||||
recording = make_recording(@user1)
|
||||
recording.users.length.should == 1
|
||||
recording.users.first.should == @user1
|
||||
@user1.reload
|
||||
@user1.recordings.length.should == 1
|
||||
@user1.recordings.first.should == recording
|
||||
recording.claimed_recordings.length.should == 1
|
||||
@user1.recordings.detect { |rr| rr == recording }.should_not be nil
|
||||
|
||||
results = Search.musician_search({},@user1)
|
||||
uu = results.musicians.detect { |mm| mm.id == @user1.id }
|
||||
uu.should_not == nil
|
||||
|
||||
results.record_count(uu).should == 1
|
||||
results.session_count(uu).should == 1
|
||||
end
|
||||
|
||||
it "should find musicians sorted by plays" do
|
||||
make_recording(@user1)
|
||||
results = Search.musician_search({ :orderby => 'plays' }, @user2)
|
||||
results.musicians[0].id.should == @user1.id
|
||||
make_recording(@user2)
|
||||
make_recording(@user2)
|
||||
results = Search.musician_search({ :orderby => 'plays' }, @user2)
|
||||
results.musicians[0].id.should == @user2.id
|
||||
end
|
||||
|
||||
it "should find all musicians sorted by now playing" do
|
||||
connection = FactoryGirl.create(:connection, :user => @user3)
|
||||
music_session = FactoryGirl.create(:music_session, :creator => @user3, :musician_access => true)
|
||||
def make_session(usr)
|
||||
connection = FactoryGirl.create(:connection, :user => usr)
|
||||
music_session = FactoryGirl.create(:music_session, :creator => usr, :musician_access => true)
|
||||
music_session.connections << connection
|
||||
music_session.save
|
||||
results = Search.musician_search({ :orderby => 'playing' }, @user2)
|
||||
results.musicians.count.should == 1
|
||||
connection = FactoryGirl.create(:connection, :user => @user4)
|
||||
music_session = FactoryGirl.create(:music_session, :creator => @user4, :musician_access => true)
|
||||
music_session.connections << connection
|
||||
music_session.save
|
||||
results = Search.musician_search({ :orderby => 'playing' }, @user2)
|
||||
results.musicians.count.should == 2
|
||||
connection = FactoryGirl.create(:connection, :user => @user1)
|
||||
music_session = FactoryGirl.create(:music_session, :creator => @user1, :musician_access => true)
|
||||
music_session.connections << connection
|
||||
music_session.save
|
||||
results = Search.musician_search({ :orderby => 'playing' }, @user2)
|
||||
results.musicians.count.should == 3
|
||||
end
|
||||
|
||||
it "should find musicians with an instrument" do
|
||||
minst = FactoryGirl.create(:musician_instrument, {
|
||||
:user => @user1,
|
||||
:instrument => Instrument.find('tuba') })
|
||||
@user1.musician_instruments << minst
|
||||
@user1.reload
|
||||
ii = @user1.instruments.detect { |inst| inst.id == 'tuba' }
|
||||
ii.should_not be_nil
|
||||
params = { :instrument => ii.id }
|
||||
results = Search.musician_search(params)
|
||||
results.musicians.each do |rr|
|
||||
rr.instruments.detect { |inst| inst.id=='tuba' }.id.should == ii.id
|
||||
context 'musician stat counters' do
|
||||
|
||||
it "displays musicians top followings" do
|
||||
@user4.followers.concat([@user4])
|
||||
@user3.followers.concat([@user4])
|
||||
@user2.followers.concat([@user4])
|
||||
expect(@user4.top_followings.count).to be 3
|
||||
expect(@user4.top_followings.map(&:id)).to match_array((@users - [@user1]).map(&:id))
|
||||
end
|
||||
results.musicians.count.should == 1
|
||||
|
||||
it "friends stat shows friend count" do
|
||||
# create friendship record
|
||||
Friendship.save(@user1.id, @user2.id)
|
||||
# search on user2
|
||||
results = Search.musician_search({}, @user2)
|
||||
friend = results.musicians.detect { |mm| mm.id == @user1.id }
|
||||
expect(friend).to_not be_nil
|
||||
expect(results.friend_count(friend)).to be 1
|
||||
@user1.reload
|
||||
expect(friend.friends?(@user2)).to be true
|
||||
expect(results.is_friend?(@user1)).to be true
|
||||
end
|
||||
|
||||
it "recording stat shows recording count" do
|
||||
recording = make_recording(@user1)
|
||||
expect(recording.users.length).to be 1
|
||||
expect(recording.users.first).to eq(@user1)
|
||||
@user1.reload
|
||||
expect(@user1.recordings.length).to be 1
|
||||
expect(@user1.recordings.first).to eq(recording)
|
||||
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.detect { |mm| mm.id == @user1.id }
|
||||
expect(uu).to_not be_nil
|
||||
|
||||
expect(results.record_count(uu)).to be 1
|
||||
expect(results.session_count(uu)).to be 1
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
it "should find musicians within a given distance of location" do
|
||||
@user1.lat.should_not == nil
|
||||
params = { :distance => 10, :city => 'San Francisco' }
|
||||
results = Search.musician_search(params)
|
||||
results.musicians.count.should == 0
|
||||
context 'musician sorting' do
|
||||
|
||||
params = { :distance => 10, :city => 'Apex' }
|
||||
results = Search.musician_search(params)
|
||||
results.musicians.count.should == User.count
|
||||
it "by plays" do
|
||||
make_recording(@user1)
|
||||
# order results by num recordings
|
||||
results = Search.musician_search({ :orderby => 'plays' }, @user2)
|
||||
expect(results.musicians[0].id).to eq(@user1.id)
|
||||
|
||||
params = { :distance => 10 }
|
||||
results = Search.musician_search(params)
|
||||
results.musicians.count.should == User.count
|
||||
# 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[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.count).to be 1
|
||||
expect(results.musicians.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.count).to be 2
|
||||
expect(results.musicians[0].id).to eq(@user4.id)
|
||||
expect(results.musicians[1].id).to eq(@user3.id)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'filter settings' do
|
||||
it "searches musicisns for an instrument" do
|
||||
minst = FactoryGirl.create(:musician_instrument, {
|
||||
:user => @user1,
|
||||
:instrument => Instrument.find('tuba') })
|
||||
@user1.musician_instruments << minst
|
||||
@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.each do |rr|
|
||||
expect(rr.instruments.detect { |inst| inst.id=='tuba' }.id).to eq(ii.id)
|
||||
end
|
||||
expect(results.musicians.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,
|
||||
:distance => 10,
|
||||
:city => 'Apex' }, @user1)
|
||||
expect(results.musicians.count).to be num
|
||||
# long distance
|
||||
results = Search.musician_search({ :per_page => num,
|
||||
:distance => 1000,
|
||||
:city => 'Miami',
|
||||
:state => 'FL' }, @user1)
|
||||
expect(results.musicians.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.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.count).to be 0
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'new users' do
|
||||
it "find nearby" do
|
||||
# create new user to ensure its excluded from results
|
||||
usr = FactoryGirl.create(:user, {city: "Austin", state: "TX", country: "US"})
|
||||
Search.new_musicians do |usrs|
|
||||
# the newly created user is not nearby the existing users (which are in Apex, NC)
|
||||
# and that user is not included in query
|
||||
expect(usrs.count).to eq(User.musicians.count - 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
function search() {
|
||||
did_show_musician_page = true;
|
||||
var queryString = 'search_m=1&page='+page_num+'&';
|
||||
var queryString = 'srch_m=1&page='+page_num+'&';
|
||||
|
||||
// order by
|
||||
var orderby = $('.musician-order-by').val();
|
||||
|
|
|
|||
|
|
@ -1,28 +1,35 @@
|
|||
<div style="min-width:770px;">
|
||||
<div class="filter-element">
|
||||
<div class="filter-element" style="padding-top:3px;">Filter By:</div>
|
||||
<%= content_tag(:div, :style => "min-width:770px;") do -%>
|
||||
<%= content_tag(:div, :class => 'filter-element') do -%>
|
||||
<%= content_tag(:div, 'Filter By:', :class => 'filter-element', :style => "padding-top:3px;") %>
|
||||
<!-- order by filter -->
|
||||
<%= select_tag(:musician_order_by, options_for_select(Search::M_ORDERINGS), {:class => 'musician-order-by'} ) %>
|
||||
</div>
|
||||
<div class="filter-element">
|
||||
<% end -%>
|
||||
<%= content_tag(:div, :class => 'filter-element') do -%>
|
||||
<!-- instrument filter -->
|
||||
<div class="filter-element" style="">Instrument:</div>
|
||||
<div id="find-musician-instrument" class="filter-element">
|
||||
<%= content_tag(:div, 'Instrument:', :class => 'filter-element') %>
|
||||
<%= content_tag(:div, :class => 'filter-element', :id => "find-musician-instrument") do -%>
|
||||
<%= select_tag(:instrument,
|
||||
options_for_select([['Any', '']].concat(JamRuby::Instrument.all.collect { |ii| [ii.description, ii.id] })),
|
||||
{:class => 'instrument-list'} ) %>
|
||||
</div>
|
||||
</div>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<!-- distance filter -->
|
||||
<div class="filter-element">
|
||||
<div class="filter-element">Within</div>
|
||||
<div class="query-distance-params" style="height:25px; ">
|
||||
<input id="musician_query_distance" type="text" name="query_distance" value="500" placeholder="500" />
|
||||
</div>
|
||||
<div class="filter-element">miles of <span id="musician-filter-city"><%= current_user.current_city(request.remote_ip) %></span></div>
|
||||
</div>
|
||||
<div class="right mr10">
|
||||
<a id="btn-refresh-musicians" style="text-decoration:none;" class="button-grey">REFRESH</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<%= content_tag(:div, :class => 'filter-element') do -%>
|
||||
<%= content_tag(:div, 'Within', :class => 'filter-element') %>
|
||||
<%= content_tag(:div, :class => 'query-distance-params', :style => "height:25px;") do -%>
|
||||
<%= text_field_tag(:query_distance,
|
||||
Search::M_MILES_DEFAULT.to_s,
|
||||
:id => :musician_query_distance,
|
||||
:placeholder => Search::M_MILES_DEFAULT.to_s) %>
|
||||
<% end -%>
|
||||
<%= content_tag(:div, :class => 'filter-element') do -%>
|
||||
miles of <%= content_tag(:span, current_user.current_city(request.remote_ip), :id => 'musician-filter-city') %>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<%= content_tag(:div,
|
||||
link_to('REFRESH', '#',
|
||||
:id => 'btn-refresh-musicians',
|
||||
:style => 'text-decoration:none',
|
||||
:class => 'button-grey'),
|
||||
:class => 'right mr10') %>
|
||||
<% end -%>
|
||||
|
|
|
|||
|
|
@ -1,26 +1,19 @@
|
|||
<!-- Musician Screen -->
|
||||
<div layout="screen" layout-id="musicians" class="screen secondary">
|
||||
<div class="content">
|
||||
<div class="content-head">
|
||||
<div class="content-icon">
|
||||
<%= image_tag "content/icon_musicians.png", {:height => 19, :width => 19} %>
|
||||
</div>
|
||||
|
||||
<h1>musicians</h1>
|
||||
<%= content_tag(:div, :layout => 'screen', 'layout-id' => 'musicians', :class => "screen secondary") do -%>
|
||||
<%= content_tag(:div, :class => :content) do -%>
|
||||
<%= content_tag(:div, :class => 'content-head') do -%>
|
||||
<%= content_tag(:div, image_tag("content/icon_musicians.png", {:height => 19, :width => 19}), :class => 'content-icon') %>
|
||||
<%= content_tag(:h1, 'musicians') %>
|
||||
<%= render "screen_navigation" %>
|
||||
</div>
|
||||
<form id="find-musician-form">
|
||||
<div class="musician-filter" id="session-controls">
|
||||
<%= render :partial => "musician_filter" %>
|
||||
</div>
|
||||
<div class="content-scroller">
|
||||
<div class="content-wrapper musician-wrapper">
|
||||
<div id="musician-filter-results"></div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<% end -%>
|
||||
<%= form_tag('', :id => 'find-musician-form') do -%>
|
||||
<%= content_tag(:div, render(:partial => "musician_filter"), :class => 'musician-filter', :id => 'session-controls') %>
|
||||
<%= content_tag(:div, :class => 'content-scroller') do -%>
|
||||
<%= content_tag(:div, content_tag(:div, '', :id => 'musician-filter-results'), :class => 'content-wrapper musician-wrapper') %>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
|
||||
<!-- Session Row Template -->
|
||||
<script type="text/template" id="template-find-musician-row">
|
||||
|
|
|
|||
|
|
@ -128,5 +128,14 @@ FactoryGirl.define do
|
|||
end
|
||||
|
||||
|
||||
|
||||
factory :geocoder, :class => JamRuby::MaxMindGeo do
|
||||
country 'US'
|
||||
sequence(:region) { |n| ['NC', 'CA'][(n-1).modulo(2)] }
|
||||
sequence(:city) { |n| ['Apex', 'San Francisco'][(n-1).modulo(2)] }
|
||||
sequence(:ip_start) { |n| ['1.1.0.0', '1.1.255.255'][(n-1).modulo(2)] }
|
||||
sequence(:ip_end) { |n| ['1.2.0.0', '1.2.255.255'][(n-1).modulo(2)] }
|
||||
sequence(:lat) { |n| [35.73265, 37.7742075][(n-1).modulo(2)] }
|
||||
sequence(:lng) { |n| [-78.85029, -122.4155311][(n-1).modulo(2)] }
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe "Musician Search", :js => true, :type => :feature, :capybara_feature => true do
|
||||
|
||||
subject { page }
|
||||
|
||||
let(:user) { FactoryGirl.create(:user) }
|
||||
|
||||
before(:all) do
|
||||
poltergeist_setup
|
||||
end
|
||||
|
||||
before(:each) do
|
||||
sign_in_poltergeist user
|
||||
visit "/client#/musicians"
|
||||
end
|
||||
|
||||
it "shows the musician search page" do
|
||||
expect(page).to have_selector('#find-musician-form')
|
||||
end
|
||||
|
||||
it "shows search results" do
|
||||
expect(page).to have_selector('#musician-filter-results .musician-list-result')
|
||||
end
|
||||
|
||||
it "shows submits query" do
|
||||
find("a#btn-refresh-musicians").trigger(:click)
|
||||
expect(page).to have_selector('#musician-filter-results .musician-list-result')
|
||||
end
|
||||
|
||||
it "shows blank result set" do
|
||||
expect(page).to have_selector('#instrument')
|
||||
find('#instrument').find(:xpath, 'option[2]').select_option
|
||||
find("a#btn-refresh-musicians").trigger(:click)
|
||||
expect(page).to_not have_selector('#musician-filter-results .musician-list-result')
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -6,89 +6,86 @@ describe "Musician Search API", :type => :api do
|
|||
|
||||
def get_query(query={})
|
||||
qstr = ''
|
||||
query.each { |kk,vv| qstr += "#{kk}=#{vv}&" }
|
||||
get "/api/search.json?#{Search::PARAM_MUSICIAN}=1&#{qstr}"
|
||||
query.each { |kk,vv| qstr += "#{kk}=#{CGI::escape(vv.to_s)}&" }
|
||||
uri = "/api/search.json?#{Search::PARAM_MUSICIAN}=1&#{qstr}"
|
||||
get uri, "CONTENT_TYPE" => 'application/json'
|
||||
end
|
||||
|
||||
|
||||
describe "profile page" do
|
||||
describe "musician search page" do
|
||||
let(:user) { FactoryGirl.create(:user) }
|
||||
|
||||
before(:each) do
|
||||
post '/sessions', "session[email]" => user.email, "session[password]" => user.password
|
||||
rack_mock_session.cookie_jar["remember_token"].should == user.remember_token
|
||||
end
|
||||
|
||||
it "blank search" do
|
||||
get_query
|
||||
last_response.status.should == 200
|
||||
sobj = JSON.parse(last_response.body)
|
||||
sobj.count.should >= 1
|
||||
sobj['musicians'].count.should == [Search::M_PER_PAGE,
|
||||
User.where(:musician => true).count].min
|
||||
end
|
||||
|
||||
it "instrument search" do
|
||||
minst = FactoryGirl.create(:musician_instrument, {
|
||||
:user => user,
|
||||
:instrument => Instrument.find('tuba') })
|
||||
user.musician_instruments << minst
|
||||
|
||||
get_query({:instrument => 'tuba'})
|
||||
last_response.status.should == 200
|
||||
response = JSON.parse(last_response.body)
|
||||
|
||||
response["musicians"].length.should == 1
|
||||
musician = response["musicians"][0]
|
||||
musician["id"].should == user.id
|
||||
instruments = musician['instruments']
|
||||
instruments.detect { |ii| ii['instrument_id'] == 'tuba' }.should_not == nil
|
||||
instruments.detect { |ii| ii['instrument_id'] == 'electric guitar' }.should_not == nil
|
||||
end
|
||||
|
||||
it "following search" do
|
||||
params = {
|
||||
first_name: "Example",
|
||||
last_name: "User",
|
||||
email: "user1@example.com",
|
||||
password: "foobar",
|
||||
password_confirmation: "foobar",
|
||||
musician: true,
|
||||
email_confirmed: true,
|
||||
city: "Apex",
|
||||
state: "NC",
|
||||
country: "US"
|
||||
}
|
||||
2.downto(1) { FactoryGirl.create(:geocoder) }
|
||||
@users = []
|
||||
@users << @user1 = FactoryGirl.create(:user, params)
|
||||
params[:email] = "user2@example.com"
|
||||
@users << @user2 = FactoryGirl.create(:user, params)
|
||||
params[:email] = "user3@example.com"
|
||||
@users << @user3 = FactoryGirl.create(:user, params)
|
||||
params[:email] = "user4@example.com"
|
||||
@users << @user4 = FactoryGirl.create(:user, params)
|
||||
@user4.followers.concat([@user2, @user3, @user4])
|
||||
@user3.followers.concat([@user3, @user4])
|
||||
@user2.followers.concat([@user4])
|
||||
@user4.followers.count.should == 3
|
||||
@users << @user1 = FactoryGirl.create(:user)
|
||||
@users << @user2 = FactoryGirl.create(:user)
|
||||
@users << @user3 = FactoryGirl.create(:user)
|
||||
@users << @user4 = FactoryGirl.create(:user)
|
||||
|
||||
Friendship.save(@user1.id, @user2.id)
|
||||
post '/sessions', "session[email]" => user.email, "session[password]" => user.password
|
||||
expect(rack_mock_session.cookie_jar["remember_token"]).to eq(user.remember_token)
|
||||
end
|
||||
|
||||
it "default search" do
|
||||
get_query
|
||||
last_response.status.should == 200
|
||||
response = JSON.parse(last_response.body)
|
||||
|
||||
musician = response["musicians"][0]
|
||||
musician["id"].should == @user4.id
|
||||
followings= musician['followings']
|
||||
followings.length.should == 3
|
||||
musician['follow_count'].to_i.should > 0
|
||||
good_response
|
||||
expect(json['musicians'].count).to be [Search::M_PER_PAGE, User.musicians_geocoded.count].min
|
||||
end
|
||||
|
||||
friend = response['musicians'].detect { |mm| mm['id'] == @user1.id }
|
||||
friend['friend_count'].should == 1
|
||||
context 'location filtering' do
|
||||
|
||||
musician['recording_count'].should == 0
|
||||
musician['session_count'].should == 0
|
||||
it "gets no musicians for out of range locations" do
|
||||
get_query({:city => 'San Francisco', :distance => 100})
|
||||
good_response
|
||||
expect((json['musicians'] || []).count).to be 0
|
||||
end
|
||||
|
||||
it "gets musicians for long-distance locations" do
|
||||
get_query({:city => 'Miami', :distance => 1000})
|
||||
good_response
|
||||
expect(json['musicians'].count).to be >= 1
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'instrument filtering' do
|
||||
|
||||
it "gets musicians for default instrument" do
|
||||
get_query({:instrument => 'electric guitar'})
|
||||
good_response
|
||||
expect(json.count).to be >= 1
|
||||
end
|
||||
|
||||
it "gets no musicians for unused instruments" do
|
||||
get_query({:instrument => 'tuba'})
|
||||
good_response
|
||||
expect(json.count).to be 0
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'results have expected data' do
|
||||
it "has follower stats " do
|
||||
@user4.followers.concat([@user2, @user3, @user4])
|
||||
@user3.followers.concat([@user3, @user4])
|
||||
@user2.followers.concat([@user4])
|
||||
expect(@user4.followers.count).to be 3
|
||||
get_query
|
||||
good_response
|
||||
musician = json["musicians"][0]
|
||||
expect(musician["id"]).to eq(@user4.id)
|
||||
followings = musician['followings']
|
||||
expect(followings.length).to be 3
|
||||
expect(musician['follow_count'].to_i).to be > 0
|
||||
end
|
||||
|
||||
it "has friend stats" do
|
||||
Friendship.save(@user1.id, @user2.id)
|
||||
get_query
|
||||
good_response
|
||||
friend = json['musicians'].detect { |mm| mm['id'] == @user1.id }
|
||||
expect(friend['friend_count']).to be 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -93,6 +93,9 @@ Spork.prefork do
|
|||
# rspec-rails.
|
||||
config.infer_base_class_for_anonymous_controllers = false
|
||||
|
||||
config.include Requests::JsonHelpers, type: :request
|
||||
config.include Requests::FeatureHelpers, type: :feature
|
||||
|
||||
config.before(:suite) do
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
module Requests
|
||||
|
||||
module FeatureHelpers
|
||||
|
||||
def poltergeist_setup
|
||||
Capybara.javascript_driver = :poltergeist
|
||||
Capybara.current_driver = Capybara.javascript_driver
|
||||
Capybara.default_wait_time = 30 # these tests are SLOOOOOW
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
module JsonHelpers
|
||||
|
||||
def json
|
||||
@json ||= JSON.parse(last_response.body)
|
||||
end
|
||||
|
||||
def good_response
|
||||
expect(last_response.status).to be 200
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue