Commit 56f3aee23b7ebc5092f0d48b8dbddffb1785bba3
1 parent
92fbfd94
Exists in
theme-brasil-digital-from-staging
and in
4 other branches
api: better support to choose returned fields
Showing
8 changed files
with
65 additions
and
37 deletions
Show diff stats
lib/noosfero/api/entities.rb
@@ -96,14 +96,14 @@ module Noosfero | @@ -96,14 +96,14 @@ module Noosfero | ||
96 | class Person < Profile | 96 | class Person < Profile |
97 | root 'people', 'person' | 97 | root 'people', 'person' |
98 | expose :user, :using => UserBasic, documentation: {type: 'User', desc: 'The user data of a person' } | 98 | expose :user, :using => UserBasic, documentation: {type: 'User', desc: 'The user data of a person' } |
99 | - expose :vote_count, if: lambda { |object, options| options[:fields].present? ? options[:fields].include?('vote_count') : false} | ||
100 | - expose :comments_count, if: lambda { |object, options| options[:fields].present? ? options[:fields].include?('comments_count') : false} do |person, options| | 99 | + expose :vote_count |
100 | + expose :comments_count do |person, options| | ||
101 | person.comments.count | 101 | person.comments.count |
102 | end | 102 | end |
103 | - expose :following_articles_count, if: lambda { |object, options| options[:fields].present? ? options[:fields].include?('following_articles_count') : false} do |person, options| | 103 | + expose :following_articles_count do |person, options| |
104 | person.following_articles.count | 104 | person.following_articles.count |
105 | end | 105 | end |
106 | - expose :articles_count, if: lambda { |object, options| options[:fields].present? ? options[:fields].include?('articles_count') : false} do |person, options| | 106 | + expose :articles_count do |person, options| |
107 | person.articles.count | 107 | person.articles.count |
108 | end | 108 | end |
109 | 109 |
lib/noosfero/api/entity.rb
@@ -22,18 +22,4 @@ class Noosfero::API::Entity < Grape::Entity | @@ -22,18 +22,4 @@ class Noosfero::API::Entity < Grape::Entity | ||
22 | end | 22 | end |
23 | end | 23 | end |
24 | 24 | ||
25 | - def self.fields_condition(fields) | ||
26 | - lambda do |object, options| | ||
27 | - return true if options[:fields].blank? | ||
28 | - fields.map { |field| options[:fields].include?(field.to_s)}.grep(true).present? | ||
29 | - end | ||
30 | - end | ||
31 | - | ||
32 | - def self.expose(*args, &block) | ||
33 | - hash = args.last.is_a?(Hash) ? args.pop : {} | ||
34 | - hash.merge!({:if => fields_condition(args)}) if hash[:if].blank? | ||
35 | - args << hash | ||
36 | - super | ||
37 | - end | ||
38 | - | ||
39 | end | 25 | end |
lib/noosfero/api/helpers.rb
@@ -39,6 +39,20 @@ require_relative '../../find_by_contents' | @@ -39,6 +39,20 @@ require_relative '../../find_by_contents' | ||
39 | @environment | 39 | @environment |
40 | end | 40 | end |
41 | 41 | ||
42 | + def present_partial(model, options) | ||
43 | + if(params[:fields].present?) | ||
44 | + begin | ||
45 | + fields = JSON.parse(params[:fields]) | ||
46 | + if fields.present? | ||
47 | + options.merge!(fields.symbolize_keys.slice(:only, :except)) | ||
48 | + end | ||
49 | + rescue | ||
50 | + options[:only] = Array.wrap(params[:fields]) | ||
51 | + end | ||
52 | + end | ||
53 | + present model, options | ||
54 | + end | ||
55 | + | ||
42 | include FindByContents | 56 | include FindByContents |
43 | 57 | ||
44 | #################################################################### | 58 | #################################################################### |
@@ -99,12 +113,12 @@ require_relative '../../find_by_contents' | @@ -99,12 +113,12 @@ require_relative '../../find_by_contents' | ||
99 | if !article.save | 113 | if !article.save |
100 | render_api_errors!(article.errors.full_messages) | 114 | render_api_errors!(article.errors.full_messages) |
101 | end | 115 | end |
102 | - present article, :with => Entities::Article, :fields => params[:fields] | 116 | + present_partial article, :with => Entities::Article |
103 | end | 117 | end |
104 | 118 | ||
105 | def present_article(asset) | 119 | def present_article(asset) |
106 | article = find_article(asset.articles, params[:id]) | 120 | article = find_article(asset.articles, params[:id]) |
107 | - present article, :with => Entities::Article, :fields => params[:fields] | 121 | + present_partial article, :with => Entities::Article |
108 | end | 122 | end |
109 | 123 | ||
110 | def present_articles_for_asset(asset, method = 'articles') | 124 | def present_articles_for_asset(asset, method = 'articles') |
@@ -113,12 +127,12 @@ require_relative '../../find_by_contents' | @@ -113,12 +127,12 @@ require_relative '../../find_by_contents' | ||
113 | end | 127 | end |
114 | 128 | ||
115 | def present_articles(articles) | 129 | def present_articles(articles) |
116 | - present articles, :with => Entities::Article, :fields => params[:fields] | 130 | + present_partial articles, :with => Entities::Article |
117 | end | 131 | end |
118 | 132 | ||
119 | def present_articles_paginated(articles, per_page=nil) | 133 | def present_articles_paginated(articles, per_page=nil) |
120 | articles = paginate(articles) | 134 | articles = paginate(articles) |
121 | - present articles, :with => Entities::Article, :fields => params[:fields] | 135 | + present_partial articles, :with => Entities::Article |
122 | end | 136 | end |
123 | 137 | ||
124 | def find_articles(asset, method = 'articles') | 138 | def find_articles(asset, method = 'articles') |
@@ -148,19 +162,19 @@ require_relative '../../find_by_contents' | @@ -148,19 +162,19 @@ require_relative '../../find_by_contents' | ||
148 | if !task.save | 162 | if !task.save |
149 | render_api_errors!(task.errors.full_messages) | 163 | render_api_errors!(task.errors.full_messages) |
150 | end | 164 | end |
151 | - present task, :with => Entities::Task, :fields => params[:fields] | 165 | + present_partial task, :with => Entities::Task |
152 | end | 166 | end |
153 | 167 | ||
154 | def present_task(asset) | 168 | def present_task(asset) |
155 | task = find_task(asset, params[:id]) | 169 | task = find_task(asset, params[:id]) |
156 | - present task, :with => Entities::Task, :fields => params[:fields] | 170 | + present_partial task, :with => Entities::Task |
157 | end | 171 | end |
158 | 172 | ||
159 | def present_tasks(asset) | 173 | def present_tasks(asset) |
160 | tasks = select_filtered_collection_of(asset, 'tasks', params) | 174 | tasks = select_filtered_collection_of(asset, 'tasks', params) |
161 | tasks = tasks.select {|t| current_person.has_permission?(t.permission, asset)} | 175 | tasks = tasks.select {|t| current_person.has_permission?(t.permission, asset)} |
162 | return forbidden! if tasks.empty? && !current_person.has_permission?(:perform_task, asset) | 176 | return forbidden! if tasks.empty? && !current_person.has_permission?(:perform_task, asset) |
163 | - present tasks, :with => Entities::Task, :fields => params[:fields] | 177 | + present_partial tasks, :with => Entities::Task |
164 | end | 178 | end |
165 | 179 | ||
166 | def make_conditions_with_parameter(params = {}) | 180 | def make_conditions_with_parameter(params = {}) |
lib/noosfero/api/v1/articles.rb
@@ -58,7 +58,7 @@ module Noosfero | @@ -58,7 +58,7 @@ module Noosfero | ||
58 | article = environment.articles.find(params[:id]) | 58 | article = environment.articles.find(params[:id]) |
59 | return forbidden! unless article.allow_edit?(current_person) | 59 | return forbidden! unless article.allow_edit?(current_person) |
60 | article.update_attributes!(params[:article]) | 60 | article.update_attributes!(params[:article]) |
61 | - present article, :with => Entities::Article, :fields => params[:fields] | 61 | + present_partial article, :with => Entities::Article |
62 | end | 62 | end |
63 | 63 | ||
64 | desc 'Report a abuse and/or violent content in a article by id' do | 64 | desc 'Report a abuse and/or violent content in a article by id' do |
@@ -190,7 +190,7 @@ module Noosfero | @@ -190,7 +190,7 @@ module Noosfero | ||
190 | article = find_article(environment.articles, params[:id]) | 190 | article = find_article(environment.articles, params[:id]) |
191 | child = find_article(article.children, params[:child_id]) | 191 | child = find_article(article.children, params[:child_id]) |
192 | child.hit | 192 | child.hit |
193 | - present child, :with => Entities::Article, :fields => params[:fields] | 193 | + present_partial child, :with => Entities::Article |
194 | end | 194 | end |
195 | 195 | ||
196 | desc 'Suggest a article to another profile' do | 196 | desc 'Suggest a article to another profile' do |
@@ -213,7 +213,7 @@ module Noosfero | @@ -213,7 +213,7 @@ module Noosfero | ||
213 | unless suggest_article.save | 213 | unless suggest_article.save |
214 | render_api_errors!(suggest_article.article_object.errors.full_messages) | 214 | render_api_errors!(suggest_article.article_object.errors.full_messages) |
215 | end | 215 | end |
216 | - present suggest_article, :with => Entities::Task, :fields => params[:fields] | 216 | + present_partial suggest_article, :with => Entities::Task |
217 | end | 217 | end |
218 | 218 | ||
219 | # Example Request: | 219 | # Example Request: |
@@ -244,7 +244,7 @@ module Noosfero | @@ -244,7 +244,7 @@ module Noosfero | ||
244 | if !article.save | 244 | if !article.save |
245 | render_api_errors!(article.errors.full_messages) | 245 | render_api_errors!(article.errors.full_messages) |
246 | end | 246 | end |
247 | - present article, :with => Entities::Article, :fields => params[:fields] | 247 | + present_partial article, :with => Entities::Article |
248 | end | 248 | end |
249 | 249 | ||
250 | end | 250 | end |
@@ -271,7 +271,7 @@ module Noosfero | @@ -271,7 +271,7 @@ module Noosfero | ||
271 | article = forbidden! | 271 | article = forbidden! |
272 | end | 272 | end |
273 | 273 | ||
274 | - present article, :with => Entities::Article, :fields => params[:fields] | 274 | + present_partial article, :with => Entities::Article |
275 | else | 275 | else |
276 | 276 | ||
277 | present_articles_for_asset(profile) | 277 | present_articles_for_asset(profile) |
lib/noosfero/api/v1/people.rb
@@ -33,12 +33,12 @@ module Noosfero | @@ -33,12 +33,12 @@ module Noosfero | ||
33 | get do | 33 | get do |
34 | people = select_filtered_collection_of(environment, 'people', params) | 34 | people = select_filtered_collection_of(environment, 'people', params) |
35 | people = people.visible_for_person(current_person) | 35 | people = people.visible_for_person(current_person) |
36 | - present people, :with => Entities::Person, :fields => params[:fields] | 36 | + present_partial people, :with => Entities::Person |
37 | end | 37 | end |
38 | 38 | ||
39 | desc "Return the logged user information" | 39 | desc "Return the logged user information" |
40 | get "/me" do | 40 | get "/me" do |
41 | - present current_person, :with => Entities::Person, :fields => params[:fields] | 41 | + present_partial current_person, :with => Entities::Person |
42 | end | 42 | end |
43 | 43 | ||
44 | desc "Return the person information" | 44 | desc "Return the person information" |
lib/noosfero/api/v1/tasks.rb
@@ -20,13 +20,13 @@ module Noosfero | @@ -20,13 +20,13 @@ module Noosfero | ||
20 | get do | 20 | get do |
21 | tasks = select_filtered_collection_of(environment, 'tasks', params) | 21 | tasks = select_filtered_collection_of(environment, 'tasks', params) |
22 | tasks = tasks.select {|t| current_person.has_permission?(t.permission, environment)} | 22 | tasks = tasks.select {|t| current_person.has_permission?(t.permission, environment)} |
23 | - present tasks, :with => Entities::Task, :fields => params[:fields] | 23 | + present_partial tasks, :with => Entities::Task |
24 | end | 24 | end |
25 | 25 | ||
26 | desc "Return the task id" | 26 | desc "Return the task id" |
27 | get ':id' do | 27 | get ':id' do |
28 | task = find_task(environment, params[:id]) | 28 | task = find_task(environment, params[:id]) |
29 | - present task, :with => Entities::Task, :fields => params[:fields] | 29 | + present_partial task, :with => Entities::Task |
30 | end | 30 | end |
31 | end | 31 | end |
32 | 32 |
test/unit/api/helpers_test.rb
@@ -214,6 +214,26 @@ class APIHelpersTest < ActiveSupport::TestCase | @@ -214,6 +214,26 @@ class APIHelpersTest < ActiveSupport::TestCase | ||
214 | #assert_equals [article1, article2], present_articles | 214 | #assert_equals [article1, article2], present_articles |
215 | end | 215 | end |
216 | 216 | ||
217 | + should 'not touch in options when no fields parameter is passed' do | ||
218 | + model = mock | ||
219 | + expects(:present).with(model, {}) | ||
220 | + present_partial(model, {}) | ||
221 | + end | ||
222 | + | ||
223 | + should 'fallback to array when fields parameter is not a json when calling present partial' do | ||
224 | + model = mock | ||
225 | + params[:fields] = 'name' | ||
226 | + expects(:present).with(model, {:only => ['name']}) | ||
227 | + present_partial(model, {}) | ||
228 | + end | ||
229 | + | ||
230 | + should 'accept json as fields parameter when calling present partial' do | ||
231 | + model = mock | ||
232 | + params[:fields] = {only: [:name, {user: [:login]}]}.to_json | ||
233 | + expects(:present).with(model, {:only => ['name', {'user' => ['login']}]}) | ||
234 | + present_partial(model, {}) | ||
235 | + end | ||
236 | + | ||
217 | ###### Captcha tests ###### | 237 | ###### Captcha tests ###### |
218 | 238 | ||
219 | should 'do not test captcha when there are no settings' do | 239 | should 'do not test captcha when there are no settings' do |
test/unit/api/people_test.rb
@@ -54,6 +54,14 @@ class PeopleTest < ActiveSupport::TestCase | @@ -54,6 +54,14 @@ class PeopleTest < ActiveSupport::TestCase | ||
54 | assert_equal expected, json | 54 | assert_equal expected, json |
55 | end | 55 | end |
56 | 56 | ||
57 | + should 'people endpoint filter by fields parameter with hierarchy' do | ||
58 | + fields = {only: [:name, {user: [:login]}]}.to_json | ||
59 | + get "/api/v1/people?#{params.to_query}&fields=#{fields}" | ||
60 | + json = JSON.parse(last_response.body) | ||
61 | + expected = {'people' => [{'name' => person.name, 'user' => {'login' => 'testapi'}}]} | ||
62 | + assert_equal expected, json | ||
63 | + end | ||
64 | + | ||
57 | 65 | ||
58 | should 'get logged person' do | 66 | should 'get logged person' do |
59 | get "/api/v1/people/me?#{params.to_query}" | 67 | get "/api/v1/people/me?#{params.to_query}" |
@@ -184,13 +192,13 @@ class PeopleTest < ActiveSupport::TestCase | @@ -184,13 +192,13 @@ class PeopleTest < ActiveSupport::TestCase | ||
184 | 192 | ||
185 | PERSON_ATTRIBUTES.map do |attribute| | 193 | PERSON_ATTRIBUTES.map do |attribute| |
186 | 194 | ||
187 | - define_method "test_should_not_expose_#{attribute}_attribute_in_person_enpoint_if_field_parameter_is_not_passed" do | ||
188 | - get "/api/v1/people/me?#{params.to_query}" | 195 | + define_method "test_should_not_expose_#{attribute}_attribute_in_person_enpoint_if_field_parameter_does_not_contain_the_attribute" do |
196 | + get "/api/v1/people/me?#{params.to_query}&fields=name" | ||
189 | json = JSON.parse(last_response.body) | 197 | json = JSON.parse(last_response.body) |
190 | assert_nil json['person'][attribute] | 198 | assert_nil json['person'][attribute] |
191 | end | 199 | end |
192 | 200 | ||
193 | - define_method "test_should_expose_#{attribute}_attribute_in_person_enpoints_only_if_field_parameter_is_passed" do | 201 | + define_method "test_should_expose_#{attribute}_attribute_in_person_enpoints_if_field_parameter_is_passed" do |
194 | get "/api/v1/people/me?#{params.to_query}&fields=#{attribute}" | 202 | get "/api/v1/people/me?#{params.to_query}&fields=#{attribute}" |
195 | json = JSON.parse(last_response.body) | 203 | json = JSON.parse(last_response.body) |
196 | assert_not_nil json['person'][attribute] | 204 | assert_not_nil json['person'][attribute] |