Commit 1a2f1931f49d544f3d636a8e3df925dc871b73c5

Authored by Joenio Costa
Committed by Antonio Terceiro
1 parent 4a74f898

ActionItem935: external blog repeater

app/helpers/blog_helper.rb
@@ -35,4 +35,5 @@ module BlogHelper @@ -35,4 +35,5 @@ module BlogHelper
35 article_title(article) + content_tag('p', article.to_html) + 35 article_title(article) + content_tag('p', article.to_html) +
36 content_tag('p', link_to( number_of_comments(article), article.url.merge(:form => 'opened', :anchor => 'comment_form') ), :class => 'metadata') 36 content_tag('p', link_to( number_of_comments(article), article.url.merge(:form => 'opened', :anchor => 'comment_form') ), :class => 'metadata')
37 end 37 end
  38 +
38 end 39 end
app/helpers/content_viewer_helper.rb
@@ -20,7 +20,7 @@ module ContentViewerHelper @@ -20,7 +20,7 @@ module ContentViewerHelper
20 unless args[:no_link] 20 unless args[:no_link]
21 title = content_tag('h3', link_to(article.name, article.url), :class => 'title') 21 title = content_tag('h3', link_to(article.name, article.url), :class => 'title')
22 end 22 end
23 - title << content_tag('span', _("%s, by %s") % [show_date(article.created_at), link_to(article.author.name, article.author.url)], :class => 'created-at') 23 + title << content_tag('span', _("%s, by %s") % [show_date(article.published_at), link_to(article.author.name, article.author.url)], :class => 'created-at')
24 end 24 end
25 title 25 title
26 end 26 end
app/models/article.rb
@@ -20,6 +20,10 @@ class Article &lt; ActiveRecord::Base @@ -20,6 +20,10 @@ class Article &lt; ActiveRecord::Base
20 20
21 settings_items :display_hits, :type => :boolean, :default => true 21 settings_items :display_hits, :type => :boolean, :default => true
22 22
  23 + before_create do |article|
  24 + article.published_at = article.created_at if article.published_at.nil?
  25 + end
  26 +
23 def self.human_attribute_name(attrib) 27 def self.human_attribute_name(attrib)
24 case attrib.to_sym 28 case attrib.to_sym
25 when :name 29 when :name
app/models/blog.rb
1 class Blog < Folder 1 class Blog < Folder
2 2
3 - has_many :posts, :class_name => 'Article', :foreign_key => 'parent_id', :source => :children, :conditions => [ 'type != ?', 'RssFeed' ], :order => 'created_at DESC' 3 + has_many :posts, :class_name => 'Article', :foreign_key => 'parent_id', :source => :children, :conditions => [ 'type != ?', 'RssFeed' ], :order => 'published_at DESC'
4 4
5 attr_accessor :feed_attrs 5 attr_accessor :feed_attrs
6 attr_accessor :filter 6 attr_accessor :filter
@@ -56,7 +56,7 @@ class Blog &lt; Folder @@ -56,7 +56,7 @@ class Blog &lt; Folder
56 article = self 56 article = self
57 children = if filter and filter[:year] and filter[:month] 57 children = if filter and filter[:year] and filter[:month]
58 filter_date = DateTime.parse("#{filter[:year]}-#{filter[:month]}-01") 58 filter_date = DateTime.parse("#{filter[:year]}-#{filter[:month]}-01")
59 - posts.paginate :page => npage, :per_page => posts_per_page, :conditions => [ 'created_at between ? and ?', filter_date, filter_date + 1.month - 1.day ] 59 + posts.paginate :page => npage, :per_page => posts_per_page, :conditions => [ 'published_at between ? and ?', filter_date, filter_date + 1.month - 1.day ]
60 else 60 else
61 posts.paginate :page => npage, :per_page => posts_per_page 61 posts.paginate :page => npage, :per_page => posts_per_page
62 end 62 end
@@ -64,4 +64,33 @@ class Blog &lt; Folder @@ -64,4 +64,33 @@ class Blog &lt; Folder
64 render :file => 'content_viewer/blog_page', :locals => {:article => article, :children => children} 64 render :file => 'content_viewer/blog_page', :locals => {:article => article, :children => children}
65 end 65 end
66 end 66 end
  67 +
  68 + has_one :external_feed, :foreign_key => 'blog_id'
  69 +
  70 + attr_accessor :external_feed_data
  71 + def external_feed_builder=(efeed)
  72 + self.external_feed_data = efeed
  73 + end
  74 +
  75 + def validate
  76 + unless self.external_feed_data.nil?
  77 + if self.external_feed(true) && self.external_feed.id == self.external_feed_data[:id].to_i
  78 + self.external_feed.attributes = self.external_feed_data
  79 + else
  80 + self.build_external_feed(self.external_feed_data)
  81 + end
  82 + self.external_feed.valid?
  83 + self.external_feed.errors.delete(:blog_id) # dont validate here relation: external_feed <-> blog
  84 + self.external_feed.errors.each do |attr,msg|
  85 + self.errors.add(attr, msg)
  86 + end
  87 + end
  88 + end
  89 +
  90 + after_save do |blog|
  91 + if blog.external_feed
  92 + blog.external_feed.save
  93 + end
  94 + end
  95 +
67 end 96 end
app/models/blog_archives_block.rb
@@ -18,10 +18,10 @@ class BlogArchivesBlock &lt; Block @@ -18,10 +18,10 @@ class BlogArchivesBlock &lt; Block
18 return nil unless owner.has_blog? 18 return nil unless owner.has_blog?
19 results = '' 19 results = ''
20 posts = owner.blog.posts 20 posts = owner.blog.posts
21 - posts.group_by{|i| i.created_at.year}.each do |year, results_by_year| 21 + posts.group_by{|i| i.published_at.year}.each do |year, results_by_year|
22 results << content_tag('li', content_tag('strong', "#{year} (#{results_by_year.size})")) 22 results << content_tag('li', content_tag('strong', "#{year} (#{results_by_year.size})"))
23 results << "<ul class='#{year}-archive'>" 23 results << "<ul class='#{year}-archive'>"
24 - results_by_year.group_by{|i| [ ('%02d' % i.created_at.month()), gettext(MONTHS[i.created_at.month() - 1])]}.sort.each do |month, results_by_month| 24 + results_by_year.group_by{|i| [ ('%02d' % i.published_at.month()), gettext(MONTHS[i.published_at.month() - 1])]}.sort.each do |month, results_by_month|
25 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]]))) 25 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]])))
26 end 26 end
27 results << "</ul>" 27 results << "</ul>"
app/models/external_feed.rb 0 → 100644
@@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
  1 +class ExternalFeed < ActiveRecord::Base
  2 +
  3 + belongs_to :blog
  4 + validates_presence_of :blog_id
  5 + validates_presence_of :address, :if => lambda {|efeed| efeed.enabled}
  6 + validates_uniqueness_of :blog_id
  7 +
  8 + def add_item(title, link, date, content)
  9 + article = TinyMceArticle.new(:name => title, :profile => blog.profile, :body => content, :published_at => date, :source => link, :profile => blog.profile, :parent => blog)
  10 + unless blog.children.exists?(:slug => article.slug)
  11 + article.save!
  12 + end
  13 + end
  14 +
  15 + def clear
  16 + # do nothing
  17 + end
  18 + def finish_fetch
  19 + if self.only_once
  20 + self.enabled = 'false'
  21 + end
  22 + self.save!
  23 + end
  24 +
  25 + def limit
  26 + 0
  27 + end
  28 +
  29 +end
