Commit 48038fc5280aa13175bba9fc78512ca7faad9c24

Authored by Rodrigo Souto
2 parents 8711e17a e137c34d

Merge branch 'stable' into noosfero_0.47.0

Conflicts:
	app/controllers/public/content_viewer_controller.rb
	features/categories_block.feature
	po/eo/noosfero.po
	po/es/noosfero.po
	po/it/noosfero.po
	test/unit/block_test.rb
app/controllers/public/content_viewer_controller.rb
... ... @@ -50,7 +50,7 @@ class ContentViewerController < ApplicationController
50 50 end
51 51  
52 52 # At this point the page will be showed
53   - @page.hit
  53 + @page.hit unless user_is_a_bot?
54 54  
55 55 @page = FilePresenter.for @page
56 56  
... ... @@ -174,4 +174,13 @@ class ContentViewerController < ApplicationController
174 174 allowed
175 175 end
176 176  
  177 + def user_is_a_bot?
  178 + user_agent= request.env["HTTP_USER_AGENT"]
  179 + user_agent.blank? ||
  180 + user_agent.match(/bot/) ||
  181 + user_agent.match(/spider/) ||
  182 + user_agent.match(/crawler/) ||
  183 + user_agent.match(/\(.*https?:\/\/.*\)/)
  184 + end
  185 +
177 186 end
... ...
app/controllers/public/events_controller.rb
... ... @@ -7,11 +7,11 @@ class EventsController < PublicController
7 7 @date = build_date(params[:year], params[:month], params[:day])
8 8  
9 9 if !params[:year] && !params[:month] && !params[:day]
10   - @events = profile.events.next_events_from_month(@date)
  10 + @events = profile.events.next_events_from_month(@date).paginate(:per_page => per_page, :page => params[:page])
11 11 end
12 12  
13 13 if params[:year] || params[:month]
14   - @events = profile.events.by_month(@date)
  14 + @events = profile.events.by_month(@date).paginate(:per_page => per_page, :page => params[:page])
15 15 end
16 16  
17 17 events_in_range = profile.events.by_range((@date - 1.month).at_beginning_of_month .. (@date + 1.month).at_end_of_month)
... ... @@ -29,4 +29,7 @@ class EventsController < PublicController
29 29  
30 30 include EventsHelper
31 31  
  32 + def per_page
  33 + 20
  34 + end
32 35 end
... ...
app/controllers/public/search_controller.rb
... ... @@ -99,14 +99,14 @@ class SearchController < PublicController
99 99 @events = []
100 100 if params[:day] || !params[:year] && !params[:month]
101 101 @events = @category ?
102   - environment.events.by_day(@date).in_category(Category.find(@category_id)) :
103   - environment.events.by_day(@date)
  102 + environment.events.by_day(@date).in_category(Category.find(@category_id)).paginate(:per_page => per_page, :page => params[:page]) :
  103 + environment.events.by_day(@date).paginate(:per_page => per_page, :page => params[:page])
104 104 end
105 105  
106 106 if params[:year] || params[:month]
107 107 @events = @category ?
108   - environment.events.by_month(@date).in_category(Category.find(@category_id)) :
109   - environment.events.by_month(@date)
  108 + environment.events.by_month(@date).in_category(Category.find(@category_id)).paginate(:per_page => per_page, :page => params[:page]) :
  109 + environment.events.by_month(@date).paginate(:per_page => per_page, :page => params[:page])
110 110 end
111 111  
112 112 @scope = date_range && params[:action] == 'events' ? environment.events.by_range(date_range) : environment.events
... ... @@ -139,7 +139,7 @@ class SearchController < PublicController
139 139  
140 140 def events_by_day
141 141 @date = build_date(params[:year], params[:month], params[:day])
142   - @events = environment.events.by_day(@date)
  142 + @events = environment.events.by_day(@date).paginate(:per_page => per_page, :page => params[:page])
143 143 render :partial => 'events/events'
144 144 end
145 145  
... ... @@ -224,4 +224,8 @@ class SearchController < PublicController
224 224 @environment.send(klass.name.underscore.pluralize).visible.includes(relations)
225 225 end
226 226  
  227 + def per_page
  228 + 20
  229 + end
  230 +
227 231 end
... ...
app/models/block.rb
... ... @@ -141,7 +141,7 @@ class Block < ActiveRecord::Base
141 141 end
142 142  
143 143 alias :active_record_cache_key :cache_key
144   - def cache_key(language='en')
  144 + def cache_key(language='en', user=nil)
145 145 active_record_cache_key+'-'+language
146 146 end
147 147  
... ...
app/models/event.rb
... ... @@ -38,15 +38,12 @@ class Event < Article
38 38 named_scope :next_events_from_month, lambda { |date|
39 39 date_temp = date.strftime("%Y-%m-%d")
40 40 { :conditions => ["start_date >= ?","#{date_temp}"],
41   - :limit => 10,
42 41 :order => 'start_date ASC'
43 42 }
44 43 }
45 44  
46 45 named_scope :by_month, lambda { |date|
47   - date_temp = date.strftime("%Y-%m")
48 46 { :conditions => ["EXTRACT(YEAR FROM start_date) = ? AND EXTRACT(MONTH FROM start_date) = ?",date.year,date.month],
49   - :limit => 10,
50 47 :order => 'start_date ASC'
51 48 }
52 49 }
... ...
app/models/members_block.rb
... ... @@ -36,4 +36,15 @@ class MembersBlock < ProfileListBlock
36 36 }
37 37 end
38 38  
  39 + def cache_key(language='en', user=nil)
  40 + logged = ''
  41 + if user
  42 + logged += '-logged-in'
  43 + if user.is_member_of? self.owner
  44 + logged += '-member'
  45 + end
  46 + end
  47 + super + logged
  48 + end
  49 +
39 50 end
... ...
app/views/events/_events.rhtml
1   -<%= list_events(@date, @events) %>
2 1 \ No newline at end of file
  2 +<%= list_events(@date, @events) %>
  3 +
  4 +<%= pagination_links @events, :param_name => 'page' %>
... ...
app/views/shared/block.rhtml
1 1 <% if block.cacheable? && use_cache %>
2   - <% cache_timeout(block.cache_key(language), block.timeout) do %>
  2 + <% cache_timeout(block.cache_key(language, user), block.timeout) do %>
