From d755b3b712e5a0a2d580d30c5ec1668ae3d58d43 Mon Sep 17 00:00:00 2001 From: Michel Felipe de Oliveira Ferreira Date: Mon, 16 Nov 2015 16:48:41 -0300 Subject: [PATCH] New feature archive articles --- app/helpers/article_helper.rb | 19 ++++++++++++++++--- app/helpers/folder_helper.rb | 6 ++++++ app/models/article.rb | 30 +++++++++++++++++++++++++----- app/models/comment.rb | 12 ++++++++++++ app/views/cms/_archived_warning.html.erb | 8 ++++++++ app/views/cms/edit.html.erb | 3 +++ app/views/content_viewer/_article_toolbar.html.erb | 7 ++++++- app/views/content_viewer/_publishing_info.html.erb | 2 +- app/views/content_viewer/view_page.html.erb | 2 +- db/migrate/20151112135709_add_archived_to_articles.rb | 9 +++++++++ db/schema.rb | 1 + plugins/vote/lib/ext/vote.rb | 18 ++++++++++++++++++ plugins/vote/lib/vote_plugin_helper.rb | 4 +++- plugins/vote/public/style.css | 9 +++++++++ plugins/vote/public/vote_actions.js | 4 +++- plugins/vote/test/functional/vote_plugin_profile_controller_test.rb | 12 ++++++++++++ plugins/vote/views/vote/_vote.html.erb | 11 ++++++++--- po/noosfero.pot | 4 ++++ po/pt/noosfero.po | 8 ++++++-- public/images/icons-app/article-private-icon.png | Bin 0 -> 273 bytes public/images/icons-app/article-public-icon.png | Bin 0 -> 570 bytes public/images/icons-app/warning-icon.png | Bin 0 -> 509 bytes public/javascripts/article.js | 6 ++++++ public/stylesheets/cms.scss | 1 + public/stylesheets/cms/access-options.scss | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/functional/cms_controller_test.rb | 28 ++++++++++++++++++++++++++++ test/unit/article_test.rb | 31 +++++++++++++++++++++++++++++++ test/unit/comment_test.rb | 11 +++++++++++ 28 files changed, 295 insertions(+), 18 deletions(-) create mode 100644 app/views/cms/_archived_warning.html.erb create mode 100644 db/migrate/20151112135709_add_archived_to_articles.rb create mode 100644 plugins/vote/lib/ext/vote.rb create mode 100644 public/images/icons-app/article-private-icon.png create mode 100644 public/images/icons-app/article-public-icon.png create mode 100644 public/images/icons-app/warning-icon.png create mode 100644 public/stylesheets/cms/access-options.scss diff --git a/app/helpers/article_helper.rb b/app/helpers/article_helper.rb index 44842ea..2b3a4c4 100644 --- a/app/helpers/article_helper.rb +++ b/app/helpers/article_helper.rb @@ -15,6 +15,12 @@ module ArticleHelper topic_creation(@article) + content_tag('h4', _('Options')) + content_tag('div', + content_tag( + 'div', + check_box(:article, :archived) + + content_tag('label', _('Do not allow new content on this article and its children'), :for => 'article_archived_true') + ) + + (article.profile.has_members? ? content_tag( 'div', @@ -63,13 +69,20 @@ module ArticleHelper content_tag('div', content_tag('div', radio_button(:article, :published, true) + - content_tag('label', _('Public (visible to other people)'), :for => 'article_published_true') + content_tag('span', ' ', :class => 'access-public-icon') + + content_tag('label', _('Public'), :for => 'article_published_true') + + content_tag('span', _('Visible to other people'), :class => 'access-note'), + :class => 'access-item' ) + content_tag('div', radio_button(:article, :published, false) + - content_tag('label', _('Private'), :for => 'article_published_false', :id => "label_private") + content_tag('span', ' ', :class => 'access-private-icon') + + content_tag('label', _('Private'), :for => 'article_published_false', :id => "label_private") + + content_tag('span', _('Limit visibility of this article'), :class => 'access-note'), + :class => 'access-item' ) + - privacity_exceptions(article, tokenized_children) + privacity_exceptions(article, tokenized_children), + :class => 'access-itens' ) end diff --git a/app/helpers/folder_helper.rb b/app/helpers/folder_helper.rb index 3c33d4f..435e903 100644 --- a/app/helpers/folder_helper.rb +++ b/app/helpers/folder_helper.rb @@ -59,7 +59,13 @@ module FolderHelper @article = article visibility_options(article,tokenized_children) + + content_tag('h4', _('Options')) + content_tag('div', + content_tag( + 'div', + check_box(:article, :archived) + + content_tag('label', _('Do not allow new content on this article and its children'), :for => 'article_archived_true') + ) + hidden_field_tag('article[accept_comments]', 0) ) end diff --git a/app/models/article.rb b/app/models/article.rb index bcb805c..15be5d8 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -8,7 +8,7 @@ class Article < ActiveRecord::Base :accept_comments, :feed, :published, :source, :source_name, :highlighted, :notify_comments, :display_hits, :slug, :external_feed_builder, :display_versions, :external_link, - :image_builder, :show_to_followers, + :image_builder, :show_to_followers, :archived, :author, :display_preview, :published_at, :person_followers acts_as_having_image @@ -152,6 +152,8 @@ class Article < ActiveRecord::Base validate :no_self_reference validate :no_cyclical_reference, :if => 'parent_id.present?' + validate :parent_archived? + def no_self_reference errors.add(:parent_id, _('self-reference is not allowed.')) if id && parent_id == id end @@ -499,6 +501,10 @@ class Article < ActiveRecord::Base end end + def archived? + (self.parent && self.parent.archived) || self.archived + end + def self.folder_types ['Folder', 'Blog', 'Forum', 'Gallery'] end @@ -645,13 +651,21 @@ class Article < ActiveRecord::Base end def hit - self.class.connection.execute('update articles set hits = hits + 1 where id = %d' % self.id.to_i) - self.hits += 1 + if !archived? + self.class.connection.execute('update articles set hits = hits + 1 where id = %d' % self.id.to_i) + self.hits += 1 + end end def self.hit(articles) - Article.where(:id => articles.map(&:id)).update_all('hits = hits + 1') - articles.each { |a| a.hits += 1 } + ids = [] + articles.each do |article| + if !article.archived? + ids << article.id + article.hits += 1 + end + end + Article.where(:id => ids).update_all('hits = hits + 1') if !ids.empty? end def can_display_hits? @@ -861,4 +875,10 @@ class Article < ActiveRecord::Base sanitizer.sanitize(text) end + def parent_archived? + if self.parent_id_changed? && self.parent && self.parent.archived? + errors.add(:parent_folder, N_('is archived!!')) + end + end + end diff --git a/app/models/comment.rb b/app/models/comment.rb index 961c79a..fff62eb 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -36,6 +36,8 @@ class Comment < ActiveRecord::Base end end + validate :article_archived? + acts_as_having_settings xss_terminate :only => [ :body, :title, :name ], :on => 'validation' @@ -218,4 +220,14 @@ class Comment < ActiveRecord::Base user.present? && user == author end + def archived? + self.source && self.source.is_a?(Article) && self.source.archived? + end + + protected + + def article_archived? + errors.add(:article, N_('associated with this comment is archived!')) if archived? + end + end diff --git a/app/views/cms/_archived_warning.html.erb b/app/views/cms/_archived_warning.html.erb new file mode 100644 index 0000000..62c48fc --- /dev/null +++ b/app/views/cms/_archived_warning.html.erb @@ -0,0 +1,8 @@ +<% if !article.errors.any? %> +
+

+ + <%= _("Archived article! It's read-only") %> +

+
+<% end %> diff --git a/app/views/cms/edit.html.erb b/app/views/cms/edit.html.erb index 9812e4b..3fdfd4b 100644 --- a/app/views/cms/edit.html.erb +++ b/app/views/cms/edit.html.erb @@ -1,5 +1,8 @@ <%= error_messages_for 'article' %> +<% if @article.archived? %> + <%= render :partial => 'archived_warning', :locals => {:article => @article} %> +<% end %>
'> <%= labelled_form_for 'article', :html => { :multipart => true, :class => @type } do |f| %> diff --git a/app/views/content_viewer/_article_toolbar.html.erb b/app/views/content_viewer/_article_toolbar.html.erb index 5b532af..7be252e 100644 --- a/app/views/content_viewer/_article_toolbar.html.erb +++ b/app/views/content_viewer/_article_toolbar.html.erb @@ -29,7 +29,9 @@ <%= expirable_button @page, :locale, content, url %> <% end %> - <%= modal_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : @page.parent))) unless remove_content_button(:new, @page) %> + <% if !@page.archived? %> + <%= modal_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : @page.parent))) unless remove_content_button(:new, @page) %> + <% end %> <% content = content_tag('span', label_for_clone_article(@page)) %> <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'new', :id => @page.id, :clone => true, :parent_id => (@page.folder? ? @page : @page.parent), :type => @page.class}) %> @@ -66,6 +68,9 @@ <% end %> <%= button_without_text(:feed, _('RSS feed'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %> <%= @plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %> + <% if @page.archived? %> + <%= render :partial => 'cms/archived_warning', :locals => {:article => @page} %> + <% end %> <%= render :partial => 'article_title', :locals => {:no_link => true} %> <%= article_translations(@page) %>
diff --git a/app/views/content_viewer/_publishing_info.html.erb b/app/views/content_viewer/_publishing_info.html.erb index d212203..38de42b 100644 --- a/app/views/content_viewer/_publishing_info.html.erb +++ b/app/views/content_viewer/_publishing_info.html.erb @@ -34,7 +34,7 @@
<% if @page.display_hits? %>
- <%= n_('Viewed one time', 'Viewed %{num} times', @page.hits) % { :num => @page.hits } %> + <%= n_('Viewed one time %{desc}', 'Viewed %{num} times %{desc}', @page.hits) % { :num => @page.hits, :desc => @page.archived? ? ''+_('(Not countable anymore)')+'' : '' } %>
<% end %> diff --git a/app/views/content_viewer/view_page.html.erb b/app/views/content_viewer/view_page.html.erb index 82cd4fc..4805d73 100644 --- a/app/views/content_viewer/view_page.html.erb +++ b/app/views/content_viewer/view_page.html.erb @@ -85,7 +85,7 @@ <% end %> - <% if @page.accept_comments? %> + <% if !@page.archived? && @page.accept_comments? %>
<%= render :partial => 'comment/comment_form', :locals =>{:url => {:controller => :comment, :action => :create}, :display_link => true, :cancel_triggers_hide => true}%>
<% end %>
diff --git a/db/migrate/20151112135709_add_archived_to_articles.rb b/db/migrate/20151112135709_add_archived_to_articles.rb new file mode 100644 index 0000000..55e31a3 --- /dev/null +++ b/db/migrate/20151112135709_add_archived_to_articles.rb @@ -0,0 +1,9 @@ +class AddArchivedToArticles < ActiveRecord::Migration + def up + add_column :articles, :archived, :boolean, :default => false + end + + def down + remove_column :articles, :archived + end +end diff --git a/db/schema.rb b/db/schema.rb index c67df27..4bd567b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -167,6 +167,7 @@ ActiveRecord::Schema.define(version: 20160324132518) do t.integer "created_by_id" t.boolean "show_to_followers", default: true t.integer "followers_count", default: 0 + t.boolean "archived", default: false end add_index "articles", ["comments_count"], name: "index_articles_on_comments_count", using: :btree diff --git a/plugins/vote/lib/ext/vote.rb b/plugins/vote/lib/ext/vote.rb new file mode 100644 index 0000000..0b5729e --- /dev/null +++ b/plugins/vote/lib/ext/vote.rb @@ -0,0 +1,18 @@ +require_dependency 'models/vote' + +class Vote + + validate :verify_target_archived + + def verify_target_archived + + if voteable.kind_of?(Article) || voteable.kind_of?(Comment) + if voteable.archived? + errors.add(:base, _("The target is achived and can't accept votes")) + false + end + end + + end + +end diff --git a/plugins/vote/lib/vote_plugin_helper.rb b/plugins/vote/lib/vote_plugin_helper.rb index 78099bb..63e59a9 100644 --- a/plugins/vote/lib/vote_plugin_helper.rb +++ b/plugins/vote/lib/vote_plugin_helper.rb @@ -2,8 +2,10 @@ module VotePluginHelper def vote_partial(target, like = true, load_voters=false) vote = like ? 1 : -1 + like_action = like ? 'like' : 'dislike' type = target.kind_of?(Article) ? 'article' : target.kind_of?(Comment) ? 'comment' : nil + disable_vote = target.archived? ? true : false proc do settings = Noosfero::Plugin::Settings.new(environment, VotePlugin) @@ -14,7 +16,7 @@ module VotePluginHelper active = user ? (like ? user.voted_for?(target) : user.voted_against?(target)) : false count = like ? target.votes_for : target.votes_against - render(:partial => 'vote/vote', :locals => {:target => target, :active => active, :action => like_action, :count => count, :voters => voters, :vote => vote, :model => type }) + render(:partial => 'vote/vote', :locals => {:target => target, :active => active, :action => like_action, :count => count, :voters => voters, :vote => vote, :model => type, :disable_vote => disable_vote }) else "" end diff --git a/plugins/vote/public/style.css b/plugins/vote/public/style.css index d128764..7d0cd06 100644 --- a/plugins/vote/public/style.css +++ b/plugins/vote/public/style.css @@ -73,3 +73,12 @@ #article .action .vote-detail img { vertical-align: bottom; } + +.comments-action-bar span.disabled a, +.comments-action-bar span.disabled a:hover, +.vote-actions span.disabled a, +.vote-actions span.disabled a:hover { + opacity: 0.5; + pointer-events: none; + cursor: default; +} diff --git a/plugins/vote/public/vote_actions.js b/plugins/vote/public/vote_actions.js index 86268af..3ccbd45 100644 --- a/plugins/vote/public/vote_actions.js +++ b/plugins/vote/public/vote_actions.js @@ -16,7 +16,9 @@ function openVotersDialog(div) { clearTimeout(openEvent); var url = $(div).data('reload_url'); hideAllVoteDetail(); - $.post(url); + if(url && url != '#'){ + $.post(url); + } } jQuery('body').live('click', function() { hideAllVoteDetail(); }); diff --git a/plugins/vote/test/functional/vote_plugin_profile_controller_test.rb b/plugins/vote/test/functional/vote_plugin_profile_controller_test.rb index f7f9ad2..128b0f5 100644 --- a/plugins/vote/test/functional/vote_plugin_profile_controller_test.rb +++ b/plugins/vote/test/functional/vote_plugin_profile_controller_test.rb @@ -32,6 +32,18 @@ class VotePluginProfileControllerTest < ActionController::TestCase assert profile.votes.empty? end + should 'not vote if a target is archived' do + article = Article.create!(:profile => profile, :name => 'Archived article', :archived => false) + comment = Comment.create!(:body => 'Comment test', :source => article, :author => profile) + xhr :post, :vote, :profile => profile.identifier, :id => article.id, :model => 'article', :vote => 1 + assert !profile.votes.empty? + + article.update_attributes(:archived => true) + xhr :post, :vote, :profile => profile.identifier, :id => comment.id, :model => 'comment', :vote => 1 + + assert !profile.voted_for?(comment) + end + should 'like comment' do xhr :post, :vote, :profile => profile.identifier, :id => comment.id, :model => 'comment', :vote => 1 assert profile.voted_for?(comment) diff --git a/plugins/vote/views/vote/_vote.html.erb b/plugins/vote/views/vote/_vote.html.erb index 0c2bc14..bbb5de3 100644 --- a/plugins/vote/views/vote/_vote.html.erb +++ b/plugins/vote/views/vote/_vote.html.erb @@ -1,9 +1,14 @@ <% -url = url_for(:controller => 'vote_plugin_profile', :profile => profile.identifier, :action => :vote, :id => target.id, :model => model, :vote => vote) -reload_url = url_for(:controller => 'vote_plugin_profile', :profile => profile.identifier, :action => :reload_vote, :id => target.id, :model => model, :vote => vote) +if disable_vote + url = reload_url = '#' + class_action = 'disabled' +else + url = url_for(:controller => 'vote_plugin_profile', :profile => profile.identifier, :action => :vote, :id => target.id, :model => model, :vote => vote) + reload_url = url_for(:controller => 'vote_plugin_profile', :profile => profile.identifier, :action => :reload_vote, :id => target.id, :model => model, :vote => vote) +end %> - class="vote-action action <%= action %>-action"> + class="vote-action action <%= action %>-action <%= class_action %>"> <%= link_to content_tag(:span, count, :class=>'like-action-counter') + content_tag(:span, '', :class=>"action-icon #{action}"), url, :class => "#{active ? 'like-action-active':''} #{user ? '':'disabled'} require-login-popup" %> diff --git a/po/noosfero.pot b/po/noosfero.pot index 5178dc8..f90c7ef 100644 --- a/po/noosfero.pot +++ b/po/noosfero.pot @@ -5073,6 +5073,10 @@ msgid_plural "Viewed %{num} times" msgstr[0] "" msgstr[1] "" +#: app/views/content_viewer/_publishing_info.html.erb:19 +msgid "(Not countable anymore)" +msgstr "" + #: app/views/content_viewer/versions_diff.html.erb:5 msgid "Changes on \"%s\"" msgstr "" diff --git a/po/pt/noosfero.po b/po/pt/noosfero.po index 611a27f..4f54ed9 100644 --- a/po/pt/noosfero.po +++ b/po/pt/noosfero.po @@ -5231,11 +5231,15 @@ msgid "Reply" msgstr "Responder" #: app/views/content_viewer/_publishing_info.html.erb:19 -msgid "Viewed one time" -msgid_plural "Viewed %{num} times" +msgid "Viewed one time %{desc}" +msgid_plural "Viewed %{num} times %{desc}" msgstr[0] "Visualizado uma vez" msgstr[1] "Visualizado %{num} vezes" +#: app/views/content_viewer/_publishing_info.html.erb:19 +msgid "(Not countable anymore)" +msgstr "(Não mais contabilizado)" + #: app/views/content_viewer/versions_diff.html.erb:5 msgid "Changes on \"%s\"" msgstr "Mudanças em \"%s\"" diff --git a/public/images/icons-app/article-private-icon.png b/public/images/icons-app/article-private-icon.png new file mode 100644 index 0000000..d91232e Binary files /dev/null and b/public/images/icons-app/article-private-icon.png differ diff --git a/public/images/icons-app/article-public-icon.png b/public/images/icons-app/article-public-icon.png new file mode 100644 index 0000000..d053ae2 Binary files /dev/null and b/public/images/icons-app/article-public-icon.png differ diff --git a/public/images/icons-app/warning-icon.png b/public/images/icons-app/warning-icon.png new file mode 100644 index 0000000..c13f43c Binary files /dev/null and b/public/images/icons-app/warning-icon.png differ diff --git a/public/javascripts/article.js b/public/javascripts/article.js index eda37e2..4e1cc00 100644 --- a/public/javascripts/article.js +++ b/public/javascripts/article.js @@ -212,4 +212,10 @@ jQuery(function($) { $("#article_published_true").click(show_hide_privacy_options); $(".custom_privacy_option").click(show_hide_token_input); + //Workaround to pointer-events:none CSS3 + $('a.disabled').click(function(e){ + e.preventDefault(); + return false; + }); + }); diff --git a/public/stylesheets/cms.scss b/public/stylesheets/cms.scss index 3afd5da..9fd6267 100644 --- a/public/stylesheets/cms.scss +++ b/public/stylesheets/cms.scss @@ -1,5 +1,6 @@ @import 'cms/fetch-external-feed'; @import 'cms/media-panel'; +@import 'cms/access-options'; table.cms-articles { table-layout: fixed; diff --git a/public/stylesheets/cms/access-options.scss b/public/stylesheets/cms/access-options.scss new file mode 100644 index 0000000..16a4525 --- /dev/null +++ b/public/stylesheets/cms/access-options.scss @@ -0,0 +1,67 @@ +//Variables +$icons-size: 24px; +$warning-color: #e75e40; +$description-color: #666; +$access-types: public, private; + +.text-warning { + text-align: center; + color: $warning-color; + font: { + size: 15px; + weight: bold; + } + + p i.icon { + display: inline-block; + font-size: inherit; + text-rendering: auto; + background: url('images/icons-app/warning-icon.png'); + vertical-align: middle; + margin-top: -5px; + width: $icons-size; + height: $icons-size; + border: none; + } +} + +#edit-article-options { + + .access-itens .access-item { + input,label { + cursor: pointer; + } + } + + .access-item { + margin: 15px 0; + label { + font: { + size: 13px; + weight: bold; + } + } + } + + @each $access_type in $access-types { + .access-#{$access_type}-icon, .access-#{$access_type}-icon { + display: inline-block; + margin-right: 5px; + width: $icons-size; + height: $icons-size; + vertical-align: middle; + background-image: url('images/icons-app/article-#{$access_type}-icon.png'); + } + } + + .access-note { + display: block; + margin: 0; + color: $description-color; + margin-left: 50px; + font: { + size: 12px; + weight: normal; + } + } +} diff --git a/test/functional/cms_controller_test.rb b/test/functional/cms_controller_test.rb index 9160c72..89246cc 100644 --- a/test/functional/cms_controller_test.rb +++ b/test/functional/cms_controller_test.rb @@ -694,6 +694,34 @@ class CmsControllerTest < ActionController::TestCase end end + should "marks a article like archived" do + article = create(Article, :profile => profile, :name => 'test', :published => true, :archived => false) + + post :edit, :profile => profile.identifier, :id => article.id, :article => {:archived => true} + get :edit, :profile => profile.identifier, :id => article.id + assert_tag :tag => 'input', :attributes => { :type => 'checkbox', :name => 'article[archived]', :id => 'article_archived', :checked => 'checked' } + + end + + should "try add children into archived folders" do + folder = create(Folder, :profile => profile, :name => 'test', :published => true, :archived => false) + article_child = create(Article, :profile => profile, :name => 'test child', :parent_id => folder.id, :published => true, :archived => false) + + get :edit, :profile => profile.identifier, :id => folder.id + assert_tag :tag => 'input', :attributes => { :type => 'checkbox', :name => 'article[archived]', :id => 'article_archived' } + + post :edit, :profile => profile.identifier, :id => folder.id, :article => {:archived => true} + + get :edit, :profile => profile.identifier, :id => article_child.id + assert_tag :tag => 'div', :attributes => { :class => 'text-warning'} + + err = assert_raises ActiveRecord::RecordInvalid do + another_article_child = create(Article, :profile => profile, :name => 'other test child', :parent_id => folder.id, :published => true, :archived => false) + end + assert_match 'Parent folder is archived', err.message + + end + should 'be able to add image with alignment' do post :new, :type => 'TinyMceArticle', :profile => profile.identifier, :article => { :name => 'image-alignment', :body => "the text of the article with image right align..." } saved = TinyMceArticle.find_by(name: 'image-alignment') diff --git a/test/unit/article_test.rb b/test/unit/article_test.rb index c58aca3..5e924a4 100644 --- a/test/unit/article_test.rb +++ b/test/unit/article_test.rb @@ -2168,10 +2168,21 @@ class ArticleTest < ActiveSupport::TestCase a3 = fast_create(Article) Article.hit([a1, a2, a3]) Article.hit([a2, a3]) + assert_equal [1, 2, 2], [a1.hits, a2.hits, a3.hits] assert_equal [1, 2, 2], [a1.reload.hits, a2.reload.hits, a3.reload.hits] end + should 'not update hit attribute of archiveds articles' do + a1 = fast_create(Article) + a2 = fast_create(Article, :archived => true) + a3 = fast_create(Article, :archived => true) + Article.hit([a1, a2, a3]) + + assert_equal [1, 0, 0], [a1.hits, a2.hits, a3.hits] + assert_equal [1, 0, 0], [a1.reload.hits, a2.reload.hits, a3.reload.hits] + end + should 'vote in a article' do article = create(Article, :name => 'Test', :profile => profile, :last_changed_by => nil) profile.vote(article, 5) @@ -2288,5 +2299,25 @@ class ArticleTest < ActiveSupport::TestCase assert_equal 10, article.reload.person_followers.count end + should 'check if a article is archived' do + folder = Folder.create!(:name => 'Parent Archived', :profile => profile) + a1 = Article.create!(:name => 'Test', :profile => profile, :parent_id => folder.id, :archived => false) + a2 = Article.create!(:name => 'Test 2', :profile => profile, :archived => true) + folder.update_attributes(:archived => true) + a1.reload + + assert a1.archived? + assert a2.archived? + end + + should 'try add a child article to a archived folder' do + folder = Folder.create!(:name => 'Parent Archived', :profile => profile, :archived => true) + + err = assert_raises ActiveRecord::RecordInvalid do + a1 = Article.create!(:name => 'Test', :profile => profile, :parent_id => folder.id, :archived => false) + end + + assert_match 'Parent folder is archived', err.message + end end diff --git a/test/unit/comment_test.rb b/test/unit/comment_test.rb index 409c6fa..eaaff46 100644 --- a/test/unit/comment_test.rb +++ b/test/unit/comment_test.rb @@ -95,6 +95,17 @@ class CommentTest < ActiveSupport::TestCase assert_equal cc + 1, ActionTracker::Record.find(activity.id).comments_count end + should 'try add a comment to a archived article' do + person = fast_create(Person) + article = Article.create!(:name => 'Test', :profile => person, :archived => true) + + err = assert_raises ActiveRecord::RecordInvalid do + comment = create(Comment, :source => article, :author_id => person.id) + end + + assert_match 'Article associated with this comment is archived', err.message + end + should 'provide author name for authenticated authors' do owner = create_user('testuser').person assert_equal 'testuser', build(Comment, :author => owner).author_name -- libgit2 0.21.2