From 1a2f1931f49d544f3d636a8e3df925dc871b73c5 Mon Sep 17 00:00:00 2001 From: Joenio Costa Date: Fri, 27 Mar 2009 16:47:32 -0300 Subject: [PATCH] ActionItem935: external blog repeater --- app/helpers/blog_helper.rb | 1 + app/helpers/content_viewer_helper.rb | 2 +- app/models/article.rb | 4 ++++ app/models/blog.rb | 33 +++++++++++++++++++++++++++++++-- app/models/blog_archives_block.rb | 4 ++-- app/models/external_feed.rb | 29 +++++++++++++++++++++++++++++ app/models/feed_reader_block.rb | 3 +++ app/views/cms/_blog.rhtml | 26 +++++++++++++++++++++----- app/views/content_viewer/blog_page.rhtml | 4 ++-- app/views/content_viewer/view_page.rhtml | 5 +++++ db/migrate/063_add_published_at_and_source_to_articles.rb | 19 +++++++++++++++++++ db/migrate/064_create_external_feeds.rb | 17 +++++++++++++++++ db/schema.rb | 17 ++++++++++++++++- lib/feed_handler.rb | 2 +- public/stylesheets/article.css | 18 ++++++++++++++++++ public/stylesheets/controller_cms.css | 23 +++++++++++++++++++++++ script/feed-updater | 14 +++++++------- test/functional/cms_controller_test.rb | 43 ++++++++++++++++++++++++++++++++++++++----- test/functional/content_viewer_controller_test.rb | 35 ++++++++++++++++++++++++----------- test/functional/profile_design_controller_test.rb | 2 +- test/functional/profile_editor_controller_test.rb | 2 +- test/unit/article_test.rb | 9 +++++++++ test/unit/blog_archives_block_test.rb | 9 ++++----- test/unit/blog_test.rb | 65 ++++++++++++++++++++++++++++++++++++++++++++--------------------- test/unit/content_viewer_helper_test.rb | 14 +++++++------- test/unit/external_feed_test.rb | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/unit/feed_handler_test.rb | 4 ++-- test/unit/feed_reader_block_test.rb | 5 +++++ test/unit/profile_test.rb | 8 +------- test/unit/published_article_test.rb | 4 ++-- test/unit/rss_feed_test.rb | 4 ++-- vendor/plugins/active_record_validations_delete/init.rb | 9 +++++++++ 32 files changed, 412 insertions(+), 85 deletions(-) create mode 100644 app/models/external_feed.rb create mode 100644 db/migrate/063_add_published_at_and_source_to_articles.rb create mode 100644 db/migrate/064_create_external_feeds.rb create mode 100644 test/unit/external_feed_test.rb create mode 100644 vendor/plugins/active_record_validations_delete/init.rb diff --git a/app/helpers/blog_helper.rb b/app/helpers/blog_helper.rb index 6d829fe..bb918f7 100644 --- a/app/helpers/blog_helper.rb +++ b/app/helpers/blog_helper.rb @@ -35,4 +35,5 @@ module BlogHelper article_title(article) + content_tag('p', article.to_html) + content_tag('p', link_to( number_of_comments(article), article.url.merge(:form => 'opened', :anchor => 'comment_form') ), :class => 'metadata') end + end diff --git a/app/helpers/content_viewer_helper.rb b/app/helpers/content_viewer_helper.rb index d336614..36db7ff 100644 --- a/app/helpers/content_viewer_helper.rb +++ b/app/helpers/content_viewer_helper.rb @@ -20,7 +20,7 @@ module ContentViewerHelper unless args[:no_link] title = content_tag('h3', link_to(article.name, article.url), :class => 'title') end - title << content_tag('span', _("%s, by %s") % [show_date(article.created_at), link_to(article.author.name, article.author.url)], :class => 'created-at') + title << content_tag('span', _("%s, by %s") % [show_date(article.published_at), link_to(article.author.name, article.author.url)], :class => 'created-at') end title end diff --git a/app/models/article.rb b/app/models/article.rb index 9be2845..9b3931c 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -20,6 +20,10 @@ class Article < ActiveRecord::Base settings_items :display_hits, :type => :boolean, :default => true + before_create do |article| + article.published_at = article.created_at if article.published_at.nil? + end + def self.human_attribute_name(attrib) case attrib.to_sym when :name diff --git a/app/models/blog.rb b/app/models/blog.rb index d0de39b..bd7f5be 100644 --- a/app/models/blog.rb +++ b/app/models/blog.rb @@ -1,6 +1,6 @@ class Blog < Folder - has_many :posts, :class_name => 'Article', :foreign_key => 'parent_id', :source => :children, :conditions => [ 'type != ?', 'RssFeed' ], :order => 'created_at DESC' + has_many :posts, :class_name => 'Article', :foreign_key => 'parent_id', :source => :children, :conditions => [ 'type != ?', 'RssFeed' ], :order => 'published_at DESC' attr_accessor :feed_attrs attr_accessor :filter @@ -56,7 +56,7 @@ class Blog < Folder article = self children = if filter and filter[:year] and filter[:month] filter_date = DateTime.parse("#{filter[:year]}-#{filter[:month]}-01") - posts.paginate :page => npage, :per_page => posts_per_page, :conditions => [ 'created_at between ? and ?', filter_date, filter_date + 1.month - 1.day ] + posts.paginate :page => npage, :per_page => posts_per_page, :conditions => [ 'published_at between ? and ?', filter_date, filter_date + 1.month - 1.day ] else posts.paginate :page => npage, :per_page => posts_per_page end @@ -64,4 +64,33 @@ class Blog < Folder render :file => 'content_viewer/blog_page', :locals => {:article => article, :children => children} end end + + has_one :external_feed, :foreign_key => 'blog_id' + + attr_accessor :external_feed_data + def external_feed_builder=(efeed) + self.external_feed_data = efeed + end + + def validate + unless self.external_feed_data.nil? + if self.external_feed(true) && self.external_feed.id == self.external_feed_data[:id].to_i + self.external_feed.attributes = self.external_feed_data + else + self.build_external_feed(self.external_feed_data) + end + self.external_feed.valid? + self.external_feed.errors.delete(:blog_id) # dont validate here relation: external_feed <-> blog + self.external_feed.errors.each do |attr,msg| + self.errors.add(attr, msg) + end + end + end + + after_save do |blog| + if blog.external_feed + blog.external_feed.save + end + end + end diff --git a/app/models/blog_archives_block.rb b/app/models/blog_archives_block.rb index e74a448..74e199d 100644 --- a/app/models/blog_archives_block.rb +++ b/app/models/blog_archives_block.rb @@ -18,10 +18,10 @@ class BlogArchivesBlock < Block return nil unless owner.has_blog? results = '' posts = owner.blog.posts - posts.group_by{|i| i.created_at.year}.each do |year, results_by_year| + posts.group_by{|i| i.published_at.year}.each do |year, results_by_year| results << content_tag('li', content_tag('strong', "#{year} (#{results_by_year.size})")) results << "" diff --git a/app/models/external_feed.rb b/app/models/external_feed.rb new file mode 100644 index 0000000..9d8f8bb --- /dev/null +++ b/app/models/external_feed.rb @@ -0,0 +1,29 @@ +class ExternalFeed < ActiveRecord::Base + + belongs_to :blog + validates_presence_of :blog_id + validates_presence_of :address, :if => lambda {|efeed| efeed.enabled} + validates_uniqueness_of :blog_id + + def add_item(title, link, date, content) + article = TinyMceArticle.new(:name => title, :profile => blog.profile, :body => content, :published_at => date, :source => link, :profile => blog.profile, :parent => blog) + unless blog.children.exists?(:slug => article.slug) + article.save! + end + end + + def clear + # do nothing + end + def finish_fetch + if self.only_once + self.enabled = 'false' + end + self.save! + end + + def limit + 0 + end + +end diff --git a/app/models/feed_reader_block.rb b/app/models/feed_reader_block.rb index 60eea6a..b5d650c 100644 --- a/app/models/feed_reader_block.rb +++ b/app/models/feed_reader_block.rb @@ -48,6 +48,9 @@ class FeedReaderBlock < Block self.feed_items = [] self.feed_title = nil end + def finish_fetch + self.save! + end def content block_title(title) + formatted_feed_content diff --git a/app/views/cms/_blog.rhtml b/app/views/cms/_blog.rhtml index 57414ef..57aab5d 100644 --- a/app/views/cms/_blog.rhtml +++ b/app/views/cms/_blog.rhtml @@ -1,3 +1,5 @@ +<%= error_messages_for 'blog' %> +