3 3 <%= display_block_content(block, user, main_content) %>
4 4 <% end %>
5 5 <% else %>
... ...
features/balloon.feature
... ... @@ -8,6 +8,7 @@ Feature: balloon
8 8 And the following communities
9 9 | identifier | name |
10 10 | sample | Sample |
  11 + And I am logged in as "joaosilva"
11 12  
12 13 @selenium
13 14 Scenario: I should not see trigger if not enabled
... ...
features/categories_block.feature
... ... @@ -24,6 +24,8 @@ Feature: categories_block
24 24 | owner | type |
25 25 | environment | CategoriesBlock |
26 26 And I am logged in as admin
  27 + And I go to /admin/environment_design
  28 + And display ".button-bar"
27 29  
28 30 # Note that this @ignore-hidden-elements only works for seeing hidden
29 31 # elements. It actually doesn't work for following hidden link or pressing
... ... @@ -31,9 +33,7 @@ Feature: categories_block
31 33 # the link.
32 34 @selenium @ignore-hidden-elements
33 35 Scenario: List just product categories
34   - Given I go to /admin/environment_design
35   - And display ".categories-block .button-bar"
36   - And I follow "Edit" within ".categories-block"
  36 + Given I follow "Edit" within ".categories-block"
37 37 And I check "Product"
38 38 When I press "Save"
39 39 Then I should see "Food"
... ... @@ -42,11 +42,9 @@ Feature: categories_block
42 42 And "Steak" should not be visible within "span#category-name"
43 43 And "Fiction" should not be visible within "span#category-name"
44 44  
45   - @selenium @ignore-hidden-elements
  45 + @selenium
46 46 Scenario: Show submenu if it exists
47   - Given I go to /admin/environment_design
48   - And display ".categories-block .button-bar"
49   - And I follow "Edit" within ".categories-block"
  47 + Given I follow "Edit" within ".categories-block"
50 48 And I check "Product"
51 49 And I press "Save"
52 50 Then I should see "Food"
... ... @@ -61,11 +59,9 @@ Feature: categories_block
61 59 And I should see "Steak"
62 60 And I should not see "Fiction"
63 61  
64   - @selenium @ignore-hidden-elements
  62 + @selenium
65 63 Scenario: Show only one submenu per time
66   - Given I go to /admin/environment_design
67   - And display ".categories-block .button-bar"
68   - And I follow "Edit" within ".categories-block"
  64 + Given I follow "Edit" within ".categories-block"
69 65 And I check "Product"
70 66 And I press "Save"
71 67 Then I should see "Book"
... ... @@ -73,20 +69,16 @@ Feature: categories_block
73 69 When I follow "block_2_category_2"
74 70 Then I should see "Literature"
75 71  
76   - @selenium @ignore-hidden-elements
  72 + @selenium
77 73 Scenario: List just general categories
78   - Given I go to /admin/environment_design
79   - And display ".categories-block .button-bar"
80   - And I follow "Edit" within ".categories-block"
  74 + Given I follow "Edit" within ".categories-block"
81 75 And I check "Generic category"
82 76 When I press "Save"
83 77 Then I should see "Wood"
84 78  
85   - @selenium @ignore-hidden-elements
  79 + @selenium
86 80 Scenario: List just regions
87   - Given I go to /admin/environment_design
88   - And display ".categories-block .button-bar"
89   - And I follow "Edit" within ".categories-block"
  81 + Given I follow "Edit" within ".categories-block"
90 82 And I check "Region"
91 83 When I press "Save"
92 84 Then I should see "Bahia"
... ...
features/comment.feature
... ... @@ -39,7 +39,7 @@ Feature: comment
39 39 When I press "Post comment"
40 40 Then I should see "Hey ho, let's go"
41 41  
42   - @selenium
  42 + @selenium-fixme
43 43 Scenario: redirect to right place after comment a picture
44 44 Given the following files
45 45 | owner | file | mime |
... ...
features/events.feature
... ... @@ -244,3 +244,38 @@ Feature: events
244 244 Given I am on /profile/josesilva/events/2009/10
245 245 When I follow "Oktoberfest"
246 246 Then I should see "Oktoberfest"
  247 +
  248 + Scenario: list events paginated for a specific profile for the month
  249 + Given I am logged in as admin
  250 + And the following users
  251 + | login |
  252 + | josemanuel |
  253 + And I am logged in as "josemanuel"
  254 + And the following events
  255 + | owner | name | start_date |
  256 + | josemanuel | Event 5 | 2009-10-12 |
  257 + | josemanuel | Event 3 | 2009-10-15 |
  258 + | josemanuel | Test Event | 2009-10-15 |
  259 + | josemanuel | Oktoberfest | 2009-10-19 |
  260 + | josemanuel | WikiSym | 2009-10-21 |
  261 + | josemanuel | Free Software | 2009-10-22 |
  262 + | josemanuel | Rachel Birthday | 2009-10-23 |
  263 + | josemanuel | Manuel Birthday | 2009-10-24 |
  264 + | josemanuel | Michelle Birthday | 2009-10-25 |
  265 + | josemanuel | Lecture Allien 10 | 2009-10-26 |
  266 + | josemanuel | Lecture Allien 11 | 2009-10-26 |
  267 + | josemanuel | Lecture Allien 12 | 2009-10-26 |
  268 + | josemanuel | Lecture Allien 13 | 2009-10-26 |
  269 + | josemanuel | Lecture Allien 14 | 2009-10-26 |
  270 + | josemanuel | Lecture Allien 15 | 2009-10-26 |
  271 + | josemanuel | Lecture Allien 16 | 2009-10-26 |
  272 + | josemanuel | Lecture Allien 17 | 2009-10-26 |
  273 + | josemanuel | Lecture Allien 18 | 2009-10-26 |
  274 + | josemanuel | Lecture Allien 19 | 2009-10-26 |
  275 + | josemanuel | Lecture Allien 20 | 2009-10-26 |
  276 + | josemanuel | Party On | 2009-10-27 |
  277 +
  278 + When I am on /profile/josemanuel/events/2009/10
  279 + Then I should not see "Party On" within "#agenda-items"
  280 + When I follow "Next"
  281 + Then I should see "Party On" within "#agenda-items"
