Commit b1bcaade41fca838672b46bb40330975da9b5dd2

Authored by Joenio Costa
2 parents 370d0e1f fa207812

Merge branch 'next'

app/models/block.rb
@@ -40,7 +40,7 @@ class Block < ActiveRecord::Base @@ -40,7 +40,7 @@ class Block < ActiveRecord::Base
40 if context[:article] 40 if context[:article]
41 return context[:article] != owner.home_page 41 return context[:article] != owner.home_page
42 else 42 else
43 - return context[:request_path] != '/' + owner.identifier 43 + return context[:request_path] != '/' + (owner.kind_of?(Profile) ? owner.identifier : '')
44 end 44 end
45 end 45 end
46 end 46 end
@@ -153,4 +153,19 @@ class Block < ActiveRecord::Base @@ -153,4 +153,19 @@ class Block < ActiveRecord::Base
153 } 153 }
154 end 154 end
155 155
  156 + DISPLAY_OPTIONS = {
  157 + 'always' => __('In all pages'),
  158 + 'home_page_only' => __('Only in the homepage'),
  159 + 'except_home_page' => __('In all pages, except in the homepage'),
  160 + 'never' => __('Don\'t display'),
  161 + }
  162 +
  163 + def display_options
  164 + DISPLAY_OPTIONS.keys
  165 + end
  166 +
  167 + def display_option_label(option)
  168 + DISPLAY_OPTIONS[option]
  169 + end
  170 +
156 end 171 end
app/models/main_block.rb
@@ -17,11 +17,15 @@ class MainBlock < Block @@ -17,11 +17,15 @@ class MainBlock < Block
17 end 17 end
18 18
19 def editable? 19 def editable?
20 - false 20 + true
21 end 21 end
22 22
23 def cacheable? 23 def cacheable?
24 - false 24 + false
  25 + end
  26 +
  27 + def display_options
  28 + ['always', 'except_home_page']
25 end 29 end
26 30
27 end 31 end
app/views/box_organizer/edit.rhtml
1 <div class="block-config-options <%= @block.class.name %>-options"> 1 <div class="block-config-options <%= @block.class.name %>-options">
2 - <h2 class="title"><%= _('Editing block') %></h2> 2 + <h2 class="title"><%= _(@block.class.description) %></h2>
3 3
4 <% form_tag(:action => 'save', :id => @block.id) do %> 4 <% form_tag(:action => 'save', :id => @block.id) do %>
5 5
@@ -9,17 +9,11 @@ @@ -9,17 +9,11 @@
9 9
10 <%= labelled_form_field _('Display this block:'), '' %> 10 <%= labelled_form_field _('Display this block:'), '' %>
11 <div style='margin-left: 10px'> 11 <div style='margin-left: 10px'>
12 - <%= radio_button(:block, :display, 'always') %>  
13 - <%= label_tag('block_display_always', _('In all pages')) %>  
14 - <br/>  
15 - <%= radio_button(:block, :display, 'home_page_only') %>  
16 - <%= label_tag('block_display_home_page_only', _('Only in the homepage')) %>  
17 - <br/>  
18 - <%= radio_button(:block, :display, 'except_home_page') %>  
19 - <%= label_tag('block_display_except_home_page', _('In all pages, except in the homepage')) %>  
20 - <br/>  
21 - <%= radio_button(:block, :display, 'never') %>  
22 - <%= label_tag('block_display_never', _("Don't display")) %> 12 + <% @block.display_options.each do |option| %>
  13 + <%= radio_button(:block, :display, option) %>
  14 + <%= label_tag("block_display_#{option}", _(@block.display_option_label(option))) %>
  15 + <br/>
  16 + <% end %>
23 </div> 17 </div>
24 18
25 <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %> 19 <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %>
plugins/comment_group/lib/ext/article.rb
@@ -7,8 +7,8 @@ class Article @@ -7,8 +7,8 @@ class Article
7 validate :not_empty_group_comments_removed 7 validate :not_empty_group_comments_removed
8 8
9 def not_empty_group_comments_removed 9 def not_empty_group_comments_removed
10 - if body  
11 - groups_with_comments = group_comments.collect {|comment| comment.group_id}.uniq 10 + if body && body_changed?
  11 + groups_with_comments = Comment.find(:all, :select => 'distinct group_id', :conditions => {:source_id => self.id}).map(&:group_id).compact
