Commit d0561132a9af7bcd87550258ef5e4358b6c0ea0c
Exists in
master
and in
29 other branches
Merge branch 'stable'
Conflicts: app/controllers/my_profile/profile_themes_controller.rb test/unit/comment_test.rb vendor/plugins/action_tracker_has_comments/init.rb
Showing
34 changed files
with
280 additions
and
154 deletions
Show diff stats
app/controllers/admin/users_controller.rb
@@ -7,7 +7,7 @@ class UsersController < AdminController | @@ -7,7 +7,7 @@ class UsersController < AdminController | ||
7 | include UsersHelper | 7 | include UsersHelper |
8 | 8 | ||
9 | def index | 9 | def index |
10 | - @filter = params[:filter] | 10 | + @filter = params[:filter] || 'all_users' |
11 | scope = environment.people.no_templates | 11 | scope = environment.people.no_templates |
12 | if @filter == 'admin_users' | 12 | if @filter == 'admin_users' |
13 | scope = scope.admins | 13 | scope = scope.admins |
@@ -16,6 +16,7 @@ class UsersController < AdminController | @@ -16,6 +16,7 @@ class UsersController < AdminController | ||
16 | elsif @filter == 'deactivated_users' | 16 | elsif @filter == 'deactivated_users' |
17 | scope = scope.deactivated | 17 | scope = scope.deactivated |
18 | end | 18 | end |
19 | + scope = scope.order('name ASC') | ||
19 | @q = params[:q] | 20 | @q = params[:q] |
20 | @collection = find_by_contents(:people, scope, @q, {:per_page => per_page, :page => params[:npage]})[:results] | 21 | @collection = find_by_contents(:people, scope, @q, {:per_page => per_page, :page => params[:npage]})[:results] |
21 | end | 22 | end |
app/controllers/application_controller.rb
@@ -21,6 +21,7 @@ class ApplicationController < ActionController::Base | @@ -21,6 +21,7 @@ class ApplicationController < ActionController::Base | ||
21 | include ApplicationHelper | 21 | include ApplicationHelper |
22 | layout :get_layout | 22 | layout :get_layout |
23 | def get_layout | 23 | def get_layout |
24 | + return nil if request.format == :js | ||
24 | theme_layout = theme_option(:layout) | 25 | theme_layout = theme_option(:layout) |
25 | if theme_layout | 26 | if theme_layout |
26 | theme_view_file('layouts/'+theme_layout) || theme_layout | 27 | theme_view_file('layouts/'+theme_layout) || theme_layout |
app/controllers/box_organizer_controller.rb
@@ -70,7 +70,7 @@ class BoxOrganizerController < ApplicationController | @@ -70,7 +70,7 @@ class BoxOrganizerController < ApplicationController | ||
70 | else | 70 | else |
71 | @center_block_types = (Box.acceptable_center_blocks & available_blocks) + plugins.dispatch(:extra_blocks, :type => boxes_holder.class, :position => 1) | 71 | @center_block_types = (Box.acceptable_center_blocks & available_blocks) + plugins.dispatch(:extra_blocks, :type => boxes_holder.class, :position => 1) |
72 | @side_block_types = (Box.acceptable_side_blocks & available_blocks) + plugins.dispatch(:extra_blocks, :type => boxes_holder.class, :position => [2,3]) | 72 | @side_block_types = (Box.acceptable_side_blocks & available_blocks) + plugins.dispatch(:extra_blocks, :type => boxes_holder.class, :position => [2,3]) |
73 | - @boxes = boxes_holder.boxes | 73 | + @boxes = boxes_holder.boxes.with_position |
74 | render :action => 'add_block', :layout => false | 74 | render :action => 'add_block', :layout => false |
75 | end | 75 | end |
76 | end | 76 | end |
app/helpers/boxes_helper.rb
@@ -39,7 +39,7 @@ module BoxesHelper | @@ -39,7 +39,7 @@ module BoxesHelper | ||
39 | end | 39 | end |
40 | 40 | ||
41 | def display_boxes(holder, main_content) | 41 | def display_boxes(holder, main_content) |
42 | - boxes = holder.boxes.first(holder.boxes_limit) | 42 | + boxes = holder.boxes.with_position.first(holder.boxes_limit) |
43 | content = boxes.reverse.map { |item| display_box(item, main_content) }.join("\n") | 43 | content = boxes.reverse.map { |item| display_box(item, main_content) }.join("\n") |
44 | content = main_content if (content.blank?) | 44 | content = main_content if (content.blank?) |
45 | 45 |
app/models/box.rb
@@ -5,6 +5,8 @@ class Box < ActiveRecord::Base | @@ -5,6 +5,8 @@ class Box < ActiveRecord::Base | ||
5 | 5 | ||
6 | include Noosfero::Plugin::HotSpot | 6 | include Noosfero::Plugin::HotSpot |
7 | 7 | ||
8 | + named_scope :with_position, :conditions => ['boxes.position > 0'] | ||
9 | + | ||
8 | def environment | 10 | def environment |
9 | owner ? (owner.kind_of?(Environment) ? owner : owner.environment) : nil | 11 | owner ? (owner.kind_of?(Environment) ? owner : owner.environment) : nil |
10 | end | 12 | end |
app/models/environment.rb
@@ -186,7 +186,7 @@ class Environment < ActiveRecord::Base | @@ -186,7 +186,7 @@ class Environment < ActiveRecord::Base | ||
186 | has_many :product_categories, :conditions => { :type => 'ProductCategory'} | 186 | has_many :product_categories, :conditions => { :type => 'ProductCategory'} |
187 | has_many :regions | 187 | has_many :regions |
188 | 188 | ||
189 | - has_many :roles | 189 | + has_many :roles, :dependent => :destroy |
190 | 190 | ||
191 | has_many :qualifiers | 191 | has_many :qualifiers |
192 | has_many :certifiers | 192 | has_many :certifiers |
app/views/blocks/location.html.erb
@@ -3,7 +3,6 @@ | @@ -3,7 +3,6 @@ | ||
3 | <div class='the-localization-map'> | 3 | <div class='the-localization-map'> |
4 | <img src="https://maps.google.com/maps/api/staticmap?center=<%=profile.lat%>,<%=profile.lng%>&zoom=<%=block.zoom%>&size=190x250&maptype=<%=block.map_type%>&markers=<%=profile.lat%>,<%=profile.lng%>&sensor=false"/> | 4 | <img src="https://maps.google.com/maps/api/staticmap?center=<%=profile.lat%>,<%=profile.lng%>&zoom=<%=block.zoom%>&size=190x250&maptype=<%=block.map_type%>&markers=<%=profile.lat%>,<%=profile.lng%>&sensor=false"/> |
5 | </div> | 5 | </div> |
6 | -</div> | ||
7 | <% else %> | 6 | <% else %> |
8 | <i><%= _('This profile has no geographical position registered.') %></i> | 7 | <i><%= _('This profile has no geographical position registered.') %></i> |
9 | <% end %> | 8 | <% end %> |
debian/changelog
1 | +noosfero (0.46.1) unstable; urgency=low | ||
2 | + | ||
3 | + * Bugfixes release | ||
4 | + | ||
5 | + -- Daniela Soares Feitosa <daniela@colivre.coop.br> Fri, 07 Mar 2014 10:33:11 +0000 | ||
6 | + | ||
1 | noosfero (0.46.0) unstable; urgency=low | 7 | noosfero (0.46.0) unstable; urgency=low |
2 | 8 | ||
3 | * New features release | 9 | * New features release |
lib/noosfero.rb
@@ -3,7 +3,7 @@ require 'fast_gettext' | @@ -3,7 +3,7 @@ require 'fast_gettext' | ||
3 | 3 | ||
4 | module Noosfero | 4 | module Noosfero |
5 | PROJECT = 'noosfero' | 5 | PROJECT = 'noosfero' |
6 | - VERSION = '0.46.0' | 6 | + VERSION = '0.46.1' |
7 | 7 | ||
8 | def self.pattern_for_controllers_in_directory(dir) | 8 | def self.pattern_for_controllers_in_directory(dir) |
9 | disjunction = controllers_in_directory(dir).join('|') | 9 | disjunction = controllers_in_directory(dir).join('|') |
lib/noosfero/core_ext.rb
1 | require 'noosfero/core_ext/string' | 1 | require 'noosfero/core_ext/string' |
2 | require 'noosfero/core_ext/integer' | 2 | require 'noosfero/core_ext/integer' |
3 | +require 'noosfero/core_ext/array' | ||
3 | require 'noosfero/core_ext/object' | 4 | require 'noosfero/core_ext/object' |
4 | require 'noosfero/core_ext/active_record' | 5 | require 'noosfero/core_ext/active_record' |
lib/noosfero/plugin/routes.rb
@@ -15,12 +15,16 @@ Dir.glob(File.join(Rails.root, plugins_root, '*', 'controllers')) do |controller | @@ -15,12 +15,16 @@ Dir.glob(File.join(Rails.root, plugins_root, '*', 'controllers')) do |controller | ||
15 | controllers_by_folder.each do |folder, controllers| | 15 | controllers_by_folder.each do |folder, controllers| |
16 | controllers.each do |controller| | 16 | controllers.each do |controller| |
17 | controller_name = controller.gsub("#{plugin_name}_plugin_",'') | 17 | controller_name = controller.gsub("#{plugin_name}_plugin_",'') |
18 | - map.connect "#{prefixes_by_folder[folder]}/#{plugin_name}/#{controller_name}/:action/:id", :controller => controller | 18 | + if %w[profile myprofile].include?(folder) |
19 | + map.connect "#{prefixes_by_folder[folder]}/#{plugin_name}/#{controller_name}/:action/:id", :controller => controller, :profile => /#{Noosfero.identifier_format}/ | ||
20 | + else | ||
21 | + map.connect "#{prefixes_by_folder[folder]}/#{plugin_name}/#{controller_name}/:action/:id", :controller => controller | ||
22 | + end | ||
19 | end | 23 | end |
20 | end | 24 | end |
21 | 25 | ||
22 | map.connect 'plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin' | 26 | map.connect 'plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin' |
23 | - map.connect 'profile/:profile/plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_profile' | ||
24 | - map.connect 'myprofile/:profile/plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_myprofile' | 27 | + map.connect 'profile/:profile/plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_profile', :profile => /#{Noosfero.identifier_format}/ |
28 | + map.connect 'myprofile/:profile/plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_myprofile', :profile => /#{Noosfero.identifier_format}/ | ||
25 | map.connect 'admin/plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_admin' | 29 | map.connect 'admin/plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_admin' |
26 | end | 30 | end |
plugins/container_block/lib/container_block_plugin.rb
plugins/container_block/lib/container_block_plugin/container_block.rb
@@ -7,6 +7,16 @@ class ContainerBlockPlugin::ContainerBlock < Block | @@ -7,6 +7,16 @@ class ContainerBlockPlugin::ContainerBlock < Block | ||
7 | settings_items :container_box_id, :type => Integer, :default => nil | 7 | settings_items :container_box_id, :type => Integer, :default => nil |
8 | settings_items :children_settings, :type => Hash, :default => {} | 8 | settings_items :children_settings, :type => Hash, :default => {} |
9 | 9 | ||
10 | + validate :no_cyclical_reference, :if => 'container_box_id.present?' | ||
11 | + | ||
12 | + def no_cyclical_reference | ||
13 | + errors.add(:box_id, _('cyclical reference is not allowed.')) if box_id == container_box_id | ||
14 | + end | ||
15 | + | ||
16 | + before_save do |b| | ||
17 | + raise "cyclical reference is not allowed" if b.box_id == b.container_box_id && !b.container_box_id.blank? | ||
18 | + end | ||
19 | + | ||
10 | def self.description | 20 | def self.description |
11 | _('Container') | 21 | _('Container') |
12 | end | 22 | end |
@@ -15,6 +25,10 @@ class ContainerBlockPlugin::ContainerBlock < Block | @@ -15,6 +25,10 @@ class ContainerBlockPlugin::ContainerBlock < Block | ||
15 | _('This block acts as a container for another blocks') | 25 | _('This block acts as a container for another blocks') |
16 | end | 26 | end |
17 | 27 | ||
28 | + def cacheable? | ||
29 | + false | ||
30 | + end | ||
31 | + | ||
18 | def layout_template | 32 | def layout_template |
19 | nil | 33 | nil |
20 | end | 34 | end |
@@ -24,8 +38,9 @@ class ContainerBlockPlugin::ContainerBlock < Block | @@ -24,8 +38,9 @@ class ContainerBlockPlugin::ContainerBlock < Block | ||
24 | end | 38 | end |
25 | 39 | ||
26 | def create_box | 40 | def create_box |
27 | - box = Box.create!(:owner => owner) | ||
28 | - settings[:container_box_id] = box.id | 41 | + container_box = Box.create!(:owner => owner) |
42 | + container_box.update_attribute(:position, nil) | ||
43 | + settings[:container_box_id] = container_box.id | ||
29 | save! | 44 | save! |
30 | end | 45 | end |
31 | 46 |
@@ -0,0 +1,28 @@ | @@ -0,0 +1,28 @@ | ||
1 | +function enableMoveContainerChildren(container, box) { | ||
2 | + var div = jQuery('#box-'+box+' > .block-outer > .block'); | ||
3 | + if(!div.is('.ui-resizable')) { | ||
4 | + div.resizable({ | ||
5 | + handles: 'e, w', | ||
6 | + containment: '#block-'+container+' .block-inner-2', | ||
7 | + resize: function( event, ui ) { | ||
8 | + ui.element.height('auto'); | ||
9 | + } | ||
10 | + }); | ||
11 | + } | ||
12 | +} | ||
13 | + | ||
14 | +function disableMoveContainerChildren(container, box) { | ||
15 | + var div = jQuery('#box-'+box+' > .block-outer > .block'); | ||
16 | + if(div.is('.ui-resizable')) { | ||
17 | + div.resizable('destroy'); | ||
18 | + } | ||
19 | +} | ||
20 | + | ||
21 | +function containerChildrenWidth(container, box) { | ||
22 | + widths = ""; | ||
23 | + jQuery('#box-'+box+' > .block-outer > .block').each(function(i) { | ||
24 | + childId = jQuery(this).attr('id').match(/block-(\d+)/)[1]; | ||
25 | + widths+=childId+","+jQuery(this).width()+"|"; | ||
26 | + }); | ||
27 | + return "widths="+widths; | ||
28 | +} |
plugins/container_block/public/style.css
1 | +#box-organizer .container-block-plugin_container-block > .block-inner-1 > .block-inner-2 > .button-bar { | ||
2 | + height: 22px; | ||
3 | + padding-bottom: 0px; | ||
4 | + width: auto; | ||
5 | +} | ||
6 | + | ||
1 | #content .boxes .container-block-plugin_container-block .container_block_child, .container-block-plugin_container-block .block-outer { | 7 | #content .boxes .container-block-plugin_container-block .container_block_child, .container-block-plugin_container-block .block-outer { |
2 | display: inline-block; | 8 | display: inline-block; |
3 | vertical-align: top; | 9 | vertical-align: top; |
@@ -17,14 +23,10 @@ | @@ -17,14 +23,10 @@ | ||
17 | background-image: url(/designs/icons/default/Tango/16x16/actions/go-previous.png); | 23 | background-image: url(/designs/icons/default/Tango/16x16/actions/go-previous.png); |
18 | } | 24 | } |
19 | 25 | ||
20 | -#content .boxes .container-block-plugin_container-block .block { | ||
21 | - outline-offset: -2px; | ||
22 | -} | ||
23 | - | ||
24 | #content .boxes .container-block-plugin_container-block .block .ui-resizable-handle { | 26 | #content .boxes .container-block-plugin_container-block .block .ui-resizable-handle { |
25 | width: 10px; | 27 | width: 10px; |
26 | height: 28px; | 28 | height: 28px; |
27 | - z-index: 0; | 29 | + z-index: 1000; |
28 | } | 30 | } |
29 | 31 | ||
30 | #content .boxes .container-block-plugin_container-block .block .ui-resizable-e { | 32 | #content .boxes .container-block-plugin_container-block .block .ui-resizable-e { |
@@ -37,6 +39,21 @@ | @@ -37,6 +39,21 @@ | ||
37 | background-image: url(/plugins/container_block/images/handle_w.png); | 39 | background-image: url(/plugins/container_block/images/handle_w.png); |
38 | } | 40 | } |
39 | 41 | ||
40 | -.container-block-plugin_container-block .button-bar .icon-resize { | 42 | +.container-block-plugin_container-block .container-block-button-bar .icon-resize { |
41 | background-image: url(/designs/icons/default/Tango/16x16/actions/view-fullscreen.png); | 43 | background-image: url(/designs/icons/default/Tango/16x16/actions/view-fullscreen.png); |
42 | } | 44 | } |
45 | + | ||
46 | +#box-organizer .block .container-block-button-bar { | ||
47 | + right: 0px; | ||
48 | + bottom: 0px; | ||
49 | + height: auto; | ||
50 | +} | ||
51 | + | ||
52 | +#box-organizer .container-block-plugin_container-block:hover .block { | ||
53 | + outline: 1px dashed black; | ||
54 | + outline-offset: -1px; | ||
55 | +} | ||
56 | + | ||
57 | +.container-block-plugin_container-block .block-target { | ||
58 | + background: #afd; | ||
59 | +} |
plugins/container_block/test/functional/container_block_home_controller_test.rb
@@ -31,6 +31,13 @@ class HomeControllerTest < ActionController::TestCase | @@ -31,6 +31,13 @@ class HomeControllerTest < ActionController::TestCase | ||
31 | assert_tag :div, :attributes => { :class => 'block container-block-plugin_container-block' } | 31 | assert_tag :div, :attributes => { :class => 'block container-block-plugin_container-block' } |
32 | end | 32 | end |
33 | 33 | ||
34 | + should 'display block title' do | ||
35 | + @block.title = "Block Title" | ||
36 | + @block.save! | ||
37 | + get :index | ||
38 | + assert_tag :div, :attributes => { :class => 'block container-block-plugin_container-block' }, :descendant => {:tag => 'h3', :attributes => { :class => "block-title"}, :content => @block.title } | ||
39 | + end | ||
40 | + | ||
34 | should 'display container children' do | 41 | should 'display container children' do |
35 | c1 = RawHTMLBlock.create!(:box => @block.container_box, :html => 'child1 content') | 42 | c1 = RawHTMLBlock.create!(:box => @block.container_box, :html => 'child1 content') |
36 | c2 = RawHTMLBlock.create!(:box => @block.container_box, :html => 'child2 content') | 43 | c2 = RawHTMLBlock.create!(:box => @block.container_box, :html => 'child2 content') |
plugins/container_block/test/unit/block_test.rb
@@ -1,31 +0,0 @@ | @@ -1,31 +0,0 @@ | ||
1 | -require 'test_helper' | ||
2 | - | ||
3 | -class BlockTest < ActiveSupport::TestCase | ||
4 | - | ||
5 | - def setup | ||
6 | - @environment = fast_create(Environment) | ||
7 | - @box = Box.create!(:owner => @environment) | ||
8 | - @container = ContainerBlockPlugin::ContainerBlock.create!(:box => @box) | ||
9 | - end | ||
10 | - | ||
11 | - should 'return environment box if block owner is not a ContainerBlock' do | ||
12 | - block = Block.create!(:box => @box) | ||
13 | - assert_equal @box, block.box | ||
14 | - end | ||
15 | - | ||
16 | - should 'return container box if block owner is a ContainerBlock' do | ||
17 | - block = Block.create!(:box => @container.container_box) | ||
18 | - assert_equal @container.container_box, block.box | ||
19 | - end | ||
20 | - | ||
21 | - should 'return block owner if block onwer is not a ContainerBlock' do | ||
22 | - block = Block.create!(:box => @box) | ||
23 | - assert_equal @environment, block.owner | ||
24 | - end | ||
25 | - | ||
26 | - should 'return environment as owner if block onwer is a ContainerBlock' do | ||
27 | - block = Block.create!(:box => @container.container_box) | ||
28 | - assert_equal @environment, block.owner | ||
29 | - end | ||
30 | - | ||
31 | -end |
plugins/container_block/test/unit/container_block_plugin/container_block_test.rb
@@ -20,6 +20,11 @@ class ContainerBlockPlugin::ContainerBlockTest < ActiveSupport::TestCase | @@ -20,6 +20,11 @@ class ContainerBlockPlugin::ContainerBlockTest < ActiveSupport::TestCase | ||
20 | assert @block.container_box_id | 20 | assert @block.container_box_id |
21 | end | 21 | end |
22 | 22 | ||
23 | + should 'created box should have nil as position' do | ||
24 | + @block.save! | ||
25 | + assert_equal nil, @block.container_box.position | ||
26 | + end | ||
27 | + | ||
23 | should 'return created box' do | 28 | should 'return created box' do |
24 | @block.save! | 29 | @block.save! |
25 | assert @block.container_box | 30 | assert @block.container_box |
@@ -89,4 +94,27 @@ class ContainerBlockPlugin::ContainerBlockTest < ActiveSupport::TestCase | @@ -89,4 +94,27 @@ class ContainerBlockPlugin::ContainerBlockTest < ActiveSupport::TestCase | ||
89 | end | 94 | end |
90 | end | 95 | end |
91 | 96 | ||
97 | + should 'not mess up with boxes positions when destroyed' do | ||
98 | + env = fast_create(Environment) | ||
99 | + box1 = fast_create(Box, :owner_id => env.id, :owner_type => 'Environment', :position => 1) | ||
100 | + box2 = fast_create(Box, :owner_id => env.id, :owner_type => 'Environment', :position => 2) | ||
101 | + box3 = fast_create(Box, :owner_id => env.id, :owner_type => 'Environment', :position => 3) | ||
102 | + block = ContainerBlockPlugin::ContainerBlock.create!(:box => box1) | ||
103 | + block.destroy | ||
104 | + assert_equal [1, 2, 3], [box1.reload.position, box2.reload.position, box3.reload.position] | ||
105 | + end | ||
106 | + | ||
107 | + should 'be able to change box' do | ||
108 | + @block.save! | ||
109 | + @block.box = Box.new(:owner => Environment.default) | ||
110 | + @block.save! | ||
111 | + end | ||
112 | + | ||
113 | + should 'not able to change box to be the same as container_box' do | ||
114 | + @block.save! | ||
115 | + @block.box = @block.container_box | ||
116 | + @block.save | ||
117 | + assert @block.errors.invalid?(:box_id) | ||
118 | + end | ||
119 | + | ||
92 | end | 120 | end |
plugins/container_block/test/unit/environment_test.rb
@@ -1,32 +0,0 @@ | @@ -1,32 +0,0 @@ | ||
1 | -require 'test_helper' | ||
2 | - | ||
3 | -class EnvironmentTest < ActiveSupport::TestCase | ||
4 | - | ||
5 | - def setup | ||
6 | - @environment = fast_create(Environment) | ||
7 | - | ||
8 | - @box = Box.create!(:owner => @environment) | ||
9 | - @block = Block.create!(:box => @box) | ||
10 | - | ||
11 | - @container = ContainerBlockPlugin::ContainerBlock.create!(:box => @box) | ||
12 | - end | ||
13 | - | ||
14 | - should 'return blocks as usual' do | ||
15 | - assert_equal [@block, @container], @environment.blocks | ||
16 | - end | ||
17 | - | ||
18 | - should 'return blocks with container children' do | ||
19 | - child = Block.create!(:box => @container.container_box) | ||
20 | - assert_equal [@block, @container, child], @environment.blocks | ||
21 | - end | ||
22 | - | ||
23 | - should 'return block with id at find method' do | ||
24 | - assert_equal @block, @environment.blocks.find(@block.id) | ||
25 | - end | ||
26 | - | ||
27 | - should 'return child block with id at find method' do | ||
28 | - child = Block.create!(:box => @container.container_box) | ||
29 | - assert_equal child, @environment.blocks.find(child.id) | ||
30 | - end | ||
31 | - | ||
32 | -end |
plugins/container_block/test/unit/profile_test.rb
@@ -1,32 +0,0 @@ | @@ -1,32 +0,0 @@ | ||
1 | -require 'test_helper' | ||
2 | - | ||
3 | -class ProfileTest < ActiveSupport::TestCase | ||
4 | - | ||
5 | - def setup | ||
6 | - @profile = fast_create(Profile) | ||
7 | - | ||
8 | - @box = Box.create!(:owner => @profile) | ||
9 | - @block = Block.create!(:box => @box) | ||
10 | - | ||
11 | - @container = ContainerBlockPlugin::ContainerBlock.create!(:box => @box) | ||
12 | - end | ||
13 | - | ||
14 | - should 'return blocks as usual' do | ||
15 | - assert_equal [@block, @container], @profile.blocks | ||
16 | - end | ||
17 | - | ||
18 | - should 'return blocks with container children' do | ||
19 | - child = Block.create!(:box => @container.container_box) | ||
20 | - assert_equal [@block, @container, child], @profile.blocks | ||
21 | - end | ||
22 | - | ||
23 | - should 'return block with id at find method' do | ||
24 | - assert_equal @block, @profile.blocks.find(@block.id) | ||
25 | - end | ||
26 | - | ||
27 | - should 'return child block with id at find method' do | ||
28 | - child = Block.create!(:box => @container.container_box) | ||
29 | - assert_equal child, @profile.blocks.find(child.id) | ||
30 | - end | ||
31 | - | ||
32 | -end |
plugins/container_block/views/blocks/container.rhtml
1 | <% edit_mode = @controller.send(:boxes_editor?) && @controller.send(:uses_design_blocks?) %> | 1 | <% edit_mode = @controller.send(:boxes_editor?) && @controller.send(:uses_design_blocks?) %> |
2 | <% box_decorator = edit_mode ? self : BoxesHelper::DontMoveBlocks %> | 2 | <% box_decorator = edit_mode ? self : BoxesHelper::DontMoveBlocks %> |
3 | 3 | ||
4 | +<%= block_title(block.title) %> | ||
4 | 5 | ||
5 | <div class="box" id="box-<%= block.container_box.id %>"> | 6 | <div class="box" id="box-<%= block.container_box.id %>"> |
6 | <%= display_box_content(block.container_box, nil) %> | 7 | <%= display_box_content(block.container_box, nil) %> |
@@ -15,8 +16,18 @@ | @@ -15,8 +16,18 @@ | ||
15 | </style> | 16 | </style> |
16 | 17 | ||
17 | <% if edit_mode %> | 18 | <% if edit_mode %> |
18 | - <div class="button-bar"> | ||
19 | - <a href="#" onclick="toggleMoveContainerChildren(<%= block.id %>, <%= block.container_box.id %>); return false;" class="button icon-resize" title=<%= _('Resize blocks').to_json %>></a> | 19 | + |
20 | + <script> | ||
21 | + jQuery("#block-<%= block.id %>").hover( | ||
22 | + function() { | ||
23 | + enableMoveContainerChildren(<%= block.id %>, <%= block.container_box.id %>); | ||
24 | + }, function() { | ||
25 | + disableMoveContainerChildren(<%= block.id %>, <%= block.container_box.id %>); | ||
26 | + } | ||
27 | + ); | ||
28 | + </script> | ||
29 | + | ||
30 | + <div class="container-block-button-bar button-bar"> | ||
20 | <%= link_to_remote '', :url => { :controller => @controller.boxes_holder.kind_of?(Environment) ? 'container_block_plugin_admin' : 'container_block_plugin_myprofile', :action => 'saveWidths', :id => block.id }, | 31 | <%= link_to_remote '', :url => { :controller => @controller.boxes_holder.kind_of?(Environment) ? 'container_block_plugin_admin' : 'container_block_plugin_myprofile', :action => 'saveWidths', :id => block.id }, |
21 | :with => "containerChildrenWidth(#{block.id}, #{block.container_box.id})", | 32 | :with => "containerChildrenWidth(#{block.id}, #{block.container_box.id})", |
22 | :html => {:class => "button icon-save container_block_save", :id => "container_block_save_#{block.id}", :title => _('Save') }, | 33 | :html => {:class => "button icon-save container_block_save", :id => "container_block_save_#{block.id}", :title => _('Save') }, |
@@ -24,37 +35,4 @@ | @@ -24,37 +35,4 @@ | ||
24 | :loaded => "close_loading();", | 35 | :loaded => "close_loading();", |
25 | :complete => "display_notice(request.responseText);"%> | 36 | :complete => "display_notice(request.responseText);"%> |
26 | </div> | 37 | </div> |
27 | - | ||
28 | - <script> | ||
29 | - function toggleMoveContainerChildren(container, box) { | ||
30 | - var div = jQuery('#box-'+box+' > .block-outer > .block'); | ||
31 | - var targetDiv = jQuery('#box-'+box+' .block-outer .block-target'); | ||
32 | - if(div.is('.ui-resizable')) { | ||
33 | - targetDiv.show(); | ||
34 | - div.find("a").die("click"); | ||
35 | - div.resizable('destroy'); | ||
36 | - } else { | ||
37 | - targetDiv.hide(); | ||
38 | - div.find("a").live("click", function(e) { | ||
39 | - e.preventDefault(); | ||
40 | - }); | ||
41 | - div.resizable({ | ||
42 | - handles: 'e, w', | ||
43 | - containment: '#block-'+container+' .block-inner-2', | ||
44 | - resize: function( event, ui ) { | ||
45 | - ui.element.height('auto'); | ||
46 | - } | ||
47 | - }); | ||
48 | - } | ||
49 | - } | ||
50 | - | ||
51 | - function containerChildrenWidth(container, box) { | ||
52 | - widths = ""; | ||
53 | - jQuery('#box-'+box+' > .block-outer > .block').each(function(i) { | ||
54 | - childId = jQuery(this).attr('id').match(/block-(\d+)/)[1]; | ||
55 | - widths+=childId+","+jQuery(this).width()+"|"; | ||
56 | - }); | ||
57 | - return "widths="+widths; | ||
58 | - } | ||
59 | - </script> | ||
60 | <% end %> | 38 | <% end %> |
plugins/require_auth_to_comment/public/hide_comment_form.js
1 | (function($) { | 1 | (function($) { |
2 | $(window).bind('userDataLoaded', function(event, data) { | 2 | $(window).bind('userDataLoaded', function(event, data) { |
3 | - if (data.login || $('meta[name=profile.allow_unauthenticated_comments]').length > 0) { | 3 | + if (data.login || $('meta[name="profile.allow_unauthenticated_comments"]').length > 0) { |
4 | $('.post-comment-button').livequery(function() { | 4 | $('.post-comment-button').livequery(function() { |
5 | $(this).show(); | 5 | $(this).show(); |
6 | }); | 6 | }); |
@@ -8,7 +8,7 @@ | @@ -8,7 +8,7 @@ | ||
8 | $(this).show(); | 8 | $(this).show(); |
9 | }); | 9 | }); |
10 | $('.comment-footer').livequery(function() { | 10 | $('.comment-footer').livequery(function() { |
11 | - $(this).show(); | 11 | + $(this).show(); |
12 | }); | 12 | }); |
13 | } | 13 | } |
14 | }); | 14 | }); |
public/stylesheets/application.css
1 | +/* browser fixes */ | ||
2 | + | ||
3 | +img:-moz-broken { | ||
4 | + -moz-force-broken-image-icon:1; | ||
5 | +} | ||
6 | + | ||
7 | +/* general styles */ | ||
8 | + | ||
1 | body { | 9 | body { |
2 | padding: 0px; | 10 | padding: 0px; |
3 | margin: 0px; | 11 | margin: 0px; |
@@ -1727,8 +1735,8 @@ a.button.disabled, input.disabled { | @@ -1727,8 +1735,8 @@ a.button.disabled, input.disabled { | ||
1727 | display: none; | 1735 | display: none; |
1728 | } | 1736 | } |
1729 | 1737 | ||
1730 | -#box-organizer .block:focus .button-bar, | ||
1731 | -#box-organizer .block:hover .button-bar { | 1738 | +#box-organizer .block-outer:focus .button-bar, |
1739 | +#box-organizer .block-outer:hover .button-bar { | ||
1732 | display: block; | 1740 | display: block; |
1733 | } | 1741 | } |
1734 | 1742 |
test/functional/profile_themes_controller_test.rb
@@ -310,4 +310,23 @@ class ProfileThemesControllerTest < ActionController::TestCase | @@ -310,4 +310,23 @@ class ProfileThemesControllerTest < ActionController::TestCase | ||
310 | assert_no_tag :content => "Select theme" | 310 | assert_no_tag :content => "Select theme" |
311 | end | 311 | end |
312 | 312 | ||
313 | + should 'not duplicate themes that are included by the user and by the environment' do | ||
314 | + t1 = Theme.create('theme1') | ||
315 | + t2 = Theme.create('theme2') | ||
316 | + Environment.any_instance.stubs('themes').returns([t1,t2]) | ||
317 | + Theme.stubs(:approved_themes).returns([t2]) | ||
318 | + | ||
319 | + get :index, :profile => "testinguser" | ||
320 | + assert_equivalent [t1, t2], assigns(:themes) | ||
321 | + end | ||
322 | + | ||
323 | + should 'sort themes by name' do | ||
324 | + t1 = Theme.create('bill-theme') | ||
325 | + t2 = Theme.create('ana-theme') | ||
326 | + Theme.stubs(:approved_themes).returns([t1,t2]) | ||
327 | + | ||
328 | + get :index, :profile => "testinguser" | ||
329 | + assert_equal [t2, t1], assigns(:themes) | ||
330 | + end | ||
331 | + | ||
313 | end | 332 | end |
test/functional/users_controller_test.rb
@@ -107,6 +107,21 @@ class UsersControllerTest < ActionController::TestCase | @@ -107,6 +107,21 @@ class UsersControllerTest < ActionController::TestCase | ||
107 | assert_equal false, u.activated? | 107 | assert_equal false, u.activated? |
108 | end | 108 | end |
109 | 109 | ||
110 | + should 'order users by name' do | ||
111 | + create_user('jeremy') | ||
112 | + create_user('bill') | ||
113 | + create_user('ana') | ||
114 | + create_user('creed') | ||
115 | + get :index | ||
116 | + | ||
117 | + assert_order ['ana', 'bill', 'creed', 'jeremy'], assigns(:collection).map(&:name) | ||
118 | + end | ||
119 | + | ||
120 | + should 'set filter to all_users by default' do | ||
121 | + get :index | ||
122 | + assert_equal 'all_users', assigns(:filter) | ||
123 | + end | ||
124 | + | ||
110 | should 'response as XML to export users' do | 125 | should 'response as XML to export users' do |
111 | get :download, :format => 'xml' | 126 | get :download, :format => 'xml' |
112 | assert_equal 'text/xml', @response.content_type | 127 | assert_equal 'text/xml', @response.content_type |
test/test_helper.rb
@@ -177,6 +177,19 @@ class ActiveSupport::TestCase | @@ -177,6 +177,19 @@ class ActiveSupport::TestCase | ||
177 | assert !tag, "expected no tag #{options.inspect}, but tag found in #{text.inspect}" | 177 | assert !tag, "expected no tag #{options.inspect}, but tag found in #{text.inspect}" |
178 | end | 178 | end |
179 | 179 | ||
180 | + def assert_order(reference, original) | ||
181 | + original.each do |value| | ||
182 | + if reference.include?(value) | ||
183 | + if reference.first == value | ||
184 | + reference.shift | ||
185 | + else | ||
186 | + assert false, "'#{value}' was found before it should be on: #{original.inspect}" | ||
187 | + end | ||
188 | + end | ||
189 | + end | ||
190 | + assert reference.blank?, "The following elements are not in the collection: #{reference.inspect}" | ||
191 | + end | ||
192 | + | ||
180 | # For models that render views (blocks, articles, ...) | 193 | # For models that render views (blocks, articles, ...) |
181 | def render(*args) | 194 | def render(*args) |
182 | view_paths = @explicit_view_paths || ActionController::Base.view_paths | 195 | view_paths = @explicit_view_paths || ActionController::Base.view_paths |
@@ -0,0 +1,11 @@ | @@ -0,0 +1,11 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | + | ||
3 | +# tests for Array core extension. See lib/noosfero/core_ext/array.rb | ||
4 | +class StringCoreExtTest < ActiveSupport::TestCase | ||
5 | + | ||
6 | + should 'allow uniq by a block' do | ||
7 | + array = [0,1,2,3,4,5,6] | ||
8 | + assert_equal [0,1], array.uniq_by {|number| number%2 } | ||
9 | + end | ||
10 | + | ||
11 | +end |
test/unit/box_test.rb
@@ -140,4 +140,11 @@ class BoxTest < ActiveSupport::TestCase | @@ -140,4 +140,11 @@ class BoxTest < ActiveSupport::TestCase | ||
140 | assert !blocks.include?('box-test_plugin-block') | 140 | assert !blocks.include?('box-test_plugin-block') |
141 | end | 141 | end |
142 | 142 | ||
143 | + should 'list only boxes with a postion greater than zero' do | ||
144 | + profile = fast_create(Profile) | ||
145 | + box = fast_create(Box, :owner_id => profile.id, :owner_type => 'Profile', :position => 0) | ||
146 | + box2 = fast_create(Box, :owner_id => profile.id, :owner_type => 'Profile', :position => 1) | ||
147 | + assert_equal [box2], profile.boxes.with_position | ||
148 | + end | ||
149 | + | ||
143 | end | 150 | end |
test/unit/boxes_helper_test.rb
@@ -13,7 +13,8 @@ class BoxesHelperTest < ActiveSupport::TestCase | @@ -13,7 +13,8 @@ class BoxesHelperTest < ActiveSupport::TestCase | ||
13 | 13 | ||
14 | should 'include profile-specific header' do | 14 | should 'include profile-specific header' do |
15 | holder = mock | 15 | holder = mock |
16 | - holder.stubs(:boxes).returns([]) | 16 | + holder.stubs(:boxes).returns(boxes = []) |
17 | + boxes.stubs(:with_position).returns([]) | ||
17 | holder.stubs(:boxes_limit).returns(0) | 18 | holder.stubs(:boxes_limit).returns(0) |
18 | holder.stubs(:custom_header_expanded).returns('my custom header') | 19 | holder.stubs(:custom_header_expanded).returns('my custom header') |
19 | @controller.stubs(:boxes_holder).returns(holder) | 20 | @controller.stubs(:boxes_holder).returns(holder) |
@@ -23,7 +24,8 @@ class BoxesHelperTest < ActiveSupport::TestCase | @@ -23,7 +24,8 @@ class BoxesHelperTest < ActiveSupport::TestCase | ||
23 | 24 | ||
24 | should 'include profile-specific footer' do | 25 | should 'include profile-specific footer' do |
25 | holder = mock | 26 | holder = mock |
26 | - holder.stubs(:boxes).returns([]) | 27 | + holder.stubs(:boxes).returns(boxes = []) |
28 | + boxes.stubs(:with_position).returns([]) | ||
27 | holder.stubs(:boxes_limit).returns(0) | 29 | holder.stubs(:boxes_limit).returns(0) |
28 | holder.stubs(:custom_footer_expanded).returns('my custom footer') | 30 | holder.stubs(:custom_footer_expanded).returns('my custom footer') |
29 | @controller.stubs(:boxes_holder).returns(holder) | 31 | @controller.stubs(:boxes_holder).returns(holder) |
test/unit/comment_test.rb
@@ -285,6 +285,37 @@ class CommentTest < ActiveSupport::TestCase | @@ -285,6 +285,37 @@ class CommentTest < ActiveSupport::TestCase | ||
285 | assert_equal [c1,c3], c.reload.children | 285 | assert_equal [c1,c3], c.reload.children |
286 | end | 286 | end |
287 | 287 | ||
288 | + should "return activities comments as a thread" do | ||
289 | + person = fast_create(Person) | ||
290 | + a = TextileArticle.create!(:profile => person, :name => 'My article', :body => 'Article body') | ||
291 | + c0 = Comment.create!(:source => a, :body => 'My comment', :author => person) | ||
292 | + c1 = Comment.create!(:reply_of_id => c0.id, :source => a, :body => 'bla', :author => person) | ||
293 | + c2 = Comment.create!(:reply_of_id => c1.id, :source => a, :body => 'bla', :author => person) | ||
294 | + c3 = Comment.create!(:reply_of_id => c0.id, :source => a, :body => 'bla', :author => person) | ||
295 | + c4 = Comment.create!(:source => a, :body => 'My comment', :author => person) | ||
296 | + result = a.activity.comments | ||
297 | + assert_equal c0, result[0] | ||
298 | + assert_equal [c1, c3], result[0].replies | ||
299 | + assert_equal [c2], result[0].replies[0].replies | ||
300 | + assert_equal c4, result[1] | ||
301 | + assert result[1].replies.empty? | ||
302 | + end | ||
303 | + | ||
304 | + should "return activities comments when some comment on thread is spam and not display its replies" do | ||
305 | + person = fast_create(Person) | ||
306 | + a = TextileArticle.create!(:profile => person, :name => 'My article', :body => 'Article body') | ||
307 | + c0 = Comment.create(:source => a, :body => 'Root comment', :author => person) | ||
308 | + c1 = Comment.create(:reply_of_id => c0.id, :source => a, :body => 'c1', :author => person) | ||
309 | + c2 = Comment.create(:source => a, :body => 'c2', :author => person) | ||
310 | + spam = Comment.create(:spam => true, :reply_of_id => c2.id, :source => a, :body => 'spam', :author => person) | ||
311 | + spam_reply = Comment.create(:reply_of_id => spam.id, :source => a, :body => 'spam reply', :author => person) | ||
312 | + result = a.activity.comments | ||
313 | + assert_equal c0, result[0] | ||
314 | + assert_equal [c1], result[0].replies.without_spam | ||
315 | + assert_equal c2, result[1] | ||
316 | + assert_equal [], result[1].replies.without_spam | ||
317 | + end | ||
318 | + | ||
288 | should 'provide author url for authenticated user' do | 319 | should 'provide author url for authenticated user' do |
289 | author = Person.new | 320 | author = Person.new |
290 | author.expects(:url).returns('http://blabla.net/author') | 321 | author.expects(:url).returns('http://blabla.net/author') |
@@ -389,6 +420,7 @@ class CommentTest < ActiveSupport::TestCase | @@ -389,6 +420,7 @@ class CommentTest < ActiveSupport::TestCase | ||
389 | end | 420 | end |
390 | 421 | ||
391 | should 'be able to select non-spam comments' do | 422 | should 'be able to select non-spam comments' do |
423 | + Comment.destroy_all | ||
392 | c1 = fast_create(Comment) | 424 | c1 = fast_create(Comment) |
393 | c2 = fast_create(Comment, :spam => false) | 425 | c2 = fast_create(Comment, :spam => false) |
394 | c3 = fast_create(Comment, :spam => true) | 426 | c3 = fast_create(Comment, :spam => true) |
@@ -660,6 +692,7 @@ class CommentTest < ActiveSupport::TestCase | @@ -660,6 +692,7 @@ class CommentTest < ActiveSupport::TestCase | ||
660 | end | 692 | end |
661 | 693 | ||
662 | should 'be able to select non-reply comments' do | 694 | should 'be able to select non-reply comments' do |
695 | + Comment.destroy_all | ||
663 | c1 = fast_create(Comment) | 696 | c1 = fast_create(Comment) |
664 | c2 = fast_create(Comment, :reply_of_id => c1.id) | 697 | c2 = fast_create(Comment, :reply_of_id => c1.id) |
665 | c3 = fast_create(Comment, :reply_of_id => c2.id) | 698 | c3 = fast_create(Comment, :reply_of_id => c2.id) |
test/unit/environment_test.rb
@@ -783,6 +783,18 @@ class EnvironmentTest < ActiveSupport::TestCase | @@ -783,6 +783,18 @@ class EnvironmentTest < ActiveSupport::TestCase | ||
783 | assert role2.valid? | 783 | assert role2.valid? |
784 | end | 784 | end |
785 | 785 | ||
786 | + should 'destroy roles when its environment is destroyed' do | ||
787 | + e1 = fast_create(Environment) | ||
788 | + role1 = Role.create!(:name => 'test_role', :environment => e1, :key => 'a_member') | ||
789 | + e2 = fast_create(Environment) | ||
790 | + role2 = Role.create!(:name => 'test_role', :environment => e2, :key => 'a_member') | ||
791 | + | ||
792 | + e2.destroy | ||
793 | + | ||
794 | + assert_nothing_raised {Role.find(role1.id)} | ||
795 | + assert_raise(ActiveRecord::RecordNotFound) {Role.find(role2.id)} | ||
796 | + end | ||
797 | + | ||
786 | should 'have a help_message_to_add_enterprise attribute' do | 798 | should 'have a help_message_to_add_enterprise attribute' do |
787 | env = Environment.new | 799 | env = Environment.new |
788 | 800 |
test/unit/profile_test.rb
@@ -1461,7 +1461,7 @@ class ProfileTest < ActiveSupport::TestCase | @@ -1461,7 +1461,7 @@ class ProfileTest < ActiveSupport::TestCase | ||
1461 | should 'list events by month' do | 1461 | should 'list events by month' do |
1462 | profile = fast_create(Profile) | 1462 | profile = fast_create(Profile) |
1463 | 1463 | ||
1464 | - today = Date.today | 1464 | + today = Date.new(2014, 03, 2) |
1465 | yesterday_event = Event.new(:name => 'Joao Birthday', :start_date => today - 1.day) | 1465 | yesterday_event = Event.new(:name => 'Joao Birthday', :start_date => today - 1.day) |
1466 | today_event = Event.new(:name => 'Ze Birthday', :start_date => today) | 1466 | today_event = Event.new(:name => 'Ze Birthday', :start_date => today) |
1467 | tomorrow_event = Event.new(:name => 'Mane Birthday', :start_date => today + 1.day) | 1467 | tomorrow_event = Event.new(:name => 'Mane Birthday', :start_date => today + 1.day) |
vendor/plugins/action_tracker_has_comments/init.rb
@@ -11,5 +11,6 @@ Rails.configuration.to_prepare do | @@ -11,5 +11,6 @@ Rails.configuration.to_prepare do | ||
11 | type, id = (self.target_type == 'Article' ? ['Article', self.target_id] : [self.class.to_s, self.id]) | 11 | type, id = (self.target_type == 'Article' ? ['Article', self.target_id] : [self.class.to_s, self.id]) |
12 | "source_type = '#{type}' AND source_id = '#{id}' AND spam IS NOT TRUE AND reply_of_id IS NULL" | 12 | "source_type = '#{type}' AND source_id = '#{id}' AND spam IS NOT TRUE AND reply_of_id IS NULL" |
13 | end | 13 | end |
14 | + | ||
14 | end | 15 | end |
15 | end | 16 | end |