Commit 4d602b805c023b2cb0bf989f775b0e31e4210a33

Authored by Joenio Costa
1 parent 28dd8dad

ActionItem806: Squashed commit of the following:

    block to list amount of posts by month
    offer BlogArchivesBlock only if profile has blog
    pagination
    save feed options after create blog
    the settings of feeds must be editable trhough it's parent blog
    not offer to create sub-folder to blog
    the title of the post and the comments count are links to the specific article
    display count of blog-post comments
    users cant create more then one blog
app/controllers/my_profile/cms_controller.rb
@@ -20,22 +20,34 @@ class CmsController < MyProfileController @@ -20,22 +20,34 @@ class CmsController < MyProfileController
20 20
21 def available_article_types 21 def available_article_types
22 articles = [ 22 articles = [
23 - Folder,  
24 TinyMceArticle, 23 TinyMceArticle,
25 TextileArticle, 24 TextileArticle,
26 - RssFeed,  
27 UploadedFile, 25 UploadedFile,
28 Event 26 Event
29 ] 27 ]
  28 + parent_id = params ? params[:parent_id] : nil
  29 + if !parent_id or !Article.find(parent_id).blog?
  30 + articles += [
  31 + Folder,
  32 + RssFeed
  33 + ]
  34 + end
30 if profile.enterprise? 35 if profile.enterprise?
31 articles << EnterpriseHomepage 36 articles << EnterpriseHomepage
32 end 37 end
33 articles 38 articles
34 end 39 end
35 40
  41 + def special_article_types
  42 + [Blog]
  43 + end
  44 +
36 def view 45 def view
37 @article = profile.articles.find(params[:id]) 46 @article = profile.articles.find(params[:id])
38 @subitems = @article.children.reject {|item| item.folder? } 47 @subitems = @article.children.reject {|item| item.folder? }
  48 + if @article.blog?
  49 + @subitems.reject! {|item| item.class == RssFeed }
  50 + end
39 @folders = @article.children.select {|item| item.folder? } 51 @folders = @article.children.select {|item| item.folder? }
40 end 52 end
41 53
@@ -80,7 +92,7 @@ class CmsController &lt; MyProfileController @@ -80,7 +92,7 @@ class CmsController &lt; MyProfileController
80 return 92 return
81 end 93 end
82 94
83 - raise "Invalid article type #{@type}" unless available_article_types.map {|item| item.name}.include?(@type) 95 + raise "Invalid article type #{@type}" unless valid_article_type?(@type)
84 klass = @type.constantize 96 klass = @type.constantize
85 @article = klass.new(params[:article]) 97 @article = klass.new(params[:article])
86 98
@@ -192,5 +204,9 @@ class CmsController &lt; MyProfileController @@ -192,5 +204,9 @@ class CmsController &lt; MyProfileController
192 [url, url.sub('https:', 'http:')] 204 [url, url.sub('https:', 'http:')]
193 end 205 end
194 206
  207 + def valid_article_type?(type)
  208 + (available_article_types + special_article_types).map {|item| item.name}.include?(type)
  209 + end
  210 +
195 end 211 end
196 212
app/controllers/my_profile/profile_design_controller.rb
@@ -29,6 +29,11 @@ class ProfileDesignController &lt; BoxOrganizerController @@ -29,6 +29,11 @@ class ProfileDesignController &lt; BoxOrganizerController
29 blocks << ProductsBlock 29 blocks << ProductsBlock
30 end 30 end
31 31
  32 + # block exclusive to profile has blog
  33 + if profile.has_blog?
  34 + blocks << BlogArchivesBlock
  35 + end
  36 +
32 blocks 37 blocks
33 end 38 end
34 39
app/controllers/public/content_viewer_controller.rb
@@ -14,6 +14,10 @@ class ContentViewerController &lt; ApplicationController @@ -14,6 +14,10 @@ class ContentViewerController &lt; ApplicationController
14 return 14 return
15 end 15 end
16 else 16 else
  17 + path.gsub!(/\/(\d{4})\/(\d{2})\Z/, '')
  18 + year = $1
  19 + month = $2
  20 +
17 @page = profile.articles.find_by_path(path) 21 @page = profile.articles.find_by_path(path)
18 unless @page 22 unless @page
19 page_from_old_path = profile.articles.find_by_old_path(path) 23 page_from_old_path = profile.articles.find_by_old_path(path)
@@ -66,6 +70,10 @@ class ContentViewerController &lt; ApplicationController @@ -66,6 +70,10 @@ class ContentViewerController &lt; ApplicationController
66 remove_comment 70 remove_comment
67 end 71 end
68 72
  73 + if @page.blog?
  74 + @page.filter = {:year => year, :month => month}
  75 + end
  76 +
69 @comments = @page.comments(true) 77 @comments = @page.comments(true)
70 end 78 end
71 79
app/helpers/article_helper.rb 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +module ArticleHelper
  2 +
  3 + def custom_options_for_article(article)
  4 + @article = article
  5 + content_tag('h4', _('Options')) +
  6 + content_tag('div',
  7 + check_box(:article, :published) +
  8 + content_tag('label', _('Published'), :for => 'article_published') +
  9 + check_box(:article, :accept_comments) +
  10 + content_tag('label', _('Accept Comments'), :for => 'article_accept_comments')
  11 + )
  12 + end
  13 +
  14 +end
app/helpers/blog_helper.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +module BlogHelper
  2 +
  3 + def custom_options_for_article(article)
  4 + @article = article
  5 + hidden_field_tag('article[published]', 1) +
  6 + hidden_field_tag('article[accept_comments]', 0)
  7 + end
  8 +
  9 +end