... ...
features/short_filename.feature
... ... @@ -1,21 +0,0 @@
1   -Feature: sitemap
2   - As a noosfero user
3   - I want to list articles
4   -
5   - Background:
6   - Given I am on the homepage
7   - And the following users
8   - | login | name |
9   - | joaosilva | Joao Silva |
10   - And the following files
11   - | owner | file | mime |
12   - | joaosilva | AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA.txt | text/plain |
13   -
14   - Scenario: view a folder page
15   - When I am on /profile/joaosilva/sitemap
16   - Then I should see "AGENDA_CULTURA_-_FESTA_DE_VAQUEIRO(...).txt"
17   -
18   - Scenario: view the CMS
19   - Given I am logged in as "joaosilva"
20   - When I am on /myprofile/joaosilva/cms
21   - Then I should see "AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_(...).txt"
lib/feed_handler.rb
... ... @@ -51,7 +51,6 @@ class FeedHandler
51 51 end
52 52  
53 53 def process(container)
54   - RAILS_DEFAULT_LOGGER.info("Processing %s with id = %d" % [container.class.name, container.id])
55 54 begin
56 55 container.class.transaction do
57 56 if container.update_errors > FeedHandler.max_errors && container.fetched_at < (Time.now - FeedHandler.disabled_period)
... ...
lib/file_presenter.rb
... ... @@ -50,6 +50,10 @@ class FilePresenter
50 50 nil
51 51 end
52 52  
  53 + def download?(view=nil)
  54 + false
  55 + end
  56 +
