Commit 67d0efad136aa2fcf6d2cf601be59bed05de091f

Authored by David Silva
Committed by Macartur Sousa
1 parent 873bf3f0
Exists in fix_sign_up_form

Elasticsearch: Adding sort and some fixings

* Sort documents by name
* Adds lexical sort for searchs without expression
* Sort by name.raw instead of name
* Indexes models by raw nested in name, remove suggests
* Fixes tests and alphabetical ordering
* Adds created at as a type of sort
* Fixing search using sort by
* Fixed Sort by to receive filter param
* Fixed noosfero to be support noosfero links
* Fixed text_articles and upload_files extensions
* Fixed api tests
* Refactored elasticsearch_plugin and elasticsearch_api
* Fixed to use partial query
* Fixed sort and query_string

Signed-off-by: Arthur Jahn <stutrzbecher@gmail.com>
Signed-off-by: DylanGuedes <djmgguedes@gmail.com>
Signed-off-by: Macartur Sousa <macartur.sc@gmail.com>
Signed-off-by: David Carlos <ddavidcarlos1392@gmail.com>
Showing 25 changed files with 389 additions and 135 deletions   Show diff stats
plugins/elasticsearch/Rakefile
... ... @@ -30,7 +30,7 @@ task :start do
30 30 if elasticsearch_development
31 31 sh 'sudo systemctl start elasticsearch >> /dev/null 2>&1'
32 32 sh 'sudo systemctl enable elasticsearch >> /dev/null 2>&1'
33   - sleep 2
  33 + sleep 10
34 34 end
35 35 end
36 36  
... ...
plugins/elasticsearch/controllers/elasticsearch_plugin_controller.rb
... ... @@ -18,6 +18,7 @@ class ElasticsearchPluginController &lt; ApplicationController
18 18 def define_results
19 19 @query = params[:query]
20 20 @results = process_results
  21 + @hits = @results.total
21 22 end
22 23  
23 24 def define_searchable_types
... ... @@ -26,13 +27,8 @@ class ElasticsearchPluginController &lt; ApplicationController
26 27 end
27 28  
28 29 def define_search_fields_types
29   - @search_filter_types = ElasticsearchHelper::search_filters
30   - @selected_filter_field = (params[:selected_filter_field] || ElasticsearchHelper::search_filters.keys.first).to_sym
  30 + @filter_types = ElasticsearchHelper::filters
  31 + @selected_filter = (params[:filter] || :relevance).to_sym
31 32 end
32 33  
33   - private
34   -
35   -# def permit_params
36   -# params.require(:per_page, :query)
37   -# end
38 34 end
... ...
plugins/elasticsearch/helpers/elasticsearch_helper.rb
... ... @@ -11,83 +11,99 @@ module ElasticsearchHelper
11 11 }
12 12 end
13 13  
14   - def self.search_filters
  14 + def self.filters
15 15 {
16   - :lexical => { label: _("Alphabetical Order")},
17   - :recent => { label: _("More Recent Order")},
18   - :access => { label: _("More accessed")}
  16 + :relevance => { label: _("Relevance")},
  17 + :lexical => { label: _("Alphabetical")},
  18 + :more_recent => { label: _("More Recent")},
19 19 }
20 20 end
21 21  
22   - def fields_from_model
23   - klass::SEARCHABLE_FIELDS.map do |key, value|
24   - if value[:weight]
25   - "#{key}^#{value[:weight]}"
26   - else
27   - "#{key}"
28   - end
29   - end
30   - end
31   -
32   - def get_query text, klass=nil
33   - query = {}
34   - unless text.blank?
35   - text = text.downcase
36   - query = {
37   - query: {
38   - match_all: {
39   - }
40   - },
41   - filter: {
42   - regexp: {
43   - name: {
44   - value: ".*" + text + ".*" }
45   - }
46   - },
47   - suggest: {
48   - autocomplete: {
49   - text: text,
50   - term: {
51   - field: "name",
52   - suggest_mode: "always"
53   - }
54   - }
55   - }
56   -
57   - }
58   - end
59   - query
60   - end
61   -
62 22 def process_results
63   - selected_type = (params[:selected_type]|| :all).to_sym
64   - if selected_type == :all
65   - search_from_all_models
66   - else
67   - search_from_model selected_type
68   - end
  23 + selected_type = (params[:selected_type].presence|| :all).to_sym
  24 + selected_type == :all ? search_from_all_models : search_from_model(selected_type)