app/helpers/cms_helper.rb
@@ -11,4 +11,16 @@ module CmsHelper @@ -11,4 +11,16 @@ module CmsHelper
11 11
12 attr_reader :environment 12 attr_reader :environment
13 13
  14 + def options_for_article(article)
  15 + article_helper = ActionView::Base.new
  16 + article_helper.extend ArticleHelper
  17 + begin
  18 + class_name = article.class.name + 'Helper'
  19 + klass = class_name.constantize
  20 + article_helper.extend klass
  21 + rescue
  22 + end
  23 + article_helper.custom_options_for_article(article)
  24 + end
  25 +
14 end 26 end
app/helpers/content_viewer_helper.rb
1 module ContentViewerHelper 1 module ContentViewerHelper
  2 +
  3 + include GetText
  4 +
  5 + def number_of_comments(article)
  6 + n = article.comments.size
  7 + if n == 0
  8 + _('No comments yet')
  9 + else
  10 + n_('One comment', '%{comments} comments', n) % { :comments => n }
  11 + end
  12 + end
  13 +
  14 + def article_title(article, args = {})
  15 + title = content_tag('h1', article.title, :class => 'title')
  16 + if article.belongs_to_blog?
  17 + unless args[:no_link]
  18 + title = content_tag('h3', link_to(article.name, article.url), :class => 'title')
  19 + end
  20 + title << content_tag('span', _("%s, by %s" % [show_date(article.created_at), article.profile.name]), :class => 'created-at')
  21 + end
  22 + title
  23 + end
  24 +
  25 + def list_posts(articles)
  26 + pagination = will_paginate(articles, {
  27 + :param_name => 'npage',
  28 + :page_links => false,
  29 + :prev_label => _('Newer posts &raquo;'),
  30 + :next_label => _('&laquo; Older posts')
  31 + })
  32 + articles.map{ |i| content_tag('div', display_post(i), :class => 'blog-post', :id => "post-#{i.id}") }.join("\n") +
  33 + (pagination or '')
  34 + end
  35 +
  36 + def display_post(article)
  37 + article_title(article) + content_tag('p', article.to_html) +
  38 + content_tag('p', link_to( number_of_comments(article), article.url ), :class => 'metadata')
  39 + end
  40 +
  41 + def article_to_html(article)
  42 + if article.blog?
  43 + children = if article.filter and article.filter[:year] and article.filter[:month]
  44 + filter_date = DateTime.parse("#{article.filter[:year]}-#{article.filter[:month]}-01")
  45 + article.posts.paginate :page => params[:npage], :per_page => article.posts_per_page, :conditions => [ 'created_at between ? and ?', filter_date, filter_date + 1.month - 1.day ]
  46 + else
  47 + article.posts.paginate :page => params[:npage], :per_page => article.posts_per_page
  48 + end
  49 + article.to_html + (children.compact.empty? ? content_tag('em', _('(no posts)')) : list_posts(children))
  50 + else
  51 + article.to_html
  52 + end
  53 + end
  54 +
2 end 55 end
app/models/article.rb
@@ -147,6 +147,10 @@ class Article &lt; ActiveRecord::Base @@ -147,6 +147,10 @@ class Article &lt; ActiveRecord::Base
147 name 147 name
148 end 148 end
149 149
  150 + def belongs_to_blog?
  151 + self.parent and self.parent.blog?
  152 + end
  153 +
150 def url 154 def url
151 self.profile.url.merge(:page => path.split('/')) 155 self.profile.url.merge(:page => path.split('/'))
152 end 156 end
@@ -159,6 +163,10 @@ class Article &lt; ActiveRecord::Base @@ -159,6 +163,10 @@ class Article &lt; ActiveRecord::Base
159 false 163 false
160 end 164 end
161 165
  166 + def blog?
  167 + false
  168 + end
  169 +
162 def display_to?(user) 170 def display_to?(user)
163 if self.public_article 171 if self.public_article
164 self.profile.display_info_to?(user) 172 self.profile.display_info_to?(user)
app/models/blog.rb 0 → 100644
@@ -0,0 +1,54 @@ @@ -0,0 +1,54 @@
  1 +class Blog < Folder
  2 +
  3 + has_many :posts, :class_name => 'Article', :foreign_key => 'parent_id', :source => :children, :conditions => [ 'type != ?', 'RssFeed' ], :order => 'created_at DESC'
  4 +
  5 + attr_accessor :feed_attrs
  6 + attr_accessor :filter
  7 +
  8 + after_create do |blog|
  9 + blog.children << RssFeed.new(:name => 'feed', :profile => blog.profile, :include => 'parent_and_children')
  10 + blog.feed = blog.feed_attrs
  11 + end
  12 +
  13 + settings_items :posts_per_page, :type => :integer, :default => 20
  14 + settings_items :title, :type => :string, :default => _('My blog')
  15 +
  16 + before_save do |blog|
  17 + blog.name = 'blog'
  18 + end
  19 +
  20 + def self.short_description
  21 + _('Blog')
  22 + end
  23 +
  24 + def self.description
  25 + _('A blog, inside which you can put other articles.')
  26 + end
  27 +
  28 + # FIXME isn't this too much including just to be able to generate some HTML?
  29 + include ActionView::Helpers::TagHelper
  30 + def to_html
  31 + content_tag('div', body) + tag('hr')
  32 + end
  33 +
  34 + def folder?
  35 + true
  36 + end
  37 +
  38 + def blog?
  39 + true
  40 + end
  41 +
  42 + def feed
  43 + self.children.find(:first, :conditions => {:type => 'RssFeed'})
  44 + end
  45 +
  46 + def feed=(attrs)
  47 + if self.feed
  48 + self.feed.update_attributes(attrs)
  49 + else
  50 + self.feed_attrs = attrs
  51 + end
  52 + end
  53 +
  54 +end