53 57 def short_description
54 58 file_type = if content_type.present?
55 59 content_type.sub(/^application\//, '').sub(/^x-/, '').sub(/^image\//, '')
... ...
lib/tasks/plugins_tests.rake
... ... @@ -25,51 +25,87 @@ def plugin_disabled_warning(plugin)
25 25 puts "E: you should enable #{plugin} plugin before running it's tests!"
26 26 end
27 27  
28   -def run_tests(name, files_glob)
29   - files = Dir.glob(files_glob)
30   - if files.empty?
31   - puts "I: no tests to run (#{name})"
  28 +def task2ext(task)
  29 + (task == :selenium || task == :cucumber) ? :feature : :rb
  30 +end
  31 +
  32 +def task2profile(task, plugin)
  33 + if task == :cucumber
  34 + return plugin
  35 + elsif task == :selenium
  36 + return "#{plugin}_selenium"
32 37 else
33   - sh 'testrb', '-Itest', *files
  38 + return 'default'
34 39 end
35 40 end
36 41  
37   -def run_cucumber(name, profile, files_glob)
38   - files = Dir.glob(files_glob)
39   - if files.empty?
40   - puts "I: no tests to run #{name}"
  42 +def filename2plugin(filename)
  43 + filename.split('/')[1]
  44 +end
  45 +
  46 +def task2folder(task)
  47 + result = case task.to_sym
  48 + when :units
  49 + :unit
  50 + when :functionals
  51 + :functional
  52 + when :integration
  53 + :integration
  54 + when :cucumber
  55 + :features
  56 + when :selenium
  57 + :features
  58 + end
  59 +
  60 + return result
  61 +end
  62 +
  63 +def run_test(name, files)
  64 + files = Array(files)
  65 + plugin = filename2plugin(files.first)
  66 + if name == :cucumber || name == :selenium
  67 + run_cucumber task2_profile(name, plugin), files
41 68 else
42   - sh 'xvfb-run', 'ruby', '-S', 'cucumber', '--profile', profile.to_s, '--format', ENV['CUCUMBER_FORMAT'] || 'progress' , *files
  69 + run_testrb files
43 70 end
44 71 end
45 72  
46   -def plugin_test_task(name, plugin, files_glob)
47   - desc "Run #{name} tests for #{plugin_name(plugin)}"
48   - task name => 'db:test:plugins:prepare' do |t|
49   - if plugin_enabled?(plugin)
50   - run_tests t.name, files_glob
51   - else
52   - plugin_disabled_warning(plugin)
  73 +def run_testrb(files)
  74 + sh 'testrb', '-Itest', *files
  75 +end
  76 +
  77 +def run_cucumber(profile, files)
  78 + sh 'xvfb-run', 'ruby', '-S', 'cucumber', '--profile', profile.to_s, '--format', ENV['CUCUMBER_FORMAT'] || 'progress' , *files
  79 +end
  80 +
  81 +def custom_run(name, files, run=:individually)
  82 + case run
  83 + when :all
  84 + run_test name, files
  85 + when :individually
  86 + files.each do |file|
  87 + run_test name, file
53 88 end
  89 + when :by_plugin
54 90 end
55 91 end
56 92  
57   -def plugin_cucumber_task(name, plugin, files_glob)
58   - desc "Run #{name} tests for #{plugin_name(plugin)}"
59   - task name => 'db:test:plugins:prepare' do |t|
60   - if plugin_enabled?(plugin)
61   - run_cucumber t.name, plugin, files_glob
62   - else
63   - plugin_disabled_warning(plugin)
64   - end
  93 +def run_tests(name, plugins, run=:individually)
  94 + plugins = Array(plugins)
  95 + glob = "plugins/{#{plugins.join(',')}}/test/#{task2folder(name)}/**/*.#{task2ext(name)}"
  96 + files = Dir.glob(glob)
  97 + if files.empty?
  98 + puts "I: no tests to run #{name}"
  99 + else
  100 + custom_run(name, files, run)
65 101 end
66 102 end
67 103  
68   -def plugin_selenium_task(name, plugin, files_glob)
  104 +def plugin_test_task(name, plugin, run=:individually)
69 105 desc "Run #{name} tests for #{plugin_name(plugin)}"
70 106 task name => 'db:test:plugins:prepare' do |t|
71 107 if plugin_enabled?(plugin)
72   - run_cucumber t.name, "#{plugin}_selenium", files_glob
  108 + run_tests(name, plugin, run)
73 109 else
74 110 plugin_disabled_warning(plugin)
75 111 end
... ... @@ -98,28 +134,28 @@ namespace :test do
98 134 namespace :noosfero_plugins do
99 135 all_plugins.each do |plugin|
100 136 namespace plugin do
101   - plugin_test_task :units, plugin, "plugins/#{plugin}/test/unit/**/*.rb"
102   - plugin_test_task :functionals, plugin, "plugins/#{plugin}/test/functional/**/*.rb"
103   - plugin_test_task :integration, plugin, "plugins/#{plugin}/test/integration/**/*.rb"
104   - plugin_cucumber_task :cucumber, plugin, "plugins/#{plugin}/features/**/*.feature"
105   - plugin_selenium_task :selenium, plugin, "plugins/#{plugin}/features/**/*.feature"
  137 + plugin_test_task :units, plugin
  138 + plugin_test_task :functionals, plugin
  139 + plugin_test_task :integration, plugin
  140 + plugin_test_task :cucumber, plugin
  141 + plugin_test_task :selenium, plugin
106 142 end
107 143  
108 144 test_sequence_task(plugin, plugin, "#{plugin}:units", "#{plugin}:functionals", "#{plugin}:integration", "#{plugin}:cucumber", "#{plugin}:selenium")
109 145 end
110 146  
111   - { :units => :unit , :functionals => :functional , :integration => :integration }.each do |taskname,folder|
  147 + [:units, :functionals, :integration].each do |taskname|
112 148 task taskname => 'db:test:plugins:prepare' do |t|
113   - run_tests t.name, "plugins/{#{enabled_plugins.join(',')}}/test/#{folder}/**/*.rb"
  149 + run_tests taskname, enabled_plugins
114 150 end
115 151 end
116 152  
117 153 task :cucumber => 'db:test:plugins:prepare' do |t|
118   - run_cucumber t.name, :default, "plugins/{#{enabled_plugins.join(',')}}/test/features/**/*.features"
  154 + run_tests :cucumber, enabled_plugins
119 155 end
120 156  
121 157 task :selenium => 'db:test:plugins:prepare' do |t|
122   - run_cucumber t.name, :selenium, "plugins/{#{enabled_plugins.join(',')}}/test/features/**/*.features"
  158 + run_tests :selenium, enabled_plugins
123 159 end
124 160  
125 161 task :temp_enable_all_plugins do
... ...
plugins/anti_spam/lib/anti_spam_plugin/wrapper.rb
... ... @@ -2,9 +2,10 @@ class AntiSpamPlugin::Wrapper &lt; SimpleDelegator
2 2 include Rakismet::Model
3 3  
4 4 @@wrappers = []
  5 + cattr_accessor :wrappers
5 6  
6 7 def self.wrap(object)
7   - wrapper = @@wrappers.find { |wrapper| wrapper.wraps?(object) }
  8 + wrapper = wrappers.find { |wrapper| wrapper.wraps?(object) }
8 9 wrapper ? wrapper.new(object) : object
9 10 end
10 11  
... ... @@ -13,6 +14,10 @@ class AntiSpamPlugin::Wrapper &lt; SimpleDelegator
13 14 end
14 15  
15 16 def self.inherited(child)
16   - @@wrappers << child
  17 + wrappers << child
17 18 end
18 19 end
  20 +
  21 +Dir.glob(File.join(AntiSpamPlugin.root_path, 'lib', 'anti_spam_plugin', '*_wrapper.rb')) do |file|
  22 + load(file)
  23 +end
... ...
plugins/community_track/test/functional/community_track_plugin_content_viewer_controller_test.rb
... ... @@ -10,7 +10,7 @@ end
10 10 class ContentViewerControllerTest < ActionController::TestCase
11 11  
12 12 def setup
13   - @profile = fast_create(Community)
  13 + @profile = Community.create!(:name => 'Sample community', :identifier => 'sample-community')
14 14 @track = create_track('track', @profile)
15 15 @step = CommunityTrackPlugin::Step.create!(:name => 'step1', :body => 'body', :profile => @profile, :parent => @track, :published => false, :end_date => Date.today, :start_date => Date.today, :tool_type => TinyMceArticle.name)
16 16  
... ... @@ -87,43 +87,35 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
87 87 end
88 88  
89 89 should 'render a div with block id for track list block' do
90   - box = fast_create(Box, :owner_id => @profile.id, :owner_type => @profile.class.name)
91   - @block = CommunityTrackPlugin::TrackListBlock.create!(:box => box)
92   - @profile.boxes << box
  90 + @block = CommunityTrackPlugin::TrackListBlock.create!(:box => @profile.boxes.last)
93 91 get :view_page, @step.url
94 92 assert_tag :tag => 'div', :attributes => { :class => 'track_list', :id => "track_list_#{@block.id}" }
95 93 end
96 94  
97 95 should 'render a div with block id for track card list block' do
98   - box = fast_create(Box, :owner_id => @profile.id, :owner_type => @profile.class.name)
99   - @block = CommunityTrackPlugin::TrackCardListBlock.create!(:box => box)
100   - @profile.boxes << box
  96 + @block = CommunityTrackPlugin::TrackCardListBlock.create!(:box => @profile.boxes.last)
101 97 get :view_page, @step.url
102 98 assert_tag :tag => 'div', :attributes => { :class => 'track_list', :id => "track_list_#{@block.id}" }
103 99 end
104 100  
105 101 should 'render tracks in track list block' do
106   - box = fast_create(Box, :owner_id => @profile.id, :owner_type => @profile.class.name)
107   - @block = CommunityTrackPlugin::TrackListBlock.create!(:box => box)
108   - @profile.boxes << box
  102 + @block = CommunityTrackPlugin::TrackListBlock.create!(:box => @profile.boxes.last)
109 103 get :view_page, @step.url
  104 + file = File.open('result.html', 'w+')
  105 + file.write(@response.body)
  106 + file.close
110 107 assert_tag :tag => 'div', :attributes => { :class => "item category_#{@track.category_name}" }, :descendant => { :tag => 'div', :attributes => { :class => 'steps' }, :descendant => { :tag => 'span', :attributes => { :class => "step #{@block.status_class(@step)}" } } }
111 108 end
112 109  
113 110 should 'render tracks in track card list block' do
114   - box = fast_create(Box, :owner_id => @profile.id, :owner_type => @profile.class.name)
115   - @block = CommunityTrackPlugin::TrackCardListBlock.create!(:box => box)
116   - @profile.boxes << box
  111 + @block = CommunityTrackPlugin::TrackCardListBlock.create!(:box => @profile.boxes.last)
117 112 get :view_page, @step.url
118 113 assert_tag :tag => 'div', :attributes => { :class => "item_card category_#{@track.category_name}" }, :descendant => { :tag => 'div', :attributes => { :class => 'track_content' } }
119 114 assert_tag :tag => 'div', :attributes => { :class => "item_card category_#{@track.category_name}" }, :descendant => { :tag => 'div', :attributes => { :class => 'track_stats' } }
120 115 end
121 116  
122 117 should 'render link to display more tracks in track list block' do
123   - box = fast_create(Box, :owner_id => @profile.id, :owner_type => @profile.class.name)
124   - @block = CommunityTrackPlugin::TrackCardListBlock.create!(:box => box)
125   - @profile.boxes << box
126   -
  118 + @block = CommunityTrackPlugin::TrackCardListBlock.create!(:box => @profile.boxes.last)
127 119 (@block.limit+1).times { |i| create_track("track#{i}", @profile) }
128 120  
129 121 get :view_page, @step.url
... ... @@ -131,9 +123,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
131 123 end
132 124  
133 125 should 'render link to show all tracks in track list block' do
134   - box = fast_create(Box, :owner_id => @profile.id, :owner_type => @profile.class.name)
135   - @block = CommunityTrackPlugin::TrackCardListBlock.create!(:box => box)
136   - @profile.boxes << box
  126 + @block = CommunityTrackPlugin::TrackCardListBlock.create!(:box => @profile.boxes.last)
137 127 @block.more_another_page = true
138 128 @block.save!
139 129  
... ...
plugins/recent_content/test/unit/recent_content_block_test.rb
... ... @@ -61,9 +61,9 @@ class RecentContentBlockTest &lt; ActiveSupport::TestCase
61 61  
62 62 root = fast_create(Blog, :name => 'test-blog', :profile_id => profile.id)
63 63  
64   - a1 = fast_create(TextileArticle, :name => 'article #1', :profile_id => profile.id, :parent_id => root.id)
65   - a2 = fast_create(TextileArticle, :name => 'article #2', :profile_id => profile.id, :parent_id => root.id)
66   - a3 = fast_create(TextileArticle, :name => 'article #3', :profile_id => profile.id, :parent_id => root.id)
  64 + a1 = fast_create(TextileArticle, :name => 'article #1', :profile_id => profile.id, :parent_id => root.id, :created_at => Time.now - 2.days)
  65 + a2 = fast_create(TextileArticle, :name => 'article #2', :profile_id => profile.id, :parent_id => root.id, :created_at => Time.now - 1.days)
  66 + a3 = fast_create(TextileArticle, :name => 'article #3', :profile_id => profile.id, :parent_id => root.id, :created_at => Time.now)
67 67  
68 68 block = RecentContentBlock.new
69 69 block.stubs(:holder).returns(profile)
... ...
po/eo/noosfero.po
... ... @@ -109,7 +109,7 @@ msgstr &quot;&quot;
109 109 #: app/views/blocks/profile_info_actions/_join_leave_community.rhtml:25
110 110 #: app/views/profile/_private_profile.rhtml:10
111 111 msgid "Join"
112   -msgstr ""
  112 +msgstr "Eniri"
113 113  
114 114 #: app/helpers/application_helper.rb:556
115 115 #: app/views/blocks/profile_info_actions/_join_leave_community.rhtml:4
... ... @@ -290,7 +290,7 @@ msgstr &quot;&quot;
290 290  
291 291 #: app/helpers/application_helper.rb:1088
292 292 msgid "See all"
293   -msgstr ""
  293 +msgstr "Vidi ĉiujn"
294 294  
295 295 #: app/helpers/application_helper.rb:1091
296 296 msgid "<span>Manage</span> %s"
... ... @@ -688,11 +688,11 @@ msgstr &quot;&quot;
688 688  
689 689 #: app/helpers/forum_helper.rb:14 app/helpers/blog_helper.rb:23
690 690 msgid "&laquo; Newer posts"
691   -msgstr ""
  691 +msgstr "&laquo; Pli freŝaj afiŝoj"
692 692  
693 693 #: app/helpers/forum_helper.rb:15 app/helpers/blog_helper.rb:24
694 694 msgid "Older posts &raquo;"
695   -msgstr ""
  695 +msgstr "Malpli freŝaj afiŝoj &raquo"
696 696  
697 697 #: app/helpers/forum_helper.rb:18
698 698 msgid "Discussion topic"
... ... @@ -774,63 +774,63 @@ msgstr &quot;&quot;
774 774 #: app/helpers/dates_helper.rb:7 app/helpers/forms_helper.rb:172
775 775 #: plugins/display_content/lib/display_content_block.rb:4
776 776 msgid "January"
777   -msgstr ""
  777 +msgstr "Januaro"
778 778  
779 779 #: app/helpers/dates_helper.rb:8 app/helpers/forms_helper.rb:172
780 780 #: plugins/display_content/lib/display_content_block.rb:5
781 781 msgid "February"
782   -msgstr ""
  782 +msgstr "Februaro"
783 783  
784 784 #: app/helpers/dates_helper.rb:9 app/helpers/forms_helper.rb:172
785 785 #: plugins/display_content/lib/display_content_block.rb:6
786 786 msgid "March"
787   -msgstr ""
  787 +msgstr "Marto"
788 788  
789 789 #: app/helpers/dates_helper.rb:10 app/helpers/forms_helper.rb:172
790 790 #: plugins/display_content/lib/display_content_block.rb:7
791 791 msgid "April"
792   -msgstr ""
  792 +msgstr "Aprilo"
793 793  
794 794 #: app/helpers/dates_helper.rb:11 app/helpers/forms_helper.rb:172
795 795 #: app/helpers/forms_helper.rb:173
796 796 #: plugins/display_content/lib/display_content_block.rb:8
797 797 msgid "May"
798   -msgstr ""
  798 +msgstr "Majo"
799 799  
800 800 #: app/helpers/dates_helper.rb:12 app/helpers/forms_helper.rb:172
801 801 #: plugins/display_content/lib/display_content_block.rb:9
802 802 msgid "June"
803   -msgstr ""
  803 +msgstr "Junio"
804 804  
805 805 #: app/helpers/dates_helper.rb:13 app/helpers/forms_helper.rb:172
806 806 #: plugins/display_content/lib/display_content_block.rb:10
807 807 msgid "July"
808   -msgstr ""
  808 +msgstr "Julio"
809 809  
810 810 #: app/helpers/dates_helper.rb:14 app/helpers/forms_helper.rb:172
811 811 #: plugins/display_content/lib/display_content_block.rb:11
812 812 msgid "August"
813   -msgstr ""
  813 +msgstr "Aŭgusto"
814 814  
815 815 #: app/helpers/dates_helper.rb:15 app/helpers/forms_helper.rb:172
816 816 #: plugins/display_content/lib/display_content_block.rb:12
817 817 msgid "September"
818   -msgstr ""
  818 +msgstr "Septembro"
819 819  
820 820 #: app/helpers/dates_helper.rb:16 app/helpers/forms_helper.rb:172
821 821 #: plugins/display_content/lib/display_content_block.rb:13
822 822 msgid "October"
823   -msgstr ""
  823 +msgstr "Oktobro"
824 824  
825 825 #: app/helpers/dates_helper.rb:17 app/helpers/forms_helper.rb:172
826 826 #: plugins/display_content/lib/display_content_block.rb:14
827 827 msgid "November"
828   -msgstr ""
  828 +msgstr "Novembro"
829 829  
830 830 #: app/helpers/dates_helper.rb:18 app/helpers/forms_helper.rb:172
831 831 #: plugins/display_content/lib/display_content_block.rb:15
832 832 msgid "December"
833   -msgstr ""
  833 +msgstr "Decembro"
834 834  
835 835 #: app/helpers/dates_helper.rb:28
836 836 #: plugins/display_content/lib/display_content_block.rb:156
... ... @@ -845,7 +845,7 @@ msgstr &quot;&quot;
845 845 #: app/helpers/dates_helper.rb:31
846 846 #: plugins/display_content/lib/display_content_block.rb:159
847 847 msgid "%{month_name} %{day}, %{year}"
848   -msgstr ""
  848 +msgstr "La %{day}-a de %{month_name} %{year}"
849 849  
850 850 #: app/helpers/dates_helper.rb:31
851 851 #: plugins/display_content/lib/display_content_block.rb:159
... ... @@ -8278,7 +8278,7 @@ msgstr &quot;&quot;
8278 8278  
8279 8279 #: app/views/account/index_anonymous.rhtml:10
8280 8280 msgid "Sign up."
8281   -msgstr ""
  8281 +msgstr "Aliĝi"
8282 8282  
8283 8283 #: app/views/account/index_anonymous.rhtml:11
8284 8284 msgid ""
... ...
po/es/noosfero.po
... ... @@ -291,7 +291,6 @@ msgid &quot;Next&quot;
291 291 msgstr "Siguiente"
292 292  
293 293 #: app/helpers/application_helper.rb:1088
294   -#, fuzzy
295 294 msgid "See all"
296 295 msgstr "Ver todos"
297 296  
... ... @@ -700,11 +699,11 @@ msgstr &quot;Configurar foro&quot;
700 699  
701 700 #: app/helpers/forum_helper.rb:14 app/helpers/blog_helper.rb:23
702 701 msgid "&laquo; Newer posts"
703   -msgstr "&laquo; Entradas recientes"
  702 +msgstr "&laquo; Noticias más nuevas"
704 703  
705 704 #: app/helpers/forum_helper.rb:15 app/helpers/blog_helper.rb:24
706 705 msgid "Older posts &raquo;"
707   -msgstr "Entradas antiguas &raquo;"
  706 +msgstr "Noticias más viejas &raquo;"
708 707  
709 708 #: app/helpers/forum_helper.rb:18
710 709 msgid "Discussion topic"
... ... @@ -852,15 +851,13 @@ msgstr &quot;%{day} de %{month} %{year}&quot;
852 851  
853 852 #: app/helpers/dates_helper.rb:28 app/helpers/dates_helper.rb:40
854 853 #: plugins/display_content/lib/display_content_block.rb:156
855   -#, fuzzy
856 854 msgid "%{month}/%{day}"
857   -msgstr "%{day} de %{month} %{year}"
  855 +msgstr "%{day}/%{month}"
858 856  
859 857 #: app/helpers/dates_helper.rb:31
860 858 #: plugins/display_content/lib/display_content_block.rb:159
861   -#, fuzzy
862 859 msgid "%{month_name} %{day}, %{year}"
863   -msgstr "%{day} de %{month} %{year}"
  860 +msgstr "%{day} de %{month} de %{year}"
864 861  
865 862 # LAs cadenas de este tipo NO se traducen
866 863 #: app/helpers/dates_helper.rb:31
... ... @@ -888,21 +885,19 @@ msgstr &quot;%{month} %{year}&quot;
888 885  
889 886 #: app/helpers/dates_helper.rb:53
890 887 msgid "%{day} %{month} %{year}, %{hour}:%{minutes}"
891   -msgstr "%{day} %{month} %{year}, %{hour}:%{minutes}"
  888 +msgstr "%{day} de %{month} de %{year}, %{hour}:%{minutes}"
892 889  
893 890 #: app/helpers/dates_helper.rb:65
894   -#, fuzzy
895 891 msgid "from %{month} %{day1} to %{day2}, %{year}"
896   -msgstr "%{day} de %{month} %{year}"
  892 +msgstr "de %{day1} para %{day2} de %{month} de %{year}"
897 893  
898 894 #: app/helpers/dates_helper.rb:72
899   -#, fuzzy
900 895 msgid "from %{date1} to %{date2}, %{year}"
901   -msgstr "Por %{author} el %{date}"
  896 +msgstr "de %{date1} para %{date2} de %{year}"
902 897  
903 898 #: app/helpers/dates_helper.rb:79
904 899 msgid "from %{date1} to %{date2}"
905   -msgstr "Por %{author} el %{date}"
  900 +msgstr "de %{date1} para %{date2}"
906 901  
907 902 #: app/helpers/dates_helper.rb:89 app/helpers/forms_helper.rb:163
908 903 msgid "Sun"
... ...
po/it/noosfero.po
... ... @@ -111,7 +111,7 @@ msgstr &quot;&quot;
111 111 #: app/views/blocks/profile_info_actions/_join_leave_community.rhtml:25
112 112 #: app/views/profile/_private_profile.rhtml:10
113 113 msgid "Join"
114   -msgstr ""
  114 +msgstr "Accedere"
115 115  
116 116 #: app/helpers/application_helper.rb:556
117 117 #: app/views/blocks/profile_info_actions/_join_leave_community.rhtml:4
... ... @@ -763,63 +763,63 @@ msgstr &quot;&quot;
763 763 #: app/helpers/dates_helper.rb:7 app/helpers/forms_helper.rb:172
764 764 #: plugins/display_content/lib/display_content_block.rb:4
765 765 msgid "January"
766   -msgstr ""
  766 +msgstr "gennaio"
767 767  
768 768 #: app/helpers/dates_helper.rb:8 app/helpers/forms_helper.rb:172
769 769 #: plugins/display_content/lib/display_content_block.rb:5
770 770 msgid "February"
771   -msgstr ""
  771 +msgstr "febbraio"
772 772  
773 773 #: app/helpers/dates_helper.rb:9 app/helpers/forms_helper.rb:172
774 774 #: plugins/display_content/lib/display_content_block.rb:6
775 775 msgid "March"
776   -msgstr ""
  776 +msgstr "marzo"
777 777  
778 778 #: app/helpers/dates_helper.rb:10 app/helpers/forms_helper.rb:172
779 779 #: plugins/display_content/lib/display_content_block.rb:7
780 780 msgid "April"
781   -msgstr ""
  781 +msgstr "aprile"
782 782  
783 783 #: app/helpers/dates_helper.rb:11 app/helpers/forms_helper.rb:172
784 784 #: app/helpers/forms_helper.rb:173
785 785 #: plugins/display_content/lib/display_content_block.rb:8
786 786 msgid "May"
787   -msgstr ""
  787 +msgstr "maggio"
788 788  
789 789 #: app/helpers/dates_helper.rb:12 app/helpers/forms_helper.rb:172
790 790 #: plugins/display_content/lib/display_content_block.rb:9
791 791 msgid "June"
792   -msgstr ""
  792 +msgstr "giugno"
793 793  
794 794 #: app/helpers/dates_helper.rb:13 app/helpers/forms_helper.rb:172
795 795 #: plugins/display_content/lib/display_content_block.rb:10
796 796 msgid "July"
797   -msgstr ""
  797 +msgstr "luglio"
798 798  
799 799 #: app/helpers/dates_helper.rb:14 app/helpers/forms_helper.rb:172
800 800 #: plugins/display_content/lib/display_content_block.rb:11
801 801 msgid "August"
802   -msgstr ""
  802 +msgstr "agosto"
803 803  
804 804 #: app/helpers/dates_helper.rb:15 app/helpers/forms_helper.rb:172
805 805 #: plugins/display_content/lib/display_content_block.rb:12
806 806 msgid "September"
807   -msgstr ""
  807 +msgstr "settembre"
808 808  
809 809 #: app/helpers/dates_helper.rb:16 app/helpers/forms_helper.rb:172
810 810 #: plugins/display_content/lib/display_content_block.rb:13
811 811 msgid "October"
812   -msgstr ""
  812 +msgstr "ottobre"
813 813  
814 814 #: app/helpers/dates_helper.rb:17 app/helpers/forms_helper.rb:172
815 815 #: plugins/display_content/lib/display_content_block.rb:14
816 816 msgid "November"
817   -msgstr ""
  817 +msgstr "novembre"
818 818  
819 819 #: app/helpers/dates_helper.rb:18 app/helpers/forms_helper.rb:172
820 820 #: plugins/display_content/lib/display_content_block.rb:15
821 821 msgid "December"
822   -msgstr ""
  822 +msgstr "dicembre"
823 823  
824 824 #: app/helpers/dates_helper.rb:28
825 825 #: plugins/display_content/lib/display_content_block.rb:156
... ... @@ -834,7 +834,7 @@ msgstr &quot;&quot;
834 834 #: app/helpers/dates_helper.rb:31
835 835 #: plugins/display_content/lib/display_content_block.rb:159
836 836 msgid "%{month_name} %{day}, %{year}"
837   -msgstr ""
  837 +msgstr "%{day} %{month_name} %{year}"
838 838  
839 839 #: app/helpers/dates_helper.rb:31
840 840 #: plugins/display_content/lib/display_content_block.rb:159
... ... @@ -8246,7 +8246,7 @@ msgstr &quot;&quot;
8246 8246  
8247 8247 #: app/views/account/index_anonymous.rhtml:10
8248 8248 msgid "Sign up."
8249   -msgstr ""
  8249 +msgstr "Registro"
8250 8250  
8251 8251 #: app/views/account/index_anonymous.rhtml:11
8252 8252 msgid ""
... ...
public/stylesheets/application.css
... ... @@ -3561,9 +3561,10 @@ div#article-parent {
3561 3561 }
3562 3562 #agenda .agenda-calendar {
3563 3563 width: 50%;
  3564 + display: inline-block;