69 25 end
70 26  
71   - def search_from_all_models
72   - models = []
73   - query = get_query params[:query]
  27 + private
74 28  
75   - ElasticsearchHelper::searchable_types.keys.each {| model | models.append( model.to_s.classify.constantize) if model != :all }
76   - Elasticsearch::Model.search(query, models, size: default_per_page(params[:per_page])).page(params[:page]).records
  29 + def search_from_all_models
  30 + query = get_query params[:query], sort_by: get_sort_by(params[:filter])
  31 + Elasticsearch::Model.search(query,searchable_models, size: default_per_page(params[:per_page])).page(params[:page]).records
77 32 end
78 33  
79 34 def search_from_model model
80 35 begin
81 36 klass = model.to_s.classify.constantize
82   - query = get_query params[:query], klass
  37 +
  38 + query = get_query params[:query], klass: klass, sort_by: get_sort_by(params[:filter])
83 39 klass.search(query, size: default_per_page(params[:per_page])).page(params[:page]).records
84 40 rescue
85 41 []
86 42 end
87 43 end
88 44  
89   - def default_per_page per_page
  45 + def default_per_page per_page=nil
90 46 per_page ||= 10
91 47 end
92 48  
  49 + def get_sort_by sort_by
  50 + case sort_by
  51 + when "lexical"
  52 + { "name.raw" => {"order" => "asc" }}
  53 + when "more_recent"
  54 + { "created_at" => {"order" => "desc"}}
  55 + end
  56 + end
  57 +
  58 + def searchable_models
  59 + begin
  60 + ElasticsearchHelper::searchable_types.except(:all).keys.map { | model | model.to_s.classify.constantize }
  61 + rescue
  62 + []
  63 + end
  64 + end
  65 +
  66 + def query_method expression="", fields=[]
  67 + query_exp = {}
  68 + if expression.blank?
  69 + else
  70 + query_exp = {
  71 + query: {
  72 + query_string: {
  73 + query: "*"+expression.downcase.split.join('* *')+"*",
  74 + fields: fields,
  75 + tie_breaker: 0.4,
  76 + minimum_should_match: "100%"
  77 + },
  78 + }
  79 + }
  80 + end
  81 + query_exp
  82 + end
  83 +
  84 + def get_query text="", options={}
  85 + klass = options[:klass]
  86 + sort_by = options[:sort_by]
  87 +
  88 + fields = klass.nil? ? (fields_from_models searchable_models) : (fields_from_models [klass])
  89 +
  90 + query = query_method(text, fields)
  91 + query[:sort] = sort_by if sort_by
  92 + query
  93 + end
  94 +
  95 + def fields_from_models klasses
  96 + fields = Set.new
  97 + klasses.each do |klass|
  98 + klass::SEARCHABLE_FIELDS.map do |key, value|
  99 + if value and value[:weight]
  100 + fields.add "#{key}^#{value[:weight]}"
  101 + else
  102 + fields.add "#{key}"
  103 + end
  104 + end
  105 + end
  106 + fields.to_a
  107 + end
  108 +
93 109 end
... ...
plugins/elasticsearch/lib/elasticsearch_indexed_model.rb
... ... @@ -2,14 +2,21 @@ module ElasticsearchIndexedModel
2 2  
3 3 def self.included base
4 4 base.send :include, Elasticsearch::Model
  5 + base.send :include, Elasticsearch::Model::Callbacks
  6 +
5 7 base.send :index_name, "#{Rails.env}_#{base.index_name}"
6 8 base.extend ClassMethods
7 9 base.class_eval do
8 10 settings index: { number_of_shards: 1 } do
9 11 mappings dynamic: 'false' do
10   - base.indexable_fields.each do |field, value|
  12 + base.indexed_fields.each do |field, value|
11 13 value = {} if value.nil?
12   - indexes field, type: value[:type].presence
  14 + type = value[:type].presence
  15 + if type.nil?
  16 + indexes(field, fields: base.raw_field(field))
  17 + else
  18 + indexes field, type: type
  19 + end
13 20 print '.'
14 21 end
15 22 end
... ... @@ -28,9 +35,19 @@ module ElasticsearchIndexedModel
28 35 end
29 36  
30 37 module ClassMethods
31   - def indexable_fields
32   - self::SEARCHABLE_FIELDS.update self.control_fields
  38 + def raw_field name
  39 + {
  40 + raw: {
  41 + type: "string",
  42 + index: "not_analyzed"
  43 + }
  44 + }
  45 + end
  46 +
  47 + def indexed_fields
  48 + self::SEARCHABLE_FIELDS.merge self.control_fields
