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 | 76 | true |
| 77 | 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 | 90 | def display_to_user?(user) |
| 80 | 91 | display_user == 'all' || (user.nil? && display_user == 'not_logged') || (user && display_user == 'logged') || (user && display_user == 'followers' && user.follows?(owner)) |
| 81 | 92 | end |
| ... | ... | @@ -314,6 +325,14 @@ class Block < ApplicationRecord |
| 314 | 325 | self.observers << block |
| 315 | 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 | 336 | private |
| 318 | 337 | |
| 319 | 338 | def home_page_path | ... | ... |
app/models/raw_html_block.rb
app/models/recent_documents_block.rb
| ... | ... | @@ -29,4 +29,12 @@ class RecentDocumentsBlock < Block |
| 29 | 29 | def self.expire_on |
| 30 | 30 | { :profile => [:article], :environment => [:article] } |
| 31 | 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 | 40 | end | ... | ... |
lib/noosfero/api/api.rb
lib/noosfero/api/entities.rb
| ... | ... | @@ -88,6 +88,7 @@ module Noosfero |
| 88 | 88 | root 'blocks', 'block' |
| 89 | 89 | expose :id, :type, :settings, :position, :enabled |
| 90 | 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 | 92 | end |
| 92 | 93 | |
| 93 | 94 | class Box < Entity | ... | ... |
| ... | ... | @@ -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 | 48 | attr == self.presentation_mode |
| 49 | 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 | 59 | end | ... | ... |
plugins/recent_content/test/unit/recent_content_block_test.rb
| ... | ... | @@ -142,4 +142,18 @@ class RecentContentBlockViewTest < ActionView::TestCase |
| 142 | 142 | |
| 143 | 143 | assert_match /Block Title/, content |
| 144 | 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 | 159 | end | ... | ... |
| ... | ... | @@ -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 | 38 | assert_equal box.id, json["boxes"].first["id"] |
| 39 | 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 | 50 | end | ... | ... |
test/api/test_helper.rb
test/unit/block_test.rb
| ... | ... | @@ -365,4 +365,64 @@ class BlockTest < ActiveSupport::TestCase |
| 365 | 365 | assert block.get_limit.is_a?(Fixnum) |
| 366 | 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 | 428 | end | ... | ... |
test/unit/recent_documents_block_test.rb
| ... | ... | @@ -128,4 +128,12 @@ class RecentDocumentsBlockViewTest < ActionView::TestCase |
| 128 | 128 | box.expects(:owner).returns(Environment.new).at_least_once |
| 129 | 129 | assert_equal '', render_block_footer(block) |
| 130 | 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 | 139 | end | ... | ... |