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 81 end
82 82  
83 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 91 end
86 92  
87 93 if @page.folder? && @page.view_as == 'image_gallery'
... ...
app/helpers/blog_helper.rb
... ... @@ -14,7 +14,7 @@ module BlogHelper
14 14 _('Edit blog')
15 15 end
16 16  
17   - def list_posts(user, articles, format = 'full')
  17 + def list_posts(articles, format = 'full')
18 18 pagination = will_paginate(articles, {
19 19 :param_name => 'npage',
20 20 :prev_label => _('« Newer posts'),
... ... @@ -25,18 +25,16 @@ module BlogHelper
25 25 articles.each_with_index{ |art,i|
26 26 css_add = [ 'position-'+(i+1).to_s() ]
27 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 39 content.join("\n<hr class='sep-posts'/>\n") + (pagination or '')
42 40 end
... ...
app/models/article.rb
... ... @@ -32,6 +32,23 @@ class Article &lt; ActiveRecord::Base
32 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 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 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 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 5 attr_accessor :feed_attrs
6   - attr_accessor :filter
7 6  
8 7 after_create do |blog|
9 8 blog.children << RssFeed.new(:name => 'feed', :profile => blog.profile)
... ... @@ -23,7 +22,9 @@ class Blog &lt; Folder
23 22 # FIXME isn't this too much including just to be able to generate some HTML?
24 23 include ActionView::Helpers::TagHelper
25 24 def to_html(options = {})
26   - posts_list(options[:page])
  25 + lambda do
  26 + render :file => 'content_viewer/blog_page'
  27 + end
27 28 end
28 29  
29 30 def folder?
... ... @@ -49,19 +50,6 @@ class Blog &lt; Folder
49 50 self.feed
50 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 53 has_one :external_feed, :foreign_key => 'blog_id', :dependent => :destroy
66 54  
67 55 attr_accessor :external_feed_data
... ...
app/models/event.rb
... ... @@ -56,17 +56,6 @@ class Event &lt; Article
56 56 first_day..last_day
57 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 59 def date_range
71 60 start_date..(end_date||start_date)
72 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 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 7 <div class='blog-description'>
8   - <%= article.body %>
  8 + <%= @page.body %>
9 9 </div>
10 10 </div>
11 11 <hr class="pre-posts"/>
12 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 14 </div>
... ...
test/functional/content_viewer_controller_test.rb
... ... @@ -603,10 +603,27 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase
603 603 assert_response :missing
604 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 623 should 'display pagination links of blog' do
607 624 blog = Blog.create!(:name => 'A blog test', :profile => profile, :posts_per_page => 5)
608 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 627 end
611 628 assert_equal 10, blog.posts.size
612 629  
... ... @@ -614,11 +631,17 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase
614 631 assert_tag :tag => 'a', :attributes => { :href => "/#{profile.identifier}/#{blog.path}?npage=2", :rel => 'next' }
615 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 645 end
623 646  
624 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 873 assert_no_match /[<>]/, article.name
874 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 894 end
... ...
test/unit/blog_helper_test.rb
... ... @@ -27,28 +27,7 @@ class BlogHelperTest &lt; Test::Unit::TestCase
27 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 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 31 end
53 32  
54 33 should 'list even/odd posts with a different class' do
... ... @@ -64,7 +43,7 @@ class BlogHelperTest &lt; Test::Unit::TestCase
64 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 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 47 end
69 48  
70 49  
... ...
test/unit/blog_test.rb
... ... @@ -82,13 +82,6 @@ class BlogTest &lt; ActiveSupport::TestCase
82 82 assert_equal [newer, older], blog.posts
83 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 85 should 'has one external feed' do
93 86 p = create_user('testuser').person
94 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 57 should 'not list feed article' do
58 58 profile.articles << Blog.new(:name => 'Blog test', :profile => profile)
59 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 61 assert_no_match /feed/, result
62 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 64 end
87 65  
88 66 def show_date(date)
... ...