more filter parameters to neo4j

* pass genres and instrument parameters to neo4j
* remove filtering based on these params using rails and pg data
* pass pagination offset to neo4j
This commit is contained in:
Nuwan 2022-02-08 20:55:00 +05:30
parent a4d8bc70b0
commit 3f5cceb031
11 changed files with 426 additions and 327 deletions

7
jam-ui/.env.development Normal file
View File

@ -0,0 +1,7 @@
HOST=beta.jamkazam.local
PORT=4000
REACT_APP_ORIGIN=jamkazam.local
REACT_APP_LEGACY_BASE_URL=http://www.jamkazam.local:3000
REACT_APP_API_BASE_URL=http://www.jamkazam.local:3000/api
REACT_APP_BITBUCKET_BUILD_NUMBER=dev
REACT_APP_BITBUCKET_COMMIT=dev

View File

@ -42,7 +42,7 @@ const closeSidePanel = () => {
cy.get('[data-testid=profileSidePanel] .modal-header button.close').click(); cy.get('[data-testid=profileSidePanel] .modal-header button.close').click();
}; };
describe.only('Friends page without data', () => { describe('Friends page without data', () => {
beforeEach(() => { beforeEach(() => {
cy.stubAuthenticate(); cy.stubAuthenticate();
cy.intercept('POST', /\S+\/filter/, { cy.intercept('POST', /\S+\/filter/, {
@ -402,7 +402,7 @@ describe('Friends page with data', () => {
}); });
cy.get('button') cy.get('button')
.contains('Close') .contains('Cancel')
.should('not.be.disabled') .should('not.be.disabled')
.click(); .click();
}); });
@ -454,7 +454,7 @@ describe('Friends page with data', () => {
.click(); .click();
cy.get('[data-testid=textMessageModal]').within(() => { cy.get('[data-testid=textMessageModal]').within(() => {
cy.get('button') cy.get('button')
.contains('Close') .contains('Cancel')
.should('not.be.disabled') .should('not.be.disabled')
.click(); .click();
}); });
@ -483,8 +483,8 @@ describe('Friends page with data', () => {
cy.get('#selGenres') cy.get('#selGenres')
.type('Pop{enter}') .type('Pop{enter}')
.click(); .click();
cy.get('#selLastActive').type('Within last 1 Day{enter}'); //cy.get('#selLastActive').type('Within last 1 Day{enter}');
cy.get('#selJoinedWithin').type('Within last 7 Day{enter}'); //cy.get('#selJoinedWithin').type('Within last 7 Day{enter}');
}; };
beforeEach(() => { beforeEach(() => {

View File

@ -358,7 +358,7 @@ function JKPeopleFilter() {
)} )}
/> />
</div> </div>
<label className="form-label" htmlFor="lastActive"> {/* <label className="form-label" htmlFor="lastActive">
Last Active{' '} Last Active{' '}
<JKTooltip title="Use this list to search for other musicians who have been active on JamKazam within a specified time period. More recent activity makes it more likely they will respond if you message or request to connect." /> <JKTooltip title="Use this list to search for other musicians who have been active on JamKazam within a specified time period. More recent activity makes it more likely they will respond if you message or request to connect." />
</label> </label>
@ -379,7 +379,7 @@ function JKPeopleFilter() {
control={control} control={control}
render={({ field }) => <Select {...field} options={joinedOpts} id="selJoinedWithin" />} render={({ field }) => <Select {...field} options={joinedOpts} id="selJoinedWithin" />}
/> />
</div> </div> */}
<label className="form-label" htmlFor="from_location"> <label className="form-label" htmlFor="from_location">
Search by My Location{' '} Search by My Location{' '}

1
ruby/.gitignore vendored
View File

@ -24,3 +24,4 @@ vendor
*.iml *.iml
.byebug_history .byebug_history
.ruby-version .ruby-version
.rails5-gems

View File

@ -208,7 +208,12 @@ module JamRuby
filter = self.data_blob filter = self.data_blob
end end
#NOTE: user_ids parameter is used to track users returned from neo4j user's latency data service. if this variable is not null means we are calling this method with user_ids returned from neo4j
if user_ids
rel = do_filter(user_ids)
else
rel = do_search(filter, user_ids) rel = do_search(filter, user_ids)
end
@page_number = [page.to_i, 1].max @page_number = [page.to_i, 1].max
rel = rel.paginate(:page => @page_number, :per_page => self.class::PER_PAGE) rel = rel.paginate(:page => @page_number, :per_page => self.class::PER_PAGE)

View File

@ -160,7 +160,7 @@ module JamRuby
rel.order('x.ordering') rel.order('x.ordering')
end end
def do_search(params={}, user_ids) def do_filter(user_ids)
rel = User.musicians.where('users.id <> ?', self.user.id) rel = User.musicians.where('users.id <> ?', self.user.id)
#user_ids parameter is used to track users returned from neo4j user's latency data service. #if this variable is not null means we are calling this method with neo4j latency data (currently this call only comes from api_search_controller#filter) #user_ids parameter is used to track users returned from neo4j user's latency data service. #if this variable is not null means we are calling this method with neo4j latency data (currently this call only comes from api_search_controller#filter)
@ -168,9 +168,9 @@ module JamRuby
unless user_ids.nil? unless user_ids.nil?
if user_ids.empty? if user_ids.empty?
return User.none # no user_ids have been passed from latency service. which means no results for the latency based filter conditions. So we return an empty data set rel = User.none # no user_ids have been passed from latency service. which means no results for the latency based filter conditions. So we return an empty data set
else else
rel = rel.where(id: user_ids).where('users.id <> ?', self.user.id) rel = rel.where(id: user_ids)
#following line does not work in postgresql 9.3 - array_position function was intruduced in postgresql 9.4 #following line does not work in postgresql 9.3 - array_position function was intruduced in postgresql 9.4
#NOTE: we can change to this once we upgrade postgresql #NOTE: we can change to this once we upgrade postgresql
@ -179,6 +179,11 @@ module JamRuby
rel = self._sort_by_ids_ordinality(rel, user_ids) rel = self._sort_by_ids_ordinality(rel, user_ids)
end end
end end
rel
end
def do_search(params={}, user_ids)
rel = User.musicians.where('users.id <> ?', self.user.id)
rel = Search.scope_schools_together(rel, self.user) rel = Search.scope_schools_together(rel, self.user)
rel = self._genres(rel) rel = self._genres(rel)
@ -194,8 +199,6 @@ module JamRuby
rel rel
end end
def search_includes(rel) def search_includes(rel)
rel.includes([:instruments, :followings, :friends]) rel.includes([:instruments, :followings, :friends])
end end

1
web/.gitignore vendored
View File

@ -44,3 +44,4 @@ public/uploads
BUILD_NUMBER BUILD_NUMBER
.byebug_history .byebug_history
.ruby-version .ruby-version
.rails5-gems

View File

@ -98,42 +98,117 @@ class ApiSearchController < ApiController
#Filter users by first fetching users from latency graph database #Filter users by first fetching users from latency graph database
#for latency specific filter options and then query the postgresql relational #for latency specific filter options and then query the postgresql relational
#database for other filter options #database for other filter options
# def filter
# page = [params[:page].to_i, 1].max
# limit = 20
# filter_params = {}
# filter_params.merge!(from_location: params[:from_location] ? '1' : '0')
# genres = params[:genres]
# if genres && genres.any?
# genres.map!{|genre| {id: genre} }
# filter_params.merge!(genres: genres)
# end
# beginner = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:proficiency_beginner])
# intermediate = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:proficiency_intermediate])
# expert = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:proficiency_expert])
# proficiency_levels = []
# proficiency_levels.push(1) if beginner
# proficiency_levels.push(2) if intermediate
# proficiency_levels.push(3) if expert
# instruments = params[:instruments]
# if instruments && instruments.any?
# inst = []
# instruments.each do |ii|
# proficiency_levels.each do |pl|
# inst << { instrument_id: ii, proficiency_level: pl}
# end
# end
# filter_params.merge!(instruments: inst)
# end
# filter_params.merge!(joined_within_days: params[:joined_within_days]) unless params[:joined_within_days].blank?
# filter_params.merge!(active_within_days: params[:active_within_days]) unless params[:active_within_days].blank?
# latency_good = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:latency_good])
# latency_fair = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:latency_fair])
# latency_high = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:latency_high])
# @latency_data = []
# #begin
# #bm = Benchmark.measure do
# @latency_data = users_latency_data(latency_good, latency_fair, latency_high, filter_params, page, limit)
# user_ids = @latency_data.map{ |l_data| l_data[:user_id] }
# user_ids = User.musicians.limit(3).map(&:id)
# #end
# # Bugsnag.notify("search_users_benchmark") do |report|
# # report.severity = "info"
# # report.add_tab(:benchmark, benchmark: bm.to_s)
# # end if Rails.env.production?
# # filter_params = {
# # "sort_order"=>"latency",
# # "instruments"=>[],
# # "genres"=> [],
# # "concert_gigs"=>"-1",
# # "interests"=>"any",
# # "studio_sessions"=>"-1",
# # "ages"=>[],
# # "skill_level"=>"-1",
# # "joined_within_days"=>"-1",
# # "active_within_days"=>"-1",
# # "from_location" => "0",
# # }
# sobj = MusicianSearch.user_search_filter(current_user)
# #debugger
# @search = sobj.search_results_page(filter_params, page, limit, user_ids)
# respond_with @search, responder: ApiResponder, status: 201, template: 'api_search/index'
# # rescue => exception
# # logger.debug("Latency exception: #{exception.message}")
# # Bugsnag.notify(exception) do |report|
# # report.severity = "error"
# # report.add_tab(:latency, {
# params: params,
# user_id: current_user.id,
# name: current_user.name,
# url: filter_latency_url,
# })
# end
# render json: {}, status: 500
# end
#end
def filter def filter
latency_good = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:latency_good]) latency_good = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:latency_good])
latency_fair = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:latency_fair]) latency_fair = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:latency_fair])
latency_high = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:latency_high]) latency_high = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:latency_high])
page = [params[:page].to_i, 1].max
@latency_data = [] limit = 20
begin filter_params = {}
#bm = Benchmark.measure do
@latency_data = users_latency_data(latency_good, latency_fair, latency_high)
user_ids = @latency_data.map{ |l_data| l_data[:user_id] }
#end
# Bugsnag.notify("search_users_benchmark") do |report|
# report.severity = "info"
# report.add_tab(:benchmark, benchmark: bm.to_s)
# end if Rails.env.production?
filter_params = {
"sort_order"=>"latency",
"instruments"=>[],
"genres"=> [],
"concert_gigs"=>"-1",
"interests"=>"any",
"studio_sessions"=>"-1",
"ages"=>[],
"skill_level"=>"-1",
"joined_within_days"=>"-1",
"active_within_days"=>"-1",
"from_location" => "0",
}
filter_params.merge!(from_location: params[:from_location] ? '1' : '0') filter_params.merge!(from_location: params[:from_location] ? '1' : '0')
filter_params.merge!(genres: params[:genres]) unless params[:genres].blank? genres = params[:genres]
filter_params.merge!(genres: genres) if genres
# if genres && genres.any?
# genres.map!{|genre| {id: genre} }
# filter_params.merge!(genres: genres)
# end
beginner = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:proficiency_beginner]) beginner = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:proficiency_beginner])
intermediate = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:proficiency_intermediate]) intermediate = ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:proficiency_intermediate])
@ -146,11 +221,13 @@ class ApiSearchController < ApiController
instruments = params[:instruments] instruments = params[:instruments]
if instruments && instruments.any? #debugger
if instruments && instruments.any? && proficiency_levels.any?
inst = [] inst = []
instruments.each do |ii| instruments.each do |ii|
proficiency_levels.each do |pl| proficiency_levels.each do |pl|
inst << { instrument_id: ii, proficiency_level: pl} inst << { id: ii[:value], proficiency: pl}
end end
end end
filter_params.merge!(instruments: inst) filter_params.merge!(instruments: inst)
@ -159,8 +236,22 @@ class ApiSearchController < ApiController
filter_params.merge!(joined_within_days: params[:joined_within_days]) unless params[:joined_within_days].blank? filter_params.merge!(joined_within_days: params[:joined_within_days]) unless params[:joined_within_days].blank?
filter_params.merge!(active_within_days: params[:active_within_days]) unless params[:active_within_days].blank? filter_params.merge!(active_within_days: params[:active_within_days]) unless params[:active_within_days].blank?
@latency_data = []
begin
#bm = Benchmark.measure do
@latency_data = users_latency_data(latency_good, latency_fair, latency_high, filter_params, page, limit)
user_ids = @latency_data.map{ |l_data| l_data[:user_id] }
#end
# Bugsnag.notify("search_users_benchmark") do |report|
# report.severity = "info"
# report.add_tab(:benchmark, benchmark: bm.to_s)
# end if Rails.env.production?
sobj = MusicianSearch.user_search_filter(current_user) sobj = MusicianSearch.user_search_filter(current_user)
@search = sobj.search_results_page(filter_params, [params[:page].to_i, 1].max, user_ids) @search = sobj.search_results_page(filter_params, page, user_ids)
respond_with @search, responder: ApiResponder, status: 201, template: 'api_search/index' respond_with @search, responder: ApiResponder, status: 201, template: 'api_search/index'

