Commit 7aba5bb2073dacf28c17db4c3886b2f349fed6e1

Authored by Daniel Damasceno
2 parents ef30cecc 444ed768

Merge branch 'elasticsearch_filter' into 'elasticsearch'

Elasticsearch filter

See merge request !17
Showing 36 changed files with 1158 additions and 622 deletions   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_indexed_model.rb
... ... @@ -1,53 +0,0 @@
1   -module ElasticsearchIndexedModel
2   -
3   - def self.included base
4   - base.send :include, Elasticsearch::Model
5   - base.send :include, Elasticsearch::Model::Callbacks
6   -
7   - base.send :index_name, "#{Rails.env}_#{base.index_name}"
8   - base.extend ClassMethods
9   - base.class_eval do
10   - settings index: { number_of_shards: 1 } do
11   - mappings dynamic: 'false' do
12   - base.indexed_fields.each do |field, value|
13   - value = {} if value.nil?
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
20   - print '.'
21   - end
22   - end
23   -
24   - base.__elasticsearch__.client.indices.delete \
25   - index: base.index_name rescue nil
26   - base.__elasticsearch__.client.indices.create \
27   - index: base.index_name,
28   - body: {
29   - settings: base.settings.to_hash,
30   - mappings: base.mappings.to_hash
31   - }
32   - end
33   - end
34   - base.send :import
35   - end
36   -
37   - module ClassMethods
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
49   - end
50   -
51   - end
52   -
53   -end
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</