Commit da4b277d048cee258e8d174df2eb243dc20136d4

Authored by Leandro Santos
2 parents 08b24ad2 a5c0c0f3

Merge branches 'rails235' and 'noosfero_grape_api' into noosfero_grape_api

Showing 60 changed files with 1197 additions and 225 deletions   Show diff stats
app/controllers/embed_controller.rb 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +class EmbedController < ApplicationController
  2 + layout 'embed'
  3 +
  4 + def block
  5 + @block = Block.find(params[:id])
  6 + if !@block.embedable? || !@block.visible?
  7 + render 'unavailable.rhtml', :status => 403
  8 + end
  9 + rescue ActiveRecord::RecordNotFound
  10 + render 'not_found.rhtml', :status => 404
  11 + end
  12 +
  13 +end
app/controllers/my_profile/maps_controller.rb
@@ -31,23 +31,11 @@ class MapsController &lt; MyProfileController @@ -31,23 +31,11 @@ class MapsController &lt; MyProfileController
31 end 31 end
32 32
33 def search_city 33 def search_city
34 -  
35 - term = params[:term];  
36 -  
37 - regions = NationalRegion.search_city(term + "%", true).map {|r|{ :label => r.city , :category => r.state}}  
38 -  
39 - render :json => regions  
40 - 34 + render :json => MapsHelper.search_city(params[:term])
41 end 35 end
42 36
43 def search_state 37 def search_state
44 -  
45 - term = params[:term];  
46 -  
47 - regions = NationalRegion.search_state(term + "%", true).map {|r|{ :label => r.state}}  
48 -  
49 - render :json => regions  
50 - 38 + render :json => MapsHelper.search_state(params[:term])
51 end 39 end
52 40
53 end 41 end
app/controllers/public/account_controller.rb
@@ -250,15 +250,19 @@ class AccountController &lt; ApplicationController @@ -250,15 +250,19 @@ class AccountController &lt; ApplicationController
250 end 250 end
251 end 251 end
252 252
253 - def check_url 253 + def check_valid_name
254 @identifier = params[:identifier] 254 @identifier = params[:identifier]
255 valid = Person.is_available?(@identifier, environment) 255 valid = Person.is_available?(@identifier, environment)
256 if valid 256 if valid
257 @status = _('This login name is available') 257 @status = _('This login name is available')
258 @status_class = 'validated' 258 @status_class = 'validated'
259 - else 259 + elsif !@identifier.empty?
  260 + @suggested_usernames = suggestion_based_on_username(@identifier)
260 @status = _('This login name is unavailable') 261 @status = _('This login name is unavailable')
261 @status_class = 'invalid' 262 @status_class = 'invalid'
  263 + else
  264 + @status_class = 'invalid'
  265 + @status = _('This field can\'t be blank')
262 end 266 end
263 render :partial => 'identifier_status' 267 render :partial => 'identifier_status'
264 end 268 end
@@ -291,6 +295,23 @@ class AccountController &lt; ApplicationController @@ -291,6 +295,23 @@ class AccountController &lt; ApplicationController
291 render :text => user_data.to_json, :layout => false, :content_type => "application/javascript" 295 render :text => user_data.to_json, :layout => false, :content_type => "application/javascript"
292 end 296 end
293 297
  298 + def search_cities
  299 + if request.xhr? and params[:state_name] and params[:city_name]
  300 + render :json => MapsHelper.search_city(params[:city_name], params[:state_name])
  301 + else
  302 + render :json => [].to_json
  303 + end
  304 + end
  305 +
  306 + def search_state
  307 + if request.xhr? and params[:state_name]
  308 + render :json => MapsHelper.search_state(params[:state_name])
  309 + else
  310 + render :json => [].to_json
  311 + end
  312 + end
  313 +
  314 +
294 protected 315 protected
295 316
296 def redirect? 317 def redirect?
app/controllers/public/content_viewer_controller.rb
@@ -50,7 +50,7 @@ class ContentViewerController &lt; ApplicationController @@ -50,7 +50,7 @@ class ContentViewerController &lt; ApplicationController
50 end 50 end
51 51
52 # At this point the page will be showed 52 # At this point the page will be showed
53 - @page.hit 53 + @page.hit unless user_is_a_bot?
54 54
55 @page = FilePresenter.for @page 55 @page = FilePresenter.for @page
56 56
@@ -183,4 +183,13 @@ class ContentViewerController &lt; ApplicationController @@ -183,4 +183,13 @@ class ContentViewerController &lt; ApplicationController
183 allowed 183 allowed
184 end 184 end
185 185
  186 + def user_is_a_bot?
  187 + user_agent= request.env["HTTP_USER_AGENT"]
  188 + user_agent.blank? ||
  189 + user_agent.match(/bot/) ||
  190 + user_agent.match(/spider/) ||
  191 + user_agent.match(/crawler/) ||
  192 + user_agent.match(/\(.*https?:\/\/.*\)/)
  193 + end
  194 +
186 end 195 end
app/controllers/public/events_controller.rb
@@ -21,7 +21,7 @@ class EventsController &lt; PublicController @@ -21,7 +21,7 @@ class EventsController &lt; PublicController
21 21
22 def events_by_day 22 def events_by_day
23 @date = build_date(params[:year], params[:month], params[:day]) 23 @date = build_date(params[:year], params[:month], params[:day])
24 - @events = profile.events.by_day(@date) 24 + @events = profile.events.by_day(@date).paginate(:per_page => per_page, :page => params[:page])
25 render :partial => 'events' 25 render :partial => 'events'
26 end 26 end
27 27
app/helpers/account_helper.rb
@@ -12,4 +12,17 @@ module AccountHelper @@ -12,4 +12,17 @@ module AccountHelper
12 _('Checking if e-mail address is already taken...') 12 _('Checking if e-mail address is already taken...')
13 end 13 end
14 end 14 end
  15 +
  16 + def suggestion_based_on_username(requested_username='')
  17 + return "" if requested_username.empty?
  18 + usernames = []
  19 + 3.times do
  20 + begin
  21 + valid_name = requested_username + rand(1000).to_s
  22 + end while (usernames.include?(valid_name) || !Person.is_available?(valid_name, environment))
  23 + usernames << valid_name
  24 + end
  25 + usernames
  26 + end
  27 +
15 end 28 end
app/helpers/boxes_helper.rb
@@ -219,6 +219,17 @@ module BoxesHelper @@ -219,6 +219,17 @@ module BoxesHelper
219 buttons << thickbox_inline_popup_icon(:help, _('Help on this block'), {}, "help-on-box-#{block.id}") << content_tag('div', content_tag('h2', _('Help')) + content_tag('div', block.help, :style => 'margin-bottom: 1em;') + thickbox_close_button(_('Close')), :style => 'display: none;', :id => "help-on-box-#{block.id}") 219 buttons << thickbox_inline_popup_icon(:help, _('Help on this block'), {}, "help-on-box-#{block.id}") << content_tag('div', content_tag('h2', _('Help')) + content_tag('div', block.help, :style => 'margin-bottom: 1em;') + thickbox_close_button(_('Close')), :style => 'display: none;', :id => "help-on-box-#{block.id}")
220 end 220 end
221 221
  222 + if block.embedable?
  223 + embed_code = block.embed_code
  224 + embed_code = instance_eval(&embed_code) if embed_code.respond_to?(:call)
  225 + html = content_tag('div',
  226 + content_tag('h2', _('Embed block code')) +
  227 + content_tag('div', _('Below, you''ll see a field containing embed code for the block. Just copy the code and paste it into your website or blogging software.'), :style => 'margin-bottom: 1em;') +
  228 + content_tag('textarea', embed_code, :style => 'margin-bottom: 1em; width:100%; height:40%;', :readonly => 'readonly') +
  229 + thickbox_close_button(_('Close')), :style => 'display: none;', :id => "embed-code-box-#{block.id}")
  230 + buttons << thickbox_inline_popup_icon(:embed, _('Embed code'), {}, "embed-code-box-#{block.id}") << html
  231 + end
  232 +
222 content_tag('div', buttons.join("\n") + tag('br', :style => 'clear: left'), :class => 'button-bar') 233 content_tag('div', buttons.join("\n") + tag('br', :style => 'clear: left'), :class => 'button-bar')
223 end 234 end
224 235
app/helpers/maps_helper.rb 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +module MapsHelper
  2 + def self.search_city term, state=""
  3 + cities = if state.empty?
  4 + NationalRegion.search_city(term + "%", true)
  5 + else
  6 + NationalRegion.search_city(term + "%", true, state)
  7 + end
  8 + cities.map {|r|{ :label => r.city , :category => r.state}}
  9 + end
  10 +
  11 + def self.search_state term
  12 + NationalRegion.search_state(term + "%", true).map {|r|{ :label => r.state}}
  13 + end
  14 +end
app/models/block.rb
@@ -16,6 +16,23 @@ class Block &lt; ActiveRecord::Base @@ -16,6 +16,23 @@ class Block &lt; ActiveRecord::Base
16 16
17 named_scope :enabled, :conditions => { :enabled => true } 17 named_scope :enabled, :conditions => { :enabled => true }
18 18
  19 + def embedable?
  20 + false
  21 + end
  22 +
  23 + def embed_code
  24 + me = self
  25 + lambda do
  26 + content_tag('iframe', '',
  27 + :src => url_for(:controller => 'embed', :action => 'block', :id => me.id, :only_path => false),
  28 + :frameborder => 0,
  29 + :width => 1024,
  30 + :height => 768,
  31 + :class => "embed block #{me.class.name.to_css_class}"
  32 + )
  33 + end
  34 + end
  35 +
