Merge Request #17

Merged
noosferogov/noosfero!17
Created by Macartur Sousa

Elasticsearch filter

Merged by Daniel Damasceno

Commits (11)
4 participants
Showing 36 changed files   Show diff stats
plugins/elasticsearch/controllers/elasticsearch_plugin_controller.rb
... ... @@ -11,7 +11,7 @@ class ElasticsearchPluginController < ApplicationController
11 11  
12 12 def search
13 13 define_searchable_types
14   - define_search_fields_types
  14 + define_sort_types
15 15 define_results
16 16 end
17 17  
... ... @@ -22,13 +22,13 @@ class ElasticsearchPluginController < ApplicationController
22 22 end
23 23  
24 24 def define_searchable_types
25   - @searchable_types = ElasticsearchHelper::searchable_types
  25 + @searchable_types = searchable_types
26 26 @selected_type = (params[:selected_type]|| :all ).to_sym
27 27 end
28 28  
29   - def define_search_fields_types
30   - @filter_types = ElasticsearchHelper::filters
31   - @selected_filter = (params[:filter] || :relevance).to_sym
  29 + def define_sort_types
  30 + @sort_types = sort_types
  31 + @selected_sort = (params[:filter] || :relevance).to_sym
32 32 end
33 33  
34 34 end
... ...
plugins/elasticsearch/helpers/elasticsearch_helper.rb
1 1 module ElasticsearchHelper
2 2  
3   - def self.searchable_types
  3 + def searchable_types
4 4 {
5 5 :all => { label: _("All Results")},
6 6 :text_article => { label: _("Articles")},
... ... @@ -11,12 +11,20 @@ module ElasticsearchHelper
11 11 }
12 12 end
13 13  
14   - def self.filters
15   - {
  14 + def sort_types
  15 + sorts = {
16 16 :relevance => { label: _("Relevance")},
17 17 :lexical => { label: _("Alphabetical")},
18 18 :more_recent => { label: _("More Recent")},
19 19 }
  20 +
  21 + selected_type = params[:selected_type] || nil
  22 +
  23 + if selected_type and selected_type.to_sym != :all
  24 + klass = selected_type.to_s.classify.constantize
  25 + sorts.update klass.especific_sort if klass.respond_to? :especific_sort
  26 + end
  27 + sorts
20 28 end
21 29  
22 30 def process_results
... ... @@ -27,15 +35,20 @@ module ElasticsearchHelper
27 35 private
28 36  
29 37 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
  38 + begin
  39 + filter = (params[:filter] || "" ).to_sym
  40 + query = get_query params[:query], sort_by: get_sort_by(filter)
  41 + Elasticsearch::Model.search(query,searchable_models, size: default_per_page(params[:per_page])).page(params[:page]).records
  42 + rescue
  43 + []
  44 + end
32 45 end
33 46  
34 47 def search_from_model model
35 48 begin
36 49 klass = model.to_s.classify.constantize
37   -
38   - query = get_query params[:query], klass: klass, sort_by: get_sort_by(params[:filter])
  50 + filter = (params[:filter] || "" ).to_sym
  51 + query = get_query params[:query], klass: klass, sort_by: get_sort_by(filter,klass)
39 52 klass.search(query, size: default_per_page(params[:per_page])).page(params[:page]).records
40 53 rescue
41 54 []
... ... @@ -46,49 +59,58 @@ module ElasticsearchHelper
46 59 per_page ||= 10
47 60 end
48 61  
49   - def get_sort_by sort_by
  62 + def get_sort_by sort_by, klass=nil
50 63 case sort_by
51   - when "lexical"
  64 + when :lexical
52 65 { "name.raw" => {"order" => "asc" }}
53   - when "more_recent"
  66 + when :more_recent
54 67 { "created_at" => {"order" => "desc"}}
  68 + else
  69 + ( klass and klass.respond_to?(:get_sort_by) ) ? klass.get_sort_by(sort_by) : nil
55 70 end
56 71 end
57 72  
58 73 def searchable_models
59   - begin
60   - ElasticsearchHelper::searchable_types.except(:all).keys.map { | model | model.to_s.classify.constantize }
61   - rescue
62   - []
63   - end
  74 + searchable_types.except(:all).keys.map { | model | model.to_s.classify.constantize }
  75 + end
  76 +
  77 + def query_string expression="", models=[]
  78 + return { match_all: {} } if not expression
  79 + {
  80 + query_string: {
  81 + query: "*"+expression.downcase.split.join('* *')+"*",
  82 + fields: fields_from_models(models),
  83 + tie_breaker: 0.4,
  84 + minimum_should_match: "100%"
  85 + }
  86 + }
64 87 end
65 88  
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   - },
  89 +
  90 + def query_method expression="", models=[]
  91 + {
  92 + query: {
  93 + filtered: {
  94 + query: query_string(expression,models),
  95 + filter: {
  96 + bool: {
  97 + should: models.map {|model| model.filter(environment: @environment.id) }
  98 + }
  99 + }
78 100 }
79 101 }
80   - end
81   - query_exp
  102 + }
82 103 end
83 104  
84 105 def get_query text="", options={}
85 106 klass = options[:klass]
86 107 sort_by = options[:sort_by]
87 108  
88   - fields = klass.nil? ? (fields_from_models searchable_models) : (fields_from_models [klass])
  109 + models = (klass.nil?) ? searchable_models : [klass]
89 110  
90   - query = query_method(text, fields)
  111 + query = query_method(text, models)
91 112 query[:sort] = sort_by if sort_by
  113 +
92 114 query
93 115 end
94 116  
... ...
plugins/elasticsearch/lib/elasticsearch_plugin/api.rb
... ... @@ -10,14 +10,18 @@ class ElasticsearchPlugin::API < Grape::API
10 10 target = process_results
11 11 present target,
12 12 :with => Elasticsearch::Entities::Result,
13   - :types => ElasticsearchHelper.searchable_types.except(:all).keys.map { |key| key.to_s.classify }
  13 + :types => searchable_types.except(:all).keys.map { |key| key.to_s.classify }
14 14 end
15 15  
16 16 get 'types' do
17   - types = {types: ElasticsearchHelper::searchable_types.stringify_keys.keys}
  17 + types = {types: searchable_types.stringify_keys.keys }
