Commit 69562568e949978baa6590dc18e464783ca34e76

Authored by Leandro Santos
2 parents a635532c d0f2adc5
Exists in staging and in 1 other branch production

Merge branch 'staging' of softwarepublico.gov.br:noosferogov/noosfero into staging

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
app/views/blocks/raw_html.html.erb
1 <%= block_title(block.title, block.subtitle) %> 1 <%= block_title(block.title, block.subtitle) %>
2 2
3 -<%= block.html.html_safe %> 3 +<%= (block.html || '').html_safe %>
lib/noosfero/api/api.rb
@@ -55,6 +55,7 @@ module Noosfero @@ -55,6 +55,7 @@ module Noosfero
55 mount V1::Search 55 mount V1::Search
56 mount V1::Contacts 56 mount V1::Contacts
57 mount V1::Boxes 57 mount V1::Boxes
  58 + mount V1::Blocks
58 mount V1::Profiles 59 mount V1::Profiles
59 mount V1::Activities 60 mount V1::Activities
60 61
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/helpers.rb
1 require 'grape' 1 require 'grape'
  2 +require 'base64'
  3 +require 'tempfile'
2 require_relative '../../find_by_contents' 4 require_relative '../../find_by_contents'
3 5
4 - module Noosfero;  
5 - module API  
6 - module APIHelpers 6 +module Noosfero;
  7 + module API
  8 + module APIHelpers
7 PRIVATE_TOKEN_PARAM = :private_token 9 PRIVATE_TOKEN_PARAM = :private_token
8 DEFAULT_ALLOWED_PARAMETERS = [:parent_id, :from, :until, :content_type, :author_id, :identifier, :archived] 10 DEFAULT_ALLOWED_PARAMETERS = [:parent_id, :from, :until, :content_type, :author_id, :identifier, :archived]
9 11
@@ -255,7 +257,7 @@ require_relative &#39;../../find_by_contents&#39; @@ -255,7 +257,7 @@ require_relative &#39;../../find_by_contents&#39;
255 else 257 else
256 created_at = scope.find(reference_id).created_at 258 created_at = scope.find(reference_id).created_at
257 scope.send("#{params.key?(:oldest) ? 'older_than' : 'younger_than'}", created_at) 259 scope.send("#{params.key?(:oldest) ? 'older_than' : 'younger_than'}", created_at)
258 - end 260 + end
259 end 261 end
260 262
261 def by_categories(scope, params) 263 def by_categories(scope, params)
@@ -412,6 +414,30 @@ require_relative &#39;../../find_by_contents&#39; @@ -412,6 +414,30 @@ require_relative &#39;../../find_by_contents&#39;
412 not_found! if Noosfero::API::API.endpoint_unavailable?(self, @environment) 414 not_found! if Noosfero::API::API.endpoint_unavailable?(self, @environment)
413 end 415 end
414 416
  417 + def asset_with_image params
  418 + if params.has_key? :image_builder
  419 + asset_api_params = params
  420 + asset_api_params[:image_builder] = base64_to_uploadedfile(asset_api_params[:image_builder])
  421 + return asset_api_params
  422 + end
  423 + params
  424 + end
  425 +
  426 + def base64_to_uploadedfile(base64_image)
  427 + tempfile = base64_to_tempfile base64_image
  428 + converted_image = base64_image
  429 + converted_image[:tempfile] = tempfile
  430 + return {uploaded_data: ActionDispatch::Http::UploadedFile.new(converted_image)}
  431 + end
  432 +
  433 + def base64_to_tempfile base64_image
  434 + base64_img_str = base64_image[:tempfile]
  435 + decoded_base64_str = Base64.decode64(base64_img_str)
  436 + tempfile = Tempfile.new(base64_image[:filename])
  437 + tempfile.write(decoded_base64_str.encode("ascii-8bit").force_encoding("utf-8"))
  438 + tempfile.rewind
  439 + tempfile
  440 + end