19 # Determines whether a given block must be visible. Optionally a 36 # Determines whether a given block must be visible. Optionally a
20 # <tt>context</tt> must be specified. <tt>context</tt> must be a hash, and 37 # <tt>context</tt> must be specified. <tt>context</tt> must be a hash, and
21 # may contain the following keys: 38 # may contain the following keys:
app/models/national_region.rb
@@ -12,7 +12,7 @@ class NationalRegion &lt; ActiveRecord::Base @@ -12,7 +12,7 @@ class NationalRegion &lt; ActiveRecord::Base
12 adtional_contions = ""; 12 adtional_contions = "";
13 13
14 if like 14 if like
15 - operator = "like" 15 + operator = "ilike"
16 find_return = :all 16 find_return = :all
17 end 17 end
18 18
@@ -41,7 +41,7 @@ class NationalRegion &lt; ActiveRecord::Base @@ -41,7 +41,7 @@ class NationalRegion &lt; ActiveRecord::Base
41 find_return = :first 41 find_return = :first
42 42
43 if like 43 if like
44 - operator = "like" 44 + operator = "ilike"
45 find_return = :all 45 find_return = :all
46 end 46 end
47 47
app/models/text_article.rb
@@ -20,4 +20,23 @@ class TextArticle &lt; Article @@ -20,4 +20,23 @@ class TextArticle &lt; Article
20 def can_display_versions? 20 def can_display_versions?
21 true 21 true
22 end 22 end
  23 +
  24 + before_save :set_relative_path
  25 +
  26 + def set_relative_path
  27 + parsed = Hpricot(self.body.to_s)
  28 + parsed.search('img[@src]').map { |i| change_element_path(i, 'src') }
  29 + parsed.search('a[@href]').map { |i| change_element_path(i, 'href') }
  30 + self.body = parsed.to_s
  31 + end
  32 +
  33 + def change_element_path(el, attribute)
  34 + fullpath = /(https?):\/\/(#{environment.default_hostname})(:\d+)?(\/.*)/.match(el[attribute])
  35 + if fullpath
  36 + domain = fullpath[2]
  37 + path = fullpath[4]
  38 + el[attribute] = path if domain == environment.default_hostname
  39 + end
  40 + end
  41 +
23 end 42 end
app/views/account/_identifier_status.rhtml
1 <div class='status-identifier'> 1 <div class='status-identifier'>
2 - <p><span class='<%= @status_class %>'><%= @status %></span></p> 2 +
  3 + <span class='<%= @status_class %>'><%= @status %></span>
  4 + <% if @suggested_usernames %>
  5 + <div class='suggested_usernames'>
  6 + <%= _('Available: ') %>
  7 + <% @suggested_usernames.each do |username| %>
  8 + <a href='#'><%= username %></a>
  9 + <% end %>
  10 + </div>
  11 + <% end %>
3 <script type="text/javascript"> 12 <script type="text/javascript">
4 jQuery('#user_login').removeClass('<%= validation_classes %>'); 13 jQuery('#user_login').removeClass('<%= validation_classes %>');
5 jQuery('#user_login').addClass('<%= @status_class %>'); 14 jQuery('#user_login').addClass('<%= @status_class %>');
  15 + jQuery('.suggested_usernames a').click(function(e) {
  16 + e.preventDefault();
  17 +
  18 + fill_username(this.innerHTML);
  19 + });
6 </script> 20 </script>
7 </div> 21 </div>
app/views/account/_signup_form.rhtml
@@ -37,20 +37,13 @@ @@ -37,20 +37,13 @@
37 <%= required text_field(:user, :login, :id => 'user_login', 37 <%= required text_field(:user, :login, :id => 'user_login',
38 :onchange => 'this.value = convToValidUsername(this.value);') %> 38 :onchange => 'this.value = convToValidUsername(this.value);') %>
39 <div id='url-check'><p>&nbsp;</p></div> 39 <div id='url-check'><p>&nbsp;</p></div>
  40 + <span id='checking-message' class='checking' style='display:none'><%= _('Checking availability of login name...') %></span>
40 </div> 41 </div>
41 <%= content_tag(:small, _('Choose your login name carefully! It will be your network access and you will not be able to change it later.'), :id => 'signup-balloon') %> 42 <%= content_tag(:small, _('Choose your login name carefully! It will be your network access and you will not be able to change it later.'), :id => 'signup-balloon') %>
42 <br style="clear: both;" /> 43 <br style="clear: both;" />
43 </div> 44 </div>
44 </div> 45 </div>
45 - <%= observe_field 'user_login',  
46 - :url => { :action => 'check_url' },  
47 - :with => 'identifier',  
48 - :update => 'url-check',  
49 - :loading => "jQuery('#user_login').removeClass('#{validation_classes}').addClass('checking');  
50 - jQuery('#url-check').html('<p><span class=\"checking\">#{checking_message(:url)}</span></p>');",  
51 - :complete => "jQuery('#user_login').removeClass('checking')"  
52 - %>  
53 - 46 + <%= javascript_include_tag "signup_form" %>
54 <div id='signup-password'> 47 <div id='signup-password'>
55 <%= required f.password_field(:password, :id => 'user_pw') %> 48 <%= required f.password_field(:password, :id => 'user_pw') %>
56 <%= content_tag(:small,_('Choose a password that you can remember easily. It must have at least 4 characters.'), :id => 'password-balloon') %> 49 <%= content_tag(:small,_('Choose a password that you can remember easily. It must have at least 4 characters.'), :id => 'password-balloon') %>
@@ -198,4 +191,8 @@ jQuery(function($) { @@ -198,4 +191,8 @@ jQuery(function($) {
198 }); 191 });
199 }); 192 });
200 193
  194 +function fill_username(element){
  195 + jQuery('#url-check').html("<p><span class='checking'><%= _('This login name is available') %></span></p>")
  196 + jQuery('#user_login').val(element).addClass('validated').removeClass('invalid')
  197 +}
201 </script> 198 </script>
app/views/embed/block.html.erb 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= display_block(@block) %>
app/views/embed/not_found.rhtml 0 → 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 +<div id='not-found'>
  2 + <p>
  3 + <%= _('You may have clicked an expired link or mistyped the address.') %>
  4 + <%= _('If you clicked a link that was in another site, or was given to you by someone else, it would be nice if you tell them that their link is not valid anymore.') %>
  5 + </p>
  6 +</div>
app/views/embed/unavailable.rhtml 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +<div id='unavailable'>
  2 + <p><%= _('Embed unavailable.') %></p>
  3 +</div>
app/views/layouts/embed.rhtml 0 → 100644
@@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
  1 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%= html_language %>" lang="<%= html_language %>">
  3 + <head>
  4 + <title>Noosfero embed block</title>
  5 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  6 + <%= noosfero_stylesheets %>
  7 + <%= noosfero_javascript %>
  8 + </head>
  9 + <body class="<%= h body_classes %>">
  10 + <div id="embed">
  11 + <div id="wrap-1">
  12 + <div id="wrap-2">
  13 + <div id="content">
  14 + <div id="content-inner">
  15 + <div class="boxes" id="boxes">
  16 + <div class="box box-1" id="box-1">
  17 + <div class="blocks">
  18 + <%= yield %>
  19 + </div>
  20 + </div>
  21 + </div>
  22 + </div>
  23 + </div>
  24 + </div>
  25 + </div>
  26 + </div>
  27 +
  28 + <script type="text/javascript">
  29 + jQuery(document).ready(function(){
  30 + jQuery('a').attr('target','_blank');
  31 + });
  32 + </script>
  33 +
  34 + </body>
  35 +</html>
app/views/profile_editor/_person_form.rhtml
@@ -19,8 +19,8 @@ @@ -19,8 +19,8 @@
19 <%= optional_field(@person, 'birth_date', labelled_form_field(_('Birth date'), '<div class="select-birth-date">' + pick_date(:profile_data, :birth_date, {:start_year => (Date.today.year - 100), :end_year => (Date.today.year - 5)}) + '</div>')) %> 19 <%= optional_field(@person, 'birth_date', labelled_form_field(_('Birth date'), '<div class="select-birth-date">' + pick_date(:profile_data, :birth_date, {:start_year => (Date.today.year - 100), :end_year => (Date.today.year - 5)}) + '</div>')) %>
20 <%= optional_field(@person, 'nationality', f.text_field(:nationality, :rel => _('Nationality'))) %> 20 <%= optional_field(@person, 'nationality', f.text_field(:nationality, :rel => _('Nationality'))) %>
21 <%= optional_field(@person, 'country', select_country(_('Country'), 'profile_data', 'country', {:class => 'type-select'})) %> 21 <%= optional_field(@person, 'country', select_country(_('Country'), 'profile_data', 'country', {:class => 'type-select'})) %>
22 -<%= optional_field(@person, 'state', f.text_field(:state, :rel => _('State'))) %>  
23 -<%= optional_field(@person, 'city', f.text_field(:city, :rel => _('City'))) %> 22 +<%= optional_field(@person, 'state', f.text_field(:state, :id => 'state_field', :rel => _('State'))) %>
  23 +<%= optional_field(@person, 'city', f.text_field(:city, :id => 'city_field', :rel => _('City'))) %>
24 <%= optional_field(@person, 'zip_code', labelled_form_field(_('ZIP code'), text_field(:profile_data, :zip_code, :rel => _('ZIP code')))) %> 24 <%= optional_field(@person, 'zip_code', labelled_form_field(_('ZIP code'), text_field(:profile_data, :zip_code, :rel => _('ZIP code')))) %>
25 <%= optional_field(@person, 'address', labelled_form_field(_('Address (street and number)'), text_field(:profile_data, :address, :rel => _('Address')))) %> 25 <%= optional_field(@person, 'address', labelled_form_field(_('Address (street and number)'), text_field(:profile_data, :address, :rel => _('Address')))) %>
26 <%= optional_field(@person, 'address_reference', labelled_form_field(_('Address reference'), text_field(:profile_data, :address_reference, :rel => _('Address reference')))) %> 26 <%= optional_field(@person, 'address_reference', labelled_form_field(_('Address reference'), text_field(:profile_data, :address_reference, :rel => _('Address reference')))) %>
@@ -36,6 +36,7 @@ @@ -36,6 +36,7 @@
36 </div> 36 </div>
37 <% end %> 37 <% end %>
38 38
  39 +<%= javascript_include_tag('city_state_validation') %>
