Commit 81f17ceabb1befb1f8c8e22d3dca69e3e292f479
1 parent
fec92470
Exists in
theme-brasil-digital-from-staging
and in
9 other branches
Implemented API-Search
Showing
4 changed files
with
113 additions
and
0 deletions
Show diff stats
lib/noosfero/api/api.rb
lib/noosfero/api/helpers.rb
| @@ -10,6 +10,7 @@ require 'grape' | @@ -10,6 +10,7 @@ require 'grape' | ||
| 10 | include SanitizeParams | 10 | include SanitizeParams |
| 11 | include Noosfero::Plugin::HotSpot | 11 | include Noosfero::Plugin::HotSpot |
| 12 | include ForgotPasswordHelper | 12 | include ForgotPasswordHelper |
| 13 | + include SearchTermHelper | ||
| 13 | 14 | ||
| 14 | def set_locale | 15 | def set_locale |
| 15 | I18n.locale = (params[:lang] || request.env['HTTP_ACCEPT_LANGUAGE'] || 'en') | 16 | I18n.locale = (params[:lang] || request.env['HTTP_ACCEPT_LANGUAGE'] || 'en') |
| @@ -39,6 +40,24 @@ require 'grape' | @@ -39,6 +40,24 @@ require 'grape' | ||
| 39 | @environment | 40 | @environment |
| 40 | end | 41 | end |
| 41 | 42 | ||
| 43 | + #################################################################### | ||
| 44 | + #### SEARCH | ||
| 45 | + #################################################################### | ||
| 46 | + def find_by_contents(asset, context, scope, query, paginate_options={:page => 1}, options={}) | ||
| 47 | + scope = scope.with_templates(options[:template_id]) unless options[:template_id].blank? | ||
| 48 | + search = plugins.dispatch_first(:find_by_contents, asset, scope, query, paginate_options, options) | ||
| 49 | + register_search_term(query, scope.count, search[:results].count, context, asset) | ||
| 50 | + search | ||
| 51 | + end | ||
| 52 | + def paginate_options(page = params[:page]) | ||
| 53 | + page = 1 if multiple_search?(@searches) || params[:display] == 'map' | ||
| 54 | + { :per_page => limit, :page => page } | ||
| 55 | + end | ||
| 56 | + def multiple_search?(searches=nil) | ||
| 57 | + ['index', 'category_index'].include?(params[:action]) || (searches && searches.size > 1) | ||
| 58 | + end | ||
| 59 | + #################################################################### | ||
| 60 | + | ||
| 42 | def logger | 61 | def logger |
| 43 | logger = Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV'] || 'production'}_api.log")) | 62 | logger = Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV'] || 'production'}_api.log")) |
| 44 | logger.formatter = GrapeLogging::Formatters::Default.new | 63 | logger.formatter = GrapeLogging::Formatters::Default.new |
| @@ -0,0 +1,33 @@ | @@ -0,0 +1,33 @@ | ||
| 1 | +module Noosfero | ||
| 2 | + module API | ||
| 3 | + module V1 | ||
| 4 | + class Search < Grape::API | ||
| 5 | + | ||
| 6 | + resource :search do | ||
| 7 | + resource :article do | ||
| 8 | + get do | ||
| 9 | + # Security checks | ||
| 10 | + sanitize_params_hash(params) | ||
| 11 | + # APIHelpers | ||
| 12 | + asset = :articles | ||
| 13 | + context = environment | ||
| 14 | + scope = environment.articles.public | ||
| 15 | + | ||
| 16 | + scope = scope.where(:type => params[:type]) if params[:type] && !(params[:type] == 'Article') | ||
| 17 | + | ||
| 18 | + category = params[:category] || "" | ||
| 19 | + query = params[:query] || "" | ||
| 20 | + order = "more_recent" | ||
| 21 | + | ||
| 22 | + options = {:filter => order, :template_id => params[:template_id], :category => category} | ||
| 23 | + | ||
| 24 | + articles = find_by_contents(asset, context, scope, query, paginate_options, options) | ||
| 25 | + present articles | ||
| 26 | + end | ||
| 27 | + end | ||
| 28 | + end | ||
| 29 | + | ||
| 30 | + end | ||
| 31 | + end | ||
| 32 | + end | ||
| 33 | +end |
| @@ -0,0 +1,60 @@ | @@ -0,0 +1,60 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/test_helper' | ||
| 2 | + | ||
| 3 | +class SearchTest < ActiveSupport::TestCase | ||
| 4 | + | ||
| 5 | + def create_article_with_optional_category(name, profile, category = nil) | ||
| 6 | + fast_create(Article, {:name => name, :profile_id => profile.id }, :search => true, :category => category) | ||
| 7 | + end | ||
| 8 | + | ||
| 9 | + should 'not list unpublished articles' do | ||
| 10 | + person = fast_create(Person) | ||
| 11 | + article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false) | ||
| 12 | + assert !article.published? | ||
| 13 | + get "/api/v1/search/article" | ||
| 14 | + json = JSON.parse(last_response.body) | ||
| 15 | + assert_empty json['results'] | ||
| 16 | + end | ||
| 17 | + | ||
| 18 | + should 'list articles' do | ||
| 19 | + person = fast_create(Person) | ||
| 20 | + art = create_article_with_optional_category('an article to be found', person) | ||
| 21 | + get "/api/v1/search/article" | ||
| 22 | + json = JSON.parse(last_response.body) | ||
| 23 | + assert_not_empty json['results'] | ||
| 24 | + end | ||
| 25 | + | ||
| 26 | + should 'invalid search string articles' do | ||
| 27 | + person = fast_create(Person) | ||
| 28 | + art = create_article_with_optional_category('an article to be found', person) | ||
| 29 | + get "/api/v1/search/article?query=test" | ||
| 30 | + json = JSON.parse(last_response.body) | ||
| 31 | + assert_empty json['results'] | ||
| 32 | + end | ||
| 33 | + | ||
| 34 | + should 'do not list articles of wrong type' do | ||
| 35 | + person = fast_create(Person) | ||
| 36 | + art = create_article_with_optional_category('an article to be found', person) | ||
| 37 | + get "/api/v1/search/article?type=TinyMceArticle" | ||
| 38 | + json = JSON.parse(last_response.body) | ||
| 39 | + assert_empty json['results'] | ||
| 40 | + end | ||
| 41 | + | ||
| 42 | + should 'list articles of one type' do | ||
| 43 | + person = fast_create(Person) | ||
| 44 | + art = create_article_with_optional_category('an article to be found', person) | ||
| 45 | + article = fast_create(TinyMceArticle, :profile_id => person.id, :name => "Some thing", :published => true) | ||
| 46 | + get "/api/v1/search/article?type=TinyMceArticle" | ||
| 47 | + json = JSON.parse(last_response.body) | ||
| 48 | + assert_equal 1, json['results'].size | ||
| 49 | + end | ||
| 50 | + | ||
| 51 | + should 'list articles of one type and query string' do | ||
| 52 | + person = fast_create(Person) | ||
| 53 | + art = create_article_with_optional_category('an article to be found', person) | ||
| 54 | + art1 = create_article_with_optional_category('article for query', person) | ||
| 55 | + article = fast_create(TinyMceArticle, :profile_id => person.id, :name => "Some thing", :published => true) | ||
| 56 | + get "/api/v1/search/article?type=TinyMceArticle&query=thing" | ||
| 57 | + json = JSON.parse(last_response.body) | ||
| 58 | + assert_equal 1, json['results'].size | ||
| 59 | + end | ||
| 60 | +end | ||
| 0 | \ No newline at end of file | 61 | \ No newline at end of file |