Commit 1bd11fcdeaa85d7fc9f0c10e23293d2e4da457d9
Exists in
master
and in
27 other branches
Merge remote-tracking branch 'origin/master'
Showing
18 changed files
with
316 additions
and
75 deletions
Show diff stats
app/controllers/my_profile/profile_design_controller.rb
| ... | ... | @@ -3,7 +3,16 @@ class ProfileDesignController < BoxOrganizerController |
| 3 | 3 | needs_profile |
| 4 | 4 | |
| 5 | 5 | protect 'edit_profile_design', :profile |
| 6 | - | |
| 6 | + | |
| 7 | + before_filter :protect_fixed_block, :only => [:save, :move_block] | |
| 8 | + | |
| 9 | + def protect_fixed_block | |
| 10 | + block = boxes_holder.blocks.find(params[:id].gsub(/^block-/, '')) | |
| 11 | + if block.fixed && !current_person.is_admin? | |
| 12 | + render_access_denied | |
| 13 | + end | |
| 14 | + end | |
| 15 | + | |
| 7 | 16 | def available_blocks |
| 8 | 17 | blocks = [ ArticleBlock, TagsBlock, RecentDocumentsBlock, ProfileInfoBlock, LinkListBlock, MyNetworkBlock, FeedReaderBlock, ProfileImageBlock, LocationBlock, SlideshowBlock, ProfileSearchBlock, HighlightsBlock ] |
| 9 | 18 | ... | ... |
app/helpers/application_helper.rb
| ... | ... | @@ -945,9 +945,9 @@ module ApplicationHelper |
| 945 | 945 | # from Article model for an ArticleBlock. |
| 946 | 946 | def reference_to_article(text, article, anchor=nil) |
| 947 | 947 | if article.profile.domains.empty? |
| 948 | - href = "/#{article.url[:profile]}/" | |
| 948 | + href = "#{Noosfero.root}/#{article.url[:profile]}/" | |
| 949 | 949 | else |
| 950 | - href = "http://#{article.profile.domains.first.name}/" | |
| 950 | + href = "http://#{article.profile.domains.first.name}#{Noosfero.root}/" | |
| 951 | 951 | end |
| 952 | 952 | href += article.url[:page].join('/') |
| 953 | 953 | href += '#' + anchor if anchor | ... | ... |
app/helpers/article_helper.rb
| ... | ... | @@ -77,12 +77,59 @@ module ArticleHelper |
| 77 | 77 | content_tag('div', |
| 78 | 78 | radio_button(:article, :published, false) + |
| 79 | 79 | content_tag('label', _('Private'), :for => 'article_published_false', :id => "label_private") |
| 80 | - ) + | |
| 81 | - (article.profile.community? ? content_tag('div', | |
| 82 | - content_tag('label', _('Fill in the search field to add the exception users to see this content'), :id => "text-input-search-exception-users") + | |
| 83 | - token_input_field_tag(:q, 'search-article-privacy-exceptions', {:action => 'search_article_privacy_exceptions'}, | |
| 84 | - {:focus => false, :hint_text => _('Type in a search term for a user'), :pre_populate => tokenized_children})) : | |
| 85 | - '')) | |
| 80 | + ) + | |
| 81 | + privacity_exceptions(article, tokenized_children) | |
| 82 | + ) | |
| 83 | + end | |
| 84 | + | |
| 85 | + def privacity_exceptions(article, tokenized_children) | |
| 86 | + content_tag('div', | |
| 87 | + content_tag('div', | |
| 88 | + ( | |
| 89 | + if article.profile | |
| 90 | + add_option_to_followers(article, tokenized_children) | |
| 91 | + else | |
| 92 | + '' | |
| 93 | + end | |
| 94 | + ) | |
| 95 | + ), | |
| 96 | + :style => "margin-left:10px" | |
| 97 | + ) | |
| 98 | + end | |
| 99 | + | |
| 100 | + def add_option_to_followers(article, tokenized_children) | |
| 101 | + label_message = article.profile.organization? ? _('For all community members') : _('For all your friends') | |
| 102 | + | |
| 103 | + check_box( | |
| 104 | + :article, | |
| 105 | + :show_to_followers, | |
| 106 | + {:class => "custom_privacy_option"} | |
| 107 | + ) + | |
| 108 | + content_tag( | |
| 109 | + 'label', | |
| 110 | + label_message, | |
| 111 | + :for => 'article_show_to_followers', | |
| 112 | + :id => 'label_show_to_followers' | |
| 113 | + ) + | |
| 114 | + (article.profile.community? ? | |
| 115 | + content_tag( | |
| 116 | + 'div', | |
| 117 | + content_tag( | |
| 118 | + 'label', | |
| 119 | + _('Fill in the search field to add the exception users to see this content'), | |
| 120 | + :id => "text-input-search-exception-users" | |
| 121 | + ) + | |
| 122 | + token_input_field_tag( | |
| 123 | + :q, | |
| 124 | + 'search-article-privacy-exceptions', | |
| 125 | + {:action => 'search_article_privacy_exceptions'}, | |
| 126 | + { | |
| 127 | + :focus => false, | |
| 128 | + :hint_text => _('Type in a search term for a user'), | |
| 129 | + :pre_populate => tokenized_children | |
| 130 | + } | |
| 131 | + ) | |
| 132 | + ) : '') | |
| 86 | 133 | end |
| 87 | 134 | |
| 88 | 135 | def prepare_to_token_input(array) | ... | ... |
app/helpers/boxes_helper.rb
| ... | ... | @@ -170,49 +170,54 @@ module BoxesHelper |
| 170 | 170 | else |
| 171 | 171 | "before-block-#{block.id}" |
| 172 | 172 | end |
| 173 | - | |
| 174 | - content_tag('div', ' ', :id => id, :class => 'block-target' ) + drop_receiving_element(id, :url => { :action => 'move_block', :target => id }, :accept => box.acceptable_blocks, :hoverclass => 'block-target-hover') | |
| 173 | + if block.nil? or modifiable?(block) | |
| 174 | + content_tag('div', ' ', :id => id, :class => 'block-target' ) + drop_receiving_element(id, :url => { :action => 'move_block', :target => id }, :accept => box.acceptable_blocks, :hoverclass => 'block-target-hover') | |
| 175 | + else | |
| 176 | + "" | |
| 177 | + end | |
| 175 | 178 | end |
| 176 | 179 | |
| 177 | 180 | # makes the given block draggable so it can be moved away. |
| 178 | 181 | def block_handle(block) |
| 179 | - draggable_element("block-#{block.id}", :revert => true) | |
| 182 | + modifiable?(block) ? draggable_element("block-#{block.id}", :revert => true) : "" | |
| 180 | 183 | end |
| 181 | 184 | |
| 182 | 185 | def block_edit_buttons(block) |
| 183 | 186 | buttons = [] |
| 184 | 187 | nowhere = 'javascript: return false;' |
| 185 | 188 | |
| 186 | - if block.first? | |
| 187 | - buttons << icon_button('up-disabled', _("Can't move up anymore."), nowhere) | |
| 188 | - else | |
| 189 | - buttons << icon_button('up', _('Move block up'), { :action => 'move_block_up', :id => block.id }, { :method => 'post' }) | |
| 190 | - end | |
| 189 | + if modifiable?(block) | |
| 190 | + if block.first? | |
| 191 | + buttons << icon_button('up-disabled', _("Can't move up anymore."), nowhere) | |
| 192 | + else | |
| 193 | + buttons << icon_button('up', _('Move block up'), { :action => 'move_block_up', :id => block.id }, { :method => 'post' }) | |
| 194 | + end | |
| 191 | 195 | |
| 192 | - if block.last? | |
| 193 | - buttons << icon_button('down-disabled', _("Can't move down anymore."), nowhere) | |
| 194 | - else | |
| 195 | - buttons << icon_button(:down, _('Move block down'), { :action => 'move_block_down' ,:id => block.id }, { :method => 'post'}) | |
| 196 | - end | |
| 196 | + if block.last? | |
| 197 | + buttons << icon_button('down-disabled', _("Can't move down anymore."), nowhere) | |
| 198 | + else | |
| 199 | + buttons << icon_button(:down, _('Move block down'), { :action => 'move_block_down' ,:id => block.id }, { :method => 'post'}) | |
| 200 | + end | |
| 197 | 201 | |
| 198 | - holder = block.owner | |
| 199 | - # move to opposite side | |
| 200 | - # FIXME too much hardcoded stuff | |
| 201 | - if holder.layout_template == 'default' | |
| 202 | - if block.box.position == 2 # area 2, left side => move to right side | |
| 203 | - buttons << icon_button('right', _('Move to the opposite side'), { :action => 'move_block', :target => 'end-of-box-' + holder.boxes[2].id.to_s, :id => block.id }, :method => 'post' ) | |
| 204 | - elsif block.box.position == 3 # area 3, right side => move to left side | |
| 205 | - buttons << icon_button('left', _('Move to the opposite side'), { :action => 'move_block', :target => 'end-of-box-' + holder.boxes[1].id.to_s, :id => block.id }, :method => 'post' ) | |
| 202 | + holder = block.owner | |
| 203 | + # move to opposite side | |
| 204 | + # FIXME too much hardcoded stuff | |
| 205 | + if holder.layout_template == 'default' | |
| 206 | + if block.box.position == 2 # area 2, left side => move to right side | |
| 207 | + buttons << icon_button('right', _('Move to the opposite side'), { :action => 'move_block', :target => 'end-of-box-' + holder.boxes[2].id.to_s, :id => block.id }, :method => 'post' ) | |
| 208 | + elsif block.box.position == 3 # area 3, right side => move to left side | |
| 209 | + buttons << icon_button('left', _('Move to the opposite side'), { :action => 'move_block', :target => 'end-of-box-' + holder.boxes[1].id.to_s, :id => block.id }, :method => 'post' ) | |
| 210 | + end | |
| 206 | 211 | end |
| 207 | - end | |
| 208 | 212 | |
| 209 | - if block.editable? | |
| 210 | - buttons << colorbox_icon_button(:edit, _('Edit'), { :action => 'edit', :id => block.id }) | |
| 211 | - end | |
| 213 | + if block.editable? | |
| 214 | + buttons << colorbox_icon_button(:edit, _('Edit'), { :action => 'edit', :id => block.id }) | |
| 215 | + end | |
| 212 | 216 | |
| 213 | - if !block.main? | |
| 214 | - buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')}) | |
| 215 | - buttons << icon_button(:clone, _('Clone'), { :action => 'clone_block', :id => block.id }, { :method => 'post' }) | |
| 217 | + if !block.main? | |
| 218 | + buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')}) | |
| 219 | + buttons << icon_button(:clone, _('Clone'), { :action => 'clone_block', :id => block.id }, { :method => 'post' }) | |
| 220 | + end | |
| 216 | 221 | end |
| 217 | 222 | |
| 218 | 223 | if block.respond_to?(:help) |
| ... | ... | @@ -248,5 +253,7 @@ module BoxesHelper |
| 248 | 253 | classes |
| 249 | 254 | end |
| 250 | 255 | |
| 251 | - | |
| 256 | + def modifiable?(block) | |
| 257 | + return !block.fixed || environment.admins.include?(user) | |
| 258 | + end | |
| 252 | 259 | end | ... | ... |
app/helpers/layout_helper.rb
| ... | ... | @@ -2,6 +2,7 @@ module LayoutHelper |
| 2 | 2 | |
| 3 | 3 | def body_classes |
| 4 | 4 | # Identify the current controller and action for the CSS: |
| 5 | + (logged_in? ? " logged-in" : "") + | |
| 5 | 6 | " controller-#{controller.controller_name}" + |
| 6 | 7 | " action-#{controller.controller_name}-#{controller.action_name}" + |
| 7 | 8 | " template-#{@layout_template || if profile.blank? then 'default' else profile.layout_template end}" + | ... | ... |
app/helpers/search_helper.rb
| ... | ... | @@ -21,6 +21,12 @@ module SearchHelper |
| 21 | 21 | 'more_comments' => _('More comments') |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | + COMMON_PROFILE_LIST_BLOCK = [ | |
| 25 | + :enterprises, | |
| 26 | + :people, | |
| 27 | + :communities | |
| 28 | + ] | |
| 29 | + | |
| 24 | 30 | # FIXME remove it after search_controler refactored |
| 25 | 31 | include EventsHelper |
| 26 | 32 | |
| ... | ... | @@ -94,7 +100,7 @@ module SearchHelper |
| 94 | 100 | compact_link = display?(asset, :compact) ? (display == 'compact' ? _('Compact') : link_to(_('Compact'), params.merge(:display => 'compact'))) : nil |
| 95 | 101 | map_link = display?(asset, :map) ? (display == 'map' ? _('Map') : link_to(_('Map'), params.merge(:display => 'map'))) : nil |
| 96 | 102 | full_link = display?(asset, :full) ? (display == 'full' ? _('Full') : link_to(_('Full'), params.merge(:display => 'full'))) : nil |
| 97 | - content_tag('div', | |
| 103 | + content_tag('div', | |
| 98 | 104 | content_tag('strong', _('Display')) + ': ' + [compact_link, map_link, full_link].compact.join(' | ').html_safe, |
| 99 | 105 | :class => 'search-customize-options' |
| 100 | 106 | ) | ... | ... |
app/models/article.rb
| ... | ... | @@ -2,7 +2,14 @@ require 'hpricot' |
| 2 | 2 | |
| 3 | 3 | class Article < ActiveRecord::Base |
| 4 | 4 | |
| 5 | - 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 | |
| 5 | + attr_accessible :name, :body, :abstract, :profile, :tag_list, :parent, | |
| 6 | + :allow_members_to_edit, :translation_of_id, :language, | |
| 7 | + :license_id, :parent_id, :display_posts_in_current_language, | |
| 8 | + :category_ids, :posts_per_page, :moderate_comments, | |
| 9 | + :accept_comments, :feed, :published, :source, | |
| 10 | + :highlighted, :notify_comments, :display_hits, :slug, | |
| 11 | + :external_feed_builder, :display_versions, :external_link, | |
| 12 | + :image_builder, :show_to_followers | |
| 6 | 13 | |
| 7 | 14 | acts_as_having_image |
| 8 | 15 | |
| ... | ... | @@ -333,7 +340,7 @@ class Article < ActiveRecord::Base |
| 333 | 340 | def belongs_to_blog? |
| 334 | 341 | self.parent and self.parent.blog? |
| 335 | 342 | end |
| 336 | - | |
| 343 | + | |
| 337 | 344 | def belongs_to_forum? |
| 338 | 345 | self.parent and self.parent.forum? |
| 339 | 346 | end |
| ... | ... | @@ -445,6 +452,7 @@ class Article < ActiveRecord::Base |
| 445 | 452 | if self.parent && !self.parent.published? |
| 446 | 453 | return false |
| 447 | 454 | end |
| 455 | + | |
| 448 | 456 | true |
| 449 | 457 | else |
| 450 | 458 | false |
| ... | ... | @@ -476,14 +484,17 @@ class Article < ActiveRecord::Base |
| 476 | 484 | {:conditions => [" articles.published = ? OR |
| 477 | 485 | articles.last_changed_by_id = ? OR |
| 478 | 486 | articles.profile_id = ? OR |
| 479 | - ?", | |
| 480 | - true, user.id, user.id, user.has_permission?(:view_private_content, profile)] } | |
| 487 | + ? OR articles.show_to_followers = ? AND ?", | |
| 488 | + true, user.id, user.id, user.has_permission?(:view_private_content, profile), | |
| 489 | + true, user.follows?(profile)]} | |
| 481 | 490 | end |
| 482 | 491 | |
| 492 | + | |
| 483 | 493 | def display_unpublished_article_to?(user) |
| 484 | 494 | user == author || allow_view_private_content?(user) || user == profile || |
| 485 | 495 | user.is_admin?(profile.environment) || user.is_admin?(profile) || |
| 486 | - article_privacy_exceptions.include?(user) | |
| 496 | + article_privacy_exceptions.include?(user) || | |
| 497 | + (self.show_to_followers && user.follows?(profile)) | |
| 487 | 498 | end |
| 488 | 499 | |
| 489 | 500 | def display_to?(user = nil) | ... | ... |
app/models/block.rb
| 1 | 1 | class Block < ActiveRecord::Base |
| 2 | 2 | |
| 3 | - attr_accessible :title, :display, :limit, :box_id, :posts_per_page, :visualization_format, :language, :display_user, :box | |
| 3 | + attr_accessible :title, :display, :limit, :box_id, :posts_per_page, :visualization_format, :language, :display_user, :box, :fixed | |
| 4 | 4 | |
| 5 | 5 | # to be able to generate HTML |
| 6 | 6 | include ActionView::Helpers::UrlHelper |
| ... | ... | @@ -110,6 +110,9 @@ class Block < ActiveRecord::Base |
| 110 | 110 | # * <tt>'all'</tt>: the block is always displayed |
| 111 | 111 | settings_items :language, :type => :string, :default => 'all' |
| 112 | 112 | |
| 113 | + # The block can be configured to be fixed. Only can be edited by environment admins | |
| 114 | + settings_items :fixed, :type => :boolean, :default => false | |
| 115 | + | |
| 113 | 116 | # returns the description of the block, used when the user sees a list of |
| 114 | 117 | # blocks to choose one to include in the design. |
| 115 | 118 | # | ... | ... |
app/views/box_organizer/edit.html.erb
| ... | ... | @@ -5,6 +5,12 @@ |
| 5 | 5 | |
| 6 | 6 | <%= labelled_form_field(_('Custom title for this block: '), text_field(:block, :title, :maxlength => 20)) %> |
| 7 | 7 | |
| 8 | + <% if environment.admins.include?(user) %> | |
| 9 | + <div class="fixed_block"> | |
| 10 | + <%= labelled_check_box(_("Fixed"), "block[fixed]", value = "1", checked = @block.fixed) %> | |
| 11 | + </div> | |
| 12 | + <% end %> | |
| 13 | + | |
| 8 | 14 | <%= render :partial => partial_for_class(@block.class) %> |
| 9 | 15 | |
| 10 | 16 | <div class="display"> | ... | ... |
app/views/events/events.html.erb
| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | <div id='agenda-toolbar'> |
| 4 | 4 | <%= button :back, _('Back to %s') % profile.name, profile.url %> |
| 5 | 5 | <% if user && user.has_permission?('post_content', profile) %> |
| 6 | - <%= button :new, _('New event'), myprofile_url(:controller => 'cms', :action => 'new', :type => 'Event') %> | |
| 6 | + <%= button :new, _('New event'), myprofile_path(:controller => 'cms', :action => 'new', :type => 'Event') %> | |
| 7 | 7 | <% end %> |
| 8 | 8 | </div> |
| 9 | 9 | ... | ... |
app/views/search/_display_results.html.erb
| ... | ... | @@ -14,7 +14,7 @@ |
| 14 | 14 | |
| 15 | 15 | <% display = display_filter(name, params[:display]) %> |
| 16 | 16 | |
| 17 | - <div class="search-results-innerbox search-results-type-<%= name.to_s.singularize %> <%= 'common-profile-list-block' if [:enterprises, :people, :communities].include?(name) %>"> | |
| 17 | + <div class="search-results-innerbox search-results-type-<%= name.to_s.singularize %> <%= 'common-profile-list-block' if SearchHelper::COMMON_PROFILE_LIST_BLOCK.include?(name) %>"> | |
| 18 | 18 | <ul> |
| 19 | 19 | <% search[:results].each do |hit| %> |
| 20 | 20 | <% partial = partial_for_class(hit.class, display) %> | ... | ... |
db/migrate/20150113131617_add_show_to_followers_for_article.rb
0 → 100644
features/edit_article.feature
| ... | ... | @@ -47,6 +47,28 @@ Feature: edit article |
| 47 | 47 | Then I should see "Access denied" |
| 48 | 48 | |
| 49 | 49 | @selenium |
| 50 | + Scenario: Hide token field when show to members is activated | |
| 51 | + Given the following communities | |
| 52 | + | name | identifier | owner | | |
| 53 | + | Free Software | freesoftware | joaosilva | | |
| 54 | + And the following users | |
| 55 | + | login | name | | |
| 56 | + | mario | Mario Souto | | |
| 57 | + | maria | Maria Silva | | |
| 58 | + And "Mario Souto" is a member of "Free Software" | |
| 59 | + And "Maria Silva" is a member of "Free Software" | |
| 60 | + And I am on freesoftware's control panel | |
| 61 | + And I follow "Manage Content" | |
| 62 | + And I should see "New content" | |
| 63 | + And I follow "New content" | |
| 64 | + And I should see "Folder" | |
| 65 | + When I follow "Folder" | |
| 66 | + And I fill in "Title" with "My Folder" | |
| 67 | + And I choose "article_published_false" | |
| 68 | + And I check "article_show_to_followers" | |
| 69 | + Then I should not see "Fill in the search" | |
| 70 | + | |
| 71 | + @selenium | |
| 50 | 72 | Scenario: show exception users field when you choose the private option |
| 51 | 73 | Given the following communities |
| 52 | 74 | | name | identifier | owner | | ... | ... |
public/javascripts/article.js
| ... | ... | @@ -136,7 +136,7 @@ jQuery(function($) { |
| 136 | 136 | if (data.length && data.length > 0) { |
| 137 | 137 | $('#media-search-results').slideDown(); |
| 138 | 138 | } |
| 139 | - $('#media-search-box .header').toggleClass('icon-loading'); | |
| 139 | + $('#media-search-box .header').toggleClass('icon-loading'); | |
| 140 | 140 | }); |
| 141 | 141 | return false; |
| 142 | 142 | }); |
| ... | ... | @@ -144,20 +144,20 @@ jQuery(function($) { |
| 144 | 144 | $('#media-upload-form form').ajaxForm({ |
| 145 | 145 | resetForm: true, |
| 146 | 146 | beforeSubmit: |
| 147 | - function() { | |
| 148 | - $('#media-upload-form').slideUp(); | |
| 149 | - $('#media-upload-box .header').toggleClass('icon-loading'); | |
| 150 | - }, | |
| 147 | + function() { | |
| 148 | + $('#media-upload-form').slideUp(); | |
| 149 | + $('#media-upload-box .header').toggleClass('icon-loading'); | |
| 150 | + }, | |
| 151 | 151 | success: |
| 152 | - function(text) { | |
| 153 | - text = text.replace('<pre>', '').replace('</pre>', ''); // old firefox | |
| 154 | - var data = $.parseJSON(text); | |
| 155 | - list_items(data, '#media-upload-results .items', true); | |
| 156 | - if (data.length && data.length > 0) { | |
| 157 | - $('#media-upload-results').slideDown(); | |
| 158 | - } | |
| 159 | - $('#media-upload-box .header').toggleClass('icon-loading'); | |
| 152 | + function(text) { | |
| 153 | + text = text.replace('<pre>', '').replace('</pre>', ''); // old firefox | |
| 154 | + var data = $.parseJSON(text); | |
| 155 | + list_items(data, '#media-upload-results .items', true); | |
| 156 | + if (data.length && data.length > 0) { | |
| 157 | + $('#media-upload-results').slideDown(); | |
| 160 | 158 | } |
| 159 | + $('#media-upload-box .header').toggleClass('icon-loading'); | |
| 160 | + } | |
| 161 | 161 | }); |
| 162 | 162 | |
| 163 | 163 | $('#media-upload-more-files').click(function() { |
| ... | ... | @@ -166,19 +166,45 @@ jQuery(function($) { |
| 166 | 166 | return false; |
| 167 | 167 | }); |
| 168 | 168 | |
| 169 | + function is_public_article() { | |
| 170 | + return $("#article_published_true").attr('checked'); | |
| 171 | + } | |
| 172 | + | |
| 173 | + function show_hide_privacy_options() { | |
| 174 | + var show_privacy_options = $("#article_published_false").attr('checked'); | |
| 175 | + var custom_privacy_option = $(".custom_privacy_option").parent("div"); | |
| 176 | + | |
| 177 | + if( show_privacy_options ) { | |
| 178 | + custom_privacy_option.show(); | |
| 179 | + } else { | |
| 180 | + custom_privacy_option.hide(); | |
| 181 | + } | |
| 182 | + show_hide_token_input(); | |
| 183 | + } | |
| 184 | + | |
| 169 | 185 | function show_hide_token_input() { |
| 170 | - if($("#article_published_false").attr('checked')) | |
| 171 | - $("#text-input-search-exception-users").parent("div").css('display', 'block'); | |
| 172 | - else | |
| 173 | - $("#text-input-search-exception-users").parent("div").css('display', 'none'); | |
| 186 | + var display_token = $(".custom_privacy_option:checked").length == 0; | |
| 187 | + var token_field = $("#text-input-search-exception-users").parent("div"); | |
| 188 | + | |
| 189 | + if( display_token && !is_public_article() ) { | |
| 190 | + token_field.css('display', 'block'); | |
| 191 | + } else { | |
| 192 | + token_field.css('display', 'none'); | |
| 193 | + } | |
| 174 | 194 | } |
| 175 | 195 | |
| 176 | 196 | if( $("#token-input-search-article-privacy-exceptions").length == 1 ) { |
| 197 | + show_hide_privacy_options(); | |
| 177 | 198 | show_hide_token_input(); |
| 178 | - | |
| 179 | - //Hide / Show the text area | |
| 180 | - $("#article_published_false").click(show_hide_token_input); | |
| 181 | - $("#article_published_true").click(show_hide_token_input); | |
| 182 | 199 | } |
| 183 | 200 | |
| 201 | + $(document).ready(function(){ | |
| 202 | + show_hide_privacy_options(); | |
| 203 | + }); | |
| 204 | + | |
| 205 | + //Hide / Show the text area | |
| 206 | + $("#article_published_false").click(show_hide_privacy_options); | |
| 207 | + $("#article_published_true").click(show_hide_privacy_options); | |
| 208 | + $(".custom_privacy_option").click(show_hide_token_input); | |
| 209 | + | |
| 184 | 210 | }); | ... | ... |
test/functional/content_viewer_controller_test.rb
| ... | ... | @@ -661,8 +661,8 @@ class ContentViewerControllerTest < ActionController::TestCase |
| 661 | 661 | get :view_page, :profile => owner.identifier, :page => folder.path |
| 662 | 662 | assert_response :success |
| 663 | 663 | assert_select '.image-gallery-item', 0 |
| 664 | - end | |
| 665 | - | |
| 664 | + end | |
| 665 | + | |
| 666 | 666 | |
| 667 | 667 | should 'display default image in the slideshow if thumbnails were not processed' do |
| 668 | 668 | @controller.stubs(:per_page).returns(1) |
| ... | ... | @@ -1296,14 +1296,14 @@ class ContentViewerControllerTest < ActionController::TestCase |
| 1296 | 1296 | def comment_form_extra_contents(args) |
| 1297 | 1297 | proc { |
| 1298 | 1298 | hidden_field_tag('comment[some_field_id]', 1) |
| 1299 | - } | |
| 1299 | + } | |
| 1300 | 1300 | end |
| 1301 | 1301 | end |
| 1302 | 1302 | class Plugin2 < Noosfero::Plugin |
| 1303 | 1303 | def comment_form_extra_contents(args) |
| 1304 | 1304 | proc { |
| 1305 | 1305 | hidden_field_tag('comment[another_field_id]', 1) |
| 1306 | - } | |
| 1306 | + } | |
| 1307 | 1307 | end |
| 1308 | 1308 | end |
| 1309 | 1309 | Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) |
| ... | ... | @@ -1373,20 +1373,20 @@ class ContentViewerControllerTest < ActionController::TestCase |
| 1373 | 1373 | get :view_page, :profile => profile.identifier, :page => [blog.path] |
| 1374 | 1374 | assert_tag :tag => 'strong', :content => /bold/ |
| 1375 | 1375 | end |
| 1376 | - | |
| 1376 | + | |
| 1377 | 1377 | should 'add extra content on article header from plugins' do |
| 1378 | 1378 | class Plugin1 < Noosfero::Plugin |
| 1379 | 1379 | def article_header_extra_contents(args) |
| 1380 | 1380 | proc { |
| 1381 | 1381 | content_tag('div', '', :class => 'plugin1') |
| 1382 | - } | |
| 1382 | + } | |
| 1383 | 1383 | end |
| 1384 | 1384 | end |
| 1385 | 1385 | class Plugin2 < Noosfero::Plugin |
| 1386 | 1386 | def article_header_extra_contents(args) |
| 1387 | 1387 | proc { |
| 1388 | 1388 | content_tag('div', '', :class => 'plugin2') |
| 1389 | - } | |
| 1389 | + } | |
| 1390 | 1390 | end |
| 1391 | 1391 | end |
| 1392 | 1392 | Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) |
| ... | ... | @@ -1447,4 +1447,35 @@ class ContentViewerControllerTest < ActionController::TestCase |
| 1447 | 1447 | assert_tag :tag => 'meta', :attributes => { :property => 'og:image', :content => /\/images\/x.png/ } |
| 1448 | 1448 | end |
| 1449 | 1449 | |
| 1450 | + should 'manage private article visualization' do | |
| 1451 | + community = Community.create(:name => 'test-community') | |
| 1452 | + community.add_member(@profile) | |
| 1453 | + community.save! | |
| 1454 | + | |
| 1455 | + blog = community.articles.find_by_name("Blog") | |
| 1456 | + | |
| 1457 | + article = TinyMceArticle.create(:name => 'Article to be shared with images', | |
| 1458 | + :body => 'This article should be shared with all social networks', | |
| 1459 | + :profile => @profile, | |
| 1460 | + :published => false, | |
| 1461 | + :show_to_followers => true) | |
| 1462 | + article.parent = blog | |
| 1463 | + article.save! | |
| 1464 | + | |
| 1465 | + otheruser = create_user('otheruser').person | |
| 1466 | + community.add_member(otheruser) | |
| 1467 | + login_as(otheruser.identifier) | |
| 1468 | + | |
| 1469 | + get :view_page, :profile => community.identifier, "page" => 'blog' | |
| 1470 | + | |
| 1471 | + assert_response :success | |
| 1472 | + assert_tag :tag => 'h1', :attributes => { :class => /title/ }, :content => article.name | |
| 1473 | + | |
| 1474 | + article.show_to_followers = false | |
| 1475 | + article.save! | |
| 1476 | + | |
| 1477 | + get :view_page, :profile => community.identifier, "page" => 'blog' | |
| 1478 | + | |
| 1479 | + assert_no_tag :tag => 'h1', :attributes => { :class => /title/ }, :content => article.name | |
| 1480 | + end | |
| 1450 | 1481 | end | ... | ... |
test/functional/profile_design_controller_test.rb
| ... | ... | @@ -737,4 +737,22 @@ class ProfileDesignControllerTest < ActionController::TestCase |
| 737 | 737 | end |
| 738 | 738 | end |
| 739 | 739 | |
| 740 | + test 'should forbid POST to save for fixed blocks' do | |
| 741 | + block = profile.blocks.last | |
| 742 | + block.fixed = true | |
| 743 | + block.save! | |
| 744 | + | |
| 745 | + post :save, id: block.id, profile: profile.identifier | |
| 746 | + assert_response :forbidden | |
| 747 | + end | |
| 748 | + | |
| 749 | + test 'should forbid POST to move_block for fixed blocks' do | |
| 750 | + block = profile.blocks.last | |
| 751 | + block.fixed = true | |
| 752 | + block.save! | |
| 753 | + | |
| 754 | + post :move_block, id: block.id, profile: profile.identifier, target: "end-of-box-#{@box3.id}" | |
| 755 | + assert_response :forbidden | |
| 756 | + end | |
| 757 | + | |
| 740 | 758 | end | ... | ... |
test/unit/boxes_helper_test.rb
| 1 | 1 | require File.dirname(__FILE__) + '/../test_helper' |
| 2 | +require File.dirname(__FILE__) + '/../../app/helpers/boxes_helper' | |
| 2 | 3 | |
| 3 | 4 | class BoxesHelperTest < ActionView::TestCase |
| 4 | 5 | |
| ... | ... | @@ -119,4 +120,31 @@ class BoxesHelperTest < ActionView::TestCase |
| 119 | 120 | display_box_content(box, '') |
| 120 | 121 | end |
| 121 | 122 | |
| 123 | + should 'not show move options on block when block is fixed' do | |
| 124 | + p = create_user_with_blocks | |
| 125 | + | |
| 126 | + b = p.blocks.select{|bk| !bk.kind_of?(MainBlock) }[0] | |
| 127 | + b.fixed = true | |
| 128 | + b.save! | |
| 129 | + | |
| 130 | + stubs(:environment).returns(p.environment) | |
| 131 | + stubs(:user).returns(p) | |
| 132 | + | |
| 133 | + assert_equal false, modifiable?(b) | |
| 134 | + end | |
| 135 | + | |
| 136 | + should 'show move options on block when block is fixed and user is admin' do | |
| 137 | + p = create_user_with_blocks | |
| 138 | + | |
| 139 | + b = p.blocks.select{|bk| !bk.kind_of?(MainBlock) }[0] | |
| 140 | + b.fixed = true | |
| 141 | + b.save! | |
| 142 | + | |
| 143 | + p.environment.add_admin(p) | |
| 144 | + | |
| 145 | + stubs(:environment).returns(p.environment) | |
| 146 | + stubs(:user).returns(p) | |
| 147 | + | |
| 148 | + assert_equal true, modifiable?(b) | |
| 149 | + end | |
| 122 | 150 | end | ... | ... |
| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | |
| 2 | + | |
| 3 | +class LayoutHelperTest < ActionView::TestCase | |
| 4 | + | |
| 5 | + should 'append logged-in class in body when user is logged-in' do | |
| 6 | + expects(:logged_in?).returns(true) | |
| 7 | + expects(:profile).returns(nil).at_least_once | |
| 8 | + assert_includes body_classes.split, 'logged-in' | |
| 9 | + end | |
| 10 | + | |
| 11 | + should 'not append logged-in class when user is not logged-in' do | |
| 12 | + expects(:logged_in?).returns(false) | |
| 13 | + expects(:profile).returns(nil).at_least_once | |
| 14 | + assert_not_includes body_classes.split, 'logged-in' | |
| 15 | + end | |
| 16 | + | |
| 17 | +end | ... | ... |