39 <script type='text/javascript'> 40 <script type='text/javascript'>
40 function toggle_text_field(id, span_id) { 41 function toggle_text_field(id, span_id) {
41 if ($(id).value == "Others") { 42 if ($(id).value == "Others") {
app/views/shared/_organization_custom_fields.rhtml
@@ -13,8 +13,8 @@ @@ -13,8 +13,8 @@
13 <%= optional_field(profile, 'address_reference', labelled_form_field(_('Address reference'), text_field(object_name, :address_reference))) %> 13 <%= optional_field(profile, 'address_reference', labelled_form_field(_('Address reference'), text_field(object_name, :address_reference))) %>
14 <%= optional_field(profile, 'district', labelled_form_field(_('District'), text_field(object_name, :district))) %> 14 <%= optional_field(profile, 'district', labelled_form_field(_('District'), text_field(object_name, :district))) %>
15 <%= optional_field(profile, 'zip_code', labelled_form_field(_('ZIP code'), text_field(object_name, :zip_code))) %> 15 <%= optional_field(profile, 'zip_code', labelled_form_field(_('ZIP code'), text_field(object_name, :zip_code))) %>
16 -<%= optional_field(profile, 'city', f.text_field(:city)) %>  
17 -<%= optional_field(profile, 'state', f.text_field(:state)) %> 16 +<%= optional_field(profile, 'city', f.text_field(:city, :id =>'city_field')) %>
  17 +<%= optional_field(profile, 'state', f.text_field(:state,:id =>'state_field')) %>
18 <%= optional_field(profile, 'country', select_country(_('Country'), object_name, 'country', {:class => 'type-select'})) %> 18 <%= optional_field(profile, 'country', select_country(_('Country'), object_name, 'country', {:class => 'type-select'})) %>
19 <%= optional_field(profile, 'tag_list', f.text_field(:tag_list)) %> 19 <%= optional_field(profile, 'tag_list', f.text_field(:tag_list)) %>
20 20
@@ -29,3 +29,4 @@ @@ -29,3 +29,4 @@
29 <%= optional_field(profile, 'acronym', f.text_field(:acronym)) %> 29 <%= optional_field(profile, 'acronym', f.text_field(:acronym)) %>
30 <%= optional_field(profile, 'foundation_year', f.text_field(:foundation_year)) %> 30 <%= optional_field(profile, 'foundation_year', f.text_field(:foundation_year)) %>
31 <% end %> 31 <% end %>
  32 +<%= javascript_include_tag('city_state_validation') %>
config/routes.rb
@@ -31,6 +31,9 @@ ActionController::Routing::Routes.draw do |map| @@ -31,6 +31,9 @@ ActionController::Routing::Routes.draw do |map|
31 map.connect 'thumbnails/*stuff', :controller => 'not_found', :action => 'nothing' 31 map.connect 'thumbnails/*stuff', :controller => 'not_found', :action => 'nothing'
32 map.connect 'user_themes/*stuff', :controller => 'not_found', :action => 'nothing' 32 map.connect 'user_themes/*stuff', :controller => 'not_found', :action => 'nothing'
33 33
  34 + # embed controller
  35 + map.embed 'embed/:action/:id', :controller => 'embed', :id => /\d+/
  36 +
34 # online documentation 37 # online documentation
35 map.doc 'doc', :controller => 'doc', :action => 'index' 38 map.doc 'doc', :controller => 'doc', :action => 'index'
36 map.doc_section 'doc/:section', :controller => 'doc', :action => 'section' 39 map.doc_section 'doc/:section', :controller => 'doc', :action => 'section'
features/balloon.feature
@@ -8,6 +8,7 @@ Feature: balloon @@ -8,6 +8,7 @@ Feature: balloon
8 And the following communities 8 And the following communities
9 | identifier | name | 9 | identifier | name |
10 | sample | Sample | 10 | sample | Sample |
  11 + And I am logged in as "joaosilva"
11 12
12 @selenium 13 @selenium
13 Scenario: I should not see trigger if not enabled 14 Scenario: I should not see trigger if not enabled
features/categories_block.feature
@@ -24,16 +24,12 @@ Feature: categories_block @@ -24,16 +24,12 @@ Feature: categories_block
24 | owner | type | 24 | owner | type |
25 | environment | CategoriesBlock | 25 | environment | CategoriesBlock |
26 And I am logged in as admin 26 And I am logged in as admin
  27 + And I go to /admin/environment_design
  28 + And display ".button-bar"
27 29
28 - # Note that this @ignore-hidden-elements only works for seeing hidden  
29 - # elements. It actually doesn't work for following hidden link or pressing  
30 - # hidden buttons. That's why it's necessary to use this display hack to show  
31 - # the link.  
32 - @selenium @ignore-hidden-elements 30 + @selenium
33 Scenario: List just product categories 31 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" 32 + Given I follow "Edit" within ".categories-block"
37 And I check "Product" 33 And I check "Product"
38 When I press "Save" 34 When I press "Save"
39 Then I should see "Food" 35 Then I should see "Food"
@@ -42,11 +38,9 @@ Feature: categories_block @@ -42,11 +38,9 @@ Feature: categories_block
42 And "Steak" should not be visible within "span#category-name" 38 And "Steak" should not be visible within "span#category-name"
43 And "Fiction" should not be visible within "span#category-name" 39 And "Fiction" should not be visible within "span#category-name"
44 40
45 - @selenium @ignore-hidden-elements 41 + @selenium
46 Scenario: Show submenu if it exists 42 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" 43 + Given I follow "Edit" within ".categories-block"
50 And I check "Product" 44 And I check "Product"
51 And I press "Save" 45 And I press "Save"
52 Then I should see "Food" 46 Then I should see "Food"
@@ -61,11 +55,9 @@ Feature: categories_block @@ -61,11 +55,9 @@ Feature: categories_block
61 And I should see "Steak" 55 And I should see "Steak"
62 And I should not see "Fiction" 56 And I should not see "Fiction"
63 57
64 - @selenium @ignore-hidden-elements 58 + @selenium
65 Scenario: Show only one submenu per time 59 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" 60 + Given I follow "Edit" within ".categories-block"
69 And I check "Product" 61 And I check "Product"
70 And I press "Save" 62 And I press "Save"
71 Then I should see "Book" 63 Then I should see "Book"
@@ -73,20 +65,16 @@ Feature: categories_block @@ -73,20 +65,16 @@ Feature: categories_block
73 When I follow "block_2_category_2" 65 When I follow "block_2_category_2"
74 Then I should see "Literature" 66 Then I should see "Literature"
75 67
76 - @selenium @ignore-hidden-elements 68 + @selenium
77 Scenario: List just general categories 69 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" 70 + Given I follow "Edit" within ".categories-block"
81 And I check "Generic category" 71 And I check "Generic category"
82 When I press "Save" 72 When I press "Save"
83 Then I should see "Wood" 73 Then I should see "Wood"
84 74
85 - @selenium @ignore-hidden-elements 75 + @selenium
86 Scenario: List just regions 76 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" 77 + Given I follow "Edit" within ".categories-block"
90 And I check "Region" 78 And I check "Region"
91 When I press "Save" 79 When I press "Save"
92 Then I should see "Bahia" 80 Then I should see "Bahia"
features/comment.feature
@@ -39,7 +39,7 @@ Feature: comment @@ -39,7 +39,7 @@ Feature: comment
39 When I press "Post comment" 39 When I press "Post comment"
40 Then I should see "Hey ho, let's go" 40 Then I should see "Hey ho, let's go"
41 41
42 - @selenium 42 + @selenium-fixme
43 Scenario: redirect to right place after comment a picture 43 Scenario: redirect to right place after comment a picture
44 Given the following files 44 Given the following files
45 | owner | file | mime | 45 | owner | file | mime |
@@ -134,4 +134,4 @@ Feature: comment @@ -134,4 +134,4 @@ Feature: comment
134 | Post one | joaosilva | Hello | Hello | 134 | Post one | joaosilva | Hello | Hello |
135 When I go to /joaosilva/forum/post-one 135 When I go to /joaosilva/forum/post-one
136 And I select "Oldest first" from "comment_order" within ".comment-order" 136 And I select "Oldest first" from "comment_order" within ".comment-order"
137 - Then I should see "Hi all" within ".article-comment"  
138 \ No newline at end of file 137 \ No newline at end of file
  138 + Then I should see "Hi all" within ".article-comment"
features/short_filename.feature
@@ -1,21 +0,0 @@ @@ -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"  
features/signup.feature
@@ -29,10 +29,20 @@ Feature: signup @@ -29,10 +29,20 @@ Feature: signup
29 And I press "Log in" 29 And I press "Log in"
30 Then I should be logged in as "josesilva" 30 Then I should be logged in as "josesilva"
31 31
  32 + @selenium
  33 + Scenario: show error message if username is already used
  34 + Given the following users
  35 + | login |
  36 + | josesilva |
  37 + When I go to signup page
  38 + And I fill in "Username" with "josesilva"
  39 + And I fill in "e-Mail" with "josesilva1"
  40 + Then I should see "This login name is unavailable"
  41 +
32 Scenario: be redirected if user goes to signup page and is logged 42 Scenario: be redirected if user goes to signup page and is logged
33 Given the following users 43 Given the following users
34 | login | name | 44 | login | name |
35 - | joaosilva | Joao Silva | 45 + | joaosilva | joao silva |
36 Given I am logged in as "joaosilva" 46 Given I am logged in as "joaosilva"
37 And I go to signup page 47 And I go to signup page
38 Then I should be on joaosilva's control panel 48 Then I should be on joaosilva's control panel
lib/feed_handler.rb
@@ -51,7 +51,6 @@ class FeedHandler @@ -51,7 +51,6 @@ class FeedHandler
51 end 51 end
52 52
53 def process(container) 53 def process(container)
54 - RAILS_DEFAULT_LOGGER.info("Processing %s with id = %d" % [container.class.name, container.id])  
55 begin 54 begin
56 container.class.transaction do 55 container.class.transaction do
57 if container.update_errors > FeedHandler.max_errors && container.fetched_at < (Time.now - FeedHandler.disabled_period) 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,6 +50,10 @@ class FilePresenter
50 nil 50 nil
51 end 51 end
52 52
  53 + def download?(view=nil)
  54 + false
  55 + end
  56 +
53 def short_description 57 def short_description
54 file_type = if content_type.present? 58 file_type = if content_type.present?
55 content_type.sub(/^application\//, '').sub(/^x-/, '').sub(/^image\//, '') 59 content_type.sub(/^application\//, '').sub(/^x-/, '').sub(/^image\//, '')
lib/tasks/plugins_tests.rake
@@ -25,51 +25,87 @@ def plugin_disabled_warning(plugin) @@ -25,51 +25,87 @@ def plugin_disabled_warning(plugin)
25 puts "E: you should enable #{plugin} plugin before running it's tests!" 25 puts "E: you should enable #{plugin} plugin before running it's tests!"
26 end 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 else 37 else
33 - sh 'testrb', '-Itest', *files 38 + return 'default'
34 end 39 end
35 end 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 else 68 else
42 - sh 'xvfb-run', 'ruby', '-S', 'cucumber', '--profile', profile.to_s, '--format', ENV['CUCUMBER_FORMAT'] || 'progress' , *files 69 + run_testrb files
43 end 70 end
44 end 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 end 88 end
  89 + when :by_plugin
54 end 90 end
55 end 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 end 101 end
66 end 102 end
67 103
68 -def plugin_selenium_task(name, plugin, files_glob) 104 +def plugin_test_task(name, plugin, run=:individually)
69 desc "Run #{name} tests for #{plugin_name(plugin)}" 105 desc "Run #{name} tests for #{plugin_name(plugin)}"
70 task name => 'db:test:plugins:prepare' do |t| 106 task name => 'db:test:plugins:prepare' do |t|
71 if plugin_enabled?(plugin) 107 if plugin_enabled?(plugin)
72 - run_cucumber t.name, "#{plugin}_selenium", files_glob 108 + run_tests(name, plugin, run)
73 else 109 else
74 plugin_disabled_warning(plugin) 110 plugin_disabled_warning(plugin)
75 end 111 end
@@ -98,28 +134,28 @@ namespace :test do @@ -98,28 +134,28 @@ namespace :test do
98 namespace :noosfero_plugins do 134 namespace :noosfero_plugins do
99 all_plugins.each do |plugin| 135 all_plugins.each do |plugin|
100 namespace plugin do 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 end 142 end
107 143
108 test_sequence_task(plugin, plugin, "#{plugin}:units", "#{plugin}:functionals", "#{plugin}:integration", "#{plugin}:cucumber", "#{plugin}:selenium") 144 test_sequence_task(plugin, plugin, "#{plugin}:units", "#{plugin}:functionals", "#{plugin}:integration", "#{plugin}:cucumber", "#{plugin}:selenium")
109 end 145 end
110 146
111 - { :units => :unit , :functionals => :functional , :integration => :integration }.each do |taskname,folder| 147 + [:units, :functionals, :integration].each do |taskname|
112 task taskname => 'db:test:plugins:prepare' do |t| 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 end 150 end
115 end 151 end
116 152
117 task :cucumber => 'db:test:plugins:prepare' do |t| 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 end 155 end
120 156
121 task :selenium => 'db:test:plugins:prepare' do |t| 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 end 159 end
124 160
125 task :temp_enable_all_plugins do 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,9 +2,10 @@ class AntiSpamPlugin::Wrapper &lt; SimpleDelegator
2 include Rakismet::Model 2 include Rakismet::Model
3 3
4 @@wrappers = [] 4 @@wrappers = []
  5 + cattr_accessor :wrappers
5 6
6 def self.wrap(object) 7 def self.wrap(object)
7 - wrapper = @@wrappers.find { |wrapper| wrapper.wraps?(object) } 8 + wrapper = wrappers.find { |wrapper| wrapper.wraps?(object) }
8 wrapper ? wrapper.new(object) : object 9 wrapper ? wrapper.new(object) : object
9 end 10 end
10 11
@@ -13,6 +14,10 @@ class AntiSpamPlugin::Wrapper &lt; SimpleDelegator @@ -13,6 +14,10 @@ class AntiSpamPlugin::Wrapper &lt; SimpleDelegator
13 end 14 end
14 15
15 def self.inherited(child) 16 def self.inherited(child)
16 - @@wrappers << child 17 + wrappers << child
17 end 18 end
18 end 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/comment_group/test/functional/comment_group_plugin_profile_controller_test.rb
@@ -36,10 +36,10 @@ class CommentGroupPluginProfileControllerTest &lt; ActionController::TestCase @@ -36,10 +36,10 @@ class CommentGroupPluginProfileControllerTest &lt; ActionController::TestCase
36 end 36 end
37 37
38 should 'show first page comments only' do 38 should 'show first page comments only' do
39 - comment1 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'secondpage', :group_id => 0)  
40 - comment2 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'firstpage 1', :group_id => 0)  
41 - comment3 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'firstpage 2', :group_id => 0)  
42 - comment4 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'firstpage 3', :group_id => 0) 39 + comment1 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :created_at => Time.now, :body => 'secondpage', :group_id => 0)
  40 + comment2 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :created_at => Time.now - 1.day, :body => 'firstpage 1', :group_id => 0)
  41 + comment3 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :created_at => Time.now - 2.days, :body => 'firstpage 2', :group_id => 0)
  42 + comment4 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :created_at => Time.now - 3.days, :body => 'firstpage 3', :group_id => 0)
43 xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0 43 xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0
44 assert_match /firstpage 1/, @response.body 44 assert_match /firstpage 1/, @response.body
45 assert_match /firstpage 2/, @response.body 45 assert_match /firstpage 2/, @response.body
plugins/community_track/lib/community_track_plugin/track_card_list_block.rb
@@ -12,4 +12,8 @@ class CommunityTrackPlugin::TrackCardListBlock &lt; CommunityTrackPlugin::TrackList @@ -12,4 +12,8 @@ class CommunityTrackPlugin::TrackCardListBlock &lt; CommunityTrackPlugin::TrackList
12 'track_card' 12 'track_card'
13 end 13 end
14 14
  15 + def embedable?
  16 + true
  17 + end
  18 +
15 end 19 end
plugins/community_track/test/functional/community_track_plugin_content_viewer_controller_test.rb
@@ -10,7 +10,7 @@ end @@ -10,7 +10,7 @@ end
10 class ContentViewerControllerTest < ActionController::TestCase 10 class ContentViewerControllerTest < ActionController::TestCase
11 11
12 def setup 12 def setup
13 - @profile = fast_create(Community) 13 + @profile = Community.create!(:name => 'Sample community', :identifier => 'sample-community')
14 @track = create_track('track', @profile) 14 @track = create_track('track', @profile)
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) 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,43 +87,35 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
87 end 87 end
88 88
89 should 'render a div with block id for track list block' do 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 get :view_page, @step.url 91 get :view_page, @step.url
94 assert_tag :tag => 'div', :attributes => { :class => 'track_list', :id => "track_list_#{@block.id}" } 92 assert_tag :tag => 'div', :attributes => { :class => 'track_list', :id => "track_list_#{@block.id}" }
95 end 93 end
96 94
97 should 'render a div with block id for track card list block' do 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 get :view_page, @step.url 97 get :view_page, @step.url
102 assert_tag :tag => 'div', :attributes => { :class => 'track_list', :id => "track_list_#{@block.id}" } 98 assert_tag :tag => 'div', :attributes => { :class => 'track_list', :id => "track_list_#{@block.id}" }
103 end 99 end
104 100
105 should 'render tracks in track list block' do 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 get :view_page, @step.url 103 get :view_page, @step.url
  104 + file = File.open('result.html', 'w+')
  105 + file.write(@response.body)
  106 + file.close