<%= _('My Blog') %>

<%= render :file => 'shared/tiny_mce' %> @@ -8,12 +10,26 @@ <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, [5, 10, 20, 50, 100])) %> -<% fields_for 'article[feed]', @article.feed do |feed| %> - -<%= labelled_form_field(_('Limit of posts in RSS Feed'), feed.select(:limit, ['5', '10', '20', '50'])) %> - -<%= labelled_form_field(_('Use as description in RSS Feed:'), feed.select(:feed_item_description, [ [ _('Article abstract'), 'abstract'], [ _('Article body'), 'body']])) %> +<% f.fields_for 'feed', @article.feed do |feed| %> + <%= labelled_form_field(_('Limit of posts in RSS Feed'), feed.select(:limit, ['5', '10', '20', '50'])) %> + <%= labelled_form_field(_('Use as description in RSS Feed:'), feed.select(:feed_item_description, [ [ _('Article abstract'), 'abstract'], [ _('Article body'), 'body']])) %> +<% end %> +<% f.fields_for 'external_feed_builder', @article.external_feed do |efeed| %> +
+ <% enabled = @article.external_feed && @article.external_feed.enabled %> + <% only_once = @article.external_feed ? @article.external_feed.only_once : true %> + <%= labelled_check_box(_('Fetch posts from an external feed'), 'article[external_feed_builder][enabled]', 'true', enabled, {:onchange => "$('external-feed-options').toggle()"}) %> + <%= hidden_field_tag 'article[external_feed_builder][enabled]', 'false' %> +
+ <%= efeed.hidden_field(:id) %> + <%= labelled_form_field( _('Feed address'), efeed.text_field(:address) ) %> +
+ <%= labelled_radio_button( _('Fetch posts only once'), 'article[external_feed_builder][only_once]', 'true', only_once) %> + <%= labelled_radio_button( _('Fetch posts always'), 'article[external_feed_builder][only_once]', 'false', !only_once) %> +
+
+
<% end %> <%= javascript_tag "$('back_to').value = 'control_panel'" %> diff --git a/app/views/content_viewer/blog_page.rhtml b/app/views/content_viewer/blog_page.rhtml index f1bda69..7ec2a36 100644 --- a/app/views/content_viewer/blog_page.rhtml +++ b/app/views/content_viewer/blog_page.rhtml @@ -1,5 +1,5 @@ +<%= 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? %> +
<%= article.body %>

