From 73ce521bb3d9c51a94dce83db2a6ed7e656c1913 Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem <svbergerem@online.de> Date: Tue, 9 Aug 2016 15:09:49 +0200 Subject: [PATCH] Modify search to include contacts --- .../app/views/publisher/mention_view.js | 3 +- .../javascripts/app/views/search_base_view.js | 13 +++++---- app/models/person.rb | 9 +++--- spec/factories.rb | 6 ---- .../app/views/publisher_mention_view_spec.js | 1 + spec/models/person_spec.rb | 29 ++++++++++++++----- 6 files changed, 37 insertions(+), 24 deletions(-) diff --git a/app/assets/javascripts/app/views/publisher/mention_view.js b/app/assets/javascripts/app/views/publisher/mention_view.js index f19ec7d1e2..b1c6e39b0e 100644 --- a/app/assets/javascripts/app/views/publisher/mention_view.js +++ b/app/assets/javascripts/app/views/publisher/mention_view.js @@ -31,7 +31,8 @@ app.views.PublisherMention = app.views.SearchBase.extend({ app.views.SearchBase.prototype.initialize.call(this, { typeaheadInput: this.typeaheadInput, customSearch: true, - autoselect: true + autoselect: true, + prefetch: true }); }, diff --git a/app/assets/javascripts/app/views/search_base_view.js b/app/assets/javascripts/app/views/search_base_view.js index d70f21cebb..352ff7ddc0 100644 --- a/app/assets/javascripts/app/views/search_base_view.js +++ b/app/assets/javascripts/app/views/search_base_view.js @@ -25,11 +25,6 @@ app.views.SearchBase = app.views.Base.extend({ return this.bloodhoundTokenizer(datum.name).concat(datum.handle); }.bind(this), queryTokenizer: Bloodhound.tokenizers.whitespace, - prefetch: { - url: "/contacts.json", - transform: this.transformBloodhoundResponse, - cache: false - }, sufficient: 5 }; @@ -42,6 +37,14 @@ app.views.SearchBase = app.views.Base.extend({ }; } + if (options.prefetch) { + bloodhoundOptions.prefetch = { + url: "/contacts.json", + transform: this.transformBloodhoundResponse, + cache: false + }; + } + this.bloodhound = new Bloodhound(bloodhoundOptions); }, diff --git a/app/models/person.rb b/app/models/person.rb index 5b400cd30b..1fa3acd6c2 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -56,7 +56,9 @@ class Person < ActiveRecord::Base validates :serialized_public_key, :presence => true validates :diaspora_handle, :uniqueness => true - scope :searchable, -> { joins(:profile).where(:profiles => {:searchable => true}) } + scope :searchable, -> (user) { + joins(:profile).where("profiles.searchable = true OR contacts.user_id = ?", user.id) + } scope :remote, -> { where('people.owner_id IS NULL') } scope :local, -> { where('people.owner_id IS NOT NULL') } scope :for_json, -> { @@ -148,10 +150,9 @@ class Person < ActiveRecord::Base sql, tokens = self.search_query_string(query) - Person.searchable.where(sql, *tokens).joins( + Person.searchable(user).where(sql, *tokens).joins( "LEFT OUTER JOIN contacts ON contacts.user_id = #{user.id} AND contacts.person_id = people.id" - ).includes(:profile - ).order(search_order) + ).includes(:profile).order(search_order) end # @return [Array<String>] postgreSQL and mysql deal with null values in orders differently, it seems. diff --git a/spec/factories.rb b/spec/factories.rb index 1c1c5e839e..4b5363f706 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -52,12 +52,6 @@ FactoryGirl.define do end end - factory :searchable_person, :parent => :person do - after(:build) do |person| - person.profile = FactoryGirl.build(:profile, :person => person, :searchable => true) - end - end - factory :like do association :author, :factory => :person association :target, :factory => :status_message diff --git a/spec/javascripts/app/views/publisher_mention_view_spec.js b/spec/javascripts/app/views/publisher_mention_view_spec.js index 68397e36e3..985ec49e8a 100644 --- a/spec/javascripts/app/views/publisher_mention_view_spec.js +++ b/spec/javascripts/app/views/publisher_mention_view_spec.js @@ -19,6 +19,7 @@ describe("app.views.PublisherMention", function() { expect(call.args[0].typeaheadInput.selector).toBe("#publisher .typeahead-mention-box"); expect(call.args[0].customSearch).toBeTruthy(); expect(call.args[0].autoselect).toBeTruthy(); + expect(call.args[0].prefetch).toBeTruthy(); }); it("calls bindTypeaheadEvents", function() { diff --git a/spec/models/person_spec.rb b/spec/models/person_spec.rb index c376da2b18..04e45066f2 100644 --- a/spec/models/person_spec.rb +++ b/spec/models/person_spec.rb @@ -294,10 +294,11 @@ describe Person, :type => :model do user_profile.last_name = "asdji" user_profile.save - @robert_grimm = FactoryGirl.build(:searchable_person) - @eugene_weinstein = FactoryGirl.build(:searchable_person) - @yevgeniy_dodis = FactoryGirl.build(:searchable_person) - @casey_grippi = FactoryGirl.build(:searchable_person) + @robert_grimm = FactoryGirl.build(:person) + @eugene_weinstein = FactoryGirl.build(:person) + @yevgeniy_dodis = FactoryGirl.build(:person) + @casey_grippi = FactoryGirl.build(:person) + @invisible_person = FactoryGirl.build(:person) @robert_grimm.profile.first_name = "Robert" @robert_grimm.profile.last_name = "Grimm" @@ -318,7 +319,14 @@ describe Person, :type => :model do @casey_grippi.profile.last_name = "Grippi" @casey_grippi.profile.save @casey_grippi.reload + + @invisible_person.profile.first_name = "Johnson" + @invisible_person.profile.last_name = "Invisible" + @invisible_person.profile.searchable = false + @invisible_person.profile.save + @invisible_person.reload end + it 'orders results by last name' do @robert_grimm.profile.first_name = "AAA" @robert_grimm.profile.save! @@ -367,10 +375,15 @@ describe Person, :type => :model do expect(people.first).to eq(@casey_grippi) end - it 'only displays searchable people' do - invisible_person = FactoryGirl.build(:person, :profile => FactoryGirl.build(:profile, :searchable => false, :first_name => "johnson")) - expect(Person.search("johnson", @user)).not_to include invisible_person - expect(Person.search("", @user)).not_to include invisible_person + it "doesn't display people that are neither searchable nor contacts" do + expect(Person.search("Johnson", @user)).to be_empty + end + + it "displays contacts that are not searchable" do + @user.contacts.create(person: @invisible_person, aspects: [@user.aspects.first]) + people = Person.search("Johnson", @user) + expect(people.count).to eq(1) + expect(people.first).to eq(@invisible_person) end it 'returns results for Diaspora handles' do -- GitLab