Commit 81f17ceabb1befb1f8c8e22d3dca69e3e292f479
1 parent
fec92470
Exists in
staging
and in
4 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 |