3564 3565 }
3565 3566 #agenda td, #agenda th {
3566   - padding: 15px;
  3567 + padding: 10px;
3567 3568 padding-right: 0px;
3568 3569 }
3569 3570 #agenda .agenda-calendar .previous-month td, #agenda .agenda-calendar .previous-month th, #agenda .agenda-calendar .next-month td, #agenda .agenda-calendar .next-month th {
... ... @@ -3621,26 +3622,25 @@ div#article-parent {
3621 3622 vertical-align: middle;
3622 3623 }
3623 3624 #agenda .agenda-calendar .current-month caption {
3624   - margin-bottom: 10px;
  3625 + margin: 10px 0px;
3625 3626 }
3626 3627 #agenda #events-of-the-day {
3627   - position: absolute;
3628   - left: 50%;
3629 3628 width: 45%;
3630   - top: 0px;
3631 3629 height: 100%;
3632 3630 padding-left: 20px;
  3631 + display: inline-block;
  3632 + vertical-align: top;
3633 3633 }
3634 3634 #agenda #events-of-the-day #agenda-items {
3635 3635 display: block;
3636 3636 overflow: auto;
3637 3637 overflow-x: hidden;
3638   - height: 80%;
  3638 + height: 250px;
3639 3639 background: white;
3640 3640 border: none;
3641 3641 }
3642 3642 #agenda-toolbar {
3643   - float: right;
  3643 + text-align: right;