12 groups = Hpricot(body.to_s).search('.macro').collect{|element| element['data-macro-group_id'].to_i} 12 groups = Hpricot(body.to_s).search('.macro').collect{|element| element['data-macro-group_id'].to_i}
13 errors.add_to_base(N_('Not empty group comment cannot be removed')) unless (groups_with_comments-groups).empty? 13 errors.add_to_base(N_('Not empty group comment cannot be removed')) unless (groups_with_comments-groups).empty?
14 end 14 end
plugins/comment_group/test/unit/article_test.rb
1 require File.dirname(__FILE__) + '/../test_helper' 1 require File.dirname(__FILE__) + '/../test_helper'
  2 +require 'benchmark'
2 3
3 class ArticleTest < ActiveSupport::TestCase 4 class ArticleTest < ActiveSupport::TestCase
4 5
@@ -16,16 +17,40 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -16,16 +17,40 @@ class ArticleTest &lt; ActiveSupport::TestCase
16 end 17 end
17 18
18 should 'do not allow a exclusion of a group comment macro if this group has comments' do 19 should 'do not allow a exclusion of a group comment macro if this group has comments' do
19 - article.update_attribute(:body, "<div class=\"macro\" data-macro-group_id=2></div>") 20 + article.body = "<div class=\"macro\" data-macro-group_id=2></div>"
20 comment1 = fast_create(Comment, :group_id => 1, :source_id => article.id) 21 comment1 = fast_create(Comment, :group_id => 1, :source_id => article.id)
21 assert !article.save 22 assert !article.save
22 assert_equal 'Not empty group comment cannot be removed', article.errors[:base] 23 assert_equal 'Not empty group comment cannot be removed', article.errors[:base]
23 end 24 end
24 25
25 should 'allow save if comment group macro is not removed for group with comments' do 26 should 'allow save if comment group macro is not removed for group with comments' do
26 - article.update_attribute(:body, "<div class=\"macro\" data-macro-group_id=1></div>") 27 + article.body = "<div class=\"macro\" data-macro-group_id=1></div>"
27 comment1 = fast_create(Comment, :group_id => 1, :source_id => article.id) 28 comment1 = fast_create(Comment, :group_id => 1, :source_id => article.id)
28 assert article.save 29 assert article.save
29 end 30 end
30 31
  32 + should 'do not validate empty group if article body is not changed' do
  33 + article.body = "<div class=\"macro\" data-macro-group_id=2></div>"
  34 + assert article.save
  35 + comment1 = fast_create(Comment, :group_id => 1, :source_id => article.id)
  36 + article.name = article.name + 'changed'
  37 + assert article.save
  38 + end
  39 +
  40 + should 'improve performance checking changes in body' do
  41 + i = 1
  42 + time0 = (Benchmark.measure { 50.times {
  43 + i = i + 1
  44 + article.body = "i = #{i}"
  45 + assert article.save
  46 + }})
  47 + i = 1
  48 + time1 = (Benchmark.measure { 50.times {
  49 + i = i + 1
  50 + article.body = "i = 1"
  51 + assert article.save
  52 + }})
  53 + assert time0.total > time1.total
  54 + end
  55 +
31 end 56 end
plugins/community_block/lib/community_block.rb 0 → 100644
@@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
  1 +class CommunityBlock < Block
  2 +
  3 + def self.description
  4 + _("Community block")
  5 + end
  6 +
  7 + def help
  8 + _("Help for Community Description Block.")
  9 + end
  10 +
  11 + def content(arg={})
  12 + block = self
  13 +
  14 + lambda do
  15 + render :file => 'community_block', :locals => { :block => block }
  16 + end
  17 + end
  18 +
  19 +end