app/models/blog_archives_block.rb 0 → 100644
@@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
  1 +class BlogArchivesBlock < Block
  2 +
  3 + include ActionView::Helpers::TagHelper
  4 + include ActionView::Helpers::UrlHelper
  5 + include ActionController::UrlWriter
  6 +
  7 + def self.description
  8 + _('List posts of your blog')
  9 + end
  10 +
  11 + def default_title
  12 + _('Blog posts')
  13 + end
  14 +
  15 + def content
  16 + return nil unless owner.has_blog?
  17 + results = ''
  18 + posts = owner.blog.posts
  19 + posts.group_by{|i| i.created_at.year}.each do |year, results_by_year|
  20 + results << content_tag('li', content_tag('strong', "#{year} (#{results_by_year.size})"))
  21 + results << "<ul class='#{year}-archive'>"
  22 + results_by_year.group_by{|i| [i.created_at.strftime("%m"), i.created_at.strftime("%B")]}.sort.each do |month, results_by_month|
  23 + results << content_tag('li', link_to("#{month[1]} (#{results_by_month.size})", owner.generate_url(:controller => 'content_viewer', :action => 'view_page', :page => [owner.blog.path, year, month[0]])))
  24 + end
  25 + results << "</ul>"
  26 + end
  27 + block_title(title) +
  28 + content_tag('ul', results, :class => 'blog-archives')
  29 + end
  30 +
  31 +end
app/models/folder.rb
1 class Folder < Article 1 class Folder < Article
2 2
  3 + acts_as_having_settings :field => :setting
  4 +
3 def self.short_description 5 def self.short_description
4 _('Folder') 6 _('Folder')
5 end 7 end
app/models/profile.rb
@@ -469,4 +469,14 @@ class Profile &lt; ActiveRecord::Base @@ -469,4 +469,14 @@ class Profile &lt; ActiveRecord::Base
469 LayoutTemplate.find(layout_template).number_of_boxes 469 LayoutTemplate.find(layout_template).number_of_boxes
470 end 470 end
471 471
  472 + def blog
  473 + if self.has_blog?
  474 + self.articles.find(:first, :conditions => {:type => 'Blog'})
  475 + end
  476 + end
  477 +
  478 + def has_blog?
  479 + !self.articles.count(:conditions => {:type => 'Blog'}).zero?
  480 + end
  481 +
472 end 482 end
app/views/cms/_blog.rhtml 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +<h3><%= _('My Blog') %></h3>
  2 +
  3 +<%= render :file => 'shared/tiny_mce' %>
  4 +
  5 +<%= f.text_field('title', :size => '64') %>
  6 +
  7 +<%= labelled_form_field(_('Description:'), text_area(:article, :body, :cols => 64)) %>
  8 +
  9 +<h4><%= _('Settings') %></h4>
  10 +
  11 +<%= f.text_field('posts_per_page') %>
  12 +
  13 +<h5><%= _('Feed options') %></h5>
  14 +
  15 +<% fields_for 'article[feed]', @article.feed do |feed| %>
  16 +
  17 +<%= labelled_form_field(_('Limit of articles'), feed.text_field(:limit)) %>
  18 +
  19 +<%= labelled_form_field(_('Use as item description:'), feed.select(:feed_item_description, [ [ _('Article abstract'), 'abstract'], [ _('Article body'), 'body']])) %>
  20 +
  21 +<% end %>
app/views/cms/edit.rhtml
@@ -24,13 +24,7 @@ @@ -24,13 +24,7 @@
24 <%= content_tag( 'small', _('Separate tags with commas') ) %> 24 <%= content_tag( 'small', _('Separate tags with commas') ) %>
25 25
26 <div id='edit-article-options'> 26 <div id='edit-article-options'>
27 - <h4><%= _('Options') %></h4>  
28 - <div>  
29 - <%= check_box :article, :published %>  
30 - <label for='article_published'><%= _('Published')%></label>  
31 - <%= check_box :article, :accept_comments %>  
32 - <label for='article_accept_comments'><%= _('Accept Comments')%></label>  
33 - </div> 27 + <%= options_for_article(@article) %>
34 </div> 28 </div>
35 29
36 <% button_bar do %> 30 <% button_bar do %>
app/views/cms/view.rhtml
@@ -13,7 +13,15 @@ @@ -13,7 +13,15 @@
13 13
14 <% button_bar(:style => 'margin-bottom: 1em;') do %> 14 <% button_bar(:style => 'margin-bottom: 1em;') do %>
15 <% parent_id = ((@article && @article.allow_children?) ? @article : nil) %> 15 <% parent_id = ((@article && @article.allow_children?) ? @article : nil) %>
16 - <%= button :add, _('New folder'), :action => 'new', :type => 'Folder', :parent_id => parent_id %> 16 + <% if profile.has_blog? %>
  17 + <%= button :edit, _('Edit blog'), :action => 'edit', :id => profile.blog.id %>
  18 + <% else %>
  19 + <%= button :add, _('Create blog'), :action => 'new', :type => 'Blog', :parent_id => parent_id %>
  20 + <% end %>
  21 +
  22 + <% if !@article or !@article.blog? %>
  23 + <%= button :add, _('New folder'), :action => 'new', :type => 'Folder', :parent_id => parent_id %>
  24 + <% end %>