app/models/feed_reader_block.rb
@@ -48,6 +48,9 @@ class FeedReaderBlock &lt; Block @@ -48,6 +48,9 @@ class FeedReaderBlock &lt; Block
48 self.feed_items = [] 48 self.feed_items = []
49 self.feed_title = nil 49 self.feed_title = nil
50 end 50 end
  51 + def finish_fetch
  52 + self.save!
  53 + end
51 54
52 def content 55 def content
53 block_title(title) + formatted_feed_content 56 block_title(title) + formatted_feed_content
app/views/cms/_blog.rhtml
  1 +<%= error_messages_for 'blog' %>
  2 +
1 <h3><%= _('My Blog') %></h3> 3 <h3><%= _('My Blog') %></h3>
2 4
3 <%= render :file => 'shared/tiny_mce' %> 5 <%= render :file => 'shared/tiny_mce' %>
@@ -8,12 +10,26 @@ @@ -8,12 +10,26 @@
8 10
9 <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, [5, 10, 20, 50, 100])) %> 11 <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, [5, 10, 20, 50, 100])) %>
10 12
11 -<% fields_for 'article[feed]', @article.feed do |feed| %>  
12 -  
13 -<%= labelled_form_field(_('Limit of posts in RSS Feed'), feed.select(:limit, ['5', '10', '20', '50'])) %>  
14 -  
15 -<%= labelled_form_field(_('Use as description in RSS Feed:'), feed.select(:feed_item_description, [ [ _('Article abstract'), 'abstract'], [ _('Article body'), 'body']])) %> 13 +<% f.fields_for 'feed', @article.feed do |feed| %>
  14 + <%= labelled_form_field(_('Limit of posts in RSS Feed'), feed.select(:limit, ['5', '10', '20', '50'])) %>
  15 + <%= labelled_form_field(_('Use as description in RSS Feed:'), feed.select(:feed_item_description, [ [ _('Article abstract'), 'abstract'], [ _('Article body'), 'body']])) %>
  16 +<% end %>
16 17
  18 +<% f.fields_for 'external_feed_builder', @article.external_feed do |efeed| %>
  19 + <div id='fetch-external-feed'>
  20 + <% enabled = @article.external_feed && @article.external_feed.enabled %>
  21 + <% only_once = @article.external_feed ? @article.external_feed.only_once : true %>
  22 + <%= labelled_check_box(_('Fetch posts from an external feed'), 'article[external_feed_builder][enabled]', 'true', enabled, {:onchange => "$('external-feed-options').toggle()"}) %>
  23 + <%= hidden_field_tag 'article[external_feed_builder][enabled]', 'false' %>
  24 + <div id='external-feed-options' style="display: <%= enabled ? 'block' : 'none' %>">
  25 + <%= efeed.hidden_field(:id) %>
  26 + <%= labelled_form_field( _('Feed address'), efeed.text_field(:address) ) %>
  27 + <div id='external-feed-options-only-once'>
  28 + <%= labelled_radio_button( _('Fetch posts only once'), 'article[external_feed_builder][only_once]', 'true', only_once) %>
  29 + <%= labelled_radio_button( _('Fetch posts always'), 'article[external_feed_builder][only_once]', 'false', !only_once) %>
  30 + </div>
  31 + </div>
  32 + </div>
17 <% end %> 33 <% end %>
18 34
19 <%= javascript_tag "$('back_to').value = 'control_panel'" %> 35 <%= javascript_tag "$('back_to').value = 'control_panel'" %>
app/views/content_viewer/blog_page.rhtml
  1 +<%= content_tag('em', _('(external feed was not loaded yet)'), :id => 'external-feed-info', :class => 'metadata') if article.blog? && article.external_feed && article.external_feed.fetched_at.nil? %>
  2 +
1 <div><%= article.body %></div> 3 <div><%= article.body %></div>
2 <hr/> 4 <hr/>
3 <%= (children.compact.empty? ? content_tag('em', _('(no posts)')) : list_posts(user, children)) %> 5 <%= (children.compact.empty? ? content_tag('em', _('(no posts)')) : list_posts(user, children)) %>
4 -  
5 -  
app/views/content_viewer/view_page.rhtml
@@ -97,6 +97,11 @@ @@ -97,6 +97,11 @@
97 </div> 97 </div>
98 <% end %> 98 <% end %>
99 99
  100 +<% if ! @page.source.nil? and ! @page.source.empty?%>
  101 +<div id="article-source">
  102 + <%= _('Source: %s') % link_to(@page.source, @page.source) %>
  103 +</div>
  104 +<% end %>
100 105
101 <div class="comments"> 106 <div class="comments">
102 <% if @page.accept_comments? %> 107 <% if @page.accept_comments? %>
db/migrate/063_add_published_at_and_source_to_articles.rb 0 → 100644
@@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
  1 +class AddPublishedAtAndSourceToArticles < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :articles, :published_at, :date
  4 + add_column :article_versions, :published_at, :date
  5 +
  6 + execute('UPDATE articles SET published_at = created_at WHERE published_at IS NULL')
  7 + execute('UPDATE article_versions SET published_at = created_at WHERE published_at IS NULL')
  8 +
  9 + add_column :articles, :source, :string, :null => true
  10 + add_column :article_versions, :source, :string, :null => true
  11 + end
  12 +
  13 + def self.down
  14 + remove_column :articles, :published_at
  15 + remove_column :article_versions, :published_at
  16 + remove_column :articles, :source
  17 + remove_column :article_versions, :source
  18 + end
  19 +end
db/migrate/064_create_external_feeds.rb 0 → 100644
@@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
  1 +class CreateExternalFeeds < ActiveRecord::Migration
  2 + def self.up
  3 + create_table :external_feeds do |t|
  4 + t.string :feed_title
  5 + t.date :fetched_at
  6 + t.string :address
  7 + t.integer :blog_id, :null => false
  8 + t.boolean :enabled, :null => false, :default => true
  9 + t.boolean :only_once, :null => false, :default => true
  10 + t.timestamps
  11 + end
  12 + end
  13 +
  14 + def self.down
  15 + drop_table :external_feeds
  16 + end
  17 +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 => 62) do 12 +ActiveRecord::Schema.define(:version => 64) 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"
