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 | 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 | ... | ... |