110 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)}" } } } 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 end 108 end
112 109
113 should 'render tracks in track card list block' do 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 get :view_page, @step.url 112 get :view_page, @step.url
118 assert_tag :tag => 'div', :attributes => { :class => "item_card category_#{@track.category_name}" }, :descendant => { :tag => 'div', :attributes => { :class => 'track_content' } } 113 assert_tag :tag => 'div', :attributes => { :class => "item_card category_#{@track.category_name}" }, :descendant => { :tag => 'div', :attributes => { :class => 'track_content' } }
119 assert_tag :tag => 'div', :attributes => { :class => "item_card category_#{@track.category_name}" }, :descendant => { :tag => 'div', :attributes => { :class => 'track_stats' } } 114 assert_tag :tag => 'div', :attributes => { :class => "item_card category_#{@track.category_name}" }, :descendant => { :tag => 'div', :attributes => { :class => 'track_stats' } }
120 end 115 end
121 116
122 should 'render link to display more tracks in track list block' do 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 (@block.limit+1).times { |i| create_track("track#{i}", @profile) } 119 (@block.limit+1).times { |i| create_track("track#{i}", @profile) }
128 120
129 get :view_page, @step.url 121 get :view_page, @step.url
@@ -131,9 +123,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -131,9 +123,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
131 end 123 end
132 124
133 should 'render link to show all tracks in track list block' do 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 @block.more_another_page = true 127 @block.more_another_page = true
138 @block.save! 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,9 +61,9 @@ class RecentContentBlockTest &lt; ActiveSupport::TestCase
61 61
62 root = fast_create(Blog, :name => 'test-blog', :profile_id => profile.id) 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 block = RecentContentBlock.new 68 block = RecentContentBlock.new
69 block.stubs(:holder).returns(profile) 69 block.stubs(:holder).returns(profile)
plugins/relevant_content/lib/ext/article.rb 0 → 100644
@@ -0,0 +1,95 @@ @@ -0,0 +1,95 @@
  1 +require_dependency 'article'
  2 +
  3 +class Article
  4 +
  5 + named_scope :relevant_content, :conditions => ["articles.published = true and (articles.type != 'UploadedFile' and articles.type != 'Blog' and articles.type != 'RssFeed') OR articles.type is NULL"]
  6 +
  7 + def self.articles_columns
  8 + Article.column_names.map {|c| "articles.#{c}"} .join(",")
  9 + end
  10 +
  11 + def self.most_accessed(owner, limit = nil)
  12 + conditions = owner.kind_of?(Environment) ? ["hits > 0"] : ["profile_id = ? and hits > 0", owner.id]
  13 + result = Article.relevant_content.find(
  14 + :all,
  15 + :order => 'hits desc',
  16 + :limit => limit,
  17 + :conditions => conditions)
  18 + result.paginate({:page => 1, :per_page => limit})
  19 + end
  20 +
  21 + def self.most_commented_relevant_content(owner, limit)
  22 + conditions = owner.kind_of?(Environment) ? ["comments_count > 0"] : ["profile_id = ? and comments_count > 0", owner.id]
  23 + result = Article.relevant_content.find(
  24 + :all,
  25 + :order => 'comments_count desc',
  26 + :limit => limit,
  27 + :conditions => conditions)
  28 + result.paginate({:page => 1, :per_page => limit})
  29 + end
  30 +
  31 + def self.more_positive_votes(owner, limit = nil)
  32 + conditions = owner.kind_of?(Environment) ? {'votes.voteable_type' => 'Article'} : ["profile_id = ? and votes.voteable_type = ? ", owner.id, 'Article']
  33 + result = Article.relevant_content.find(
  34 + :all,
  35 + :order => 'sum(vote) desc',
  36 + :group => 'voteable_id, ' + articles_columns,
  37 + :limit => limit,
  38 + :having => ['sum(vote) > 0'],
  39 + :conditions => conditions,
  40 + :joins => 'INNER JOIN votes ON articles.id = votes.voteable_id')
  41 + result.paginate({:page => 1, :per_page => limit})
  42 + end
  43 +
  44 + def self.more_negative_votes(owner, limit = nil)
  45 + conditions = owner.kind_of?(Environment) ? {'votes.voteable_type' => 'Article'} : ["profile_id = ? and votes.voteable_type = 'Article' ", owner.id]
  46 + result = Article.relevant_content.find(
  47 + :all,
  48 + :order => 'sum(vote) asc',
  49 + :group => 'voteable_id, ' + articles_columns,
  50 + :limit => limit,
  51 + :having => ['sum(vote) < 0'],
  52 + :conditions => conditions,
  53 + :joins => 'INNER JOIN votes ON articles.id = votes.voteable_id'
  54 + )
  55 + result.paginate({:page => 1, :per_page => limit})
  56 + end
  57 +
  58 + def self.most_liked(owner, limit = nil)
  59 + conditions = owner.kind_of?(Environment) ? ["votes.voteable_type = 'Article' and vote > 0"] : ["votes.voteable_type = 'Article' and vote > 0 and profile_id = ? ", owner.id]
  60 + result = Article.relevant_content.find(
  61 + :all,
  62 + :select => articles_columns,
  63 + :order => 'count(voteable_id) desc',
  64 + :group => 'voteable_id, ' + articles_columns,
  65 + :limit => limit,
  66 + :conditions => conditions,
  67 + :joins => 'INNER JOIN votes ON articles.id = votes.voteable_id')
  68 + result.paginate({:page => 1, :per_page => limit})
  69 + end
  70 +
  71 + def self.most_disliked(owner, limit = nil)
  72 + conditions = owner.kind_of?(Environment) ? ["votes.voteable_type = 'Article' and vote < 0"] : ["votes.voteable_type = 'Article' and vote < 0 and profile_id = ? ", owner.id]
  73 + result = Article.relevant_content.find(
  74 + :all,
  75 + :order => 'count(voteable_id) desc',
  76 + :group => 'voteable_id, ' + articles_columns,
  77 + :limit => limit,
  78 + :conditions => conditions,
  79 + :joins => 'INNER JOIN votes ON articles.id = votes.voteable_id')
  80 + result.paginate({:page => 1, :per_page => limit})
  81 + end
  82 +
  83 + def self.most_voted(owner, limit = nil)
  84 + conditions = owner.kind_of?(Environment) ? ["votes.voteable_type = 'Article'"] : ["votes.voteable_type = 'Article' and profile_id = ? ", owner.id]
  85 + result = Article.relevant_content.find(
  86 + :all,
  87 + :select => articles_columns,
  88 + :order => 'count(voteable_id) desc',
  89 + :group => 'voteable_id, ' + articles_columns,
  90 + :limit => limit,
  91 + :conditions => conditions,
  92 + :joins => 'INNER JOIN votes ON articles.id = votes.voteable_id')
  93 + result.paginate({:page => 1, :per_page => limit})
  94 + end
  95 +end
plugins/relevant_content/lib/relevant_content_plugin.rb 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +class RelevantContentPlugin < Noosfero::Plugin
  2 +
  3 + def self.plugin_name
  4 + "Relevant Content Plugin"
  5 + end
  6 +
  7 + def self.plugin_description
  8 + _("A plugin that lists the most accessed, most commented, most liked and most disliked contents.")
  9 + end
  10 +
  11 + def self.extra_blocks
  12 + {
  13 + RelevantContentPlugin::RelevantContentBlock => {}
  14 + }
  15 + end
  16 +
  17 + def stylesheet?
  18 + true
  19 + end
  20 +
  21 +end
plugins/relevant_content/lib/relevant_content_plugin/relevant_content_block.rb 0 → 100644
@@ -0,0 +1,93 @@ @@ -0,0 +1,93 @@
  1 +class RelevantContentPlugin::RelevantContentBlock < Block
  2 + def self.description
  3 + _('Relevant content')
  4 + end
  5 +
  6 + def default_title
  7 + _('Relevant content')
  8 + end
  9 +
  10 + def help
  11 + _('This block lists the most popular content.')
  12 + end
  13 +
  14 + settings_items :limit, :type => :integer, :default => 5
  15 + settings_items :show_most_read, :type => :boolean, :default => 1
  16 + settings_items :show_most_commented, :type => :boolean, :default => 1
  17 + settings_items :show_most_liked, :type => :boolean, :default => 1
  18 + settings_items :show_most_disliked, :type => :boolean, :default => 0
  19 + settings_items :show_most_voted, :type => :boolean, :default => 1
  20 +
  21 + include ActionController::UrlWriter
  22 + def content(args={})
  23 +
  24 + content = block_title(title)
  25 +
  26 + if self.show_most_read
  27 + docs = Article.most_accessed(owner, self.limit)
  28 + if !docs.blank?
  29 + subcontent = ""
  30 + subcontent += content_tag(:span, _("Most read articles"), :class=>"title mread") + "\n"
  31 + subcontent += content_tag(:ul, docs.map {|item| content_tag('li', link_to(h(item.title), item.url))}.join("\n"))
  32 + content += content_tag(:div, subcontent, :class=>"block mread") + "\n"
  33 + end
  34 + end
  35 +
  36 + if self.show_most_commented
  37 + docs = Article.most_commented_relevant_content(owner, self.limit)
  38 + if !docs.blank?
  39 + subcontent = ""
  40 + subcontent += content_tag(:span, _("Most commented articles"), :class=>"title mcommented") + "\n"
  41 + subcontent += content_tag(:ul, docs.map {|item| content_tag('li', link_to(h(item.title), item.url))}.join("\n"))
  42 + content += content_tag(:div, subcontent, :class=>"block mcommented") + "\n"
  43 + end
  44 + end
  45 +
  46 + if owner.kind_of?(Environment)
  47 + env = owner
  48 + else
  49 + env = owner.environment
  50 + end
  51 +
  52 + if env.plugin_enabled?(VotePlugin)
  53 + if self.show_most_liked
  54 + docs = Article.more_positive_votes(owner, self.limit)
  55 + if !docs.blank?
  56 + subcontent = ""
  57 + subcontent += content_tag(:span, _("Most liked articles"), :class=>"title mliked") + "\n"
  58 + subcontent += content_tag(:ul, docs.map {|item| content_tag('li', link_to(h(item.title), item.url))}.join("\n"))
  59 + content += content_tag(:div, subcontent, :class=>"block mliked") + "\n"
  60 + end
  61 + end
  62 + if self.show_most_disliked
  63 + docs = Article.more_negative_votes(owner, self.limit)
  64 + if !docs.blank?
  65 + subcontent = ""
  66 + subcontent += content_tag(:span, _("Most disliked articles"), :class=>"title mdisliked") + "\n"
  67 + subcontent += content_tag(:ul, docs.map {|item| content_tag('li', link_to(h(item.title), item.url))}.join("\n"))
  68 + content += content_tag(:div, subcontent, :class=>"block mdisliked") + "\n"
  69 + end
  70 + end
  71 +
  72 + if self.show_most_voted
  73 + docs = Article.most_voted(owner, self.limit)
  74 + if !docs.blank?
  75 + subcontent = ""
  76 + subcontent += content_tag(:span, _("Most voted articles"), :class=>"title mvoted") + "\n"
  77 + subcontent += content_tag(:ul, docs.map {|item| content_tag('li', link_to(h(item.title), item.url))}.join("\n"))
  78 + content += content_tag(:div, subcontent, :class=>"block mvoted") + "\n"
  79 + end
  80 + end
  81 + end
  82 + return content
  83 + end
  84 +
  85 + def timeout
  86 + 4.hours
  87 + end
  88 +
  89 + def self.expire_on
  90 + { :profile => [:article], :environment => [:article] }
  91 + end
  92 +
  93 +end