18 18 present types, with: Grape::Presenters::Presenter
19 19 end
20 20  
  21 + get 'sort_types' do
  22 + present sort_types, with: Grape::Presenters::Presenter
  23 + end
  24 +
21 25 end
22 26  
23 27 end
... ...
plugins/elasticsearch/lib/ext/community.rb
1 1 require_dependency 'community'
2   -require_relative '../elasticsearch_indexed_model'
  2 +require_relative '../searchable_model_helper'
3 3  
4 4 class Community
  5 +
5 6 def self.control_fields
6 7 {
7   - :created_at => {type: 'date'}
  8 + :secret => { type: :boolean },
  9 + :visible => { type: :boolean },
  10 + :activities_count => { type: :integer },
  11 + :members_count => { type: :integer }
  12 + }
  13 + end
  14 +
  15 + def self.should
  16 + [
  17 + { and:
  18 + [
  19 + {term: { :secret => false }},
  20 + {term: { :visible => true }}
  21 + ]
  22 + }
  23 + ]
  24 + end
  25 +
  26 + def self.especific_sort
  27 + {
  28 + :more_active => { label: _("More Active") },
  29 + :more_popular => { label: _("More Popular") }
8 30 }
9 31 end
10   - include ElasticsearchIndexedModel
  32 +
  33 + def self.get_sort_by sort_by=""
  34 + case sort_by
  35 + when :more_active
  36 + { :activities_count => {order: :desc}}
  37 + when :more_popular
  38 + { :members_count => {order: :desc}}
  39 + end
  40 + end
  41 +
  42 + include SearchableModelHelper
11 43 end
... ...
plugins/elasticsearch/lib/ext/event.rb
1 1 require_dependency 'event'
2   -require_relative '../elasticsearch_indexed_model'
  2 +
  3 +require_relative '../searchable_model_helper'
  4 +require_relative '../nested_helper/profile'
3 5  
4 6 class Event
  7 + #TODO: o filtro é feito de forma diferente do artigo
  8 +
5 9 def self.control_fields
6 10 {
7   - :advertise => {},
8   - :published => {},
9   - :created_at => {type: 'date'}
  11 + :advertise => {type: :boolean},
  12 + :published => {type: :boolean},
  13 + :profile => { type: :nested , hash: NestedProfile.hash }
10 14 }
11 15 end
12   - include ElasticsearchIndexedModel
  16 +
  17 + def self.should
  18 + [
  19 + { and: [
  20 + { term: { advertise: true }},
  21 + { term: { published: true }}
  22 + ]
  23 + }
  24 + ]
  25 + end
  26 +
  27 + def self.nested_filter
  28 + [
  29 + NestedProfile::filter
  30 + ]
  31 + end
  32 +
  33 + include SearchableModelHelper
13 34 end
... ...
plugins/elasticsearch/lib/ext/person.rb
1 1 require_dependency 'person'
2   -require_relative '../elasticsearch_indexed_model'
  2 +
  3 +require_relative '../searchable_model_helper'
3 4  
4 5 class Person
  6 +
5 7 def self.control_fields
6 8 {
7   - :visible => {type: 'boolean'},
8   - :public_profile => {type: 'boolean'},
9   - :created_at => {type: 'date'}
  9 + :visible => {type: 'boolean'},
  10 + :secret => { type: :boolean },
  11 + :activities_count => { type: :integer },
  12 + :friends_count => { type: :integer }
10 13 }
11 14 end
12   - include ElasticsearchIndexedModel
  15 +
  16 + def self.should
  17 + [
  18 + { and:
  19 + [
  20 + {term: { :secret => false }},
  21 + {term: { :visible => true }}
  22 + ]
  23 + }
  24 + ]
  25 + end
  26 +
  27 + def self.especific_sort
  28 + {
  29 + :more_active => { label: _("More Active") },
  30 + :more_popular => { label: _("More Popular") }
  31 + }
  32 + end
  33 +
  34 + def self.get_sort_by sort_by=""
  35 + case sort_by
  36 + when :more_active
  37 + { :activities_count => {order: :desc}}
  38 + when :more_popular
  39 + { :friends_count => {order: :desc} }
  40 + end
  41 + end
  42 +
  43 + include SearchableModelHelper
13 44 end
... ...
plugins/elasticsearch/lib/ext/text_article.rb
1 1 # REQUIRE TO LOAD DESCENDANTS FROM TEXT_ARTICLE
2 2 require_dependency 'raw_html_article'
3 3 require_dependency 'tiny_mce_article'
4   -
5 4 require_dependency 'text_article'
6   -require_relative '../elasticsearch_indexed_model'
  5 +
  6 +require_relative '../searchable_model_helper'
  7 +require_relative '../nested_helper/profile'
7 8  
8 9 class TextArticle
  10 +
9 11 def self.control_fields
10 12 {
11   - :advertise => {},
12   - :published => {},
13   - :created_at => {type: 'date'}
  13 + :advertise => { type: :boolean },
  14 + :published => { type: 'boolean'},
  15 + :comments_count => { type: :integer },
  16 + :hits => { type: :integer },
  17 + :profile => { type: :nested , hash: NestedProfile.hash }
  18 + }
  19 + end
  20 +
  21 + def self.should
  22 + [
  23 + { and: [
  24 + { term: { advertise: true }},
  25 + { term: { published: true }}
  26 + ]
  27 + }
  28 + ]
  29 + end
  30 +
  31 + def self.nested_filter
  32 + [
  33 + NestedProfile::filter
  34 + ]
  35 + end
  36 +
  37 + def self.especific_sort
  38 + {
  39 + :more_popular => { label: _("More Viewed") },
  40 + :more_comments => { label: _("Most Commented") }
14 41 }
15 42 end
16   - include ElasticsearchIndexedModel
  43 +
  44 + def self.get_sort_by sort_by=""
  45 + case sort_by
  46 + when :more_popular
  47 + { :hits => {order: :desc} }
  48 + when :more_comments
  49 + { :comments_count => {order: :desc}}
  50 + end
  51 + end
  52 +
  53 + include SearchableModelHelper