@@ -42,6 +42,8 @@ ActiveRecord::Schema.define(:version =&gt; 62) do @@ -42,6 +42,8 @@ ActiveRecord::Schema.define(:version =&gt; 62) do
42 t.text "setting" 42 t.text "setting"
43 t.boolean "notify_comments", :default => false 43 t.boolean "notify_comments", :default => false
44 t.integer "hits", :default => 0 44 t.integer "hits", :default => 0
  45 + t.date "published_at"
  46 + t.string "source"
45 end 47 end
46 48
47 create_table "articles", :force => true do |t| 49 create_table "articles", :force => true do |t|
@@ -75,6 +77,8 @@ ActiveRecord::Schema.define(:version =&gt; 62) do @@ -75,6 +77,8 @@ ActiveRecord::Schema.define(:version =&gt; 62) do
75 t.text "setting" 77 t.text "setting"
76 t.boolean "notify_comments", :default => true 78 t.boolean "notify_comments", :default => true
77 t.integer "hits", :default => 0 79 t.integer "hits", :default => 0
  80 + t.date "published_at"
  81 + t.string "source"
78 end 82 end
79 83
80 create_table "articles_categories", :id => false, :force => true do |t| 84 create_table "articles_categories", :id => false, :force => true do |t|
@@ -160,6 +164,17 @@ ActiveRecord::Schema.define(:version =&gt; 62) do @@ -160,6 +164,17 @@ ActiveRecord::Schema.define(:version =&gt; 62) do
160 t.string "theme" 164 t.string "theme"
161 end 165 end
162 166
  167 + create_table "external_feeds", :force => true do |t|
  168 + t.string "feed_title"
  169 + t.date "fetched_at"
  170 + t.string "address"
  171 + t.integer "blog_id", :null => false
  172 + t.boolean "enabled", :default => true, :null => false
  173 + t.boolean "only_once", :default => true, :null => false
  174 + t.datetime "created_at"
  175 + t.datetime "updated_at"
  176 + end
  177 +
163 create_table "favorite_enteprises_people", :id => false, :force => true do |t| 178 create_table "favorite_enteprises_people", :id => false, :force => true do |t|
164 t.integer "person_id" 179 t.integer "person_id"
165 t.integer "enterprise_id" 180 t.integer "enterprise_id"
lib/feed_handler.rb
@@ -32,7 +32,7 @@ class FeedHandler @@ -32,7 +32,7 @@ class FeedHandler
32 parse.items[0..container.limit-1].each do |item| 32 parse.items[0..container.limit-1].each do |item|
33 container.add_item(item.title, item.link, item.date, item.content) 33 container.add_item(item.title, item.link, item.date, item.content)
34 end 34 end
35 - container.save! 35 + container.finish_fetch
36 end 36 end
37 end 37 end
38 38
public/stylesheets/article.css
@@ -32,6 +32,16 @@ @@ -32,6 +32,16 @@
32 font-size: 10px; 32 font-size: 10px;
33 } 33 }
34 34
  35 +#article-source {
  36 + color: #999;
  37 + font-size: 11px;
  38 + text-align: right;
  39 + font-weight: bold;
  40 +}
  41 +#article-source a {
  42 + font-weight: normal;
  43 +}
  44 +
35 /* * * Comments * * */ 45 /* * * Comments * * */
36 46
37 .comments { } 47 .comments { }
@@ -183,12 +193,18 @@ @@ -183,12 +193,18 @@
183 margin-bottom: 2px; 193 margin-bottom: 2px;
184 } 194 }
185 195
  196 +.metadata,
186 .blog-post .metadata { 197 .blog-post .metadata {
187 display: block; 198 display: block;
188 text-align: center; 199 text-align: center;
189 font-size: small; 200 font-size: small;
190 } 201 }
191 202
  203 +.metadata {
  204 + text-align: right;
  205 + color: gray;
  206 +}
  207 +
192 #content .created-at { 208 #content .created-at {
193 color: gray; 209 color: gray;
194 font-size: small; 210 font-size: small;
@@ -237,3 +253,5 @@ @@ -237,3 +253,5 @@
237 text-align: center; 253 text-align: center;
238 font-size: small; 254 font-size: small;
239 } 255 }
  256 +
  257 +
public/stylesheets/controller_cms.css
@@ -122,3 +122,26 @@ div.file-manager-button a:hover { @@ -122,3 +122,26 @@ div.file-manager-button a:hover {
122 .file-manager-small .file-manager-controls * { 122 .file-manager-small .file-manager-controls * {
123 text-align: right; 123 text-align: right;
124 } 124 }
  125 +
  126 +/************* external blog options *****************/
  127 +
  128 +#fetch-external-feed {
  129 + border: 1px solid #EEE;
  130 + padding: 5px;
  131 + margin: 5px 0;
  132 + width: 460px
  133 +}
  134 +#fetch-external-feed label,
  135 +#fetch-external-feed .formfield,
  136 +#fetch-external-feed #external-feed-options #external-feed-options-only-once label,
  137 +#fetch-external-feed #external-feed-options #external-feed-options-only-once .formfieldline,
  138 +#fetch-external-feed #external-feed-options #external-feed-options-only-once .formfield {
  139 + display: inline;
  140 +}
  141 +#fetch-external-feed .type-text input {
  142 + width: 400px;
  143 +}
  144 +#fetch-external-feed #external-feed-options label,
  145 +#fetch-external-feed #external-feed-options .formfield {
  146 + display: block;
  147 +}
script/feed-updater
1 #!/usr/bin/env ruby 1 #!/usr/bin/env ruby
2 require File.dirname(__FILE__) + '/../config/environment' 2 require File.dirname(__FILE__) + '/../config/environment'
3 3
4 -FeedReaderBlock.find(:all).each do |feed_block|  
5 - unless feed_block.address.nil? 4 +(FeedReaderBlock.find(:all) + ExternalFeed.find(:all, :conditions => {:enabled => true})).each do |container|
  5 + unless container.address.nil?
6 begin 6 begin
7 handler = FeedHandler.new 7 handler = FeedHandler.new
8 - handler.process(feed_block)  
9 - RAILS_DEFAULT_LOGGER.info("%s ID %d fetched at %s" % [feed_block.class.name, feed_block.id, feed_block.fetched_at]) 8 + handler.process(container)
  9 + RAILS_DEFAULT_LOGGER.info("%s ID %d fetched at %s" % [container.class.name, container.id, container.fetched_at])