View File

@ -10,7 +10,7 @@ module LatencyHelper
unknown: { label: 'UNKNOWN', min: -2, max: -2 } unknown: { label: 'UNKNOWN', min: -2, max: -2 }
}; };
def users_latency_data(latency_good, latency_fair, latency_high) def users_latency_data(latency_good, latency_fair, latency_high, filter_opts, page, limit)
latency_data = [] latency_data = []
uri = URI(filter_latency_url) uri = URI(filter_latency_url)
@ -20,12 +20,25 @@ module LatencyHelper
req = Net::HTTP::Post.new(uri) req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Basic #{Rails.application.config.latency_data_host_auth_code}" req["Authorization"] = "Basic #{Rails.application.config.latency_data_host_auth_code}"
req["Content-Type"] = "application/json" req["Content-Type"] = "application/json"
req.body = {
req_params = {
my_user_id: current_user.id, my_user_id: current_user.id,
my_public_ip: request.remote_ip, my_public_ip: request.remote_ip,
my_device_id: nil, my_device_id: nil,
my_client_id: nil my_client_id: nil,
}.to_json from_location: filter_opts[:from_location] || "0",
offset: page,
limit: limit
}
req_params.merge!(instruments: filter_opts[:instruments]) if filter_opts[:instruments]
req_params.merge!(genres: filter_opts[:genres]) if filter_opts[:genres]
#TODO: enable following two lines one joined and active options are been supported by neo4j handler
#req_params.merge!(joined_within_days: filter_opts[:joined_within_days]) if filter_opts[:joined_within_days]
#req_params.merge!(active_within_days: filter_opts[:active_within_days]) if filter_opts[:active_within_days]
req.body = req_params.to_json
response = http.request(req) response = http.request(req)