17 54 end
... ...
plugins/elasticsearch/lib/ext/uploaded_file.rb
1 1 require_dependency 'uploaded_file'
2   -require_relative '../elasticsearch_indexed_model'
  2 +
  3 +require_relative '../searchable_model_helper'
  4 +require_relative '../nested_helper/profile'
3 5  
4 6 class UploadedFile
5 7 def self.control_fields
6 8 {
7   - :advertise => {},
8   - :published => {},
9   - :created_at => {type: 'date'}
  9 + :advertise => {type: :boolean},
  10 + :published => {type: :boolean},
  11 + :profile => { type: :nested , hash: NestedProfile.hash }
10 12 }
11 13 end
12   - include ElasticsearchIndexedModel
  14 +
  15 + def self.should
  16 + [
  17 + { and: [
  18 + { term: { advertise: true }},
  19 + { term: { published: true }}
  20 + ]
  21 + }
  22 + ]
  23 + end
  24 +
  25 + def self.nested_filter
  26 + [
  27 + NestedProfile::filter
  28 + ]
  29 + end
  30 +
  31 + include SearchableModelHelper
13 32 end
... ...
plugins/elasticsearch/lib/nested_helper/environment.rb 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +module NestedEnvironment
  2 +
  3 + def self.hash
  4 + {
  5 + :id => { type: :integer },
  6 + :is_default => {type: :boolean }
  7 + }
  8 + end
  9 +
  10 + def self.filter environment=1
  11 + {
  12 + query: {
  13 + nested: {
  14 + path: "environment",
  15 + query: {
  16 + bool: {
  17 + must: { term: { "environment.id" => environment } },
  18 + }
  19 + }
  20 + }
  21 + }
  22 + }
  23 + end
  24 +
  25 +end
... ...
plugins/elasticsearch/lib/nested_helper/profile.rb 0 → 100644
... ... @@ -0,0 +1,29 @@
  1 +module NestedProfile
  2 +
  3 + def self.hash
  4 + {
  5 + :id => { type: :integer },
  6 + :visible => { type: :boolean },
  7 + :public_profile => { type: :boolean }
  8 + }
  9 + end
  10 +
  11 + def self.filter
  12 + {
  13 + query: {
  14 + nested: {
  15 + path: "profile",
  16 + query: {
  17 + bool: {
  18 + must:[
  19 + { term: { "profile.visible" => true } },
  20 + { term: { "profile.public_profile" => true } }
  21 + ],
  22 + }
  23 + }
  24 + }
  25 + }
  26 + }
  27 + end
  28 +
  29 +end
... ...
plugins/elasticsearch/lib/searchable_model/elasticsearch_indexed_model.rb 0 → 100644
... ... @@ -0,0 +1,99 @@
  1 +require_relative '../nested_helper/environment'
  2 +
  3 +module ElasticsearchIndexedModel
  4 +
  5 + def self.included base
  6 + base.send :include, Elasticsearch::Model
  7 + base.send :include, Elasticsearch::Model::Callbacks
  8 +
  9 + base.send :index_name, "#{Rails.env}_#{base.index_name}"
  10 +
  11 + base.extend ClassMethods
  12 + base.send :include, InstanceMethods
  13 +
  14 + base.class_eval do
  15 + settings index: { number_of_shards: 1 } do
  16 + mappings dynamic: 'false' do
  17 + base.indexed_fields.each do |field, value|
  18 + type = value[:type].presence
  19 +
  20 + if type == :nested
  21 + indexes(field, type: type) do
  22 + value[:hash].each do |hash_field, hash_value|
  23 + indexes(hash_field, base.indexes_as_hash(hash_field,hash_value[:type].presence))
  24 + end
  25 + end
  26 + else
  27 + indexes(field, base.indexes_as_hash(field,type))
  28 + end
  29 + print '.'
  30 + end
  31 + end
  32 +
  33 + base.__elasticsearch__.client.indices.delete \
  34 + index: base.index_name rescue nil
  35 + base.__elasticsearch__.client.indices.create \
  36 + index: base.index_name,
  37 + body: {
  38 + settings: base.settings.to_hash,
  39 + mappings: base.mappings.to_hash
  40 + }
  41 + end
  42 + end
  43 + base.send :import
  44 + end
  45 +
  46 + module ClassMethods
  47 +
  48 + def indexes_as_hash(name, type)
  49 + hash = {}
  50 + if type.nil?
  51 + hash[:fields] = raw_field(name, type)
  52 + else
  53 + hash[:type] = type if not type.nil?
  54 + end
  55 + hash
  56 + end
  57 +
  58 + def raw_field name, type
  59 + {
  60 + raw: {
  61 + type: "string",
  62 + index: "not_analyzed"
  63 + }
  64 + }
  65 + end
  66 +
  67 + def indexed_fields
  68 + fields = {
  69 + :environment => {type: :nested, hash: NestedEnvironment::hash },
  70 + :category_ids => {type: :integer },
  71 + :created_at => {type: :date }
  72 + }
  73 + fields.update(self::SEARCHABLE_FIELDS)
  74 + fields.update(self.control_fields)
  75 + fields
  76 + end
  77 +
  78 + end
  79 +
  80 + module InstanceMethods
  81 + def as_indexed_json options={}
  82 + attrs = {}
  83 +
  84 + self.class.indexed_fields.each do |field, value|
  85 + type = value[:type].presence
  86 + if type == :nested
  87 + attrs[field] = {}
  88 + value[:hash].each do |hash_field, hash_value|
  89 + attrs[field][hash_field] = self.send(field).send(hash_field)
  90 + end
  91 + else
  92 + attrs[field] = self.send(field)
  93 + end
  94 + end
  95 + attrs.as_json
  96 + end
  97 + end
  98 +
  99 +end