0 \ No newline at end of file 94 \ No newline at end of file
plugins/relevant_content/public/style.css 0 → 100644
@@ -0,0 +1,79 @@ @@ -0,0 +1,79 @@
  1 +#content .relevant-content-plugin_relevant-content-block {
  2 + padding: 10px 0px 10px 10px;
  3 + word-wrap: break-word;
  4 +}
  5 +
  6 +.relevant-content-plugin_relevant-content-block ul {
  7 + margin: 0px;
  8 + padding: 0px 0px 0px 20px;
  9 +}
  10 +.relevant-content-plugin_relevant-content-block li {
  11 + margin: 0px;
  12 + padding: 0px;
  13 + list-style: none
  14 +}
  15 +.relevant-content-plugin_relevant-content-block a {
  16 + text-decoration: none;
  17 +}
  18 +.relevant-content-plugin_relevant-content-block .block-footer-content {
  19 + font-size: 10px;
  20 +}
  21 +.relevant-content-plugin_relevant-content-block .block-footer-content a:hover {
  22 + text-decoration: underline;
  23 +}
  24 +
  25 +.relevant-content-plugin_relevant-content-block p {
  26 + text-align:center;
  27 +}
  28 +
  29 +.relevant-content-plugin_relevant-content-block p.like{
  30 + background-image: url('images/positive-hand.png');
  31 + background-repeat: no-repeat;
  32 + min-width: 50px;
  33 + text-align:center;
  34 +}
  35 +
  36 +.relevant-content-plugin_relevant-content-block p.dislike{
  37 + background-image: url('images/negative-hand.png');
  38 + background-repeat: no-repeat;
  39 + min-width: 50px;
  40 + text-align:center;
  41 +}
  42 +
  43 +
  44 +.relevant-content-plugin_relevant-content-block {
  45 + //overflow: hidden;
  46 + display: block;
  47 + width: 100%;
  48 +}
  49 +
  50 +
  51 +.relevant-content-cover img {
  52 + width: 100%;
  53 +}
  54 +
  55 +.relevant-content-plugin_relevant-content-block span.title {
  56 + display: block;
  57 + margin: 20px 0px 0px;
  58 + padding: 0px 0px 0px 20px;
  59 +}
  60 +
  61 +.relevant-content-plugin_relevant-content-block span.title.mread {
  62 +
  63 +}
  64 +
  65 +.relevant-content-plugin_relevant-content-block span.title.mcommented {
  66 +
  67 +}
  68 +
  69 +.relevant-content-plugin_relevant-content-block span.title.mliked {
  70 +
  71 +}
  72 +
  73 +.relevant-content-plugin_relevant-content-block span.title.mdisliked {
  74 +
  75 +}
  76 +
  77 +.relevant-content-plugin_relevant-content-block span.title.mvoted {
  78 +
  79 +}
plugins/relevant_content/test/test_helper.rb 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +require File.dirname(__FILE__) + '/../../../test/test_helper'
plugins/relevant_content/test/unit/article.rb 0 → 100644
@@ -0,0 +1,148 @@ @@ -0,0 +1,148 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +require 'comment_controller'
  4 +# Re-raise errors caught by the controller.
  5 +class CommentController; def rescue_action(e) raise e end; end
  6 +
  7 +class RelevantContentBlockTest < ActiveSupport::TestCase
  8 +
  9 + include AuthenticatedTestHelper
  10 + fixtures :users, :environments
  11 +
  12 + def setup
  13 + @controller = CommentController.new
  14 + @request = ActionController::TestRequest.new
  15 + @response = ActionController::TestResponse.new
  16 + @profile = create_user('testinguser').person
  17 + @environment = @profile.environment
  18 + end
  19 + attr_reader :profile, :environment
  20 +
  21 + def enable_vote_plugin
  22 + enabled = false
  23 + environment=Environment.default
  24 + if Noosfero::Plugin.all.include?('VotePlugin')
  25 + if not environment.enabled_plugins.include?(:vote)
  26 + environment.enable_plugin(Vote)
  27 + environment.save!
  28 + end
  29 + enabled = true
  30 + end
  31 + enabled
  32 + end
  33 +
  34 + should 'list most commented articles' do
  35 + Article.delete_all
  36 + a1 = create(TextileArticle, :name => "art 1", :profile_id => profile.id)
  37 + a2 = create(TextileArticle, :name => "art 2", :profile_id => profile.id)
  38 + a3 = create(TextileArticle, :name => "art 3", :profile_id => profile.id)
  39 +
  40 + 2.times { Comment.create(:title => 'test', :body => 'asdsad', :author => profile, :source => a2).save! }
  41 + 4.times { Comment.create(:title => 'test', :body => 'asdsad', :author => profile, :source => a3).save! }
  42 +
  43 + # should respect the order (more commented comes first)
  44 + assert_equal a3.name, profile.articles.most_commented_relevant_content(Environment.default, 3).first.name
  45 + # It is a2 instead of a1 since it does not list articles without comments
  46 + assert_equal a2.name, profile.articles.most_commented_relevant_content(Environment.default, 3).last.name
  47 + end
  48 +
  49 +
  50 + should 'find the most voted' do
  51 + if not enable_vote_plugin
  52 + return
  53 + end
  54 + article = fast_create(Article, {:name=>'2 votes'})
  55 + 2.times{
  56 + person = fast_create(Person)
  57 + person.vote_for(article)
  58 + }
  59 + article = fast_create(Article, {:name=>'10 votes'})
  60 + 10.times{
  61 + person = fast_create(Person)
  62 + person.vote_for(article)
  63 + }
  64 + article = fast_create(Article, {:name=>'5 votes'})
  65 + 5.times{
  66 + person = fast_create(Person)
  67 + person.vote_for(article)
  68 + }
  69 + articles = Article.most_voted(Environment.default, 5)
  70 + assert_equal '10 votes', articles.first.name
  71 + assert_equal '2 votes', articles.last.name
  72 + end
  73 +
  74 + should 'list the most postive' do
  75 + if not enable_vote_plugin
  76 + return
  77 + end
  78 + article = fast_create(Article, {:name=>'23 votes for 20 votes against'})
  79 + 20.times{
  80 + person = fast_create(Person)
  81 + person.vote_against(article)
  82 + }
  83 + 23.times{
  84 + person = fast_create(Person)
  85 + person.vote_for(article)
  86 + }
  87 + article = fast_create(Article, {:name=>'10 votes for 5 votes against'})
  88 + 10.times{
  89 + person = fast_create(Person)
  90 + person.vote_for(article)
  91 + }
  92 + 5.times{
  93 + person = fast_create(Person)
  94 + person.vote_against(article)
  95 + }
  96 + article = fast_create(Article, {:name=>'2 votes against'})
  97 + 2.times{
  98 + person = fast_create(Person)
  99 + person.vote_against(article)
  100 + }
  101 +
  102 + article = fast_create(Article, {:name=>'7 votes for'})
  103 + 7.times{
  104 + person = fast_create(Person)
  105 + person.vote_for(article)
  106 + }
  107 + articles = Article.more_positive_votes(Environment.default, 5)
  108 + assert_equal '7 votes for', articles.first.name
  109 + assert_equal '23 votes for 20 votes against', articles.last.name
  110 + end
  111 +
  112 + should 'list the most negative' do
  113 + if not enable_vote_plugin
  114 + return
  115 + end
  116 + article = fast_create(Article, {:name=>'23 votes for 29 votes against'})
  117 + 29.times{
  118 + person = fast_create(Person)
  119 + person.vote_against(article)
  120 + }
  121 + 23.times{
  122 + person = fast_create(Person)
  123 + person.vote_for(article)
  124 + }
  125 + article = fast_create(Article, {:name=>'10 votes for 15 votes against'})
  126 + 10.times{
  127 + person = fast_create(Person)
  128 + person.vote_for(article)
  129 + }
  130 + 15.times{
  131 + person = fast_create(Person)
  132 + person.vote_against(article)
  133 + }
  134 + article = fast_create(Article, {:name=>'2 votes against'})
  135 + 2.times{
  136 + person = fast_create(Person)
  137 + person.vote_against(article)
  138 + }
  139 + article = fast_create(Article, {:name=>'7 votes for'})
  140 + 7.times{
  141 + person = fast_create(Person)
  142 + person.vote_for(article)
  143 + }
  144 + articles = Article.more_negative_votes(Environment.default, 5)
  145 + assert_equal '23 votes for 29 votes against', articles.first.name
  146 + assert_equal '2 votes against', articles.last.name
  147 + end
  148 +end
0 \ No newline at end of file 149 \ No newline at end of file
plugins/relevant_content/test/unit/relevant_content_block_test.rb 0 → 100644
@@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +require 'comment_controller'
  4 +# Re-raise errors caught by the controller.
  5 +class CommentController; def rescue_action(e) raise e end; end
  6 +
  7 +class RelevantContentBlockTest < ActiveSupport::TestCase
  8 +
  9 + include AuthenticatedTestHelper
  10 + fixtures :users, :environments
  11 +
  12 + def setup
  13 + @controller = CommentController.new
  14 + @request = ActionController::TestRequest.new
  15 + @response = ActionController::TestResponse.new
  16 +
  17 + @profile = create_user('testinguser').person
  18 + @environment = @profile.environment
  19 + end
  20 + attr_reader :profile, :environment
  21 +
  22 + should 'have a default title' do
  23 + relevant_content_block = RelevantContentPlugin::RelevantContentBlock.new
  24 + block = Block.new
  25 + assert_not_equal block.default_title, relevant_content_block.default_title
  26 + end
  27 +
  28 + should 'have a help tooltip' do
  29 + relevant_content_block = RelevantContentPlugin::RelevantContentBlock.new
  30 + block = Block.new
  31 + assert_not_equal "", relevant_content_block.help
  32 + end
  33 +
  34 + should 'describe itself' do
  35 + assert_not_equal Block.description, RelevantContentPlugin::RelevantContentBlock.description
  36 + end
  37 +
  38 + should 'is editable' do
  39 + block = RelevantContentPlugin::RelevantContentBlock.new
  40 + assert block.editable?
  41 + end
  42 +
  43 + should 'expire' do
  44 + assert_equal RelevantContentPlugin::RelevantContentBlock.expire_on, {:environment=>[:article], :profile=>[:article]}
  45 + end
  46 +
  47 +end
plugins/relevant_content/test/unit/relevant_content_plugin_test.rb 0 → 100644
@@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class RelevantContentPluginTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @plugin = RelevantContentPlugin.new
  7 + end
  8 +
  9 + should 'be a noosfero plugin' do
  10 + assert_kind_of Noosfero::Plugin, @plugin
  11 + end
  12 +
  13 + should 'have name' do
  14 + assert_equal 'Relevant Content Plugin', RelevantContentPlugin.plugin_name
  15 + end
  16 +
  17 + should 'have description' do
  18 + assert_equal _("A plugin that lists the most accessed, most commented, most liked and most disliked contents."), RelevantContentPlugin.plugin_description
  19 + end
  20 +
  21 + should 'have stylesheet' do
  22 + assert @plugin.stylesheet?
  23 + end
  24 +
  25 + should "return RelevantContentBlock in extra_blocks class method" do
  26 + assert RelevantContentPlugin.extra_blocks.keys.include?(RelevantContentPlugin::RelevantContentBlock)
  27 + end
  28 +
  29 +end
plugins/relevant_content/views/box_organizer/relevant_content_plugin/_relevant_content_block.rhtml 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +<div id='edit-relevant-content-block'>
  2 + <%= labelled_form_field _('Limit of items per category'), text_field(:block, :limit, :size => 3) %>
  3 + <%= labelled_check_box _('Display most accessed content'), "block[show_most_read]", 1 ,@block.show_most_read %><BR>
  4 + <%= labelled_check_box _('Display most commented content'), "block[show_most_commented]", 1 ,@block.show_most_commented %><BR>
  5 + <%= labelled_check_box _('Display most liked content'), "block[show_most_liked]", 1 ,@block.show_most_liked %><BR>
  6 + <%= labelled_check_box _('Display most voted content'), "block[show_most_voted]", 1 ,@block.show_most_voted %><BR>
  7 + <%= labelled_check_box _('Display most disliked content'), "block[show_most_disliked]", 1 , @block.show_most_disliked %><BR>
  8 +</div>
