From b3068b11263fab2924cd91501cec37b1feb76fb4 Mon Sep 17 00:00:00 2001 From: Gabriela Navarro Date: Mon, 12 Jan 2015 17:57:40 -0200 Subject: [PATCH] Add option to all community and users followers view a private article --- app/helpers/article_helper.rb | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ app/models/article.rb | 21 ++++++++++++++++----- db/migrate/20150113131617_add_show_to_followers_for_article.rb | 9 +++++++++ features/edit_article.feature | 22 ++++++++++++++++++++++ public/javascripts/article.js | 68 +++++++++++++++++++++++++++++++++++++++++++++++--------------------- test/functional/content_viewer_controller_test.rb | 45 ++++++++++++++++++++++++++++++++++++++------- 6 files changed, 185 insertions(+), 39 deletions(-) create mode 100644 db/migrate/20150113131617_add_show_to_followers_for_article.rb diff --git a/app/helpers/article_helper.rb b/app/helpers/article_helper.rb index db3a768..8bca69a 100644 --- a/app/helpers/article_helper.rb +++ b/app/helpers/article_helper.rb @@ -77,12 +77,59 @@ module ArticleHelper content_tag('div', radio_button(:article, :published, false) + content_tag('label', _('Private'), :for => 'article_published_false', :id => "label_private") - ) + - (article.profile.community? ? content_tag('div', - content_tag('label', _('Fill in the search field to add the exception users to see this content'), :id => "text-input-search-exception-users") + - token_input_field_tag(:q, 'search-article-privacy-exceptions', {:action => 'search_article_privacy_exceptions'}, - {:focus => false, :hint_text => _('Type in a search term for a user'), :pre_populate => tokenized_children})) : - '')) + ) + + privacity_exceptions(article, tokenized_children) + ) + end + + def privacity_exceptions(article, tokenized_children) + content_tag('div', + content_tag('div', + ( + if article.profile + add_option_to_followers(article, tokenized_children) + else + '' + end + ) + ), + :style => "margin-left:10px" + ) + end + + def add_option_to_followers(article, tokenized_children) + label_message = article.profile.organization? ? _('For all community members') : _('For all your friends') + + check_box( + :article, + :show_to_followers, + {:class => "custom_privacy_option"} + ) + + content_tag( + 'label', + label_message, + :for => 'article_show_to_followers', + :id => 'label_show_to_followers' + ) + + (article.profile.community? ? + content_tag( + 'div', + content_tag( + 'label', + _('Fill in the search field to add the exception users to see this content'), + :id => "text-input-search-exception-users" + ) + + token_input_field_tag( + :q, + 'search-article-privacy-exceptions', + {:action => 'search_article_privacy_exceptions'}, + { + :focus => false, + :hint_text => _('Type in a search term for a user'), + :pre_populate => tokenized_children + } + ) + ) : '') end def prepare_to_token_input(array) diff --git a/app/models/article.rb b/app/models/article.rb index 6023bfb..b52bd5b 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -2,7 +2,14 @@ require 'hpricot' class Article < ActiveRecord::Base - attr_accessible :name, :body, :abstract, :profile, :tag_list, :parent, :allow_members_to_edit, :translation_of_id, :language, :license_id, :parent_id, :display_posts_in_current_language, :category_ids, :posts_per_page, :moderate_comments, :accept_comments, :feed, :published, :source, :highlighted, :notify_comments, :display_hits, :slug, :external_feed_builder, :display_versions, :external_link, :image_builder + attr_accessible :name, :body, :abstract, :profile, :tag_list, :parent, + :allow_members_to_edit, :translation_of_id, :language, + :license_id, :parent_id, :display_posts_in_current_language, + :category_ids, :posts_per_page, :moderate_comments, + :accept_comments, :feed, :published, :source, + :highlighted, :notify_comments, :display_hits, :slug, + :external_feed_builder, :display_versions, :external_link, + :image_builder, :show_to_followers acts_as_having_image @@ -333,7 +340,7 @@ class Article < ActiveRecord::Base def belongs_to_blog? self.parent and self.parent.blog? end - + def belongs_to_forum? self.parent and self.parent.forum? end @@ -445,6 +452,7 @@ class Article < ActiveRecord::Base if self.parent && !self.parent.published? return false end + true else false @@ -476,14 +484,17 @@ class Article < ActiveRecord::Base {:conditions => [" articles.published = ? OR articles.last_changed_by_id = ? OR articles.profile_id = ? OR - ?", - true, user.id, user.id, user.has_permission?(:view_private_content, profile)] } + ? OR articles.show_to_followers = ? AND ?", + true, user.id, user.id, user.has_permission?(:view_private_content, profile), + true, user.follows?(profile)]} end + def display_unpublished_article_to?(user) user == author || allow_view_private_content?(user) || user == profile || user.is_admin?(profile.environment) || user.is_admin?(profile) || - article_privacy_exceptions.include?(user) + article_privacy_exceptions.include?(user) || + (self.show_to_followers && user.follows?(profile)) end def display_to?(user = nil) diff --git a/db/migrate/20150113131617_add_show_to_followers_for_article.rb b/db/migrate/20150113131617_add_show_to_followers_for_article.rb new file mode 100644 index 0000000..f4fa99b --- /dev/null +++ b/db/migrate/20150113131617_add_show_to_followers_for_article.rb @@ -0,0 +1,9 @@ +class AddShowToFollowersForArticle < ActiveRecord::Migration + def up + add_column :articles, :show_to_followers, :boolean, :default => false + end + + def down + remove_column :articles, :show_to_followers + end +end diff --git a/features/edit_article.feature b/features/edit_article.feature index 3ec91be..014941d 100644 --- a/features/edit_article.feature +++ b/features/edit_article.feature @@ -47,6 +47,28 @@ Feature: edit article Then I should see "Access denied" @selenium + Scenario: Hide token field when show to members is activated + Given the following communities + | name | identifier | owner | + | Free Software | freesoftware | joaosilva | + And the following users + | login | name | + | mario | Mario Souto | + | maria | Maria Silva | + And "Mario Souto" is a member of "Free Software" + And "Maria Silva" is a member of "Free Software" + And I am on freesoftware's control panel + And I follow "Manage Content" + And I should see "New content" + And I follow "New content" + And I should see "Folder" + When I follow "Folder" + And I fill in "Title" with "My Folder" + And I choose "article_published_false" + And I check "article_show_to_followers" + Then I should not see "Fill in the search" + + @selenium Scenario: show exception users field when you choose the private option Given the following communities | name | identifier | owner | diff --git a/public/javascripts/article.js b/public/javascripts/article.js index 06901ae..1391160 100644 --- a/public/javascripts/article.js +++ b/public/javascripts/article.js @@ -136,7 +136,7 @@ jQuery(function($) { if (data.length && data.length > 0) { $('#media-search-results').slideDown(); } - $('#media-search-box .header').toggleClass('icon-loading'); + $('#media-search-box .header').toggleClass('icon-loading'); }); return false; }); @@ -144,20 +144,20 @@ jQuery(function($) { $('#media-upload-form form').ajaxForm({ resetForm: true, beforeSubmit: - function() { - $('#media-upload-form').slideUp(); - $('#media-upload-box .header').toggleClass('icon-loading'); - }, + function() { + $('#media-upload-form').slideUp(); + $('#media-upload-box .header').toggleClass('icon-loading'); + }, success: - function(text) { - text = text.replace('
', '').replace('
', ''); // old firefox - var data = $.parseJSON(text); - list_items(data, '#media-upload-results .items', true); - if (data.length && data.length > 0) { - $('#media-upload-results').slideDown(); - } - $('#media-upload-box .header').toggleClass('icon-loading'); + function(text) { + text = text.replace('
', '').replace('
', ''); // old firefox + var data = $.parseJSON(text); + list_items(data, '#media-upload-results .items', true); + if (data.length && data.length > 0) { + $('#media-upload-results').slideDown(); } + $('#media-upload-box .header').toggleClass('icon-loading'); + } }); $('#media-upload-more-files').click(function() { @@ -166,19 +166,45 @@ jQuery(function($) { return false; }); + function is_public_article() { + return $("#article_published_true").attr('checked'); + } + + function show_hide_privacy_options() { + var show_privacy_options = $("#article_published_false").attr('checked'); + var custom_privacy_option = $(".custom_privacy_option").parent("div"); + + if( show_privacy_options ) { + custom_privacy_option.show(); + } else { + custom_privacy_option.hide(); + } + show_hide_token_input(); + } + function show_hide_token_input() { - if($("#article_published_false").attr('checked')) - $("#text-input-search-exception-users").parent("div").css('display', 'block'); - else - $("#text-input-search-exception-users").parent("div").css('display', 'none'); + var display_token = $(".custom_privacy_option:checked").length == 0; + var token_field = $("#text-input-search-exception-users").parent("div"); + + if( display_token && !is_public_article() ) { + token_field.css('display', 'block'); + } else { + token_field.css('display', 'none'); + } } if( $("#token-input-search-article-privacy-exceptions").length == 1 ) { + show_hide_privacy_options(); show_hide_token_input(); - - //Hide / Show the text area - $("#article_published_false").click(show_hide_token_input); - $("#article_published_true").click(show_hide_token_input); } + $(document).ready(function(){ + show_hide_privacy_options(); + }); + + //Hide / Show the text area + $("#article_published_false").click(show_hide_privacy_options); + $("#article_published_true").click(show_hide_privacy_options); + $(".custom_privacy_option").click(show_hide_token_input); + }); diff --git a/test/functional/content_viewer_controller_test.rb b/test/functional/content_viewer_controller_test.rb index 03ef14c..9517922 100644 --- a/test/functional/content_viewer_controller_test.rb +++ b/test/functional/content_viewer_controller_test.rb @@ -661,8 +661,8 @@ class ContentViewerControllerTest < ActionController::TestCase get :view_page, :profile => owner.identifier, :page => folder.path assert_response :success assert_select '.image-gallery-item', 0 - end - + end + should 'display default image in the slideshow if thumbnails were not processed' do @controller.stubs(:per_page).returns(1) @@ -1296,14 +1296,14 @@ class ContentViewerControllerTest < ActionController::TestCase def comment_form_extra_contents(args) proc { hidden_field_tag('comment[some_field_id]', 1) - } + } end end class Plugin2 < Noosfero::Plugin def comment_form_extra_contents(args) proc { hidden_field_tag('comment[another_field_id]', 1) - } + } end end Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) @@ -1373,20 +1373,20 @@ class ContentViewerControllerTest < ActionController::TestCase get :view_page, :profile => profile.identifier, :page => [blog.path] assert_tag :tag => 'strong', :content => /bold/ end - + should 'add extra content on article header from plugins' do class Plugin1 < Noosfero::Plugin def article_header_extra_contents(args) proc { content_tag('div', '', :class => 'plugin1') - } + } end end class Plugin2 < Noosfero::Plugin def article_header_extra_contents(args) proc { content_tag('div', '', :class => 'plugin2') - } + } end end Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) @@ -1447,4 +1447,35 @@ class ContentViewerControllerTest < ActionController::TestCase assert_tag :tag => 'meta', :attributes => { :property => 'og:image', :content => /\/images\/x.png/ } end + should 'manage private article visualization' do + community = Community.create(:name => 'test-community') + community.add_member(@profile) + community.save! + + blog = community.articles.find_by_name("Blog") + + article = TinyMceArticle.create(:name => 'Article to be shared with images', + :body => 'This article should be shared with all social networks', + :profile => @profile, + :published => false, + :show_to_followers => true) + article.parent = blog + article.save! + + otheruser = create_user('otheruser').person + community.add_member(otheruser) + login_as(otheruser.identifier) + + get :view_page, :profile => community.identifier, "page" => 'blog' + + assert_response :success + assert_tag :tag => 'h1', :attributes => { :class => /title/ }, :content => article.name + + article.show_to_followers = false + article.save! + + get :view_page, :profile => community.identifier, "page" => 'blog' + + assert_no_tag :tag => 'h1', :attributes => { :class => /title/ }, :content => article.name + end end -- libgit2 0.21.2