... ...
plugins/elasticsearch/lib/searchable_model/filter.rb 0 → 100644
... ... @@ -0,0 +1,41 @@
  1 +require_relative '../nested_helper/environment'
  2 +
  3 +module Filter
  4 +
  5 + def self.included base
  6 + base.extend ClassMethods
  7 + base.send :include, InstanceMethods
  8 + end
  9 +
  10 + module ClassMethods
  11 +
  12 + def filter options={}
  13 + environment = options[:environment].presence
  14 +
  15 + result_filter = {}
  16 + result_filter[:indices] = {:index => self.index_name, :no_match_filter => "none" }
  17 + result_filter[:indices][:filter] = { :bool => self.filter_bool(environment) }
  18 +
  19 + result_filter
  20 + end
  21 +
  22 + def filter_bool environment
  23 + result_filter = {}
  24 +
  25 + result_filter[:must] = [ NestedEnvironment::filter(environment) ]
  26 +
  27 + self.nested_filter.each {|filter| result_filter[:must].append(filter)} if self.respond_to? :nested_filter
  28 + self.must.each {|filter| result_filter[:must].append(filter) } if self.respond_to? :must
  29 +
  30 + result_filter[:should] = self.should if self.respond_to? :should
  31 + result_filter[:must_not] = self.must_not if self.respond_to? :must_not
  32 +
  33 + result_filter
  34 + end
  35 + end
  36 +
  37 + module InstanceMethods
  38 +
  39 + end
  40 +
  41 +end
... ...
plugins/elasticsearch/lib/searchable_model_helper.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +require_relative './searchable_model/elasticsearch_indexed_model'
  2 +require_relative './searchable_model/filter'
  3 +
  4 +module SearchableModelHelper
  5 + def self.included base
  6 + base.send :include, ElasticsearchIndexedModel
  7 + base.send :include, Filter
  8 + end
  9 +end
... ...
plugins/elasticsearch/public/style.css
... ... @@ -3,7 +3,7 @@
3 3 }
4 4  
5 5 .controller-elasticsearch_plugin .sidebar {
6   - width: 270px;
  6 + min-width: 240px;
7 7 }
8 8  
9 9 .controller-elasticsearch_plugin .search_form {
... ... @@ -38,7 +38,7 @@
38 38 }
39 39  
40 40 .controller-elasticsearch_plugin .results {
41   - flex: 2;
  41 + flex: 1;
42 42 margin-top: 20px;
43 43 border-radius: 5px;
44 44 border: 1px solid #eee;
... ... @@ -124,15 +124,13 @@
124 124 margin: 15px;
125 125 }
126 126  
127   -.controller-elasticsearch_plugin .search-item .person-item {
128   - display: flex;
129   -}
130   -
131 127 .controller-elasticsearch_plugin .right-side {
132   - flex: 2;
  128 + float: left;
  129 + width: calc(100% - 80px);
133 130 }
134 131  
135 132 .controller-elasticsearch_plugin .left-side {
  133 + float: left;
136 134 width: 80px;
137 135 }
138 136  
... ...
plugins/elasticsearch/test/api/elasticsearch_plugin_api_test.rb 0 → 100644
... ... @@ -0,0 +1,113 @@
  1 +require "#{File.dirname(__FILE__)}/../test_helper"
  2 +require_relative '../../helpers/elasticsearch_helper'
  3 +
  4 +class ElasticsearchPluginApiTest < ActiveSupport::TestCase
  5 +
  6 + include ElasticsearchTestHelper
  7 + include ElasticsearchHelper
  8 +
  9 + def indexed_models
  10 + [Person,TextArticle,UploadedFile,Community,Event]
  11 + end
  12 +
  13 + def create_instances
  14 + create_instances_environment
  15 + create_instances_environment2
  16 + end
  17 +
  18 + def create_instances_environment2
  19 + create_user "Sample User Environment 2", environment:Environment.second
  20 + fast_create Community, name:"Sample Community Environment 2", created_at: Date.new, environment_id: Environment.second.id
  21 + end
  22 +
  23 + def create_instances_environment
  24 + create_visible_models
  25 + create_private_models
  26 + end
  27 +
  28 + def create_visible_models
  29 + 7.times{ | index | create_user "person #{index}" }
  30 + 4.times{ | index | fast_create Community, name: "community #{index}", created_at: Date.new }
  31 + end
  32 +
  33 + def create_private_models
  34 + secret_user = create_user("Secret Person")
  35 + fast_update(secret_user.person, secret: true, visible: true)
  36 +
  37 + invisible_user= create_user("Invisible Person")
  38 + fast_update(invisible_user.person, secret: false, visible: false, public_profile: false)
  39 +
  40 + fast_create(Community, name: "secret community", secret: true, visible: true)
  41 + fast_create(Community, name: "invisible community", secret: false, visible: false)
  42 +
  43 + create_private_article(TextArticle,public_person: User.first.person, private_person: invisible_user.person)
  44 + create_private_article(UploadedFile,public_person: User.first.person, private_person: invisible_user.person)
  45 + create_private_article(Event,public_person: User.first.person, private_person: invisible_user.person)
  46 +
  47 + end
  48 +
  49 + def create_private_article model,options = {}
  50 + public_person = options[:public_person]
  51 + private_person = options[:private_person]
  52 +
  53 + fast_create(model, name: "#{model.to_s.underscore} not advertise", advertise: false, published: true, profile_id: public_person, created_at: Time.now)
  54 + fast_create(model, name: "#{model.to_s.underscore} not published", advertise: true, published: false, profile_id: public_person, created_at: Time.now)
  55 + fast_create(model, name: "#{model.to_s.underscore} with not visible profile", advertise: true, published: true, profile_id: private_person, created_at: Time.now)
  56 + fast_create(model, name: "#{model.to_s.underscore} with not public_profile", advertise: true, published: true, profile_id: private_person, created_at: Time.now)
  57 + end
  58 +
  59 + def create_instances
  60 + 7.times.each {|index| create_user "person #{index}"}
  61 + 4.times.each {|index| fast_create Community, name: "community #{index}" }
  62 + end
  63 +
  64 + should 'show all types avaliable in /search/types endpoint' do
  65 + get "/api/v1/search/types"
  66 + json = JSON.parse(last_response.body)
  67 + assert_equal 200, last_response.status
  68 + assert_equal searchable_types.stringify_keys.keys, json["types"]
  69 + end
  70 +
  71 + should 'respond with endpoint /search with more than 10 results' do
  72 + get "/api/v1/search"
  73 + json = JSON.parse(last_response.body)
  74 + assert_equal 200, last_response.status
  75 + assert_equal 10, json["results"].count
  76 + end
  77 +
  78 + should 'respond with query in downcase' do
  79 + get "/api/v1/search?query=person"
  80 + json = JSON.parse(last_response.body)
  81 + assert_equal 200, last_response.status
  82 + assert_equal 7, json["results"].count
  83 + end
  84 +
  85 + should 'respond with query in uppercase' do
  86 + get "/api/v1/search?query=PERSON"
  87 + json = JSON.parse(last_response.body)
  88 + assert_equal 200, last_response.status
  89 + assert_equal 7, json["results"].count
  90 + end
  91 +
  92 + should 'respond with selected_type' do
  93 + get "/api/v1/search?selected_type=community"
  94 + json = JSON.parse(last_response.body)
  95 + assert_equal 200, last_response.status
  96 + assert_equal 4, json["results"].count
  97 + end
  98 +
  99 + should 'filter person by default environment' do
  100 + get "/api/v1/search?selected_type=person"
  101 + json = JSON.parse(last_response.body)
  102 + assert_equal 200, last_response.status
  103 + assert_equal 7, json["results"].count
  104 + end
  105 +
  106 + should 'not show private text_article' do
  107 + get "/api/v1/search?selected_type=text_article"
  108 + json = JSON.parse(last_response.body)
  109 + assert_equal 200, last_response.status
  110 + assert_equal 7, json["results"].count
  111 + end
  112 +
  113 +end