33 49 end
  50 +
34 51 end
35 52  
36 53 end
... ...
plugins/elasticsearch/lib/elasticsearch_plugin.rb
... ... @@ -17,12 +17,24 @@ class ElasticsearchPlugin &lt; Noosfero::Plugin
17 17 end
18 18  
19 19 def search_controller_filters
20   - block = proc do
21   - redirect_to controller: 'elasticsearch_plugin', action: 'search', params: params
22   - end
  20 + block = proc do
  21 +
  22 + case action_name
  23 + when 'contents'
  24 + params[:selected_type] = :text_article
  25 + when 'index'
  26 + when 'articles'
  27 + params[:selected_type] = :text_article
  28 + else
  29 + params[:selected_type] = action_name.singularize.to_sym
  30 + end
  31 +
  32 + redirect_to controller: 'elasticsearch_plugin', action: 'search', params: params
  33 + end
23 34  
24 35 [{ :type => 'before_filter',
25 36 :method_name => 'redirect_search_to_elastic',
26 37 :block => block }]
27 38 end
  39 +
28 40 end
... ...
plugins/elasticsearch/lib/elasticsearch_plugin/entities.rb
1 1 module Elasticsearch
2 2 module Entities
  3 +
3 4 class Result < Api::Entity
4 5 root "results","result"
5 6  
... ... @@ -7,11 +8,24 @@ module Elasticsearch
7 8 options[:types].detect { |type| type.to_s.upcase if object.is_a? (type.to_s.classify.constantize) }
8 9 end
9 10  
  11 + expose :id
10 12 expose :name
11 13  
12 14 expose :author, if: lambda { |object,options| object.respond_to? 'author'} do |object, options|
13 15 object.author.present? ? object.author.name : ""
14 16 end
  17 +
  18 + expose :description, if: lambda { |object,options| object.respond_to? 'description'} do |object, options|
  19 + object.description.present? ? object.description : ""
  20 + end
  21 +
  22 + expose :abstract, if: lambda { |object,options| object.respond_to? 'abstract'} do |object, options|
  23 + object.abstract.present? ? object.abstract : ""
  24 + end
  25 +
  26 + expose :created_at, :format_with => :timestamp
  27 + expose :updated_at, :format_with => :timestamp
15 28 end
  29 +
16 30 end
17 31 end
... ...
plugins/elasticsearch/lib/ext/community.rb
... ... @@ -3,7 +3,9 @@ require_relative &#39;../elasticsearch_indexed_model&#39;
3 3  
4 4 class Community
5 5 def self.control_fields
6   - {}
  6 + {
  7 + :created_at => {type: 'date'}
  8 + }
7 9 end
8 10 include ElasticsearchIndexedModel
9 11 end
... ...
plugins/elasticsearch/lib/ext/event.rb
... ... @@ -6,6 +6,7 @@ class Event
6 6 {
7 7 :advertise => {},
8 8 :published => {},
  9 + :created_at => {type: 'date'}
9 10 }
10 11 end
11 12 include ElasticsearchIndexedModel
... ...
plugins/elasticsearch/lib/ext/person.rb
... ... @@ -6,6 +6,7 @@ class Person
6 6 {
7 7 :visible => {type: 'boolean'},
8 8 :public_profile => {type: 'boolean'},
  9 + :created_at => {type: 'date'}
9 10 }
10 11 end
11 12 include ElasticsearchIndexedModel
... ...
plugins/elasticsearch/lib/ext/text_article.rb
  1 +# REQUIRE TO LOAD DESCENDANTS FROM TEXT_ARTICLE
  2 +require_dependency 'raw_html_article'
  3 +require_dependency 'tiny_mce_article'
  4 +
1 5 require_dependency 'text_article'
2 6 require_relative '../elasticsearch_indexed_model'
3 7  
... ... @@ -6,6 +10,7 @@ class TextArticle
6 10 {
7 11 :advertise => {},
8 12 :published => {},
  13 + :created_at => {type: 'date'}
9 14 }
10 15 end
11 16 include ElasticsearchIndexedModel
... ...
plugins/elasticsearch/lib/ext/uploaded_file.rb
... ... @@ -6,6 +6,7 @@ class UploadedFile
6 6 {
7 7 :advertise => {},
8 8 :published => {},
  9 + :created_at => {type: 'date'}
9 10 }
10 11 end
11 12 include ElasticsearchIndexedModel
... ...
plugins/elasticsearch/test/test_helper.rb
... ... @@ -20,7 +20,7 @@ module ElasticsearchTestHelper
20 20 model.__elasticsearch__.create_index! force: true
21 21 model.import
22 22 }
23   - sleep 1
  23 + sleep 2