0 \ No newline at end of file 9 \ No newline at end of file
plugins/relevant_content/views/environment_design/relevant_content_plugin 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +../box_organizer/relevant_content_plugin
0 \ No newline at end of file 2 \ No newline at end of file
plugins/relevant_content/views/profile_design/relevant_content_plugin 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +../box_organizer/relevant_content_plugin
0 \ No newline at end of file 2 \ No newline at end of file
public/designs/icons/tango/style.css
1 /******************SMALL ICONS********************/ 1 /******************SMALL ICONS********************/
  2 +.icon-embed { background-image: url(Tango/16x16/apps/utilities-terminal.png) }
2 .icon-edit { background-image: url(Tango/16x16/apps/text-editor.png) } 3 .icon-edit { background-image: url(Tango/16x16/apps/text-editor.png) }
3 .icon-home { background-image: url(Tango/16x16/actions/go-home.png) } 4 .icon-home { background-image: url(Tango/16x16/actions/go-home.png) }
4 .icon-home-not { background-image: url(mod/16x16/actions/go-home-not.png) } 5 .icon-home-not { background-image: url(mod/16x16/actions/go-home-not.png) }
public/javascripts/city_state_validation.js 0 → 100644
@@ -0,0 +1,60 @@ @@ -0,0 +1,60 @@
  1 +(function($){
  2 + autoCompleteStateCity($);
  3 + $('[id$="_country"]').change(function(){
  4 + autoCompleteStateCity($);
  5 + })
  6 +})(jQuery);
  7 +
  8 +function autoCompleteStateCity($) {
  9 + var country_selected = $('[id$="_country"] option:selected').val()
  10 + if(country_selected == "BR")
  11 + {
  12 + $('#state_field').autocomplete({
  13 + source : function(request, response){
  14 + $.ajax({
  15 + type: "GET",
  16 + url: '/account/search_state',
  17 + data: {state_name: request.term},
  18 + success: function(result){
  19 + response(result);
  20 + },
  21 + error: function(ajax, stat, errorThrown) {
  22 + console.log('Link not found : ' + errorThrown);
  23 + }
  24 + });
  25 + },
  26 +
  27 + minLength: 3
  28 + });
  29 +
  30 + $('#city_field').autocomplete({
  31 + source : function(request, response){
  32 + $.ajax({
  33 + type: "GET",
  34 + url: '/account/search_cities',
  35 + data: {city_name: request.term, state_name: $("#state_field").val()},
  36 + success: function(result){
  37 + response(result);
  38 + },
  39 + error: function(ajax, stat, errorThrown) {
  40 + console.log('Link not found : ' + errorThrown);
  41 + }
  42 + });
  43 + },
  44 +
  45 + minLength: 3
  46 + });
  47 + }
  48 + else
  49 + {
  50 + if ($('#state_field').data('autocomplete')) {
  51 + $('#state_field').autocomplete("destroy");
  52 + $('#state_field').removeData('autocomplete');
  53 + }
  54 +
  55 + if ($('#city_field').data('autocomplete')) {
  56 + $('#city_field').autocomplete("destroy");
  57 + $('#city_field').removeData('autocomplete');
  58 + }
  59 + }
  60 +}
public/javascripts/signup_form.js 0 → 100644
@@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
  1 +function verifyLoginLoad() {
  2 + jQuery('#user_login').removeClass('available unavailable valid validated invalid checking').addClass('checking');
  3 + jQuery('#url-check').html(jQuery('#checking-message').html());
  4 +}
  5 +
  6 +function verifyLoginAjax(value) {
  7 + verifyLoginLoad();
  8 +
  9 + jQuery.get(
  10 + "/account/check_valid_name",
  11 + {'identifier': encodeURIComponent(value)},
  12 + function(request){
  13 + jQuery('#user_login').removeClass('checking');
  14 + jQuery("#url-check").html(request);
  15 + }
  16 + );
  17 +}
  18 +
  19 +jQuery(document).ready(function(){
  20 + jQuery("#user_login").blur(function(){
  21 + verifyLoginAjax(this.value);
  22 + });
  23 +});
public/stylesheets/application.css
@@ -6040,6 +6040,11 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { @@ -6040,6 +6040,11 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6040 text-align: right; 6040 text-align: right;
6041 } 6041 }
6042 6042
  6043 +#url-check .suggested_usernames,
  6044 +#url-check .suggested_usernames a {
  6045 + color: #005000;
  6046 +}
  6047 +
6043 #email-check, 6048 #email-check,
6044 #fake-check, 6049 #fake-check,
6045 #password-rate, 6050 #password-rate,
test/functional/account_controller_test.rb
@@ -8,7 +8,6 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -8,7 +8,6 @@ class AccountControllerTest &lt; ActionController::TestCase
8 # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead 8 # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead
9 # Then, you can remove it from this and the units test. 9 # Then, you can remove it from this and the units test.
10 include AuthenticatedTestHelper 10 include AuthenticatedTestHelper
11 -  
12 all_fixtures 11 all_fixtures
13 12
14 def teardown 13 def teardown
@@ -17,8 +16,8 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -17,8 +16,8 @@ class AccountControllerTest &lt; ActionController::TestCase
17 16
18 def setup 17 def setup
19 @controller = AccountController.new 18 @controller = AccountController.new
20 - @request = ActionController::TestRequest.new  
21 - @response = ActionController::TestResponse.new 19 + @request = ActionController::TestRequest.new
  20 + @response = ActionController::TestResponse.new
22 disable_signup_bot_check 21 disable_signup_bot_check
23 end 22 end
24 23
@@ -646,21 +645,28 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -646,21 +645,28 @@ class AccountControllerTest &lt; ActionController::TestCase
646 assert_redirected_to :controller => 'home', :action => 'index' 645 assert_redirected_to :controller => 'home', :action => 'index'
647 end 646 end
648 647
649 - should 'check_url is available on environment' do 648 + should 'check_valid_name is available on environment' do
650 env = fast_create(Environment, :name => 'Environment test') 649 env = fast_create(Environment, :name => 'Environment test')
651 @controller.expects(:environment).returns(env).at_least_once 650 @controller.expects(:environment).returns(env).at_least_once
652 profile = create_user('mylogin').person 651 profile = create_user('mylogin').person
653 - get :check_url, :identifier => 'mylogin' 652 + get :check_valid_name, :identifier => 'mylogin'
654 assert_equal 'validated', assigns(:status_class) 653 assert_equal 'validated', assigns(:status_class)
655 end 654 end
656 655
657 should 'check if url is not available on environment' do 656 should 'check if url is not available on environment' do
658 @controller.expects(:environment).returns(Environment.default).at_least_once 657 @controller.expects(:environment).returns(Environment.default).at_least_once
659 profile = create_user('mylogin').person 658 profile = create_user('mylogin').person
660 - get :check_url, :identifier => 'mylogin' 659 + get :check_valid_name, :identifier => 'mylogin'
661 assert_equal 'invalid', assigns(:status_class) 660 assert_equal 'invalid', assigns(:status_class)
662 end 661 end
663 662
  663 + should 'suggest a list with three possible usernames' do
  664 + profile = create_user('mylogin').person
  665 + get :check_valid_name, :identifier => 'mylogin'
  666 +
  667 + assert_equal 3, assigns(:suggested_usernames).uniq.size
  668 + end
  669 +
664 should 'check if e-mail is available on environment' do 670 should 'check if e-mail is available on environment' do
665 env = fast_create(Environment, :name => 'Environment test') 671 env = fast_create(Environment, :name => 'Environment test')
666 @controller.expects(:environment).returns(env).at_least_once 672 @controller.expects(:environment).returns(env).at_least_once
@@ -926,6 +932,30 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -926,6 +932,30 @@ class AccountControllerTest &lt; ActionController::TestCase
926 assert @response.body.blank? 932 assert @response.body.blank?
927 end 933 end
928 934
  935 + should "Search for state" do
  936 + create_state_and_city
  937 +
  938 + xhr :get, :search_state, :state_name=>"Rio Grande"
  939 +
  940 + json_response = ActiveSupport::JSON.decode(@response.body)
  941 + label = json_response[0]['label']
  942 +
  943 + assert_equal label, "Rio Grande do Sul"
  944 + end
  945 +
  946 + should "Search for city" do
  947 + create_state_and_city
  948 +
  949 + xhr :get, :search_cities, :state_name=>"Rio Grande do Sul", :city_name=>"Lavras"
  950 +
  951 + json_response = ActiveSupport::JSON.decode(@response.body)
  952 + label = json_response[0]['label']
  953 + category = json_response[0]['category']
  954 +
  955 + assert_equal category, "Rio Grande do Sul"
  956 + assert_equal label, "Lavras do Sul"
  957 + end
  958 +
929 protected 959 protected
930 def new_user(options = {}, extra_options ={}) 960 def new_user(options = {}, extra_options ={})
931 data = {:profile_data => person_data} 961 data = {:profile_data => person_data}
@@ -954,4 +984,18 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -954,4 +984,18 @@ class AccountControllerTest &lt; ActionController::TestCase
954 environment.min_signup_delay = 0 984 environment.min_signup_delay = 0
955 environment.save! 985 environment.save!
956 end 986 end
  987 +
  988 + def create_state_and_city
  989 + city = 'Lavras do Sul'
  990 + state = 'Rio Grande do Sul'
  991 +
  992 + parent_region = fast_create(NationalRegion, :name => state,
  993 + :national_region_code => '43',
  994 + :national_region_type_id => NationalRegionType::STATE)
  995 +
  996 + fast_create(NationalRegion, :name => city,
  997 + :national_region_code => '431150',
  998 + :national_region_type_id => NationalRegionType::CITY,
  999 + :parent_national_region_code => parent_region.national_region_code)
  1000 + end
957 end 1001 end
test/functional/content_viewer_controller_test.rb
@@ -72,9 +72,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -72,9 +72,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
72 get :view_page, :profile => 'someone', :page => [ '500.html' ] 72 get :view_page, :profile => 'someone', :page => [ '500.html' ]
73 73
74 assert_response :success 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 end 76 end
79 77
80 should 'produce a download-link when article is not text/html' do 78 should 'produce a download-link when article is not text/html' do
@@ -577,14 +575,6 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -577,14 +575,6 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
577 assert_template 'view_page' 575 assert_template 'view_page'
578 end 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 should "display 'Upload files' when create children of image gallery" do 578 should "display 'Upload files' when create children of image gallery" do
589 login_as(profile.identifier) 579 login_as(profile.identifier)
590 f = Gallery.create!(:name => 'gallery', :profile => profile) 580 f = Gallery.create!(:name => 'gallery', :profile => profile)
@@ -1360,8 +1350,23 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1360,8 +1350,23 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1360 1350
1361 should 'display link to download of non-recognized file types on its page' do 1351 should 'display link to download of non-recognized file types on its page' do
1362 file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/test.txt', 'bin/unknown'), :profile => profile) 1352 file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/test.txt', 'bin/unknown'), :profile => profile)
1363 - get :view_page, file.url.merge(:view=>:true)  
1364 - assert_match /this is a sample text file/, @response.body 1353 + get :view_page, file.url
  1354 + assert_match /#{file.public_filename}/, @response.body
  1355 + end
  1356 +
  1357 + should 'not count hit from bots' do
  1358 + article = fast_create(Article, :profile_id => profile.id)
  1359 + assert_no_difference article, :hits do
  1360 + @request.env['HTTP_USER_AGENT'] = 'bot'
  1361 + get 'view_page', :profile => profile.identifier, :page => article.path.split('/')
  1362 + @request.env['HTTP_USER_AGENT'] = 'spider'
  1363 + get 'view_page', :profile => profile.identifier, :page => article.path.split('/')
  1364 + @request.env['HTTP_USER_AGENT'] = 'crawler'
  1365 + get 'view_page', :profile => profile.identifier, :page => article.path.split('/')
  1366 + @request.env['HTTP_USER_AGENT'] = '(http://some-crawler.com)'
  1367 + get 'view_page', :profile => profile.identifier, :page => article.path.split('/')
  1368 + article.reload
  1369 + end
