Commit 64e4639c91da8a2beadf7639f95357b1db1f3e97

Authored by Rodrigo Souto
Committed by Joenio Costa
1 parent d839a4de

Blog paginate only with the available post for the user

  * Posts unavailable for the user weren't displayed but were
    considered on pagination.

(ActionItem1557)
app/controllers/public/content_viewer_controller.rb
@@ -81,7 +81,13 @@ class ContentViewerController < ApplicationController @@ -81,7 +81,13 @@ class ContentViewerController < ApplicationController
81 end 81 end
82 82
83 if @page.blog? 83 if @page.blog?
84 - @page.filter = {:year => params[:year], :month => params[:month]} 84 + posts = if params[:year] and params[:month]
  85 + filter_date = DateTime.parse("#{params[:year]}-#{params[:month]}-01")
  86 + @page.posts.by_range(filter_date..Article.last_day_of_month(filter_date))
  87 + else
  88 + @page.posts
  89 + end
  90 + @posts = available_articles(posts, user).paginate :page => params[:npage], :per_page => @page.posts_per_page
85 end 91 end
86 92
87 if @page.folder? && @page.view_as == 'image_gallery' 93 if @page.folder? && @page.view_as == 'image_gallery'
app/helpers/blog_helper.rb
@@ -14,7 +14,7 @@ module BlogHelper @@ -14,7 +14,7 @@ module BlogHelper
14 _('Edit blog') 14 _('Edit blog')
15 end 15 end
16 16
17 - def list_posts(user, articles, format = 'full') 17 + def list_posts(articles, format = 'full')
18 pagination = will_paginate(articles, { 18 pagination = will_paginate(articles, {
19 :param_name => 'npage', 19 :param_name => 'npage',
20 :prev_label => _('« Newer posts'), 20 :prev_label => _('« Newer posts'),
@@ -25,18 +25,16 @@ module BlogHelper @@ -25,18 +25,16 @@ module BlogHelper
25 articles.each_with_index{ |art,i| 25 articles.each_with_index{ |art,i|
26 css_add = [ 'position-'+(i+1).to_s() ] 26 css_add = [ 'position-'+(i+1).to_s() ]
27 position = (i%2 == 0) ? 'odd-post' : 'even-post' 27 position = (i%2 == 0) ? 'odd-post' : 'even-post'
28 - if art.published? || (user==art.profile)  
29 - css_add << 'first' if i == 0  
30 - css_add << 'last' if i == (artic_len-1)  
31 - css_add << 'not-published' if !art.published?  
32 - css_add << position + '-inner'  
33 - content << content_tag('div',  
34 - content_tag('div',  
35 - display_post(art, format) + '<br style="clear:both"/>',  
36 - :class => 'blog-post ' + css_add.join(' '),  
37 - :id => "post-#{art.id}"), :class => position  
38 - )  
39 - end 28 + css_add << 'first' if i == 0
  29 + css_add << 'last' if i == (artic_len-1)
  30 + css_add << 'not-published' if !art.published?
  31 + css_add << position + '-inner'
  32 + content << content_tag('div',
  33 + content_tag('div',
  34 + display_post(art, format) + '<br style="clear:both"/>',
  35 + :class => 'blog-post ' + css_add.join(' '),
  36 + :id => "post-#{art.id}"), :class => position
  37 + )
40 } 38 }
41 content.join("\n<hr class='sep-posts'/>\n") + (pagination or '') 39 content.join("\n<hr class='sep-posts'/>\n") + (pagination or '')
42 end 40 end
app/models/article.rb
@@ -32,6 +32,23 @@ class Article &lt; ActiveRecord::Base @@ -32,6 +32,23 @@ class Article &lt; ActiveRecord::Base
32 {:include => 'categories', :conditions => { 'categories.id' => category.id }} 32 {:include => 'categories', :conditions => { 'categories.id' => category.id }}
33 } 33 }
34 34
  35 + named_scope :by_range, lambda { |range| {
  36 + :conditions => [
  37 + 'published_at BETWEEN :start_date AND :end_date', { :start_date => range.first, :end_date => range.last }
  38 + ]
  39 + }}
  40 +
  41 + def self.first_day_of_month(date)
  42 + date ||= Date.today
  43 + Date.new(date.year, date.month, 1)
  44 + end
  45 +
  46 + def self.last_day_of_month(date)
  47 + date ||= Date.today
  48 + date >>= 1
  49 + Date.new(date.year, date.month, 1) - 1.day
  50 + end
  51 +
35 URL_FORMAT = /\A(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?\Z/ix 52 URL_FORMAT = /\A(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?\Z/ix
36 53
37 validates_format_of :external_link, :with => URL_FORMAT, :if => lambda { |article| !article.external_link.blank? } 54 validates_format_of :external_link, :with => URL_FORMAT, :if => lambda { |article| !article.external_link.blank? }
app/models/blog.rb
@@ -3,7 +3,6 @@ class Blog &lt; Folder @@ -3,7 +3,6 @@ class Blog &lt; Folder
3 has_many :posts, :class_name => 'Article', :foreign_key => 'parent_id', :source => :children, :conditions => [ 'type != ?', 'RssFeed' ], :order => 'published_at DESC, id DESC' 3 has_many :posts, :class_name => 'Article', :foreign_key => 'parent_id', :source => :children, :conditions => [ 'type != ?', 'RssFeed' ], :order => 'published_at DESC, id DESC'
4 4
5 attr_accessor :feed_attrs 5 attr_accessor :feed_attrs
6 - attr_accessor :filter  
7 6
8 after_create do |blog| 7 after_create do |blog|
9 blog.children << RssFeed.new(:name => 'feed', :profile => blog.profile) 8 blog.children << RssFeed.new(:name => 'feed', :profile => blog.profile)
@@ -23,7 +22,9 @@ class Blog &lt; Folder @@ -23,7 +22,9 @@ class Blog &lt; Folder
23 # FIXME isn't this too much including just to be able to generate some HTML? 22 # FIXME isn't this too much including just to be able to generate some HTML?
24 include ActionView::Helpers::TagHelper 23 include ActionView::Helpers::TagHelper
25 def to_html(options = {}) 24 def to_html(options = {})
26 - posts_list(options[:page]) 25 + lambda do
  26 + render :file => 'content_viewer/blog_page'
  27 + end
27 end 28 end
28 29
29 def folder? 30 def folder?
@@ -49,19 +50,6 @@ class Blog &lt; Folder @@ -49,19 +50,6 @@ class Blog &lt; Folder
49 self.feed 50 self.feed
50 end 51 end
51 52
52 - def posts_list(npage)  
53 - article = self  
54 - children = if filter and filter[:year] and filter[:month]  
55 - filter_date = DateTime.parse("#{filter[:year]}-#{filter[:month]}-01")  
56 - posts.paginate :page => npage, :per_page => posts_per_page, :conditions => [ 'published_at between ? and ?', filter_date, filter_date + 1.month - 1.day ]  
57 - else  
58 - posts.paginate :page => npage, :per_page => posts_per_page  
59 - end  
60 - lambda do  
61 - render :file => 'content_viewer/blog_page', :locals => {:article => article, :children => children}  
62 - end  
63 - end  
64 -  
65 has_one :external_feed, :foreign_key => 'blog_id', :dependent => :destroy 53 has_one :external_feed, :foreign_key => 'blog_id', :dependent => :destroy
66 54
67 attr_accessor :external_feed_data 55 attr_accessor :external_feed_data
app/models/event.rb
@@ -56,17 +56,6 @@ class Event &lt; Article @@ -56,17 +56,6 @@ class Event &lt; Article
56 first_day..last_day 56 first_day..last_day
57 end 57 end
58 58
59 - def self.first_day_of_month(date)  
60 - date ||= Date.today  
61 - Date.new(date.year, date.month, 1)  
62 - end  
63 -  
64 - def self.last_day_of_month(date)  
65 - date ||= Date.today  
66 - date >>= 1  
67 - Date.new(date.year, date.month, 1) - 1.day  
68 - end  
69 -  
70 def date_range 59 def date_range
71 start_date..(end_date||start_date) 60 start_date..(end_date||start_date)
72 end 61 end
app/views/content_viewer/blog_page.rhtml
1 -<% add_rss_feed_to_head(article.name, article.feed.url) if article.blog? && article.feed %> 1 +<% add_rss_feed_to_head(@page.name, @page.feed.url) if @page.blog? && @page.feed %>
2 2
3 -<%= content_tag('em', _('(external feed was not loaded yet)'), :id => 'external-feed-info', :class => 'metadata') if article.blog? && article.external_feed && article.external_feed.enabled && article.external_feed.fetched_at.nil? %> 3 +<%= content_tag('em', _('(external feed was not loaded yet)'), :id => 'external-feed-info', :class => 'metadata') if @page.blog? && @page.external_feed && @page.external_feed.enabled && @page.external_feed.fetched_at.nil? %>
4 4
5 <div> 5 <div>
6 - <%= link_to(image_tag('icons-mime/rss-feed.png'), article.feed.url, :class => 'blog-feed-link') if article.blog? && article.feed %> 6 + <%= link_to(image_tag('icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.blog? && @page.feed %>
7 <div class='blog-description'> 7 <div class='blog-description'>
8 - <%= article.body %> 8 + <%= @page.body %>
9 </div> 9 </div>
10 </div> 10 </div>
11 <hr class="pre-posts"/> 11 <hr class="pre-posts"/>
12 <div class="blog-posts"> 12 <div class="blog-posts">
13 - <%= (children.compact.empty? ? content_tag('em', _('(no posts)')) : list_posts(user, children, article.visualization_format)) %> 13 + <%= (@posts.compact.empty? ? content_tag('em', _('(no posts)')) : list_posts(@posts, @page.visualization_format)) %>
14 </div> 14 </div>
test/functional/content_viewer_controller_test.rb
@@ -603,10 +603,27 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase @@ -603,10 +603,27 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase
603 assert_response :missing 603 assert_response :missing
604 end 604 end
605 605
  606 + should 'list unpublished posts to owner with a different class' do
  607 + login_as('testinguser')
  608 + blog = Blog.create!(:name => 'A blog test', :profile => profile)
  609 + blog.posts << TextileArticle.create!(:name => 'Post', :profile => profile, :parent => blog, :published => false)
  610 +
  611 + get :view_page, :profile => profile.identifier, :page => [blog.path]
  612 + assert_tag :tag => 'div', :attributes => {:class => /not-published/}
  613 + end
  614 +
  615 + should 'not list unpublished posts to a not logged person' do
  616 + blog = Blog.create!(:name => 'A blog test', :profile => profile)
  617 + blog.posts << TextileArticle.create!(:name => 'Post', :profile => profile, :parent => blog, :published => false)
  618 +
  619 + get :view_page, :profile => profile.identifier, :page => [blog.path]
  620 + assert_no_tag :tag => 'a', :content => "Post"
  621 + end
  622 +
606 should 'display pagination links of blog' do 623 should 'display pagination links of blog' do
607 blog = Blog.create!(:name => 'A blog test', :profile => profile, :posts_per_page => 5) 624 blog = Blog.create!(:name => 'A blog test', :profile => profile, :posts_per_page => 5)
608 for n in 1..10 625 for n in 1..10
609 - blog.children << TextileArticle.create!(:name => "Post #{n}", :profile => profile, :parent => blog) 626 + blog.posts << TextileArticle.create!(:name => "Post #{n}", :profile => profile, :parent => blog)
610 end 627 end
611 assert_equal 10, blog.posts.size 628 assert_equal 10, blog.posts.size
612 629
@@ -614,11 +631,17 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase @@ -614,11 +631,17 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase
614 assert_tag :tag => 'a', :attributes => { :href => "/#{profile.identifier}/#{blog.path}?npage=2", :rel => 'next' } 631 assert_tag :tag => 'a', :attributes => { :href => "/#{profile.identifier}/#{blog.path}?npage=2", :rel => 'next' }
615 end 632 end
616 633
617 - should 'set year and month filter from URL params' do  
618 - profile.articles << Blog.new(:name => 'A blog test', :profile => profile)  
619 - year, month = profile.blog.created_at.year.to_s, '%02d' % profile.blog.created_at.month  
620 - get :view_page, :profile => profile.identifier, :page => [profile.blog.path], :year => year, :month => month  
621 - assert_equal({ :year => year.to_s, :month => month.to_s }, assigns(:page).filter) 634 + should 'display filtered posts' do
  635 + blog = Blog.create!(:name => 'A blog test', :profile => profile)
  636 + not_display_post = TextileArticle.new(:name => "Post 1", :profile => profile, :parent => blog)
  637 + display_post = TextileArticle.new(:name => "Post 2", :profile => profile, :parent => blog)
  638 +
  639 + not_display_post.update_attribute(:published_at, DateTime.parse('2009-09-10'))
  640 + display_post.update_attribute(:published_at, DateTime.parse('2010-09-10'))
  641 +
  642 + get :view_page, :profile => profile.identifier, :page => [blog.path], :year => 2010, :month => 9
  643 + assert_no_tag :tag => 'a', :content => "Post 1"
  644 + assert_tag :tag => 'a', :content => "Post 2"
622 end 645 end
623 646
624 should 'give link to create new article inside folder when view child of folder' do 647 should 'give link to create new article inside folder when view child of folder' do
test/unit/article_test.rb
@@ -873,4 +873,22 @@ class ArticleTest &lt; Test::Unit::TestCase @@ -873,4 +873,22 @@ class ArticleTest &lt; Test::Unit::TestCase
873 assert_no_match /[<>]/, article.name 873 assert_no_match /[<>]/, article.name
874 end 874 end
875 875
  876 + should 'found articles with published date between a range' do
  877 + start_date = DateTime.parse('2010-07-06')
  878 + end_date = DateTime.parse('2010-08-02')
  879 +
  880 + article_found1 = fast_create(Article, :published_at => start_date)
  881 + article_found2 = fast_create(Article, :published_at => end_date)
  882 + article_not_found = fast_create(Article, :published_at => end_date + 1.month)
  883 +
  884 + assert_includes Article.by_range(start_date..end_date), article_found1
  885 + assert_includes Article.by_range(start_date..end_date), article_found2
  886 + assert_not_includes Article.by_range(start_date..end_date), article_not_found
  887 + end
  888 +
  889 + should 'calculate first/end day of a month' do
  890 + assert_equal 1, Article.first_day_of_month(DateTime.parse('2010-07-06')).day
  891 + assert_equal 31, Article.last_day_of_month(DateTime.parse('2010-07-06')).day
  892 + end
  893 +
876 end 894 end
test/unit/blog_helper_test.rb
@@ -27,28 +27,7 @@ class BlogHelperTest &lt; Test::Unit::TestCase @@ -27,28 +27,7 @@ class BlogHelperTest &lt; Test::Unit::TestCase
27 expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", :class => 'blog-post position-1 first last odd-post-inner', :id => "post-#{published_post.id}").returns('POST') 27 expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", :class => 'blog-post position-1 first last odd-post-inner', :id => "post-#{published_post.id}").returns('POST')
28 expects(:content_tag).with('div', 'POST', {:class => 'odd-post'}).returns('RESULT') 28 expects(:content_tag).with('div', 'POST', {:class => 'odd-post'}).returns('RESULT')
29 29
30 - assert_equal 'RESULT', list_posts(profile, blog.posts)  
31 - end  
32 -  
33 - should 'list unpublished posts to owner with a different class' do  
34 - blog.children << unpublished_post = TextileArticle.create!(:name => 'Post', :profile => profile, :parent => blog, :published => false)  
35 -  
36 - expects(:display_post).with(anything, anything).returns('POST')  
37 - expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", :class => 'blog-post position-1 first last not-published odd-post-inner', :id => "post-#{unpublished_post.id}").returns('POST')  
38 - expects(:content_tag).with('div', 'POST', {:class => 'odd-post'}).returns('RESULT')  
39 - assert_equal 'RESULT', list_posts(profile, blog.posts)  
40 - end  
41 -  
42 - should 'not list unpublished posts to not owner' do  
43 - blog.children << unpublished_post = TextileArticle.create!(:name => 'First post', :profile => profile, :parent => blog, :published => false)  
44 -  
45 - blog.children << published_post = TextileArticle.create!(:name => 'Second post', :profile => profile, :parent => blog, :published => true)  
46 -  
47 - expects(:display_post).with(anything, anything).returns('POST')  
48 - expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", has_entries(:id => "post-#{unpublished_post.id}")).never  
49 - expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", has_entries(:id => "post-#{published_post.id}")).returns('POST')  
50 - expects(:content_tag).with('div', 'POST', {:class => 'odd-post'}).returns('RESULT')  
51 - assert_equal 'RESULT', list_posts(nil, blog.posts) 30 + assert_equal 'RESULT', list_posts(blog.posts)
52 end 31 end
53 32
54 should 'list even/odd posts with a different class' do 33 should 'list even/odd posts with a different class' do
@@ -64,7 +43,7 @@ class BlogHelperTest &lt; Test::Unit::TestCase @@ -64,7 +43,7 @@ class BlogHelperTest &lt; Test::Unit::TestCase
64 expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", :class => 'blog-post position-2 last even-post-inner', :id => "post-#{older_post.id}").returns('POST 2') 43 expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", :class => 'blog-post position-2 last even-post-inner', :id => "post-#{older_post.id}").returns('POST 2')
65 expects(:content_tag).with('div', "POST 2", :class => 'even-post').returns('EVEN-POST') 44 expects(:content_tag).with('div', "POST 2", :class => 'even-post').returns('EVEN-POST')
66 45
67 - assert_equal "ODD-POST\n<hr class='sep-posts'/>\nEVEN-POST", list_posts(nil, blog.posts) 46 + assert_equal "ODD-POST\n<hr class='sep-posts'/>\nEVEN-POST", list_posts(blog.posts)
68 end 47 end
69 48
70 49
test/unit/blog_test.rb
@@ -82,13 +82,6 @@ class BlogTest &lt; ActiveSupport::TestCase @@ -82,13 +82,6 @@ class BlogTest &lt; ActiveSupport::TestCase
82 assert_equal [newer, older], blog.posts 82 assert_equal [newer, older], blog.posts
83 end 83 end
84 84
85 - should 'has filter' do  
86 - p = create_user('testuser').person  
87 - blog = Blog.create!(:profile => p, :name => 'Blog test')  
88 - blog.filter = {:param => 'value'}  
89 - assert_equal 'value', blog.filter[:param]  
90 - end  
91 -  
92 should 'has one external feed' do 85 should 'has one external feed' do
93 p = create_user('testuser').person 86 p = create_user('testuser').person
94 blog = Blog.create!(:profile => p, :name => 'Blog test') 87 blog = Blog.create!(:profile => p, :name => 'Blog test')
test/unit/content_viewer_helper_test.rb
@@ -57,32 +57,10 @@ class ContentViewerHelperTest &lt; Test::Unit::TestCase @@ -57,32 +57,10 @@ class ContentViewerHelperTest &lt; Test::Unit::TestCase
57 should 'not list feed article' do 57 should 'not list feed article' do
58 profile.articles << Blog.new(:name => 'Blog test', :profile => profile) 58 profile.articles << Blog.new(:name => 'Blog test', :profile => profile)
59 assert_includes profile.blog.children.map{|i| i.class}, RssFeed 59 assert_includes profile.blog.children.map{|i| i.class}, RssFeed
60 - result = list_posts(nil, profile.blog.posts) 60 + result = list_posts(profile.blog.posts)
61 assert_no_match /feed/, result 61 assert_no_match /feed/, result
62 end 62 end
63 63
64 - should 'filter blog posts by date' do  
65 - blog = Blog.create!(:name => 'Blog test', :profile => profile)  
66 -  
67 - nov = TextileArticle.create!(:name => 'November post', :parent => blog, :profile => profile)  
68 - nov.update_attributes!(:published_at => DateTime.parse('2008-11-15'))  
69 -  
70 - sep = TextileArticle.create!(:name => 'September post', :parent => blog, :profile => profile)  
71 - sep.update_attribute(:published_at, DateTime.parse('2008-09-10'))  
72 -  
73 - blog.reload  
74 - blog.filter = {:year => 2008, :month => 11}  
75 - assert blog.save!  
76 -  
77 - self.stubs(:params).returns({:npage => nil})  
78 -  
79 - expects(:render).with(:file => 'content_viewer/blog_page', :locals => {:article => blog, :children => [nov]}).returns("BLI")  
80 -  
81 - result = article_to_html(blog)  
82 -  
83 - assert_equal 'BLI', result  
84 - end  
85 -  
86 end 64 end
87 65
88 def show_date(date) 66 def show_date(date)