17 <%= lightbox_button('new', _('New article'), :action => 'new', :parent_id => parent_id) %> 25 <%= lightbox_button('new', _('New article'), :action => 'new', :parent_id => parent_id) %>
18 <% end %> 26 <% end %>
19 27
app/views/content_viewer/view_page.rhtml
@@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
23 23
24 <div onmouseover="showArticleActions(true)" 24 <div onmouseover="showArticleActions(true)"
25 onmouseout="showArticleActions(false)"> 25 onmouseout="showArticleActions(false)">
26 - <h1><%= @page.title %></h1> 26 + <%= article_title(@page, :no_link => true) %>
27 <script type="text/javascript"> 27 <script type="text/javascript">
28 function showArticleActions( show ) { 28 function showArticleActions( show ) {
29 var act = $("article-actions"); 29 var act = $("article-actions");
@@ -65,7 +65,7 @@ @@ -65,7 +65,7 @@
65 <% end %> 65 <% end %>
66 66
67 <div class="article-body"> 67 <div class="article-body">
68 - <%= @page.to_html %> 68 + <%= article_to_html(@page) %>
69 <br style="clear:both" /> 69 <br style="clear:both" />
70 </div> <!-- end class="article-body" --> 70 </div> <!-- end class="article-body" -->
71 71
@@ -82,9 +82,8 @@ @@ -82,9 +82,8 @@
82 <i class="do-not-comment"><%= _('This article does not accept comments')%></i> 82 <i class="do-not-comment"><%= _('This article does not accept comments')%></i>
83 <% else %> 83 <% else %>
84 <h3 <%= 'class="no-comments-yet"' if @comments.size == 0 %>> 84 <h3 <%= 'class="no-comments-yet"' if @comments.size == 0 %>>
85 - <%= @comments.size == 0 ? _('No comments yet') :  
86 - (n_('One comment', '%{comments} comments', @comments.size)) % { :comments => @comments.size}  
87 - %></h3> 85 + <%= number_of_comments(@page) %>
  86 + </h3>
88 <%= render :partial => 'comment', :collection => @comments %> 87 <%= render :partial => 'comment', :collection => @comments %>
89 <%= render :partial => 'comment_form' %> 88 <%= render :partial => 'comment_form' %>
90 <% end %> 89 <% end %>
db/migrate/056_add_data_to_articles.rb 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +class AddDataToArticles < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :articles, :setting, :text
  4 + add_column :article_versions, :setting, :text
  5 + end
  6 +
  7 + def self.down
  8 + remove_column :articles, :setting
  9 + remove_column :article_versions, :setting
  10 + end
  11 +end
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 # 9 #
10 # It's strongly recommended to check this file into your version control system. 10 # It's strongly recommended to check this file into your version control system.
11 11
12 -ActiveRecord::Schema.define(:version => 55) do 12 +ActiveRecord::Schema.define(:version => 56) do
13 13
14 create_table "article_versions", :force => true do |t| 14 create_table "article_versions", :force => true do |t|
15 t.integer "article_id" 15 t.integer "article_id"
@@ -39,6 +39,7 @@ ActiveRecord::Schema.define(:version =&gt; 55) do @@ -39,6 +39,7 @@ ActiveRecord::Schema.define(:version =&gt; 55) do
39 t.boolean "public_article", :default => true 39 t.boolean "public_article", :default => true
40 t.boolean "accept_comments", :default => true 40 t.boolean "accept_comments", :default => true
41 t.integer "reference_article_id" 41 t.integer "reference_article_id"
  42 + t.text "setting"
42 end 43 end
43 44
44 create_table "articles", :force => true do |t| 45 create_table "articles", :force => true do |t|
@@ -69,6 +70,7 @@ ActiveRecord::Schema.define(:version =&gt; 55) do @@ -69,6 +70,7 @@ ActiveRecord::Schema.define(:version =&gt; 55) do
69 t.boolean "public_article", :default => true 70 t.boolean "public_article", :default => true
70 t.boolean "accept_comments", :default => true 71 t.boolean "accept_comments", :default => true
71 t.integer "reference_article_id" 72 t.integer "reference_article_id"
  73 + t.text "setting"
72 end 74 end
73 75
74 create_table "articles_categories", :id => false, :force => true do |t| 76 create_table "articles_categories", :id => false, :force => true do |t|
public/stylesheets/article.css
@@ -165,3 +165,39 @@ @@ -165,3 +165,39 @@
165 border: none; 165 border: none;
166 } 166 }
167 167
  168 +/* * * Blog * * */
  169 +
  170 +.blog-post a {
  171 + text-decoration: none;
  172 +}
  173 +
  174 +#content .title {
  175 + margin-bottom: 2px;
  176 +}
  177 +
  178 +.blog-post .metadata {
  179 + display: block;
  180 + text-align: center;
  181 + font-size: small;
  182 +}
  183 +
  184 +#content .created-at {
  185 + color: gray;
  186 + font-size: small;
  187 + display: block;
  188 + text-align: right;
  189 +}
  190 +
  191 +#content .blog-post .created-at {
  192 + text-align: left;
  193 +}
  194 +
  195 +#content .pagination .prev_page {
  196 + position: absolute;
  197 + right: 0;
  198 +}
  199 +
  200 +#content .pagination .next_page {
  201 + position: absolute;
  202 + left: 0;
  203 +}
public/stylesheets/blocks/blog-archives-block.css 0 → 100644
@@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
  1 +#content .blog-archives-block {
  2 + padding: 10px 0px 10px 10px;
  3 +}
  4 +
  5 +.blog-archives-block ul {
  6 + margin: 0px;
  7 + padding: 0px 0px 0px 20px;
  8 +}
  9 +
  10 +.blog-archives-block li {
  11 + margin: 0px;
  12 + padding: 0px;
  13 +}
  14 +
  15 +.blog-archives-block a {
  16 + text-decoration: none;
  17 +}