... ...
plugins/elasticsearch/test/api/elasticsearch_plugin_entities_test.rb 0 → 100644
... ... @@ -0,0 +1,124 @@
  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", environment_id: 1
  13 +
  14 + fast_create Community, name: "sample community", created_at: 10.days.ago,updated_at: 5.days.ago, environment_id: 1
  15 +
  16 + fast_create UploadedFile, name: "sample uploadedfile", created_at: 3.days.ago, updated_at: 1.days.ago, author_id: user.person.id, abstract: "sample abstract", profile_id: user.person.id
  17 + fast_create Event, name: "sample event", created_at: 20.days.ago, updated_at: 5.days.ago, author_id: user.person.id, abstract: "sample abstract", profile_id: user.person.id
  18 + fast_create RawHTMLArticle, name: "sample raw html article", created_at: 15.days.ago ,updated_at: 5.days.ago, author_id: user.person.id, profile_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, profile_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 +
  39 + should 'show attributes from community' do
  40 + params = {:selected_type => "community" }
  41 + get "/api/v1/search?#{params.to_query}"
  42 + json= JSON.parse(last_response.body)
  43 +
  44 + expected_community = Community.find_by name: "sample community"
  45 +
  46 + assert_equal 200, last_response.status
  47 +
  48 + assert_equal expected_community.id, json['results'][0]['id']
  49 + assert_equal expected_community.name, json['results'][0]['name']
  50 + assert_equal expected_community.type, json['results'][0]['type']
  51 + assert_equal "", json['results'][0]['description']
  52 + assert_equal expected_community.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][0]['created_at']
  53 + assert_equal expected_community.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][0]['updated_at']
  54 + end
  55 +
  56 + should 'show attributes from text_article' do
  57 + params = {:selected_type => "text_article" }
  58 + get "/api/v1/search?#{params.to_query}"
  59 +
  60 + json= JSON.parse(last_response.body)
  61 +
  62 + assert_equal 200, last_response.status
  63 +
  64 + expected_text_articles = TextArticle.all
  65 +
  66 + expected_text_articles.each_with_index {|object,index|
  67 + assert_equal object.id, json['results'][index]['id']
  68 + assert_equal object.name, json['results'][index]['name']
  69 + assert_equal "TextArticle", json['results'][index]['type']
  70 +
  71 + expected_author = (object.author.nil?) ? "" : object.author.name
  72 +
  73 + assert_equal expected_author, json['results'][index]['author']
  74 + assert_equal object.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['created_at']
  75 + assert_equal object.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['updated_at']
  76 + }
  77 + end
  78 +
  79 + should 'show attributes from uploaded_file' do
  80 + params = {:selected_type => "uploaded_file"}
  81 + get "/api/v1/search?#{params.to_query}"
  82 +
  83 + json= JSON.parse(last_response.body)
  84 +
  85 + assert_equal 200, last_response.status
  86 +
  87 + expected_uploaded_files = UploadedFile.all
  88 + expected_uploaded_files.each_with_index {|object,index|
  89 + assert_equal object.id, json['results'][index]['id']
  90 + assert_equal object.name, json['results'][index]['name']
  91 + assert_equal object.abstract, json['results'][index]['abstract']
  92 + assert_equal "UploadedFile", json['results'][index]['type']
  93 +
  94 + expected_author = (object.author.nil?) ? "" : object.author.name
  95 + assert_equal expected_author, json['results'][index]['author']
  96 +
  97 + assert_equal object.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['created_at']
  98 + assert_equal object.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['updated_at']
  99 + }
  100 + end
  101 +
  102 + should 'show attributes from event' do
  103 + params = {:selected_type => "event"}
  104 + get "/api/v1/search?#{params.to_query}"
  105 +
  106 + json= JSON.parse(last_response.body)
  107 +
  108 + assert_equal 200, last_response.status
  109 + expected_events = Event.all
  110 + expected_events.each_with_index {|object,index|
  111 + assert_equal object.id, json['results'][index]['id']
  112 + assert_equal object.name, json['results'][index]['name']
  113 + assert_equal object.abstract, json['results'][index]['abstract']
  114 + assert_equal "Event", json['results'][index]['type']
  115 +
  116 + expected_author = (object.author.nil?) ? "" : object.author.name
  117 + assert_equal expected_author, json['results'][index]['author']
  118 +
  119 + assert_equal object.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['created_at']
  120 + assert_equal object.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['updated_at']
  121 + }
  122 + end
  123 +
  124 +end