View File

@ -15,13 +15,13 @@ if @search.is_a?(BaseSearch)
end end
if @search.is_a? MusicianSearch if @search.is_a? MusicianSearch
node :description do |foo| # node :description do |foo|
@search.description # @search.description
end # end
node :is_blank_filter do |foo| # node :is_blank_filter do |foo|
@search.is_blank? # @search.is_blank?
end # end
child(:results => :musicians) { child(:results => :musicians) {
attributes :id, :first_name, :last_name, :name, :city, :state, :country, :online, :musician, :photo_url, :biography, :regionname, :score, :full_score attributes :id, :first_name, :last_name, :name, :city, :state, :country, :online, :musician, :photo_url, :biography, :regionname, :score, :full_score
@ -83,183 +83,183 @@ if @search.is_a?(BaseSearch)
end end
} }
elsif @search.is_a?(BandSearch) elsif @search.is_a?(BandSearch)
node :is_blank_filter do |foo| # node :is_blank_filter do |foo|
@search.is_blank?(params[:subtype]) # @search.is_blank?(params[:subtype])
# end
# node :description do |foo|
# @search.description(params[:subtype])
# end
# child(:results => :bands) {
# attributes :id, :name, :city, :state, :country, :photo_url, :biography, :logo_url, :website
# node :is_following do |band|
# @search.is_follower?(band)
# end
# node :biography do |band|
# band.biography.nil? ? "" : band.biography
# end
# child :genres => :genres do
# attributes :genre_id, :description
# end
# child :users => :players do |pl|
# node :user_id do |uu| uu.id end
# node :photo_url do |uu| uu.photo_url end
# node :name do |uu| uu.name end
# node :instruments do |uu| uu.instruments.map(&:id).join(',') end
# end
# node :follow_count do |band| @search.follow_count(band) end
# node :recording_count do |band| @search.record_count(band) end
# node :session_count do |band| @search.session_count(band) end
# }
end end
node :description do |foo|
@search.description(params[:subtype])
end
child(:results => :bands) {
attributes :id, :name, :city, :state, :country, :photo_url, :biography, :logo_url, :website
node :is_following do |band|
@search.is_follower?(band)
end
node :biography do |band|
band.biography.nil? ? "" : band.biography
end
child :genres => :genres do
attributes :genre_id, :description
end
child :users => :players do |pl|
node :user_id do |uu| uu.id end
node :photo_url do |uu| uu.photo_url end
node :name do |uu| uu.name end
node :instruments do |uu| uu.instruments.map(&:id).join(',') end
end
node :follow_count do |band| @search.follow_count(band) end
node :recording_count do |band| @search.record_count(band) end
node :session_count do |band| @search.session_count(band) end
}
end
else else
node :search_type do |ss| ss.search_type end node :search_type do |ss| ss.search_type end
if @search.session_invite_search? # if @search.session_invite_search?
child(:results => :suggestions) { # child(:results => :suggestions) {
node :value do |uu| uu.name end # node :value do |uu| uu.name end
node :data do |uu| uu.id end # node :data do |uu| uu.id end
} # }
end # end
if @search.bands_text_search? # if @search.bands_text_search?
child(:results => :bands) { # child(:results => :bands) {
attributes :id, :name, :location, :photo_url, :logo_url, :website # attributes :id, :name, :location, :photo_url, :logo_url, :website
} # }
end # end
if @search.musicians_text_search? # if @search.musicians_text_search?
child(:results => :musicians) { # child(:results => :musicians) {
attributes :id, :first_name, :last_name, :name, :location, :photo_url # attributes :id, :first_name, :last_name, :name, :location, :photo_url
node :is_friend do |musician| # node :is_friend do |musician|
musician.friends?(current_user) # musician.friends?(current_user)
end # end
node :pending_friend_request do |musician| # node :pending_friend_request do |musician|
musician.pending_friend_request?(current_user) # musician.pending_friend_request?(current_user)
end # end
child :musician_instruments => :instruments do # child :musician_instruments => :instruments do
attributes :instrument_id, :description, :proficiency_level, :priority # attributes :instrument_id, :description, :proficiency_level, :priority
end # end
} # }
end # end
if @search.musicians_filter_search? # if @search.musicians_filter_search?
node :page_count do |foo| # node :page_count do |foo|
@search.page_count # @search.page_count
end # end
node :my_audio_latency do |user| # node :my_audio_latency do |user|
current_user.last_jam_audio_latency.round if current_user.last_jam_audio_latency # current_user.last_jam_audio_latency.round if current_user.last_jam_audio_latency
end # end
node :is_blank_filter do |foo| # node :is_blank_filter do |foo|
@search.is_blank? # @search.is_blank?
end # end
node :filter_json do |foo| # node :filter_json do |foo|
@search.to_json # @search.to_json
end # end
child(:results => :musicians) { # child(:results => :musicians) {
attributes :id, :first_name, :last_name, :name, :city, :state, :country, :online, :musician, :photo_url, :biography, :regionname, :score, :full_score # attributes :id, :first_name, :last_name, :name, :city, :state, :country, :online, :musician, :photo_url, :biography, :regionname, :score, :full_score
node :is_friend do |musician| # node :is_friend do |musician|
@search.is_friend?(musician) # @search.is_friend?(musician)
end # end
node :is_following do |musician| # node :is_following do |musician|
@search.is_follower?(musician) # @search.is_follower?(musician)
end # end
node :pending_friend_request do |musician| # node :pending_friend_request do |musician|
musician.pending_friend_request?(current_user) # musician.pending_friend_request?(current_user)
end # end
node :biography do |musician| # node :biography do |musician|
musician.biography.nil? ? "" : musician.biography # musician.biography.nil? ? "" : musician.biography
end # end
child :musician_instruments => :instruments do # child :musician_instruments => :instruments do
attributes :instrument_id, :description, :proficiency_level, :priority # attributes :instrument_id, :description, :proficiency_level, :priority
end # end
child :top_followings => :followings do |uf| # child :top_followings => :followings do |uf|
node :user_id do |uu| uu.id end # node :user_id do |uu| uu.id end
node :photo_url do |uu| uu.photo_url end # node :photo_url do |uu| uu.photo_url end
node :name do |uu| uu.name end # node :name do |uu| uu.name end
end # end
node :follow_count do |musician| @search.follow_count(musician) end # node :follow_count do |musician| @search.follow_count(musician) end
node :friend_count do |musician| @search.friend_count(musician) end # node :friend_count do |musician| @search.friend_count(musician) end
node :recording_count do |musician| @search.record_count(musician) end # node :recording_count do |musician| @search.record_count(musician) end
node :session_count do |musician| @search.session_count(musician) end # node :session_count do |musician| @search.session_count(musician) end
node :audio_latency do |musician| # node :audio_latency do |musician|
last_jam_audio_latency(musician) # last_jam_audio_latency(musician)
end # end
} # }
end # end
if @search.bands_filter_search? # if @search.bands_filter_search?
node :page_count do |foo| # node :page_count do |foo|
@search.page_count # @search.page_count
end # end
child(:results => :bands) { # child(:results => :bands) {
attributes :id, :name, :city, :state, :country, :photo_url, :biography, :logo_url, :website # attributes :id, :name, :city, :state, :country, :photo_url, :biography, :logo_url, :website
node :is_following do |band| # node :is_following do |band|
@search.is_follower?(band) # @search.is_follower?(band)
end # end
node :biography do |band| # node :biography do |band|
band.biography.nil? ? "" : band.biography # band.biography.nil? ? "" : band.biography
end # end
child :genres => :genres do # child :genres => :genres do
attributes :genre_id, :description # attributes :genre_id, :description
end # end
child :users => :players do |pl| # child :users => :players do |pl|
node :user_id do |uu| uu.id end # node :user_id do |uu| uu.id end
node :photo_url do |uu| uu.photo_url end # node :photo_url do |uu| uu.photo_url end
node :name do |uu| uu.name end # node :name do |uu| uu.name end
node :instruments do |uu| uu.instruments.map(&:id).join(',') end # node :instruments do |uu| uu.instruments.map(&:id).join(',') end
end # end
node :follow_count do |band| @search.follow_count(band) end # node :follow_count do |band| @search.follow_count(band) end
node :recording_count do |band| @search.record_count(band) end # node :recording_count do |band| @search.record_count(band) end
node :session_count do |band| @search.session_count(band) end # node :session_count do |band| @search.session_count(band) end
} # }
end # end
if @search.fans_text_search? # if @search.fans_text_search?
child(:results => :fans) { # child(:results => :fans) {
attributes :id, :first_name, :last_name, :name, :location, :photo_url # attributes :id, :first_name, :last_name, :name, :location, :photo_url
node :is_friend do |fan| # node :is_friend do |fan|
fan.friends?(current_user) # fan.friends?(current_user)
end # end
node :pending_friend_request do |fan| # node :pending_friend_request do |fan|
fan.pending_friend_request?(current_user) # fan.pending_friend_request?(current_user)
end # end
} # }
end # end
end end

