Commit 718c0f5679b256174d7b8ee3674e12be4b81d55e
1 parent
45c48c56
Exists in
master
and in
29 other branches
[tolerance-time] Tolerance Time Plugin
Showing
15 changed files
with
368 additions
and
0 deletions
Show diff stats
plugins/tolerance_time/controllers/tolerance_time_plugin_myprofile_controller.rb
0 → 100644
@@ -0,0 +1,37 @@ | @@ -0,0 +1,37 @@ | ||
1 | +class ToleranceTimePluginMyprofileController < MyProfileController | ||
2 | + def index | ||
3 | + @tolerance = ToleranceTimePlugin::Tolerance.find_by_profile_id(profile.id) || ToleranceTimePlugin::Tolerance.create!(:profile => profile) | ||
4 | + convert_values | ||
5 | + if request.post? | ||
6 | + begin | ||
7 | + convert_params | ||
8 | + @tolerance.update_attributes!(params[:tolerance]) | ||
9 | + convert_values | ||
10 | + session[:notice] = _('Tolerance updated') | ||
11 | + rescue | ||
12 | + session[:notice] = _('Tolerance could not be updated') | ||
13 | + end | ||
14 | + end | ||
15 | + end | ||
16 | + | ||
17 | + private | ||
18 | + | ||
19 | + def convert_params | ||
20 | + params[:tolerance][:content_tolerance] = params[:tolerance][:content_tolerance].to_i * params[:content_tolerance_unit].to_i if !params[:tolerance][:content_tolerance].blank? | ||
21 | + params[:tolerance][:comment_tolerance] = params[:tolerance][:comment_tolerance].to_i * params[:comment_tolerance_unit].to_i if !params[:tolerance][:comment_tolerance].blank? | ||
22 | + end | ||
23 | + | ||
24 | + def convert_values | ||
25 | + @content_default_unit = select_unit(@tolerance.content_tolerance) | ||
26 | + @comment_default_unit = select_unit(@tolerance.comment_tolerance) | ||
27 | + @tolerance.content_tolerance /= @content_default_unit if !@tolerance.content_tolerance.nil? | ||
28 | + @tolerance.comment_tolerance /= @comment_default_unit if !@tolerance.comment_tolerance.nil? | ||
29 | + end | ||
30 | + | ||
31 | + def select_unit(value) | ||
32 | + return 1 if value.nil? || value == 0 | ||
33 | + return 3600 if value % 3600 == 0 | ||
34 | + return 60 if value % 60 == 0 | ||
35 | + return 1 | ||
36 | + end | ||
37 | +end |
plugins/tolerance_time/db/migrate/20120719090320_create_tolerance_time_plugin_tolerances.rb
0 → 100644
@@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
1 | +class CreateToleranceTimePluginTolerances < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + create_table :tolerance_time_plugin_tolerances do |t| | ||
4 | + t.references :profile | ||
5 | + t.integer :content_tolerance | ||
6 | + t.integer :comment_tolerance | ||
7 | + end | ||
8 | + end | ||
9 | + | ||
10 | + def self.down | ||
11 | + drop_table :tolerance_time_plugin_tolerances | ||
12 | + end | ||
13 | +end |
plugins/tolerance_time/db/migrate/20120719095004_create_tolerance_time_plugin_publications.rb
0 → 100644
@@ -0,0 +1,12 @@ | @@ -0,0 +1,12 @@ | ||
1 | +class CreateToleranceTimePluginPublications < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + create_table :tolerance_time_plugin_publications do |t| | ||
4 | + t.references :target, :polymorphic => true | ||
5 | + t.timestamps | ||
6 | + end | ||
7 | + end | ||
8 | + | ||
9 | + def self.down | ||
10 | + drop_table :tolerance_time_plugin_publications | ||
11 | + end | ||
12 | +end |
@@ -0,0 +1,23 @@ | @@ -0,0 +1,23 @@ | ||
1 | +require_dependency 'article' | ||
2 | + | ||
3 | +class Article | ||
4 | + after_create do |article| | ||
5 | + ToleranceTimePlugin::Publication.create!(:target => article) if article.published | ||
6 | + end | ||
7 | + | ||
8 | + before_save do |article| | ||
9 | + if article.published_changed? | ||
10 | + if article.published | ||
11 | + ToleranceTimePlugin::Publication.create!(:target => article) | ||
12 | + else | ||
13 | + publication = ToleranceTimePlugin::Publication.find_by_target(article) | ||
14 | + publication.destroy if publication.present? | ||
15 | + end | ||
16 | + end | ||
17 | + end | ||
18 | + | ||
19 | + before_destroy do |article| | ||
20 | + publication = ToleranceTimePlugin::Publication.find_by_target(article) | ||
21 | + publication.destroy if publication.present? | ||
22 | + end | ||
23 | +end |
@@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
1 | +require_dependency 'comment' | ||
2 | + | ||
3 | +class Comment | ||
4 | + after_create do |comment| | ||
5 | + ToleranceTimePlugin::Publication.create!(:target => comment) | ||
6 | + end | ||
7 | + | ||
8 | + before_destroy do |comment| | ||
9 | + publication = ToleranceTimePlugin::Publication.find_by_target(comment) | ||
10 | + publication.destroy if publication.present? | ||
11 | + end | ||
12 | +end | ||
13 | + |
@@ -0,0 +1,48 @@ | @@ -0,0 +1,48 @@ | ||
1 | +require_dependency 'ext/article' | ||
2 | +require_dependency 'ext/comment' | ||
3 | + | ||
4 | +class ToleranceTimePlugin < Noosfero::Plugin | ||
5 | + | ||
6 | + def self.plugin_name | ||
7 | + "Tolerance Time" | ||
8 | + end | ||
9 | + | ||
10 | + def self.plugin_description | ||
11 | + _("Adds a tolerance time for editing content after its publication") | ||
12 | + end | ||
13 | + | ||
14 | + def self.expired?(content) | ||
15 | + publication = ToleranceTimePlugin::Publication.find_by_target(content) | ||
16 | + (content.kind_of?(Comment) || (!content.folder? && content.published?)) && (!publication.present? || publication.expired?) | ||
17 | + end | ||
18 | + | ||
19 | + def control_panel_buttons | ||
20 | + {:title => _('Tolerance Adjustements'), :url => {:controller => 'tolerance_time_plugin_myprofile', :profile => context.profile.identifier}, :icon => 'tolerance-time' } | ||
21 | + end | ||
22 | + | ||
23 | + def stylesheet? | ||
24 | + true | ||
25 | + end | ||
26 | + | ||
27 | + def cms_controller_filters | ||
28 | + block = lambda do | ||
29 | + content = Article.find(params[:id]) | ||
30 | + if self.class.expired?(content) | ||
31 | + session[:notice] = _('This content can\'t be edited anymore because it expired the tolerance time') | ||
32 | + redirect_to content.url | ||
33 | + end | ||
34 | + end | ||
35 | + | ||
36 | + { :type => 'before_filter', | ||
37 | + :method_name => 'expired_content', | ||
38 | + :options => {:only => 'edit'}, | ||
39 | + :block => block } | ||
40 | + end | ||
41 | + | ||
42 | + def content_expire_edit(content) | ||
43 | + if self.class.expired?(content) | ||
44 | + _('The tolerance time for editing this content is over.') | ||
45 | + end | ||
46 | + end | ||
47 | + | ||
48 | +end |
plugins/tolerance_time/lib/tolerance_time_plugin/publication.rb
0 → 100644
@@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
1 | +class ToleranceTimePlugin::Publication < Noosfero::Plugin::ActiveRecord | ||
2 | + belongs_to :target, :polymorphic => true | ||
3 | + validates_presence_of :target_id, :target_type | ||
4 | + validates_uniqueness_of :target_id, :scope => :target_type | ||
5 | + | ||
6 | + class << self | ||
7 | + def find_by_target(target) | ||
8 | + kind = target.kind_of?(Article) ? 'Article' : 'Comment' | ||
9 | + find_by_target_id_and_target_type(target.id, kind) | ||
10 | + end | ||
11 | + end | ||
12 | + | ||
13 | + def expired? | ||
14 | + profile = (target.kind_of?(Article) ? target.profile : target.article.profile) | ||
15 | + profile_tolerance = ToleranceTimePlugin::Tolerance.find_by_profile_id(profile.id) | ||
16 | + if target.kind_of?(Article) | ||
17 | + tolerance_time = profile_tolerance.content_tolerance || 1.0/0 | ||
18 | + elsif target.kind_of?(Comment) | ||
19 | + tolerance_time = profile_tolerance.comment_tolerance || 1.0/0 | ||
20 | + else | ||
21 | + tolerance_time = 1.0/0 | ||
22 | + end | ||
23 | + created_at.to_i+tolerance_time < Time.now.to_i | ||
24 | + end | ||
25 | +end |
plugins/tolerance_time/lib/tolerance_time_plugin/tolerance.rb
0 → 100644
@@ -0,0 +1,7 @@ | @@ -0,0 +1,7 @@ | ||
1 | +class ToleranceTimePlugin::Tolerance < Noosfero::Plugin::ActiveRecord | ||
2 | + belongs_to :profile | ||
3 | + validates_presence_of :profile_id | ||
4 | + validates_uniqueness_of :profile_id | ||
5 | + validates_numericality_of :content_tolerance, :only_integer => true, :allow_nil => true | ||
6 | + validates_numericality_of :comment_tolerance, :only_integer => true, :allow_nil => true | ||
7 | +end |
4.71 KB
@@ -0,0 +1,33 @@ | @@ -0,0 +1,33 @@ | ||
1 | +require File.dirname(__FILE__) + '/../../../../test/test_helper' | ||
2 | + | ||
3 | +class ArticleTest < ActiveSupport::TestCase | ||
4 | + should 'create a publication after publishing the article' do | ||
5 | + article = fast_create(Article, :published => false, :profile_id => fast_create(Profile).id) | ||
6 | + assert_nil ToleranceTimePlugin::Publication.find_by_target(article) | ||
7 | + | ||
8 | + article.published = true | ||
9 | + article.save! | ||
10 | + assert_not_nil ToleranceTimePlugin::Publication.find_by_target(article) | ||
11 | + end | ||
12 | + | ||
13 | + should 'destroy publication if the article is destroyed' do | ||
14 | + profile = fast_create(Profile) | ||
15 | + article = fast_create(Article, :profile_id => profile.id) | ||
16 | + article_publication = ToleranceTimePlugin::Publication.create!(:target => article) | ||
17 | + article.destroy | ||
18 | + assert_raise ActiveRecord::RecordNotFound do | ||
19 | + article_publication.reload | ||
20 | + end | ||
21 | + end | ||
22 | + | ||
23 | + should 'destroy publication if the article is changed to not published' do | ||
24 | + profile = fast_create(Profile) | ||
25 | + article = fast_create(Article, :profile_id => profile.id) | ||
26 | + article_publication = ToleranceTimePlugin::Publication.create!(:target => article) | ||
27 | + article.published = false | ||
28 | + article.save! | ||
29 | + assert_raise ActiveRecord::RecordNotFound do | ||
30 | + article_publication.reload | ||
31 | + end | ||
32 | + end | ||
33 | +end |
@@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
1 | +require File.dirname(__FILE__) + '/../../../../test/test_helper' | ||
2 | + | ||
3 | +class CommentTest < ActiveSupport::TestCase | ||
4 | + should 'create a publication after posting a comment' do | ||
5 | + article = fast_create(Article, :profile_id => fast_create(Person).id) | ||
6 | + comment = Comment.new(:author_id => fast_create(Person).id, :body => 'Hello There!', :source_id => article.id) | ||
7 | + assert_difference ToleranceTimePlugin::Publication, :count do | ||
8 | + comment.save! | ||
9 | + end | ||
10 | + assert_not_nil ToleranceTimePlugin::Publication.find_by_target(comment) | ||
11 | + end | ||
12 | + | ||
13 | + should 'destroy publication if the comment is destroyed' do | ||
14 | + profile = fast_create(Profile) | ||
15 | + article = fast_create(Article, :profile_id => profile.id) | ||
16 | + comment = fast_create(Comment, :source_id => article.id) | ||
17 | + comment_publication = ToleranceTimePlugin::Publication.create!(:target => comment) | ||
18 | + comment.destroy | ||
19 | + assert_raise ActiveRecord::RecordNotFound do | ||
20 | + comment_publication.reload | ||
21 | + end | ||
22 | + end | ||
23 | +end | ||
24 | + |
plugins/tolerance_time/test/unit/tolerance_time_plugin/publication_test.rb
0 → 100644
@@ -0,0 +1,68 @@ | @@ -0,0 +1,68 @@ | ||
1 | +require File.dirname(__FILE__) + '/../../../../../test/test_helper' | ||
2 | + | ||
3 | +class ToleranceTimePlugin::PublicationTest < ActiveSupport::TestCase | ||
4 | + should 'validate presence of target' do | ||
5 | + publication = ToleranceTimePlugin::Publication.new | ||
6 | + publication.valid? | ||
7 | + assert publication.errors.invalid?(:target_id) | ||
8 | + assert publication.errors.invalid?(:target_type) | ||
9 | + | ||
10 | + publication.target = fast_create(Article) | ||
11 | + publication.valid? | ||
12 | + assert !publication.errors.invalid?(:target_id) | ||
13 | + assert !publication.errors.invalid?(:target_type) | ||
14 | + end | ||
15 | + | ||
16 | + should 'validate uniqueness of target' do | ||
17 | + target = fast_create(Article) | ||
18 | + p1 = ToleranceTimePlugin::Publication.create!(:target => target) | ||
19 | + p2 = ToleranceTimePlugin::Publication.new(:target => target) | ||
20 | + p2.valid? | ||
21 | + | ||
22 | + assert p2.errors.invalid?(:target_id) | ||
23 | + end | ||
24 | + | ||
25 | + should 'be able to find publication by target' do | ||
26 | + article = fast_create(Article) | ||
27 | + publication = ToleranceTimePlugin::Publication.create!(:target => article) | ||
28 | + assert_equal publication, ToleranceTimePlugin::Publication.find_by_target(article) | ||
29 | + end | ||
30 | + | ||
31 | + should 'avaliate if the publication is expired' do | ||
32 | + profile = fast_create(Profile) | ||
33 | + author = fast_create(Person) | ||
34 | + a1 = fast_create(Article, :profile_id => profile.id) | ||
35 | + a2 = fast_create(Article, :profile_id => profile.id) | ||
36 | + c1 = fast_create(Comment, :source_id => a1.id) | ||
37 | + c2 = fast_create(Comment, :source_id => a2.id) | ||
38 | + ToleranceTimePlugin::Tolerance.create!(:profile => profile, :content_tolerance => 10.minutes, :comment_tolerance => 5.minutes) | ||
39 | + expired_article = ToleranceTimePlugin::Publication.create!(:target => a1) | ||
40 | + expired_article.created_at = 15.minutes.ago | ||
41 | + expired_article.save! | ||
42 | + on_time_article = ToleranceTimePlugin::Publication.create!(:target => a2) | ||
43 | + on_time_article.created_at = 5.minutes.ago | ||
44 | + on_time_article.save! | ||
45 | + expired_comment = ToleranceTimePlugin::Publication.create!(:target => c1) | ||
46 | + expired_comment.created_at = 8.minutes.ago | ||
47 | + expired_comment.save! | ||
48 | + on_time_comment = ToleranceTimePlugin::Publication.create!(:target => c2) | ||
49 | + on_time_comment.created_at = 2.minutes.ago | ||
50 | + on_time_comment.save! | ||
51 | + | ||
52 | + assert expired_article.expired? | ||
53 | + assert !on_time_article.expired? | ||
54 | + assert expired_comment.expired? | ||
55 | + assert !on_time_comment.expired? | ||
56 | + end | ||
57 | + | ||
58 | + should 'consider tolerance infinity if not defined' do | ||
59 | + profile = fast_create(Profile) | ||
60 | + article = fast_create(Article, :profile_id => profile.id) | ||
61 | + article_publication = ToleranceTimePlugin::Publication.create!(:target => article) | ||
62 | + article_publication.created_at = 1000.years.ago | ||
63 | + article_publication.save! | ||
64 | + ToleranceTimePlugin::Tolerance.create!(:profile => profile) | ||
65 | + | ||
66 | + assert !article_publication.expired? | ||
67 | + end | ||
68 | +end |
plugins/tolerance_time/test/unit/tolerance_time_plugin/tolerance_test.rb
0 → 100644
@@ -0,0 +1,37 @@ | @@ -0,0 +1,37 @@ | ||
1 | +require File.dirname(__FILE__) + '/../../../../../test/test_helper' | ||
2 | + | ||
3 | +class ToleranceTimePlugin::ToleranceTest < ActiveSupport::TestCase | ||
4 | + should 'validate presence of profile' do | ||
5 | + tolerance = ToleranceTimePlugin::Tolerance.new | ||
6 | + tolerance.valid? | ||
7 | + assert tolerance.errors.invalid?(:profile_id) | ||
8 | + | ||
9 | + tolerance.profile = fast_create(Profile) | ||
10 | + tolerance.valid? | ||
11 | + assert !tolerance.errors.invalid?(:profile_id) | ||
12 | + end | ||
13 | + | ||
14 | + should 'validate uniqueness of profile' do | ||
15 | + profile = fast_create(Profile) | ||
16 | + t1 = ToleranceTimePlugin::Tolerance.create!(:profile => profile) | ||
17 | + t2 = ToleranceTimePlugin::Tolerance.new(:profile => profile) | ||
18 | + t2.valid? | ||
19 | + | ||
20 | + assert t2.errors.invalid?(:profile_id) | ||
21 | + end | ||
22 | + | ||
23 | + should 'validate integer format for comment and content tolerance' do | ||
24 | + tolerance = ToleranceTimePlugin::Tolerance.new(:profile => fast_create(Profile)) | ||
25 | + assert tolerance.valid? | ||
26 | + | ||
27 | + tolerance.comment_tolerance = 'sdfa' | ||
28 | + tolerance.content_tolerance = 4.5 | ||
29 | + tolerance.valid? | ||
30 | + assert tolerance.errors.invalid?(:comment_tolerance) | ||
31 | + assert tolerance.errors.invalid?(:content_tolerance) | ||
32 | + | ||
33 | + tolerance.comment_tolerance = 3 | ||
34 | + tolerance.content_tolerance = 6 | ||
35 | + assert tolerance.valid? | ||
36 | + end | ||
37 | +end |
plugins/tolerance_time/views/tolerance_time_plugin_myprofile/index.html.erb
0 → 100644
@@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
1 | +<h1><%= _('Tolerance Adjustments') %></h1> | ||
2 | + | ||
3 | +<%= error_messages_for :tolerance %> | ||
4 | + | ||
5 | +<% form_for :tolerance, @tolerance do |f| %> | ||
6 | + | ||
7 | + <% time_units = [[_('Seconds'), 1], [_('Minutes'), 60], [_('Hours'), 3600]]%> | ||
8 | + | ||
9 | + <% if profile.organization? %> | ||
10 | + <%= labelled_form_field(_('Content edition tolerance time'), | ||
11 | + f.text_field(:content_tolerance, :size => 2, :style => 'font-size: 14px; text-align: right') + | ||
12 | + select_tag(:content_tolerance_unit, options_for_select(time_units, @content_default_unit) )) %> | ||
13 | + <% end %> | ||
14 | + <%= labelled_form_field(_('Comment edition tolerance time'), | ||
15 | + f.text_field(:comment_tolerance, :size => 2, :style => 'font-size: 14px; text-align: right') + | ||
16 | + select_tag(:comment_tolerance_unit, options_for_select(time_units, @comment_default_unit) )) %> | ||
17 | + | ||
18 | + <%= content_tag( 'small', _('Empty means unlimited and zero means right away.') ) %> | ||
19 | + | ||
20 | + <% button_bar do %> | ||
21 | + <%= submit_button('save', _('Save'))%> | ||
22 | + <%= button('back', _('Back'), {:controller => 'profile_editor'})%> | ||
23 | + <% end %> | ||
24 | +<% end %> |