24 24 end
25 25  
26 26 def setup_environment
... ...
plugins/elasticsearch/test/unit/api/elasticsearch_plugin_api_test.rb
... ... @@ -9,8 +9,8 @@ class ElasticsearchPluginApiTest &lt; ActiveSupport::TestCase
9 9 end
10 10  
11 11 def create_instances
12   - 7.times.each {|index| create_user "person_#{index}"}
13   - 4.times.each {|index| fast_create Community, name: "community_#{index}", created_at: Date.new }
  12 + 7.times.each {|index| create_user "person #{index}"}
  13 + 4.times.each {|index| fast_create Community, name: "community #{index}" }
14 14 end
15 15  
16 16 should 'show all types avaliable in /search/types endpoint' do
... ... @@ -28,14 +28,14 @@ class ElasticsearchPluginApiTest &lt; ActiveSupport::TestCase
28 28 end
29 29  
30 30 should 'respond with query in downcase' do
31   - get "/api/v1/search?query=person_"
  31 + get "/api/v1/search?query=person"
32 32 json = JSON.parse(last_response.body)
33 33 assert_equal 200, last_response.status
34 34 assert_equal 7, json["results"].count
35 35 end
36 36  
37   - should 'respond with query in upcase' do
38   - get "/api/v1/search?query=PERSON_"
  37 + should 'respond with query in uppercase' do
  38 + get "/api/v1/search?query=PERSON"