... ...
plugins/elasticsearch/test/functional/elasticsearch_plugin_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,176 @@
  1 +require "#{File.dirname(__FILE__)}/../test_helper"
  2 +
  3 +class ElasticsearchPluginControllerTest < ActionController::TestCase
  4 +
  5 + include ElasticsearchTestHelper
  6 +
  7 + def indexed_models
  8 + [Person,TextArticle,UploadedFile,Community,Event]
  9 + end
  10 +
  11 + def create_instances
  12 + create_instances_environment
  13 + create_instances_environment2
  14 + end
  15 +
  16 + def create_instances_environment2
  17 + create_user "Sample User Environment 2", environment:Environment.second
  18 + fast_create Community, name:"Sample Community Environment 2", created_at: Date.new, environment_id: Environment.second.id
  19 + end
  20 +
  21 + def create_instances_environment
  22 + create_visible_models
  23 + create_private_models
  24 + end
  25 +
  26 + def create_visible_models
  27 + 5.times do | index |
  28 + create_user "person #{index}"
  29 + end
  30 + 6.times do | index |
  31 + fast_create Community, name: "community #{index}", created_at: Date.new
  32 + end
  33 + end
  34 +
  35 + def create_private_models
  36 + secret_user = create_user("Secret Person")
  37 + fast_update(secret_user.person, secret: true, visible: true)
  38 +
  39 + invisible_user= create_user("Invisible Person")
  40 + fast_update(invisible_user.person, secret: false, visible: false, public_profile: false)
  41 +
  42 + fast_create(Community, name: "secret community", secret: true, visible: true)
  43 + fast_create(Community, name: "invisible community", secret: false, visible: false)
  44 +
  45 + create_private_article(TextArticle,public_person: User.first.person, private_person: invisible_user.person)
  46 + create_private_article(UploadedFile,public_person: User.first.person, private_person: invisible_user.person)
  47 + create_private_article(Event,public_person: User.first.person, private_person: invisible_user.person)
  48 +
  49 + end
  50 +
  51 + def create_private_article model,options = {}
  52 + public_person = options[:public_person]
  53 + private_person = options[:private_person]
  54 +
  55 + fast_create(model, name: "#{model.to_s.underscore} not advertise", advertise: false, published: true, profile_id: public_person, created_at: Time.now)
  56 + fast_create(model, name: "#{model.to_s.underscore} not published", advertise: true, published: false, profile_id: public_person, created_at: Time.now)
  57 + fast_create(model, name: "#{model.to_s.underscore} with not visible profile", advertise: true, published: true, profile_id: private_person, created_at: Time.now)
  58 + fast_create(model, name: "#{model.to_s.underscore} with not public_profile", advertise: true, published: true, profile_id: private_person, created_at: Time.now)
  59 + end
  60 +
  61 +
  62 + should 'work and uses control filter variables' do
  63 + get :index
  64 + assert_response :success
  65 + assert_not_nil assigns(:searchable_types)
  66 + assert_not_nil assigns(:selected_type)
  67 + assert_not_nil assigns(:sort_types)
  68 + assert_not_nil assigns(:selected_sort)
  69 + end
  70 +
  71 + should 'return 10 results if selected_type is nil and query is nil' do
  72 + get :index
  73 + assert_response :success
  74 + assert_select ".search-item" , 10
  75 + end
  76 +
  77 + should 'render pagination if results has more than 10' do
  78 + get :index
  79 + assert_response :success
  80 + assert_select ".pagination", 1
  81 + end
  82 +
  83 + should 'return results filtered by selected_type' do
  84 + get :index, { 'selected_type' => :community}
  85 + assert_response :success
  86 + assert_select ".search-item", 6
  87 + assert_template partial: '_community_display'
  88 + end
  89 +
  90 + should 'return results filtered by query' do
  91 + get :index, { 'query' => "person"}
  92 + assert_response :success
  93 + assert_select ".search-item", 5
  94 + assert_template partial: '_person_display'
  95 + end
  96 +
  97 + should 'return results filtered by query with uppercase' do
  98 + get :index, {'query' => "PERSON 1"}
  99 + assert_response :success
  100 + assert_template partial: '_person_display'
  101 + assert_tag(tag: "div", attributes: { class: "person-item" } , descendant: { tag: "a", child: "person 1"} )
  102 + end
  103 +
  104 + should 'return results filtered by query with downcase' do
  105 + get :index, {'query' => "person 1"}
  106 + assert_response :success
  107 + assert_tag(tag: "div", attributes: { class: "person-item" } , descendant: { tag: "a", child: "person 1"} )
  108 + end
  109 +
  110 + should 'return new community indexed' do
  111 + get :index, { "selected_type" => :community}
  112 + assert_response :success
  113 + assert_select ".search-item", 6
  114 +
  115 + fast_create Community, name: "community #{7}", created_at: Date.new
  116 + Community.import
  117 + sleep 2
  118 +
  119 + get :index, { "selected_type" => :community}
  120 + assert_response :success
  121 + assert_select ".search-item", 7
  122 + end
  123 +
  124 + should 'not return community deleted' do
  125 + get :index, { "selected_type" => :community}
  126 + assert_response :success
  127 + assert_select ".search-item", 6
  128 +
  129 + Community.first.delete
  130 + Community.import
  131 + sleep 2
  132 +
  133 + get :index, { "selected_type" => :community}
  134 + assert_response :success
  135 + assert_select ".search-item", 5
  136 + end
  137 +
  138 + should 'redirect to elasticsearch plugin when request are send to core' do
  139 + @controller = SearchController.new
  140 + get 'index'
  141 + params = {:action => 'index', :controller => 'search'}
  142 + assert_redirected_to controller: 'elasticsearch_plugin', action: 'search', params: params
  143 + end
  144 +
  145 +
  146 + should 'filter community by default environment' do
  147 + get :index, { "selected_type" => :community}
  148 + assert_response :success
  149 + assert_select ".search-item", 6
  150 + end
  151 +
  152 + should 'filter person by default environment' do
  153 + get :index, { "selected_type" => :person}
  154 + assert_response :success
  155 + assert_select ".search-item", 5
  156 + end
  157 +
  158 + should 'not show private text_article' do
  159 + get :index, { :selected_type => "text_article" }
  160 + assert_response :success
  161 + assert_select ".search-item", 6
  162 + end
  163 +
  164 + should 'not show private uploaded_file' do
  165 + get :index, { :selected_type => "uploaded_file" }
  166 + assert_response :success
  167 + assert_select ".search-item", 0
  168 + end
  169 +
  170 + should 'not show private event' do
  171 + get :index, { :selected_type => "event" }
  172 + assert_response :success
  173 + assert_select ".search-item", 0
  174 + end
  175 +
  176 +end