3644 3644 font-variant: normal;
3645 3645 font-weight: normal;
3646 3646 }
... ... @@ -3663,6 +3663,9 @@ h1#agenda-title {
3663 3663 display: block;
3664 3664 margin-top: 10px;
3665 3665 }
  3666 +#agenda .pagination {
  3667 + margin-top: 15px;
  3668 +}
3666 3669 /* ==> public/stylesheets/controller_favorite_enterprises.css <== */
3667 3670  
3668 3671 /* ==> @import url(manage_contacts_list.css); <== */
... ...
test/functional/content_viewer_controller_test.rb
... ... @@ -72,9 +72,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
72 72 get :view_page, :profile => 'someone', :page => [ '500.html' ]
73 73  
74 74 assert_response :success
75   - assert_match /^text\/html/, @response.headers['Content-Type']
76   - assert @response.headers['Content-Disposition'].present?
77   - assert_match /attachment/, @response.headers['Content-Disposition']
  75 + assert_match /#{html.public_filename}/, @response.body
78 76 end
79 77  
80 78 should 'produce a download-link when article is not text/html' do
... ... @@ -577,14 +575,6 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
577 575 assert_template 'view_page'
578 576 end
579 577  
580   - should 'download data for image when not view' do
581   - file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :profile => profile)
582   - get :view_page, :profile => profile.identifier, :page => file.explode_path
583   -
584   - assert_response :success
585   - assert_template nil
586   - end
587   -
588 578 should "display 'Upload files' when create children of image gallery" do
589 579 login_as(profile.identifier)
590 580 f = Gallery.create!(:name => 'gallery', :profile => profile)
... ... @@ -1355,8 +1345,23 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1355 1345  
1356 1346 should 'display link to download of non-recognized file types on its page' do
1357 1347 file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/test.txt', 'bin/unknown'), :profile => profile)
1358   - get :view_page, file.url.merge(:view=>:true)
1359   - assert_match /this is a sample text file/, @response.body
  1348 + get :view_page, file.url
  1349 + assert_match /#{file.public_filename}/, @response.body
  1350 + end
  1351 +
  1352 + should 'not count hit from bots' do
  1353 + article = fast_create(Article, :profile_id => profile.id)
  1354 + assert_no_difference article, :hits do
  1355 + @request.env['HTTP_USER_AGENT'] = 'bot'
  1356 + get 'view_page', :profile => profile.identifier, :page => article.path.split('/')
  1357 + @request.env['HTTP_USER_AGENT'] = 'spider'
  1358 + get 'view_page', :profile => profile.identifier, :page => article.path.split('/')
  1359 + @request.env['HTTP_USER_AGENT'] = 'crawler'
  1360 + get 'view_page', :profile => profile.identifier, :page => article.path.split('/')
  1361 + @request.env['HTTP_USER_AGENT'] = '(http://some-crawler.com)'
  1362 + get 'view_page', :profile => profile.identifier, :page => article.path.split('/')
  1363 + article.reload
  1364 + end