39 39 json = JSON.parse(last_response.body)
40 40 assert_equal 200, last_response.status
41 41 assert_equal 7, json["results"].count
... ... @@ -47,5 +47,4 @@ class ElasticsearchPluginApiTest &lt; ActiveSupport::TestCase
47 47 assert_equal 200, last_response.status
48 48 assert_equal 4, json["results"].count
49 49 end
50   -
51 50 end
... ...
plugins/elasticsearch/test/unit/api/elasticsearch_plugin_entities_test.rb 0 → 100644
... ... @@ -0,0 +1,122 @@
  1 +require "#{File.dirname(__FILE__)}/../../test_helper"
  2 +
  3 +class ElasticsearchPluginEntitiesTest < ActiveSupport::TestCase
  4 +
  5 + include ElasticsearchTestHelper
  6 +
  7 + def indexed_models
  8 + [Person,TextArticle,UploadedFile,Community,Event]
  9 + end
  10 +
  11 + def create_instances
  12 + user = create_user "sample person"
  13 +
  14 + fast_create Community, name: "sample community", created_at: 10.days.ago,updated_at: 5.days.ago
  15 + fast_create UploadedFile, name: "sample uploadedfile", created_at: 3.days.ago, updated_at: 1.days.ago, author_id: user.person.id, abstract: "sample abstract"
  16 + fast_create Event, name: "sample event", created_at: 20.days.ago, updated_at: 5.days.ago, author_id: user.person.id, abstract: "sample abstract"
  17 +
  18 + fast_create RawHTMLArticle, name: "sample raw html article", created_at: 15.days.ago ,updated_at: 5.days.ago, author_id: user.person.id
  19 + fast_create TinyMceArticle, name: "sample tiny mce article", created_at: 5.days.ago, updated_at: 5.days.ago, author_id: user.person.id
  20 + end
  21 +
  22 + should 'show attributes from person' do
  23 + params = {:selected_type => "person" }
  24 + get "/api/v1/search?#{params.to_query}"
  25 + json= JSON.parse(last_response.body)
  26 +
  27 + expected_person = Person.find_by name: "sample person"
  28 +
  29 + assert_equal 200, last_response.status
  30 + assert_equal expected_person.id, json['results'][0]['id']
  31 + assert_equal expected_person.name, json['results'][0]['name']
  32 + assert_equal expected_person.type, json['results'][0]['type']
  33 + assert_equal "", json['results'][0]['description']
  34 + assert_equal expected_person.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][0]['created_at']
  35 + assert_equal expected_person.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][0]['updated_at']
  36 + end
  37 +
  38 + should 'show attributes from community' do
  39 + params = {:selected_type => "community" }
  40 + get "/api/v1/search?#{params.to_query}"
  41 + json= JSON.parse(last_response.body)
  42 +
  43 + expected_community = Community.find_by name: "sample community"
  44 +
  45 + assert_equal 200, last_response.status
  46 + assert_equal expected_community.id, json['results'][0]['id']
  47 + assert_equal expected_community.name, json['results'][0]['name']
  48 + assert_equal expected_community.type, json['results'][0]['type']
  49 + assert_equal "", json['results'][0]['description']
  50 + assert_equal expected_community.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][0]['created_at']
  51 + assert_equal expected_community.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][0]['updated_at']
  52 + end
  53 +
  54 + should 'show attributes from text_article' do
  55 + params = {:selected_type => "text_article" }
  56 + get "/api/v1/search?#{params.to_query}"
  57 +
  58 + json= JSON.parse(last_response.body)
  59 +
  60 + assert_equal 200, last_response.status
  61 +
  62 + expected_text_articles = TextArticle.all
  63 +
  64 + expected_text_articles.each_with_index {|object,index|
  65 + assert_equal object.id, json['results'][index]['id']
  66 + assert_equal object.name, json['results'][index]['name']
  67 + assert_equal "TextArticle", json['results'][index]['type']
  68 +
  69 + expected_author = (object.author.nil?) ? "" : object.author.name
  70 +
  71 + assert_equal expected_author, json['results'][index]['author']
  72 + assert_equal object.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['created_at']
  73 + assert_equal object.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['updated_at']
  74 + }
  75 + end
  76 +
  77 + should 'show attributes from uploaded_file' do
  78 + params = {:selected_type => "uploaded_file"}
  79 + get "/api/v1/search?#{params.to_query}"
  80 +
  81 + json= JSON.parse(last_response.body)
  82 +
  83 + assert_equal 200, last_response.status
  84 +
  85 + expected_uploaded_files = UploadedFile.all
  86 + expected_uploaded_files.each_with_index {|object,index|
  87 + assert_equal object.id, json['results'][index]['id']
  88 + assert_equal object.name, json['results'][index]['name']
  89 + assert_equal object.abstract, json['results'][index]['abstract']
  90 + assert_equal "UploadedFile", json['results'][index]['type']
  91 +
  92 + expected_author = (object.author.nil?) ? "" : object.author.name
  93 + assert_equal expected_author, json['results'][index]['author']
  94 +
  95 + assert_equal object.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['created_at']
  96 + assert_equal object.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['updated_at']
  97 + }
  98 + end
  99 +
  100 + should 'show attributes from event' do
  101 + params = {:selected_type => "event"}
  102 + get "/api/v1/search?#{params.to_query}"
  103 +
  104 + json= JSON.parse(last_response.body)
  105 +
  106 + assert_equal 200, last_response.status
  107 + expected_events = Event.all
  108 + expected_events.each_with_index {|object,index|
  109 + assert_equal object.id, json['results'][index]['id']
  110 + assert_equal object.name, json['results'][index]['name']
  111 + assert_equal object.abstract, json['results'][index]['abstract']
  112 + assert_equal "Event", json['results'][index]['type']
  113 +
  114 + expected_author = (object.author.nil?) ? "" : object.author.name
  115 + assert_equal expected_author, json['results'][index]['author']
  116 +
  117 + assert_equal object.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['created_at']
  118 + assert_equal object.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['updated_at']
  119 + }
  120 + end
  121 +
  122 +end
... ...
plugins/elasticsearch/test/unit/controllers/elasticsearch_plugin_controller_test.rb
... ... @@ -15,13 +15,13 @@ class ElasticsearchPluginControllerTest &lt; ActionController::TestCase
15 15  
16 16 def create_people
17 17 5.times do | index |
18   - create_user "person_#{index}"
  18 + create_user "person #{index}"
19 19 end
20 20 end
21 21  
22 22 def create_communities
23 23 6.times do | index |
24   - fast_create Community, name: "community_#{index}", created_at: Date.new
  24 + fast_create Community, name: "community #{index}", created_at: Date.new
25 25 end
26 26 end
27 27  
... ... @@ -30,8 +30,8 @@ class ElasticsearchPluginControllerTest &lt; ActionController::TestCase
30 30 assert_response :success
31 31 assert_not_nil assigns(:searchable_types)
32 32 assert_not_nil assigns(:selected_type)
33   - assert_not_nil assigns(:search_filter_types)
34   - assert_not_nil assigns(:selected_filter_field)
  33 + assert_not_nil assigns(:filter_types)
  34 + assert_not_nil assigns(:selected_filter)