plugins/community_block/lib/community_block_plugin.rb 0 → 100644
@@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
  1 +require_dependency File.dirname(__FILE__) + '/community_block'
  2 +
  3 +class CommunityBlockPlugin < Noosfero::Plugin
  4 +
  5 + def self.plugin_name
  6 + "Community Block Plugin"
  7 + end
  8 +
  9 + def self.plugin_description
  10 + _("A plugin that adds a block to show community description")
  11 + end
  12 +
  13 + def self.extra_blocks
  14 + {
  15 + CommunityBlock => {:type => Community}
  16 + }
  17 + end
  18 +
  19 + def self.has_admin_url?
  20 + false
  21 + end
  22 +
  23 + def stylesheet?
  24 + true
  25 + end
  26 +
  27 +end
plugins/community_block/public/style.css 0 → 100644
@@ -0,0 +1,104 @@ @@ -0,0 +1,104 @@
  1 +#content .box-1 .community-block {
  2 + display: table;
  3 + width: 100%;
  4 +}
  5 +
  6 +#content .box-1 .community-block .community-block-logo {
  7 + float: left;
  8 + width: 150px;
  9 + height: 150px;
  10 + padding: 5px;
  11 +}
  12 +
  13 +#content .box-1 .community-block-info {
  14 + float: left;
  15 + padding: 5px;
  16 + width: 360px;
  17 + margin-left: 2px;
  18 +}
  19 +
  20 +#content .box-1 .community-block .community-block-title .menu-submenu {
  21 + bottom: 154px;
  22 + right: -120px;
  23 +}
  24 +
  25 +#content .box-1 .community-block .community-block-title .menu-submenu-header {
  26 + display: none;
  27 +}
  28 +
  29 +#content .box-1 .community-block .community-block-title .menu-submenu-content {
  30 + border: 1px solid #888a85;
  31 + border-radius: 4px;
  32 + background-color: #efefef;
  33 + background-image: none;
  34 +}
  35 +
  36 +#content .box-1 .community-block .community-block-title .menu-submenu-content h4 {
  37 + display: none;
  38 +}
  39 +
  40 +#content .box-1 .community-block .community-block-title .menu-submenu-content ul {
  41 + list-style: none;
  42 +}
  43 +
  44 +#content .box-1 .community-block .community-block-title .menu-submenu-content li {
  45 + padding: 7px;
  46 + font-size: 10px;
  47 +}
  48 +
  49 +#content .box-1 .community-block .community-block-title .menu-submenu-content a {
  50 + color: #000;
  51 +}
  52 +
  53 +#content .box-1 .community-block .community-block-title .menu-submenu-footer {
  54 + display: none;
  55 +}
  56 +
  57 +#content .box-1 .community-block .community-block-title h1 {
  58 + font-variant: small-caps;
  59 + color: #555753;
  60 + text-align: left;
  61 + padding-left: 10px;
  62 + margin: 0px 0px 2px 0px;
  63 +}
  64 +
  65 +#content .box-1 .community-block .community-block-button {
  66 + border: 1px solid #CCCCCC;
  67 + border-radius: 4px;
  68 + float: right;
  69 + height: 22px;
  70 + line-height: 22px;
  71 + margin-top: 1px;
  72 + margin-right: 1px;
  73 + background-color: #F4F4F4;
  74 + background-position: center center;
  75 + background-repeat: no-repeat;
  76 + cursor: pointer;
  77 +}
  78 +
  79 +#content .box-1 .community-block .community-block-button.icon-add {
  80 + width: 20px;
  81 + background-image: url('/designs/icons/default/Tango/16x16/actions/add.png');
  82 +}
  83 +
  84 +#content .box-1 .community-block .community-block-button.icon-remove {
  85 + width: 20px;
  86 + background-image: url('/designs/icons/default/Tango/16x16/actions/remove.png');
  87 +}
  88 +
  89 +#content .box-1 .community-block .community-block-button.icon-arrow {
  90 + width: 16px;
  91 + background-image: url('/images/top-arrow.png');
  92 +}
  93 +
  94 +#content .box-1 .community-block .community-block-button:hover {
  95 + background-color: #DDDDDD;
  96 +}
  97 +
  98 +
  99 +#content .box-1 .community-block .community-block-description {
  100 + font-style: italic;
  101 + color: black;
  102 + padding: 10px;
  103 +}
  104 +
