Commit b6cb1220fd6285ac15dcebcea16a13daa6ad3dbb

Authored by Leandro Santos
2 parents 7b24dc08 719cdc46

Merge branch 'api-blocks' into 'master'

Api endpoint for blocks



See merge request !913
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 &lt; Block @@ -20,4 +20,12 @@ class RawHTMLBlock &lt; 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 &lt; Block @@ -29,4 +29,12 @@ class RecentDocumentsBlock &lt; 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
lib/noosfero/api/v1/blocks.rb 0 → 100644
@@ -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 &lt; Block @@ -48,4 +48,12 @@ class RecentContentBlock &lt; 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 &lt; ActionView::TestCase @@ -142,4 +142,18 @@ class RecentContentBlockViewTest &lt; 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
test/api/blocks_test.rb 0 → 100644
@@ -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 &lt; ActiveSupport::TestCase @@ -38,4 +38,13 @@ class BoxesTest &lt; 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 &lt; ActiveSupport::TestCase @@ -365,4 +365,64 @@ class BlockTest &lt; 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 &lt; ActionView::TestCase @@ -128,4 +128,12 @@ class RecentDocumentsBlockViewTest &lt; 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