Commit d0561132a9af7bcd87550258ef5e4358b6c0ea0c
Exists in
master
and in
22 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 | include UsersHelper |
| 8 | 8 | |
| 9 | 9 | def index |
| 10 | - @filter = params[:filter] | |
| 10 | + @filter = params[:filter] || 'all_users' | |
| 11 | 11 | scope = environment.people.no_templates |
| 12 | 12 | if @filter == 'admin_users' |
| 13 | 13 | scope = scope.admins |
| ... | ... | @@ -16,6 +16,7 @@ class UsersController < AdminController |
| 16 | 16 | elsif @filter == 'deactivated_users' |
| 17 | 17 | scope = scope.deactivated |
| 18 | 18 | end |
| 19 | + scope = scope.order('name ASC') | |
| 19 | 20 | @q = params[:q] |
| 20 | 21 | @collection = find_by_contents(:people, scope, @q, {:per_page => per_page, :page => params[:npage]})[:results] |
| 21 | 22 | end | ... | ... |
app/controllers/application_controller.rb
| ... | ... | @@ -21,6 +21,7 @@ class ApplicationController < ActionController::Base |
| 21 | 21 | include ApplicationHelper |
| 22 | 22 | layout :get_layout |
| 23 | 23 | def get_layout |
| 24 | + return nil if request.format == :js | |
| 24 | 25 | theme_layout = theme_option(:layout) |
| 25 | 26 | if theme_layout |
| 26 | 27 | theme_view_file('layouts/'+theme_layout) || theme_layout | ... | ... |
app/controllers/box_organizer_controller.rb
| ... | ... | @@ -70,7 +70,7 @@ class BoxOrganizerController < ApplicationController |
| 70 | 70 | else |
| 71 | 71 | @center_block_types = (Box.acceptable_center_blocks & available_blocks) + plugins.dispatch(:extra_blocks, :type => boxes_holder.class, :position => 1) |
| 72 | 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 | 74 | render :action => 'add_block', :layout => false |
| 75 | 75 | end |
| 76 | 76 | end | ... | ... |
app/helpers/boxes_helper.rb
| ... | ... | @@ -39,7 +39,7 @@ module BoxesHelper |
| 39 | 39 | end |
| 40 | 40 | |
| 41 | 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 | 43 | content = boxes.reverse.map { |item| display_box(item, main_content) }.join("\n") |
| 44 | 44 | content = main_content if (content.blank?) |
| 45 | 45 | ... | ... |
app/models/box.rb
app/models/environment.rb
| ... | ... | @@ -186,7 +186,7 @@ class Environment < ActiveRecord::Base |
| 186 | 186 | has_many :product_categories, :conditions => { :type => 'ProductCategory'} |
| 187 | 187 | has_many :regions |
| 188 | 188 | |
| 189 | - has_many :roles | |
| 189 | + has_many :roles, :dependent => :destroy | |
| 190 | 190 | |
| 191 | 191 | has_many :qualifiers |
| 192 | 192 | has_many :certifiers | ... | ... |
app/views/blocks/location.html.erb
| ... | ... | @@ -3,7 +3,6 @@ |
| 3 | 3 | <div class='the-localization-map'> |
| 4 | 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 | 5 | </div> |
| 6 | -</div> | |
| 7 | 6 | <% else %> |
| 8 | 7 | <i><%= _('This profile has no geographical position registered.') %></i> |
| 9 | 8 | <% end %> | ... | ... |
debian/changelog
lib/noosfero.rb
lib/noosfero/core_ext.rb
lib/noosfero/plugin/routes.rb
| ... | ... | @@ -15,12 +15,16 @@ Dir.glob(File.join(Rails.root, plugins_root, '*', 'controllers')) do |controller |
| 15 | 15 | controllers_by_folder.each do |folder, controllers| |
| 16 | 16 | controllers.each do |controller| |
| 17 | 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 | 23 | end |
| 20 | 24 | end |
| 21 | 25 | |
| 22 | 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 | 29 | map.connect 'admin/plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_admin' |
| 26 | 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 | 7 | settings_items :container_box_id, :type => Integer, :default => nil |
| 8 | 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 | 20 | def self.description |
| 11 | 21 | _('Container') |
| 12 | 22 | end |
| ... | ... | @@ -15,6 +25,10 @@ class ContainerBlockPlugin::ContainerBlock < Block |
| 15 | 25 | _('This block acts as a container for another blocks') |
| 16 | 26 | end |
| 17 | 27 | |
| 28 | + def cacheable? | |
| 29 | + false | |
| 30 | + end | |
| 31 | + | |
| 18 | 32 | def layout_template |
| 19 | 33 | nil |
| 20 | 34 | end |
| ... | ... | @@ -24,8 +38,9 @@ class ContainerBlockPlugin::ContainerBlock < Block |
| 24 | 38 | end |
| 25 | 39 | |
| 26 | 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 | 44 | save! |
| 30 | 45 | end |
| 31 | 46 | ... | ... |
| ... | ... | @@ -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 | 7 | #content .boxes .container-block-plugin_container-block .container_block_child, .container-block-plugin_container-block .block-outer { |
| 2 | 8 | display: inline-block; |
| 3 | 9 | vertical-align: top; |
| ... | ... | @@ -17,14 +23,10 @@ |
| 17 | 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 | 26 | #content .boxes .container-block-plugin_container-block .block .ui-resizable-handle { |
| 25 | 27 | width: 10px; |
| 26 | 28 | height: 28px; |
| 27 | - z-index: 0; | |
| 29 | + z-index: 1000; | |
| 28 | 30 | } |
| 29 | 31 | |
| 30 | 32 | #content .boxes .container-block-plugin_container-block .block .ui-resizable-e { |
| ... | ... | @@ -37,6 +39,21 @@ |
| 37 | 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 | 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 | 31 | assert_tag :div, :attributes => { :class => 'block container-block-plugin_container-block' } |
| 32 | 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 | 41 | should 'display container children' do |
| 35 | 42 | c1 = RawHTMLBlock.create!(:box => @block.container_box, :html => 'child1 content') |
| 36 | 43 | c2 = RawHTMLBlock.create!(:box => @block.container_box, :html => 'child2 content') | ... | ... |
plugins/container_block/test/unit/block_test.rb
| ... | ... | @@ -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 | 20 | assert @block.container_box_id |
| 21 | 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 | 28 | should 'return created box' do |
| 24 | 29 | @block.save! |
| 25 | 30 | assert @block.container_box |
| ... | ... | @@ -89,4 +94,27 @@ class ContainerBlockPlugin::ContainerBlockTest < ActiveSupport::TestCase |
| 89 | 94 | end |
| 90 | 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 | 120 | end | ... | ... |
plugins/container_block/test/unit/environment_test.rb
| ... | ... | @@ -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 | -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 | 1 | <% edit_mode = @controller.send(:boxes_editor?) && @controller.send(:uses_design_blocks?) %> |
| 2 | 2 | <% box_decorator = edit_mode ? self : BoxesHelper::DontMoveBlocks %> |
| 3 | 3 | |
| 4 | +<%= block_title(block.title) %> | |
| 4 | 5 | |
| 5 | 6 | <div class="box" id="box-<%= block.container_box.id %>"> |
| 6 | 7 | <%= display_box_content(block.container_box, nil) %> |
| ... | ... | @@ -15,8 +16,18 @@ |
| 15 | 16 | </style> |
| 16 | 17 | |
| 17 | 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 | 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 | 32 | :with => "containerChildrenWidth(#{block.id}, #{block.container_box.id})", |
| 22 | 33 | :html => {:class => "button icon-save container_block_save", :id => "container_block_save_#{block.id}", :title => _('Save') }, |
| ... | ... | @@ -24,37 +35,4 @@ |
| 24 | 35 | :loaded => "close_loading();", |
| 25 | 36 | :complete => "display_notice(request.responseText);"%> |
| 26 | 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 | 38 | <% end %> | ... | ... |
plugins/require_auth_to_comment/public/hide_comment_form.js
| 1 | 1 | (function($) { |
| 2 | 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 | 4 | $('.post-comment-button').livequery(function() { |
| 5 | 5 | $(this).show(); |
| 6 | 6 | }); |
| ... | ... | @@ -8,7 +8,7 @@ |
| 8 | 8 | $(this).show(); |
| 9 | 9 | }); |
| 10 | 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 | 9 | body { |
| 2 | 10 | padding: 0px; |
| 3 | 11 | margin: 0px; |
| ... | ... | @@ -1727,8 +1735,8 @@ a.button.disabled, input.disabled { |
| 1727 | 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 | 1740 | display: block; |
| 1733 | 1741 | } |
| 1734 | 1742 | ... | ... |
test/functional/profile_themes_controller_test.rb
| ... | ... | @@ -310,4 +310,23 @@ class ProfileThemesControllerTest < ActionController::TestCase |
| 310 | 310 | assert_no_tag :content => "Select theme" |
| 311 | 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 | 332 | end | ... | ... |
test/functional/users_controller_test.rb
| ... | ... | @@ -107,6 +107,21 @@ class UsersControllerTest < ActionController::TestCase |
| 107 | 107 | assert_equal false, u.activated? |
| 108 | 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 | 125 | should 'response as XML to export users' do |
| 111 | 126 | get :download, :format => 'xml' |
| 112 | 127 | assert_equal 'text/xml', @response.content_type | ... | ... |
test/test_helper.rb
| ... | ... | @@ -177,6 +177,19 @@ class ActiveSupport::TestCase |
| 177 | 177 | assert !tag, "expected no tag #{options.inspect}, but tag found in #{text.inspect}" |
| 178 | 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 | 193 | # For models that render views (blocks, articles, ...) |
| 181 | 194 | def render(*args) |
| 182 | 195 | view_paths = @explicit_view_paths || ActionController::Base.view_paths | ... | ... |
| ... | ... | @@ -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 | 140 | assert !blocks.include?('box-test_plugin-block') |
| 141 | 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 | 150 | end | ... | ... |
test/unit/boxes_helper_test.rb
| ... | ... | @@ -13,7 +13,8 @@ class BoxesHelperTest < ActiveSupport::TestCase |
| 13 | 13 | |
| 14 | 14 | should 'include profile-specific header' do |
| 15 | 15 | holder = mock |
| 16 | - holder.stubs(:boxes).returns([]) | |
| 16 | + holder.stubs(:boxes).returns(boxes = []) | |
| 17 | + boxes.stubs(:with_position).returns([]) | |
| 17 | 18 | holder.stubs(:boxes_limit).returns(0) |
| 18 | 19 | holder.stubs(:custom_header_expanded).returns('my custom header') |
| 19 | 20 | @controller.stubs(:boxes_holder).returns(holder) |
| ... | ... | @@ -23,7 +24,8 @@ class BoxesHelperTest < ActiveSupport::TestCase |
| 23 | 24 | |
| 24 | 25 | should 'include profile-specific footer' do |
| 25 | 26 | holder = mock |
| 26 | - holder.stubs(:boxes).returns([]) | |
| 27 | + holder.stubs(:boxes).returns(boxes = []) | |
| 28 | + boxes.stubs(:with_position).returns([]) | |
| 27 | 29 | holder.stubs(:boxes_limit).returns(0) |
| 28 | 30 | holder.stubs(:custom_footer_expanded).returns('my custom footer') |
| 29 | 31 | @controller.stubs(:boxes_holder).returns(holder) | ... | ... |
test/unit/comment_test.rb
| ... | ... | @@ -285,6 +285,37 @@ class CommentTest < ActiveSupport::TestCase |
| 285 | 285 | assert_equal [c1,c3], c.reload.children |
| 286 | 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 | 319 | should 'provide author url for authenticated user' do |
| 289 | 320 | author = Person.new |
| 290 | 321 | author.expects(:url).returns('http://blabla.net/author') |
| ... | ... | @@ -389,6 +420,7 @@ class CommentTest < ActiveSupport::TestCase |
| 389 | 420 | end |
| 390 | 421 | |
| 391 | 422 | should 'be able to select non-spam comments' do |
| 423 | + Comment.destroy_all | |
| 392 | 424 | c1 = fast_create(Comment) |
| 393 | 425 | c2 = fast_create(Comment, :spam => false) |
| 394 | 426 | c3 = fast_create(Comment, :spam => true) |
| ... | ... | @@ -660,6 +692,7 @@ class CommentTest < ActiveSupport::TestCase |
| 660 | 692 | end |
| 661 | 693 | |
| 662 | 694 | should 'be able to select non-reply comments' do |
| 695 | + Comment.destroy_all | |
| 663 | 696 | c1 = fast_create(Comment) |
| 664 | 697 | c2 = fast_create(Comment, :reply_of_id => c1.id) |
| 665 | 698 | c3 = fast_create(Comment, :reply_of_id => c2.id) | ... | ... |
test/unit/environment_test.rb
| ... | ... | @@ -783,6 +783,18 @@ class EnvironmentTest < ActiveSupport::TestCase |
| 783 | 783 | assert role2.valid? |
| 784 | 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 | 798 | should 'have a help_message_to_add_enterprise attribute' do |
| 787 | 799 | env = Environment.new |
| 788 | 800 | ... | ... |
test/unit/profile_test.rb
| ... | ... | @@ -1461,7 +1461,7 @@ class ProfileTest < ActiveSupport::TestCase |
| 1461 | 1461 | should 'list events by month' do |
| 1462 | 1462 | profile = fast_create(Profile) |
| 1463 | 1463 | |
| 1464 | - today = Date.today | |
| 1464 | + today = Date.new(2014, 03, 2) | |
| 1465 | 1465 | yesterday_event = Event.new(:name => 'Joao Birthday', :start_date => today - 1.day) |
| 1466 | 1466 | today_event = Event.new(:name => 'Ze Birthday', :start_date => today) |
| 1467 | 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 | 11 | type, id = (self.target_type == 'Article' ? ['Article', self.target_id] : [self.class.to_s, self.id]) |
| 12 | 12 | "source_type = '#{type}' AND source_id = '#{id}' AND spam IS NOT TRUE AND reply_of_id IS NULL" |
| 13 | 13 | end |
| 14 | + | |
| 14 | 15 | end |
| 15 | 16 | end | ... | ... |