1365 end 1370 end
1366 1371
1367 should 'add meta tags with article info' do 1372 should 'add meta tags with article info' do
test/functional/embed_controller_test.rb 0 → 100644
@@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class EmbedControllerTest < ActionController::TestCase
  4 +
  5 + def setup
  6 + login_as(create_admin_user(Environment.default))
  7 + @block = LoginBlock.create!
  8 + @block.class.any_instance.stubs(:embedable?).returns(true)
  9 + @environment = Environment.default
  10 + @environment.boxes.create!
  11 + @environment.boxes.first.blocks << @block
  12 + end
  13 +
  14 + should 'be able to get embed block' do
  15 + get :block, :id => @block.id
  16 + assert_tag :tag => 'div', :attributes => { :id => "block-#{@block.id}" }
  17 + end
  18 +
  19 + should 'display error message when not found block' do
  20 + Block.delete_all
  21 + get :block, :id => 1
  22 + assert_tag :tag => 'div', :attributes => { :id => "not-found" }
  23 + end
  24 +
  25 + should 'display error message when block is not visible/public' do
  26 + @block.display = 'never'
  27 + assert @block.save
  28 + get :block, :id => @block.id
  29 + assert_tag :tag => 'div', :attributes => { :id => "unavailable" }
  30 + end
  31 +
  32 + should 'display error message when block is not embedable' do
  33 + @block.class.any_instance.stubs(:embedable?).returns(false)
  34 + get :block, :id => @block.id
  35 + assert_tag :tag => 'div', :attributes => { :id => "unavailable" }
  36 + end
  37 +
  38 +
  39 +end
test/functional/events_controller_test.rb
@@ -46,4 +46,12 @@ class EventsControllerTest &lt; ActionController::TestCase @@ -46,4 +46,12 @@ class EventsControllerTest &lt; ActionController::TestCase
46 assert_equal 20, assigns(:events).count 46 assert_equal 20, assigns(:events).count
47 end 47 end
48 48
  49 + should 'show events of specific day' do
  50 + profile.events << Event.new(:name => 'Joao Birthday', :start_date => Date.new(2009, 10, 28))
  51 +
  52 + get :events_by_day, :profile => profile.identifier, :year => 2009, :month => 10, :day => 28
  53 +
  54 + assert_tag :tag => 'a', :content => /Joao Birthday/
  55 + end
  56 +
49 end 57 end
test/functional/search_controller_test.rb
@@ -74,14 +74,14 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -74,14 +74,14 @@ class SearchControllerTest &lt; ActionController::TestCase
74 assert_includes assigns(:searches)[:articles][:results], art 74 assert_includes assigns(:searches)[:articles][:results], art
75 end 75 end
76 76
77 - should 'redirect contents to articles' do 77 + should 'redirect contents to articles' do
78 person = fast_create(Person) 78 person = fast_create(Person)
79 art = create_article_with_optional_category('an article to be found', person) 79 art = create_article_with_optional_category('an article to be found', person)
80 80
81 get 'contents', :query => 'article found' 81 get 'contents', :query => 'article found'
82 - # full description to avoid deprecation warning 82 + # full description to avoid deprecation warning
83 assert_redirected_to :controller => :search, :action => :articles, :query => 'article found' 83 assert_redirected_to :controller => :search, :action => :articles, :query => 'article found'
84 - end 84 + end
85 85
86 # 'assets' outside any category 86 # 'assets' outside any category
87 should 'list articles in general' do 87 should 'list articles in general' do
@@ -259,10 +259,10 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -259,10 +259,10 @@ class SearchControllerTest &lt; ActionController::TestCase
259 259
260 should 'render specific action when only one asset is enabled' do 260 should 'render specific action when only one asset is enabled' do
261 environment = Environment.default 261 environment = Environment.default
262 - # article is not disabled 262 + # article is not disabled
263 [:enterprises, :people, :communities, :products, :events].select do |key, name| 263 [:enterprises, :people, :communities, :products, :events].select do |key, name|
264 - environment.enable('disable_asset_' + key.to_s)  
265 - end 264 + environment.enable('disable_asset_' + key.to_s)
  265 + end
266 environment.save! 266 environment.save!
267 @controller.stubs(:environment).returns(environment) 267 @controller.stubs(:environment).returns(environment)
268 268
@@ -274,25 +274,25 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -274,25 +274,25 @@ class SearchControllerTest &lt; ActionController::TestCase
274 assert !assigns(:searches).has_key?(:communities) 274 assert !assigns(:searches).has_key?(:communities)
275 assert !assigns(:searches).has_key?(:products) 275 assert !assigns(:searches).has_key?(:products)
276 assert !assigns(:searches).has_key?(:events) 276 assert !assigns(:searches).has_key?(:events)
277 - end 277 + end
278 278
279 should 'search all enabled assets in general search' do 279 should 'search all enabled assets in general search' do
280 ent1 = create_profile_with_optional_category(Enterprise, 'test enterprise') 280 ent1 = create_profile_with_optional_category(Enterprise, 'test enterprise')
281 prod_cat = ProductCategory.create!(:name => 'pctest', :environment => Environment.default) 281 prod_cat = ProductCategory.create!(:name => 'pctest', :environment => Environment.default)
282 prod = ent1.products.create!(:name => 'test product', :product_category => prod_cat) 282 prod = ent1.products.create!(:name => 'test product', :product_category => prod_cat)
283 - art = Article.create!(:name => 'test article', :profile_id => fast_create(Person).id)  
284 - per = Person.create!(:name => 'test person', :identifier => 'test-person', :user_id => fast_create(User).id)  
285 - com = Community.create!(:name => 'test community')  
286 - eve = Event.create!(:name => 'test event', :profile_id => fast_create(Person).id) 283 + art = Article.create!(:name => 'test article', :profile_id => fast_create(Person).id)
  284 + per = Person.create!(:name => 'test person', :identifier => 'test-person', :user_id => fast_create(User).id)
  285 + com = Community.create!(:name => 'test community')
  286 + eve = Event.create!(:name => 'test event', :profile_id => fast_create(Person).id)
287 287
288 get :index, :query => 'test' 288 get :index, :query => 'test'
289 289
290 [:articles, :enterprises, :people, :communities, :products, :events].select do |key, name| 290 [:articles, :enterprises, :people, :communities, :products, :events].select do |key, name|
291 - !assigns(:environment).enabled?('disable_asset_' + key.to_s)  
292 - end.each do |asset|  
293 - assert !assigns(:searches)[asset][:results].empty?  
294 - end  
295 - end 291 + !assigns(:environment).enabled?('disable_asset_' + key.to_s)
  292 + end.each do |asset|
  293 + assert !assigns(:searches)[asset][:results].empty?
  294 + end
  295 + end
296 296
297 should 'display category image while in directory' do 297 should 'display category image while in directory' do
298 parent = Category.create!(:name => 'category1', :environment => Environment.default) 298 parent = Category.create!(:name => 'category1', :environment => Environment.default)
@@ -318,8 +318,8 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -318,8 +318,8 @@ class SearchControllerTest &lt; ActionController::TestCase
318 person = create_user('someone').person 318 person = create_user('someone').person
319 ten_days_ago = Date.today - 10.day 319 ten_days_ago = Date.today - 10.day
320 320
321 - ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], :start_date => ten_days_ago)  
322 - ev2 = create_event(person, :name => 'event 2', :category_ids => [@category.id], :start_date => Date.today - 2.month) 321 + ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], :start_date => ten_days_ago)
  322 + ev2 = create_event(person, :name => 'event 2', :category_ids => [@category.id], :start_date => Date.today - 2.month)
323 323
324 get :events, :day => ten_days_ago.day, :month => ten_days_ago.month, :year => ten_days_ago.year 324 get :events, :day => ten_days_ago.day, :month => ten_days_ago.month, :year => ten_days_ago.year
325 assert_equal [ev1], assigns(:events) 325 assert_equal [ev1], assigns(:events)
@@ -329,7 +329,7 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -329,7 +329,7 @@ class SearchControllerTest &lt; ActionController::TestCase
329 person = create_user('someone').person 329 person = create_user('someone').person
330 ten_days_ago = Date.today - 10.day 330 ten_days_ago = Date.today - 10.day
331 331
332 - ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], :start_date => ten_days_ago) 332 + ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], :start_date => ten_days_ago)
333 ev2 = create_event(person, :name => 'event 2', :start_date => ten_days_ago) 333 ev2 = create_event(person, :name => 'event 2', :start_date => ten_days_ago)
334 334
335 get :events, :day => ten_days_ago.day, :month => ten_days_ago.month, :year => ten_days_ago.year, :category_path => @category.path.split('/') 335 get :events, :day => ten_days_ago.day, :month => ten_days_ago.month, :year => ten_days_ago.year, :category_path => @category.path.split('/')
@@ -339,8 +339,8 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -339,8 +339,8 @@ class SearchControllerTest &lt; ActionController::TestCase
339 339
340 should 'return events of today when no date specified' do 340 should 'return events of today when no date specified' do
341 person = create_user('someone').person 341 person = create_user('someone').person
342 - ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], :start_date => Date.today)  
343 - ev2 = create_event(person, :name => 'event 2', :category_ids => [@category.id], :start_date => Date.today - 2.month) 342 + ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], :start_date => Date.today)
  343 + ev2 = create_event(person, :name => 'event 2', :category_ids => [@category.id], :start_date => Date.today - 2.month)
344 344
345 get :events 345 get :events
346 346
@@ -351,9 +351,9 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -351,9 +351,9 @@ class SearchControllerTest &lt; ActionController::TestCase
351 person = create_user('someone').person 351 person = create_user('someone').person
352 352
353 ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], 353 ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id],
354 - :start_date => Date.today + 2.month) 354 + :start_date => Date.today + 2.month)
355 ev2 = create_event(person, :name => 'event 2', :category_ids => [@category.id], 355 ev2 = create_event(person, :name => 'event 2', :category_ids => [@category.id],
356 - :start_date => Date.today + 2.day) 356 + :start_date => Date.today + 2.day)
357 357
358 get :events 358 get :events
359 359
@@ -373,8 +373,9 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -373,8 +373,9 @@ class SearchControllerTest &lt; ActionController::TestCase
373 end 373 end
374 374
375 should 'see the events paginated' do 375 should 'see the events paginated' do
  376 + person = create_user('testuser').person
376 30.times do |i| 377 30.times do |i|
377 - create_event(person, :name => "Event #{i}", :start_date => Date.today) 378 + create_event(person, :name => "Event #{i}", :start_date => Date.today)
378 end 379 end
379 get :events 380 get :events
380 assert_equal 20, assigns(:events).count 381 assert_equal 20, assigns(:events).count
@@ -433,8 +434,8 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -433,8 +434,8 @@ class SearchControllerTest &lt; ActionController::TestCase
433 end 434 end
434 435
435 should 'show link to article asset in the see all foot link of the articles block in the category page' do 436 should 'show link to article asset in the see all foot link of the articles block in the category page' do
436 - (1..SearchController::MULTIPLE_SEARCH_LIMIT+1).each do |i|  
437 - a = create_user("test#{i}").person.articles.create!(:name => "article #{i} to be found") 437 + (1..SearchController::MULTIPLE_SEARCH_LIMIT+1).each do |i|
  438 + a = create_user("test#{i}").person.articles.create!(:name => "article #{i} to be found")
438 ArticleCategorization.add_category_to_article(@category, a) 439 ArticleCategorization.add_category_to_article(@category, a)
439 end 440 end
440 441
@@ -580,55 +581,55 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -580,55 +581,55 @@ class SearchControllerTest &lt; ActionController::TestCase
580 assert_not_includes assigns(:searches)[:communities][:results], p1 581 assert_not_includes assigns(:searches)[:communities][:results], p1
581 end 582 end
582 583
583 - should 'keep old urls working' do  
584 - get :assets, :asset => 'articles' 584 + should 'keep old urls working' do
  585 + get :assets, :asset => 'articles'