View File

@ -27,15 +27,95 @@ describe "Musician Filter API", type: :request do
]) ])
} }
let(:response_body_pop) { mock_latency_response([
{ user: user1, ars_total_latency: 1.0, ars_internet_latency: 0.4, audio_latency: 0.6 }, #GOOD
{ user: user2, ars_total_latency: 40.0, ars_internet_latency: 25.0, audio_latency: 15.0 }, #GOOD
{ user: user3, ars_total_latency: 40.1, ars_internet_latency: 25, audio_latency: 15.1 }, #FAIR
])
}
let(:response_body_pop_and_rap) { mock_latency_response([
{ user: user1, ars_total_latency: 1.0, ars_internet_latency: 0.4, audio_latency: 0.6 }, #GOOD
])
}
let(:response_body_drums_intermediate) { mock_latency_response([
{ user: user1, ars_total_latency: 1.0, ars_internet_latency: 0.4, audio_latency: 0.6 },
{ user: user2, ars_total_latency: 40.0, ars_internet_latency: 25.0, audio_latency: 15.0 },
{ user: user3, ars_total_latency: 40.1, ars_internet_latency: 25, audio_latency: 15.1 },
{ user: user4, ars_total_latency: 60.0, ars_internet_latency: 30, audio_latency: 30.0 }
])
}
let(:response_body_drums_violin_expert) { mock_latency_response([
{ user: user2, ars_total_latency: 40.0, ars_internet_latency: 25.0, audio_latency: 15.0 },
{ user: user3, ars_total_latency: 40.1, ars_internet_latency: 25, audio_latency: 15.1 },
])
}
let(:response_body_active_within_one_day) { mock_latency_response([
{ user: user4, ars_total_latency: 60.0, ars_internet_latency: 30, audio_latency: 30.0 }, #FAIR
])
}
let(:response_body_joined_within_one_day) { mock_latency_response([
{ user: user4, ars_total_latency: 60.0, ars_internet_latency: 30, audio_latency: 30.0 }, #FAIR
{ user: user5, ars_total_latency: 60.1, ars_internet_latency: 30.1, audio_latency: 30 }, #HIGH
])
}
let(:pop) { Genre.find_by_id('pop') } let(:pop) { Genre.find_by_id('pop') }
let(:rap) { Genre.find_by_id('rap') } let(:rap) { Genre.find_by_id('rap') }
let(:rock) { Genre.find_by_id('rock') } let(:rock) { Genre.find_by_id('rock') }
before(:each) do before(:each) do
User.delete_all User.delete_all
stub_request(:post, latency_data_uri) stub_request(:post, latency_data_uri)
.with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'}) .with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'})
.to_return( body: response_body, status: 200) .to_return( body: response_body, status: 200)
stub_request(:post, latency_data_uri).
with(
body: hash_including({ genres: ["pop"]}),
:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'}
)
.to_return( body: response_body_pop, status: 200)
stub_request(:post, latency_data_uri).
with(
body: hash_including({ genres: ["pop", "rap"]}),
:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'}
)
.to_return( body: response_body_pop_and_rap, status: 200)
stub_request(:post, latency_data_uri).
with(
body: hash_including({ instruments: [{id: 'drums', proficiency: 2}]}),
:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'}
)
.to_return( body: response_body_drums_intermediate, status: 200)
stub_request(:post, latency_data_uri).
with(
body: hash_including({ instruments: [{id: 'drums', proficiency: 3}, {id: 'violin', proficiency: 3}]}),
:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'}
)
.to_return( body: response_body_drums_violin_expert, status: 200)
stub_request(:post, latency_data_uri).
with(
body: hash_including({ active_within_days: '1'}),
:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'}
)
.to_return( body: response_body_active_within_one_day, status: 200)
stub_request(:post, latency_data_uri).
with(
body: hash_including({ joined_within_days: '1'}),
:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'}
)
.to_return( body: response_body_joined_within_one_day, status: 200)
end end
def login(user) def login(user)
@ -118,134 +198,32 @@ describe "Musician Filter API", type: :request do
end end
it "filter musicians by genres" do it "filter musicians by genres" do
#------ user1 and user2 are good latency ------ post '/api/filter.json', { latency_good: true, latency_fair: true, latency_high: true, genres: ['pop'] }
user1.genres = [pop, rap, rock]
user1.save!
user2.genres = [pop]
user2.save!
#-------- user3 and user4 are fair latency -----
user3.genres = [rock]
user3.save!
user4.genres = [pop, rock]
user4.save!
#-------- user5 and user6 are high latency -----
user5.genres = [rap, rock]
user5.save!
user6.genres = [rock]
user6.save!
#debugger
post '/api/filter.json', { latency_good: true, latency_fair: false, latency_high: false, genres: ['pop'] }
expect(JSON.parse(response.body)["musicians"].size).to eq(2)
post '/api/filter.json', { latency_good: false, latency_fair: true, latency_high: true, genres: ['rap'] }
expect(JSON.parse(response.body)["musicians"].size).to eq(1)
post '/api/filter.json', { latency_good: true, latency_fair: false, latency_high: true, genres: ['rock'] }
expect(JSON.parse(response.body)["musicians"].size).to eq(3) expect(JSON.parse(response.body)["musicians"].size).to eq(3)
post '/api/filter.json', { latency_good: false, latency_fair: true, latency_high: false, genres: ['pop', 'rock'] } post '/api/filter.json', { latency_good: true, latency_fair: true, latency_high: true, genres: ['pop', 'rap'] }
expect(JSON.parse(response.body)["musicians"].size).to eq(2) expect(JSON.parse(response.body)["musicians"].size).to eq(1)
end end
it "filter musicians by instruments they play" do it "filter musicians by instruments they play" do
user1.musician_instruments << FactoryGirl.create(:musician_instrument, player: user1, instrument: JamRuby::Instrument.find('drums'), proficiency_level: 1 )
user1.musician_instruments << FactoryGirl.create(:musician_instrument, player: user1, instrument: JamRuby::Instrument.find('violin'), proficiency_level: 2 )
user1.save!
user2.musician_instruments << FactoryGirl.create(:musician_instrument, player: user2, instrument: JamRuby::Instrument.find('violin'), proficiency_level: 1 ) post '/api/filter.json', { latency_good: true, latency_fair: true, latency_high: true, instruments: [{value: "drums", label: "Drums"}], proficiency_intermediate: true }
user2.save! expect(JSON.parse(response.body)["musicians"].size).to eq(4)
user3.musician_instruments << FactoryGirl.create(:musician_instrument, player: user3, instrument: JamRuby::Instrument.find('drums'), proficiency_level: 2 ) post '/api/filter.json', { latency_good: true, latency_fair: true, latency_high: true, instruments: [{value: "drums", label: "Drums"}, {value: 'violin', label: 'Violin'}], proficiency_expert: true }
user3.save!
post '/api/filter.json', { latency_good: true, latency_fair: true, latency_high: true, instruments: ['drums'], proficiency_intermediate: true }
expect(JSON.parse(response.body)["musicians"].size).to eq(1)
post '/api/filter.json', { latency_good: false, latency_fair: true, latency_high: true, instruments: ['drums'], proficiency_beginner: true }
expect(JSON.parse(response.body)["musicians"].size).to eq(0)
post '/api/filter.json', { latency_good: true, latency_fair: false, latency_high: false, instruments: ['drums, violin'], proficiency_beginner: true }
expect(JSON.parse(response.body)["musicians"].size).to eq(2) expect(JSON.parse(response.body)["musicians"].size).to eq(2)
post '/api/filter.json', { latency_good: false, latency_fair: true, latency_high: false, instruments: ['drums'], proficiency_beginner: true }
expect(JSON.parse(response.body)["musicians"].size).to eq(0)
end end
it "filter musicians by days ago that they joined" do it "filter musicians by days ago that they joined" do
user1.created_at = 1.day.ago pending
user1.save!
user2.created_at = 6.days.ago
user2.save!
user3.created_at = 7.days.ago
user3.save!
user4.created_at = 29.days.ago
user4.save!
user5.created_at = 30.days.ago
user5.save!
user6.created_at = 31.days.ago
user6.save!
post '/api/filter.json', { latency_good: true, latency_fair: true, latency_high: true, joined_within_days: 1 } post '/api/filter.json', { latency_good: true, latency_fair: true, latency_high: true, joined_within_days: 1 }
expect(JSON.parse(response.body)["musicians"].size).to eq(1)
post '/api/filter.json', { latency_good: true, latency_fair: false, latency_high: false, joined_within_days: 7 }
expect(JSON.parse(response.body)["musicians"].size).to eq(2) expect(JSON.parse(response.body)["musicians"].size).to eq(2)
post '/api/filter.json', { latency_good: true, latency_fair: true, latency_high: false, joined_within_days: 7 }
expect(JSON.parse(response.body)["musicians"].size).to eq(3)
post '/api/filter.json', { latency_good: false, latency_fair: true, latency_high: false, joined_within_days: 29 }
expect(JSON.parse(response.body)["musicians"].size).to eq(2)
end
describe "number of days ago they last active" do
before(:each) do
User.update_all(updated_at: 91.days.ago, last_jam_updated_at: 91.days.ago)
end end
it "finds user updated_at is within a day ago" do it "finds user updated_at is within a day ago" do
user1.update_column(:updated_at, 1.day.ago) pending
post '/api/filter.json', { latency_good: true, latency_fair: true, latency_high: true, active_within_days: 1 } post '/api/filter.json', { latency_good: true, latency_fair: true, latency_high: true, active_within_days: 1 }
expect(JSON.parse(response.body)["musicians"].size).to eq(1) expect(JSON.parse(response.body)["musicians"].size).to eq(1)
end end
it "finds user last_jam_updated is within a day ago" do
user1.update_column(:last_jam_updated_at, 1.day.ago)
post '/api/filter.json', { latency_good: true, latency_fair: true, latency_high: true, active_within_days: 1 }
expect(JSON.parse(response.body)["musicians"].size).to eq(1)
end
it "finds user updated_at and last_jam_updated is within a day ago" do
user1.update_column(:last_jam_updated_at, 1.day.ago)
user1.update_column(:updated_at, 1.day.ago)
post '/api/filter.json', { latency_good: true, latency_fair: true, latency_high: true, active_within_days: 1 }
expect(JSON.parse(response.body)["musicians"].size).to eq(1)
end
it "finds users updated_at and last_jam_updated within 90 days ago" do
user1.update_column(:last_jam_updated_at, 1.day.ago)
user1.update_column(:updated_at, 7.day.ago)
user2.update_column(:last_jam_updated_at, 30.day.ago)
user2.update_column(:updated_at, 60.day.ago)
user3.update_column(:last_jam_updated_at, 90.day.ago)
user3.update_column(:updated_at, 90.day.ago)
post '/api/filter.json', { latency_good: true, latency_fair: true, latency_high: true, active_within_days: 90 }
expect(JSON.parse(response.body)["musicians"].size).to eq(3)
end
end
end end