1360 1365 end
1361 1366  
1362 1367 should 'add meta tags with article info' do
... ...
test/functional/events_controller_test.rb
... ... @@ -38,4 +38,12 @@ class EventsControllerTest &lt; ActionController::TestCase
38 38 assert_tag :tag =>'a', :attributes => {:href => "/profile/#{profile.identifier}/events/#{next_month.year}/#{next_month.month}"}, :content => next_month_name
39 39 end
40 40  
  41 + should 'see the events paginated' do
  42 + 30.times do |i|
  43 + profile.events << Event.new(:name => "Lesson #{i}", :start_date => Date.today)
  44 + end
  45 + get :events, :profile => profile.identifier
  46 + assert_equal 20, assigns(:events).count
  47 + end
  48 +
41 49 end
... ...
test/functional/search_controller_test.rb
... ... @@ -370,6 +370,15 @@ class SearchControllerTest &lt; ActionController::TestCase
370 370 assert_equal [ 'upcoming event 1' ], assigns(:searches)[:events][:results].map(&:name)
371 371 end
372 372  
  373 + should 'see the events paginated' do
  374 + person = create_user('testuser').person
  375 + 30.times do |i|
  376 + create_event(person, :name => "Event #{i}", :start_date => Date.today)
  377 + end
  378 + get :events
  379 + assert_equal 20, assigns(:events).count
  380 + end
  381 +