415 private 441 private
416 442
417 def parser_params(params) 443 def parser_params(params)
lib/noosfero/api/v1/articles.rb
@@ -56,7 +56,7 @@ module Noosfero @@ -56,7 +56,7 @@ module Noosfero
56 post ':id' do 56 post ':id' do
57 article = environment.articles.find(params[:id]) 57 article = environment.articles.find(params[:id])
58 return forbidden! unless article.allow_edit?(current_person) 58 return forbidden! unless article.allow_edit?(current_person)
59 - article.update_attributes!(params[:article]) 59 + article.update_attributes!(asset_with_image(params[:article]))
60 present_partial article, :with => Entities::Article 60 present_partial article, :with => Entities::Article
61 end 61 end
62 62
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
lib/noosfero/api/v1/people.rb
@@ -55,11 +55,10 @@ module Noosfero @@ -55,11 +55,10 @@ module Noosfero
55 post ':id' do 55 post ':id' do
56 authenticate! 56 authenticate!
57 return forbidden! if current_person.id.to_s != params[:id] 57 return forbidden! if current_person.id.to_s != params[:id]
58 - current_person.update_attributes!(params[:person]) 58 + current_person.update_attributes!(asset_with_image(params[:person]))
59 present current_person, :with => Entities::Person, :current_person => current_person 59 present current_person, :with => Entities::Person, :current_person => current_person
60 end 60 end
61 -  
62 - # Example Request: 61 +
63 # POST api/v1/people?person[login]=some_login&person[password]=some_password&person[name]=Jack 62 # POST api/v1/people?person[login]=some_login&person[password]=some_password&person[name]=Jack
64 # for each custom field for person, add &person[field_name]=field_value to the request 63 # for each custom field for person, add &person[field_name]=field_value to the request
65 desc "Create person" 64 desc "Create person"
@@ -76,7 +75,7 @@ module Noosfero @@ -76,7 +75,7 @@ module Noosfero
76 params[:person][:custom_values][key]=params[:person].delete(key) if Person.custom_fields(environment).any?{|cf| cf.name==key} 75 params[:person][:custom_values][key]=params[:person].delete(key) if Person.custom_fields(environment).any?{|cf| cf.name==key}
77 end 76 end
78 77
79 - user = User.build(user_data, params[:person], environment) 78 + user = User.build(user_data, asset_with_image(params[:person]), environment)
80 79
81 begin 80 begin
82 user.signup! 81 user.signup!
plugins/ldap/lib/ldap_plugin.rb
@@ -53,7 +53,7 @@ class LdapPlugin &lt; Noosfero::Plugin @@ -53,7 +53,7 @@ class LdapPlugin &lt; Noosfero::Plugin
53 return nil if attrs.nil? 53 return nil if attrs.nil?
54 54
55 user_login = get_login(attrs, ldap.attr_login, login) 55 user_login = get_login(attrs, ldap.attr_login, login)
56 - user = User.find_or_initialize_by_login(user_login) 56 + user = User.find_or_initialize_by(login: user_login)
57 return nil if !user.new_record? && !user.activated? 57 return nil if !user.new_record? && !user.activated?
58 58
59 user.login = user_login 59 user.login = user_login
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/helpers_test.rb
1 require_relative 'test_helper' 1 require_relative 'test_helper'
  2 +require "base64"
2 require 'noosfero/api/helpers' 3 require 'noosfero/api/helpers'
3 4
4 class APIHelpersTest < ActiveSupport::TestCase 5 class APIHelpersTest < ActiveSupport::TestCase
@@ -264,6 +265,23 @@ class APIHelpersTest &lt; ActiveSupport::TestCase @@ -264,6 +265,23 @@ class APIHelpersTest &lt; ActiveSupport::TestCase
264 end 265 end
265 266
266 ###### END Captcha tests ###### 267 ###### END Captcha tests ######
  268 + should 'create a :uploaded_data hash, expected by image_builder ' do
  269 + base64_image = create_base64_image
  270 + uploadedfile = base64_to_uploadedfile base64_image
  271 + assert uploadedfile.has_key? :uploaded_data
  272 + assert_equal uploadedfile[:uploaded_data].original_filename, base64_image[:filename]
  273 + assert_equal uploadedfile[:uploaded_data].content_type, base64_image[:type]
  274 + assert uploadedfile[:uploaded_data].tempfile
  275 + end
  276 +
  277 + should 'return a params copy with a UploadedFile object' do
  278 + base64_image = create_base64_image
  279 + params = {}
  280 + params.merge!({image_builder: base64_image})
  281 + asset_params = asset_with_image params
  282 + assert !asset_params[:image_builder][:uploaded_data].nil?
  283 + assert asset_params[:image_builder][:uploaded_data].is_a? ActionDispatch::Http::UploadedFile
  284 + end
267 285
268 protected 286 protected
269 287
test/api/people_test.rb
@@ -388,4 +388,14 @@ class PeopleTest &lt; ActiveSupport::TestCase @@ -388,4 +388,14 @@ class PeopleTest &lt; ActiveSupport::TestCase
388 end 388 end
389 end 389 end
390 390
  391 + should 'update person image' do
  392 + login_api
  393 + base64_image = create_base64_image
  394 + params.merge!({person: {image_builder: base64_image}})
  395 + assert_nil person.image
  396 + post "/api/v1/people/#{person.id}?#{params.to_query}"
  397 + person.reload
  398 + assert_not_nil person.image
  399 + assert_equal person.image.filename, base64_image[:filename]
  400 + end
