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,11 +187,16 @@ module Noosfero | ||
187 | end | 187 | end |
188 | end | 188 | end |
189 | 189 | ||
190 | - class Comment < Entity | ||
191 | - root 'comments', 'comment' | 190 | + class CommentBase < Entity |
192 | expose :body, :title, :id | 191 | expose :body, :title, :id |
193 | expose :created_at, :format_with => :timestamp | 192 | expose :created_at, :format_with => :timestamp |
194 | expose :author, :using => Profile | 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 | end | 200 | end |
196 | 201 | ||
197 | class User < Entity | 202 | class User < Entity |
lib/noosfero/api/v1/comments.rb
@@ -2,9 +2,12 @@ module Noosfero | @@ -2,9 +2,12 @@ module Noosfero | ||
2 | module API | 2 | module API |
3 | module V1 | 3 | module V1 |
4 | class Comments < Grape::API | 4 | class Comments < Grape::API |
5 | + MAX_PER_PAGE = 20 | ||
6 | + | ||
5 | before { authenticate! } | 7 | before { authenticate! } |
6 | 8 | ||
7 | resource :articles do | 9 | resource :articles do |
10 | + paginate max_per_page: MAX_PER_PAGE | ||
8 | # Collect comments from articles | 11 | # Collect comments from articles |
9 | # | 12 | # |
10 | # Parameters: | 13 | # Parameters: |
@@ -17,7 +20,7 @@ module Noosfero | @@ -17,7 +20,7 @@ module Noosfero | ||
17 | get ":id/comments" do | 20 | get ":id/comments" do |
18 | article = find_article(environment.articles, params[:id]) | 21 | article = find_article(environment.articles, params[:id]) |
19 | comments = select_filtered_collection_of(article, :comments, params) | 22 | comments = select_filtered_collection_of(article, :comments, params) |
20 | - | 23 | + comments = comments.without_reply if(params[:without_reply].present?) |
21 | present comments, :with => Entities::Comment, :current_person => current_person | 24 | present comments, :with => Entities::Comment, :current_person => current_person |
22 | end | 25 | end |
23 | 26 |
plugins/gallery_block/lib/gallery_block.rb
@@ -30,12 +30,4 @@ class GalleryBlock < Block | @@ -30,12 +30,4 @@ class GalleryBlock < Block | ||
30 | def images | 30 | def images |
31 | gallery ? gallery.images : [] | 31 | gallery ? gallery.images : [] |
32 | end | 32 | end |
33 | - | ||
34 | - def content(args={}) | ||
35 | - block = self | ||
36 | - proc do | ||
37 | - render :file => 'gallery_block', :locals => { :block => block } | ||
38 | - end | ||
39 | - end | ||
40 | - | ||
41 | end | 33 | end |
plugins/gallery_block/test/unit/gallery_block_test.rb
@@ -20,3 +20,38 @@ class GalleryBlockTest < ActiveSupport::TestCase | @@ -20,3 +20,38 @@ class GalleryBlockTest < ActiveSupport::TestCase | ||
20 | end | 20 | end |
21 | 21 | ||
22 | end | 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 @@ | @@ -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,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,24 +16,6 @@ class ProfileDescriptionBlock < Block | ||
16 | _('PROFILE DESCRIPTION') | 16 | _('PROFILE DESCRIPTION') |
17 | end | 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 | def cacheable? | 19 | def cacheable? |
38 | false | 20 | false |
39 | end | 21 | end |
plugins/profile_description_block/test/unit/profile_description_block_test.rb
1 | require 'test_helper' | 1 | require 'test_helper' |
2 | 2 | ||
3 | class ProfileDescriptionBlockTest < ActiveSupport::TestCase | 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 | def setup | 14 | def setup |
5 | e = Environment.default | 15 | e = Environment.default |
6 | e.enabled_plugins = ['ProfileDescriptionPlugin'] | 16 | e.enabled_plugins = ['ProfileDescriptionPlugin'] |
@@ -10,20 +20,20 @@ class ProfileDescriptionBlockTest < ActiveSupport::TestCase | @@ -10,20 +20,20 @@ class ProfileDescriptionBlockTest < ActiveSupport::TestCase | ||
10 | :description => "") | 20 | :description => "") |
11 | end | 21 | end |
12 | 22 | ||
13 | - should 'describe itself' do | ||
14 | - assert_not_equal Block.description, ProfileDescriptionBlock.description | ||
15 | - end | ||
16 | - | ||
17 | should "show profile description inside block" do | 23 | should "show profile description inside block" do |
18 | new_block = ProfileDescriptionBlock.create! | 24 | new_block = ProfileDescriptionBlock.create! |
25 | + | ||
19 | @profile.boxes.first.blocks << new_block | 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 | "description block doesn't show not found description message" | 30 | "description block doesn't show not found description message" |
31 | + | ||
23 | description = "This is an test" | 32 | description = "This is an test" |
24 | @profile.update_attribute("description", description) | 33 | @profile.update_attribute("description", description) |
25 | @profile.save! | 34 | @profile.save! |
26 | - assert (instance_eval(&Block.last.content).include?(description)), | 35 | + |
36 | + assert (render_block_content(Block.last).include?(description)), | ||
27 | "Description block doesn't show profile description" | 37 | "Description block doesn't show profile description" |
28 | end | 38 | end |
29 | end | 39 | end |
plugins/profile_description_block/views/blocks/profile_description.html.erb
1 | <div class = 'profile-description-block'> | 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 | </div> | 13 | </div> |
test/api/comments_test.rb
@@ -87,4 +87,26 @@ class CommentsTest < ActiveSupport::TestCase | @@ -87,4 +87,26 @@ class CommentsTest < ActiveSupport::TestCase | ||
87 | assert_not_nil comment.source | 87 | assert_not_nil comment.source |
88 | end | 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 | end | 112 | end |