585 assert_redirected_to :controller => :search, :action => :articles 586 assert_redirected_to :controller => :search, :action => :articles
586 - get :assets, :asset => 'people' 587 + get :assets, :asset => 'people'
587 assert_redirected_to :controller => :search, :action => :people 588 assert_redirected_to :controller => :search, :action => :people
588 - get :assets, :asset => 'communities' 589 + get :assets, :asset => 'communities'
589 assert_redirected_to :controller => :search, :action => :communities 590 assert_redirected_to :controller => :search, :action => :communities
590 - get :assets, :asset => 'products' 591 + get :assets, :asset => 'products'
591 assert_redirected_to :controller => :search, :action => :products 592 assert_redirected_to :controller => :search, :action => :products
592 - get :assets, :asset => 'enterprises' 593 + get :assets, :asset => 'enterprises'
593 assert_redirected_to :controller => :search, :action => :enterprises 594 assert_redirected_to :controller => :search, :action => :enterprises
594 - get :assets, :asset => 'events' 595 + get :assets, :asset => 'events'
595 assert_redirected_to :controller => :search, :action => :events 596 assert_redirected_to :controller => :search, :action => :events
596 - end 597 + end
597 598
598 - should 'show tag cloud' do  
599 - @controller.stubs(:is_cache_expired?).returns(true) 599 + should 'show tag cloud' do
  600 + @controller.stubs(:is_cache_expired?).returns(true)
600 a = Article.create!(:name => 'my article', :profile_id => fast_create(Person).id) 601 a = Article.create!(:name => 'my article', :profile_id => fast_create(Person).id)
601 a.tag_list = ['one', 'two'] 602 a.tag_list = ['one', 'two']
602 - a.save_tags 603 + a.save_tags
603 604
604 - get :tags 605 + get :tags
605 606
606 - assert assigns(:tags)["two"] = 1  
607 - assert assigns(:tags)["one"] = 1  
608 - end 607 + assert assigns(:tags)["two"] = 1
  608 + assert assigns(:tags)["one"] = 1
  609 + end
609 610
610 should 'show tagged content' do 611 should 'show tagged content' do
611 - @controller.stubs(:is_cache_expired?).returns(true) 612 + @controller.stubs(:is_cache_expired?).returns(true)
612 a = Article.create!(:name => 'my article', :profile_id => fast_create(Person).id) 613 a = Article.create!(:name => 'my article', :profile_id => fast_create(Person).id)
613 a2 = Article.create!(:name => 'my article 2', :profile_id => fast_create(Person).id) 614 a2 = Article.create!(:name => 'my article 2', :profile_id => fast_create(Person).id)
614 a.tag_list = ['one', 'two'] 615 a.tag_list = ['one', 'two']
615 a2.tag_list = ['two', 'three'] 616 a2.tag_list = ['two', 'three']
616 - a.save_tags 617 + a.save_tags
617 a2.save_tags 618 a2.save_tags
618 619
619 - get :tag, :tag => 'two' 620 + get :tag, :tag => 'two'
620 621
621 assert_equivalent [a, a2], assigns(:searches)[:tag][:results] 622 assert_equivalent [a, a2], assigns(:searches)[:tag][:results]
622 623
623 - get :tag, :tag => 'one' 624 + get :tag, :tag => 'one'
624 625
625 assert_equivalent [a], assigns(:searches)[:tag][:results] 626 assert_equivalent [a], assigns(:searches)[:tag][:results]
626 end 627 end
627 628
628 should 'not show assets from other environments' do 629 should 'not show assets from other environments' do
629 other_env = Environment.create!(:name => 'Another environment') 630 other_env = Environment.create!(:name => 'Another environment')
630 - p1 = Person.create!(:name => 'Hildebrando', :identifier => 'hild', :user_id => fast_create(User).id, :environment_id => other_env.id)  
631 - p2 = Person.create!(:name => 'Adamastor', :identifier => 'adam', :user_id => fast_create(User).id) 631 + p1 = Person.create!(:name => 'Hildebrando', :identifier => 'hild', :user_id => fast_create(User).id, :environment_id => other_env.id)
  632 + p2 = Person.create!(:name => 'Adamastor', :identifier => 'adam', :user_id => fast_create(User).id)
632 art1 = Article.create!(:name => 'my article', :profile_id => p1.id) 633 art1 = Article.create!(:name => 'my article', :profile_id => p1.id)
633 art2 = Article.create!(:name => 'my article', :profile_id => p2.id) 634 art2 = Article.create!(:name => 'my article', :profile_id => p2.id)
634 635
@@ -639,9 +640,9 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -639,9 +640,9 @@ class SearchControllerTest &lt; ActionController::TestCase
639 640
640 should 'order articles by more recent' do 641 should 'order articles by more recent' do
641 Article.destroy_all 642 Article.destroy_all
642 - art1 = Article.create!(:name => 'review C', :profile_id => fast_create(Person).id, :created_at => Time.now-1.days)  
643 - art2 = Article.create!(:name => 'review A', :profile_id => fast_create(Person).id, :created_at => Time.now)  
644 - art3 = Article.create!(:name => 'review B', :profile_id => fast_create(Person).id, :created_at => Time.now-2.days) 643 + art1 = Article.create!(:name => 'review C', :profile_id => fast_create(Person).id, :created_at => Time.now-1.days)
  644 + art2 = Article.create!(:name => 'review A', :profile_id => fast_create(Person).id, :created_at => Time.now)
  645 + art3 = Article.create!(:name => 'review B', :profile_id => fast_create(Person).id, :created_at => Time.now-2.days)
645 646
646 get :articles, :filter => :more_recent 647 get :articles, :filter => :more_recent
647 648
test/integration/routing_test.rb
@@ -270,5 +270,8 @@ class RoutingTest &lt; ActionController::IntegrationTest @@ -270,5 +270,8 @@ class RoutingTest &lt; ActionController::IntegrationTest
270 assert_routing('/work/free-software/versions', :controller => 'content_viewer', :action => 'article_versions', :page => [ 'work', 'free-software'] ) 270 assert_routing('/work/free-software/versions', :controller => 'content_viewer', :action => 'article_versions', :page => [ 'work', 'free-software'] )
271 end 271 end
272 272
  273 + should 'have route to get HTML code of Blocks to embed' do
  274 + assert_routing('/embed/block/12345', :controller => 'embed', :action => 'block', :id => '12345')
  275 + end
273 276
274 end 277 end
test/unit/account_helper_test.rb 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class AccountHelperTest < ActiveSupport::TestCase
  4 +
  5 + include AccountHelper
  6 + include ActionView::Helpers::TagHelper
  7 +
  8 + should 'not suggest usernames if username is empty' do
  9 + assert_equal '', suggestion_based_on_username
  10 + end
  11 +
  12 + should 'suggest valid usernames' do
  13 + ze = create_user('ze').person
  14 + stubs(:environment).returns(ze.environment)
  15 + suggestions = suggestion_based_on_username('ze')
  16 + suggestions.each do |suggestion|
  17 + assert_equal true, Person.is_available?(suggestion, ze.environment)
  18 + end
  19 + end
  20 +
  21 +end
test/unit/block_test.rb
@@ -223,6 +223,16 @@ class BlockTest &lt; ActiveSupport::TestCase @@ -223,6 +223,16 @@ class BlockTest &lt; ActiveSupport::TestCase
223 assert !block.visible?(3) 223 assert !block.visible?(3)
224 end 224 end
225 225
  226 + should 'not be embedable by default' do
  227 + assert !Block.new.embedable?
  228 + end
  229 +
  230 + should 'generate embed code' do
  231 + b = Block.new
  232 + b.stubs(:url_for).returns('http://myblogtest.com/embed/block/1')
  233 + assert_equal "<iframe class=\"embed block block\" frameborder=\"0\" height=\"768\" src=\"http://myblogtest.com/embed/block/1\" width=\"1024\"></iframe>", b.embed_code.call
  234 + end
  235 +
226 should 'default value for display_user is all' do 236 should 'default value for display_user is all' do
227 block = Block.new 237 block = Block.new
228 assert_equal 'all', block.display_user 238 assert_equal 'all', block.display_user
test/unit/profile_test.rb
@@ -363,7 +363,7 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -363,7 +363,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
363 t2 = c.tasks.build; t2.save!; t2.finish 363 t2 = c.tasks.build; t2.save!; t2.finish
364 t3 = c.tasks.build; t3.save!; t3.finish 364 t3 = c.tasks.build; t3.save!; t3.finish
365 365
366 - assert_equal [t2, t3], c.tasks.finished 366 + assert_equivalent [t2, t3], c.tasks.finished
367 end 367 end
368 368
369 should 'responds to categories' do 369 should 'responds to categories' do
test/unit/tags_helper_test.rb
@@ -20,12 +20,14 @@ class TagsHelperTest &lt; ActiveSupport::TestCase @@ -20,12 +20,14 @@ class TagsHelperTest &lt; ActiveSupport::TestCase
20 20
21 should 'order tags alphabetically with special characters' do 21 should 'order tags alphabetically with special characters' do
22 result = tag_cloud( 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 :id, 25 :id,
26 { :host=>'noosfero.org', :controller=>'test', :action=>'tag' } 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 end 31 end
30 32
31 end 33 end
test/unit/text_article_test.rb
@@ -37,4 +37,51 @@ class TextArticleTest &lt; ActiveSupport::TestCase @@ -37,4 +37,51 @@ class TextArticleTest &lt; ActiveSupport::TestCase
37 assert_equal Blog.icon_name, TextArticle.icon_name(article) 37 assert_equal Blog.icon_name, TextArticle.icon_name(article)
38 end 38 end
39 39
  40 + should 'change image path to relative' do
  41 + person = create_user('testuser').person
  42 + article = TextArticle.new(:profile => person, :name => 'test')
  43 + env = Environment.default
  44 + article.body = "<img src=\"http://#{env.default_hostname}/test.png\" />"
  45 + article.save!
  46 + assert_equal "<img src=\"/test.png\" />", article.body
  47 + end
  48 +
  49 + should 'change link to relative path' do
  50 + person = create_user('testuser').person
  51 + article = TextArticle.new(:profile => person, :name => 'test')
  52 + env = Environment.default
  53 + article.body = "<a href=\"http://#{env.default_hostname}/test\">test</a>"
  54 + article.save!
  55 + assert_equal "<a href=\"/test\">test</a>", article.body
  56 + end
  57 +
  58 + should 'change image path to relative for domain with https' do
  59 + person = create_user('testuser').person
  60 + article = TextArticle.new(:profile => person, :name => 'test')
  61 + env = Environment.default
  62 + article.body = "<img src=\"https://#{env.default_hostname}/test.png\" />"
  63 + article.save!
  64 + assert_equal "<img src=\"/test.png\" />", article.body
  65 + end
  66 +
  67 + should 'change image path to relative for domain with port' do
  68 + person = create_user('testuser').person
  69 + article = TextArticle.new(:profile => person, :name => 'test')
  70 + env = Environment.default
  71 + article.body = "<img src=\"http://#{env.default_hostname}:3000/test.png\" />"
  72 + article.save!
  73 + assert_equal "<img src=\"/test.png\" />", article.body
  74 + end
  75 +
  76 + should 'change image path to relative for domain with www' do
  77 + person = create_user('testuser').person
  78 + article = TextArticle.new(:profile => person, :name => 'test')
  79 + env = Environment.default
  80 + env.force_www = true
  81 + env.save!
  82 + article.body = "<img src=\"http://#{env.default_hostname}:3000/test.png\" />"
  83 + article.save!
  84 + assert_equal "<img src=\"/test.png\" />", article.body
  85 + end
  86 +
40 end 87 end
test/unit/uploaded_file_test.rb
@@ -324,13 +324,11 @@ class UploadedFileTest &lt; ActiveSupport::TestCase @@ -324,13 +324,11 @@ class UploadedFileTest &lt; ActiveSupport::TestCase
324 should 'group trackers activity of image\'s upload' do 324 should 'group trackers activity of image\'s upload' do
325 ActionTracker::Record.delete_all 325 ActionTracker::Record.delete_all
326 gallery = fast_create(Gallery, :profile_id => profile.id) 326 gallery = fast_create(Gallery, :profile_id => profile.id)
327 - count = ActionTracker::Record.find_all_by_verb('upload_image').count  
328 image1 = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => gallery, :profile => profile) 327 image1 = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => gallery, :profile => profile)
329 - count += 1  
330 - assert_equal count, ActionTracker::Record.find_all_by_verb('upload_image').count 328 + assert_equal 1, ActionTracker::Record.find_all_by_verb('upload_image').count
331 329
332 image2 = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg'), :parent => gallery, :profile => profile) 330 image2 = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg'), :parent => gallery, :profile => profile)
333 - assert_equal count, ActionTracker::Record.find_all_by_verb('upload_image').count 331 + assert_equal 1, ActionTracker::Record.find_all_by_verb('upload_image').count
334 end 332 end
335 333
336 { 334 {