diff --git a/jam-ui/cypress/e2e/friends/friends-page.cy.js b/jam-ui/cypress/e2e/friends/friends-page.cy.js index 51bfb00a9..1bdadbb70 100644 --- a/jam-ui/cypress/e2e/friends/friends-page.cy.js +++ b/jam-ui/cypress/e2e/friends/friends-page.cy.js @@ -1,5 +1,7 @@ /// +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(); + }); + + }); + }); }); diff --git a/jam-ui/src/components/page/JKPeopleFilter.js b/jam-ui/src/components/page/JKPeopleFilter.js index 06d649ba4..2d503882c 100644 --- a/jam-ui/src/components/page/JKPeopleFilter.js +++ b/jam-ui/src/components/page/JKPeopleFilter.js @@ -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){ diff --git a/ruby/lib/jam_ruby.rb b/ruby/lib/jam_ruby.rb index b6368e9e9..d858e0c74 100755 --- a/ruby/lib/jam_ruby.rb +++ b/ruby/lib/jam_ruby.rb @@ -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" diff --git a/ruby/lib/jam_ruby/models/base_search.rb b/ruby/lib/jam_ruby/models/base_search.rb index 7ba937f47..23214f73b 100644 --- a/ruby/lib/jam_ruby/models/base_search.rb +++ b/ruby/lib/jam_ruby/models/base_search.rb @@ -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) diff --git a/ruby/lib/jam_ruby/models/beta_musician_search.rb b/ruby/lib/jam_ruby/models/beta_musician_search.rb new file mode 100644 index 000000000..c14a7c0c9 --- /dev/null +++ b/ruby/lib/jam_ruby/models/beta_musician_search.rb @@ -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 \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/musician_search.rb b/ruby/lib/jam_ruby/models/musician_search.rb index 76da51354..50888fc90 100644 --- a/ruby/lib/jam_ruby/models/musician_search.rb +++ b/ruby/lib/jam_ruby/models/musician_search.rb @@ -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 diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index efb7c27ee..e23b931bf 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -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" diff --git a/web/app/controllers/api_search_controller.rb b/web/app/controllers/api_search_controller.rb index 2315f305a..6c0d65e27 100644 --- a/web/app/controllers/api_search_controller.rb +++ b/web/app/controllers/api_search_controller.rb @@ -147,7 +147,7 @@ class ApiSearchController < ApiController @latency_data = result[:data] @nextOffset = result[:next] - user_ids = @latency_data.map{ |l_data| l_data[:user_id] } + user_ids = @latency_data.map{ |l_data| l_data[:user_id] } #end # Bugsnag.notify("search_users_benchmark") do |report| @@ -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'