From 718c0f5679b256174d7b8ee3674e12be4b81d55e Mon Sep 17 00:00:00 2001 From: Rodrigo Souto Date: Tue, 21 Aug 2012 17:28:37 +0000 Subject: [PATCH] [tolerance-time] Tolerance Time Plugin --- plugins/tolerance_time/controllers/tolerance_time_plugin_myprofile_controller.rb | 37 +++++++++++++++++++++++++++++++++++++ plugins/tolerance_time/db/migrate/20120719090320_create_tolerance_time_plugin_tolerances.rb | 13 +++++++++++++ plugins/tolerance_time/db/migrate/20120719095004_create_tolerance_time_plugin_publications.rb | 12 ++++++++++++ plugins/tolerance_time/lib/ext/article.rb | 23 +++++++++++++++++++++++ plugins/tolerance_time/lib/ext/comment.rb | 13 +++++++++++++ plugins/tolerance_time/lib/tolerance_time_plugin.rb | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ plugins/tolerance_time/lib/tolerance_time_plugin/publication.rb | 25 +++++++++++++++++++++++++ plugins/tolerance_time/lib/tolerance_time_plugin/tolerance.rb | 7 +++++++ plugins/tolerance_time/public/icons/tolerance-time.png | Bin 0 -> 4822 bytes plugins/tolerance_time/public/style.css | 4 ++++ plugins/tolerance_time/test/unit/article_test.rb | 33 +++++++++++++++++++++++++++++++++ plugins/tolerance_time/test/unit/comment_test.rb | 24 ++++++++++++++++++++++++ plugins/tolerance_time/test/unit/tolerance_time_plugin/publication_test.rb | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ plugins/tolerance_time/test/unit/tolerance_time_plugin/tolerance_test.rb | 37 +++++++++++++++++++++++++++++++++++++ plugins/tolerance_time/views/tolerance_time_plugin_myprofile/index.html.erb | 24 ++++++++++++++++++++++++ 15 files changed, 368 insertions(+), 0 deletions(-) create mode 100644 plugins/tolerance_time/controllers/tolerance_time_plugin_myprofile_controller.rb create mode 100644 plugins/tolerance_time/db/migrate/20120719090320_create_tolerance_time_plugin_tolerances.rb create mode 100644 plugins/tolerance_time/db/migrate/20120719095004_create_tolerance_time_plugin_publications.rb create mode 100644 plugins/tolerance_time/lib/ext/article.rb create mode 100644 plugins/tolerance_time/lib/ext/comment.rb create mode 100644 plugins/tolerance_time/lib/tolerance_time_plugin.rb create mode 100644 plugins/tolerance_time/lib/tolerance_time_plugin/publication.rb create mode 100644 plugins/tolerance_time/lib/tolerance_time_plugin/tolerance.rb create mode 100644 plugins/tolerance_time/public/icons/tolerance-time.png create mode 100644 plugins/tolerance_time/public/style.css create mode 100644 plugins/tolerance_time/test/unit/article_test.rb create mode 100644 plugins/tolerance_time/test/unit/comment_test.rb create mode 100644 plugins/tolerance_time/test/unit/tolerance_time_plugin/publication_test.rb create mode 100644 plugins/tolerance_time/test/unit/tolerance_time_plugin/tolerance_test.rb create mode 100644 plugins/tolerance_time/views/tolerance_time_plugin_myprofile/index.html.erb diff --git a/plugins/tolerance_time/controllers/tolerance_time_plugin_myprofile_controller.rb b/plugins/tolerance_time/controllers/tolerance_time_plugin_myprofile_controller.rb new file mode 100644 index 0000000..391dddc --- /dev/null +++ b/plugins/tolerance_time/controllers/tolerance_time_plugin_myprofile_controller.rb @@ -0,0 +1,37 @@ +class ToleranceTimePluginMyprofileController < MyProfileController + def index + @tolerance = ToleranceTimePlugin::Tolerance.find_by_profile_id(profile.id) || ToleranceTimePlugin::Tolerance.create!(:profile => profile) + convert_values + if request.post? + begin + convert_params + @tolerance.update_attributes!(params[:tolerance]) + convert_values + session[:notice] = _('Tolerance updated') + rescue + session[:notice] = _('Tolerance could not be updated') + end + end + end + + private + + def convert_params + params[:tolerance][:content_tolerance] = params[:tolerance][:content_tolerance].to_i * params[:content_tolerance_unit].to_i if !params[:tolerance][:content_tolerance].blank? + params[:tolerance][:comment_tolerance] = params[:tolerance][:comment_tolerance].to_i * params[:comment_tolerance_unit].to_i if !params[:tolerance][:comment_tolerance].blank? + end + + def convert_values + @content_default_unit = select_unit(@tolerance.content_tolerance) + @comment_default_unit = select_unit(@tolerance.comment_tolerance) + @tolerance.content_tolerance /= @content_default_unit if !@tolerance.content_tolerance.nil? + @tolerance.comment_tolerance /= @comment_default_unit if !@tolerance.comment_tolerance.nil? + end + + def select_unit(value) + return 1 if value.nil? || value == 0 + return 3600 if value % 3600 == 0 + return 60 if value % 60 == 0 + return 1 + end +end diff --git a/plugins/tolerance_time/db/migrate/20120719090320_create_tolerance_time_plugin_tolerances.rb b/plugins/tolerance_time/db/migrate/20120719090320_create_tolerance_time_plugin_tolerances.rb new file mode 100644 index 0000000..8b1b8f9 --- /dev/null +++ b/plugins/tolerance_time/db/migrate/20120719090320_create_tolerance_time_plugin_tolerances.rb @@ -0,0 +1,13 @@ +class CreateToleranceTimePluginTolerances < ActiveRecord::Migration + def self.up + create_table :tolerance_time_plugin_tolerances do |t| + t.references :profile + t.integer :content_tolerance + t.integer :comment_tolerance + end + end + + def self.down + drop_table :tolerance_time_plugin_tolerances + end +end diff --git a/plugins/tolerance_time/db/migrate/20120719095004_create_tolerance_time_plugin_publications.rb b/plugins/tolerance_time/db/migrate/20120719095004_create_tolerance_time_plugin_publications.rb new file mode 100644 index 0000000..a93877f --- /dev/null +++ b/plugins/tolerance_time/db/migrate/20120719095004_create_tolerance_time_plugin_publications.rb @@ -0,0 +1,12 @@ +class CreateToleranceTimePluginPublications < ActiveRecord::Migration + def self.up + create_table :tolerance_time_plugin_publications do |t| + t.references :target, :polymorphic => true + t.timestamps + end + end + + def self.down + drop_table :tolerance_time_plugin_publications + end +end diff --git a/plugins/tolerance_time/lib/ext/article.rb b/plugins/tolerance_time/lib/ext/article.rb new file mode 100644 index 0000000..8c47799 --- /dev/null +++ b/plugins/tolerance_time/lib/ext/article.rb @@ -0,0 +1,23 @@ +require_dependency 'article' + +class Article + after_create do |article| + ToleranceTimePlugin::Publication.create!(:target => article) if article.published + end + + before_save do |article| + if article.published_changed? + if article.published + ToleranceTimePlugin::Publication.create!(:target => article) + else + publication = ToleranceTimePlugin::Publication.find_by_target(article) + publication.destroy if publication.present? + end + end + end + + before_destroy do |article| + publication = ToleranceTimePlugin::Publication.find_by_target(article) + publication.destroy if publication.present? + end +end diff --git a/plugins/tolerance_time/lib/ext/comment.rb b/plugins/tolerance_time/lib/ext/comment.rb new file mode 100644 index 0000000..ff64c05 --- /dev/null +++ b/plugins/tolerance_time/lib/ext/comment.rb @@ -0,0 +1,13 @@ +require_dependency 'comment' + +class Comment + after_create do |comment| + ToleranceTimePlugin::Publication.create!(:target => comment) + end + + before_destroy do |comment| + publication = ToleranceTimePlugin::Publication.find_by_target(comment) + publication.destroy if publication.present? + end +end + diff --git a/plugins/tolerance_time/lib/tolerance_time_plugin.rb b/plugins/tolerance_time/lib/tolerance_time_plugin.rb new file mode 100644 index 0000000..89c6283 --- /dev/null +++ b/plugins/tolerance_time/lib/tolerance_time_plugin.rb @@ -0,0 +1,48 @@ +require_dependency 'ext/article' +require_dependency 'ext/comment' + +class ToleranceTimePlugin < Noosfero::Plugin + + def self.plugin_name + "Tolerance Time" + end + + def self.plugin_description + _("Adds a tolerance time for editing content after its publication") + end + + def self.expired?(content) + publication = ToleranceTimePlugin::Publication.find_by_target(content) + (content.kind_of?(Comment) || (!content.folder? && content.published?)) && (!publication.present? || publication.expired?) + end + + def control_panel_buttons + {:title => _('Tolerance Adjustements'), :url => {:controller => 'tolerance_time_plugin_myprofile', :profile => context.profile.identifier}, :icon => 'tolerance-time' } + end + + def stylesheet? + true + end + + def cms_controller_filters + block = lambda do + content = Article.find(params[:id]) + if self.class.expired?(content) + session[:notice] = _('This content can\'t be edited anymore because it expired the tolerance time') + redirect_to content.url + end + end + + { :type => 'before_filter', + :method_name => 'expired_content', + :options => {:only => 'edit'}, + :block => block } + end + + def content_expire_edit(content) + if self.class.expired?(content) + _('The tolerance time for editing this content is over.') + end + end + +end diff --git a/plugins/tolerance_time/lib/tolerance_time_plugin/publication.rb b/plugins/tolerance_time/lib/tolerance_time_plugin/publication.rb new file mode 100644 index 0000000..f2cc45f --- /dev/null +++ b/plugins/tolerance_time/lib/tolerance_time_plugin/publication.rb @@ -0,0 +1,25 @@ +class ToleranceTimePlugin::Publication < Noosfero::Plugin::ActiveRecord + belongs_to :target, :polymorphic => true + validates_presence_of :target_id, :target_type + validates_uniqueness_of :target_id, :scope => :target_type + + class << self + def find_by_target(target) + kind = target.kind_of?(Article) ? 'Article' : 'Comment' + find_by_target_id_and_target_type(target.id, kind) + end + end + + def expired? + profile = (target.kind_of?(Article) ? target.profile : target.article.profile) + profile_tolerance = ToleranceTimePlugin::Tolerance.find_by_profile_id(profile.id) + if target.kind_of?(Article) + tolerance_time = profile_tolerance.content_tolerance || 1.0/0 + elsif target.kind_of?(Comment) + tolerance_time = profile_tolerance.comment_tolerance || 1.0/0 + else + tolerance_time = 1.0/0 + end + created_at.to_i+tolerance_time < Time.now.to_i + end +end diff --git a/plugins/tolerance_time/lib/tolerance_time_plugin/tolerance.rb b/plugins/tolerance_time/lib/tolerance_time_plugin/tolerance.rb new file mode 100644 index 0000000..310a86a --- /dev/null +++ b/plugins/tolerance_time/lib/tolerance_time_plugin/tolerance.rb @@ -0,0 +1,7 @@ +class ToleranceTimePlugin::Tolerance < Noosfero::Plugin::ActiveRecord + belongs_to :profile + validates_presence_of :profile_id + validates_uniqueness_of :profile_id + validates_numericality_of :content_tolerance, :only_integer => true, :allow_nil => true + validates_numericality_of :comment_tolerance, :only_integer => true, :allow_nil => true +end diff --git a/plugins/tolerance_time/public/icons/tolerance-time.png b/plugins/tolerance_time/public/icons/tolerance-time.png new file mode 100644 index 0000000..cc3221d Binary files /dev/null and b/plugins/tolerance_time/public/icons/tolerance-time.png differ diff --git a/plugins/tolerance_time/public/style.css b/plugins/tolerance_time/public/style.css new file mode 100644 index 0000000..92b3a9e --- /dev/null +++ b/plugins/tolerance_time/public/style.css @@ -0,0 +1,4 @@ +.controller-profile_editor a.control-panel-tolerance-time, +.controller-profile_editor .msie6 a.control-panel-tolerance-time { + background-image: url(icons/tolerance-time.png) +} diff --git a/plugins/tolerance_time/test/unit/article_test.rb b/plugins/tolerance_time/test/unit/article_test.rb new file mode 100644 index 0000000..781dbe6 --- /dev/null +++ b/plugins/tolerance_time/test/unit/article_test.rb @@ -0,0 +1,33 @@ +require File.dirname(__FILE__) + '/../../../../test/test_helper' + +class ArticleTest < ActiveSupport::TestCase + should 'create a publication after publishing the article' do + article = fast_create(Article, :published => false, :profile_id => fast_create(Profile).id) + assert_nil ToleranceTimePlugin::Publication.find_by_target(article) + + article.published = true + article.save! + assert_not_nil ToleranceTimePlugin::Publication.find_by_target(article) + end + + should 'destroy publication if the article is destroyed' do + profile = fast_create(Profile) + article = fast_create(Article, :profile_id => profile.id) + article_publication = ToleranceTimePlugin::Publication.create!(:target => article) + article.destroy + assert_raise ActiveRecord::RecordNotFound do + article_publication.reload + end + end + + should 'destroy publication if the article is changed to not published' do + profile = fast_create(Profile) + article = fast_create(Article, :profile_id => profile.id) + article_publication = ToleranceTimePlugin::Publication.create!(:target => article) + article.published = false + article.save! + assert_raise ActiveRecord::RecordNotFound do + article_publication.reload + end + end +end diff --git a/plugins/tolerance_time/test/unit/comment_test.rb b/plugins/tolerance_time/test/unit/comment_test.rb new file mode 100644 index 0000000..b124d83 --- /dev/null +++ b/plugins/tolerance_time/test/unit/comment_test.rb @@ -0,0 +1,24 @@ +require File.dirname(__FILE__) + '/../../../../test/test_helper' + +class CommentTest < ActiveSupport::TestCase + should 'create a publication after posting a comment' do + article = fast_create(Article, :profile_id => fast_create(Person).id) + comment = Comment.new(:author_id => fast_create(Person).id, :body => 'Hello There!', :source_id => article.id) + assert_difference ToleranceTimePlugin::Publication, :count do + comment.save! + end + assert_not_nil ToleranceTimePlugin::Publication.find_by_target(comment) + end + + should 'destroy publication if the comment is destroyed' do + profile = fast_create(Profile) + article = fast_create(Article, :profile_id => profile.id) + comment = fast_create(Comment, :source_id => article.id) + comment_publication = ToleranceTimePlugin::Publication.create!(:target => comment) + comment.destroy + assert_raise ActiveRecord::RecordNotFound do + comment_publication.reload + end + end +end + diff --git a/plugins/tolerance_time/test/unit/tolerance_time_plugin/publication_test.rb b/plugins/tolerance_time/test/unit/tolerance_time_plugin/publication_test.rb new file mode 100644 index 0000000..08abfc8 --- /dev/null +++ b/plugins/tolerance_time/test/unit/tolerance_time_plugin/publication_test.rb @@ -0,0 +1,68 @@ +require File.dirname(__FILE__) + '/../../../../../test/test_helper' + +class ToleranceTimePlugin::PublicationTest < ActiveSupport::TestCase + should 'validate presence of target' do + publication = ToleranceTimePlugin::Publication.new + publication.valid? + assert publication.errors.invalid?(:target_id) + assert publication.errors.invalid?(:target_type) + + publication.target = fast_create(Article) + publication.valid? + assert !publication.errors.invalid?(:target_id) + assert !publication.errors.invalid?(:target_type) + end + + should 'validate uniqueness of target' do + target = fast_create(Article) + p1 = ToleranceTimePlugin::Publication.create!(:target => target) + p2 = ToleranceTimePlugin::Publication.new(:target => target) + p2.valid? + + assert p2.errors.invalid?(:target_id) + end + + should 'be able to find publication by target' do + article = fast_create(Article) + publication = ToleranceTimePlugin::Publication.create!(:target => article) + assert_equal publication, ToleranceTimePlugin::Publication.find_by_target(article) + end + + should 'avaliate if the publication is expired' do + profile = fast_create(Profile) + author = fast_create(Person) + a1 = fast_create(Article, :profile_id => profile.id) + a2 = fast_create(Article, :profile_id => profile.id) + c1 = fast_create(Comment, :source_id => a1.id) + c2 = fast_create(Comment, :source_id => a2.id) + ToleranceTimePlugin::Tolerance.create!(:profile => profile, :content_tolerance => 10.minutes, :comment_tolerance => 5.minutes) + expired_article = ToleranceTimePlugin::Publication.create!(:target => a1) + expired_article.created_at = 15.minutes.ago + expired_article.save! + on_time_article = ToleranceTimePlugin::Publication.create!(:target => a2) + on_time_article.created_at = 5.minutes.ago + on_time_article.save! + expired_comment = ToleranceTimePlugin::Publication.create!(:target => c1) + expired_comment.created_at = 8.minutes.ago + expired_comment.save! + on_time_comment = ToleranceTimePlugin::Publication.create!(:target => c2) + on_time_comment.created_at = 2.minutes.ago + on_time_comment.save! + + assert expired_article.expired? + assert !on_time_article.expired? + assert expired_comment.expired? + assert !on_time_comment.expired? + end + + should 'consider tolerance infinity if not defined' do + profile = fast_create(Profile) + article = fast_create(Article, :profile_id => profile.id) + article_publication = ToleranceTimePlugin::Publication.create!(:target => article) + article_publication.created_at = 1000.years.ago + article_publication.save! + ToleranceTimePlugin::Tolerance.create!(:profile => profile) + + assert !article_publication.expired? + end +end diff --git a/plugins/tolerance_time/test/unit/tolerance_time_plugin/tolerance_test.rb b/plugins/tolerance_time/test/unit/tolerance_time_plugin/tolerance_test.rb new file mode 100644 index 0000000..44b8876 --- /dev/null +++ b/plugins/tolerance_time/test/unit/tolerance_time_plugin/tolerance_test.rb @@ -0,0 +1,37 @@ +require File.dirname(__FILE__) + '/../../../../../test/test_helper' + +class ToleranceTimePlugin::ToleranceTest < ActiveSupport::TestCase + should 'validate presence of profile' do + tolerance = ToleranceTimePlugin::Tolerance.new + tolerance.valid? + assert tolerance.errors.invalid?(:profile_id) + + tolerance.profile = fast_create(Profile) + tolerance.valid? + assert !tolerance.errors.invalid?(:profile_id) + end + + should 'validate uniqueness of profile' do + profile = fast_create(Profile) + t1 = ToleranceTimePlugin::Tolerance.create!(:profile => profile) + t2 = ToleranceTimePlugin::Tolerance.new(:profile => profile) + t2.valid? + + assert t2.errors.invalid?(:profile_id) + end + + should 'validate integer format for comment and content tolerance' do + tolerance = ToleranceTimePlugin::Tolerance.new(:profile => fast_create(Profile)) + assert tolerance.valid? + + tolerance.comment_tolerance = 'sdfa' + tolerance.content_tolerance = 4.5 + tolerance.valid? + assert tolerance.errors.invalid?(:comment_tolerance) + assert tolerance.errors.invalid?(:content_tolerance) + + tolerance.comment_tolerance = 3 + tolerance.content_tolerance = 6 + assert tolerance.valid? + end +end diff --git a/plugins/tolerance_time/views/tolerance_time_plugin_myprofile/index.html.erb b/plugins/tolerance_time/views/tolerance_time_plugin_myprofile/index.html.erb new file mode 100644 index 0000000..954ba77 --- /dev/null +++ b/plugins/tolerance_time/views/tolerance_time_plugin_myprofile/index.html.erb @@ -0,0 +1,24 @@ +

<%= _('Tolerance Adjustments') %>

+ +<%= error_messages_for :tolerance %> + +<% form_for :tolerance, @tolerance do |f| %> + + <% time_units = [[_('Seconds'), 1], [_('Minutes'), 60], [_('Hours'), 3600]]%> + + <% if profile.organization? %> + <%= labelled_form_field(_('Content edition tolerance time'), + f.text_field(:content_tolerance, :size => 2, :style => 'font-size: 14px; text-align: right') + + select_tag(:content_tolerance_unit, options_for_select(time_units, @content_default_unit) )) %> + <% end %> + <%= labelled_form_field(_('Comment edition tolerance time'), + f.text_field(:comment_tolerance, :size => 2, :style => 'font-size: 14px; text-align: right') + + select_tag(:comment_tolerance_unit, options_for_select(time_units, @comment_default_unit) )) %> + + <%= content_tag( 'small', _('Empty means unlimited and zero means right away.') ) %> + + <% button_bar do %> + <%= submit_button('save', _('Save'))%> + <%= button('back', _('Back'), {:controller => 'profile_editor'})%> + <% end %> +<% end %> -- libgit2 0.21.2