391 end 401 end
test/api/test_helper.rb
@@ -69,8 +69,24 @@ class ActiveSupport::TestCase @@ -69,8 +69,24 @@ class ActiveSupport::TestCase
69 @params[:private_token] = @private_token 69 @params[:private_token] = @private_token
70 end 70 end
71 71
  72 + def logout_api
  73 + @params.delete(:private_token)
  74 + end
  75 +
72 attr_accessor :private_token, :user, :person, :params, :environment 76 attr_accessor :private_token, :user, :person, :params, :environment
73 77
  78 + def create_base64_image
  79 + image_path = File.absolute_path(Rails.root + 'public/images/noosfero-network.png')
  80 + image_name = File.basename(image_path)
  81 + image_type = "image/#{File.extname(image_name).delete "."}"
  82 + encoded_base64_img = Base64.encode64(File.open(image_path) {|io| io.read })
  83 + base64_image = {}
  84 + base64_image[:tempfile] = encoded_base64_img
  85 + base64_image[:filename] = image_name
  86 + base64_image[:type] = image_type
  87 + base64_image
  88 + end
  89 +
74 private 90 private
75 91
76 def json_response_ids(kind) 92 def json_response_ids(kind)
test/unit/block_test.rb
@@ -398,4 +398,64 @@ class BlockTest &lt; ActiveSupport::TestCase @@ -398,4 +398,64 @@ class BlockTest &lt; ActiveSupport::TestCase
398 assert block.get_limit.is_a?(Fixnum) 398 assert block.get_limit.is_a?(Fixnum)
399 end 399 end
400 400
  401 + should 'return true at visible_to_user? when block is visible' do
  402 + block = Block.new
  403 + person = create_user('person_one').person
  404 + assert block.visible_to_user?(person)
  405 + end
  406 +
  407 + should 'return false at visible_to_user? when block is not visible and user is nil' do
  408 + block = Block.new
  409 + person = create_user('person_one').person
  410 + block.stubs(:owner).returns(person)
  411 + block.expects(:visible?).returns(false)
  412 + assert !block.visible_to_user?(nil)
  413 + end
  414 +
  415 + should 'return false at visible_to_user? when block is not visible and user does not has permission' do
  416 + block = Block.new
  417 + person = create_user('person_one').person
  418 + community = fast_create(Community)
  419 + block.stubs(:owner).returns(community)
  420 + block.expects(:visible?).returns(false)
  421 + assert !block.visible_to_user?(person)
  422 + end
  423 +
  424 + should 'return true at visible_to_user? when block is not visible and user has permission' do
  425 + block = Block.new
  426 + person = create_user('person_one').person
  427 + community = fast_create(Community)
  428 + give_permission(person, 'edit_profile_design', community)
  429 + block.stubs(:owner).returns(community)
  430 + block.expects(:visible?).returns(false)
  431 + assert block.visible_to_user?(person)
  432 + end
  433 +
  434 + should 'return false at visible_to_user? when block is not visible and user does not has permission in environment' do
  435 + block = Block.new
  436 + environment = Environment.default
  437 + person = create_user('person_one').person
  438 + block.stubs(:owner).returns(environment)
  439 + block.expects(:visible?).returns(false)
  440 + assert !block.visible_to_user?(person)
  441 + end
  442 +
  443 + should 'return true at visible_to_user? when block is not visible and user has permission in environment' do
  444 + block = Block.new
  445 + environment = Environment.default
  446 + person = create_user('person_one').person
  447 + give_permission(person, 'edit_environment_design', environment)
  448 + block.stubs(:owner).returns(environment)
  449 + block.expects(:visible?).returns(false)
  450 + assert block.visible_to_user?(person)
  451 + end
  452 +
  453 + should 'return false at visible_to_user? when block is not visible to user' do
  454 + block = Block.new
  455 + person = create_user('person_one').person
  456 + block.stubs(:owner).returns(person)
  457 + block.expects(:visible?).returns(true)
  458 + block.expects(:display_to_user?).returns(false)
  459 + assert !block.visible_to_user?(nil)
  460 + end
401 end 461 end
test/unit/raw_html_block_test.rb
@@ -40,4 +40,11 @@ class RawHTMLBlockTest &lt; ActiveSupport::TestCase @@ -40,4 +40,11 @@ class RawHTMLBlockTest &lt; ActiveSupport::TestCase
40 assert block.editable?(user) 40 assert block.editable?(user)
41 end 41 end
42 42
  43 + should 'not raise if there is no html defined' do
  44 + block = RawHTMLBlock.new(:html => nil)
  45 + assert_nothing_raised do
  46 + render_block_content(block)
  47 + end
  48 + end
  49 +
43 end 50 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