test/functional/cms_controller_test.rb
@@ -630,4 +630,99 @@ class CmsControllerTest &lt; Test::Unit::TestCase @@ -630,4 +630,99 @@ class CmsControllerTest &lt; Test::Unit::TestCase
630 assert_no_tag :tag => 'div', :descendant => { :tag => 'h4', :content => 'Categorize your article' } 630 assert_no_tag :tag => 'div', :descendant => { :tag => 'h4', :content => 'Categorize your article' }
631 end 631 end
632 632
  633 + should 'offer to create a blog' do
  634 + get :index, :profile => profile.identifier
  635 + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/new?type=Blog"}
  636 + end
  637 +
  638 + should 'not display input name on create blog' do
  639 + get :new, :profile => profile.identifier, :type => 'Blog'
  640 + assert_no_tag :tag => 'input', :attributes => { :name => 'article[name]', :type => 'text' }
  641 + end
  642 +
  643 + should 'display posts per page input with default value on edit blog' do
  644 + get :new, :profile => profile.identifier, :type => 'Blog'
  645 + assert_tag :tag => 'input', :attributes => { :name => 'article[posts_per_page]', :type => 'text', :value => '20' }
  646 + end
  647 +
  648 + should 'not offer to create special article types' do
  649 + get :new, :profile => profile.identifier
  650 + assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/new?type=Blog"}
  651 + end
  652 +
  653 + should 'not offer to create a blog if user already have' do
  654 + profile.articles << Blog.new(:name => 'blog test')
  655 +
  656 + profile.articles.reload
  657 + assert profile.has_blog?
  658 +
  659 + get :index, :profile => profile.identifier
  660 + assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/new?type=Blog"}
  661 + end
  662 +
  663 + should 'offer to edit a blog' do
  664 + profile.articles << Blog.new(:name => 'blog test')
  665 +
  666 + profile.articles.reload
  667 + assert profile.has_blog?
  668 +
  669 + b = profile.blog
  670 + get :index, :profile => profile.identifier
  671 + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/edit/#{b.id}"}
  672 + end
  673 +
  674 + should 'not offer to add folder to blog' do
  675 + profile.articles << Blog.new(:name => 'blog test')
  676 +
  677 + profile.articles.reload
  678 + assert profile.has_blog?
  679 +
  680 + get :view, :profile => profile.identifier, :id => profile.blog.id
  681 + assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/new?parent_id=#{profile.blog.id}&amp;type=Folder"}
  682 + end
  683 +
  684 + should 'not show feed subitem for blog' do
  685 + profile.articles << Blog.new(:name => 'Blog for test')
  686 +
  687 + profile.articles.reload
  688 + assert profile.has_blog?
  689 +
  690 + get :view, :profile => profile.identifier, :id => profile.blog.id
  691 +
  692 + assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/edit/#{profile.blog.feed.id}" }
  693 + end
  694 +
  695 + should 'update feed options by edit blog form' do
  696 + profile.articles << Blog.new(:name => 'Blog for test')
  697 + post :edit, :profile => profile.identifier, :id => profile.blog.id, :article => { :feed => { :limit => 7 } }
  698 + assert_equal 7, profile.blog.feed.limit
  699 + end
  700 +
  701 + should 'not offer folder to blog articles' do
  702 + @controller.stubs(:profile).returns(Enterprise.new)
  703 + blog = Blog.create!(:name => 'Blog for test', :profile => profile)
  704 + @controller.stubs(:params).returns({ :parent_id => blog.id })
  705 +
  706 + assert_not_includes @controller.available_article_types, Folder
  707 + end
  708 +
  709 + should 'not offer rssfeed to blog articles' do
  710 + @controller.stubs(:profile).returns(Enterprise.new)
  711 + blog = Blog.create!(:name => 'Blog for test', :profile => profile)
  712 + @controller.stubs(:params).returns({ :parent_id => blog.id })
  713 +
  714 + assert_not_includes @controller.available_article_types, RssFeed
  715 + end
  716 +
  717 + should 'update blog posts_per_page setting' do
  718 + profile.articles << Blog.new(:name => 'Blog for test')
  719 + post :edit, :profile => profile.identifier, :id => profile.blog.id, :article => { :posts_per_page => 5 }
  720 + assert_equal 5, profile.blog.posts_per_page
  721 + end
  722 +
  723 + should 'display input title on create blog' do
  724 + get :new, :profile => profile.identifier, :type => 'Blog'
  725 + assert_tag :tag => 'input', :attributes => { :name => 'article[title]', :type => 'text' }
  726 + end
  727 +
633 end 728 end
test/functional/content_viewer_controller_test.rb
@@ -528,4 +528,22 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase @@ -528,4 +528,22 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase
528 assert_response :missing 528 assert_response :missing
529 end 529 end
530 530
  531 + should 'display pagination links of blog' do
  532 + blog = Blog.create!(:name => 'A blog test', :profile => profile, :posts_per_page => 5)
  533 + for n in 1..10
  534 + blog.children << TextileArticle.create!(:name => "Post #{n}", :profile => profile, :parent => blog)
  535 + end
  536 + assert_equal 10, blog.posts.size
  537 +
  538 + get :view_page, :profile => profile.identifier, :page => [blog.path]
  539 + assert_tag :tag => 'a', :attributes => { :href => "/#{profile.identifier}/#{blog.path}?npage=2", :rel => 'next' }
  540 + end
  541 +
  542 + should 'extract year and month from path' do
  543 + blog = Blog.create!(:name => 'A blog test', :profile => profile)
  544 + year, month = blog.created_at.year, blog.created_at.month
  545 + get :view_page, :profile => profile.identifier, :page => [blog.path, year, month]
  546 + assert_equal({ :year => year.to_s, :month => month.to_s }, assigns(:page).filter)
  547 + end
  548 +
