refactor beta site musician search

refactor the back end model classes for musician searches.
for this introduce new BetaMusicianSearch model class and
move the logic related to beta site search functionality in to
that class.
This commit is contained in:
Nuwan 2022-12-06 12:02:01 +05:30
parent 50ed5116f7
commit 0b209feafa
8 changed files with 267 additions and 227 deletions

View File

@ -1,5 +1,7 @@
/// <reference types="cypress" />
import { after } from "lodash";
const showSidePanelContent = () => {
cy.get('[data-testid=profileSidePanel] h4').should('have.text', 'Test User1');
cy.get('[data-testid=profileSidePanel] .modal-body p').within(() => {
@ -106,180 +108,6 @@ describe('Friends page with data', () => {
cy.intercept('GET', /\S+\/profile\S+/, { fixture: 'person' });
});
describe('listing users', () => {
beforeEach(() => {
cy.visit('/friends');
});
describe('in desktop', () => {
beforeEach(() => {
cy.viewport('macbook-13');
});
it.only('paginate', () => {
cy.get('[data-testid=peopleListTable] > tbody tr').should('have.length', 10);
cy.wait('@getPeople_page2')
cy.get('[data-testid=paginate-next-page]').click();
cy.get('[data-testid=peopleListTable] > tbody tr').should('have.length', 20);
//cy.get('[data-testid=paginate-next-page]').should('not.exist');
cy.get('[data-testid=paginate-next-page]').click();
cy.get('[data-testid=peopleListTable] > tbody tr').should('have.length', 30);
cy.get('[data-testid=paginate-next-page]').should('not.exist');
});
it('show profiles', () => {
cy.contains('Find New Friends').should('exist');
cy.contains('Update Search').should('exist');
cy.contains('Reset Filters').should('exist');
cy.get('[data-testid=peopleListTable] > tbody tr')
.should('have.length', 10)
.first()
.contains('Test User1');
});
it('click profile name', () => {
//open side panel by clicking name
cy.get('[data-testid=peopleListTable]').within(() => {
cy.contains('Test User1').click();
});
showSidePanelContent();
closeSidePanel();
});
it('click more button', () => {
//open side panel by clicking more button
cy.get('[data-testid=peopleListTable] > tbody tr')
.first()
.find('[data-testid=btnMore]')
.click();
showSidePanelContent();
closeSidePanel();
});
it('click more link', () => {
//open side panel by clicking more link
cy.get('[data-testid=peopleListTable] > tbody tr')
.first()
.find('[data-testid=linkMore]')
.click();
showSidePanelContent();
closeSidePanel();
});
it('click description more link', () => {
cy.get('[data-testid=peopleListTable] > tbody tr')
.first()
.find('td[data-testid=biography-col]')
.within(() => {
cy.contains('More').click();
});
showSidePanelContent();
closeSidePanel();
});
it('click instruments more link', () => {
cy.get('[data-testid=peopleListTable] > tbody tr')
.first()
.find('[data-testid=instrumentList]')
.within(() => {
cy.get('div').should('have.length', 4); //show only 4 instruments plus more link
cy.contains('Acoustic Guitar: Expert');
cy.contains('Keyboard: Expert');
cy.contains('Ukulele: Expert');
cy.contains('Voice: Expert');
cy.contains('More').click();
});
showSidePanelContent();
closeSidePanel();
});
it('click genres more link', () => {
cy.get('[data-testid=peopleListTable] > tbody tr')
.first()
.find('td[data-testid=genres-col]')
.within(() => {
cy.contains('More').click();
});
showSidePanelContent();
closeSidePanel();
});
});
describe('in mobile', () => {
beforeEach(() => {
cy.viewport('iphone-6');
});
it('show profile', () => {
cy.get('[data-testid=peopleSwiper] .swiper-slide').should('have.length', 10);
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.eq(0)
.contains('Test User1');
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.eq(0)
.should('be.visible');
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.eq(2)
.should('not.be.visible');
});
it('show all profile description', () => {
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.first()
.find('[data-testid=mobBiography]')
.should('not.contain', 'More');
});
it('show all instruments', () => {
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.first()
.find('[data-testid=instrumentList] div')
.its('length')
.should('be.gte', 1);
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.first()
.find('[data-testid=instrumentList]')
.should('not.contain', 'More');
});
it('show all genres', () => {
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.first()
.find('[data-testid=genreList] div')
.its('length')
.should('be.gte', 1);
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.first()
.find('[data-testid=genreList]')
.should('not.contain', 'More');
});
//it.skip('click connect button', () => {});
//it.skip('click message button', () => {});
it('paginate', () => {
cy.get('[data-testid=peopleSwiper] .swiper-button-prev').should('have.class', 'swiper-button-disabled');
for (let i = 0; i < 19; i++) {
cy.get('[data-testid=peopleSwiper] .swiper-button-next').click();
cy.wait(500);
}
cy.get('[data-testid=peopleSwiper] .swiper-button-next').should('have.class', 'swiper-button-disabled');
});
it('click more button', () => {
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.first()
.find('[data-testid=btnMore]')
.click();
showSidePanelContent();
closeSidePanel();
});
});
});
describe('making friendship', () => {
it('add friend', () => {
cy.intercept('GET', /\S+\/profile\S+/, { fixture: 'person' });
@ -327,6 +155,8 @@ describe('Friends page with data', () => {
});
});
describe('chat window', () => {
beforeEach(() => {
cy.visit('/friends');
@ -523,7 +353,7 @@ describe('Friends page with data', () => {
});
//the subsequent request sent to perfetch data and store in redux prefetched buffer
cy.wait('@getPeople_page2').then(interception => {
assert.isNotNull(interception.response.body, '1st API call has data - (prefethed)');
assert.isNotNull(interception.response.body, '2nd API call has data - (prefethed)');
});
cy.get('[data-testid=btnUpdateSearch]').click();
@ -580,4 +410,180 @@ describe('Friends page with data', () => {
});
});
describe('listing users', () => {
beforeEach(() => {
cy.visit('/friends');
});
describe('in desktop', () => {
beforeEach(() => {
cy.viewport('macbook-13');
});
it('paginate', () => {
cy.get('[data-testid=peopleListTable] > tbody tr').should('have.length', 10);
cy.wait('@getPeople_page2')
cy.get('[data-testid=paginate-next-page]').click();
cy.get('[data-testid=peopleListTable] > tbody tr').should('have.length', 20);
//cy.get('[data-testid=paginate-next-page]').should('not.exist');
cy.get('[data-testid=paginate-next-page]').click();
cy.get('[data-testid=peopleListTable] > tbody tr').should('have.length', 30);
cy.get('[data-testid=paginate-next-page]').should('not.exist');
});
it('show profiles', () => {
cy.contains('Find New Friends').should('exist');
cy.contains('Update Search').should('exist');
cy.contains('Reset Filters').should('exist');
cy.get('[data-testid=peopleListTable] > tbody tr')
.should('have.length', 10)
.first()
.contains('Test User1');
});
it('click profile name', () => {
//open side panel by clicking name
cy.get('[data-testid=peopleListTable]').within(() => {
cy.contains('Test User1').click();
});
showSidePanelContent();
closeSidePanel();
});
it('click more button', () => {
//open side panel by clicking more button
cy.get('[data-testid=peopleListTable] > tbody tr')
.first()
.find('[data-testid=btnMore]')
.click();
showSidePanelContent();
closeSidePanel();
});
it('click more link', () => {
//open side panel by clicking more link
cy.get('[data-testid=peopleListTable] > tbody tr')
.first()
.find('[data-testid=linkMore]')
.click();
showSidePanelContent();
closeSidePanel();
});
it('click description more link', () => {
cy.get('[data-testid=peopleListTable] > tbody tr')
.first()
.find('td[data-testid=biography-col]')
.within(() => {
cy.contains('More').click();
});
showSidePanelContent();
closeSidePanel();
});
it('click instruments more link', () => {
cy.get('[data-testid=peopleListTable] > tbody tr')
.first()
.find('[data-testid=instrumentList]')
.within(() => {
cy.get('div').should('have.length', 4); //show only 4 instruments plus more link
cy.contains('Acoustic Guitar: Expert');
cy.contains('Keyboard: Expert');
cy.contains('Ukulele: Expert');
cy.contains('Voice: Expert');
cy.contains('More').click();
});
showSidePanelContent();
closeSidePanel();
});
it('click genres more link', () => {
cy.get('[data-testid=peopleListTable] > tbody tr')
.first()
.find('td[data-testid=genres-col]')
.within(() => {
cy.contains('More').click();
});
showSidePanelContent();
closeSidePanel();
});
});
describe('in mobile', () => {
beforeEach(() => {
cy.viewport('iphone-6');
});
it('show profile', () => {
cy.get('[data-testid=peopleSwiper] .swiper-slide').should('have.length', 10);
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.eq(0)
.contains('Test User1');
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.eq(0)
.should('be.visible');
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.eq(2)
.should('not.be.visible');
});
it('show all profile description', () => {
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.first()
.find('[data-testid=mobBiography]')
.should('not.contain', 'More');
});
it('show all instruments', () => {
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.first()
.find('[data-testid=instrumentList] div')
.its('length')
.should('be.gte', 1);
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.first()
.find('[data-testid=instrumentList]')
.should('not.contain', 'More');
});
it('show all genres', () => {
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.first()
.find('[data-testid=genreList] div')
.its('length')
.should('be.gte', 1);
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.first()
.find('[data-testid=genreList]')
.should('not.contain', 'More');
});
//it.skip('click connect button', () => {});
//it.skip('click message button', () => {});
it('paginate', () => {
cy.get('[data-testid=peopleSwiper] .swiper-button-prev').should('have.class', 'swiper-button-disabled');
for (let i = 0; i < 19; i++) {
cy.get('[data-testid=peopleSwiper] .swiper-button-next').click();
cy.wait(200);
}
cy.get('[data-testid=peopleSwiper] .swiper-button-next').should('have.class', 'swiper-button-disabled');
});
it('click more button', () => {
cy.get('[data-testid=peopleSwiper] .swiper-slide')
.first()
.find('[data-testid=btnMore]')
.click();
showSidePanelContent();
closeSidePanel();
});
});
});
});

View File

@ -170,7 +170,7 @@ function JKPeopleFilter() {
try {
if(page.current === 0){
dispatch(fetchPeople({ data: params.current, offset: offset || 0, limit: perPageLimit }));
dispatch(fetchPeople({ data: params.current, offset: 0, limit: perPageLimit }));
page.current += 1
}else{
if(prefetched.length > 0){

View File

@ -290,6 +290,7 @@ require "jam_ruby/models/online_presence"
require "jam_ruby/models/json_store"
require "jam_ruby/models/base_search"
require "jam_ruby/models/musician_search"
require "jam_ruby/models/beta_musician_search"
require "jam_ruby/models/teacher"
require "jam_ruby/models/teacher_experience"
require "jam_ruby/models/language"

View File

@ -187,6 +187,13 @@ module JamRuby
rel
end
def _active_within(rel)
if 0 <= (val = json[KEY_ACTIVE_WITHIN].to_i)
rel = rel.where("users.id IN (SELECT users.id FROM users GROUP BY id HAVING GREATEST(updated_at, last_jam_updated_at) >= ?)", val.days.ago.at_beginning_of_day)
end
rel
end
def _sort_order(rel)
end
@ -200,17 +207,7 @@ module JamRuby
rel
end
def filter_includes(rel)
rel
end
def user_search_results(user_ids)
rel = do_filter(user_ids)
rel = self.filter_includes(rel)
process_results_page(rel.all, true) #skip_counters = true
end
def search_results_page(filter=nil, page=1, user_ids=nil)
def search_results_page(filter=nil, page=1)
if filter
self.data_blob = filter
self.save
@ -218,12 +215,7 @@ module JamRuby
filter = self.data_blob
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)
end
rel = do_search(filter)
@page_number = [page.to_i, 1].max
rel = rel.paginate(:page => @page_number, :per_page => self.class::PER_PAGE)

View File

@ -0,0 +1,47 @@
module JamRuby
class BetaMusicianSearch < MusicianSearch
def search_includes(rel)
rel.includes([:instruments, :genres])
end
def do_search(user_ids)
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)
#debugger
unless user_ids.nil?
if user_ids.empty?
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
rel = rel.where(id: user_ids)
#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
#rel = rel.where(id: user_ids).where('users.id <> ?', self.user.id).order("array_position(ARRAY[#{user_ids.map { |i| "'#{i}'" }.join(',')}], id::TEXT)")
#rel = self._sort_by_ids_ordinality(rel, user_ids)
end
end
rel = rel.select("users.*, (SELECT count(friendships.id) > 0 AS is_friend FROM friendships WHERE friendships.user_id = users.id AND friendships.friend_id = '#{self.user.id}'), (SELECT count(follows.id) > 0 AS is_following FROM follows WHERE follows.user_id = users.id AND follows.followable_id = '#{self.user.id}' AND follows.followable_type = 'JamRuby::User'), (SELECT count(friend_requests.id) > 0 as pending_friend_request from friend_requests WHERE (friend_requests.user_id = '#{self.user.id}' AND friend_requests.friend_id = users.id) OR (friend_requests.user_id = users.id AND friend_requests.friend_id = '#{self.user.id}') )")
rel = self._joined_within(rel)
rel = self._active_within(rel)
rel
end
def process_results_page(_results, skip_counters)
super(_results, skip_counters)
self
end
def user_search_results(user_ids)
rel = do_search(user_ids)
rel = self.search_includes(rel)
process_results_page(rel.all, true) #skip_counters = true
end
end
end

View File

@ -127,13 +127,6 @@ module JamRuby
rel
end
def _active_within(rel)
if 0 <= (val = json[KEY_ACTIVE_WITHIN].to_i)
rel = rel.where("users.id IN (SELECT users.id FROM users GROUP BY id HAVING GREATEST(updated_at, last_jam_updated_at) >= ?)", val.days.ago.at_beginning_of_day)
end
rel
end
def _sort_order(rel)
val = json[self.class::KEY_SORT_ORDER]
if self.class::SORT_VALS[1] == val
@ -160,31 +153,31 @@ module JamRuby
rel.order('x.ordering')
end
def do_filter(user_ids)
rel = User.musicians.where('users.id <> ?', self.user.id)
# def do_filter(user_ids)
# 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)
#debugger
# #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)
# #debugger
unless user_ids.nil?
if user_ids.empty?
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
rel = rel.where(id: user_ids)
# unless user_ids.nil?
# if user_ids.empty?
# 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
# rel = rel.where(id: user_ids)
#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
#rel = rel.where(id: user_ids).where('users.id <> ?', self.user.id).order("array_position(ARRAY[#{user_ids.map { |i| "'#{i}'" }.join(',')}], id::TEXT)")
# #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
# #rel = rel.where(id: user_ids).where('users.id <> ?', self.user.id).order("array_position(ARRAY[#{user_ids.map { |i| "'#{i}'" }.join(',')}], id::TEXT)")
#rel = self._sort_by_ids_ordinality(rel, user_ids)
end
end
# #rel = self._sort_by_ids_ordinality(rel, user_ids)
# end
# end
rel = rel.select("users.*, (SELECT count(friendships.id) > 0 AS is_friend FROM friendships WHERE friendships.user_id = users.id AND friendships.friend_id = '#{self.user.id}'), (SELECT count(follows.id) > 0 AS is_following FROM follows WHERE follows.user_id = users.id AND follows.followable_id = '#{self.user.id}' AND follows.followable_type = 'JamRuby::User'), (SELECT count(friend_requests.id) > 0 as pending_friend_request from friend_requests WHERE (friend_requests.user_id = '#{self.user.id}' AND friend_requests.friend_id = users.id) OR (friend_requests.user_id = users.id AND friend_requests.friend_id = '#{self.user.id}') )")
rel
end
# rel = rel.select("users.*, (SELECT count(friendships.id) > 0 AS is_friend FROM friendships WHERE friendships.user_id = users.id AND friendships.friend_id = '#{self.user.id}'), (SELECT count(follows.id) > 0 AS is_following FROM follows WHERE follows.user_id = users.id AND follows.followable_id = '#{self.user.id}' AND follows.followable_type = 'JamRuby::User'), (SELECT count(friend_requests.id) > 0 as pending_friend_request from friend_requests WHERE (friend_requests.user_id = '#{self.user.id}' AND friend_requests.friend_id = users.id) OR (friend_requests.user_id = users.id AND friend_requests.friend_id = '#{self.user.id}') )")
# rel
# end
def do_search(params={}, user_ids)
def do_search(params={})
rel = User.musicians.where('users.id <> ?', self.user.id)
rel = Search.scope_schools_together(rel, self.user)
@ -196,18 +189,18 @@ module JamRuby
rel = self._instruments(rel)
rel = self._interests(rel)
#rel = self._sort_order(rel)
rel = self._joined_within(rel)
rel = self._active_within(rel)
#rel = self._joined_within(rel)
#rel = self._active_within(rel)
rel
#raise rel.inspect
end
def search_includes(rel)
rel.includes([:instruments, :followings, :friends])
end
def filter_includes(rel)
rel.includes([:instruments, :genres])
end
def process_results_page(_results, skip_counters = false)
@results = _results

View File

@ -232,6 +232,7 @@ module JamRuby
has_one :musician_search, :class_name => 'JamRuby::MusicianSearch'
has_one :band_search, :class_name => 'JamRuby::BandSearch'
has_one :beta_musician_search, class_name: 'JamRuby::BetaMusicianSearch'
belongs_to :teacher, :class_name => 'JamRuby::Teacher', foreign_key: :teacher_id
has_many :jam_track_session, :class_name => "JamRuby::JamTrackSession"

View File

@ -155,9 +155,9 @@ class ApiSearchController < ApiController
# report.add_tab(:benchmark, benchmark: bm.to_s)
# end if Rails.env.production?
sobj = MusicianSearch.user_search_filter(current_user)
sobj = BetaMusicianSearch.user_search_filter(current_user)
#@search = sobj.search_results_page(filter_params, page, user_ids)
#debugger
debugger
@search = sobj.user_search_results(user_ids)
respond_with @search, responder: ApiResponder, status: 201, template: 'api_search/filter'