diff --git a/lib/noosfero/api/api.rb b/lib/noosfero/api/api.rb index 150ff6a..92ad47b 100644 --- a/lib/noosfero/api/api.rb +++ b/lib/noosfero/api/api.rb @@ -51,6 +51,7 @@ module Noosfero mount V1::Tasks mount V1::Tags mount V1::Environments + mount V1::Search mount Session diff --git a/lib/noosfero/api/helpers.rb b/lib/noosfero/api/helpers.rb index 63c6f72..3e1cc33 100644 --- a/lib/noosfero/api/helpers.rb +++ b/lib/noosfero/api/helpers.rb @@ -10,6 +10,7 @@ require 'grape' include SanitizeParams include Noosfero::Plugin::HotSpot include ForgotPasswordHelper + include SearchTermHelper def set_locale I18n.locale = (params[:lang] || request.env['HTTP_ACCEPT_LANGUAGE'] || 'en') @@ -39,6 +40,24 @@ require 'grape' @environment end + #################################################################### + #### SEARCH + #################################################################### + def find_by_contents(asset, context, scope, query, paginate_options={:page => 1}, options={}) + scope = scope.with_templates(options[:template_id]) unless options[:template_id].blank? + search = plugins.dispatch_first(:find_by_contents, asset, scope, query, paginate_options, options) + register_search_term(query, scope.count, search[:results].count, context, asset) + search + end + def paginate_options(page = params[:page]) + page = 1 if multiple_search?(@searches) || params[:display] == 'map' + { :per_page => limit, :page => page } + end + def multiple_search?(searches=nil) + ['index', 'category_index'].include?(params[:action]) || (searches && searches.size > 1) + end + #################################################################### + def logger logger = Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV'] || 'production'}_api.log")) logger.formatter = GrapeLogging::Formatters::Default.new diff --git a/lib/noosfero/api/v1/search.rb b/lib/noosfero/api/v1/search.rb new file mode 100644 index 0000000..0f80863 --- /dev/null +++ b/lib/noosfero/api/v1/search.rb @@ -0,0 +1,33 @@ +module Noosfero + module API + module V1 + class Search < Grape::API + + resource :search do + resource :article do + get do + # Security checks + sanitize_params_hash(params) + # APIHelpers + asset = :articles + context = environment + scope = environment.articles.public + + scope = scope.where(:type => params[:type]) if params[:type] && !(params[:type] == 'Article') + + category = params[:category] || "" + query = params[:query] || "" + order = "more_recent" + + options = {:filter => order, :template_id => params[:template_id], :category => category} + + articles = find_by_contents(asset, context, scope, query, paginate_options, options) + present articles + end + end + end + + end + end + end +end diff --git a/test/unit/api/search_test.rb b/test/unit/api/search_test.rb new file mode 100644 index 0000000..c10281d --- /dev/null +++ b/test/unit/api/search_test.rb @@ -0,0 +1,60 @@ +require File.dirname(__FILE__) + '/test_helper' + +class SearchTest < ActiveSupport::TestCase + + def create_article_with_optional_category(name, profile, category = nil) + fast_create(Article, {:name => name, :profile_id => profile.id }, :search => true, :category => category) + end + + should 'not list unpublished articles' do + person = fast_create(Person) + article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false) + assert !article.published? + get "/api/v1/search/article" + json = JSON.parse(last_response.body) + assert_empty json['results'] + end + + should 'list articles' do + person = fast_create(Person) + art = create_article_with_optional_category('an article to be found', person) + get "/api/v1/search/article" + json = JSON.parse(last_response.body) + assert_not_empty json['results'] + end + + should 'invalid search string articles' do + person = fast_create(Person) + art = create_article_with_optional_category('an article to be found', person) + get "/api/v1/search/article?query=test" + json = JSON.parse(last_response.body) + assert_empty json['results'] + end + + should 'do not list articles of wrong type' do + person = fast_create(Person) + art = create_article_with_optional_category('an article to be found', person) + get "/api/v1/search/article?type=TinyMceArticle" + json = JSON.parse(last_response.body) + assert_empty json['results'] + end + + should 'list articles of one type' do + person = fast_create(Person) + art = create_article_with_optional_category('an article to be found', person) + article = fast_create(TinyMceArticle, :profile_id => person.id, :name => "Some thing", :published => true) + get "/api/v1/search/article?type=TinyMceArticle" + json = JSON.parse(last_response.body) + assert_equal 1, json['results'].size + end + + should 'list articles of one type and query string' do + person = fast_create(Person) + art = create_article_with_optional_category('an article to be found', person) + art1 = create_article_with_optional_category('article for query', person) + article = fast_create(TinyMceArticle, :profile_id => person.id, :name => "Some thing", :published => true) + get "/api/v1/search/article?type=TinyMceArticle&query=thing" + json = JSON.parse(last_response.body) + assert_equal 1, json['results'].size + end +end \ No newline at end of file -- libgit2 0.21.2