Commit 4d602b805c023b2cb0bf989f775b0e31e4210a33
1 parent
28dd8dad
Exists in
master
and in
29 other branches
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
Showing
30 changed files
with
800 additions
and
18 deletions
Show diff stats
app/controllers/my_profile/cms_controller.rb
... | ... | @@ -20,22 +20,34 @@ class CmsController < MyProfileController |
20 | 20 | |
21 | 21 | def available_article_types |
22 | 22 | articles = [ |
23 | - Folder, | |
24 | 23 | TinyMceArticle, |
25 | 24 | TextileArticle, |
26 | - RssFeed, | |
27 | 25 | UploadedFile, |
28 | 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 | 35 | if profile.enterprise? |
31 | 36 | articles << EnterpriseHomepage |
32 | 37 | end |
33 | 38 | articles |
34 | 39 | end |
35 | 40 | |
41 | + def special_article_types | |
42 | + [Blog] | |
43 | + end | |
44 | + | |
36 | 45 | def view |
37 | 46 | @article = profile.articles.find(params[:id]) |
38 | 47 | @subitems = @article.children.reject {|item| item.folder? } |
48 | + if @article.blog? | |
49 | + @subitems.reject! {|item| item.class == RssFeed } | |
50 | + end | |
39 | 51 | @folders = @article.children.select {|item| item.folder? } |
40 | 52 | end |
41 | 53 | |
... | ... | @@ -80,7 +92,7 @@ class CmsController < MyProfileController |
80 | 92 | return |
81 | 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 | 96 | klass = @type.constantize |
85 | 97 | @article = klass.new(params[:article]) |
86 | 98 | |
... | ... | @@ -192,5 +204,9 @@ class CmsController < MyProfileController |
192 | 204 | [url, url.sub('https:', 'http:')] |
193 | 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 | 211 | end |
196 | 212 | ... | ... |
app/controllers/my_profile/profile_design_controller.rb
app/controllers/public/content_viewer_controller.rb
... | ... | @@ -14,6 +14,10 @@ class ContentViewerController < ApplicationController |
14 | 14 | return |
15 | 15 | end |
16 | 16 | else |
17 | + path.gsub!(/\/(\d{4})\/(\d{2})\Z/, '') | |
18 | + year = $1 | |
19 | + month = $2 | |
20 | + | |
17 | 21 | @page = profile.articles.find_by_path(path) |
18 | 22 | unless @page |
19 | 23 | page_from_old_path = profile.articles.find_by_old_path(path) |
... | ... | @@ -66,6 +70,10 @@ class ContentViewerController < ApplicationController |
66 | 70 | remove_comment |
67 | 71 | end |
68 | 72 | |
73 | + if @page.blog? | |
74 | + @page.filter = {:year => year, :month => month} | |
75 | + end | |
76 | + | |
69 | 77 | @comments = @page.comments(true) |
70 | 78 | end |
71 | 79 | ... | ... |
... | ... | @@ -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/cms_helper.rb
... | ... | @@ -11,4 +11,16 @@ module CmsHelper |
11 | 11 | |
12 | 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 | 26 | end | ... | ... |
app/helpers/content_viewer_helper.rb
1 | 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 »'), | |
30 | + :next_label => _('« 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 | 55 | end | ... | ... |
app/models/article.rb
... | ... | @@ -147,6 +147,10 @@ class Article < ActiveRecord::Base |
147 | 147 | name |
148 | 148 | end |
149 | 149 | |
150 | + def belongs_to_blog? | |
151 | + self.parent and self.parent.blog? | |
152 | + end | |
153 | + | |
150 | 154 | def url |
151 | 155 | self.profile.url.merge(:page => path.split('/')) |
152 | 156 | end |
... | ... | @@ -159,6 +163,10 @@ class Article < ActiveRecord::Base |
159 | 163 | false |
160 | 164 | end |
161 | 165 | |
166 | + def blog? | |
167 | + false | |
168 | + end | |
169 | + | |
162 | 170 | def display_to?(user) |
163 | 171 | if self.public_article |
164 | 172 | self.profile.display_info_to?(user) | ... | ... |
... | ... | @@ -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 | ... | ... |
... | ... | @@ -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
app/models/profile.rb
... | ... | @@ -469,4 +469,14 @@ class Profile < ActiveRecord::Base |
469 | 469 | LayoutTemplate.find(layout_template).number_of_boxes |
470 | 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 | 482 | end | ... | ... |
... | ... | @@ -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 | 24 | <%= content_tag( 'small', _('Separate tags with commas') ) %> |
25 | 25 | |
26 | 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 | 28 | </div> |
35 | 29 | |
36 | 30 | <% button_bar do %> | ... | ... |
app/views/cms/view.rhtml
... | ... | @@ -13,7 +13,15 @@ |
13 | 13 | |
14 | 14 | <% button_bar(:style => 'margin-bottom: 1em;') do %> |
15 | 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 | 25 | <%= lightbox_button('new', _('New article'), :action => 'new', :parent_id => parent_id) %> |
18 | 26 | <% end %> |
19 | 27 | ... | ... |
app/views/content_viewer/view_page.rhtml
... | ... | @@ -23,7 +23,7 @@ |
23 | 23 | |
24 | 24 | <div onmouseover="showArticleActions(true)" |
25 | 25 | onmouseout="showArticleActions(false)"> |
26 | - <h1><%= @page.title %></h1> | |
26 | + <%= article_title(@page, :no_link => true) %> | |
27 | 27 | <script type="text/javascript"> |
28 | 28 | function showArticleActions( show ) { |
29 | 29 | var act = $("article-actions"); |
... | ... | @@ -65,7 +65,7 @@ |
65 | 65 | <% end %> |
66 | 66 | |
67 | 67 | <div class="article-body"> |
68 | - <%= @page.to_html %> | |
68 | + <%= article_to_html(@page) %> | |
69 | 69 | <br style="clear:both" /> |
70 | 70 | </div> <!-- end class="article-body" --> |
71 | 71 | |
... | ... | @@ -82,9 +82,8 @@ |
82 | 82 | <i class="do-not-comment"><%= _('This article does not accept comments')%></i> |
83 | 83 | <% else %> |
84 | 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 | 87 | <%= render :partial => 'comment', :collection => @comments %> |
89 | 88 | <%= render :partial => 'comment_form' %> |
90 | 89 | <% end %> | ... | ... |
... | ... | @@ -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 | ... | ... |
db/schema.rb
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | # |
10 | 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 | 14 | create_table "article_versions", :force => true do |t| |
15 | 15 | t.integer "article_id" |
... | ... | @@ -39,6 +39,7 @@ ActiveRecord::Schema.define(:version => 55) do |
39 | 39 | t.boolean "public_article", :default => true |
40 | 40 | t.boolean "accept_comments", :default => true |
41 | 41 | t.integer "reference_article_id" |
42 | + t.text "setting" | |
42 | 43 | end |
43 | 44 | |
44 | 45 | create_table "articles", :force => true do |t| |
... | ... | @@ -69,6 +70,7 @@ ActiveRecord::Schema.define(:version => 55) do |
69 | 70 | t.boolean "public_article", :default => true |
70 | 71 | t.boolean "accept_comments", :default => true |
71 | 72 | t.integer "reference_article_id" |
73 | + t.text "setting" | |
72 | 74 | end |
73 | 75 | |
74 | 76 | create_table "articles_categories", :id => false, :force => true do |t| | ... | ... |
public/stylesheets/article.css
... | ... | @@ -165,3 +165,39 @@ |
165 | 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 | +} | ... | ... |
... | ... | @@ -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 < Test::Unit::TestCase |
630 | 630 | assert_no_tag :tag => 'div', :descendant => { :tag => 'h4', :content => 'Categorize your article' } |
631 | 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}&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 | 728 | end | ... | ... |
test/functional/content_viewer_controller_test.rb
... | ... | @@ -528,4 +528,22 @@ class ContentViewerControllerTest < Test::Unit::TestCase |
528 | 528 | assert_response :missing |
529 | 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 | 549 | end | ... | ... |
test/functional/profile_design_controller_test.rb
... | ... | @@ -269,5 +269,15 @@ class ProfileDesignControllerTest < Test::Unit::TestCase |
269 | 269 | assert_tag :tag => 'a', :attributes => {:href => '/myprofile/test_profile'} |
270 | 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 < Test::Unit::TestCase |
263 | 263 | assert !Article.new.folder?, 'should identify itself as non-folder' |
264 | 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 | 270 | should 'always display if public content' do |
267 | 271 | person = create_user('testuser').person |
268 | 272 | assert_equal true, person.home_page.display_to?(nil) |
... | ... | @@ -544,4 +548,18 @@ class ArticleTest < Test::Unit::TestCase |
544 | 548 | assert_nil page |
545 | 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 | 565 | end | ... | ... |
... | ... | @@ -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 | ... | ... |
... | ... | @@ -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 | ... | ... |
... | ... | @@ -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 | ... | ... |
... | ... | @@ -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 | ... | ... |
... | ... | @@ -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 < Test::Unit::TestCase |
967 | 967 | assert_not_equal p1.environment, p2.environment |
968 | 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 | 992 | private |
971 | 993 | |
972 | 994 | def assert_invalid_identifier(id) | ... | ... |