Commit 7c23a765db516a4879c6e0d3566b2fa1c22b0c1c

Authored by David Silva
Committed by Macartur Sousa
1 parent 0dd3b2f8

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>
... ...