<%= (children.compact.empty? ? content_tag('em', _('(no posts)')) : list_posts(user, children)) %> - - diff --git a/app/views/content_viewer/view_page.rhtml b/app/views/content_viewer/view_page.rhtml index a5f1c12..849e917 100644 --- a/app/views/content_viewer/view_page.rhtml +++ b/app/views/content_viewer/view_page.rhtml @@ -97,6 +97,11 @@ <% end %> +<% if ! @page.source.nil? and ! @page.source.empty?%> +
+ <%= _('Source: %s') % link_to(@page.source, @page.source) %> +
+<% end %>
<% if @page.accept_comments? %> diff --git a/db/migrate/063_add_published_at_and_source_to_articles.rb b/db/migrate/063_add_published_at_and_source_to_articles.rb new file mode 100644 index 0000000..69cb183 --- /dev/null +++ b/db/migrate/063_add_published_at_and_source_to_articles.rb @@ -0,0 +1,19 @@ +class AddPublishedAtAndSourceToArticles < ActiveRecord::Migration + def self.up + add_column :articles, :published_at, :date + add_column :article_versions, :published_at, :date + + execute('UPDATE articles SET published_at = created_at WHERE published_at IS NULL') + execute('UPDATE article_versions SET published_at = created_at WHERE published_at IS NULL') + + add_column :articles, :source, :string, :null => true + add_column :article_versions, :source, :string, :null => true + end + + def self.down + remove_column :articles, :published_at + remove_column :article_versions, :published_at + remove_column :articles, :source + remove_column :article_versions, :source + end +end diff --git a/db/migrate/064_create_external_feeds.rb b/db/migrate/064_create_external_feeds.rb new file mode 100644 index 0000000..b368752 --- /dev/null +++ b/db/migrate/064_create_external_feeds.rb @@ -0,0 +1,17 @@ +class CreateExternalFeeds < ActiveRecord::Migration + def self.up + create_table :external_feeds do |t| + t.string :feed_title + t.date :fetched_at + t.string :address + t.integer :blog_id, :null => false + t.boolean :enabled, :null => false, :default => true + t.boolean :only_once, :null => false, :default => true + t.timestamps + end + end + + def self.down + drop_table :external_feeds + end +end diff --git a/db/schema.rb b/db/schema.rb index e90ad0c..b72bebe 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -9,7 +9,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 62) do +ActiveRecord::Schema.define(:version => 64) do create_table "article_versions", :force => true do |t| t.integer "article_id" @@ -42,6 +42,8 @@ ActiveRecord::Schema.define(:version => 62) do t.text "setting" t.boolean "notify_comments", :default => false t.integer "hits", :default => 0 + t.date "published_at" + t.string "source" end create_table "articles", :force => true do |t| @@ -75,6 +77,8 @@ ActiveRecord::Schema.define(:version => 62) do t.text "setting" t.boolean "notify_comments", :default => true t.integer "hits", :default => 0 + t.date "published_at" + t.string "source" end create_table "articles_categories", :id => false, :force => true do |t| @@ -160,6 +164,17 @@ ActiveRecord::Schema.define(:version => 62) do t.string "theme" end + create_table "external_feeds", :force => true do |t| + t.string "feed_title" + t.date "fetched_at" + t.string "address" + t.integer "blog_id", :null => false + t.boolean "enabled", :default => true, :null => false + t.boolean "only_once", :default => true, :null => false + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "favorite_enteprises_people", :id => false, :force => true do |t| t.integer "person_id" t.integer "enterprise_id" diff --git a/lib/feed_handler.rb b/lib/feed_handler.rb index 273bffa..df87208 100644 --- a/lib/feed_handler.rb +++ b/lib/feed_handler.rb @@ -32,7 +32,7 @@ class FeedHandler parse.items[0..container.limit-1].each do |item| container.add_item(item.title, item.link, item.date, item.content) end - container.save! + container.finish_fetch end end diff --git a/public/stylesheets/article.css b/public/stylesheets/article.css index cd60bce..f5633f8 100644 --- a/public/stylesheets/article.css +++ b/public/stylesheets/article.css @@ -32,6 +32,16 @@ font-size: 10px; } +#article-source { + color: #999; + font-size: 11px; + text-align: right; + font-weight: bold; +} +#article-source a { + font-weight: normal; +} + /* * * Comments * * */ .comments { } @@ -183,12 +193,18 @@ margin-bottom: 2px; } +.metadata, .blog-post .metadata { display: block; text-align: center; font-size: small; } +.metadata { + text-align: right; + color: gray; +} + #content .created-at { color: gray; font-size: small; @@ -237,3 +253,5 @@ text-align: center; font-size: small; } + + diff --git a/public/stylesheets/controller_cms.css b/public/stylesheets/controller_cms.css index de68c30..b5c700c 100644 --- a/public/stylesheets/controller_cms.css +++ b/public/stylesheets/controller_cms.css @@ -122,3 +122,26 @@ div.file-manager-button a:hover { .file-manager-small .file-manager-controls * { text-align: right; } + +/************* external blog options *****************/ + +#fetch-external-feed { + border: 1px solid #EEE; + padding: 5px; + margin: 5px 0; + width: 460px +} +#fetch-external-feed label, +#fetch-external-feed .formfield, +#fetch-external-feed #external-feed-options #external-feed-options-only-once label, +#fetch-external-feed #external-feed-options #external-feed-options-only-once .formfieldline, +#fetch-external-feed #external-feed-options #external-feed-options-only-once .formfield { + display: inline; +} +#fetch-external-feed .type-text input { + width: 400px; +} +#fetch-external-feed #external-feed-options label, +#fetch-external-feed #external-feed-options .formfield { + display: block; +} diff --git a/script/feed-updater b/script/feed-updater index 4b4d94f..ac2cf1c 100755 --- a/script/feed-updater +++ b/script/feed-updater @@ -1,18 +1,18 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../config/environment' -FeedReaderBlock.find(:all).each do |feed_block| - unless feed_block.address.nil? +(FeedReaderBlock.find(:all) + ExternalFeed.find(:all, :conditions => {:enabled => true})).each do |container| + unless container.address.nil? begin handler = FeedHandler.new - handler.process(feed_block) - RAILS_DEFAULT_LOGGER.info("%s ID %d fetched at %s" % [feed_block.class.name, feed_block.id, feed_block.fetched_at]) + handler.process(container) + RAILS_DEFAULT_LOGGER.info("%s ID %d fetched at %s" % [container.class.name, container.id, container.fetched_at]) rescue FeedHandler::ParseError => ex - RAILS_DEFAULT_LOGGER.warn("Error parsing content from %s ID %d\n%s" % [feed_block.class.name, feed_block.id, ex.to_s]) + RAILS_DEFAULT_LOGGER.warn("Error parsing content from %s ID %d\n%s" % [container.class.name, container.id, ex.to_s]) rescue FeedHandler::FetchError => ex - RAILS_DEFAULT_LOGGER.warn("Error fetching content from %s ID %d\n%s" % [feed_block.class.name, feed_block.id, ex.to_s]) + RAILS_DEFAULT_LOGGER.warn("Error fetching content from %s ID %d\n%s" % [container.class.name, container.id, ex.to_s]) rescue Exception => ex - RAILS_DEFAULT_LOGGER.warn("Unknown error from %s ID %d\n%s" % [feed_block.class.name, feed_block.id, ex.to_s]) + RAILS_DEFAULT_LOGGER.warn("Unknown error from %s ID %d\n%s" % [container.class.name, container.id, ex.to_s]) end end end diff --git a/test/functional/cms_controller_test.rb b/test/functional/cms_controller_test.rb index 4cc4a22..1081378 100644 --- a/test/functional/cms_controller_test.rb +++ b/test/functional/cms_controller_test.rb @@ -716,7 +716,7 @@ class CmsControllerTest < Test::Unit::TestCase end should 'offer to edit a blog' do - profile.articles << Blog.new(:name => 'blog test') + profile.articles << Blog.new(:name => 'blog test', :profile => profile) profile.articles.reload assert profile.has_blog? @@ -727,7 +727,7 @@ class CmsControllerTest < Test::Unit::TestCase end should 'not offer to add folder to blog' do - profile.articles << Blog.new(:name => 'blog test') + profile.articles << Blog.new(:name => 'blog test', :profile => profile) profile.articles.reload assert profile.has_blog? @@ -737,7 +737,7 @@ class CmsControllerTest < Test::Unit::TestCase end should 'not show feed subitem for blog' do - profile.articles << Blog.new(:name => 'Blog for test') + profile.articles << Blog.new(:name => 'Blog for test', :profile => profile) profile.articles.reload assert profile.has_blog? @@ -748,7 +748,7 @@ class CmsControllerTest < Test::Unit::TestCase end should 'update feed options by edit blog form' do - profile.articles << Blog.new(:name => 'Blog for test') + profile.articles << Blog.new(:name => 'Blog for test', :profile => profile) post :edit, :profile => profile.identifier, :id => profile.blog.id, :article => { :feed => { :limit => 7 } } assert_equal 7, profile.blog.feed.limit end @@ -770,8 +770,9 @@ class CmsControllerTest < Test::Unit::TestCase end should 'update blog posts_per_page setting' do - profile.articles << Blog.new(:name => 'Blog for test') + profile.articles << Blog.new(:name => 'Blog for test', :profile => profile) post :edit, :profile => profile.identifier, :id => profile.blog.id, :article => { :posts_per_page => 5 } + profile.blog.reload assert_equal 5, profile.blog.posts_per_page end @@ -909,4 +910,36 @@ class CmsControllerTest < Test::Unit::TestCase assert_template nil assert_redirected_to file.url.merge(:view => true) end + + should 'display external feed options when edit blog' do + get :new, :profile => profile.identifier, :type => 'Blog' + assert_tag :tag => 'input', :attributes => { :name => 'article[external_feed_builder][enabled]' } + assert_tag :tag => 'input', :attributes => { :name => 'article[external_feed_builder][address]' } + end + + should "display 'Fetch posts from an external feed' checked if blog has enabled external feed" do + profile.articles << Blog.new(:title => 'test blog', :profile => profile) + profile.blog.create_external_feed(:address => 'address', :enabled => true) + get :edit, :profile => profile.identifier, :id => profile.blog.id + assert_tag :tag => 'input', :attributes => { :name => 'article[external_feed_builder][enabled]', :checked => 'checked' } + end + + should "display 'Fetch posts from an external feed' unchecked if blog has disabled external feed" do + profile.articles << Blog.new(:title => 'test blog', :profile => profile) + profile.blog.create_external_feed(:address => 'address', :enabled => false) + get :edit, :profile => profile.identifier, :id => profile.blog.id + assert_tag :tag => 'input', :attributes => { :name => 'article[external_feed_builder][enabled]', :checked => nil } + end + + should "hide external feed options when 'Fetch posts from an external feed' unchecked" do + get :new, :profile => profile.identifier, :type => 'Blog' + assert_tag :tag => 'input', :attributes => { :name => 'article[external_feed_builder][enabled]', :checked => nil } + assert_tag :tag => 'div', :attributes => { :id => 'external-feed-options', :style => 'display: none' } + end + + should 'only_once option marked by default' do + get :new, :profile => profile.identifier, :type => 'Blog' + assert_tag :tag => 'input', :attributes => { :name => 'article[external_feed_builder][only_once]', :checked => 'checked', :value => 'true' } + end + end diff --git a/test/functional/content_viewer_controller_test.rb b/test/functional/content_viewer_controller_test.rb index ea609f0..b1a7cc7 100644 --- a/test/functional/content_viewer_controller_test.rb +++ b/test/functional/content_viewer_controller_test.rb @@ -14,8 +14,9 @@ class ContentViewerControllerTest < Test::Unit::TestCase @response = ActionController::TestResponse.new @profile = create_user('testinguser').person + @environment = @profile.environment end - attr_reader :profile + attr_reader :profile, :environment def test_local_files_reference page = profile.articles.build(:name => 'test') @@ -638,9 +639,9 @@ class ContentViewerControllerTest < Test::Unit::TestCase end should 'extract year and month from path' do - blog = Blog.create!(:name => 'A blog test', :profile => profile) - year, month = blog.created_at.year.to_s, '%02d' % blog.created_at.month - get :view_page, :profile => profile.identifier, :page => [blog.path, year, month] + profile.articles << Blog.new(:name => 'A blog test', :profile => profile) + year, month = profile.blog.created_at.year.to_s, '%02d' % profile.blog.created_at.month + get :view_page, :profile => profile.identifier, :page => [profile.blog.path, year, month] assert_equal({ :year => year.to_s, :month => month.to_s }, assigns(:page).filter) end @@ -693,17 +694,17 @@ class ContentViewerControllerTest < Test::Unit::TestCase should 'add meta tag to rss feed on view blog' do login_as(profile.identifier) - a = Blog.create!(:name => 'article folder', :profile => profile) - get :view_page, :profile => profile.identifier, :page => [a.path] - assert_tag :tag => 'link', :attributes => { :rel => 'alternate', :type => 'application/rss+xml', :title => 'feed', :href => /\/#{profile.identifier}\/blog\/feed/} + profile.articles << Blog.new(:title => 'article blog', :profile => profile) + get :view_page, :profile => profile.identifier, :page => ['blog'] + assert_tag :tag => 'link', :attributes => { :rel => 'alternate', :type => 'application/rss+xml', :title => 'feed', :href => "http://#{environment.default_hostname}/testinguser/blog/feed" } end should 'add meta tag to rss feed on view post blog' do login_as(profile.identifier) - a = Blog.create!(:name => 'article folder', :profile => profile) - t = TextileArticle.create!(:name => 'first post', :parent => a, :profile => profile) - get :view_page, :profile => profile.identifier, :page => [t.path] - assert_tag :tag => 'link', :attributes => { :rel => 'alternate', :type => 'application/rss+xml', :title => 'feed', :href => /\/#{profile.identifier}\/blog\/feed/} + profile.articles << Blog.new(:name => 'article folder', :profile => profile) + profile.blog.posts << TextileArticle.new(:name => 'first post', :parent => profile.blog, :profile => profile) + get :view_page, :profile => profile.identifier, :page => ['blog', 'first-post'] + assert_tag :tag => 'link', :attributes => { :rel => 'alternate', :type => 'application/rss+xml', :title => 'feed', :href => "http://#{environment.default_hostname}/testinguser/blog/feed" } end should 'link to post with comment form opened' do @@ -787,4 +788,16 @@ class ContentViewerControllerTest < Test::Unit::TestCase assert_template 'slideshow' end + should 'display source from article' do + profile.articles << TextileArticle.new(:name => "Article one", :profile => profile, :source => 'http://www.original-source.invalid') + get :view_page, :profile => profile.identifier, :page => ['article-one'] + assert_tag :tag => 'div', :attributes => { :id => 'article-source' }, :content => /http:\/\/www.original-source.invalid/ + end + + should 'not display source if article has no source' do + profile.articles << TextileArticle.new(:name => "Article one", :profile => profile) + get :view_page, :profile => profile.identifier, :page => ['article-one'] + assert_no_tag :tag => 'div', :attributes => { :id => 'article-source' } + end + end diff --git a/test/functional/profile_design_controller_test.rb b/test/functional/profile_design_controller_test.rb index 15ab0ae..eaa854d 100644 --- a/test/functional/profile_design_controller_test.rb +++ b/test/functional/profile_design_controller_test.rb @@ -274,7 +274,7 @@ class ProfileDesignControllerTest < Test::Unit::TestCase end should 'offer to create blog archives block only if has blog' do - Blog.create!(:name => 'Blog test', :profile => holder) + holder.articles << Blog.new(:name => 'Blog test', :profile => holder) get :add_block, :profile => 'designtestuser' assert_tag :tag => 'input', :attributes => { :id => 'type_blogarchivesblock', :value => 'BlogArchivesBlock' } end diff --git a/test/functional/profile_editor_controller_test.rb b/test/functional/profile_editor_controller_test.rb index c920138..7b402fe 100644 --- a/test/functional/profile_editor_controller_test.rb +++ b/test/functional/profile_editor_controller_test.rb @@ -628,7 +628,7 @@ class ProfileEditorControllerTest < Test::Unit::TestCase should 'offer to config blog in control panel' do profile.articles << Blog.new(:name => 'My blog', :profile => profile) - get :index, :profile => 'default_user' + get :index, :profile => profile.identifier assert_tag :tag => 'a', :attributes => { :href => "/myprofile/default_user/cms/edit/#{profile.blog.id}" } end diff --git a/test/unit/article_test.rb b/test/unit/article_test.rb index 7b683a6..26fe24e 100644 --- a/test/unit/article_test.rb +++ b/test/unit/article_test.rb @@ -684,4 +684,13 @@ class ArticleTest < Test::Unit::TestCase assert_equal profile, Article.new(:last_changed_by => nil, :profile => profile).author end + should 'have published_at' do + assert_respond_to Article.new, :published_at + end + + should 'published_at is same as created_at if not set' do + a = Article.create!(:name => 'Published at', :profile => profile) + assert_equal a.created_at, a.published_at + end + end diff --git a/test/unit/blog_archives_block_test.rb b/test/unit/blog_archives_block_test.rb index df61967..de5b519 100644 --- a/test/unit/blog_archives_block_test.rb +++ b/test/unit/blog_archives_block_test.rb @@ -4,7 +4,7 @@ class BlogArchivesBlockTest < ActiveSupport::TestCase def setup @profile = create_user('flatline').person - @profile.articles << Blog.new(:name => 'blog', :profile => @profile) + @profile.articles << Blog.new(:name => 'blog-test', :profile => @profile) end attr_reader :profile @@ -22,7 +22,7 @@ class BlogArchivesBlockTest < ActiveSupport::TestCase blog = profile.blog for i in 1..10 do post = TextileArticle.create!(:name => "post #{i} test", :profile => profile, :parent => blog) - post.update_attribute(:created_at, date) + post.update_attribute(:published_at, date) end block = BlogArchivesBlock.new block.stubs(:owner).returns(profile) @@ -34,19 +34,18 @@ class BlogArchivesBlockTest < ActiveSupport::TestCase blog = profile.blog for i in 1..10 do post = TextileArticle.create!(:name => "post #{i} test", :profile => profile, :parent => blog) - post.update_attribute(:created_at, date) + post.update_attribute(:published_at, date) end block = BlogArchivesBlock.new block.stubs(:owner).returns(profile) assert_tag_in_string block.content, :tag => 'a', :content => 'January (10)', :attributes => {:href => /2008\/01/} end - should 'order list of amount posts' do blog = profile.blog for i in 1..10 do post = TextileArticle.create!(:name => "post #{i} test", :profile => profile, :parent => blog) - post.update_attribute(:created_at, DateTime.parse("2008-#{i}-01")) + post.update_attribute(:published_at, DateTime.parse("2008-#{i}-01")) end block = BlogArchivesBlock.new block.stubs(:owner).returns(profile) diff --git a/test/unit/blog_test.rb b/test/unit/blog_test.rb index 9ff34a6..744ec4a 100644 --- a/test/unit/blog_test.rb +++ b/test/unit/blog_test.rb @@ -38,24 +38,16 @@ class BlogTest < ActiveSupport::TestCase assert_equal 'body', b.feed.feed_item_description end - should 'get first blog from profile' do - p = create_user('testuser').person - b = Blog.create!(:profile => p, :name => 'blog_feed_test') - assert_equal p.blog, b - end - should 'save feed options' do p = create_user('testuser').person - b = Blog.create!(:profile => p, :name => 'blog_feed_test') + p.articles << Blog.new(:profile => p, :name => 'blog_feed_test') p.blog.feed = { :limit => 7 } assert_equal 7, p.blog.feed.limit end should 'save feed options after create blog' do p = create_user('testuser').person - b = Blog.create!(:profile => p, :name => 'blog_feed_test', :feed => { :limit => 7 }) - - p.blog.feed.reload + p.articles << Blog.new(:profile => p, :name => 'blog_feed_test', :feed => { :limit => 7 }) assert_equal 7, p.blog.feed.limit end @@ -65,16 +57,16 @@ class BlogTest < ActiveSupport::TestCase end should 'update posts per page setting' do - p = create_user('testusermerda').person - blog = Blog.create!(:profile => p, :name => 'Blog test') - blog.reload - blog.posts_per_page = 5 + p = create_user('testuser').person + p.articles << Blog.new(:profile => p, :name => 'Blog test') + blog = p.blog + blog.posts_per_page = 7 assert blog.save! - assert_equal 5, blog.posts_per_page + assert_equal 7, p.blog.posts_per_page end should 'has posts' do - p = create_user('testusermerda').person + p = create_user('testuser').person blog = Blog.create!(:profile => p, :name => 'Blog test') post = TextileArticle.create!(:name => 'First post', :profile => p, :parent => blog) blog.children << post @@ -82,25 +74,56 @@ class BlogTest < ActiveSupport::TestCase end should 'not includes rss feed in posts' do - p = create_user('testusermerda').person + p = create_user('testuser').person blog = Blog.create!(:profile => p, :name => 'Blog test') assert_includes blog.children, blog.feed assert_not_includes blog.posts, blog.feed end - should 'list posts ordered by created at' do - p = create_user('testusermerda').person + should 'list posts ordered by published at' do + p = create_user('testuser').person blog = Blog.create!(:profile => p, :name => 'Blog test') newer = TextileArticle.create!(:name => 'Post 2', :parent => blog, :profile => p) - older = TextileArticle.create!(:name => 'Post 1', :parent => blog, :profile => p, :created_at => Time.now - 1.month) + older = TextileArticle.create!(:name => 'Post 1', :parent => blog, :profile => p, :published_at => Time.now - 1.month) assert_equal [newer, older], blog.posts end should 'has filter' do - p = create_user('testusermerda').person + p = create_user('testuser').person blog = Blog.create!(:profile => p, :name => 'Blog test') blog.filter = {:param => 'value'} assert_equal 'value', blog.filter[:param] end + should 'has one external feed' do + p = create_user('testuser').person + blog = Blog.create!(:profile => p, :name => 'Blog test') + efeed = blog.create_external_feed(:address => 'http://invalid.url') + assert_equal efeed, blog.external_feed + end + + should 'build external feed after save' do + p = create_user('testuser').person + blog = Blog.new(:profile => p, :name => 'Blog test') + blog.external_feed_builder = { :address => 'feed address' } + blog.save! + assert blog.external_feed.valid? + end + + should 'update external feed' do + p = create_user('testuser').person + blog = Blog.new(:profile => p, :name => 'Blog test') + blog.create_external_feed(:address => 'feed address') + blog.external_feed_builder = { :address => 'address edited' } + blog.save! + assert_equal 'address edited', blog.external_feed.address + end + + should 'invalid blog if has invalid external_feed' do + p = create_user('testuser').person + blog = Blog.new(:profile => p, :name => 'Blog test', :external_feed_builder => {:enabled => true}) + blog.save + assert ! blog.valid? + end + end diff --git a/test/unit/content_viewer_helper_test.rb b/test/unit/content_viewer_helper_test.rb index bff0db0..8616085 100644 --- a/test/unit/content_viewer_helper_test.rb +++ b/test/unit/content_viewer_helper_test.rb @@ -11,17 +11,17 @@ class ContentViewerHelperTest < Test::Unit::TestCase end attr :profile - should 'display created-at for blog posts' do + should 'display published-at for blog posts' do blog = Blog.create!(:name => 'Blog test', :profile => profile) post = TextileArticle.create!(:name => 'post test', :profile => profile, :parent => blog) result = article_title(post) - assert_match /#{show_date(post.created_at)}, by .*#{profile.identifier}/, result + assert_match /#{show_date(post.published_at)}, by .*#{profile.identifier}/, result end - should 'not display created-at for non-blog posts' do + should 'not display published-at for non-blog posts' do article = TextileArticle.create!(:name => 'article for test', :profile => profile) result = article_title(article) - assert_no_match /#{show_date(article.created_at)}, by .*#{profile.identifier}/, result + assert_no_match /#{show_date(article.published_at)}, by .*#{profile.identifier}/, result end should 'create link on title of blog posts' do @@ -54,7 +54,7 @@ class ContentViewerHelperTest < Test::Unit::TestCase end should 'not list feed article' do - profile.articles << Blog.new(:name => 'Blog test') + profile.articles << Blog.new(:name => 'Blog test', :profile => profile) assert_includes profile.blog.children.map{|i| i.class}, RssFeed result = list_posts(nil, profile.blog.posts) assert_no_match /feed/, result @@ -64,10 +64,10 @@ class ContentViewerHelperTest < Test::Unit::TestCase blog = Blog.create!(:name => 'Blog test', :profile => profile) nov = TextileArticle.create!(:name => 'November post', :parent => blog, :profile => profile) - nov.update_attributes!(:created_at => DateTime.parse('2008-11-15')) + nov.update_attributes!(:published_at => DateTime.parse('2008-11-15')) sep = TextileArticle.create!(:name => 'September post', :parent => blog, :profile => profile) - sep.update_attribute(:created_at, DateTime.parse('2008-09-10')) + sep.update_attribute(:published_at, DateTime.parse('2008-09-10')) blog.reload blog.filter = {:year => 2008, :month => 11} diff --git a/test/unit/external_feed_test.rb b/test/unit/external_feed_test.rb new file mode 100644 index 0000000..a0a3a32 --- /dev/null +++ b/test/unit/external_feed_test.rb @@ -0,0 +1,63 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class ExternalFeedTest < ActiveSupport::TestCase + + def setup + @profile = create_user('test-person').person + @blog = Blog.create!(:name => 'test-blog', :profile => @profile) + end + attr_reader :profile, :blog + + should 'require blog' do + e = ExternalFeed.new(:address => 'http://localhost') + assert !e.valid? + e.blog = blog + assert e.save! + end + + should 'belongs to blog' do + e = ExternalFeed.create!(:address => 'http://localhost', :blog => blog) + e.reload + assert_equal blog, e.blog + end + + should 'not add same item twice' do + e = ExternalFeed.create!(:address => 'http://localhost', :blog => blog) + assert e.add_item('Article title', 'http://orig.link.invalid', Time.now, 'Content for external post') + assert !e.add_item('Article title', 'http://orig.link.invalid', Time.now, 'Content for external post') + assert_equal 1, e.blog.posts.size + end + + should 'nothing when clear' do + assert_respond_to ExternalFeed.new, :clear + end + + should 'not limit' do + assert_equal 0, ExternalFeed.new.limit + end + + should 'disable external feed if fetch only once on finish fetch' do + e = ExternalFeed.create(:address => 'http://localhost', :blog => blog, :only_once => true, :enabled => true) + assert e.enabled + assert e.finish_fetch + assert !e.enabled + end + + should 'add items to blog as posts' do + handler = FeedHandler.new + e = ExternalFeed.create!(:address => 'test/fixtures/files/feed.xml', :blog => blog, :enabled => true) + handler.process(e) + assert_equal ["Last POST", "Second POST", "First POST"], e.blog.posts.map{|i| i.title} + end + + should 'require address if enabled' do + e = ExternalFeed.new(:blog => blog, :enabled => true) + assert !e.valid? + end + + should 'not require address if disabled' do + e = ExternalFeed.new(:blog => blog, :enabled => false) + assert e.valid? + end + +end diff --git a/test/unit/feed_handler_test.rb b/test/unit/feed_handler_test.rb index 88a0796..ff5b3ca 100644 --- a/test/unit/feed_handler_test.rb +++ b/test/unit/feed_handler_test.rb @@ -68,8 +68,8 @@ class FeedHandlerTest < Test::Unit::TestCase handler.process(container) end - should 'save after processing' do - container.expects(:save!) + should 'finish_fetch after processing' do + container.expects(:finish_fetch) handler.process(container) end diff --git a/test/unit/feed_reader_block_test.rb b/test/unit/feed_reader_block_test.rb index 1b8ff67..53eef41 100644 --- a/test/unit/feed_reader_block_test.rb +++ b/test/unit/feed_reader_block_test.rb @@ -68,4 +68,9 @@ class FeedReaderBlockTest < ActiveSupport::TestCase assert_equal [], feed.feed_items end + should 'save! when commit' do + feed.expects(:save!) + feed.finish_fetch + end + end diff --git a/test/unit/profile_test.rb b/test/unit/profile_test.rb index 34fce7b..31e78b9 100644 --- a/test/unit/profile_test.rb +++ b/test/unit/profile_test.rb @@ -1160,7 +1160,7 @@ class ProfileTest < Test::Unit::TestCase should 'has blog' do p = create_user('testuser').person - b = Blog.create!(:profile => p, :name => 'blog_feed_test') + p.articles << Blog.new(:profile => p, :name => 'blog_feed_test') assert p.has_blog? end @@ -1169,12 +1169,6 @@ class ProfileTest < Test::Unit::TestCase assert !p.has_blog? end - should 'get blog when has blog' do - p = create_user('testuser').person - b = Blog.create!(:profile => p, :name => 'blog_feed_test') - assert_equal b, p.blog - end - should 'get nil when no blog' do p = create_user('testuser').person assert_nil p.blog diff --git a/test/unit/published_article_test.rb b/test/unit/published_article_test.rb index 2ca0889..c7d5f3f 100644 --- a/test/unit/published_article_test.rb +++ b/test/unit/published_article_test.rb @@ -56,10 +56,10 @@ class PublishedArticleTest < ActiveSupport::TestCase @article.expects(:parent).returns(parent) parent.expects(:blog?).returns(true) prof = Community.create!(:name => 'test_comm', :identifier => 'test_comm') - blog = Blog.create!(:profile => prof, :name => 'Blog test') + prof.articles << Blog.new(:profile => prof, :name => 'Blog test') p = PublishedArticle.create!(:reference_article => @article, :profile => prof) - assert_equal p.parent, blog + assert_equal p.parent, prof.blog end should 'not be created in community blog if did not come from a blog' do diff --git a/test/unit/rss_feed_test.rb b/test/unit/rss_feed_test.rb index a05bc7f..b49916f 100644 --- a/test/unit/rss_feed_test.rb +++ b/test/unit/rss_feed_test.rb @@ -109,7 +109,7 @@ class RssFeedTest < Test::Unit::TestCase should 'list blog posts with more recent first and respecting limit' do profile = create_user('testuser').person - blog = Blog.create(:name => 'blog', :profile => profile) + blog = Blog.create!(:name => 'blog-test', :profile => profile) posts = [] 6.times do |i| posts << TextArticle.create!(:name => "post #{i}", :profile => profile, :parent => blog) @@ -123,7 +123,7 @@ class RssFeedTest < Test::Unit::TestCase should 'list only published posts from blog' do profile = create_user('testuser').person - blog = Blog.create(:name => 'blog', :profile => profile) + blog = Blog.create!(:name => 'blog-test', :profile => profile) posts = [] 5.times do |i| posts << TextArticle.create!(:name => "post #{i}", :profile => profile, :parent => blog) diff --git a/vendor/plugins/active_record_validations_delete/init.rb b/vendor/plugins/active_record_validations_delete/init.rb new file mode 100644 index 0000000..475c3b2 --- /dev/null +++ b/vendor/plugins/active_record_validations_delete/init.rb @@ -0,0 +1,9 @@ +# monkey patch to remove a single error from the errors collection +# http://dev.rubyonrails.org/ticket/8137 + +ActiveRecord::Errors.module_eval do + # remove a single error from the errors collection by key + def delete(key) + @errors.delete(key.to_s) + end +end -- libgit2 0.21.2