531 end 549 end
test/functional/profile_design_controller_test.rb
@@ -269,5 +269,15 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase @@ -269,5 +269,15 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase
269 assert_tag :tag => 'a', :attributes => {:href => '/myprofile/test_profile'} 269 assert_tag :tag => 'a', :attributes => {:href => '/myprofile/test_profile'}
270 end 270 end
271 271
272 -end 272 + should 'offer to create blog archives block only if has blog' do
  273 + Blog.create!(:name => 'Blog test', :profile => holder)
  274 + get :add_block, :profile => 'designtestuser'
  275 + assert_tag :tag => 'input', :attributes => { :id => 'type_blogarchivesblock', :value => 'BlogArchivesBlock' }
  276 + end
273 277
  278 + should 'not offer to create blog archives block if user dont have blog' do
  279 + get :add_block, :profile => 'designtestuser'
  280 + assert_no_tag :tag => 'input', :attributes => { :id => 'type_blogarchivesblock', :value => 'BlogArchivesBlock' }
  281 + end
  282 +
  283 +end
test/unit/article_test.rb
@@ -263,6 +263,10 @@ class ArticleTest &lt; Test::Unit::TestCase @@ -263,6 +263,10 @@ class ArticleTest &lt; Test::Unit::TestCase
263 assert !Article.new.folder?, 'should identify itself as non-folder' 263 assert !Article.new.folder?, 'should identify itself as non-folder'
264 end 264 end
265 265
  266 + should 'identify itself as a non-blog' do
  267 + assert !Article.new.blog?, 'should identify itself as non-blog'
  268 + end
  269 +
266 should 'always display if public content' do 270 should 'always display if public content' do
267 person = create_user('testuser').person 271 person = create_user('testuser').person
268 assert_equal true, person.home_page.display_to?(nil) 272 assert_equal true, person.home_page.display_to?(nil)
@@ -544,4 +548,18 @@ class ArticleTest &lt; Test::Unit::TestCase @@ -544,4 +548,18 @@ class ArticleTest &lt; Test::Unit::TestCase
544 assert_nil page 548 assert_nil page
545 end 549 end
546 550
  551 + should 'identify if belongs to blog' do
  552 + p = create_user('user_blog_test').person
  553 + blog = Blog.create!(:name => 'Blog test', :profile => p)
  554 + post = TextileArticle.create!(:name => 'First post', :profile => p, :parent => blog)
  555 + assert post.belongs_to_blog?
  556 + end
  557 +
  558 + should 'not belongs to blog' do
  559 + p = create_user('user_blog_test').person
  560 + folder = Folder.create!(:name => 'Not Blog', :profile => p)
  561 + a = TextileArticle.create!(:name => 'Not blog post', :profile => p, :parent => folder)
  562 + assert !a.belongs_to_blog?
  563 + end
  564 +
547 end 565 end
test/unit/blog_archives_block_test.rb 0 → 100644
@@ -0,0 +1,68 @@ @@ -0,0 +1,68 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class BlogArchivesBlockTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @profile = create_user('flatline').person
  7 + @profile.articles << Blog.new(:name => 'blog', :profile => @profile)
  8 + end
  9 + attr_reader :profile
  10 +
  11 + should 'default describe' do
  12 + assert_not_equal Block.description, BlogArchivesBlock.description
  13 + end
  14 +
  15 + should 'is editable' do
  16 + l = BlogArchivesBlock.new
  17 + assert l.editable?
  18 + end
  19 +
  20 + should 'list amount posts by year' do
  21 + date = DateTime.parse('2008-01-01')
  22 + blog = profile.blog
  23 + for i in 1..10 do
  24 + post = TextileArticle.create!(:name => "post #{i} test", :profile => profile, :parent => blog)
  25 + post.update_attribute(:created_at, date)
  26 + end
  27 + block = BlogArchivesBlock.new
  28 + block.stubs(:owner).returns(profile)
  29 + assert_tag_in_string block.content, :tag => 'li', :content => '2008 (10)'
  30 + end
  31 +
  32 + should 'list amount posts by month' do
  33 + date = DateTime.parse('2008-01-01')
  34 + blog = profile.blog
  35 + for i in 1..10 do
  36 + post = TextileArticle.create!(:name => "post #{i} test", :profile => profile, :parent => blog)
  37 + post.update_attribute(:created_at, date)
  38 + end
  39 + block = BlogArchivesBlock.new
  40 + block.stubs(:owner).returns(profile)
  41 + assert_tag_in_string block.content, :tag => 'a', :content => 'January (10)', :attributes => {:href => /2008\/01/}
  42 + end
  43 +
  44 +
  45 + should 'order list of amount posts' do
  46 + blog = profile.blog
  47 + for i in 1..10 do
  48 + post = TextileArticle.create!(:name => "post #{i} test", :profile => profile, :parent => blog)
  49 + post.update_attribute(:created_at, DateTime.parse("2008-#{i}-01"))
  50 + end
  51 + block = BlogArchivesBlock.new
  52 + block.stubs(:owner).returns(profile)
  53 + assert_tag_in_string block.content, :tag => 'li', :content => 'January (1)',
  54 + :sibling => {:tag => 'li', :content => 'February (1)',
  55 + :sibling => {:tag => 'li', :content => 'March (1)',
  56 + :sibling => {:tag => 'li', :content => 'April (1)',
  57 + :sibling => {:tag => 'li', :content => 'May (1)'}}}}
  58 + end
  59 +
  60 + should 'not display any content if has no blog' do
  61 + profile.stubs(:has_blog?).returns(false)
  62 + assert !profile.has_blog?
  63 + block = BlogArchivesBlock.new
  64 + block.stubs(:owner).returns(profile)
  65 + assert_nil block.content
  66 + end
  67 +
  68 +end