373 382 %w[ people enterprises articles events communities products ].each do |asset|
374 383 should "render asset-specific template when searching for #{asset}" do
375 384 get "#{asset}"
... ...
test/unit/block_test.rb
... ... @@ -222,4 +222,11 @@ class BlockTest &lt; ActiveSupport::TestCase
222 222 assert block.visible?(2)
223 223 assert !block.visible?(3)
224 224 end
  225 +
  226 + should 'accept user as parameter on cache_key without change its value' do
  227 + person = fast_create(Person)
  228 + block = Block.new
  229 + assert_equal block.cache_key('en'), block.cache_key('en', person)
  230 + end
  231 +
225 232 end
... ...
test/unit/members_block_test.rb
... ... @@ -35,4 +35,28 @@ class MembersBlockTest &lt; ActiveSupport::TestCase
35 35 assert_same list, block.profiles
36 36 end
37 37  
  38 + should 'use logged-in to compose cache key' do
  39 + person = fast_create(Person)
  40 + community = fast_create(Community)
  41 + block = MembersBlock.create
  42 + block.expects(:owner).returns(community)
  43 +
  44 + assert_match(/-logged-in/,block.cache_key('en', person))
  45 + end
  46 +
  47 + should 'use logged-in and member to compose cache key for members' do
  48 + person = fast_create(Person)
  49 + community = fast_create(Community)
  50 + community.add_member person
  51 + block = MembersBlock.create
  52 + block.expects(:owner).returns(community)
  53 +
  54 + assert_match(/-logged-in-member/,block.cache_key('en', person))
  55 + end
  56 +
  57 + should 'not change block cache key if user is nil' do
  58 + block = MembersBlock.new
  59 + assert_equal block.cache_key('en'), block.cache_key('en', nil)
  60 + end
  61 +
38 62 end
... ...
test/unit/tags_helper_test.rb
... ... @@ -20,12 +20,14 @@ class TagsHelperTest &lt; ActiveSupport::TestCase
20 20  
21 21 should 'order tags alphabetically with special characters' do
22 22 result = tag_cloud(
23   - { 'aula'=>9, 'área'=>2, 'area'=>2, 'avião'=>2, 'armário'=>2,
24   - 'A'=>1, 'Á'=>1, 'AB'=>1, 'ÁA'=>1 },
  23 + { 'area'=>9, 'área'=>2, 'base'=>2, 'báse' => 3,
  24 + 'A'=>1, 'Á'=>1, 'zebra'=>1, 'zebrá'=>1 },
25 25 :id,
26 26 { :host=>'noosfero.org', :controller=>'test', :action=>'tag' }
27 27 )
28   - assert_equal %w(A Á ÁA AB area área armário aula avião).join("\n"), result
  28 + result = result.split("\n")
  29 + assert_order ['Á', 'área', 'báse', 'zebrá'], result
  30 + assert_order ['A', 'area', 'base', 'zebra'], result
29 31 end
30 32  
31 33 end
... ...