Commit b6cb1220fd6285ac15dcebcea16a13daa6ad3dbb
Exists in
ratings_minor_fixes
and in
4 other branches
Merge branch 'api-blocks' into 'master'
Api endpoint for blocks See merge request !913
Showing
13 changed files
with
254 additions
and
0 deletions
Show diff stats
app/models/block.rb
@@ -76,6 +76,17 @@ class Block < ApplicationRecord | @@ -76,6 +76,17 @@ class Block < ApplicationRecord | ||
76 | true | 76 | true |
77 | end | 77 | end |
78 | 78 | ||
79 | + def visible_to_user?(user) | ||
80 | + visible = self.display_to_user?(user) | ||
81 | + if self.owner.kind_of?(Profile) | ||
82 | + visible &= self.owner.display_info_to?(user) | ||
83 | + visible &= (self.visible? || user && user.has_permission?(:edit_profile_design, self.owner)) | ||
84 | + elsif self.owner.kind_of?(Environment) | ||
85 | + visible &= (self.visible? || user && user.has_permission?(:edit_environment_design, self.owner)) | ||
86 | + end | ||
87 | + visible | ||
88 | + end | ||
89 | + | ||
79 | def display_to_user?(user) | 90 | def display_to_user?(user) |
80 | display_user == 'all' || (user.nil? && display_user == 'not_logged') || (user && display_user == 'logged') || (user && display_user == 'followers' && user.follows?(owner)) | 91 | display_user == 'all' || (user.nil? && display_user == 'not_logged') || (user && display_user == 'logged') || (user && display_user == 'followers' && user.follows?(owner)) |
81 | end | 92 | end |
@@ -314,6 +325,14 @@ class Block < ApplicationRecord | @@ -314,6 +325,14 @@ class Block < ApplicationRecord | ||
314 | self.observers << block | 325 | self.observers << block |
315 | end | 326 | end |
316 | 327 | ||
328 | + def api_content | ||
329 | + nil | ||
330 | + end | ||
331 | + | ||
332 | + def display_api_content_by_default? | ||
333 | + false | ||
334 | + end | ||
335 | + | ||
317 | private | 336 | private |
318 | 337 | ||
319 | def home_page_path | 338 | def home_page_path |
app/models/raw_html_block.rb
@@ -20,4 +20,12 @@ class RawHTMLBlock < Block | @@ -20,4 +20,12 @@ class RawHTMLBlock < Block | ||
20 | user.has_permission?('edit_raw_html_block', environment) | 20 | user.has_permission?('edit_raw_html_block', environment) |
21 | end | 21 | end |
22 | 22 | ||
23 | + def api_content | ||
24 | + { html: html } | ||
25 | + end | ||
26 | + | ||
27 | + def display_api_content_by_default? | ||
28 | + true | ||
29 | + end | ||
30 | + | ||
23 | end | 31 | end |
app/models/recent_documents_block.rb
@@ -29,4 +29,12 @@ class RecentDocumentsBlock < Block | @@ -29,4 +29,12 @@ class RecentDocumentsBlock < Block | ||
29 | def self.expire_on | 29 | def self.expire_on |
30 | { :profile => [:article], :environment => [:article] } | 30 | { :profile => [:article], :environment => [:article] } |
31 | end | 31 | end |
32 | + | ||
33 | + def api_content | ||
34 | + Noosfero::API::Entities::ArticleBase.represent(docs).as_json | ||
35 | + end | ||
36 | + | ||
37 | + def display_api_content_by_default? | ||
38 | + false | ||
39 | + end | ||
32 | end | 40 | end |
lib/noosfero/api/api.rb
@@ -53,6 +53,7 @@ module Noosfero | @@ -53,6 +53,7 @@ module Noosfero | ||
53 | mount V1::Search | 53 | mount V1::Search |
54 | mount V1::Contacts | 54 | mount V1::Contacts |
55 | mount V1::Boxes | 55 | mount V1::Boxes |
56 | + mount V1::Blocks | ||
56 | mount V1::Profiles | 57 | mount V1::Profiles |
57 | mount V1::Activities | 58 | mount V1::Activities |
58 | 59 |
lib/noosfero/api/entities.rb
@@ -88,6 +88,7 @@ module Noosfero | @@ -88,6 +88,7 @@ module Noosfero | ||
88 | root 'blocks', 'block' | 88 | root 'blocks', 'block' |
89 | expose :id, :type, :settings, :position, :enabled | 89 | expose :id, :type, :settings, :position, :enabled |
90 | expose :mirror, :mirror_block_id, :title | 90 | expose :mirror, :mirror_block_id, :title |
91 | + expose :api_content, if: lambda { |object, options| options[:display_api_content] || object.display_api_content_by_default? } | ||
91 | end | 92 | end |
92 | 93 | ||
93 | class Box < Entity | 94 | class Box < Entity |
@@ -0,0 +1,17 @@ | @@ -0,0 +1,17 @@ | ||
1 | +module Noosfero | ||
2 | + module API | ||
3 | + module V1 | ||
4 | + | ||
5 | + class Blocks < Grape::API | ||
6 | + resource :blocks do | ||
7 | + get ':id' do | ||
8 | + block = Block.find(params["id"]) | ||
9 | + return forbidden! unless block.visible_to_user?(current_person) | ||
10 | + present block, :with => Entities::Block, display_api_content: true | ||
11 | + end | ||
12 | + end | ||
13 | + end | ||
14 | + | ||
15 | + end | ||
16 | + end | ||
17 | +end |
plugins/recent_content/lib/recent_content_block.rb
@@ -48,4 +48,12 @@ class RecentContentBlock < Block | @@ -48,4 +48,12 @@ class RecentContentBlock < Block | ||
48 | attr == self.presentation_mode | 48 | attr == self.presentation_mode |
49 | end | 49 | end |
50 | 50 | ||
51 | + def api_content | ||
52 | + children = self.articles_of_folder(self.root, self.total_items) | ||
53 | + Noosfero::API::Entities::ArticleBase.represent(children).as_json | ||
54 | + end | ||
55 | + | ||
56 | + def display_api_content_by_default? | ||
57 | + false | ||
58 | + end | ||
51 | end | 59 | end |
plugins/recent_content/test/unit/recent_content_block_test.rb
@@ -142,4 +142,18 @@ class RecentContentBlockViewTest < ActionView::TestCase | @@ -142,4 +142,18 @@ class RecentContentBlockViewTest < ActionView::TestCase | ||
142 | 142 | ||
143 | assert_match /Block Title/, content | 143 | assert_match /Block Title/, content |
144 | end | 144 | end |
145 | + | ||
146 | + should 'return articles in api_content' do | ||
147 | + profile = create_user('testuser').person | ||
148 | + | ||
149 | + root = fast_create(Blog, name: 'test-blog', profile_id: profile.id) | ||
150 | + article = fast_create(TextArticle, parent_id: root.id, profile_id: profile.id) | ||
151 | + | ||
152 | + block = RecentContentBlock.new | ||
153 | + block.stubs(:holder).returns(profile) | ||
154 | + block.selected_folder = root.id | ||
155 | + block.presentation_mode = '' | ||
156 | + assert_equal [article.id], block.api_content['articles'].map {|a| a[:id]} | ||
157 | + end | ||
158 | + | ||
145 | end | 159 | end |
@@ -0,0 +1,97 @@ | @@ -0,0 +1,97 @@ | ||
1 | +require_relative 'test_helper' | ||
2 | + | ||
3 | +class BlocksTest < ActiveSupport::TestCase | ||
4 | + | ||
5 | + def setup | ||
6 | + create_and_activate_user | ||
7 | + login_api | ||
8 | + @environment = Environment.default | ||
9 | + @profile = fast_create(Profile) | ||
10 | + end | ||
11 | + | ||
12 | + attr_accessor :environment, :profile | ||
13 | + | ||
14 | + should 'get an environment block' do | ||
15 | + box = fast_create(Box, :owner_id => environment.id, :owner_type => Environment.name) | ||
16 | + block = fast_create(Block, box_id: box.id) | ||
17 | + get "/api/v1/blocks/#{block.id}?#{params.to_query}" | ||
18 | + json = JSON.parse(last_response.body) | ||
19 | + assert_equal block.id, json["block"]["id"] | ||
20 | + end | ||
21 | + | ||
22 | + should 'get a profile block' do | ||
23 | + box = fast_create(Box, :owner_id => profile.id, :owner_type => Profile.name) | ||
24 | + block = fast_create(Block, box_id: box.id) | ||
25 | + get "/api/v1/blocks/#{block.id}?#{params.to_query}" | ||
26 | + json = JSON.parse(last_response.body) | ||
27 | + assert_equal block.id, json["block"]["id"] | ||
28 | + end | ||
29 | + | ||
30 | + should 'get a profile block for a not logged in user' do | ||
31 | + logout_api | ||
32 | + box = fast_create(Box, :owner_id => profile.id, :owner_type => Profile.name) | ||
33 | + block = fast_create(Block, box_id: box.id) | ||
34 | + get "/api/v1/blocks/#{block.id}?#{params.to_query}" | ||
35 | + json = JSON.parse(last_response.body) | ||
36 | + assert_equal block.id, json["block"]["id"] | ||
37 | + end | ||
38 | + | ||
39 | + should 'not get a profile block for a not logged in user' do | ||
40 | + logout_api | ||
41 | + profile = fast_create(Profile, public_profile: false) | ||
42 | + box = fast_create(Box, :owner_id => profile.id, :owner_type => Profile.name) | ||
43 | + block = fast_create(Block, box_id: box.id) | ||
44 | + get "/api/v1/blocks/#{block.id}?#{params.to_query}" | ||
45 | + assert_equal 403, last_response.status | ||
46 | + end | ||
47 | + | ||
48 | + should 'not get a profile block for an user without permission' do | ||
49 | + profile = fast_create(Profile, public_profile: false) | ||
50 | + box = fast_create(Box, :owner_id => profile.id, :owner_type => Profile.name) | ||
51 | + block = fast_create(Block, box_id: box.id) | ||
52 | + get "/api/v1/blocks/#{block.id}?#{params.to_query}" | ||
53 | + assert_equal 403, last_response.status | ||
54 | + end | ||
55 | + | ||
56 | + should 'get a block for an user with permission in a private profile' do | ||
57 | + profile = fast_create(Profile, public_profile: false) | ||
58 | + profile.add_admin(person) | ||
59 | + box = fast_create(Box, :owner_id => profile.id, :owner_type => Profile.name) | ||
60 | + block = fast_create(Block, box_id: box.id) | ||
61 | + get "/api/v1/blocks/#{block.id}?#{params.to_query}" | ||
62 | + json = JSON.parse(last_response.body) | ||
63 | + assert_equal block.id, json["block"]["id"] | ||
64 | + end | ||
65 | + | ||
66 | + should 'display api content by default' do | ||
67 | + box = fast_create(Box, :owner_id => environment.id, :owner_type => Environment.name) | ||
68 | + block = fast_create(Block, box_id: box.id) | ||
69 | + get "/api/v1/blocks/#{block.id}?#{params.to_query}" | ||
70 | + json = JSON.parse(last_response.body) | ||
71 | + assert json["block"].key?('api_content') | ||
72 | + end | ||
73 | + | ||
74 | + should 'display api content of a specific block' do | ||
75 | + class SomeBlock < Block | ||
76 | + def api_content | ||
77 | + {some_content: { name: 'test'} } | ||
78 | + end | ||
79 | + end | ||
80 | + box = fast_create(Box, :owner_id => environment.id, :owner_type => Environment.name) | ||
81 | + block = fast_create(SomeBlock, box_id: box.id) | ||
82 | + get "/api/v1/blocks/#{block.id}?#{params.to_query}" | ||
83 | + json = JSON.parse(last_response.body) | ||
84 | + assert_equal "test", json["block"]["api_content"]["some_content"]["name"] | ||
85 | + end | ||
86 | + | ||
87 | + should 'display api content of raw html block' do | ||
88 | + box = fast_create(Box, :owner_id => environment.id, :owner_type => Environment.name) | ||
89 | + block = fast_create(RawHTMLBlock, box_id: box.id) | ||
90 | + block.html = '<div>test</div>' | ||
91 | + block.save! | ||
92 | + get "/api/v1/blocks/#{block.id}?#{params.to_query}" | ||
93 | + json = JSON.parse(last_response.body) | ||
94 | + assert_equal "<div>test</div>", json["block"]["api_content"]["html"] | ||
95 | + end | ||
96 | + | ||
97 | +end |
test/api/boxes_test.rb
@@ -38,4 +38,13 @@ class BoxesTest < ActiveSupport::TestCase | @@ -38,4 +38,13 @@ class BoxesTest < ActiveSupport::TestCase | ||
38 | assert_equal box.id, json["boxes"].first["id"] | 38 | assert_equal box.id, json["boxes"].first["id"] |
39 | end | 39 | end |
40 | 40 | ||
41 | + should 'not display block api_content by default' do | ||
42 | + Environment.delete_all | ||
43 | + environment = fast_create(Environment, :is_default => true) | ||
44 | + box = fast_create(Box, :owner_id => environment.id, :owner_type => 'Environment') | ||
45 | + block = fast_create(Block, box_id: box.id) | ||
46 | + get "/api/v1/environments/default/boxes?#{params.to_query}" | ||
47 | + json = JSON.parse(last_response.body) | ||
48 | + assert !json["boxes"].first["blocks"].first.key?('api_content') | ||
49 | + end | ||
41 | end | 50 | end |
test/api/test_helper.rb
@@ -31,6 +31,10 @@ class ActiveSupport::TestCase | @@ -31,6 +31,10 @@ class ActiveSupport::TestCase | ||
31 | @params[:private_token] = @private_token | 31 | @params[:private_token] = @private_token |
32 | end | 32 | end |
33 | 33 | ||
34 | + def logout_api | ||
35 | + @params.delete(:private_token) | ||
36 | + end | ||
37 | + | ||
34 | attr_accessor :private_token, :user, :person, :params, :environment | 38 | attr_accessor :private_token, :user, :person, :params, :environment |
35 | 39 | ||
36 | private | 40 | private |
test/unit/block_test.rb
@@ -365,4 +365,64 @@ class BlockTest < ActiveSupport::TestCase | @@ -365,4 +365,64 @@ class BlockTest < ActiveSupport::TestCase | ||
365 | assert block.get_limit.is_a?(Fixnum) | 365 | assert block.get_limit.is_a?(Fixnum) |
366 | end | 366 | end |
367 | 367 | ||
368 | + should 'return true at visible_to_user? when block is visible' do | ||
369 | + block = Block.new | ||
370 | + person = create_user('person_one').person | ||
371 | + assert block.visible_to_user?(person) | ||
372 | + end | ||
373 | + | ||
374 | + should 'return false at visible_to_user? when block is not visible and user is nil' do | ||
375 | + block = Block.new | ||
376 | + person = create_user('person_one').person | ||
377 | + block.stubs(:owner).returns(person) | ||
378 | + block.expects(:visible?).returns(false) | ||
379 | + assert !block.visible_to_user?(nil) | ||
380 | + end | ||
381 | + | ||
382 | + should 'return false at visible_to_user? when block is not visible and user does not has permission' do | ||
383 | + block = Block.new | ||
384 | + person = create_user('person_one').person | ||
385 | + community = fast_create(Community) | ||
386 | + block.stubs(:owner).returns(community) | ||
387 | + block.expects(:visible?).returns(false) | ||
388 | + assert !block.visible_to_user?(person) | ||
389 | + end | ||
390 | + | ||
391 | + should 'return true at visible_to_user? when block is not visible and user has permission' do | ||
392 | + block = Block.new | ||
393 | + person = create_user('person_one').person | ||
394 | + community = fast_create(Community) | ||
395 | + give_permission(person, 'edit_profile_design', community) | ||
396 | + block.stubs(:owner).returns(community) | ||
397 | + block.expects(:visible?).returns(false) | ||
398 | + assert block.visible_to_user?(person) | ||
399 | + end | ||
400 | + | ||
401 | + should 'return false at visible_to_user? when block is not visible and user does not has permission in environment' do | ||
402 | + block = Block.new | ||
403 | + environment = Environment.default | ||
404 | + person = create_user('person_one').person | ||
405 | + block.stubs(:owner).returns(environment) | ||
406 | + block.expects(:visible?).returns(false) | ||
407 | + assert !block.visible_to_user?(person) | ||
408 | + end | ||
409 | + | ||
410 | + should 'return true at visible_to_user? when block is not visible and user has permission in environment' do | ||
411 | + block = Block.new | ||
412 | + environment = Environment.default | ||
413 | + person = create_user('person_one').person | ||
414 | + give_permission(person, 'edit_environment_design', environment) | ||
415 | + block.stubs(:owner).returns(environment) | ||
416 | + block.expects(:visible?).returns(false) | ||
417 | + assert block.visible_to_user?(person) | ||
418 | + end | ||
419 | + | ||
420 | + should 'return false at visible_to_user? when block is not visible to user' do | ||
421 | + block = Block.new | ||
422 | + person = create_user('person_one').person | ||
423 | + block.stubs(:owner).returns(person) | ||
424 | + block.expects(:visible?).returns(true) | ||
425 | + block.expects(:display_to_user?).returns(false) | ||
426 | + assert !block.visible_to_user?(nil) | ||
427 | + end | ||
368 | end | 428 | end |
test/unit/recent_documents_block_test.rb
@@ -128,4 +128,12 @@ class RecentDocumentsBlockViewTest < ActionView::TestCase | @@ -128,4 +128,12 @@ class RecentDocumentsBlockViewTest < ActionView::TestCase | ||
128 | box.expects(:owner).returns(Environment.new).at_least_once | 128 | box.expects(:owner).returns(Environment.new).at_least_once |
129 | assert_equal '', render_block_footer(block) | 129 | assert_equal '', render_block_footer(block) |
130 | end | 130 | end |
131 | + | ||
132 | + should 'return articles in api_content' do | ||
133 | + profile = fast_create(Profile) | ||
134 | + article = fast_create(TextArticle, profile_id: profile.id) | ||
135 | + block = RecentDocumentsBlock.new | ||
136 | + block.stubs(:owner).returns(profile) | ||
137 | + assert_equal [article.id], block.api_content['articles'].map {|a| a[:id]} | ||
138 | + end | ||
131 | end | 139 | end |