test/unit/blog_helper_test.rb 0 → 100644
@@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class BlogHelperTest < Test::Unit::TestCase
  4 +
  5 + include BlogHelper
  6 +
  7 + def setup
  8 + stubs(:show_date).returns('')
  9 + @profile = create_user('blog_helper_test').person
  10 + end
  11 + attr :profile
  12 +
  13 + should 'add real tests' do
  14 + assert true
  15 + end
  16 +
  17 +end
test/unit/blog_test.rb 0 → 100644
@@ -0,0 +1,106 @@ @@ -0,0 +1,106 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class BlogTest < ActiveSupport::TestCase
  4 +
  5 + should 'be an article' do
  6 + assert_kind_of Article, Blog.new
  7 + end
  8 +
  9 + should 'provide proper description' do
  10 + assert_kind_of String, Blog.description
  11 + end
  12 +
  13 + should 'provide proper short description' do
  14 + assert_kind_of String, Blog.short_description
  15 + end
  16 +
  17 + should 'provide own icon name' do
  18 + assert_not_equal Article.new.icon_name, Blog.new.icon_name
  19 + end
  20 +
  21 + should 'identify as folder' do
  22 + assert Blog.new.folder?, 'blog must identity itself as folder'
  23 + end
  24 +
  25 + should 'identify as blog' do
  26 + assert Blog.new.blog?, 'blog must identity itself as blog'
  27 + end
  28 +
  29 + should 'create rss feed automatically' do
  30 + p = create_user('testuser').person
  31 + b = Blog.create!(:profile => p, :name => 'blog_feed_test')
  32 + assert_kind_of RssFeed, b.feed
  33 + end
  34 +
  35 + should 'get first blog from profile' do
  36 + p = create_user('testuser').person
  37 + b = Blog.create!(:profile => p, :name => 'blog_feed_test')
  38 + assert_equal p.blog, b
  39 + end
  40 +
  41 + should 'save feed options' do
  42 + p = create_user('testuser').person
  43 + b = Blog.create!(:profile => p, :name => 'blog_feed_test')
  44 + p.blog.feed = { :limit => 7 }
  45 + assert_equal 7, p.blog.feed.limit
  46 + end
  47 +
  48 + should 'includes only articles child of the same article on feed' do
  49 + p = create_user('testuser').person
  50 + b = Blog.create!(:profile => p, :name => 'blog_feed_test')
  51 + assert_equal 'parent_and_children', b.feed.include
  52 + end
  53 +
  54 + should 'save feed options after create blog' do
  55 + p = create_user('testuser').person
  56 + b = Blog.create!(:profile => p, :name => 'blog_feed_test', :feed => { :limit => 7 })
  57 +
  58 + p.blog.feed.reload
  59 + assert_equal 7, p.blog.feed.limit
  60 + end
  61 +
  62 + should 'list 20 posts per page by default' do
  63 + blog = Blog.new
  64 + assert_equal 20, blog.posts_per_page
  65 + end
  66 +
  67 + should 'update posts per page setting' do
  68 + p = create_user('testusermerda').person
  69 + blog = Blog.create!(:profile => p, :name => 'Blog test')
  70 + blog.reload
  71 + blog.posts_per_page = 5
  72 + assert blog.save!
  73 + assert_equal 5, blog.posts_per_page
  74 + end
  75 +
  76 + should 'has posts' do
  77 + p = create_user('testusermerda').person
  78 + blog = Blog.create!(:profile => p, :name => 'Blog test')
  79 + post = TextileArticle.create!(:name => 'First post', :profile => p, :parent => blog)
  80 + blog.children << post
  81 + assert_includes blog.posts, post
  82 + end
  83 +
  84 + should 'not includes rss feed in posts' do
  85 + p = create_user('testusermerda').person
  86 + blog = Blog.create!(:profile => p, :name => 'Blog test')
  87 + assert_includes blog.children, blog.feed
  88 + assert_not_includes blog.posts, blog.feed
  89 + end
  90 +
  91 + should 'list posts ordered by created at' do
  92 + p = create_user('testusermerda').person
  93 + blog = Blog.create!(:profile => p, :name => 'Blog test', :profile => p)
  94 + newer = TextileArticle.create!(:name => 'Post 2', :parent => blog, :profile => p)
  95 + older = TextileArticle.create!(:name => 'Post 1', :parent => blog, :profile => p, :created_at => Time.now - 1.month)
  96 + assert_equal [newer, older], blog.posts
  97 + end
  98 +
  99 + should 'has filter' do
  100 + p = create_user('testusermerda').person
  101 + blog = Blog.create!(:profile => p, :name => 'Blog test', :profile => p)
  102 + blog.filter = {:param => 'value'}
  103 + assert_equal 'value', blog.filter[:param]
  104 + end
  105 +
  106 +end
test/unit/cms_helper_test.rb 0 → 100644
@@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class CmsHelperTest < Test::Unit::TestCase
  4 +
  5 + include CmsHelper
  6 + include BlogHelper
  7 +
  8 + should 'show default options for article' do
  9 + result = options_for_article(RssFeed.new)
  10 + assert_match /id="article_published" name="article\[published\]" type="checkbox" value="1"/, result
  11 + assert_match /id="article_accept_comments" name="article\[accept_comments\]" type="checkbox" value="1"/, result
  12 + end
  13 +
  14 + should 'show custom options for blog' do
  15 + result = options_for_article(Blog.new)
  16 + assert_match /id="article\[published\]" name="article\[published\]" type="hidden" value="1"/, result
  17 + assert_match /id="article\[accept_comments\]" name="article\[accept_comments\]" type="hidden" value="0"/, result
  18 + end
  19 +
  20 +end
  21 +
  22 +module RssFeedHelper
  23 +end