35 35 end
36 36  
37 37 should 'return 10 results if selected_type is nil and query is nil' do
... ... @@ -54,31 +54,31 @@ class ElasticsearchPluginControllerTest &lt; ActionController::TestCase
54 54 end
55 55  
56 56 should 'return results filtered by query' do
57   - get :index, { 'query' => "person_"}
  57 + get :index, { 'query' => "person"}
58 58 assert_response :success
59 59 assert_select ".search-item", 5
60 60 assert_template partial: '_person_display'
61 61 end
62 62  
63   - should 'return results filtered by query with uppercase' do
64   - get :index, {'query' => "PERSON_1"}
65   - assert_response :success
66   - assert_select ".search-item", 1
67   - assert_template partial: '_person_display'
68   - end
  63 + should 'return results filtered by query with uppercase' do
  64 + get :index, {'query' => "PERSON 1"}
  65 + assert_response :success
  66 + assert_template partial: '_person_display'
  67 + assert_tag(tag: "div", attributes: { class: "person-item" } , descendant: { tag: "a", child: "person 1"} )
  68 + end
69 69  
70   - should 'return results filtered by query with downcase' do
71   - get :index, {'query' => "person_1"}
72   - assert_response :success
73   - assert_select ".search-item", 1
74   - end
  70 + should 'return results filtered by query with downcase' do
  71 + get :index, {'query' => "person 1"}
  72 + assert_response :success
  73 + assert_tag(tag: "div", attributes: { class: "person-item" } , descendant: { tag: "a", child: "person 1"} )
  74 + end
75 75  
76 76 should 'return new person indexed' do
77 77 get :index, { "selected_type" => :community}
78 78 assert_response :success
79 79 assert_select ".search-item", 6
80 80  
81   - fast_create Community, name: "community_#{7}", created_at: Date.new
  81 + fast_create Community, name: "community #{7}", created_at: Date.new
82 82 Community.import
83 83 sleep 2
84 84  
... ... @@ -108,7 +108,7 @@ class ElasticsearchPluginControllerTest &lt; ActionController::TestCase
108 108 end
109 109  
110 110 should 'pass params to elastic search controller' do
111   - get 'index', { query: 'community_' }
  111 + get 'index', { query: 'community' }
112 112 assert_not_nil assigns(:results)
113 113 assert_template partial: '_community_display'
114 114 end
... ...
plugins/elasticsearch/test/unit/helpers/elasticsearch_helper_test.rb 0 → 100644
... ... @@ -0,0 +1,86 @@
  1 +require "#{File.dirname(__FILE__)}/../../test_helper"
  2 +require_relative '../../../helpers/elasticsearch_helper.rb'
  3 +
  4 +class ElasticsearchHelperTest < ActiveSupport::TestCase
  5 +
  6 + include ElasticsearchTestHelper
  7 + include ElasticsearchHelper
  8 +
  9 + attr_accessor :params
  10 +
  11 + def indexed_models
  12 + [Person,TextArticle,UploadedFile,Community,Event]
  13 + end
  14 +
  15 + def create_instances
  16 + create_user "Jose Abreu"
  17 + create_user "Joana Abreu"
  18 + create_user "Joao Abreu"
  19 + create_user "Ana Abreu"
  20 + end
  21 +
  22 + should 'return default_per_page when nil is passed' do
  23 + assert_not_nil default_per_page nil
  24 + assert_equal 10, default_per_page(nil)
  25 + end
  26 +
  27 + should 'return default_per_page when per_page is passed' do
  28 + assert_equal 15, default_per_page(15)
  29 + end
  30 +
  31 + should 'have indexed_models in searchable_models' do
  32 + assert_equivalent indexed_models, searchable_models
  33 + end
  34 +
  35 + should 'return query_string if expression is valid' do
  36 +
  37 + query= "my_query"
  38 + fields = ['name','login']
  39 + result = query_method(query,fields)
  40 +
  41 + assert_includes result[:query][:query_string][:query], query
  42 + assert_equivalent result[:query][:query_string][:fields], fields
  43 + end
  44 +
  45 +
  46 + should 'return fields from models using weight' do
  47 + class StubClass
  48 + SEARCHABLE_FIELDS = {:name => {:weight => 10},
  49 + :login => {:weight => 20},
  50 + :description => {:weight => 2}}
  51 + end
  52 +
  53 + expected = ["name^10", "login^20", "description^2"]
  54 + assert_equivalent expected, fields_from_models([StubClass])
  55 + end
  56 +
  57 + should 'search from model Person sorted by Alphabetic' do
  58 + self.params= {:selected_type => 'person',
  59 + :filter => 'lexical',
  60 + :query => "Abreu",
  61 + :per_page => 4}
  62 +
  63 + result = process_results
  64 + assert_equal ["Ana Abreu","Joana Abreu","Joao Abreu","Jose Abreu"], result.map(&:name)
  65 + end
  66 +
  67 + should 'search from model Person sorted by More Recent' do
  68 + self.params= {:selected_type => 'person',
  69 + :filter => 'more_recent',
  70 + :query => 'ABREU',
  71 + :per_page => 4}
  72 +
  73 + result = process_results
  74 + assert_equal ["Ana Abreu","Joao Abreu","Joana Abreu","Jose Abreu"], result.map(&:name)
  75 + end
  76 +
  77 + should 'search from model Person sorted by Relevance' do
  78 + self.params= {:selected_type => 'person',
  79 + :query => 'JOA BREU',
  80 + :per_page => 4}
  81 +
  82 + result = process_results
  83 + assert_equal ["Joana Abreu", "Joao Abreu"], result.map(&:name)
  84 + end
  85 +
  86 +end