plugins/community_block/test/functional/commmunity_block_plugin_profile_design_controller_test.rb 0 → 100644
@@ -0,0 +1,87 @@ @@ -0,0 +1,87 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +# Re-raise errors caught by the controller.
  4 +class ProfileController
  5 + append_view_path File.join(File.dirname(__FILE__) + '/../../views')
  6 + def rescue_action(e)
  7 + raise e
  8 + end
  9 +end
  10 +
  11 +class ProfileControllerTest < ActionController::TestCase
  12 +
  13 + def setup
  14 + @controller = ProfileController.new
  15 + @request = ActionController::TestRequest.new
  16 + @response = ActionController::TestResponse.new
  17 +
  18 + @user = create_user('testinguser').person
  19 + login_as(@user.identifier)
  20 +
  21 + @community = fast_create(Community, :environment_id => Environment.default)
  22 + @community.add_member @user
  23 + @community.add_admin @user
  24 +
  25 + @environment = @community.environment
  26 + @environment.enabled_plugins = ['CommunityBlock']
  27 + @environment.save!
  28 +
  29 + CommunityBlock.delete_all
  30 + @box1 = Box.create!(:owner => @community)
  31 + @community.boxes = [@box1]
  32 +
  33 + @block = CommunityBlock.new
  34 + @block.box = @box1
  35 + @block.save!
  36 +
  37 + @community.blocks<<@block
  38 + @community.save!
  39 + end
  40 +
  41 + should 'display community-block' do
  42 + get :index, :profile => @community.identifier
  43 + assert_tag :div, :attributes => {:class => 'community-block-logo'}
  44 + assert_tag :div, :attributes => {:class => 'community-block-info'}
  45 + assert_tag :div, :attributes => {:class => 'community-block-title'}
  46 + assert_tag :div, :attributes => {:class => 'community-block-description'}
  47 + end
  48 +
  49 + should 'display *leave* button when the user is logged in and is a member of the community' do
  50 + get :index, :profile => @community.identifier
  51 + assert_tag :span, :attributes => {:class => 'community-block-button icon-remove'}
  52 + end
  53 +
  54 + should 'display *send email to administrators* button when the user is logged in and is a member of the community' do
  55 + get :index, :profile => @community.identifier
  56 + assert_match /\{&quot;Send an e-mail&quot;:\{&quot;href&quot;:&quot;\/contact\/#{@community.identifier}\/new&quot;\}\}/, @response.body
  57 + end
  58 +
  59 + should 'display *report* button when the user is logged in and is a member of the community' do
  60 + get :index, :profile => @community.identifier
  61 + assert_match /\{&quot;Report abuse&quot;:\{&quot;href&quot;:&quot;\/profile\/#{@community.identifier}\/report_abuse&quot;\}\}/, @response.body
  62 + end
  63 +
  64 + should 'display *join* button when the user is logged in and is not a member of the community' do
  65 + @community.remove_member @user
  66 + get :index, :profile => @community.identifier
  67 + assert_tag :span, :attributes => {:class => 'community-block-button icon-add'}
  68 + end
  69 +
  70 + should 'display *control panel* link option when the user is logged in and is community admin' do
  71 + get :index, :profile => @community.identifier
  72 + assert_match /\{&quot;Control panel&quot;:\{&quot;href&quot;:&quot;\/myprofile\/#{@community.identifier}&quot;\}\}/, @response.body
  73 + end
  74 +
  75 + should 'display *join* button when the user is not logged in' do
  76 + logout
  77 + get :index, :profile => @community.identifier
  78 + assert_tag :span, :attributes => {:class => 'community-block-button icon-add'}
  79 + end
  80 +
  81 + should 'not display *arrow* button when the user is not logged in' do
  82 + logout
  83 + get :index, :profile => @community.identifier
  84 + assert_no_tag :span, :attributes => {:class => 'community-block-button icon-arrow'}
  85 + end
  86 +
  87 +end
plugins/community_block/test/test_helper.rb 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +require File.dirname(__FILE__) + '/../../../test/test_helper'
plugins/community_block/test/unit/commmunity_block_plugin_test.rb 0 → 100644
@@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class CommunityBlockPluginTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @plugin = CommunityBlockPlugin.new
  7 + end
  8 +
  9 + should 'be a noosfero plugin' do
  10 + assert_kind_of Noosfero::Plugin, @plugin
  11 + end
  12 +
  13 + should 'have name' do
  14 + assert_equal 'Community Block Plugin', CommunityBlockPlugin.plugin_name
  15 + end
  16 +
  17 + should 'have description' do
  18 + assert_equal "A plugin that adds a block to show community description", CommunityBlockPlugin.plugin_description
  19 + end
  20 +
  21 + should 'have stylesheet' do
  22 + assert @plugin.stylesheet?
  23 + end
  24 +
  25 + should "return CommunityBlock in extra_blocks class method" do
  26 + assert CommunityBlockPlugin.extra_blocks.keys.include?(CommunityBlock)
  27 + end
  28 +
  29 + should "return false for class method has_admin_url?" do
  30 + assert !CommunityBlockPlugin.has_admin_url?
  31 + end
  32 +
  33 +end
plugins/community_block/test/unit/commmunity_block_test.rb 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class CommunityBlockTest < ActiveSupport::TestCase
  4 +
  5 + should "display community block" do
  6 + block = CommunityBlock.new
  7 + self.expects(:render).with(:file => 'community_block', :locals => { :block => block })
  8 + instance_eval(& block.content)
  9 + end
  10 +
  11 +end
plugins/community_block/views/community_block.rhtml 0 → 100644
@@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
  1 +<div class="community-block">
  2 + <div class="community-block-logo">
  3 + <%= link_to profile_image(profile, :big), profile.url %>
  4 + </div>
  5 + <div class="community-block-info">
  6 + <div class="community-block-title">
  7 +
  8 + <%
  9 + links = []
  10 +
  11 + if logged_in?
  12 +
  13 + if profile.enable_contact?
  14 + links.push(_('Send an e-mail') => {:href => url_for({:controller => 'contact', :action => 'new', :profile => profile.identifier})})
  15 + end
  16 +
  17 + links.push(_('Report abuse') => {:href => url_for({:controller => 'profile', :action => 'report_abuse', :profile => profile.identifier})})
  18 +
  19 + if !user.nil? && user.has_permission?('edit_profile', profile)
  20 + links.push(_('Control panel') => {:href => url_for({:controller => 'profile_editor', :profile => profile.identifier})})
  21 + end %>
  22 +
  23 + <%= link_to(
  24 + content_tag('span','',:class => 'community-block-button icon-arrow'),
  25 + '#',
  26 + :onclick => "toggleSubmenu(this,'',#{links.to_json}); return false;",
  27 + :class => 'simplemenu-trigger') %>
  28 +
  29 + <% end %>
  30 +
  31 + <% if logged_in? %>
  32 + <% if profile.members.include?(user) || profile.already_request_membership?(user) %>
  33 + <%= link_to(
  34 + content_tag('span', '', :class => 'community-block-button icon-remove'),
  35 + profile.leave_url) %>
  36 + <% else %>
  37 + <%= link_to(
  38 + content_tag('span', '', :class => 'community-block-button icon-add'),
  39 + profile.join_url) %>
  40 + <% end %>
  41 + <% else %>
  42 + <%= link_to(
  43 + content_tag('span', '', :class => 'community-block-button icon-add'),
  44 + profile.join_not_logged_url) %>
  45 + <% end %>
  46 +
  47 + <h1><%=profile.name%></h1>
  48 + </div>
  49 + <div class="community-block-description"><%= profile.description %></div>
  50 + </div>
  51 + <div style="clear:both"></div>
  52 +</div>
plugins/pg_search/lib/pg_search_plugin.rb
@@ -10,7 +10,7 @@ class PgSearchPlugin &lt; Noosfero::Plugin @@ -10,7 +10,7 @@ class PgSearchPlugin &lt; Noosfero::Plugin
10 10
11 def find_by_contents(asset, scope, query, paginate_options={}, options={}) 11 def find_by_contents(asset, scope, query, paginate_options={}, options={})
12 scope = scope.pg_search_plugin_search(query) unless query.blank? 12 scope = scope.pg_search_plugin_search(query) unless query.blank?
13 - scope = scope.send(options[:filter]) unless options[:filter] 13 + scope = scope.send(options[:filter]) if options[:filter]
14 {:results => scope.paginate(paginate_options)} 14 {:results => scope.paginate(paginate_options)}
15 end 15 end
16 16
plugins/pg_search/test/unit/pg_search_plugin_test.rb
@@ -31,6 +31,11 @@ class PgSearchPluginTest &lt; ActiveSupport::TestCase @@ -31,6 +31,11 @@ class PgSearchPluginTest &lt; ActiveSupport::TestCase
31 # assert_includes search(Profile, 'colmeia'), profile 31 # assert_includes search(Profile, 'colmeia'), profile
32 # end 32 # end
33 33
  34 + should 'check if filter option is defined' do
  35 + plugin = PgSearchPlugin.new
  36 + assert plugin.find_by_contents('asset', Profile, 'query', {:page => 1})
  37 + end
  38 +
34 private 39 private
35 40
36 def search(scope, query) 41 def search(scope, query)
test/functional/profile_design_controller_test.rb
@@ -300,6 +300,27 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase @@ -300,6 +300,27 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase
300 assert !@controller.instance_variable_get('@side_block_types').include?(CustomBlock8) 300 assert !@controller.instance_variable_get('@side_block_types').include?(CustomBlock8)
301 end 301 end
302 302
  303 + should 'not edit main block with never option' do
  304 + get :edit, :profile => 'designtestuser', :id => @b4.id
  305 + assert_no_tag :input, :attributes => { :type => 'radio', :value => 'never'}
  306 + end
  307 +
  308 + should 'not edit main block with home_page_only option' do
  309 + get :edit, :profile => 'designtestuser', :id => @b4.id
  310 + assert_no_tag :input, :attributes => { :type => 'radio', :value => 'home_page_only'}
  311 + end
  312 +
  313 + should 'edit main block with always option' do
  314 + get :edit, :profile => 'designtestuser', :id => @b4.id
  315 + assert_tag :input, :attributes => { :type => 'radio', :value => 'always'}
  316 + end
  317 +
  318 + should 'edit main block with except_home_page option' do
  319 + get :edit, :profile => 'designtestuser', :id => @b4.id
  320 + assert_tag :input, :attributes => { :type => 'radio', :value => 'except_home_page'}
  321 + end
  322 +
  323 +
303 ###################################################### 324 ######################################################
304 # END - tests for BoxOrganizerController features 325 # END - tests for BoxOrganizerController features
305 ###################################################### 326 ######################################################
test/unit/main_block_test.rb
@@ -11,8 +11,22 @@ class MainBlockTest &lt; ActiveSupport::TestCase @@ -11,8 +11,22 @@ class MainBlockTest &lt; ActiveSupport::TestCase
11 ok("MainBlock must not have a content") { MainBlock.new.content.blank? } 11 ok("MainBlock must not have a content") { MainBlock.new.content.blank? }
12 end 12 end
13 13
14 - should 'not be editable' do  
15 - assert !MainBlock.new.editable? 14 + should 'be editable' do
  15 + assert MainBlock.new.editable?
  16 + end
  17 +
  18 + should 'be visible on environment' do
  19 + env = Environment.new
  20 + block = MainBlock.new
  21 + block.stubs(:owner).returns(env)
  22 + assert block.visible?
  23 + end
  24 +
  25 + should 'not be visible on environment' do
  26 + env = Environment.new
  27 + block = MainBlock.new(:display => 'never')
  28 + block.stubs(:owner).returns(env)
  29 + assert !block.visible?
16 end 30 end
17 31
18 end 32 end