From aaa5d1b8fec04f9401bb3fff7459c3f253fdc908 Mon Sep 17 00:00:00 2001 From: Macartur Sousa Date: Wed, 29 Jun 2016 15:36:32 -0300 Subject: [PATCH] Refactored elasticsearch_plugin and elasticsearch_api --- plugins/elasticsearch/helpers/elasticsearch_helper.rb | 70 ++++++++++++++++++++++++++++++++++------------------------------------ plugins/elasticsearch/lib/elasticsearch_plugin/entities.rb | 14 ++++++++++++++ plugins/elasticsearch/test/unit/api/elasticsearch_plugin_api_test.rb | 3 +-- plugins/elasticsearch/test/unit/api/elasticsearch_plugin_entities_test.rb | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ plugins/elasticsearch/test/unit/helpers/elasticsearch_helper_test.rb | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ plugins/elasticsearch/test/unit/models/community_test.rb | 4 ---- plugins/elasticsearch/test/unit/models/event_test.rb | 4 ---- plugins/elasticsearch/test/unit/models/person_test.rb | 5 ----- plugins/elasticsearch/test/unit/models/text_article_test.rb | 4 ---- plugins/elasticsearch/test/unit/models/uploaded_file_test.rb | 4 ---- plugins/elasticsearch/views/elasticsearch_plugin/_person_display.html.erb | 1 - 11 files changed, 261 insertions(+), 60 deletions(-) create mode 100644 plugins/elasticsearch/test/unit/api/elasticsearch_plugin_entities_test.rb create mode 100644 plugins/elasticsearch/test/unit/helpers/elasticsearch_helper_test.rb diff --git a/plugins/elasticsearch/helpers/elasticsearch_helper.rb b/plugins/elasticsearch/helpers/elasticsearch_helper.rb index cfad0bf..df9039a 100644 --- a/plugins/elasticsearch/helpers/elasticsearch_helper.rb +++ b/plugins/elasticsearch/helpers/elasticsearch_helper.rb @@ -19,42 +19,16 @@ module ElasticsearchHelper } end - def fields_from_models klasses - fields = Set.new - klasses.each do |klass| - klass::SEARCHABLE_FIELDS.map do |key, value| - if value and value[:weight] - fields.add "#{key}^#{value[:weight]}" - else - fields.add "#{key}" - end - end - end - fields.to_a - end - - def get_sort_by sort_by - case sort_by - when "lexical" - { "name.raw" => {"order" => "asc" }} - when "recent" - { "created_at" => {"order" => "desc"}} - end - end - def process_results - selected_type = (params[:selected_type]|| :all).to_sym - if selected_type == :all - search_from_all_models - else - search_from_model selected_type - end + selected_type = (params[:selected_type].presence|| :all).to_sym + selected_type == :all ? search_from_all_models : search_from_model(selected_type) end + private + def search_from_all_models query = get_query params[:query], sort_by: get_sort_by(params[:selected_filter]) - models = searchable_models - Elasticsearch::Model.search(query, models, size: default_per_page(params[:per_page])).page(params[:page]).records + Elasticsearch::Model.search(query,searchable_models, size: default_per_page(params[:per_page])).page(params[:page]).records end def search_from_model model @@ -68,17 +42,28 @@ module ElasticsearchHelper end end - def default_per_page per_page + def default_per_page per_page=nil per_page ||= 10 end - private + def get_sort_by sort_by + case sort_by + when "lexical" + { "name.raw" => {"order" => "asc" }} + when "recent" + { "created_at" => {"order" => "desc"}} + end + end def searchable_models - ElasticsearchHelper::searchable_types.except(:all).keys.map { | model | model.to_s.classify.constantize } + begin + ElasticsearchHelper::searchable_types.except(:all).keys.map { | model | model.to_s.classify.constantize } + rescue + [] + end end - def query_method expression, fields + def query_method expression="", fields=[] query_exp = {} if expression.blank? query_exp = { @@ -107,8 +92,21 @@ module ElasticsearchHelper } query[:sort] = [sort_by,"_score"] if sort_by - query end + def fields_from_models klasses + fields = Set.new + klasses.each do |klass| + klass::SEARCHABLE_FIELDS.map do |key, value| + if value and value[:weight] + fields.add "#{key}^#{value[:weight]}" + else + fields.add "#{key}" + end + end + end + fields.to_a + end + end diff --git a/plugins/elasticsearch/lib/elasticsearch_plugin/entities.rb b/plugins/elasticsearch/lib/elasticsearch_plugin/entities.rb index 92936da..07e65e3 100644 --- a/plugins/elasticsearch/lib/elasticsearch_plugin/entities.rb +++ b/plugins/elasticsearch/lib/elasticsearch_plugin/entities.rb @@ -1,5 +1,6 @@ module Elasticsearch module Entities + class Result < Api::Entity root "results","result" @@ -7,11 +8,24 @@ module Elasticsearch options[:types].detect { |type| type.to_s.upcase if object.is_a? (type.to_s.classify.constantize) } end + expose :id expose :name expose :author, if: lambda { |object,options| object.respond_to? 'author'} do |object, options| object.author.present? ? object.author.name : "" end + + expose :description, if: lambda { |object,options| object.respond_to? 'description'} do |object, options| + object.description.present? ? object.description : "" + end + + expose :abstract, if: lambda { |object,options| object.respond_to? 'abstract'} do |object, options| + object.abstract.present? ? object.abstract : "" + end + + expose :created_at, :format_with => :timestamp + expose :updated_at, :format_with => :timestamp end + end end diff --git a/plugins/elasticsearch/test/unit/api/elasticsearch_plugin_api_test.rb b/plugins/elasticsearch/test/unit/api/elasticsearch_plugin_api_test.rb index beb0322..e149bd9 100644 --- a/plugins/elasticsearch/test/unit/api/elasticsearch_plugin_api_test.rb +++ b/plugins/elasticsearch/test/unit/api/elasticsearch_plugin_api_test.rb @@ -10,7 +10,7 @@ class ElasticsearchPluginApiTest < ActiveSupport::TestCase def create_instances 7.times.each {|index| create_user "person #{index}"} - 4.times.each {|index| fast_create Community, name: "community #{index}", created_at: Date.new } + 4.times.each {|index| fast_create Community, name: "community #{index}" } end should 'show all types avaliable in /search/types endpoint' do @@ -47,5 +47,4 @@ class ElasticsearchPluginApiTest < ActiveSupport::TestCase assert_equal 200, last_response.status assert_equal 4, json["results"].count end - end diff --git a/plugins/elasticsearch/test/unit/api/elasticsearch_plugin_entities_test.rb b/plugins/elasticsearch/test/unit/api/elasticsearch_plugin_entities_test.rb new file mode 100644 index 0000000..415b9f3 --- /dev/null +++ b/plugins/elasticsearch/test/unit/api/elasticsearch_plugin_entities_test.rb @@ -0,0 +1,122 @@ +require "#{File.dirname(__FILE__)}/../../test_helper" + +class ElasticsearchPluginEntitiesTest < ActiveSupport::TestCase + + include ElasticsearchTestHelper + + def indexed_models + [Person,TextArticle,UploadedFile,Community,Event] + end + + def create_instances + user = create_user "sample person" + + fast_create Community, name: "sample community", created_at: 10.days.ago,updated_at: 5.days.ago + fast_create UploadedFile, name: "sample uploadedfile", created_at: 3.days.ago, updated_at: 1.days.ago, author_id: user.person.id, abstract: "sample abstract" + fast_create Event, name: "sample event", created_at: 20.days.ago, updated_at: 5.days.ago, author_id: user.person.id, abstract: "sample abstract" + + fast_create RawHTMLArticle, name: "sample raw html article", created_at: 15.days.ago ,updated_at: 5.days.ago, author_id: user.person.id + fast_create TinyMceArticle, name: "sample tiny mce article", created_at: 5.days.ago, updated_at: 5.days.ago, author_id: user.person.id + end + + should 'show attributes from person' do + params = {:selected_type => "person" } + get "/api/v1/search?#{params.to_query}" + json= JSON.parse(last_response.body) + + expected_person = Person.find_by name: "sample person" + + assert_equal 200, last_response.status + assert_equal expected_person.id, json['results'][0]['id'] + assert_equal expected_person.name, json['results'][0]['name'] + assert_equal expected_person.type, json['results'][0]['type'] + assert_equal "", json['results'][0]['description'] + assert_equal expected_person.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][0]['created_at'] + assert_equal expected_person.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][0]['updated_at'] + end + + should 'show attributes from community' do + params = {:selected_type => "community" } + get "/api/v1/search?#{params.to_query}" + json= JSON.parse(last_response.body) + + expected_community = Community.find_by name: "sample community" + + assert_equal 200, last_response.status + assert_equal expected_community.id, json['results'][0]['id'] + assert_equal expected_community.name, json['results'][0]['name'] + assert_equal expected_community.type, json['results'][0]['type'] + assert_equal "", json['results'][0]['description'] + assert_equal expected_community.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][0]['created_at'] + assert_equal expected_community.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][0]['updated_at'] + end + + should 'show attributes from text_article' do + params = {:selected_type => "text_article" } + get "/api/v1/search?#{params.to_query}" + + json= JSON.parse(last_response.body) + + assert_equal 200, last_response.status + + expected_text_articles = TextArticle.all + + expected_text_articles.each_with_index {|object,index| + assert_equal object.id, json['results'][index]['id'] + assert_equal object.name, json['results'][index]['name'] + assert_equal "TextArticle", json['results'][index]['type'] + + expected_author = (object.author.nil?) ? "" : object.author.name + + assert_equal expected_author, json['results'][index]['author'] + assert_equal object.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['created_at'] + assert_equal object.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['updated_at'] + } + end + + should 'show attributes from uploaded_file' do + params = {:selected_type => "uploaded_file"} + get "/api/v1/search?#{params.to_query}" + + json= JSON.parse(last_response.body) + + assert_equal 200, last_response.status + + expected_uploaded_files = UploadedFile.all + expected_uploaded_files.each_with_index {|object,index| + assert_equal object.id, json['results'][index]['id'] + assert_equal object.name, json['results'][index]['name'] + assert_equal object.abstract, json['results'][index]['abstract'] + assert_equal "UploadedFile", json['results'][index]['type'] + + expected_author = (object.author.nil?) ? "" : object.author.name + assert_equal expected_author, json['results'][index]['author'] + + assert_equal object.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['created_at'] + assert_equal object.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['updated_at'] + } + end + + should 'show attributes from event' do + params = {:selected_type => "event"} + get "/api/v1/search?#{params.to_query}" + + json= JSON.parse(last_response.body) + + assert_equal 200, last_response.status + expected_events = Event.all + expected_events.each_with_index {|object,index| + assert_equal object.id, json['results'][index]['id'] + assert_equal object.name, json['results'][index]['name'] + assert_equal object.abstract, json['results'][index]['abstract'] + assert_equal "Event", json['results'][index]['type'] + + expected_author = (object.author.nil?) ? "" : object.author.name + assert_equal expected_author, json['results'][index]['author'] + + assert_equal object.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['created_at'] + assert_equal object.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['updated_at'] + } + end + +end diff --git a/plugins/elasticsearch/test/unit/helpers/elasticsearch_helper_test.rb b/plugins/elasticsearch/test/unit/helpers/elasticsearch_helper_test.rb new file mode 100644 index 0000000..5bbba0d --- /dev/null +++ b/plugins/elasticsearch/test/unit/helpers/elasticsearch_helper_test.rb @@ -0,0 +1,90 @@ +require "#{File.dirname(__FILE__)}/../../test_helper" +require_relative '../../../helpers/elasticsearch_helper.rb' + +class ElasticsearchHelperTest < ActiveSupport::TestCase + + include ElasticsearchTestHelper + include ElasticsearchHelper + + attr_accessor :params + + def indexed_models + [Person,TextArticle,UploadedFile,Community,Event] + end + + def create_instances + create_user "Jose Abreu" + create_user "Joao Abreu" + create_user "Joana Abreu" + create_user "Ana Abreu" + end + + should 'return default_per_page when nil is passed' do + assert_not_nil default_per_page nil + assert_equal 10, default_per_page(nil) + end + + should 'return default_per_page when per_page is passed' do + assert_equal 15, default_per_page(15) + end + + should 'have indexed_models in searchable_models' do + assert_equivalent indexed_models, searchable_models + end + + should 'return match_all if expression is blank' do + assert_includes query_method.keys, :match_all + end + + should 'return multi_match if expression is valid' do + + query= "my_query" + fields = ['name','login'] + result = query_method(query,fields) + + assert_includes result.keys, :multi_match + assert_includes result[:multi_match][:query], query + assert_equivalent result[:multi_match][:fields], fields + end + + + should 'return fields from models using weight' do + class StubClass + SEARCHABLE_FIELDS = {:name => {:weight => 10}, + :login => {:weight => 20}, + :description => {:weight => 2}} + end + + expected = ["name^10", "login^20", "description^2"] + assert_equivalent expected, fields_from_models([StubClass]) + end + + should 'search from model Person sorted by Alphabetic' do + self.params= {:selected_type => 'person', + :selected_filter => 'lexical', + :per_page => 4} + + result = process_results + assert_equal ["Ana Abreu","Joana Abreu","Joao Abreu","Jose Abreu"], result.map(&:name) + end + + should 'search from model Person sorted by More Recent' do + self.params= {:selected_type => 'person', + :selected_filter => 'more_recent', + :per_page => 4} + + result = process_results + assert_equal ["Jose Abreu","Joao Abreu","Joana Abreu","Ana Abreu"],result.map(&:name) + end + + should 'search from model Person sorted by Relevance' do + self.params= {:selected_type => 'person', + :selected_filter => 'more_recent', + :query => 'JOAO ABREU', + :per_page => 4} + + result = process_results + assert_equal ["Joao Abreu","Jose Abreu","Joana Abreu","Ana Abreu"],result.map(&:name) + end + +end diff --git a/plugins/elasticsearch/test/unit/models/community_test.rb b/plugins/elasticsearch/test/unit/models/community_test.rb index 74cac82..3d3036d 100644 --- a/plugins/elasticsearch/test/unit/models/community_test.rb +++ b/plugins/elasticsearch/test/unit/models/community_test.rb @@ -8,10 +8,6 @@ class CommunityTest < ActionController::TestCase [Community] end - def setup - super - end - should 'index searchable fields for Community model' do Community::SEARCHABLE_FIELDS.each do |key, value| assert_includes indexed_fields(Community), key diff --git a/plugins/elasticsearch/test/unit/models/event_test.rb b/plugins/elasticsearch/test/unit/models/event_test.rb index b857896..8b044f5 100644 --- a/plugins/elasticsearch/test/unit/models/event_test.rb +++ b/plugins/elasticsearch/test/unit/models/event_test.rb @@ -8,10 +8,6 @@ class EventTest < ActionController::TestCase [Event] end - def setup - super - end - should 'index searchable fields for Event model' do Event::SEARCHABLE_FIELDS.each do |key, value| assert_includes indexed_fields(Event), key diff --git a/plugins/elasticsearch/test/unit/models/person_test.rb b/plugins/elasticsearch/test/unit/models/person_test.rb index a8cafc5..0012343 100644 --- a/plugins/elasticsearch/test/unit/models/person_test.rb +++ b/plugins/elasticsearch/test/unit/models/person_test.rb @@ -8,10 +8,6 @@ class PersonTest < ActionController::TestCase [Person] end - def setup - super - end - should 'index searchable fields for Person model' do Person::SEARCHABLE_FIELDS.each do |key, value| assert_includes indexed_fields(Person), key @@ -24,5 +20,4 @@ class PersonTest < ActionController::TestCase assert_includes indexed_fields(Person)[key][:type], value[:type] || 'string' end end - end diff --git a/plugins/elasticsearch/test/unit/models/text_article_test.rb b/plugins/elasticsearch/test/unit/models/text_article_test.rb index 937b77f..1455d8f 100644 --- a/plugins/elasticsearch/test/unit/models/text_article_test.rb +++ b/plugins/elasticsearch/test/unit/models/text_article_test.rb @@ -8,10 +8,6 @@ class TextArticleTest < ActionController::TestCase [TextArticle] end - def setup - super - end - should 'index searchable fields for TextArticle model' do TextArticle::SEARCHABLE_FIELDS.each do |key, value| assert_includes indexed_fields(TextArticle), key diff --git a/plugins/elasticsearch/test/unit/models/uploaded_file_test.rb b/plugins/elasticsearch/test/unit/models/uploaded_file_test.rb index 04bd842..0146047 100644 --- a/plugins/elasticsearch/test/unit/models/uploaded_file_test.rb +++ b/plugins/elasticsearch/test/unit/models/uploaded_file_test.rb @@ -8,10 +8,6 @@ class UploadedFileTest < ActionController::TestCase [UploadedFile] end - def setup - super - end - should 'index searchable fields for UploadedFile model' do UploadedFile::SEARCHABLE_FIELDS.each do |key, value| assert_includes indexed_fields(UploadedFile), key diff --git a/plugins/elasticsearch/views/elasticsearch_plugin/_person_display.html.erb b/plugins/elasticsearch/views/elasticsearch_plugin/_person_display.html.erb index 01b1d19..08ac688 100644 --- a/plugins/elasticsearch/views/elasticsearch_plugin/_person_display.html.erb +++ b/plugins/elasticsearch/views/elasticsearch_plugin/_person_display.html.erb @@ -7,7 +7,6 @@

<%= link_to person.name, person.url %>

<%= person.description %>

- <%= person.created_at %>
-- libgit2 0.21.2