... ...
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 2
  23 + sleep 3
24 24 end
25 25  
26 26 def setup_environment
... ...
plugins/elasticsearch/test/unit/community_test.rb 0 → 100644
... ... @@ -0,0 +1,46 @@
  1 +require "#{File.dirname(__FILE__)}/../test_helper"
  2 +
  3 +class CommunityTest < ActiveSupport::TestCase
  4 +
  5 + include ElasticsearchTestHelper
  6 +
  7 + def indexed_models
  8 + [Community]
  9 + end
  10 +
  11 + should 'index searchable fields for Community model' do
  12 + Community::SEARCHABLE_FIELDS.each do |key, value|
  13 + assert_includes indexed_fields(Community), key
  14 + end
  15 + end
  16 +
  17 + should 'index control fields for Community model' do
  18 + Community::control_fields.each do |key, value|
  19 + assert_includes indexed_fields(Community), key
  20 + assert_equal indexed_fields(Community)[key][:type], value[:type] || 'string'
  21 + end
  22 + end
  23 +
  24 + should 'respond with should method to return public community' do
  25 + assert Community.respond_to? :should
  26 + end
  27 +
  28 + should 'respond with especific sort' do
  29 + assert Community.respond_to? :especific_sort
  30 + end
  31 +
  32 + should 'respond with get_sort_by to order especific sort' do
  33 + assert Community.respond_to? :get_sort_by
  34 + end
  35 +
  36 + should 'return hash to sort by more_active' do
  37 + more_active_hash = {:activities_count => {order: :desc}}
  38 + assert_equal more_active_hash, Community.get_sort_by(:more_active)
  39 + end
  40 +
  41 + should 'return hash to sort by more_popular' do
  42 + more_popular_hash = {:members_count => {order: :desc}}
  43 + assert_equal more_popular_hash, Community.get_sort_by(:more_popular)
  44 + end
  45 +
  46 +end
... ...
plugins/elasticsearch/test/unit/elasticsearch_helper_test.rb 0 → 100644
... ... @@ -0,0 +1,80 @@
  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 fields from models using weight' do
  36 + class StubClass
  37 + SEARCHABLE_FIELDS = {:name => {:weight => 10},
  38 + :login => {:weight => 20},
  39 + :description => {:weight => 2}}
  40 + end
  41 +
  42 + expected = ["name^10", "login^20", "description^2"]
  43 + assert_equivalent expected, fields_from_models([StubClass])
  44 + end
  45 +
  46 + should 'search from model Person sorted by Alphabetic' do
  47 + self.params= {:selected_type => 'person',
  48 + :filter => 'lexical',
  49 + :query => "Abreu",
  50 + :per_page => 4}
  51 +
  52 + result = process_results
  53 + assert_equal ["Ana Abreu","Joana Abreu","Joao Abreu","Jose Abreu"], result.map(&:name)
  54 + end
  55 +
  56 + should 'search from model Person sorted by More Recent' do
  57 + self.params= {:selected_type => 'person',
  58 + :filter => 'more_recent',
  59 + :query => 'ABREU',
  60 + :per_page => 4}
  61 +
  62 + result = process_results
  63 + assert_equal ["Ana Abreu","Joao Abreu","Joana Abreu","Jose Abreu"], result.map(&:name)
  64 + end
  65 +
  66 + should 'search from model Person sorted by Relevance' do
  67 + self.params= {:selected_type => 'person',
  68 + :query => 'JOA BREU',
  69 + :per_page => 4}
  70 +
  71 + result = process_results
  72 + assert_equal ["Joana Abreu", "Joao Abreu"], result.map(&:name)
  73 + end
  74 +
  75 + should 'have sort in get_query return if has the option sort_by ' do
  76 + self.params= {}
  77 + assert get_query("", sort_by: :more_popular).keys.include?(:sort)
  78 + end
  79 +
  80 +end
... ...
plugins/elasticsearch/test/unit/event_test.rb 0 → 100644
... ... @@ -0,0 +1,37 @@
  1 +require "#{File.dirname(__FILE__)}/../test_helper"
  2 +require_relative '../../lib/nested_helper/profile'
  3 +
  4 +class EventTest < ActionController::TestCase
  5 +
  6 + include ElasticsearchTestHelper
  7 +
  8 + def indexed_models
  9 + [Event]
  10 + end
  11 +
  12 + should 'index searchable fields for Event model' do
  13 + Event::SEARCHABLE_FIELDS.each do |key, value|
  14 + assert_includes indexed_fields(Event), key
  15 + end
  16 + end
  17 +
  18 + should 'index control fields for Event model' do
  19 + Event::control_fields.each do |key, value|
  20 + assert_includes indexed_fields(Event), key
  21 + assert_equal indexed_fields(Event)[key][:type], value[:type] || 'string'
  22 + end
  23 + end
  24 +
  25 + should 'respond with should method to return public event' do
  26 + assert Event.respond_to? :should
  27 + end
  28 +
  29 + should 'respond with nested_filter' do
  30 + assert Event.respond_to? :nested_filter
  31 + end
  32 +
  33 + should 'have NestedProfile_filter in nested_filter' do
  34 + assert Event.nested_filter.include? NestedProfile.filter
  35 + end
  36 +
  37 +end
... ...
plugins/elasticsearch/test/unit/person_test.rb 0 → 100644
... ... @@ -0,0 +1,45 @@
  1 +require "#{File.dirname(__FILE__)}/../test_helper"
  2 +
  3 +class PersonTest < ActionController::TestCase
  4 +
  5 + include ElasticsearchTestHelper
  6 +
  7 + def indexed_models
  8 + [Person]
  9 + end
  10 +
  11 + should 'index searchable fields for Person model' do
  12 + Person::SEARCHABLE_FIELDS.each do |key, value|
  13 + assert_includes indexed_fields(Person), key
  14 + end
  15 + end
  16 +
  17 + should 'index control fields for Person model' do
  18 + Person::control_fields.each do |key, value|
  19 + assert_includes indexed_fields(Person), key
  20 + assert_equal indexed_fields(Person)[key][:type], value[:type] || 'string'
  21 + end
  22 + end
  23 +
  24 + should 'respond with should method to return public person' do
  25 + assert Person.respond_to? :should
  26 + end
  27 +
  28 + should 'respond with especific sort' do
  29 + assert Person.respond_to? :especific_sort
  30 + end
  31 +
  32 + should 'respond with get_sort_by to order especific sort' do
  33 + assert Person.respond_to? :get_sort_by
  34 + end
  35 +
  36 + should 'return hash to sort by more_active' do
  37 + more_active_hash = {:activities_count => {order: :desc}}
  38 + assert_equal more_active_hash, Person.get_sort_by(:more_active)
  39 + end
  40 +
  41 + should 'return hash to sort by more_popular' do
  42 + more_popular_hash = {:friends_count => {order: :desc}}
  43 + assert_equal more_popular_hash, Person.get_sort_by(:more_popular)
  44 + end
  45 +end