... ...
plugins/elasticsearch/test/unit/models/community_test.rb
... ... @@ -8,10 +8,6 @@ class CommunityTest &lt; ActionController::TestCase
8 8 [Community]
9 9 end
10 10  
11   - def setup
12   - super
13   - end
14   -
15 11 should 'index searchable fields for Community model' do
16 12 Community::SEARCHABLE_FIELDS.each do |key, value|
17 13 assert_includes indexed_fields(Community), key
... ...
plugins/elasticsearch/test/unit/models/event_test.rb
... ... @@ -8,10 +8,6 @@ class EventTest &lt; ActionController::TestCase
8 8 [Event]
9 9 end
10 10  
11   - def setup
12   - super
13   - end
14   -
15 11 should 'index searchable fields for Event model' do
16 12 Event::SEARCHABLE_FIELDS.each do |key, value|
17 13 assert_includes indexed_fields(Event), key
... ...
plugins/elasticsearch/test/unit/models/person_test.rb
... ... @@ -8,10 +8,6 @@ class PersonTest &lt; ActionController::TestCase
8 8 [Person]
9 9 end
10 10  
11   - def setup
12   - super
13   - end
14   -
15 11 should 'index searchable fields for Person model' do
16 12 Person::SEARCHABLE_FIELDS.each do |key, value|
17 13 assert_includes indexed_fields(Person), key
... ... @@ -24,5 +20,4 @@ class PersonTest &lt; ActionController::TestCase
24 20 assert_includes indexed_fields(Person)[key][:type], value[:type] || 'string'
25 21 end
26 22 end
27   -
28 23 end
... ...
plugins/elasticsearch/test/unit/models/text_article_test.rb
... ... @@ -8,10 +8,6 @@ class TextArticleTest &lt; ActionController::TestCase
8 8 [TextArticle]
9 9 end
10 10  
11   - def setup
12   - super
13   - end
14   -
15 11 should 'index searchable fields for TextArticle model' do
16 12 TextArticle::SEARCHABLE_FIELDS.each do |key, value|
17 13 assert_includes indexed_fields(TextArticle), key
... ...
plugins/elasticsearch/test/unit/models/uploaded_file_test.rb
... ... @@ -8,10 +8,6 @@ class UploadedFileTest &lt; ActionController::TestCase
8 8 [UploadedFile]
9 9 end
10 10  
11   - def setup
12   - super
13   - end
14   -
15 11 should 'index searchable fields for UploadedFile model' do
16 12 UploadedFile::SEARCHABLE_FIELDS.each do |key, value|
17 13 assert_includes indexed_fields(UploadedFile), key
... ...
plugins/elasticsearch/views/elasticsearch_plugin/_person_display.html.erb
... ... @@ -3,7 +3,7 @@
3 3 <%= profile_image person %>
4 4 </div>
5 5 <div class="right-side">
6   - <%= person.created_at.strftime("%d %B %Y at %H:%M") %> - <%= person.name %> <span class="model-label"><%= _("Person") %></span>
  6 + <%= person.created_at.strftime("%d %B %Y at %H:%M") %> - <span class="model-label"><%= _("Person") %></span>