10 rescue FeedHandler::ParseError => ex 10 rescue FeedHandler::ParseError => ex
11 - RAILS_DEFAULT_LOGGER.warn("Error parsing content from %s ID %d\n%s" % [feed_block.class.name, feed_block.id, ex.to_s]) 11 + RAILS_DEFAULT_LOGGER.warn("Error parsing content from %s ID %d\n%s" % [container.class.name, container.id, ex.to_s])
12 rescue FeedHandler::FetchError => ex 12 rescue FeedHandler::FetchError => ex
13 - RAILS_DEFAULT_LOGGER.warn("Error fetching content from %s ID %d\n%s" % [feed_block.class.name, feed_block.id, ex.to_s]) 13 + RAILS_DEFAULT_LOGGER.warn("Error fetching content from %s ID %d\n%s" % [container.class.name, container.id, ex.to_s])
14 rescue Exception => ex 14 rescue Exception => ex
15 - RAILS_DEFAULT_LOGGER.warn("Unknown error from %s ID %d\n%s" % [feed_block.class.name, feed_block.id, ex.to_s]) 15 + RAILS_DEFAULT_LOGGER.warn("Unknown error from %s ID %d\n%s" % [container.class.name, container.id, ex.to_s])
16 end 16 end
17 end 17 end
18 end 18 end
test/functional/cms_controller_test.rb
@@ -716,7 +716,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase @@ -716,7 +716,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase
716 end 716 end
717 717
718 should 'offer to edit a blog' do 718 should 'offer to edit a blog' do
719 - profile.articles << Blog.new(:name => 'blog test') 719 + profile.articles << Blog.new(:name => 'blog test', :profile => profile)
720 720
721 profile.articles.reload 721 profile.articles.reload
722 assert profile.has_blog? 722 assert profile.has_blog?
@@ -727,7 +727,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase @@ -727,7 +727,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase
727 end 727 end
728 728
729 should 'not offer to add folder to blog' do 729 should 'not offer to add folder to blog' do
730 - profile.articles << Blog.new(:name => 'blog test') 730 + profile.articles << Blog.new(:name => 'blog test', :profile => profile)
731 731
732 profile.articles.reload 732 profile.articles.reload
733 assert profile.has_blog? 733 assert profile.has_blog?
@@ -737,7 +737,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase @@ -737,7 +737,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase
737 end 737 end
738 738
739 should 'not show feed subitem for blog' do 739 should 'not show feed subitem for blog' do
740 - profile.articles << Blog.new(:name => 'Blog for test') 740 + profile.articles << Blog.new(:name => 'Blog for test', :profile => profile)
741 741
742 profile.articles.reload 742 profile.articles.reload
743 assert profile.has_blog? 743 assert profile.has_blog?
@@ -748,7 +748,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase @@ -748,7 +748,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase
748 end 748 end
749 749
750 should 'update feed options by edit blog form' do 750 should 'update feed options by edit blog form' do
751 - profile.articles << Blog.new(:name => 'Blog for test') 751 + profile.articles << Blog.new(:name => 'Blog for test', :profile => profile)
752 post :edit, :profile => profile.identifier, :id => profile.blog.id, :article => { :feed => { :limit => 7 } } 752 post :edit, :profile => profile.identifier, :id => profile.blog.id, :article => { :feed => { :limit => 7 } }
753 assert_equal 7, profile.blog.feed.limit 753 assert_equal 7, profile.blog.feed.limit
754 end 754 end
@@ -770,8 +770,9 @@ class CmsControllerTest &lt; Test::Unit::TestCase @@ -770,8 +770,9 @@ class CmsControllerTest &lt; Test::Unit::TestCase
770 end 770 end
771 771
772 should 'update blog posts_per_page setting' do 772 should 'update blog posts_per_page setting' do
773 - profile.articles << Blog.new(:name => 'Blog for test') 773 + profile.articles << Blog.new(:name => 'Blog for test', :profile => profile)
774 post :edit, :profile => profile.identifier, :id => profile.blog.id, :article => { :posts_per_page => 5 } 774 post :edit, :profile => profile.identifier, :id => profile.blog.id, :article => { :posts_per_page => 5 }
  775 + profile.blog.reload
775 assert_equal 5, profile.blog.posts_per_page 776 assert_equal 5, profile.blog.posts_per_page
776 end 777 end
777 778
@@ -909,4 +910,36 @@ class CmsControllerTest &lt; Test::Unit::TestCase @@ -909,4 +910,36 @@ class CmsControllerTest &lt; Test::Unit::TestCase
909 assert_template nil 910 assert_template nil
910 assert_redirected_to file.url.merge(:view => true) 911 assert_redirected_to file.url.merge(:view => true)
911 end 912 end
  913 +
  914 + should 'display external feed options when edit blog' do
  915 + get :new, :profile => profile.identifier, :type => 'Blog'
  916 + assert_tag :tag => 'input', :attributes => { :name => 'article[external_feed_builder][enabled]' }
  917 + assert_tag :tag => 'input', :attributes => { :name => 'article[external_feed_builder][address]' }
  918 + end
  919 +
  920 + should "display 'Fetch posts from an external feed' checked if blog has enabled external feed" do
  921 + profile.articles << Blog.new(:title => 'test blog', :profile => profile)
  922 + profile.blog.create_external_feed(:address => 'address', :enabled => true)
  923 + get :edit, :profile => profile.identifier, :id => profile.blog.id
  924 + assert_tag :tag => 'input', :attributes => { :name => 'article[external_feed_builder][enabled]', :checked => 'checked' }
  925 + end
  926 +
  927 + should "display 'Fetch posts from an external feed' unchecked if blog has disabled external feed" do
  928 + profile.articles << Blog.new(:title => 'test blog', :profile => profile)
  929 + profile.blog.create_external_feed(:address => 'address', :enabled => false)
  930 + get :edit, :profile => profile.identifier, :id => profile.blog.id
  931 + assert_tag :tag => 'input', :attributes => { :name => 'article[external_feed_builder][enabled]', :checked => nil }
  932 + end
  933 +
  934 + should "hide external feed options when 'Fetch posts from an external feed' unchecked" do
  935 + get :new, :profile => profile.identifier, :type => 'Blog'
  936 + assert_tag :tag => 'input', :attributes => { :name => 'article[external_feed_builder][enabled]', :checked => nil }
  937 + assert_tag :tag => 'div', :attributes => { :id => 'external-feed-options', :style => 'display: none' }
  938 + end
  939 +
  940 + should 'only_once option marked by default' do
  941 + get :new, :profile => profile.identifier, :type => 'Blog'
  942 + assert_tag :tag => 'input', :attributes => { :name => 'article[external_feed_builder][only_once]', :checked => 'checked', :value => 'true' }
  943 + end
  944 +
912 end 945 end
test/functional/content_viewer_controller_test.rb
@@ -14,8 +14,9 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase @@ -14,8 +14,9 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase
14 @response = ActionController::TestResponse.new 14 @response = ActionController::TestResponse.new
15 15
16 @profile = create_user('testinguser').person 16 @profile = create_user('testinguser').person
  17 + @environment = @profile.environment
17 end 18 end
18 - attr_reader :profile 19 + attr_reader :profile, :environment
19 20
20 def test_local_files_reference 21 def test_local_files_reference
21 page = profile.articles.build(:name => 'test') 22 page = profile.articles.build(:name => 'test')
@@ -638,9 +639,9 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase @@ -638,9 +639,9 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase
638 end 639 end
639 640
640 should 'extract year and month from path' do 641 should 'extract year and month from path' do
641 - blog = Blog.create!(:name => 'A blog test', :profile => profile)  
642 - year, month = blog.created_at.year.to_s, '%02d' % blog.created_at.month  
643 - get :view_page, :profile => profile.identifier, :page => [blog.path, year, month] 642 + profile.articles << Blog.new(:name => 'A blog test', :profile => profile)
  643 + year, month = profile.blog.created_at.year.to_s, '%02d' % profile.blog.created_at.month
  644 + get :view_page, :profile => profile.identifier, :page => [profile.blog.path, year, month]