... ...
plugins/elasticsearch/test/unit/text_article_test.rb 0 → 100644
... ... @@ -0,0 +1,55 @@
  1 +require "#{File.dirname(__FILE__)}/../test_helper"
  2 +require_relative '../../lib/nested_helper/profile'
  3 +
  4 +class TextArticleTest < ActionController::TestCase
  5 +
  6 + include ElasticsearchTestHelper
  7 +
  8 + def indexed_models
  9 + [TextArticle]
  10 + end
  11 +
  12 + should 'index searchable fields for TextArticle model' do
  13 + TextArticle::SEARCHABLE_FIELDS.each do |key, value|
  14 + assert_includes indexed_fields(TextArticle), key
  15 + end
  16 + end
  17 +
  18 + should 'index control fields for TextArticle model' do
  19 + TextArticle::control_fields.each do |key, value|
  20 + assert_includes indexed_fields(TextArticle), key
  21 + assert_equal indexed_fields(TextArticle)[key][:type], value[:type] || 'string'
  22 + end
  23 + end
  24 +
  25 + should 'respond with should method to return public text_article' do
  26 + assert TextArticle.respond_to? :should
  27 + end
  28 +
  29 + should 'respond with especific sort' do
  30 + assert TextArticle.respond_to? :especific_sort
  31 + end
  32 +
  33 + should 'respond with get_sort_by to order especific sort' do
  34 + assert TextArticle.respond_to? :get_sort_by
  35 + end
  36 +
  37 + should 'return hash to sort by most commented' do
  38 + more_active_hash = {:comments_count => {order: :desc}}
  39 + assert_equal more_active_hash, TextArticle.get_sort_by(:more_comments)
  40 + end
  41 +
  42 + should 'return hash to sort by more popular' do
  43 + more_popular_hash = {:hits => {order: :desc}}
  44 + assert_equal more_popular_hash, TextArticle.get_sort_by(:more_popular)
  45 + end
  46 +
  47 + should 'respond with nested_filter' do
  48 + assert TextArticle.respond_to? :nested_filter
  49 + end
  50 +
  51 + should 'have NestedProfile_filter in nested_filter' do
  52 + assert TextArticle.nested_filter.include? NestedProfile.filter
  53 + end
  54 +
  55 +end
... ...
plugins/elasticsearch/test/unit/uploaded_file_test.rb 0 → 100644
... ... @@ -0,0 +1,36 @@
  1 +require "#{File.dirname(__FILE__)}/../test_helper"
  2 +
  3 +class UploadedFileTest < ActionController::TestCase
  4 +
  5 + include ElasticsearchTestHelper
  6 +
  7 + def indexed_models
  8 + [UploadedFile]
  9 + end
  10 +
  11 + should 'index searchable fields for UploadedFile model' do
  12 + UploadedFile::SEARCHABLE_FIELDS.each do |key, value|
  13 + assert_includes indexed_fields(UploadedFile), key
  14 + end
  15 + end
  16 +
  17 + should 'index control fields for UploadedFile model' do
  18 + UploadedFile::control_fields.each do |key, value|
  19 + assert_includes indexed_fields(UploadedFile), key
  20 + assert_equal indexed_fields(UploadedFile)[key][:type], value[:type].presence || 'string'
  21 + end
  22 + end
  23 +
  24 + should 'respond with should method to return public text_article' do
  25 + assert TextArticle.respond_to? :should
  26 + end
  27 +
  28 + should 'respond with nested_filter' do
  29 + assert TextArticle.respond_to? :nested_filter
  30 + end
  31 +
  32 + should 'have NestedProfile_filter in nested_filter' do
  33 + assert TextArticle.nested_filter.include? NestedProfile.filter
  34 + end
  35 +
  36 +end
... ...
plugins/elasticsearch/views/elasticsearch_plugin/_person_display.html.erb
... ... @@ -9,4 +9,6 @@
9 9 <p><%= person.description %></p>
10 10 </div>
11 11 </div>
  12 + <div style="clear: both">
  13 + </div>
12 14 </div>
... ...
plugins/elasticsearch/views/elasticsearch_plugin/search.html.erb
... ... @@ -26,18 +26,18 @@
26 26 <div class="sidebar">
27 27 <ul class="search-options">
28 28 <% for type,value in @searchable_types %>
29   - <li class="select-search-type <%= "active" if type == @selected_type %>">
30   - <%= link_to value[:label], "?selected_type=#{type}&query=#{@query}&filter=#{@selected_filter}"%>
31   - </li>
  29 + <li class="select-search-type <%= "active" if type == @selected_type %>">
  30 + <%= link_to value[:label], "?selected_type=#{type}&query=#{@query}"%>
  31 + </li>
32 32 <% end %>
33 33 </ul>
34 34 <div class="search-filter">
35 35 <h3 class="box-title"><%= _("Sort by") %></h3>
36 36 <ul>
37   - <% for type, value in @filter_types %>
38   - <li class="select-search-type <%= "active" if type == @selected_filter %>">
39   - <%= link_to value[:label], "?selected_type=#{@selected_type}&query=#{@query}&filter=#{type}" %>
40   - </li>
  37 + <% for type, value in @sort_types %>
  38 + <li class="select-search-type <%= "active" if type == @selected_sort %>">
  39 + <%= link_to value[:label], "?selected_type=#{@selected_type}&query=#{@query}&filter=#{type}" %>
  40 + </li>
41 41 <% end %>
42 42 </ul>
43 43 </div>
... ...