7 7 <div class="body">
8 8 <h2><%= link_to person.name, person.url %></h2>
9 9 <p><%= person.description %></p>
... ...
plugins/elasticsearch/views/elasticsearch_plugin/_text_article_display.html.erb
1 1 <div class="text_article-header">
2   - <%= text_article.created_at.strftime("%d %B %Y at %H:%M") %> - <%= text_article.setting[:author_name] %> - <span class="model-label"><%= _("Community") %></span>
  2 + <%= text_article.created_at.strftime("%d %B %Y at %H:%M") %> - <%= "#{text_article.author.name} -" if text_article.author %> <span class="model-label"><%= _("Article") %></span>
3 3 </div>
4 4 <div class="body">
5 5 <h2><%= link_to text_article.name, text_article.url %></h2>
... ...
plugins/elasticsearch/views/elasticsearch_plugin/_uploaded_file_display.html.erb
1 1 <div class="uploaded_file-header">
2   - <%= uploaded_file.created_at.strftime("%d %B %Y at %H:%M") %> - <%=uploaded_file.setting[:author_name]%> - <span class="model-label"><%= _("Files") %></span>
  2 + <%= uploaded_file.created_at.strftime("%d %B %Y at %H:%M") %> - <%= "#{uploaded_file.author.name} -" if uploaded_file.author %><span class="model-label"><%= _("Files") %></span>
3 3 </div>
4 4 <div class="body">
5 5 <h2><%= link_to uploaded_file.name, uploaded_file.url %></h2>
... ...
plugins/elasticsearch/views/elasticsearch_plugin/search.html.erb
... ... @@ -5,7 +5,7 @@
5 5 <ul>
6 6 <% for type,value in @searchable_types %>
7 7 <li class="select-search-type <%= "active" if type == @selected_type %>">
8   - <%= link_to value[:label], "?selected_type=#{type}&query=#{@query}&selected_filter_field=#{@selected_filter_field}"%>
  8 + <%= link_to value[:label], "?selected_type=#{type}&query=#{@query}&filter=#{@selected_filter}"%>
9 9 </li>
10 10 <% end %>
11 11 </ul>
... ... @@ -13,8 +13,10 @@
13 13 <div class="search-filter">
14 14 <h3 class="box-title"><%= _("Sort by") %></h3>
15 15 <ul>
16   - <% for type in @search_filter_types.values %>
17   - <li><a href="#"><%= type[:label] %></a></li>
  16 + <% for type, value in @filter_types %>
  17 + <li class="select-search-type <%= "active" if type == @selected_filter %>">
  18 + <%= link_to value[:label], "?selected_type=#{@selected_type}&query=#{@query}&filter=#{type}" %>
  19 + </li>
18 20 <% end %>
19 21 </ul>
20 22 </div>
... ... @@ -24,21 +26,22 @@
24 26 <div class="search_field">
25 27 <%= form_tag '/plugin/elasticsearch/search', method: :get do %>
26 28 <%= hidden_field_tag "selected_type", @selected_type %>
27   - <%= hidden_field_tag "selected_filter_field", @selected_filter_field %>
  29 + <% if @selected_filter %>
  30 + <%= hidden_field_tag "filter", @selected_filter %>
  31 + <% end %>
28 32 <%= text_field_tag :query, @query %>
29 33 <%= submit_tag _("Send") %>
30 34 <% end %>
31 35 </div>
32 36 <div class="results-count">
33   - <% if not @query.blank? %>
34   - <p>
35   - <strong><%= @results.total %></strong><%= _(" results for ") %><%= @query %>
  37 + <p>
  38 + <strong><%= @hits %></strong>
  39 + <% if not @query.blank? %>
  40 + <%= _(" results for ") %><%= @query %>
  41 + <% else %>
  42 + <%= _(" total results") %>
  43 + <% end %>
36 44 </p>
37   - <% else %>
38   - <p>
39   - <strong><%= @results.total %></strong><%= _(" total results") %>
40   - </p>
41   - <% end %>
42 45 </div>
43 46  
44 47  
... ... @@ -55,7 +58,7 @@
55 58 <% end %>
56 59 <% end %>
57 60 <div class="search_paginate">
58   - <%= pagination_links @results %>
  61 + <%= pagination_links @results if @results.count > 0 %>
59 62 </div>
60 63 </div>
61 64 </div>
... ...