644 assert_equal({ :year => year.to_s, :month => month.to_s }, assigns(:page).filter) 645 assert_equal({ :year => year.to_s, :month => month.to_s }, assigns(:page).filter)
645 end 646 end
646 647
@@ -693,17 +694,17 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase @@ -693,17 +694,17 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase
693 694
694 should 'add meta tag to rss feed on view blog' do 695 should 'add meta tag to rss feed on view blog' do
695 login_as(profile.identifier) 696 login_as(profile.identifier)
696 - a = Blog.create!(:name => 'article folder', :profile => profile)  
697 - get :view_page, :profile => profile.identifier, :page => [a.path]  
698 - assert_tag :tag => 'link', :attributes => { :rel => 'alternate', :type => 'application/rss+xml', :title => 'feed', :href => /\/#{profile.identifier}\/blog\/feed/} 697 + profile.articles << Blog.new(:title => 'article blog', :profile => profile)
  698 + get :view_page, :profile => profile.identifier, :page => ['blog']
  699 + assert_tag :tag => 'link', :attributes => { :rel => 'alternate', :type => 'application/rss+xml', :title => 'feed', :href => "http://#{environment.default_hostname}/testinguser/blog/feed" }
699 end 700 end
700 701
701 should 'add meta tag to rss feed on view post blog' do 702 should 'add meta tag to rss feed on view post blog' do
702 login_as(profile.identifier) 703 login_as(profile.identifier)
703 - a = Blog.create!(:name => 'article folder', :profile => profile)  
704 - t = TextileArticle.create!(:name => 'first post', :parent => a, :profile => profile)  
705 - get :view_page, :profile => profile.identifier, :page => [t.path]  
706 - assert_tag :tag => 'link', :attributes => { :rel => 'alternate', :type => 'application/rss+xml', :title => 'feed', :href => /\/#{profile.identifier}\/blog\/feed/} 704 + profile.articles << Blog.new(:name => 'article folder', :profile => profile)
  705 + profile.blog.posts << TextileArticle.new(:name => 'first post', :parent => profile.blog, :profile => profile)
  706 + get :view_page, :profile => profile.identifier, :page => ['blog', 'first-post']
  707 + assert_tag :tag => 'link', :attributes => { :rel => 'alternate', :type => 'application/rss+xml', :title => 'feed', :href => "http://#{environment.default_hostname}/testinguser/blog/feed" }
707 end 708 end
708 709
709 should 'link to post with comment form opened' do 710 should 'link to post with comment form opened' do
@@ -787,4 +788,16 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase @@ -787,4 +788,16 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase
787 assert_template 'slideshow' 788 assert_template 'slideshow'
788 end 789 end
789 790
  791 + should 'display source from article' do
  792 + profile.articles << TextileArticle.new(:name => "Article one", :profile => profile, :source => 'http://www.original-source.invalid')
  793 + get :view_page, :profile => profile.identifier, :page => ['article-one']
  794 + assert_tag :tag => 'div', :attributes => { :id => 'article-source' }, :content => /http:\/\/www.original-source.invalid/
  795 + end
  796 +
  797 + should 'not display source if article has no source' do
  798 + profile.articles << TextileArticle.new(:name => "Article one", :profile => profile)
  799 + get :view_page, :profile => profile.identifier, :page => ['article-one']
  800 + assert_no_tag :tag => 'div', :attributes => { :id => 'article-source' }
  801 + end
  802 +
790 end 803 end
test/functional/profile_design_controller_test.rb
@@ -274,7 +274,7 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase @@ -274,7 +274,7 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase
274 end 274 end
275 275
276 should 'offer to create blog archives block only if has blog' do 276 should 'offer to create blog archives block only if has blog' do
277 - Blog.create!(:name => 'Blog test', :profile => holder) 277 + holder.articles << Blog.new(:name => 'Blog test', :profile => holder)
278 get :add_block, :profile => 'designtestuser' 278 get :add_block, :profile => 'designtestuser'
279 assert_tag :tag => 'input', :attributes => { :id => 'type_blogarchivesblock', :value => 'BlogArchivesBlock' } 279 assert_tag :tag => 'input', :attributes => { :id => 'type_blogarchivesblock', :value => 'BlogArchivesBlock' }
280 end 280 end
test/functional/profile_editor_controller_test.rb
@@ -628,7 +628,7 @@ class ProfileEditorControllerTest &lt; Test::Unit::TestCase @@ -628,7 +628,7 @@ class ProfileEditorControllerTest &lt; Test::Unit::TestCase
628 628
629 should 'offer to config blog in control panel' do 629 should 'offer to config blog in control panel' do
630 profile.articles << Blog.new(:name => 'My blog', :profile => profile) 630 profile.articles << Blog.new(:name => 'My blog', :profile => profile)
631 - get :index, :profile => 'default_user' 631 + get :index, :profile => profile.identifier
632 assert_tag :tag => 'a', :attributes => { :href => "/myprofile/default_user/cms/edit/#{profile.blog.id}" } 632 assert_tag :tag => 'a', :attributes => { :href => "/myprofile/default_user/cms/edit/#{profile.blog.id}" }
633 end 633 end
634 634
test/unit/article_test.rb
@@ -684,4 +684,13 @@ class ArticleTest &lt; Test::Unit::TestCase @@ -684,4 +684,13 @@ class ArticleTest &lt; Test::Unit::TestCase
684 assert_equal profile, Article.new(:last_changed_by => nil, :profile => profile).author 684 assert_equal profile, Article.new(:last_changed_by => nil, :profile => profile).author
685 end 685 end
686 686
  687 + should 'have published_at' do
  688 + assert_respond_to Article.new, :published_at
  689 + end
  690 +
  691 + should 'published_at is same as created_at if not set' do
  692 + a = Article.create!(:name => 'Published at', :profile => profile)
  693 + assert_equal a.created_at, a.published_at
  694 + end
  695 +
687 end 696 end
test/unit/blog_archives_block_test.rb
@@ -4,7 +4,7 @@ class BlogArchivesBlockTest &lt; ActiveSupport::TestCase @@ -4,7 +4,7 @@ class BlogArchivesBlockTest &lt; ActiveSupport::TestCase
4 4
5 def setup 5 def setup
6 @profile = create_user('flatline').person 6 @profile = create_user('flatline').person
7 - @profile.articles << Blog.new(:name => 'blog', :profile => @profile) 7 + @profile.articles << Blog.new(:name => 'blog-test', :profile => @profile)
8 end 8 end
9 attr_reader :profile 9 attr_reader :profile
10 10
@@ -22,7 +22,7 @@ class BlogArchivesBlockTest &lt; ActiveSupport::TestCase @@ -22,7 +22,7 @@ class BlogArchivesBlockTest &lt; ActiveSupport::TestCase
22 blog = profile.blog 22 blog = profile.blog
23 for i in 1..10 do 23 for i in 1..10 do
24 post = TextileArticle.create!(:name => "post #{i} test", :profile => profile, :parent => blog) 24 post = TextileArticle.create!(:name => "post #{i} test", :profile => profile, :parent => blog)
25 - post.update_attribute(:created_at, date) 25 + post.update_attribute(:published_at, date)
26 end 26 end
27 block = BlogArchivesBlock.new 27 block = BlogArchivesBlock.new
28 block.stubs(:owner).returns(profile) 28 block.stubs(:owner).returns(profile)
@@ -34,19 +34,18 @@ class BlogArchivesBlockTest &lt; ActiveSupport::TestCase @@ -34,19 +34,18 @@ class BlogArchivesBlockTest &lt; ActiveSupport::TestCase
34 blog = profile.blog 34 blog = profile.blog
35 for i in 1..10 do 35 for i in 1..10 do
36 post = TextileArticle.create!(:name => "post #{i} test", :profile => profile, :parent => blog) 36 post = TextileArticle.create!(:name => "post #{i} test", :profile => profile, :parent => blog)
37 - post.update_attribute(:created_at, date) 37 + post.update_attribute(:published_at, date)
38 end 38 end
39 block = BlogArchivesBlock.new 39 block = BlogArchivesBlock.new
40 block.stubs(:owner).returns(profile) 40 block.stubs(:owner).returns(profile)
41 assert_tag_in_string block.content, :tag => 'a', :content => 'January (10)', :attributes => {:href => /2008\/01/} 41 assert_tag_in_string block.content, :tag => 'a', :content => 'January (10)', :attributes => {:href => /2008\/01/}
42 end 42 end
43 43
44 -  
45 should 'order list of amount posts' do 44 should 'order list of amount posts' do
46 blog = profile.blog 45 blog = profile.blog
47 for i in 1..10 do 46 for i in 1..10 do
48 post = TextileArticle.create!(:name => "post #{i} test", :profile => profile, :parent => blog) 47 post = TextileArticle.create!(:name => "post #{i} test", :profile => profile, :parent => blog)
49 - post.update_attribute(:created_at, DateTime.parse("2008-#{i}-01")) 48 + post.update_attribute(:published_at, DateTime.parse("2008-#{i}-01"))
50 end 49 end
51 block = BlogArchivesBlock.new 50 block = BlogArchivesBlock.new
52 block.stubs(:owner).returns(profile) 51 block.stubs(:owner).returns(profile)
test/unit/blog_test.rb
@@ -38,24 +38,16 @@ class BlogTest &lt; ActiveSupport::TestCase @@ -38,24 +38,16 @@ class BlogTest &lt; ActiveSupport::TestCase
38 assert_equal 'body', b.feed.feed_item_description 38 assert_equal 'body', b.feed.feed_item_description
39 end 39 end
40 40
41 - should 'get first blog from profile' do  
42 - p = create_user('testuser').person  
43 - b = Blog.create!(:profile => p, :name => 'blog_feed_test')  
44 - assert_equal p.blog, b  
45 - end  
46 -  
47 should 'save feed options' do 41 should 'save feed options' do
48 p = create_user('testuser').person 42 p = create_user('testuser').person
49 - b = Blog.create!(:profile => p, :name => 'blog_feed_test') 43 + p.articles << Blog.new(:profile => p, :name => 'blog_feed_test')
50 p.blog.feed = { :limit => 7 } 44 p.blog.feed = { :limit => 7 }
51 assert_equal 7, p.blog.feed.limit 45 assert_equal 7, p.blog.feed.limit
52 end 46 end
53 47
54 should 'save feed options after create blog' do 48 should 'save feed options after create blog' do
55 p = create_user('testuser').person 49 p = create_user('testuser').person
56 - b = Blog.create!(:profile => p, :name => 'blog_feed_test', :feed => { :limit => 7 })  
57 -  
58 - p.blog.feed.reload 50 + p.articles << Blog.new(:profile => p, :name => 'blog_feed_test', :feed => { :limit => 7 })
59 assert_equal 7, p.blog.feed.limit 51 assert_equal 7, p.blog.feed.limit
60 end 52 end
61 53
@@ -65,16 +57,16 @@ class BlogTest &lt; ActiveSupport::TestCase @@ -65,16 +57,16 @@ class BlogTest &lt; ActiveSupport::TestCase
65 end 57 end
66 58
67 should 'update posts per page setting' do 59 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 60 + p = create_user('testuser').person
  61 + p.articles << Blog.new(:profile => p, :name => 'Blog test')
  62 + blog = p.blog
  63 + blog.posts_per_page = 7
72 assert blog.save! 64 assert blog.save!
73 - assert_equal 5, blog.posts_per_page 65 + assert_equal 7, p.blog.posts_per_page
74 end 66 end
75 67
76 should 'has posts' do 68 should 'has posts' do
77 - p = create_user('testusermerda').person 69 + p = create_user('testuser').person
78 blog = Blog.create!(:profile => p, :name => 'Blog test') 70 blog = Blog.create!(:profile => p, :name => 'Blog test')
79 post = TextileArticle.create!(:name => 'First post', :profile => p, :parent => blog) 71 post = TextileArticle.create!(:name => 'First post', :profile => p, :parent => blog)
80 blog.children << post 72 blog.children << post
@@ -82,25 +74,56 @@ class BlogTest &lt; ActiveSupport::TestCase @@ -82,25 +74,56 @@ class BlogTest &lt; ActiveSupport::TestCase
82 end 74 end
83 75
84 should 'not includes rss feed in posts' do 76 should 'not includes rss feed in posts' do
85 - p = create_user('testusermerda').person 77 + p = create_user('testuser').person
86 blog = Blog.create!(:profile => p, :name => 'Blog test') 78 blog = Blog.create!(:profile => p, :name => 'Blog test')
87 assert_includes blog.children, blog.feed 79 assert_includes blog.children, blog.feed
88 assert_not_includes blog.posts, blog.feed 80 assert_not_includes blog.posts, blog.feed
89 end 81 end
90 82
91 - should 'list posts ordered by created at' do  
92 - p = create_user('testusermerda').person 83 + should 'list posts ordered by published at' do
  84 + p = create_user('testuser').person
93 blog = Blog.create!(:profile => p, :name => 'Blog test') 85 blog = Blog.create!(:profile => p, :name => 'Blog test')
94 newer = TextileArticle.create!(:name => 'Post 2', :parent => blog, :profile => p) 86 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) 87 + older = TextileArticle.create!(:name => 'Post 1', :parent => blog, :profile => p, :published_at => Time.now - 1.month)
96 assert_equal [newer, older], blog.posts 88 assert_equal [newer, older], blog.posts
97 end 89 end
98 90
99 should 'has filter' do 91 should 'has filter' do
100 - p = create_user('testusermerda').person 92 + p = create_user('testuser').person
101 blog = Blog.create!(:profile => p, :name => 'Blog test') 93 blog = Blog.create!(:profile => p, :name => 'Blog test')
102 blog.filter = {:param => 'value'} 94 blog.filter = {:param => 'value'}
103 assert_equal 'value', blog.filter[:param] 95 assert_equal 'value', blog.filter[:param]
104 end 96 end
105 97
  98 + should 'has one external feed' do
  99 + p = create_user('testuser').person
  100 + blog = Blog.create!(:profile => p, :name => 'Blog test')
  101 + efeed = blog.create_external_feed(:address => 'http://invalid.url')
  102 + assert_equal efeed, blog.external_feed
  103 + end
  104 +
  105 + should 'build external feed after save' do
  106 + p = create_user('testuser').person
  107 + blog = Blog.new(:profile => p, :name => 'Blog test')
  108 + blog.external_feed_builder = { :address => 'feed address' }
  109 + blog.save!
  110 + assert blog.external_feed.valid?
  111 + end
  112 +
  113 + should 'update external feed' do
  114 + p = create_user('testuser').person
  115 + blog = Blog.new(:profile => p, :name => 'Blog test')
  116 + blog.create_external_feed(:address => 'feed address')
  117 + blog.external_feed_builder = { :address => 'address edited' }
  118 + blog.save!
  119 + assert_equal 'address edited', blog.external_feed.address
  120 + end
  121 +
  122 + should 'invalid blog if has invalid external_feed' do
  123 + p = create_user('testuser').person
  124 + blog = Blog.new(:profile => p, :name => 'Blog test', :external_feed_builder => {:enabled => true})
  125 + blog.save
  126 + assert ! blog.valid?
  127 + end
  128 +
106 end 129 end
test/unit/content_viewer_helper_test.rb
@@ -11,17 +11,17 @@ class ContentViewerHelperTest &lt; Test::Unit::TestCase @@ -11,17 +11,17 @@ class ContentViewerHelperTest &lt; Test::Unit::TestCase
11 end 11 end
12 attr :profile 12 attr :profile
13 13
14 - should 'display created-at for blog posts' do 14 + should 'display published-at for blog posts' do
15 blog = Blog.create!(:name => 'Blog test', :profile => profile) 15 blog = Blog.create!(:name => 'Blog test', :profile => profile)
16 post = TextileArticle.create!(:name => 'post test', :profile => profile, :parent => blog) 16 post = TextileArticle.create!(:name => 'post test', :profile => profile, :parent => blog)
17 result = article_title(post) 17 result = article_title(post)
18 - assert_match /#{show_date(post.created_at)}, by .*#{profile.identifier}/, result 18 + assert_match /#{show_date(post.published_at)}, by .*#{profile.identifier}/, result
19 end 19 end
20 20
21 - should 'not display created-at for non-blog posts' do 21 + should 'not display published-at for non-blog posts' do
22 article = TextileArticle.create!(:name => 'article for test', :profile => profile) 22 article = TextileArticle.create!(:name => 'article for test', :profile => profile)
23 result = article_title(article) 23 result = article_title(article)
24 - assert_no_match /#{show_date(article.created_at)}, by .*#{profile.identifier}/, result 24 + assert_no_match /#{show_date(article.published_at)}, by .*#{profile.identifier}/, result
25 end 25 end
26 26
27 should 'create link on title of blog posts' do 27 should 'create link on title of blog posts' do
@@ -54,7 +54,7 @@ class ContentViewerHelperTest &lt; Test::Unit::TestCase @@ -54,7 +54,7 @@ class ContentViewerHelperTest &lt; Test::Unit::TestCase
54 end 54 end
55 55
56 should 'not list feed article' do 56 should 'not list feed article' do
57 - profile.articles << Blog.new(:name => 'Blog test') 57 + profile.articles << Blog.new(:name => 'Blog test', :profile => profile)
58 assert_includes profile.blog.children.map{|i| i.class}, RssFeed 58 assert_includes profile.blog.children.map{|i| i.class}, RssFeed
59 result = list_posts(nil, profile.blog.posts) 59 result = list_posts(nil, profile.blog.posts)
60 assert_no_match /feed/, result 60 assert_no_match /feed/, result
@@ -64,10 +64,10 @@ class ContentViewerHelperTest &lt; Test::Unit::TestCase @@ -64,10 +64,10 @@ class ContentViewerHelperTest &lt; Test::Unit::TestCase
64 blog = Blog.create!(:name => 'Blog test', :profile => profile) 64 blog = Blog.create!(:name => 'Blog test', :profile => profile)
65 65
66 nov = TextileArticle.create!(:name => 'November post', :parent => blog, :profile => profile) 66 nov = TextileArticle.create!(:name => 'November post', :parent => blog, :profile => profile)
67 - nov.update_attributes!(:created_at => DateTime.parse('2008-11-15')) 67 + nov.update_attributes!(:published_at => DateTime.parse('2008-11-15'))
68 68
69 sep = TextileArticle.create!(:name => 'September post', :parent => blog, :profile => profile) 69 sep = TextileArticle.create!(:name => 'September post', :parent => blog, :profile => profile)
70 - sep.update_attribute(:created_at, DateTime.parse('2008-09-10')) 70 + sep.update_attribute(:published_at, DateTime.parse('2008-09-10'))
71 71
72 blog.reload 72 blog.reload
73 blog.filter = {:year => 2008, :month => 11} 73 blog.filter = {:year => 2008, :month => 11}
test/unit/external_feed_test.rb 0 → 100644
@@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class ExternalFeedTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @profile = create_user('test-person').person
  7 + @blog = Blog.create!(:name => 'test-blog', :profile => @profile)
  8 + end
  9 + attr_reader :profile, :blog
  10 +
  11 + should 'require blog' do
  12 + e = ExternalFeed.new(:address => 'http://localhost')
  13 + assert !e.valid?
  14 + e.blog = blog
  15 + assert e.save!
  16 + end
  17 +
  18 + should 'belongs to blog' do
  19 + e = ExternalFeed.create!(:address => 'http://localhost', :blog => blog)
  20 + e.reload
  21 + assert_equal blog, e.blog
  22 + end
  23 +
  24 + should 'not add same item twice' do
  25 + e = ExternalFeed.create!(:address => 'http://localhost', :blog => blog)
  26 + assert e.add_item('Article title', 'http://orig.link.invalid', Time.now, 'Content for external post')
  27 + assert !e.add_item('Article title', 'http://orig.link.invalid', Time.now, 'Content for external post')
  28 + assert_equal 1, e.blog.posts.size
  29 + end
  30 +
  31 + should 'nothing when clear' do
  32 + assert_respond_to ExternalFeed.new, :clear
  33 + end
  34 +
  35 + should 'not limit' do
  36 + assert_equal 0, ExternalFeed.new.limit
  37 + end
  38 +
  39 + should 'disable external feed if fetch only once on finish fetch' do
  40 + e = ExternalFeed.create(:address => 'http://localhost', :blog => blog, :only_once => true, :enabled => true)
  41 + assert e.enabled
  42 + assert e.finish_fetch
  43 + assert !e.enabled
  44 + end
  45 +
  46 + should 'add items to blog as posts' do
  47 + handler = FeedHandler.new
  48 + e = ExternalFeed.create!(:address => 'test/fixtures/files/feed.xml', :blog => blog, :enabled => true)
  49 + handler.process(e)
  50 + assert_equal ["Last POST", "Second POST", "First POST"], e.blog.posts.map{|i| i.title}
  51 + end
  52 +
  53 + should 'require address if enabled' do
  54 + e = ExternalFeed.new(:blog => blog, :enabled => true)
  55 + assert !e.valid?
  56 + end
  57 +
  58 + should 'not require address if disabled' do
  59 + e = ExternalFeed.new(:blog => blog, :enabled => false)
  60 + assert e.valid?
  61 + end
  62 +
  63 +end
test/unit/feed_handler_test.rb
@@ -68,8 +68,8 @@ class FeedHandlerTest &lt; Test::Unit::TestCase @@ -68,8 +68,8 @@ class FeedHandlerTest &lt; Test::Unit::TestCase
68 handler.process(container) 68 handler.process(container)
69 end 69 end
70 70
71 - should 'save after processing' do  
72 - container.expects(:save!) 71 + should 'finish_fetch after processing' do
  72 + container.expects(:finish_fetch)
73 handler.process(container) 73 handler.process(container)
74 end 74 end
75 75
test/unit/feed_reader_block_test.rb
@@ -68,4 +68,9 @@ class FeedReaderBlockTest &lt; ActiveSupport::TestCase @@ -68,4 +68,9 @@ class FeedReaderBlockTest &lt; ActiveSupport::TestCase
68 assert_equal [], feed.feed_items 68 assert_equal [], feed.feed_items
69 end 69 end
70 70
  71 + should 'save! when commit' do
  72 + feed.expects(:save!)
  73 + feed.finish_fetch
  74 + end
  75 +
71 end 76 end
test/unit/profile_test.rb
@@ -1160,7 +1160,7 @@ class ProfileTest &lt; Test::Unit::TestCase @@ -1160,7 +1160,7 @@ class ProfileTest &lt; Test::Unit::TestCase
1160 1160
1161 should 'has blog' do 1161 should 'has blog' do
1162 p = create_user('testuser').person 1162 p = create_user('testuser').person
1163 - b = Blog.create!(:profile => p, :name => 'blog_feed_test') 1163 + p.articles << Blog.new(:profile => p, :name => 'blog_feed_test')
1164 assert p.has_blog? 1164 assert p.has_blog?
1165 end 1165 end
1166 1166
@@ -1169,12 +1169,6 @@ class ProfileTest &lt; Test::Unit::TestCase @@ -1169,12 +1169,6 @@ class ProfileTest &lt; Test::Unit::TestCase
1169 assert !p.has_blog? 1169 assert !p.has_blog?
1170 end 1170 end
1171 1171
1172 - should 'get blog when has blog' do  
1173 - p = create_user('testuser').person  
1174 - b = Blog.create!(:profile => p, :name => 'blog_feed_test')  
1175 - assert_equal b, p.blog  
1176 - end  
1177 -  
1178 should 'get nil when no blog' do 1172 should 'get nil when no blog' do
1179 p = create_user('testuser').person 1173 p = create_user('testuser').person
1180 assert_nil p.blog 1174 assert_nil p.blog
test/unit/published_article_test.rb
@@ -56,10 +56,10 @@ class PublishedArticleTest &lt; ActiveSupport::TestCase @@ -56,10 +56,10 @@ class PublishedArticleTest &lt; ActiveSupport::TestCase
56 @article.expects(:parent).returns(parent) 56 @article.expects(:parent).returns(parent)
57 parent.expects(:blog?).returns(true) 57 parent.expects(:blog?).returns(true)
58 prof = Community.create!(:name => 'test_comm', :identifier => 'test_comm') 58 prof = Community.create!(:name => 'test_comm', :identifier => 'test_comm')
59 - blog = Blog.create!(:profile => prof, :name => 'Blog test') 59 + prof.articles << Blog.new(:profile => prof, :name => 'Blog test')
60 p = PublishedArticle.create!(:reference_article => @article, :profile => prof) 60 p = PublishedArticle.create!(:reference_article => @article, :profile => prof)
61 61
62 - assert_equal p.parent, blog 62 + assert_equal p.parent, prof.blog
63 end 63 end
64 64
65 should 'not be created in community blog if did not come from a blog' do 65 should 'not be created in community blog if did not come from a blog' do
test/unit/rss_feed_test.rb
@@ -109,7 +109,7 @@ class RssFeedTest &lt; Test::Unit::TestCase @@ -109,7 +109,7 @@ class RssFeedTest &lt; Test::Unit::TestCase
109 109
110 should 'list blog posts with more recent first and respecting limit' do 110 should 'list blog posts with more recent first and respecting limit' do
111 profile = create_user('testuser').person 111 profile = create_user('testuser').person
112 - blog = Blog.create(:name => 'blog', :profile => profile) 112 + blog = Blog.create!(:name => 'blog-test', :profile => profile)
113 posts = [] 113 posts = []
114 6.times do |i| 114 6.times do |i|
115 posts << TextArticle.create!(:name => "post #{i}", :profile => profile, :parent => blog) 115 posts << TextArticle.create!(:name => "post #{i}", :profile => profile, :parent => blog)
@@ -123,7 +123,7 @@ class RssFeedTest &lt; Test::Unit::TestCase @@ -123,7 +123,7 @@ class RssFeedTest &lt; Test::Unit::TestCase
123 123
124 should 'list only published posts from blog' do 124 should 'list only published posts from blog' do
125 profile = create_user('testuser').person 125 profile = create_user('testuser').person
126 - blog = Blog.create(:name => 'blog', :profile => profile) 126 + blog = Blog.create!(:name => 'blog-test', :profile => profile)
127 posts = [] 127 posts = []
128 5.times do |i| 128 5.times do |i|
129 posts << TextArticle.create!(:name => "post #{i}", :profile => profile, :parent => blog) 129 posts << TextArticle.create!(:name => "post #{i}", :profile => profile, :parent => blog)
vendor/plugins/active_record_validations_delete/init.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +# monkey patch to remove a single error from the errors collection
  2 +# http://dev.rubyonrails.org/ticket/8137
  3 +
  4 +ActiveRecord::Errors.module_eval do
  5 + # remove a single error from the errors collection by key
  6 + def delete(key)
  7 + @errors.delete(key.to_s)
  8 + end
  9 +end