Commit 3c5828873aebe07383b3f786d950e40023c4ea55
Exists in
staging
Merge branch 'master' into staging
Showing
10 changed files
with
140 additions
and
86 deletions
Show diff stats
lib/noosfero/api/entities.rb
| ... | ... | @@ -187,11 +187,16 @@ module Noosfero |
| 187 | 187 | end |
| 188 | 188 | end |
| 189 | 189 | |
| 190 | - class Comment < Entity | |
| 191 | - root 'comments', 'comment' | |
| 190 | + class CommentBase < Entity | |
| 192 | 191 | expose :body, :title, :id |
| 193 | 192 | expose :created_at, :format_with => :timestamp |
| 194 | 193 | expose :author, :using => Profile |
| 194 | + expose :reply_of, :using => CommentBase | |
| 195 | + end | |
| 196 | + | |
| 197 | + class Comment < CommentBase | |
| 198 | + root 'comments', 'comment' | |
| 199 | + expose :children, as: :replies, :using => Comment | |
| 195 | 200 | end |
| 196 | 201 | |
| 197 | 202 | class User < Entity | ... | ... |
lib/noosfero/api/v1/comments.rb
| ... | ... | @@ -2,9 +2,12 @@ module Noosfero |
| 2 | 2 | module API |
| 3 | 3 | module V1 |
| 4 | 4 | class Comments < Grape::API |
| 5 | + MAX_PER_PAGE = 20 | |
| 6 | + | |
| 5 | 7 | before { authenticate! } |
| 6 | 8 | |
| 7 | 9 | resource :articles do |
| 10 | + paginate max_per_page: MAX_PER_PAGE | |
| 8 | 11 | # Collect comments from articles |
| 9 | 12 | # |
| 10 | 13 | # Parameters: |
| ... | ... | @@ -17,7 +20,7 @@ module Noosfero |
| 17 | 20 | get ":id/comments" do |
| 18 | 21 | article = find_article(environment.articles, params[:id]) |
| 19 | 22 | comments = select_filtered_collection_of(article, :comments, params) |
| 20 | - | |
| 23 | + comments = comments.without_reply if(params[:without_reply].present?) | |
| 21 | 24 | present comments, :with => Entities::Comment, :current_person => current_person |
| 22 | 25 | end |
| 23 | 26 | ... | ... |
plugins/gallery_block/lib/gallery_block.rb
plugins/gallery_block/test/unit/gallery_block_test.rb
| ... | ... | @@ -20,3 +20,38 @@ class GalleryBlockTest < ActiveSupport::TestCase |
| 20 | 20 | end |
| 21 | 21 | |
| 22 | 22 | end |
| 23 | + | |
| 24 | +require 'boxes_helper' | |
| 25 | + | |
| 26 | +class GalleryBlockViewTest < ActionView::TestCase | |
| 27 | + include BoxesHelper | |
| 28 | + | |
| 29 | + def setup | |
| 30 | + @community = fast_create(Community) | |
| 31 | + end | |
| 32 | + | |
| 33 | + should 'display the default message for empty gallery' do | |
| 34 | + block = GalleryBlock.new | |
| 35 | + block.stubs(:owner).returns(@community) | |
| 36 | + | |
| 37 | + ActionView::Base.any_instance.expects(:block_title).returns("") | |
| 38 | + | |
| 39 | + content = render_block_content(block) | |
| 40 | + | |
| 41 | + assert_match /#{_('Please, edit this block and choose some gallery')}/, content | |
| 42 | + end | |
| 43 | + | |
| 44 | + should "display the gallery's content" do | |
| 45 | + gallery = fast_create(Gallery, :profile_id => @community.id) | |
| 46 | + image = create(UploadedFile, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => gallery, :profile => @community) | |
| 47 | + block = create(GalleryBlock, :gallery_id => gallery.id) | |
| 48 | + block.stubs(:owner).returns(@community) | |
| 49 | + | |
| 50 | + ActionView::Base.any_instance.expects(:block_title).returns("") | |
| 51 | + | |
| 52 | + content = render_block_content(block) | |
| 53 | + | |
| 54 | + assert_tag_in_string content, tag: 'img', attributes: {src: image.public_filename(:thumb)} | |
| 55 | + assert_tag_in_string content, tag: 'span', content: _('Next') | |
| 56 | + end | |
| 57 | +end | ... | ... |
| ... | ... | @@ -0,0 +1,44 @@ |
| 1 | +<%= block_title(block.title, block.subtitle) %> | |
| 2 | + | |
| 3 | +<% unless block.images.blank? %> | |
| 4 | + <%= link_to content_tag(:span, _('Previous')), '#', :class => 'gallery-block-prev gallery-block-arrow icon-left' %> | |
| 5 | + <div class="gallery-block-container"> | |
| 6 | + <ul class="gallery-list"> | |
| 7 | + <% block.images.in_groups_of(block.groups_of).each do |group| %> | |
| 8 | + <li class="gallery-group"> | |
| 9 | + <div class="gallery-items"> | |
| 10 | + <ul> | |
| 11 | + <% group.reject{ |x| x.nil? }.each_with_index do |p, i| %> | |
| 12 | + <li class="gallery-item"> | |
| 13 | + <%= link_to image_tag(p.public_filename(:thumb), :alt => p.name, :title => p.name), p.view_url, :class => 'gallery-image' %> | |
| 14 | + <div class="gallery-image-info position-<%= i + 1 %>" style="display: none"> | |
| 15 | + <div class="gallery-image-text"> | |
| 16 | + <h3><%= p.name %></h3> | |
| 17 | + </div> | |
| 18 | + </div> | |
| 19 | + </li> | |
| 20 | + <% end %> | |
| 21 | + </ul> | |
| 22 | + </div> | |
| 23 | + </li> | |
| 24 | + <% end %> | |
| 25 | + </ul> | |
| 26 | + </div> | |
| 27 | + <%= link_to content_tag(:span, _('Next')), '#', :class => 'gallery-block-next gallery-block-arrow icon-right' %> | |
| 28 | + <script type="text/javascript"> | |
| 29 | + (function($) { | |
| 30 | + var options = { | |
| 31 | + fx : 'scrollHorz', | |
| 32 | + timeout: 0, | |
| 33 | + prev: '#block-<%= block.id %> .gallery-block-prev', | |
| 34 | + next: '#block-<%= block.id %> .gallery-block-next', | |
| 35 | + speed: 2000, | |
| 36 | + timeout: <%= block.interval * 1000 %> | |
| 37 | + } | |
| 38 | + $('#block-<%= block.id %> .gallery-list').cycle(options); | |
| 39 | + })(jQuery); | |
| 40 | + </script> | |
| 41 | + <p class="gallery-block-footer"></p> | |
| 42 | +<% else %> | |
| 43 | + <em><%= _('Please, edit this block and choose some gallery') %></em> | |
| 44 | +<% end %> | ... | ... |
plugins/gallery_block/views/gallery_block.html.erb
| ... | ... | @@ -1,44 +0,0 @@ |
| 1 | -<%= block_title(block.title, block.subtitle) %> | |
| 2 | - | |
| 3 | -<% unless block.images.blank? %> | |
| 4 | - <%= link_to content_tag(:span, _('Previous')), '#', :class => 'gallery-block-prev gallery-block-arrow icon-left' %> | |
| 5 | - <div class="gallery-block-container"> | |
| 6 | - <ul class="gallery-list"> | |
| 7 | - <% block.images.in_groups_of(block.groups_of).each do |group| %> | |
| 8 | - <li class="gallery-group"> | |
| 9 | - <div class="gallery-items"> | |
| 10 | - <ul> | |
| 11 | - <% group.reject{ |x| x.nil? }.each_with_index do |p, i| %> | |
| 12 | - <li class="gallery-item"> | |
| 13 | - <%= link_to image_tag(p.public_filename(:thumb), :alt => p.name, :title => p.name), p.view_url, :class => 'gallery-image' %> | |
| 14 | - <div class="gallery-image-info position-<%= i + 1 %>" style="display: none"> | |
| 15 | - <div class="gallery-image-text"> | |
| 16 | - <h3><%= p.name %></h3> | |
| 17 | - </div> | |
| 18 | - </div> | |
| 19 | - </li> | |
| 20 | - <% end %> | |
| 21 | - </ul> | |
| 22 | - </div> | |
| 23 | - </li> | |
| 24 | - <% end %> | |
| 25 | - </ul> | |
| 26 | - </div> | |
| 27 | - <%= link_to content_tag(:span, _('Next')), '#', :class => 'gallery-block-next gallery-block-arrow icon-right' %> | |
| 28 | - <script type="text/javascript"> | |
| 29 | - (function($) { | |
| 30 | - var options = { | |
| 31 | - fx : 'scrollHorz', | |
| 32 | - timeout: 0, | |
| 33 | - prev: '#block-<%= block.id %> .gallery-block-prev', | |
| 34 | - next: '#block-<%= block.id %> .gallery-block-next', | |
| 35 | - speed: 2000, | |
| 36 | - timeout: <%= block.interval * 1000 %> | |
| 37 | - } | |
| 38 | - $('#block-<%= block.id %> .gallery-list').cycle(options); | |
| 39 | - })(jQuery); | |
| 40 | - </script> | |
| 41 | - <p class="gallery-block-footer"></p> | |
| 42 | -<% else %> | |
| 43 | - <em><%= _('Please, edit this block and choose some gallery') %></em> | |
| 44 | -<% end %> |
plugins/profile_description_block/lib/profile_description_block.rb
| ... | ... | @@ -16,24 +16,6 @@ class ProfileDescriptionBlock < Block |
| 16 | 16 | _('PROFILE DESCRIPTION') |
| 17 | 17 | end |
| 18 | 18 | |
| 19 | - def content(args={}) | |
| 20 | - description = if self.owner.description.blank? | |
| 21 | - "Description field is empty or | |
| 22 | - not enabled on enviroment" | |
| 23 | - else | |
| 24 | - self.owner.description | |
| 25 | - end | |
| 26 | - block = self | |
| 27 | - s = show_name | |
| 28 | - proc do | |
| 29 | - render( | |
| 30 | - :file => 'blocks/profile_description', | |
| 31 | - :locals => { :block => block, :show_name => s , | |
| 32 | - :description => description} | |
| 33 | - ) | |
| 34 | - end | |
| 35 | - end | |
| 36 | - | |
| 37 | 19 | def cacheable? |
| 38 | 20 | false |
| 39 | 21 | end | ... | ... |
plugins/profile_description_block/test/unit/profile_description_block_test.rb
| 1 | 1 | require 'test_helper' |
| 2 | 2 | |
| 3 | 3 | class ProfileDescriptionBlockTest < ActiveSupport::TestCase |
| 4 | + should 'describe itself' do | |
| 5 | + assert_not_equal Block.description, ProfileDescriptionBlock.description | |
| 6 | + end | |
| 7 | +end | |
| 8 | + | |
| 9 | +require 'boxes_helper' | |
| 10 | + | |
| 11 | +class ProfileDescriptionBlockViewTest < ActionView::TestCase | |
| 12 | + include BoxesHelper | |
| 13 | + | |
| 4 | 14 | def setup |
| 5 | 15 | e = Environment.default |
| 6 | 16 | e.enabled_plugins = ['ProfileDescriptionPlugin'] |
| ... | ... | @@ -10,20 +20,20 @@ class ProfileDescriptionBlockTest < ActiveSupport::TestCase |
| 10 | 20 | :description => "") |
| 11 | 21 | end |
| 12 | 22 | |
| 13 | - should 'describe itself' do | |
| 14 | - assert_not_equal Block.description, ProfileDescriptionBlock.description | |
| 15 | - end | |
| 16 | - | |
| 17 | 23 | should "show profile description inside block" do |
| 18 | 24 | new_block = ProfileDescriptionBlock.create! |
| 25 | + | |
| 19 | 26 | @profile.boxes.first.blocks << new_block |
| 20 | - block_menssage = "Description field is empty" | |
| 21 | - assert (instance_eval(&Block.last.content).include?(block_menssage)), | |
| 27 | + | |
| 28 | + block_message = "Description field is empty" | |
| 29 | + assert (render_block_content(Block.last).include?(block_message)), | |
| 22 | 30 | "description block doesn't show not found description message" |
| 31 | + | |
| 23 | 32 | description = "This is an test" |
| 24 | 33 | @profile.update_attribute("description", description) |
| 25 | 34 | @profile.save! |
| 26 | - assert (instance_eval(&Block.last.content).include?(description)), | |
| 35 | + | |
| 36 | + assert (render_block_content(Block.last).include?(description)), | |
| 27 | 37 | "Description block doesn't show profile description" |
| 28 | 38 | end |
| 29 | 39 | end | ... | ... |
plugins/profile_description_block/views/blocks/profile_description.html.erb
| 1 | 1 | <div class = 'profile-description-block'> |
| 2 | -<div class = "block-title"> | |
| 3 | - <%= block.title %> | |
| 4 | -</div> | |
| 5 | -<div class = "profile-description-block-title"> | |
| 6 | - <%= description %> | |
| 7 | -</div> | |
| 2 | + <div class = "block-title"> | |
| 3 | + <%= block.title %> | |
| 4 | + </div> | |
| 5 | + | |
| 6 | + <div class = "profile-description-block-title"> | |
| 7 | + <% if block.owner.description.blank? %> | |
| 8 | + Description field is empty or not enabled on enviroment | |
| 9 | + <% else %> | |
| 10 | + <%= block.owner.description %> | |
| 11 | + <% end %> | |
| 12 | + </div> | |
| 8 | 13 | </div> | ... | ... |
test/api/comments_test.rb
| ... | ... | @@ -87,4 +87,26 @@ class CommentsTest < ActiveSupport::TestCase |
| 87 | 87 | assert_not_nil comment.source |
| 88 | 88 | end |
| 89 | 89 | |
| 90 | + should 'paginate comments' do | |
| 91 | + article = fast_create(Article, :profile_id => user.person.id, :name => "Some thing") | |
| 92 | + 5.times { article.comments.create!(:body => "some comment", :author => user.person) } | |
| 93 | + params[:per_page] = 3 | |
| 94 | + | |
| 95 | + get "/api/v1/articles/#{article.id}/comments?#{params.to_query}" | |
| 96 | + json = JSON.parse(last_response.body) | |
| 97 | + assert_equal 200, last_response.status | |
| 98 | + assert_equal 3, json["comments"].length | |
| 99 | + end | |
| 100 | + | |
| 101 | + should 'return only root comments' do | |
| 102 | + article = fast_create(Article, :profile_id => user.person.id, :name => "Some thing") | |
| 103 | + comment1 = article.comments.create!(:body => "some comment", :author => user.person) | |
| 104 | + comment2 = article.comments.create!(:body => "another comment", :author => user.person, :reply_of_id => comment1.id) | |
| 105 | + params[:without_reply] = true | |
| 106 | + | |
| 107 | + get "/api/v1/articles/#{article.id}/comments?#{params.to_query}" | |
| 108 | + json = JSON.parse(last_response.body) | |
| 109 | + assert_equal 200, last_response.status | |
| 110 | + assert_equal [comment1.id], json["comments"].map { |c| c['id'] } | |
| 111 | + end | |
| 90 | 112 | end | ... | ... |