test/unit/content_viewer_helper_test.rb 0 → 100644
@@ -0,0 +1,95 @@ @@ -0,0 +1,95 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class ContentViewerHelperTest < Test::Unit::TestCase
  4 +
  5 + include ActionView::Helpers::TagHelper
  6 + include ContentViewerHelper
  7 +
  8 + def setup
  9 + @profile = create_user('blog_helper_test').person
  10 + end
  11 + attr :profile
  12 +
  13 + should 'display created-at for blog posts' do
  14 + blog = Blog.create!(:name => 'Blog test', :profile => profile)
  15 + post = TextileArticle.create!(:name => 'post test', :profile => profile, :parent => blog)
  16 + result = article_title(post)
  17 + assert_match /#{post.created_at}, by #{profile.identifier}/, result
  18 + end
  19 +
  20 + should 'not display created-at for non-blog posts' do
  21 + article = TextileArticle.create!(:name => 'article for test', :profile => profile)
  22 + result = article_title(article)
  23 + assert_no_match /#{article.created_at}, by #{profile.identifier}/, result
  24 + end
  25 +
  26 + should 'create link on title of blog posts' do
  27 + blog = Blog.create!(:name => 'Blog test', :profile => profile)
  28 + post = TextileArticle.create!(:name => 'post test', :profile => profile, :parent => blog)
  29 + assert post.belongs_to_blog?
  30 + result = article_title(post)
  31 + assert_match /a href='#{post.url}'>#{post.name}</, result
  32 + end
  33 +
  34 + should 'not create link on title if pass no_link option' do
  35 + blog = Blog.create!(:name => 'Blog test', :profile => profile)
  36 + post = TextileArticle.create!(:name => 'post test', :profile => profile, :parent => blog)
  37 + result = article_title(post, :no_link => :true)
  38 + assert_no_match /a href='#{post.url}'>#{post.name}</, result
  39 + end
  40 +
  41 + should 'not create link on title if non-blog post' do
  42 + article = TextileArticle.create!(:name => 'art test', :profile => profile)
  43 + result = article_title(article)
  44 + assert_no_match /a href='#{article.url}'>#{article.name}</, result
  45 + end
  46 +
  47 + should 'count total of comments from post' do
  48 + article = TextileArticle.new(:name => 'first post for test', :body => 'first post for test', :profile => profile)
  49 + article.stubs(:url).returns('')
  50 + article.stubs(:comments).returns([Comment.new(:author => profile, :title => 'test', :body => 'test')])
  51 + result = display_post(article)
  52 + assert_match /One comment/, result
  53 + end
  54 +
  55 + should 'not list feed article' do
  56 + profile.articles << Blog.new(:name => 'Blog test')
  57 + assert_includes profile.blog.children.map{|i| i.class}, RssFeed
  58 + result = list_posts(profile.blog.posts)
  59 + assert_no_match /feed/, result
  60 + end
  61 +
  62 + should 'filter blog posts by date' do
  63 + blog = Blog.create!(:name => 'Blog test', :profile => profile)
  64 +
  65 + nov = TextileArticle.create!(:name => 'November post', :parent => blog, :profile => profile)
  66 + nov.update_attributes!(:created_at => DateTime.parse('2008-11-15'))
  67 +
  68 + sep = TextileArticle.create!(:name => 'September post', :parent => blog, :profile => profile)
  69 + sep.update_attribute(:created_at, DateTime.parse('2008-09-10'))
  70 +
  71 + blog.reload
  72 + blog.filter = {:year => 2008, :month => 11}
  73 + assert blog.save!
  74 +
  75 + self.stubs(:params).returns({:npage => nil})
  76 +
  77 + result = article_to_html(blog)
  78 +
  79 + assert_match /November post/, result
  80 + assert_no_match /September post/, result
  81 + end
  82 +
  83 +end
  84 +
  85 +def show_date(date)
  86 + date.to_s
  87 +end
  88 +def link_to(content, url)
  89 + "<a href='#{url}'>#{content}</a>"
  90 +end
  91 +def _(text)
  92 + text
  93 +end
  94 +def will_paginate(arg1, arg2)
  95 +end
test/unit/profile_test.rb
@@ -967,6 +967,28 @@ class ProfileTest &lt; Test::Unit::TestCase @@ -967,6 +967,28 @@ class ProfileTest &lt; Test::Unit::TestCase
967 assert_not_equal p1.environment, p2.environment 967 assert_not_equal p1.environment, p2.environment
968 end 968 end
969 969
  970 + should 'has blog' do
  971 + p = create_user('testuser').person
  972 + b = Blog.create!(:profile => p, :name => 'blog_feed_test')
  973 + assert p.has_blog?
  974 + end
  975 +
  976 + should 'not has blog' do
  977 + p = create_user('testuser').person
  978 + assert !p.has_blog?
  979 + end
  980 +
  981 + should 'get blog when has blog' do
  982 + p = create_user('testuser').person
  983 + b = Blog.create!(:profile => p, :name => 'blog_feed_test')
  984 + assert_equal b, p.blog
  985 + end
  986 +
  987 + should 'get nil when no blog' do
  988 + p = create_user('testuser').person
  989 + assert_nil p.blog
  990 + end
  991 +
970 private 992 private
971 993
972 def assert_invalid_identifier(id) 994 def assert_invalid_identifier(id)