Commit af190be9024982c5d0fdd088782174420a3bf65c

Authored by Daniela Feitosa
2 parents cbcad870 d5f224bb

Merge branch 'rails235'

Conflicts:
	features/categories_block.feature
	public/stylesheets/application.css
Showing 92 changed files with 1924 additions and 205 deletions   Show diff stats
app/controllers/box_organizer_controller.rb
@@ -80,6 +80,22 @@ class BoxOrganizerController < ApplicationController @@ -80,6 +80,22 @@ class BoxOrganizerController < ApplicationController
80 render :action => 'edit', :layout => false 80 render :action => 'edit', :layout => false
81 end 81 end
82 82
  83 + def search_autocomplete
  84 + if request.xhr? and params[:query]
  85 + search = params[:query]
  86 + path_list = if boxes_holder.is_a?(Environment) && boxes_holder.enabled?('use_portal_community') && boxes_holder.portal_community
  87 + boxes_holder.portal_community.articles.find(:all, :conditions=>"name ILIKE '%#{search}%' or path ILIKE '%#{search}%'", :limit=>20).map { |content| "/{portal}/"+content.path }
  88 + elsif boxes_holder.is_a?(Profile)
  89 + boxes_holder.articles.find(:all, :conditions=>"name ILIKE '%#{search}%' or path ILIKE '%#{search}%'", :limit=>20).map { |content| "/{profile}/"+content.path }
  90 + else
  91 + []
  92 + end
  93 + render :json => path_list.to_json
  94 + else
  95 + redirect_to "/"
  96 + end
  97 + end
  98 +
83 def save 99 def save
84 @block = boxes_holder.blocks.find(params[:id]) 100 @block = boxes_holder.blocks.find(params[:id])
85 @block.update_attributes(params[:block]) 101 @block.update_attributes(params[:block])
@@ -99,6 +115,12 @@ class BoxOrganizerController < ApplicationController @@ -99,6 +115,12 @@ class BoxOrganizerController < ApplicationController
99 end 115 end
100 end 116 end
101 117
  118 + def clone_block
  119 + block = Block.find(params[:id])
  120 + block.duplicate
  121 + redirect_to :action => 'index'
  122 + end
  123 +
102 protected :boxes_editor? 124 protected :boxes_editor?
103 125
104 end 126 end
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/my_profile/profile_design_controller.rb
@@ -55,10 +55,4 @@ class ProfileDesignController &lt; BoxOrganizerController @@ -55,10 +55,4 @@ class ProfileDesignController &lt; BoxOrganizerController
55 blocks 55 blocks
56 end 56 end
57 57
58 - def clone  
59 - block = Block.find(params[:id])  
60 - block.duplicate  
61 - redirect_to :action => 'index'  
62 - end  
63 -  
64 end 58 end
app/controllers/public/account_controller.rb
@@ -246,15 +246,19 @@ class AccountController &lt; ApplicationController @@ -246,15 +246,19 @@ class AccountController &lt; ApplicationController
246 end 246 end
247 end 247 end
248 248
249 - def check_url 249 + def check_valid_name
250 @identifier = params[:identifier] 250 @identifier = params[:identifier]
251 valid = Person.is_available?(@identifier, environment) 251 valid = Person.is_available?(@identifier, environment)
252 if valid 252 if valid
253 @status = _('This login name is available') 253 @status = _('This login name is available')
254 @status_class = 'validated' 254 @status_class = 'validated'
255 - else 255 + elsif !@identifier.empty?
  256 + @suggested_usernames = suggestion_based_on_username(@identifier)
256 @status = _('This login name is unavailable') 257 @status = _('This login name is unavailable')
257 @status_class = 'invalid' 258 @status_class = 'invalid'
  259 + else
  260 + @status_class = 'invalid'
  261 + @status = _('This field can\'t be blank')
258 end 262 end
259 render :partial => 'identifier_status' 263 render :partial => 'identifier_status'
260 end 264 end
@@ -287,6 +291,23 @@ class AccountController &lt; ApplicationController @@ -287,6 +291,23 @@ class AccountController &lt; ApplicationController
287 render :text => user_data.to_json, :layout => false, :content_type => "application/javascript" 291 render :text => user_data.to_json, :layout => false, :content_type => "application/javascript"
288 end 292 end
289 293
  294 + def search_cities
  295 + if request.xhr? and params[:state_name] and params[:city_name]
  296 + render :json => MapsHelper.search_city(params[:city_name], params[:state_name])
  297 + else
  298 + render :json => [].to_json
  299 + end
  300 + end
  301 +
  302 + def search_state
  303 + if request.xhr? and params[:state_name]
  304 + render :json => MapsHelper.search_state(params[:state_name])
  305 + else
  306 + render :json => [].to_json
  307 + end
  308 + end
  309 +
  310 +
290 protected 311 protected
291 312
292 def redirect? 313 def redirect?
app/controllers/public/content_viewer_controller.rb
@@ -113,6 +113,15 @@ class ContentViewerController &lt; ApplicationController @@ -113,6 +113,15 @@ class ContentViewerController &lt; ApplicationController
113 @comments = @plugins.filter(:unavailable_comments, @comments) 113 @comments = @plugins.filter(:unavailable_comments, @comments)
114 @comments_count = @comments.count 114 @comments_count = @comments.count
115 @comments = @comments.without_reply.paginate(:per_page => per_page, :page => params[:comment_page] ) 115 @comments = @comments.without_reply.paginate(:per_page => per_page, :page => params[:comment_page] )
  116 + @comment_order = params[:comment_order].nil? ? 'oldest' : params[:comment_order]
  117 +
  118 + if request.xhr? and params[:comment_order]
  119 + if @comment_order == 'newest'
  120 + @comments = @comments.reverse
  121 + end
  122 +
  123 + return render :partial => 'comment/comment', :collection => @comments
  124 + end
116 125
117 if params[:slideshow] 126 if params[:slideshow]
118 render :action => 'slideshow', :layout => 'slideshow' 127 render :action => 'slideshow', :layout => 'slideshow'
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
@@ -65,7 +65,7 @@ module BoxesHelper @@ -65,7 +65,7 @@ module BoxesHelper
65 end 65 end
66 66
67 def display_box_content(box, main_content) 67 def display_box_content(box, main_content)
68 - context = { :article => @page, :request_path => request.path, :locale => locale, :params => request.params } 68 + context = { :article => @page, :request_path => request.path, :locale => locale, :params => request.params, :user => user }
69 box_decorator.select_blocks(box.blocks.includes(:box), context).map { |item| display_block(item, main_content) }.join("\n") + box_decorator.block_target(box) 69 box_decorator.select_blocks(box.blocks.includes(:box), context).map { |item| display_block(item, main_content) }.join("\n") + box_decorator.block_target(box)
70 end 70 end
71 71
@@ -212,13 +212,24 @@ module BoxesHelper @@ -212,13 +212,24 @@ module BoxesHelper
212 212
213 if !block.main? 213 if !block.main?
214 buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')}) 214 buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')})
215 - buttons << icon_button(:clone, _('Clone'), { :action => 'clone', :id => block.id }, { :method => 'post' }) 215 + buttons << icon_button(:clone, _('Clone'), { :action => 'clone_block', :id => block.id }, { :method => 'post' })
216 end 216 end
217 217
218 if block.respond_to?(:help) 218 if block.respond_to?(:help)
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/macros_helper.rb
@@ -20,14 +20,16 @@ module MacrosHelper @@ -20,14 +20,16 @@ module MacrosHelper
20 jQuery('<div>'+#{macro_configuration_dialog(macro).to_json}+'</div>').dialog({ 20 jQuery('<div>'+#{macro_configuration_dialog(macro).to_json}+'</div>').dialog({
21 title: #{macro_title(macro).to_json}, 21 title: #{macro_title(macro).to_json},
22 modal: true, 22 modal: true,
23 - buttons: [  
24 - {text: #{_('Ok').to_json}, click: function(){ 23 + buttons: {
  24 + #{_('Ok').to_json}: function(){
25 tinyMCE.activeEditor.execCommand('mceInsertContent', false, 25 tinyMCE.activeEditor.execCommand('mceInsertContent', false,
26 (function(dialog){ #{macro_generator(macro)} })(this)); 26 (function(dialog){ #{macro_generator(macro)} })(this));
27 jQuery(this).dialog('close'); 27 jQuery(this).dialog('close');
28 - }},  
29 - {text: #{_('Cancel').to_json}, click: function(){jQuery(this).dialog('close');}}  
30 - ] 28 + },
  29 + #{_('Cancel').to_json}: function(){
  30 + jQuery(this).dialog('close');
  31 + }
  32 + }
31 }); 33 });
32 }" 34 }"
33 end 35 end
@@ -57,7 +59,11 @@ module MacrosHelper @@ -57,7 +59,11 @@ module MacrosHelper
57 59
58 def macro_generator(macro) 60 def macro_generator(macro)
59 if macro.configuration[:generator] 61 if macro.configuration[:generator]
60 - macro.configuration[:generator] 62 + if macro.configuration[:generator].respond_to?(:call)
  63 + macro.configuration[:generator].call(macro)
  64 + else
  65 + macro.configuration[:generator]
  66 + end
61 else 67 else
62 macro_default_generator(macro) 68 macro_default_generator(macro)
63 end 69 end
@@ -66,8 +72,7 @@ module MacrosHelper @@ -66,8 +72,7 @@ module MacrosHelper
66 72
67 def macro_default_generator(macro) 73 def macro_default_generator(macro)
68 code = "var params = {};" 74 code = "var params = {};"
69 - configuration = macro_configuration(macro)  
70 - configuration[:params].map do |field| 75 + macro.configuration[:params].map do |field|
71 code += "params.#{field[:name]} = jQuery('*[name=#{field[:name]}]', dialog).val();" 76 code += "params.#{field[:name]} = jQuery('*[name=#{field[:name]}]', dialog).val();"
72 end 77 end
73 code + " 78 code + "
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/helpers/token_helper.rb
@@ -27,7 +27,7 @@ module TokenHelper @@ -27,7 +27,7 @@ module TokenHelper
27 hintText: #{options[:hint_text].to_json}, 27 hintText: #{options[:hint_text].to_json},
28 noResultsText: #{options[:no_results_text].to_json}, 28 noResultsText: #{options[:no_results_text].to_json},
29 searchingText: #{options[:searching_text].to_json}, 29 searchingText: #{options[:searching_text].to_json},
30 - searchDelay: #{options[:serach_delay].to_json}, 30 + searchDelay: #{options[:search_delay].to_json},
31 preventDuplicates: #{options[:prevent_duplicates].to_json}, 31 preventDuplicates: #{options[:prevent_duplicates].to_json},
32 backspaceDeleteItem: #{options[:backspace_delete_item].to_json}, 32 backspaceDeleteItem: #{options[:backspace_delete_item].to_json},
33 queryParam: #{name.to_json}, 33 queryParam: #{name.to_json},
app/models/block.rb
@@ -16,17 +16,36 @@ class Block &lt; ActiveRecord::Base @@ -16,17 +16,36 @@ 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:
22 # 39 #
23 # * <tt>:article</tt>: the article being viewed currently 40 # * <tt>:article</tt>: the article being viewed currently
24 # * <tt>:language</tt>: in which language the block will be displayed 41 # * <tt>:language</tt>: in which language the block will be displayed
  42 + # * <tt>:user</tt>: the logged user
25 def visible?(context = nil) 43 def visible?(context = nil)
26 return false if display == 'never' 44 return false if display == 'never'
27 45
28 if context 46 if context
29 return false if language != 'all' && language != context[:locale] 47 return false if language != 'all' && language != context[:locale]
  48 + return false unless display_to_user?(context[:user])
30 49
31 begin 50 begin
32 return self.send("display_#{display}", context) 51 return self.send("display_#{display}", context)
@@ -38,6 +57,10 @@ class Block &lt; ActiveRecord::Base @@ -38,6 +57,10 @@ class Block &lt; ActiveRecord::Base
38 true 57 true
39 end 58 end
40 59
  60 + def display_to_user?(user)
  61 + display_user == 'all' || (user.nil? && display_user == 'not_logged') || (user && display_user == 'logged')
  62 + end
  63 +
41 def display_always(context) 64 def display_always(context)
42 true 65 true
43 end 66 end
@@ -68,6 +91,14 @@ class Block &lt; ActiveRecord::Base @@ -68,6 +91,14 @@ class Block &lt; ActiveRecord::Base
68 # the homepage of its owner. 91 # the homepage of its owner.
69 settings_items :display, :type => :string, :default => 'always' 92 settings_items :display, :type => :string, :default => 'always'
70 93
  94 +
  95 + # The condition for displaying a block to users. It can assume the following values:
  96 + #
  97 + # * <tt>'all'</tt>: the block is always displayed
  98 + # * <tt>'logged'</tt>: the block is displayed to logged users only
  99 + # * <tt>'not_logged'</tt>: the block is displayed only to not logged users
  100 + settings_items :display_user, :type => :string, :default => 'all'
  101 +
71 # The block can be configured to be displayed in all languages or in just one language. It can assume any locale of the environment: 102 # The block can be configured to be displayed in all languages or in just one language. It can assume any locale of the environment:
72 # 103 #
73 # * <tt>'all'</tt>: the block is always displayed 104 # * <tt>'all'</tt>: the block is always displayed
@@ -171,12 +202,20 @@ class Block &lt; ActiveRecord::Base @@ -171,12 +202,20 @@ class Block &lt; ActiveRecord::Base
171 'never' => __('Don\'t display'), 202 'never' => __('Don\'t display'),
172 } 203 }
173 204
174 - def display_options 205 + def display_options_available
175 DISPLAY_OPTIONS.keys 206 DISPLAY_OPTIONS.keys
176 end 207 end
177 208
178 - def display_option_label(option)  
179 - DISPLAY_OPTIONS[option] 209 + def display_options
  210 + DISPLAY_OPTIONS.slice(*display_options_available)
  211 + end
  212 +
  213 + def display_user_options
  214 + @display_user_options ||= {
  215 + 'all' => __('All users'),
  216 + 'logged' => __('Logged'),
  217 + 'not_logged' => __('Not logged'),
  218 + }
180 end 219 end
181 220
182 def duplicate 221 def duplicate
app/models/link_list_block.rb
@@ -70,6 +70,8 @@ class LinkListBlock &lt; Block @@ -70,6 +70,8 @@ class LinkListBlock &lt; Block
70 def expand_address(address) 70 def expand_address(address)
71 add = if owner.respond_to?(:identifier) 71 add = if owner.respond_to?(:identifier)
72 address.gsub('{profile}', owner.identifier) 72 address.gsub('{profile}', owner.identifier)
  73 + elsif owner.is_a?(Environment) && owner.enabled?('use_portal_community') && owner.portal_community
  74 + address.gsub('{portal}', owner.portal_community.identifier)
73 else 75 else
74 address 76 address
75 end 77 end
app/models/main_block.rb
@@ -24,7 +24,7 @@ class MainBlock &lt; Block @@ -24,7 +24,7 @@ class MainBlock &lt; Block
24 false 24 false
25 end 25 end
26 26
27 - def display_options 27 + def display_options_available
28 ['always', 'except_home_page'] 28 ['always', 'except_home_page']
29 end 29 end
30 30
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
@@ -7,6 +7,8 @@ @@ -7,6 +7,8 @@
7 7
8 <% @profile_data = @person %> 8 <% @profile_data = @person %>
9 9
  10 +<%= javascript_include_tag('sign_up_password_rate') %>
  11 +
10 <%= error_messages_for :user, :person, :header_message => _('The account could not be created') %> 12 <%= error_messages_for :user, :person, :header_message => _('The account could not be created') %>
11 13
12 <% labelled_form_for :user, @user, :html => { :multipart => true, :id => 'signup-form', :honeypot => true } do |f| %> 14 <% labelled_form_for :user, @user, :html => { :multipart => true, :id => 'signup-form', :honeypot => true } do |f| %>
@@ -35,24 +37,30 @@ @@ -35,24 +37,30 @@
35 <%= required text_field(:user, :login, :id => 'user_login', 37 <%= required text_field(:user, :login, :id => 'user_login',
36 :onchange => 'this.value = convToValidUsername(this.value);') %> 38 :onchange => 'this.value = convToValidUsername(this.value);') %>
37 <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>
38 </div> 41 </div>
39 <%= 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') %>
40 <br style="clear: both;" /> 43 <br style="clear: both;" />
41 </div> 44 </div>
42 </div> 45 </div>
43 - <%= observe_field 'user_login',  
44 - :url => { :action => 'check_url' },  
45 - :with => 'identifier',  
46 - :update => 'url-check',  
47 - :loading => "jQuery('#user_login').removeClass('#{validation_classes}').addClass('checking');  
48 - jQuery('#url-check').html('<p><span class=\"checking\">#{checking_message(:url)}</span></p>');",  
49 - :complete => "jQuery('#user_login').removeClass('checking')"  
50 - %>  
51 - 46 + <%= javascript_include_tag "signup_form" %>
52 <div id='signup-password'> 47 <div id='signup-password'>
53 <%= required f.password_field(:password, :id => 'user_pw') %> 48 <%= required f.password_field(:password, :id => 'user_pw') %>
54 <%= 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') %>
55 - <div id='fake-check'><p>&nbsp;</p></div> 50 + <div id='password-rate'>
  51 + <p><span class="invalid hidden" id='result-short'>
  52 + <%=_('Short') %>
  53 + </span></p>
  54 + <p><span class="invalid hidden" id='result-bad'>
  55 + <%=_('Bad') %>
  56 + </span></p>
  57 + <p><span class="invalid hidden" id='result-good'>
  58 + <%=_('Good') %>
  59 + </span></p>
  60 + <p><span class="invalid hidden" id='result-strong'>
  61 + <%=_('Strong') %>
  62 + </span></p>
  63 + </div>
56 </div> 64 </div>
57 65
58 <div id='signup-password-confirmation'> 66 <div id='signup-password-confirmation'>
@@ -182,4 +190,9 @@ jQuery(function($) { @@ -182,4 +190,9 @@ jQuery(function($) {
182 else $(this).addClass('validated'); 190 else $(this).addClass('validated');
183 }); 191 });
184 }); 192 });
  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 +}
185 </script> 198 </script>
app/views/box_organizer/_link_list_block.rhtml
  1 +<%= javascript_include_tag "edit-link-list.js" %>
  2 +
1 <strong><%= _('Links') %></strong> 3 <strong><%= _('Links') %></strong>
2 <div id='edit-link-list-block'> 4 <div id='edit-link-list-block'>
3 -<table id='links' class='noborder'>  
4 - <tr>  
5 - <th><%= _('Icon') %></th>  
6 - <th><%= _('Name') %></th>  
7 - <th><%= _('Address') %></th>  
8 - <th><%= _('Title') %></th>  
9 - <th><%= _('Target') %></th>  
10 - </tr>  
11 - <% for link in @block.links do %>  
12 - <tr>  
13 - <td><%= icon_selector(link['icon']) %></td>  
14 - <td><%= text_field_tag 'block[links][][name]', link[:name], :class => 'link-name', :maxlength => 20 %></td>  
15 - <td class='cel-address'><%= text_field_tag 'block[links][][address]', link[:address], :class => 'link-address' %></td>  
16 - <td><%= text_field_tag 'block[links][][title]', link[:title], :class => 'link-title' %></td>  
17 - <td><%= select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, link[:target])) %></td>  
18 - </tr>  
19 - <% end %>  
20 -</table> 5 + <ul class='link-list-header'>
  6 + <li class='link-list-icon'><%= _('Icon') %></li>
  7 + <li class='link-list-name'><%= _('Name') %></li>
  8 + <li class='link-list-address'><%= _('Address') %></li>
  9 + <li class='link-list-target'><%= _('Target') %></li>
  10 + </ul>
  11 + <ul id="dropable-link-list">
  12 + <% for link in @block.links do %>
  13 + <li>
  14 + <ul class="link-list-row">
  15 + <li>
  16 + <%= icon_selector(link['icon']) %>
  17 + </li>
  18 + <li>
  19 + <%= text_field_tag 'block[links][][name]', link[:name], :class => 'link-name', :maxlength => 20 %>
  20 + </li>
  21 + <li>
  22 + <%= text_field_tag 'block[links][][address]', link[:address], :class => 'link-address' %>
  23 + </li>
  24 + <li>
  25 + <%= select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, link[:target])) %>
  26 + </li>
  27 + <li>
  28 + <%= button_without_text(:delete, _('Delete'), "#" , :class=>"delete-link-list-row") %>
  29 + </li>
  30 + </ul>
  31 + </li>
  32 + <% end %>
  33 + </ul>
  34 + <input type="hidden" id="page_url" value="<%=url_for(:action=>'search_autocomplete')%>" />
21 </div> 35 </div>
22 36
23 <%= link_to_function(_('New link'), nil, :class => 'button icon-add with-text') do |page| 37 <%= link_to_function(_('New link'), nil, :class => 'button icon-add with-text') do |page|
24 - page.insert_html :bottom, 'links', content_tag('tr',  
25 - content_tag('td', icon_selector('ok')) +  
26 - content_tag('td', text_field_tag('block[links][][name]', '', :maxlength => 20)) +  
27 - content_tag('td', text_field_tag('block[links][][address]', nil, :class => 'link-address'), :class => 'cel-address') +  
28 - content_tag('td', text_field_tag('block[links][][title]', '', :class => 'link-title')) +  
29 - content_tag('td', select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, '_self'))) 38 + page.insert_html :bottom, 'dropable-link-list', content_tag('li',
  39 + content_tag('ul',
  40 + content_tag('li', icon_selector('ok')) +
  41 + content_tag('li', text_field_tag('block[links][][name]', '', :maxlength => 20)) +
  42 + content_tag('li', text_field_tag('block[links][][address]', nil, :class => 'link-address')) +
  43 + content_tag('li', select_tag('block[links][][target]',
  44 + options_for_select(LinkListBlock::TARGET_OPTIONS, '_self'))) +
  45 + content_tag('li', button_without_text(:delete, _('Delete'), "#" , :class=>"delete-link-list-row")),
  46 + :class=>"link-list-row new_link_row")
30 ) + 47 ) +
31 - javascript_tag("$('edit-link-list-block').scrollTop = $('edit-link-list-block').scrollHeight") 48 + javascript_tag("new_link_action()")
32 end %> 49 end %>
app/views/box_organizer/edit.rhtml
@@ -7,13 +7,14 @@ @@ -7,13 +7,14 @@
7 7
8 <%= render :partial => partial_for_class(@block.class) %> 8 <%= render :partial => partial_for_class(@block.class) %>
9 9
10 - <%= labelled_form_field _('Display this block:'), '' %>  
11 - <div style='margin-left: 10px'>  
12 - <% @block.display_options.each do |option| %>  
13 - <%= radio_button(:block, :display, option) %>  
14 - <%= label_tag("block_display_#{option}", _(@block.display_option_label(option))) %>  
15 - <br/>  
16 - <% end %> 10 + <div class="display">
  11 + <%= labelled_form_field _('Display this block:'),
  12 + select_tag('block[display]', options_from_collection_for_select(@block.display_options, :first, :last, @block.display))
  13 + %>
  14 + </div>
  15 + <div class="display_user">
  16 + <%= labelled_form_field _('Display to users:'), '' %>
  17 + <%= select_tag('block[display_user]', options_from_collection_for_select(@block.display_user_options, :first, :last, @block.display_user)) %>
17 </div> 18 </div>
18 19
19 <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %> 20 <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %>
app/views/content_viewer/view_page.rhtml
@@ -80,8 +80,26 @@ @@ -80,8 +80,26 @@
80 </h3> 80 </h3>
81 <% end %> 81 <% end %>
82 82
83 - <% if @page.accept_comments? && @comments.count > 1 %> 83 + <% if @page.accept_comments? && @comments_count > 1 %>
84 <%= link_to(_('Post a comment'), '#', :class => 'display-comment-form', :id => 'top-post-comment-button', :onclick => "jQuery('#page-comment-form .display-comment-form').first().click();") %> 84 <%= link_to(_('Post a comment'), '#', :class => 'display-comment-form', :id => 'top-post-comment-button', :onclick => "jQuery('#page-comment-form .display-comment-form').first().click();") %>
  85 +
  86 + <%= hidden_field_tag("page_url", url_for(:controller=>'content_viewer', :action=>'view_page', :profile=>profile.identifier)) %>
  87 + <%= javascript_include_tag "comment_order.js" %>
  88 + <div class="comment-order">
  89 + <% form_tag({:controller=>'content_viewer' , :action=>'view_page'}, {:method=>'get', :id=>"form_order"}) do %>
  90 + <%= select_tag 'comment_order', options_for_select({_('Oldest first')=>'oldest', _('Newest first')=>'newest'}, @comment_order) %>
  91 + <% end %>
  92 + </div>
  93 + <% end %>
  94 +
  95 + <% if @page.accept_comments? and @comments.count > 1 %>
  96 + <%= hidden_field_tag("page_url", url_for(:controller=>'content_viewer', :action=>'view_page', :profile=>profile.identifier)) %>
  97 + <%= javascript_include_tag "comment_order.js" %>
  98 + <div class="comment-order">
  99 + <% form_tag({:controller=>'content_viewer' , :action=>'view_page'}, {:method=>'get', :id=>"form_order"}) do %>
  100 + <%= select_tag 'comment_order', options_for_select({_('Oldest first')=>'oldest', _('Newest first')=>'newest'}, @comment_order) %>
  101 + <% end %>
  102 + </div>
85 <% end %> 103 <% end %>
86 104
87 <ul class="article-comments-list"> 105 <ul class="article-comments-list">
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/categories_block.feature
@@ -26,14 +26,9 @@ Feature: categories_block @@ -26,14 +26,9 @@ Feature: categories_block
26 And I am logged in as admin 26 And I am logged in as admin
27 And I go to /admin/environment_design 27 And I go to /admin/environment_design
28 28
29 - # Note that this @ignore-hidden-elements only works for seeing hidden  
30 - # elements. It actually doesn't work for following hidden link or pressing  
31 - # hidden buttons. That's why it's necessary to use this display hack to show  
32 - # the link.  
33 - @selenium @ignore-hidden-elements 29 + @selenium
34 Scenario: List just product categories 30 Scenario: List just product categories
35 - Given display ".button-bar"  
36 - And I follow "Edit" within ".categories-block" 31 + Given I follow "Edit" within ".categories-block"
37 And I check "Product" 32 And I check "Product"
38 When I press "Save" 33 When I press "Save"
39 Then I should see "Food" 34 Then I should see "Food"
@@ -44,8 +39,7 @@ Feature: categories_block @@ -44,8 +39,7 @@ Feature: categories_block
44 39
45 @selenium 40 @selenium
46 Scenario: Show submenu if it exists 41 Scenario: Show submenu if it exists
47 - Given display ".button-bar"  
48 - And I follow "Edit" within ".categories-block" 42 + Given I follow "Edit" within ".categories-block"
49 And I check "Product" 43 And I check "Product"
50 And I press "Save" 44 And I press "Save"
51 Then I should see "Food" 45 Then I should see "Food"
@@ -62,8 +56,7 @@ Feature: categories_block @@ -62,8 +56,7 @@ Feature: categories_block
62 56
63 @selenium 57 @selenium
64 Scenario: Show only one submenu per time 58 Scenario: Show only one submenu per time
65 - Given display ".button-bar"  
66 - And I follow "Edit" within ".categories-block" 59 + Given I follow "Edit" within ".categories-block"
67 And I check "Product" 60 And I check "Product"
68 And I press "Save" 61 And I press "Save"
69 Then I should see "Book" 62 Then I should see "Book"
@@ -73,16 +66,14 @@ Feature: categories_block @@ -73,16 +66,14 @@ Feature: categories_block
73 66
74 @selenium 67 @selenium
75 Scenario: List just general categories 68 Scenario: List just general categories
76 - Given display ".button-bar"  
77 - And I follow "Edit" within ".categories-block" 69 + Given I follow "Edit" within ".categories-block"
78 And I check "Generic category" 70 And I check "Generic category"
79 When I press "Save" 71 When I press "Save"
80 Then I should see "Wood" 72 Then I should see "Wood"
81 73
82 @selenium 74 @selenium
83 Scenario: List just regions 75 Scenario: List just regions
84 - Given display ".button-bar"  
85 - And I follow "Edit" within ".categories-block" 76 + Given I follow "Edit" within ".categories-block"
86 And I check "Region" 77 And I check "Region"
87 When I press "Save" 78 When I press "Save"
88 Then I should see "Bahia" 79 Then I should see "Bahia"
features/comment.feature
@@ -97,3 +97,41 @@ Feature: comment @@ -97,3 +97,41 @@ Feature: comment
97 Given I am on /booking/article-to-comment 97 Given I am on /booking/article-to-comment
98 And I follow "Post a comment" 98 And I follow "Post a comment"
99 Then "Post a comment" should not be visible within "#article" 99 Then "Post a comment" should not be visible within "#article"
  100 +
  101 + @selenium
  102 + Scenario: the newest post from a forum should be displayed first.
  103 + Given the following users
  104 + | login | name |
  105 + | joaosilva | Joao Silva |
  106 + And the following forums
  107 + | owner | name |
  108 + | joaosilva | Forum |
  109 + And the following articles
  110 + | owner | name | parent |
  111 + | joaosilva | Post one | Forum |
  112 + And the following comments
  113 + | article | author | title | body |
  114 + | Post one | joaosilva | Hi all | Hi all |
  115 + | Post one | joaosilva | Hello | Hello |
  116 + When I go to /joaosilva/forum/post-one
  117 + And I select "Newest first" from "comment_order" within ".comment-order"
  118 + Then I should see "Hello" within ".article-comment"
  119 +
  120 + @selenium
  121 + Scenario: the oldest post from a forum should be displayed first.
  122 + Given the following users
  123 + | login | name |
  124 + | joaosilva | Joao Silva |
  125 + And the following forums
  126 + | owner | name |
  127 + | joaosilva | Forum |
  128 + And the following articles
  129 + | owner | name | parent |
  130 + | joaosilva | Post one | Forum |
  131 + And the following comments
  132 + | article | author | title | body |
  133 + | Post one | joaosilva | Hi all | Hi all |
  134 + | Post one | joaosilva | Hello | Hello |
  135 + When I go to /joaosilva/forum/post-one
  136 + And I select "Oldest first" from "comment_order" within ".comment-order"
  137 + Then I should see "Hi all" within ".article-comment"
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/noosfero/i18n.rb
@@ -6,9 +6,15 @@ class Object @@ -6,9 +6,15 @@ class Object
6 alias :ngettext :n_ 6 alias :ngettext :n_
7 end 7 end
8 8
  9 +
  10 +custom_locale_dir = Rails.root.join('custom_locales', Rails.env)
  11 +repos = []
  12 +if File.exists?(custom_locale_dir)
  13 + repos << FastGettext::TranslationRepository.build('environment', :type => 'po', :path => custom_locale_dir)
  14 +end
  15 +
9 # translations in place? 16 # translations in place?
10 locale_dir = Rails.root.join('locale') 17 locale_dir = Rails.root.join('locale')
11 -repos = []  
12 if File.exists?(locale_dir) 18 if File.exists?(locale_dir)
13 repos << FastGettext::TranslationRepository.build('noosfero', :type => 'mo', :path => locale_dir) 19 repos << FastGettext::TranslationRepository.build('noosfero', :type => 'mo', :path => locale_dir)
14 repos << FastGettext::TranslationRepository.build('iso_3166', :type => 'mo', :path => locale_dir) 20 repos << FastGettext::TranslationRepository.build('iso_3166', :type => 'mo', :path => locale_dir)
lib/noosfero/plugin.rb
@@ -16,14 +16,7 @@ class Noosfero::Plugin @@ -16,14 +16,7 @@ class Noosfero::Plugin
16 end 16 end
17 17
18 def init_system 18 def init_system
19 - enabled_plugins = Dir.glob(File.join(Rails.root, 'config', 'plugins', '*'))  
20 - if Rails.env.test? && !enabled_plugins.include?(File.join(Rails.root, 'config', 'plugins', 'foo'))  
21 - enabled_plugins << File.join(Rails.root, 'plugins', 'foo')  
22 - end  
23 -  
24 - enabled_plugins.select do |entry|  
25 - File.directory?(entry)  
26 - end.each do |dir| 19 + available_plugins.each do |dir|
27 load_plugin dir 20 load_plugin dir
28 end 21 end
29 end 22 end
@@ -76,12 +69,19 @@ class Noosfero::Plugin @@ -76,12 +69,19 @@ class Noosfero::Plugin
76 klass(plugin_name) 69 klass(plugin_name)
77 end 70 end
78 71
79 - def all  
80 - @all ||= [] 72 + def available_plugins
  73 + unless @available_plugins
  74 + path = File.join(Rails.root, 'config', 'plugins', '*')
  75 + @available_plugins = Dir.glob(path).select{ |i| File.directory?(i) }
  76 + if Rails.env.test? && !@available_plugins.include?(File.join(Rails.root, 'config', 'plugins', 'foo'))
  77 + @available_plugins << File.join(Rails.root, 'plugins', 'foo')
  78 + end
  79 + end
  80 + @available_plugins
81 end 81 end
82 82
83 - def inherited(subclass)  
84 - all << subclass.to_s unless all.include?(subclass.to_s) 83 + def all
  84 + @all ||= available_plugins.map{ |dir| (File.basename(dir) + "_plugin").camelize }
85 end 85 end
86 86
87 def public_name 87 def public_name
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/pg_search/lib/ext/active_record.rb
@@ -2,11 +2,9 @@ require_dependency &#39;active_record&#39; @@ -2,11 +2,9 @@ require_dependency &#39;active_record&#39;
2 2
3 class ActiveRecord::Base 3 class ActiveRecord::Base
4 def self.pg_search_plugin_search(query) 4 def self.pg_search_plugin_search(query)
5 - query.gsub!(/\|/,' ')  
6 - formatted_query = query.split.map{|w| w += ":*"}.join('|')  
7 - 5 + filtered_query = query.gsub(/[\|\(\)\\\/\s\[\]'"*%&!:]/,' ').split.map{|w| w += ":*"}.join('|')
8 if defined?(self::SEARCHABLE_FIELDS) 6 if defined?(self::SEARCHABLE_FIELDS)
9 - where("to_tsvector('simple', #{pg_search_plugin_fields}) @@ to_tsquery('#{formatted_query}')") 7 + where("to_tsvector('simple', #{pg_search_plugin_fields}) @@ to_tsquery('#{filtered_query}')")
10 else 8 else
11 raise "No searchable fields defined for #{self.name}" 9 raise "No searchable fields defined for #{self.name}"
12 end 10 end
plugins/pg_search/test/unit/pg_search_plugin_test.rb
@@ -21,6 +21,11 @@ class PgSearchPluginTest &lt; ActiveSupport::TestCase @@ -21,6 +21,11 @@ class PgSearchPluginTest &lt; ActiveSupport::TestCase
21 assert_includes search(Profile, 'admin deb'), profile2 21 assert_includes search(Profile, 'admin deb'), profile2
22 end 22 end
23 23
  24 + should 'locate profile escaping special characters' do
  25 + profile = fast_create(Profile, :name => 'John', :identifier => 'waterfall')
  26 + assert_includes search(Profile, ') ( /\/\/\/\/\ o_o oOo o_o /\/\/\/\/\ ) ((tx waterfall)'), profile
  27 + end
  28 +
24 # TODO This feature is available only on Postgresql 9.0 29 # TODO This feature is available only on Postgresql 9.0
25 # http://www.postgresql.org/docs/9.0/static/unaccent.html 30 # http://www.postgresql.org/docs/9.0/static/unaccent.html
26 # should 'ignore accents' do 31 # should 'ignore accents' do
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
plugins/variables/doc/variables.textile 0 → 100644
@@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
  1 +h1. Variables Plugin
  2 +
  3 +A set of simple variables to be used in a macro context.
  4 +
  5 +h2. Usage
  6 +
  7 +* Create a HTML content using RawHTMLBlock, TinyMceArticle or other
  8 + article with HTML support
  9 +* Add a HTML div tag with css class "macro" (see Example)
  10 +* Add inner that div tag the variable desired, like {profile}
  11 +
  12 +h2. Usage with TinyMceArticle
  13 +
  14 +The Noosfero's macros add a extra button in toolbar of the editor
  15 +to use macros in a single way, that way this plugin add a option
  16 +called "Variables" under this option.
  17 +
  18 +h2. Supported variables
  19 +
  20 +* {profile} - will be replaced by the identifier of the profile
  21 +* {name} - will be replaced by the name of the profile
  22 +
  23 +h2. Example
  24 +
  25 +<pre>
  26 +<div class="macro" data-macro="variables_plugin/profile">
  27 + the identifier of the profile = {profile}
  28 + the name of the profile = {name}
  29 +</div>
  30 +</pre>
  31 +
  32 +h2. Info
  33 +
  34 +This plugin was inspired by the solution proposed by the Serpro in
  35 +the merge-request #419 on the Gitorious:
  36 +
  37 +* https://gitorious.org/noosfero/noosfero/merge_requests/419
  38 +
  39 +And improved by the guys from the UnB.
plugins/variables/lib/variables_plugin.rb 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +class VariablesPlugin < Noosfero::Plugin
  2 +
  3 + def self.plugin_name
  4 + "Variables Plugin"
  5 + end
  6 +
  7 + def self.plugin_description
  8 + _("A set of simple variables to be used in a macro context")
  9 + end
  10 +
  11 +end
  12 +
  13 +require_dependency 'variables_plugin/macros/profile'
plugins/variables/lib/variables_plugin/macros/profile.rb 0 → 100644
@@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
  1 +ActionView::Base.sanitized_allowed_attributes += ['data-macro']
  2 +
  3 +class VariablesPlugin::Profile < Noosfero::Plugin::Macro
  4 +
  5 + def self.configuration
  6 + {
  7 + :title => _('Variables'),
  8 + :skip_dialog => false,
  9 + :generator => method(:macro_default_generator),
  10 + :params => [
  11 + {
  12 + :name => 'variable',
  13 + :label => _('Select the desired variable'),
  14 + :type => 'select',
  15 + :values => ['{profile}', '{name}']
  16 + }
  17 + ],
  18 + }
  19 + end
  20 +
  21 + def self.macro_default_generator(macro)
  22 + "
  23 + '<div class=\"macro mceNonEditable\" data-macro=\"#{macro.identifier}\">'
  24 + + jQuery('*[name=variable]', dialog).val()
  25 + + '</div>';
  26 + "
  27 + end
  28 +
  29 + def parse(params, inner_html, source)
  30 + if context.profile
  31 + inner_html.gsub!(/\{profile\}/, context.profile.identifier)
  32 + inner_html.gsub!(/\{name\}/, context.profile.name)
  33 + end
  34 + inner_html
  35 + end
  36 +
  37 +end
plugins/variables/test/unit/profile_test.rb 0 → 100644
@@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
  1 +class ProfileTest < ActiveSupport::TestCase
  2 +
  3 + def setup
  4 + @macro = VariablesPlugin::Profile.new
  5 + @macro.context = mock()
  6 + @profile = fast_create(Community)
  7 + @macro.context.stubs(:profile).returns(@profile)
  8 + end
  9 +
  10 + attr_reader :macro, :profile
  11 +
  12 + should 'have a configuration' do
  13 + assert VariablesPlugin::Profile.configuration
  14 + end
  15 +
  16 + should 'substitute the {profile} variable by the profile idenfifier' do
  17 + html = 'the profile identifier is {profile}'
  18 + content = macro.parse({}, html, profile)
  19 + assert_equal "the profile identifier is #{profile.identifier}", content
  20 + end
  21 +
  22 + should 'substitute the {name} variable by the profile name' do
  23 + html = 'the profile name is {name}'
  24 + content = macro.parse({}, html, profile)
  25 + assert_equal "the profile name is #{profile.name}", content
  26 + end
  27 +
  28 + should 'do not change the content if the variable is not supported' do
  29 + html = 'the variable {unsupported} is not supported'
  30 + content = macro.parse({}, html, profile)
  31 + assert_equal html, content
  32 + end
  33 +
  34 + should 'do nothing out of profile context' do
  35 + macro.context.stubs(:profile).returns(nil)
  36 + html = 'there is no {support} out of profile context'
  37 + content = macro.parse({}, html, profile)
  38 + assert_equal html, content
  39 + end
  40 +
  41 +end
plugins/variables/test/unit/variables_plugin_test.rb 0 → 100644
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +require 'test_helper'
  2 +
  3 +class VariablesPluginTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @environment = Environment.default
  7 + @plugin = VariablesPlugin.new
  8 + end
  9 +
  10 + attr_reader :environment, :plugin
  11 +
  12 + should 'have a name' do
  13 + assert_not_equal Noosfero::Plugin.plugin_name, VariablesPlugin::plugin_name
  14 + end
  15 +
  16 + should 'describe yourself' do
  17 + assert_not_equal Noosfero::Plugin.plugin_description, VariablesPlugin::plugin_description
  18 + end
  19 +
  20 +end
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-undo { background-image: url(Tango/16x16/actions/edit-undo.png) } 4 .icon-undo { background-image: url(Tango/16x16/actions/edit-undo.png) }
4 .icon-home { background-image: url(Tango/16x16/actions/go-home.png) } 5 .icon-home { background-image: url(Tango/16x16/actions/go-home.png) }
public/designs/themes/base/style.css
@@ -1275,6 +1275,11 @@ hr.pre-posts, hr.sep-posts { @@ -1275,6 +1275,11 @@ hr.pre-posts, hr.sep-posts {
1275 padding-right: 9px; 1275 padding-right: 9px;
1276 } 1276 }
1277 1277
  1278 +.comment-order {
  1279 + float: right;
  1280 + display: block;
  1281 +}
  1282 +
1278 .comment-from-owner .comment-created-at { 1283 .comment-from-owner .comment-created-at {
1279 color: #333; 1284 color: #333;
1280 } 1285 }
public/images/drag-and-drop.png 0 → 100644

1.11 KB

public/javascripts/application.js
@@ -1101,4 +1101,4 @@ jQuery(document).ready(function(){ @@ -1101,4 +1101,4 @@ jQuery(document).ready(function(){
1101 jQuery("#article_has_terms_of_use").click(function(){ 1101 jQuery("#article_has_terms_of_use").click(function(){
1102 showHideTermsOfUse(); 1102 showHideTermsOfUse();
1103 }); 1103 });
1104 -});  
1105 \ No newline at end of file 1104 \ No newline at end of file
  1105 +});
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/comment_order.js 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +function send_order(order, url) {
  2 + open_loading(DEFAULT_LOADING_MESSAGE);
  3 +
  4 + jQuery.ajax({
  5 + url:url,
  6 + data: {"comment_order":order},
  7 + success: function(response) {
  8 + close_loading();
  9 + jQuery(".article-comments-list").html(response);
  10 + },
  11 + error: function() { close_loading() }
  12 + });
  13 +}
  14 +
  15 +
  16 +jQuery(document).ready(function(){
  17 + jQuery("#comment_order").change(function(){
  18 + var url = jQuery("#page_url").val();
  19 + send_order(this.value, url);
  20 + });
  21 +});
0 \ No newline at end of file 22 \ No newline at end of file
public/javascripts/edit-link-list.js 0 → 100644
@@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
  1 +function send_ajax(source_url) {
  2 + jQuery(".link-address").autocomplete({
  3 + source : function(request, response){
  4 + jQuery.ajax({
  5 + type: "GET",
  6 + url: source_url,
  7 + data: {query: request.term},
  8 + success: function(result){
  9 + response(result);
  10 + },
  11 + error: function(ajax, stat, errorThrown) {
  12 + console.log('Link not found : ' + errorThrown);
  13 + }
  14 + });
  15 + },
  16 +
  17 + minLength: 3
  18 + });
  19 +}
  20 +
  21 +function new_link_action(){
  22 + send_ajax(jQuery("#page_url").val());
  23 +
  24 + jQuery(".delete-link-list-row").click(function(){
  25 + jQuery(this).parent().parent().remove();
  26 + return false;
  27 + });
  28 +
  29 + jQuery(document).scrollTop(jQuery('#dropable-link-list').scrollTop());
  30 +}
  31 +
  32 +jQuery(document).ready(function(){
  33 + new_link_action();
  34 +
  35 + jQuery("#dropable-link-list").sortable({
  36 + revert: true,
  37 + axis: "y"
  38 + });
  39 +});
0 \ No newline at end of file 40 \ No newline at end of file
public/javascripts/sign_up_password_rate.js 0 → 100644
@@ -0,0 +1,121 @@ @@ -0,0 +1,121 @@
  1 +// This jQuery plugin is written by firas kassem [2007.04.05] and was modified to fit noosfero
  2 +// Firas Kassem phiras.wordpress.com || phiras at gmail {dot} com
  3 +// for more information : http://phiras.wordpress.com/2007/04/08/password-strength-meter-a-jquery-plugin/
  4 +
  5 +var blankPass = -1
  6 +var shortPass = 0
  7 +var badPass = 1
  8 +var goodPass = 2
  9 +var strongPass = 3
  10 +
  11 +
  12 +function passwordStrength(password,username)
  13 +{
  14 + score = 0
  15 +
  16 + if(password.length == 0) return blankPass
  17 +
  18 + //password < 4
  19 + if (password.length < 4 ) { return shortPass }
  20 +
  21 + //password == username
  22 + if (password.toLowerCase()==username.toLowerCase()) badPass
  23 +
  24 + //password length
  25 + score += password.length * 4
  26 + score += ( checkRepetition(1,password).length - password.length ) * 1
  27 + score += ( checkRepetition(2,password).length - password.length ) * 1
  28 + score += ( checkRepetition(3,password).length - password.length ) * 1
  29 + score += ( checkRepetition(4,password).length - password.length ) * 1
  30 +
  31 + //password has 3 numbers
  32 + if (password.match(/(.*[0-9].*[0-9].*[0-9])/)) score += 5
  33 +
  34 + //password has 2 sybols
  35 + if (password.match(/(.*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~])/)) score += 5
  36 +
  37 + //password has Upper and Lower chars
  38 + if (password.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/)) score += 10
  39 +
  40 + //password has number and chars
  41 + if (password.match(/([a-zA-Z])/) && password.match(/([0-9])/)) score += 15
  42 + //
  43 + //password has number and symbol
  44 + if (password.match(/([!,@,#,$,%,^,&,*,?,_,~])/) && password.match(/([0-9])/)) score += 15
  45 +
  46 + //password has char and symbol
  47 + if (password.match(/([!,@,#,$,%,^,&,*,?,_,~])/) && password.match(/([a-zA-Z])/)) score += 15
  48 +
  49 + //password is just a nubers or chars
  50 + if (password.match(/^\w+$/) || password.match(/^\d+$/) ) score -= 10
  51 +
  52 + //verifing 0 < score < 100
  53 + if ( score < 0 ) score = 0
  54 + if ( score > 100 ) score = 100
  55 +
  56 + if (score < 34 ) return badPass
  57 + if (score < 68 ) return goodPass
  58 + return strongPass
  59 +}
  60 +
  61 +function checkRepetition(pLen,str)
  62 +{
  63 + res = ""
  64 + for ( i=0; i<str.length ; i++ )
  65 + {
  66 + repeated=true
  67 + for (j=0;j < pLen && (j+i+pLen) < str.length;j++)
  68 + repeated=repeated && (str.charAt(j+i)==str.charAt(j+i+pLen))
  69 + if (j<pLen) repeated=false
  70 + if (repeated)
  71 + {
  72 + i+=pLen-1
  73 + repeated=false
  74 + }
  75 + else
  76 + {
  77 + res+=str.charAt(i)
  78 + }
  79 + }
  80 + return res
  81 +}
  82 +
  83 +jQuery(document).ready(function() {
  84 + jQuery('#user_pw').keyup(function()
  85 + {
  86 + var result = passwordStrength(jQuery('#user_pw').val(),jQuery('#user_login').val())
  87 + if(result == blankPass)
  88 + {
  89 + showRateField('#result-blank')
  90 + } else
  91 + if(result == shortPass)
  92 + {
  93 + showRateField('#result-short')
  94 + } else
  95 + if( result == badPass )
  96 + {
  97 + showRateField('#result-bad')
  98 + } else
  99 + if( result == goodPass )
  100 + {
  101 + showRateField('#result-good')
  102 + } else
  103 + if( result == strongPass )
  104 + {
  105 + showRateField('#result-strong')
  106 + }
  107 +
  108 + })
  109 +})
  110 +
  111 +function showRateField(validation)
  112 +{
  113 + jQuery('#result-blank').addClass('hidden')
  114 + jQuery('#result-short').addClass('hidden')
  115 + jQuery('#result-bad').addClass('hidden')
  116 + jQuery('#result-good').addClass('hidden')
  117 + jQuery('#result-strong').addClass('hidden')
  118 +
  119 + jQuery(validation).removeClass('hidden')
  120 +
  121 +}
0 \ No newline at end of file 122 \ No newline at end of file
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
@@ -1859,20 +1859,70 @@ a.button.disabled, input.disabled { @@ -1859,20 +1859,70 @@ a.button.disabled, input.disabled {
1859 text-decoration: none; 1859 text-decoration: none;
1860 } 1860 }
1861 /* ==> blocks/link-list-block.css <<= */ 1861 /* ==> blocks/link-list-block.css <<= */
1862 -  
1863 #edit-link-list-block { 1862 #edit-link-list-block {
1864 - width: 820px; 1863 + width: 620px;
  1864 + position: relative;
  1865 + left: -24px;
1865 } 1866 }
1866 -  
1867 -#edit-link-list-block table {  
1868 - width: auto;  
1869 - margin-bottom: 10px; 1867 +.link-list-header {
  1868 + width: 98%;
  1869 + height: 25px;
  1870 + padding: 10px 1px 10px 10px;
  1871 + margin-bottom: 5px;
  1872 + cursor: pointer;
1870 } 1873 }
1871 -#edit-link-list-block table .cel-address {  
1872 - width: 220px; 1874 +.link-list-header li {
  1875 + list-style-type: none;
  1876 + display: inline;
  1877 + font-weight: bold;
  1878 + font-size: 14px;
  1879 + text-align: center;
1873 } 1880 }
1874 -#edit-link-list-block table .cel-address input {  
1875 - width: 100%; 1881 +#dropable-link-list {
  1882 + padding-left: 23px;
  1883 + margin-top: -12px;
  1884 +}
  1885 +#dropable-link-list li {
  1886 + list-style-type: none;
  1887 +}
  1888 +.link-list-row {
  1889 + line-height: 25px;
  1890 + margin-bottom: 5px;
  1891 + padding: 10px 1px 10px 10px;
  1892 + cursor: pointer;
  1893 + width: 97%;
  1894 +}
  1895 +.link-list-row:hover {
  1896 + background: #ddd url(/images/drag-and-drop.png) no-repeat;
  1897 + background-position: 98% 15px;
  1898 +}
  1899 +.link-list-row li {
  1900 + list-style-type: none;
  1901 + display: inline;
  1902 + margin-left: 5px;
  1903 +}
  1904 +.link-list-row li div {
  1905 + float: left;
  1906 + margin-top: 4px;
  1907 +}
  1908 +.link-list-row li a {
  1909 + line-height: 27px !important;
  1910 + padding-right: 5px;
  1911 +}
  1912 +.link-list-icon {
  1913 + margin-left: 14px;
  1914 +}
  1915 +.link-list-name {
  1916 + margin-left: 40px;
  1917 +}
  1918 +.link-list-address {
  1919 + margin-left: 90px;
  1920 +}
  1921 +.link-list-target {
  1922 + margin-left: 77px;
  1923 +}
  1924 +.new_link_row li {
  1925 + margin-left: 7px;
1876 } 1926 }
1877 #content .link-list-block { 1927 #content .link-list-block {
1878 padding: 10px 0px 10px 10px; 1928 padding: 10px 0px 10px 10px;
@@ -5989,8 +6039,14 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { @@ -5989,8 +6039,14 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
5989 text-align: right; 6039 text-align: right;
5990 } 6040 }
5991 6041
  6042 +#url-check .suggested_usernames,
  6043 +#url-check .suggested_usernames a {
  6044 + color: #005000;
  6045 +}
  6046 +
5992 #email-check, 6047 #email-check,
5993 #fake-check, 6048 #fake-check,
  6049 +#password-rate,
5994 #password-check { 6050 #password-check {
5995 margin: -2px 16px -5px 13px; 6051 margin: -2px 16px -5px 13px;
5996 text-align: right; 6052 text-align: right;
@@ -5999,10 +6055,20 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { @@ -5999,10 +6055,20 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
5999 6055
6000 #email-check p, 6056 #email-check p,
6001 #fake-check p, 6057 #fake-check p,
  6058 +#password-rate p,
6002 #password-check p { 6059 #password-check p {
6003 margin: 0; 6060 margin: 0;
6004 } 6061 }
6005 6062
  6063 +#password-rate {
  6064 + font-weight:bold;
  6065 +}
  6066 +
  6067 +.hidden {
  6068 + visibility: hidden;
  6069 + display: none;
  6070 +}
  6071 +
6006 .available { 6072 .available {
6007 color: #88BD00; 6073 color: #88BD00;
6008 } 6074 }
@@ -6016,6 +6082,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { @@ -6016,6 +6082,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6016 } 6082 }
6017 6083
6018 #email-check p, 6084 #email-check p,
  6085 +#password-rate p,
6019 #password-check p, 6086 #password-check p,
6020 #url-check p { 6087 #url-check p {
6021 margin: 0; 6088 margin: 0;
@@ -6607,3 +6674,19 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { @@ -6607,3 +6674,19 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6607 .diff li.diff-block-info { 6674 .diff li.diff-block-info {
6608 background: none repeat scroll 0 0 gray; 6675 background: none repeat scroll 0 0 gray;
6609 } 6676 }
  6677 +
  6678 +#signup-form #result-short {
  6679 + color: red;
  6680 +}
  6681 +
  6682 +#signup-form #result-bad {
  6683 + color: #825A2C;
  6684 +}
  6685 +
  6686 +#signup-form #result-good {
  6687 + color: #32CD32;
  6688 +}
  6689 +
  6690 +#signup-form #result-strong {
  6691 + color: green;
  6692 +}
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
@@ -656,21 +655,28 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -656,21 +655,28 @@ class AccountControllerTest &lt; ActionController::TestCase
656 assert_redirected_to :controller => 'home', :action => 'index' 655 assert_redirected_to :controller => 'home', :action => 'index'
657 end 656 end
658 657
659 - should 'check_url is available on environment' do 658 + should 'check_valid_name is available on environment' do
660 env = fast_create(Environment, :name => 'Environment test') 659 env = fast_create(Environment, :name => 'Environment test')
661 @controller.expects(:environment).returns(env).at_least_once 660 @controller.expects(:environment).returns(env).at_least_once
662 profile = create_user('mylogin').person 661 profile = create_user('mylogin').person
663 - get :check_url, :identifier => 'mylogin' 662 + get :check_valid_name, :identifier => 'mylogin'
664 assert_equal 'validated', assigns(:status_class) 663 assert_equal 'validated', assigns(:status_class)
665 end 664 end
666 665
667 should 'check if url is not available on environment' do 666 should 'check if url is not available on environment' do
668 @controller.expects(:environment).returns(Environment.default).at_least_once 667 @controller.expects(:environment).returns(Environment.default).at_least_once
669 profile = create_user('mylogin').person 668 profile = create_user('mylogin').person
670 - get :check_url, :identifier => 'mylogin' 669 + get :check_valid_name, :identifier => 'mylogin'
671 assert_equal 'invalid', assigns(:status_class) 670 assert_equal 'invalid', assigns(:status_class)
672 end 671 end
673 672
  673 + should 'suggest a list with three possible usernames' do
  674 + profile = create_user('mylogin').person
  675 + get :check_valid_name, :identifier => 'mylogin'
  676 +
  677 + assert_equal 3, assigns(:suggested_usernames).uniq.size
  678 + end
  679 +
674 should 'check if e-mail is available on environment' do 680 should 'check if e-mail is available on environment' do
675 env = fast_create(Environment, :name => 'Environment test') 681 env = fast_create(Environment, :name => 'Environment test')
676 @controller.expects(:environment).returns(env).at_least_once 682 @controller.expects(:environment).returns(env).at_least_once
@@ -699,6 +705,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -699,6 +705,7 @@ class AccountControllerTest &lt; ActionController::TestCase
699 {:test => 5} 705 {:test => 5}
700 end 706 end
701 end 707 end
  708 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
702 709
703 e = User.find_by_login('ze').environment 710 e = User.find_by_login('ze').environment
704 e.enable_plugin(Plugin1.name) 711 e.enable_plugin(Plugin1.name)
@@ -789,6 +796,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -789,6 +796,7 @@ class AccountControllerTest &lt; ActionController::TestCase
789 lambda {"<strong>Plugin2 text</strong>"} 796 lambda {"<strong>Plugin2 text</strong>"}
790 end 797 end
791 end 798 end
  799 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
792 800
793 Environment.default.enable_plugin(Plugin1.name) 801 Environment.default.enable_plugin(Plugin1.name)
794 Environment.default.enable_plugin(Plugin2.name) 802 Environment.default.enable_plugin(Plugin2.name)
@@ -805,6 +813,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -805,6 +813,7 @@ class AccountControllerTest &lt; ActionController::TestCase
805 User.new(:login => 'testuser') 813 User.new(:login => 'testuser')
806 end 814 end
807 end 815 end
  816 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name])
808 Environment.default.enable_plugin(Plugin1.name) 817 Environment.default.enable_plugin(Plugin1.name)
809 818
810 post :login, :user => {:login => "testuser"} 819 post :login, :user => {:login => "testuser"}
@@ -819,6 +828,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -819,6 +828,7 @@ class AccountControllerTest &lt; ActionController::TestCase
819 nil 828 nil
820 end 829 end
821 end 830 end
  831 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name])
822 Environment.default.enable_plugin(Plugin1.name) 832 Environment.default.enable_plugin(Plugin1.name)
823 post :login, :user => {:login => 'johndoe', :password => 'test'} 833 post :login, :user => {:login => 'johndoe', :password => 'test'}
824 assert session[:user] 834 assert session[:user]
@@ -832,6 +842,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -832,6 +842,7 @@ class AccountControllerTest &lt; ActionController::TestCase
832 false 842 false
833 end 843 end
834 end 844 end
  845 + Noosfero::Plugin.stubs(:all).returns([TestRegistrationPlugin.name])
835 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestRegistrationPlugin.new]) 846 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestRegistrationPlugin.new])
836 847
837 post :signup, :user => { :login => 'testuser', :password => '123456', :password_confirmation => '123456', :email => 'testuser@example.com' } 848 post :signup, :user => { :login => 'testuser', :password => '123456', :password_confirmation => '123456', :email => 'testuser@example.com' }
@@ -850,6 +861,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -850,6 +861,7 @@ class AccountControllerTest &lt; ActionController::TestCase
850 true 861 true
851 end 862 end
852 end 863 end
  864 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
853 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new]) 865 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new])
854 866
855 get :login 867 get :login
@@ -863,6 +875,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -863,6 +875,7 @@ class AccountControllerTest &lt; ActionController::TestCase
863 false 875 false
864 end 876 end
865 end 877 end
  878 + Noosfero::Plugin.stubs(:all).returns([TestRegistrationPlugin.name])
866 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestRegistrationPlugin.new]) 879 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestRegistrationPlugin.new])
867 880
868 #Redirect on get action 881 #Redirect on get action
@@ -886,6 +899,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -886,6 +899,7 @@ class AccountControllerTest &lt; ActionController::TestCase
886 true 899 true
887 end 900 end
888 end 901 end
  902 + Noosfero::Plugin.stubs(:all).returns([Plugin1.new, Plugin2.new])
889 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new]) 903 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new])
890 904
891 get :login 905 get :login
@@ -904,6 +918,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -904,6 +918,7 @@ class AccountControllerTest &lt; ActionController::TestCase
904 lambda {"<strong>Plugin2 text</strong>"} 918 lambda {"<strong>Plugin2 text</strong>"}
905 end 919 end
906 end 920 end
  921 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
907 922
908 Environment.default.enable_plugin(Plugin1.name) 923 Environment.default.enable_plugin(Plugin1.name)
909 Environment.default.enable_plugin(Plugin2.name) 924 Environment.default.enable_plugin(Plugin2.name)
@@ -927,6 +942,30 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -927,6 +942,30 @@ class AccountControllerTest &lt; ActionController::TestCase
927 assert @response.body.blank? 942 assert @response.body.blank?
928 end 943 end
929 944
  945 + should "Search for state" do
  946 + create_state_and_city
  947 +
  948 + xhr :get, :search_state, :state_name=>"Rio Grande"
  949 +
  950 + json_response = ActiveSupport::JSON.decode(@response.body)
  951 + label = json_response[0]['label']
  952 +
  953 + assert_equal label, "Rio Grande do Sul"
  954 + end
  955 +
  956 + should "Search for city" do
  957 + create_state_and_city
  958 +
  959 + xhr :get, :search_cities, :state_name=>"Rio Grande do Sul", :city_name=>"Lavras"
  960 +
  961 + json_response = ActiveSupport::JSON.decode(@response.body)
  962 + label = json_response[0]['label']
  963 + category = json_response[0]['category']
  964 +
  965 + assert_equal category, "Rio Grande do Sul"
  966 + assert_equal label, "Lavras do Sul"
  967 + end
  968 +
930 protected 969 protected
931 def new_user(options = {}, extra_options ={}) 970 def new_user(options = {}, extra_options ={})
932 data = {:profile_data => person_data} 971 data = {:profile_data => person_data}
@@ -955,4 +994,18 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -955,4 +994,18 @@ class AccountControllerTest &lt; ActionController::TestCase
955 environment.min_signup_delay = 0 994 environment.min_signup_delay = 0
956 environment.save! 995 environment.save!
957 end 996 end
  997 +
  998 + def create_state_and_city
  999 + city = 'Lavras do Sul'
  1000 + state = 'Rio Grande do Sul'
  1001 +
  1002 + parent_region = fast_create(NationalRegion, :name => state,
  1003 + :national_region_code => '43',
  1004 + :national_region_type_id => NationalRegionType::STATE)
  1005 +
  1006 + fast_create(NationalRegion, :name => city,
  1007 + :national_region_code => '431150',
  1008 + :national_region_type_id => NationalRegionType::CITY,
  1009 + :parent_national_region_code => parent_region.national_region_code)
  1010 + end
958 end 1011 end
test/functional/application_controller_test.rb
@@ -374,6 +374,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -374,6 +374,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase
374 end 374 end
375 plugin2_path = '/plugin2/style.css' 375 plugin2_path = '/plugin2/style.css'
376 376
  377 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
  378 +
377 environment = Environment.default 379 environment = Environment.default
378 environment.enable_plugin(Plugin1.name) 380 environment.enable_plugin(Plugin1.name)
379 environment.enable_plugin(Plugin2.name) 381 environment.enable_plugin(Plugin2.name)
@@ -405,6 +407,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -405,6 +407,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase
405 plugin2_path2 = '/plugin2/'+js2 407 plugin2_path2 = '/plugin2/'+js2
406 plugin2_path3 = '/plugin2/'+js3 408 plugin2_path3 = '/plugin2/'+js3
407 409
  410 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
  411 +
408 environment = Environment.default 412 environment = Environment.default
409 environment.enable_plugin(Plugin1.name) 413 environment.enable_plugin(Plugin1.name)
410 environment.enable_plugin(Plugin2.name) 414 environment.enable_plugin(Plugin2.name)
@@ -428,6 +432,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -428,6 +432,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase
428 end 432 end
429 end 433 end
430 434
  435 + Noosfero::Plugin.stubs(:all).returns([TestBodyBeginning1Plugin.name, TestBodyBeginning2Plugin.name])
  436 +
431 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestBodyBeginning1Plugin.new, TestBodyBeginning2Plugin.new]) 437 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestBodyBeginning1Plugin.new, TestBodyBeginning2Plugin.new])
432 438
433 get :index 439 get :index
@@ -449,6 +455,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -449,6 +455,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase
449 end 455 end
450 end 456 end
451 457
  458 + Noosfero::Plugin.stubs(:all).returns([TestHeadEnding1Plugin.name, TestHeadEnding2Plugin.name])
  459 +
452 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestHeadEnding1Plugin.new, TestHeadEnding2Plugin.new]) 460 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestHeadEnding1Plugin.new, TestHeadEnding2Plugin.new])
453 461
454 get :index 462 get :index
@@ -513,6 +521,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -513,6 +521,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase
513 :block => lambda {} } 521 :block => lambda {} }
514 end 522 end
515 end 523 end
  524 + Noosfero::Plugin.stubs(:all).returns([FilterPlugin.name])
516 525
517 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([FilterPlugin.new]) 526 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([FilterPlugin.new])
518 527
@@ -531,6 +540,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -531,6 +540,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase
531 :block => lambda {'plugin block called'} } 540 :block => lambda {'plugin block called'} }
532 end 541 end
533 end 542 end
  543 + Noosfero::Plugin.stubs(:all).returns([OtherFilterPlugin.name])
534 544
535 environment1 = fast_create(Environment, :name => 'test environment') 545 environment1 = fast_create(Environment, :name => 'test environment')
536 environment1.enable_plugin(OtherFilterPlugin.name) 546 environment1.enable_plugin(OtherFilterPlugin.name)
test/functional/catalog_controller_test.rb
@@ -91,6 +91,7 @@ class CatalogControllerTest &lt; ActionController::TestCase @@ -91,6 +91,7 @@ class CatalogControllerTest &lt; ActionController::TestCase
91 lambda {"<span id='plugin2'>This is Plugin2 speaking!</span>"} 91 lambda {"<span id='plugin2'>This is Plugin2 speaking!</span>"}
92 end 92 end
93 end 93 end
  94 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
94 95
95 product = fast_create(Product, :profile_id => @enterprise.id) 96 product = fast_create(Product, :profile_id => @enterprise.id)
96 environment = Environment.default 97 environment = Environment.default
test/functional/content_viewer_controller_test.rb
@@ -1197,6 +1197,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1197,6 +1197,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1197 class Plugin2 < Noosfero::Plugin 1197 class Plugin2 < Noosfero::Plugin
1198 def content_remove_edit(content); false; end 1198 def content_remove_edit(content); false; end
1199 end 1199 end
  1200 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
1200 1201
1201 environment.enable_plugin(Plugin1.name) 1202 environment.enable_plugin(Plugin1.name)
1202 environment.enable_plugin(Plugin2.name) 1203 environment.enable_plugin(Plugin2.name)
@@ -1213,6 +1214,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1213,6 +1214,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1213 class Plugin2 < Noosfero::Plugin 1214 class Plugin2 < Noosfero::Plugin
1214 def content_expire_edit(content); nil; end 1215 def content_expire_edit(content); nil; end
1215 end 1216 end
  1217 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
1216 1218
1217 environment.enable_plugin(Plugin1.name) 1219 environment.enable_plugin(Plugin1.name)
1218 environment.enable_plugin(Plugin2.name) 1220 environment.enable_plugin(Plugin2.name)
@@ -1258,6 +1260,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1258,6 +1260,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1258 } 1260 }
1259 end 1261 end
1260 end 1262 end
  1263 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
1261 1264
1262 Environment.default.enable_plugin(Plugin1.name) 1265 Environment.default.enable_plugin(Plugin1.name)
1263 Environment.default.enable_plugin(Plugin2.name) 1266 Environment.default.enable_plugin(Plugin2.name)
@@ -1282,6 +1285,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1282,6 +1285,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1282 scope.where(:referrer => 'kernel.org') 1285 scope.where(:referrer => 'kernel.org')
1283 end 1286 end
1284 end 1287 end
  1288 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
1285 1289
1286 Environment.default.enable_plugin(Plugin1) 1290 Environment.default.enable_plugin(Plugin1)
1287 Environment.default.enable_plugin(Plugin2) 1291 Environment.default.enable_plugin(Plugin2)
@@ -1339,6 +1343,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1339,6 +1343,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1339 } 1343 }
1340 end 1344 end
1341 end 1345 end
  1346 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
1342 1347
1343 Environment.default.enable_plugin(Plugin1.name) 1348 Environment.default.enable_plugin(Plugin1.name)
1344 Environment.default.enable_plugin(Plugin2.name) 1349 Environment.default.enable_plugin(Plugin2.name)
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/enterprise_registration_controller_test.rb
@@ -193,6 +193,7 @@ class EnterpriseRegistrationControllerTest &lt; ActionController::TestCase @@ -193,6 +193,7 @@ class EnterpriseRegistrationControllerTest &lt; ActionController::TestCase
193 {'plugin2' => 'Plugin 2'} 193 {'plugin2' => 'Plugin 2'}
194 end 194 end
195 end 195 end
  196 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
196 197
197 environment = Environment.default 198 environment = Environment.default
198 environment.enable_plugin(Plugin1.name) 199 environment.enable_plugin(Plugin1.name)
test/functional/environment_design_controller_test.rb
@@ -370,4 +370,47 @@ class EnvironmentDesignControllerTest &lt; ActionController::TestCase @@ -370,4 +370,47 @@ class EnvironmentDesignControllerTest &lt; ActionController::TestCase
370 assert @controller.instance_variable_get('@side_block_types').include?(CustomBlock8) 370 assert @controller.instance_variable_get('@side_block_types').include?(CustomBlock8)
371 end 371 end
372 372
  373 + should 'clone a block' do
  374 + login_as(create_admin_user(Environment.default))
  375 + block = TagsBlock.create!
  376 + assert_difference TagsBlock, :count, 1 do
  377 + post :clone_block, :id => block.id
  378 + assert_response :redirect
  379 + end
  380 + end
  381 +
  382 + should 'return a list of paths from portal related to the words used in the query search' do
  383 + env = Environment.default
  384 + login_as(create_admin_user(env))
  385 + community = fast_create(Community, :environment_id => env)
  386 + env.portal_community = community
  387 + env.enable('use_portal_community')
  388 + env.save
  389 + @controller.stubs(:boxes_holder).returns(env)
  390 + article1 = fast_create(Article, :profile_id => community.id, :name => "Some thing")
  391 + article2 = fast_create(Article, :profile_id => community.id, :name => "Some article")
  392 + article3 = fast_create(Article, :profile_id => community.id, :name => "Not an article")
  393 +
  394 + xhr :get, :search_autocomplete, :query => 'Some'
  395 +
  396 + json_response = ActiveSupport::JSON.decode(@response.body)
  397 +
  398 + assert_response :success
  399 + assert_equal json_response.include?("/{portal}/"+article1.path), true
  400 + assert_equal json_response.include?("/{portal}/"+article2.path), true
  401 + assert_equal json_response.include?("/{portal}/"+article3.path), false
  402 + end
  403 +
  404 + should 'return empty if portal not configured' do
  405 + env = Environment.default
  406 + login_as(create_admin_user(env))
  407 +
  408 + xhr :get, :search_autocomplete, :query => 'Some'
  409 +
  410 + json_response = ActiveSupport::JSON.decode(@response.body)
  411 +
  412 + assert_response :success
  413 + assert_equal json_response, []
  414 + end
  415 +
373 end 416 end
test/functional/friends_controller_test.rb
@@ -68,6 +68,7 @@ class FriendsControllerTest &lt; ActionController::TestCase @@ -68,6 +68,7 @@ class FriendsControllerTest &lt; ActionController::TestCase
68 false 68 false
69 end 69 end
70 end 70 end
  71 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
71 72
72 e = profile.environment 73 e = profile.environment
73 e.enable_plugin(Plugin1.name) 74 e.enable_plugin(Plugin1.name)
test/functional/home_controller_test.rb
@@ -107,6 +107,7 @@ class HomeControllerTest &lt; ActionController::TestCase @@ -107,6 +107,7 @@ class HomeControllerTest &lt; ActionController::TestCase
107 lambda {"<a href='plugin2'>Plugin2 link</a>"} 107 lambda {"<a href='plugin2'>Plugin2 link</a>"}
108 end 108 end
109 end 109 end
  110 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
110 111
111 Environment.default.enable_plugin(Plugin1) 112 Environment.default.enable_plugin(Plugin1)
112 Environment.default.enable_plugin(Plugin2) 113 Environment.default.enable_plugin(Plugin2)
@@ -129,6 +130,7 @@ class HomeControllerTest &lt; ActionController::TestCase @@ -129,6 +130,7 @@ class HomeControllerTest &lt; ActionController::TestCase
129 true 130 true
130 end 131 end
131 end 132 end
  133 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
132 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new]) 134 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new])
133 135
134 get :index 136 get :index
test/functional/memberships_controller_test.rb
@@ -234,6 +234,7 @@ class MembershipsControllerTest &lt; ActionController::TestCase @@ -234,6 +234,7 @@ class MembershipsControllerTest &lt; ActionController::TestCase
234 {'plugin2' => 'Plugin 2'} 234 {'plugin2' => 'Plugin 2'}
235 end 235 end
236 end 236 end
  237 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
237 238
238 environment = Environment.default 239 environment = Environment.default
239 environment.enable_plugin(Plugin1.name) 240 environment.enable_plugin(Plugin1.name)
test/functional/plugins_controller_test.rb
@@ -47,7 +47,7 @@ class PluginsControllerTest &lt; ActionController::TestCase @@ -47,7 +47,7 @@ class PluginsControllerTest &lt; ActionController::TestCase
47 end 47 end
48 end 48 end
49 49
50 - Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s,Plugin2.to_s]) 50 + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s])
51 51
52 get :index 52 get :index
53 53
test/functional/profile_controller_test.rb
@@ -1255,6 +1255,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -1255,6 +1255,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
1255 {:title => 'Plugin2 tab', :id => 'plugin2_tab', :content => lambda { 'Content from plugin2.' }} 1255 {:title => 'Plugin2 tab', :id => 'plugin2_tab', :content => lambda { 'Content from plugin2.' }}
1256 end 1256 end
1257 end 1257 end
  1258 + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s])
1258 1259
1259 e = profile.environment 1260 e = profile.environment
1260 e.enable_plugin(Plugin1.name) 1261 e.enable_plugin(Plugin1.name)
test/functional/profile_design_controller_test.rb
@@ -173,7 +173,8 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase @@ -173,7 +173,8 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase
173 should 'have options to display blocks' do 173 should 'have options to display blocks' do
174 get :edit, :profile => 'designtestuser', :id => @b1.id 174 get :edit, :profile => 'designtestuser', :id => @b1.id
175 %w[always home_page_only except_home_page never].each do |option| 175 %w[always home_page_only except_home_page never].each do |option|
176 - assert_tag :input, :attributes => { :type => 'radio', :value => option} 176 + assert_tag :select, :attributes => {:name => 'block[display]'},
  177 + :descendant => {:tag => 'option', :attributes => {:value => option}}
177 end 178 end
178 end 179 end
179 180
@@ -302,24 +303,42 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase @@ -302,24 +303,42 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase
302 303
303 should 'not edit main block with never option' do 304 should 'not edit main block with never option' do
304 get :edit, :profile => 'designtestuser', :id => @b4.id 305 get :edit, :profile => 'designtestuser', :id => @b4.id
305 - assert_no_tag :input, :attributes => { :type => 'radio', :value => 'never'} 306 + assert_no_tag :select, :attributes => {:name => 'block[display]'},
  307 + :descendant => {:tag => 'option', :attributes => {:value => 'never'}}
306 end 308 end
307 309
308 should 'not edit main block with home_page_only option' do 310 should 'not edit main block with home_page_only option' do
309 get :edit, :profile => 'designtestuser', :id => @b4.id 311 get :edit, :profile => 'designtestuser', :id => @b4.id
310 - assert_no_tag :input, :attributes => { :type => 'radio', :value => 'home_page_only'} 312 + assert_no_tag :select, :attributes => {:name => 'block[display]'},
  313 + :descendant => {:tag => 'option', :attributes => {:value => 'home_page_only'}}
311 end 314 end
312 315
313 should 'edit main block with always option' do 316 should 'edit main block with always option' do
314 get :edit, :profile => 'designtestuser', :id => @b4.id 317 get :edit, :profile => 'designtestuser', :id => @b4.id
315 - assert_tag :input, :attributes => { :type => 'radio', :value => 'always'} 318 + assert_tag :select, :attributes => {:name => 'block[display]'},
  319 + :descendant => {:tag => 'option', :attributes => {:value => 'always'}}
316 end 320 end
317 321
318 should 'edit main block with except_home_page option' do 322 should 'edit main block with except_home_page option' do
319 get :edit, :profile => 'designtestuser', :id => @b4.id 323 get :edit, :profile => 'designtestuser', :id => @b4.id
320 - assert_tag :input, :attributes => { :type => 'radio', :value => 'except_home_page'} 324 + assert_tag :select, :attributes => {:name=> 'block[display]'},
  325 + :descendant => {:tag => 'option', :attributes => {:value => 'except_home_page'}}
321 end 326 end
322 327
  328 + should 'return a list of paths related to the words used in the query search' do
  329 + article1 = fast_create(Article, :profile_id => @profile.id, :name => "Some thing")
  330 + article2 = fast_create(Article, :profile_id => @profile.id, :name => "Some article")
  331 + article3 = fast_create(Article, :profile_id => @profile.id, :name => "Not an article")
  332 +
  333 + xhr :get, :search_autocomplete, :profile => 'designtestuser' , :query => 'Some'
  334 +
  335 + json_response = ActiveSupport::JSON.decode(@response.body)
  336 +
  337 + assert_response :success
  338 + assert_equal json_response.include?("/{profile}/"+article1.path), true
  339 + assert_equal json_response.include?("/{profile}/"+article2.path), true
  340 + assert_equal json_response.include?("/{profile}/"+article3.path), false
  341 + end
323 342
324 ###################################################### 343 ######################################################
325 # END - tests for BoxOrganizerController features 344 # END - tests for BoxOrganizerController features
@@ -739,7 +758,7 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase @@ -739,7 +758,7 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase
739 should 'clone a block' do 758 should 'clone a block' do
740 block = ProfileImageBlock.create!(:box => profile.boxes.first) 759 block = ProfileImageBlock.create!(:box => profile.boxes.first)
741 assert_difference ProfileImageBlock, :count, 1 do 760 assert_difference ProfileImageBlock, :count, 1 do
742 - post :clone, :id => block.id, :profile => profile.identifier 761 + post :clone_block, :id => block.id, :profile => profile.identifier
743 assert_response :redirect 762 assert_response :redirect
744 end 763 end
745 end 764 end
test/functional/profile_editor_controller_test.rb
@@ -868,6 +868,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase @@ -868,6 +868,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
868 {:title => "Plugin2 button", :icon => 'plugin2_icon', :url => 'plugin2_url'} 868 {:title => "Plugin2 button", :icon => 'plugin2_icon', :url => 'plugin2_url'}
869 end 869 end
870 end 870 end
  871 + Noosfero::Plugin.stubs(:all).returns([TestControlPanelButtons1.to_s, TestControlPanelButtons2.to_s])
871 872
872 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestControlPanelButtons1.new, TestControlPanelButtons2.new]) 873 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestControlPanelButtons1.new, TestControlPanelButtons2.new])
873 874
@@ -883,6 +884,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase @@ -883,6 +884,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
883 "<input id='field_added_by_plugin' value='value_of_field_added_by_plugin'/>" 884 "<input id='field_added_by_plugin' value='value_of_field_added_by_plugin'/>"
884 end 885 end
885 end 886 end
  887 + Noosfero::Plugin.stubs(:all).returns([TestProfileEditPlugin.to_s])
886 888
887 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestProfileEditPlugin.new]) 889 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestProfileEditPlugin.new])
888 890
@@ -911,6 +913,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase @@ -911,6 +913,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
911 lambda {"<strong>Plugin2 text</strong>"} 913 lambda {"<strong>Plugin2 text</strong>"}
912 end 914 end
913 end 915 end
  916 + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s])
914 917
915 Environment.default.enable_plugin(Plugin1) 918 Environment.default.enable_plugin(Plugin1)
916 Environment.default.enable_plugin(Plugin2) 919 Environment.default.enable_plugin(Plugin2)
@@ -932,6 +935,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase @@ -932,6 +935,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
932 lambda {"<strong>Plugin2 text</strong>"} 935 lambda {"<strong>Plugin2 text</strong>"}
933 end 936 end
934 end 937 end
  938 + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s])
935 939
936 Environment.default.enable_plugin(Plugin1) 940 Environment.default.enable_plugin(Plugin1)
937 Environment.default.enable_plugin(Plugin2) 941 Environment.default.enable_plugin(Plugin2)
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
@@ -163,6 +163,7 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -163,6 +163,7 @@ class SearchControllerTest &lt; ActionController::TestCase
163 lambda {"<span id='plugin2'>This is Plugin2 speaking!</span>"} 163 lambda {"<span id='plugin2'>This is Plugin2 speaking!</span>"}
164 end 164 end
165 end 165 end
  166 + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s])
166 167
167 enterprise = fast_create(Enterprise) 168 enterprise = fast_create(Enterprise)
168 prod_cat = fast_create(ProductCategory) 169 prod_cat = fast_create(ProductCategory)
@@ -189,6 +190,7 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -189,6 +190,7 @@ class SearchControllerTest &lt; ActionController::TestCase
189 return { :name => _('Property2'), :content => lambda { link_to(product.name, '/plugin2') } } 190 return { :name => _('Property2'), :content => lambda { link_to(product.name, '/plugin2') } }
190 end 191 end
191 end 192 end
  193 + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s])
192 enterprise = fast_create(Enterprise) 194 enterprise = fast_create(Enterprise)
193 prod_cat = fast_create(ProductCategory) 195 prod_cat = fast_create(ProductCategory)
194 product = fast_create(Product, {:profile_id => enterprise.id, :name => "produto1", :product_category_id => prod_cat.id}, :search => true) 196 product = fast_create(Product, {:profile_id => enterprise.id, :name => "produto1", :product_category_id => prod_cat.id}, :search => true)
@@ -257,10 +259,10 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -257,10 +259,10 @@ class SearchControllerTest &lt; ActionController::TestCase
257 259
258 should 'render specific action when only one asset is enabled' do 260 should 'render specific action when only one asset is enabled' do
259 environment = Environment.default 261 environment = Environment.default
260 - # article is not disabled 262 + # article is not disabled
261 [:enterprises, :people, :communities, :products, :events].select do |key, name| 263 [:enterprises, :people, :communities, :products, :events].select do |key, name|
262 - environment.enable('disable_asset_' + key.to_s)  
263 - end 264 + environment.enable('disable_asset_' + key.to_s)
  265 + end
264 environment.save! 266 environment.save!
265 @controller.stubs(:environment).returns(environment) 267 @controller.stubs(:environment).returns(environment)
266 268
@@ -272,25 +274,25 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -272,25 +274,25 @@ class SearchControllerTest &lt; ActionController::TestCase
272 assert !assigns(:searches).has_key?(:communities) 274 assert !assigns(:searches).has_key?(:communities)
273 assert !assigns(:searches).has_key?(:products) 275 assert !assigns(:searches).has_key?(:products)
274 assert !assigns(:searches).has_key?(:events) 276 assert !assigns(:searches).has_key?(:events)
275 - end 277 + end
276 278
277 should 'search all enabled assets in general search' do 279 should 'search all enabled assets in general search' do
278 ent1 = create_profile_with_optional_category(Enterprise, 'test enterprise') 280 ent1 = create_profile_with_optional_category(Enterprise, 'test enterprise')
279 prod_cat = ProductCategory.create!(:name => 'pctest', :environment => Environment.default) 281 prod_cat = ProductCategory.create!(:name => 'pctest', :environment => Environment.default)
280 prod = ent1.products.create!(:name => 'test product', :product_category => prod_cat) 282 prod = ent1.products.create!(:name => 'test product', :product_category => prod_cat)
281 - art = Article.create!(:name => 'test article', :profile_id => fast_create(Person).id)  
282 - per = Person.create!(:name => 'test person', :identifier => 'test-person', :user_id => fast_create(User).id)  
283 - com = Community.create!(:name => 'test community')  
284 - 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)
285 287
286 get :index, :query => 'test' 288 get :index, :query => 'test'
287 289
288 [:articles, :enterprises, :people, :communities, :products, :events].select do |key, name| 290 [:articles, :enterprises, :people, :communities, :products, :events].select do |key, name|
289 - !assigns(:environment).enabled?('disable_asset_' + key.to_s)  
290 - end.each do |asset|  
291 - assert !assigns(:searches)[asset][:results].empty?  
292 - end  
293 - 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
294 296
295 should 'display category image while in directory' do 297 should 'display category image while in directory' do
296 parent = Category.create!(:name => 'category1', :environment => Environment.default) 298 parent = Category.create!(:name => 'category1', :environment => Environment.default)
@@ -316,8 +318,8 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -316,8 +318,8 @@ class SearchControllerTest &lt; ActionController::TestCase
316 person = create_user('someone').person 318 person = create_user('someone').person
317 ten_days_ago = Date.today - 10.day 319 ten_days_ago = Date.today - 10.day
318 320
319 - ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], :start_date => ten_days_ago)  
320 - 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)
321 323
322 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
323 assert_equal [ev1], assigns(:events) 325 assert_equal [ev1], assigns(:events)
@@ -327,7 +329,7 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -327,7 +329,7 @@ class SearchControllerTest &lt; ActionController::TestCase
327 person = create_user('someone').person 329 person = create_user('someone').person
328 ten_days_ago = Date.today - 10.day 330 ten_days_ago = Date.today - 10.day
329 331
330 - 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)
331 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)
332 334
333 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('/')
@@ -337,8 +339,8 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -337,8 +339,8 @@ class SearchControllerTest &lt; ActionController::TestCase
337 339
338 should 'return events of today when no date specified' do 340 should 'return events of today when no date specified' do
339 person = create_user('someone').person 341 person = create_user('someone').person
340 - ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], :start_date => Date.today)  
341 - 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)
342 344
343 get :events 345 get :events
344 346
@@ -349,9 +351,9 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -349,9 +351,9 @@ class SearchControllerTest &lt; ActionController::TestCase
349 person = create_user('someone').person 351 person = create_user('someone').person
350 352
351 ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], 353 ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id],
352 - :start_date => Date.today + 2.month) 354 + :start_date => Date.today + 2.month)
353 ev2 = create_event(person, :name => 'event 2', :category_ids => [@category.id], 355 ev2 = create_event(person, :name => 'event 2', :category_ids => [@category.id],
354 - :start_date => Date.today + 2.day) 356 + :start_date => Date.today + 2.day)
355 357
356 get :events 358 get :events
357 359
@@ -373,7 +375,7 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -373,7 +375,7 @@ class SearchControllerTest &lt; ActionController::TestCase
373 should 'see the events paginated' do 375 should 'see the events paginated' do
374 person = create_user('testuser').person 376 person = create_user('testuser').person
375 30.times do |i| 377 30.times do |i|
376 - create_event(person, :name => "Event #{i}", :start_date => Date.today) 378 + create_event(person, :name => "Event #{i}", :start_date => Date.today)
377 end 379 end
378 get :events 380 get :events
379 assert_equal 20, assigns(:events).count 381 assert_equal 20, assigns(:events).count
@@ -432,8 +434,8 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -432,8 +434,8 @@ class SearchControllerTest &lt; ActionController::TestCase
432 end 434 end
433 435
434 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
435 - (1..SearchController::MULTIPLE_SEARCH_LIMIT+1).each do |i|  
436 - 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")
437 ArticleCategorization.add_category_to_article(@category, a) 439 ArticleCategorization.add_category_to_article(@category, a)
438 end 440 end
439 441
@@ -579,55 +581,55 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -579,55 +581,55 @@ class SearchControllerTest &lt; ActionController::TestCase
579 assert_not_includes assigns(:searches)[:communities][:results], p1 581 assert_not_includes assigns(:searches)[:communities][:results], p1
580 end 582 end
581 583
582 - should 'keep old urls working' do  
583 - get :assets, :asset => 'articles' 584 + should 'keep old urls working' do
  585 + get :assets, :asset => 'articles'
584 assert_redirected_to :controller => :search, :action => :articles 586 assert_redirected_to :controller => :search, :action => :articles
585 - get :assets, :asset => 'people' 587 + get :assets, :asset => 'people'
586 assert_redirected_to :controller => :search, :action => :people 588 assert_redirected_to :controller => :search, :action => :people
587 - get :assets, :asset => 'communities' 589 + get :assets, :asset => 'communities'
588 assert_redirected_to :controller => :search, :action => :communities 590 assert_redirected_to :controller => :search, :action => :communities
589 - get :assets, :asset => 'products' 591 + get :assets, :asset => 'products'
590 assert_redirected_to :controller => :search, :action => :products 592 assert_redirected_to :controller => :search, :action => :products
591 - get :assets, :asset => 'enterprises' 593 + get :assets, :asset => 'enterprises'
592 assert_redirected_to :controller => :search, :action => :enterprises 594 assert_redirected_to :controller => :search, :action => :enterprises
593 - get :assets, :asset => 'events' 595 + get :assets, :asset => 'events'
594 assert_redirected_to :controller => :search, :action => :events 596 assert_redirected_to :controller => :search, :action => :events
595 - end 597 + end
596 598
597 - should 'show tag cloud' do  
598 - @controller.stubs(:is_cache_expired?).returns(true) 599 + should 'show tag cloud' do
  600 + @controller.stubs(:is_cache_expired?).returns(true)
599 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)
600 a.tag_list = ['one', 'two'] 602 a.tag_list = ['one', 'two']
601 - a.save_tags 603 + a.save_tags
602 604
603 - get :tags 605 + get :tags
604 606
605 - assert assigns(:tags)["two"] = 1  
606 - assert assigns(:tags)["one"] = 1  
607 - end 607 + assert assigns(:tags)["two"] = 1
  608 + assert assigns(:tags)["one"] = 1
  609 + end
608 610
609 should 'show tagged content' do 611 should 'show tagged content' do
610 - @controller.stubs(:is_cache_expired?).returns(true) 612 + @controller.stubs(:is_cache_expired?).returns(true)
611 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)
612 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)
613 a.tag_list = ['one', 'two'] 615 a.tag_list = ['one', 'two']
614 a2.tag_list = ['two', 'three'] 616 a2.tag_list = ['two', 'three']
615 - a.save_tags 617 + a.save_tags
616 a2.save_tags 618 a2.save_tags
617 619
618 - get :tag, :tag => 'two' 620 + get :tag, :tag => 'two'
619 621
620 assert_equivalent [a, a2], assigns(:searches)[:tag][:results] 622 assert_equivalent [a, a2], assigns(:searches)[:tag][:results]
621 623
622 - get :tag, :tag => 'one' 624 + get :tag, :tag => 'one'
623 625
624 assert_equivalent [a], assigns(:searches)[:tag][:results] 626 assert_equivalent [a], assigns(:searches)[:tag][:results]
625 end 627 end
626 628
627 should 'not show assets from other environments' do 629 should 'not show assets from other environments' do
628 other_env = Environment.create!(:name => 'Another environment') 630 other_env = Environment.create!(:name => 'Another environment')
629 - p1 = Person.create!(:name => 'Hildebrando', :identifier => 'hild', :user_id => fast_create(User).id, :environment_id => other_env.id)  
630 - 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)
631 art1 = Article.create!(:name => 'my article', :profile_id => p1.id) 633 art1 = Article.create!(:name => 'my article', :profile_id => p1.id)
632 art2 = Article.create!(:name => 'my article', :profile_id => p2.id) 634 art2 = Article.create!(:name => 'my article', :profile_id => p2.id)
633 635
@@ -638,9 +640,9 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -638,9 +640,9 @@ class SearchControllerTest &lt; ActionController::TestCase
638 640
639 should 'order articles by more recent' do 641 should 'order articles by more recent' do
640 Article.destroy_all 642 Article.destroy_all
641 - art1 = Article.create!(:name => 'review C', :profile_id => fast_create(Person).id, :created_at => Time.now-1.days)  
642 - art2 = Article.create!(:name => 'review A', :profile_id => fast_create(Person).id, :created_at => Time.now)  
643 - 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)
644 646
645 get :articles, :filter => :more_recent 647 get :articles, :filter => :more_recent
646 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/application_helper_test.rb
@@ -676,6 +676,7 @@ class ApplicationHelperTest &lt; ActiveSupport::TestCase @@ -676,6 +676,7 @@ class ApplicationHelperTest &lt; ActiveSupport::TestCase
676 should 'parse macros' do 676 should 'parse macros' do
677 class Plugin1 < Noosfero::Plugin 677 class Plugin1 < Noosfero::Plugin
678 end 678 end
  679 + Noosfero::Plugin.stubs(:all).returns(['ApplicationHelperTest::Plugin1'])
679 680
680 class Plugin1::Macro1 < Noosfero::Plugin::Macro 681 class Plugin1::Macro1 < Noosfero::Plugin::Macro
681 def parse(params, inner_html, source) 682 def parse(params, inner_html, source)
test/unit/block_test.rb
@@ -223,6 +223,61 @@ class BlockTest &lt; ActiveSupport::TestCase @@ -223,6 +223,61 @@ 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 +
  236 + should 'default value for display_user is all' do
  237 + block = Block.new
  238 + assert_equal 'all', block.display_user
  239 + end
  240 +
  241 + should 'display block to not logged users for display_user = all' do
  242 + block = Block.new
  243 + assert block.display_to_user?(nil)
  244 + end
  245 +
  246 + should 'display block to logged users for display_user = all' do
  247 + block = Block.new
  248 + assert block.display_to_user?(User.new)
  249 + end
  250 +
  251 + should 'display block to logged users for display_user = logged' do
  252 + block = Block.new
  253 + block.display_user = 'logged'
  254 + assert block.display_to_user?(User.new)
  255 + end
  256 +
  257 + should 'do not display block to logged users for display_user = not_logged' do
  258 + block = Block.new
  259 + block.display_user = 'not_logged'
  260 + assert !block.display_to_user?(User.new)
  261 + end
  262 +
  263 + should 'do not display block to not logged users for display_user = logged' do
  264 + block = Block.new
  265 + block.display_user = 'logged'
  266 + assert !block.display_to_user?(nil)
  267 + end
  268 +
  269 + should 'display block to not logged users for display_user = not_logged' do
  270 + block = Block.new
  271 + block.display_user = 'not_logged'
  272 + assert block.display_to_user?(nil)
  273 + end
  274 +
  275 + should 'not be visible if display_to_user? is false' do
  276 + block = Block.new
  277 + block.expects(:display_to_user?).once.returns(false)
  278 + assert !block.visible?({})
  279 + end
  280 +
226 should 'accept user as parameter on cache_key without change its value' do 281 should 'accept user as parameter on cache_key without change its value' do
227 person = fast_create(Person) 282 person = fast_create(Person)
228 block = Block.new 283 block = Block.new
test/unit/boxes_helper_test.rb
@@ -54,6 +54,7 @@ class BoxesHelperTest &lt; ActiveSupport::TestCase @@ -54,6 +54,7 @@ class BoxesHelperTest &lt; ActiveSupport::TestCase
54 expects(:display_block).with(b, '') 54 expects(:display_block).with(b, '')
55 stubs(:request).returns(request) 55 stubs(:request).returns(request)
56 stubs(:block_target).returns('') 56 stubs(:block_target).returns('')
  57 + stubs(:user).returns(nil)
57 expects(:locale).returns('en') 58 expects(:locale).returns('en')
58 with_box_decorator self do 59 with_box_decorator self do
59 display_box_content(box, '') 60 display_box_content(box, '')
@@ -73,6 +74,7 @@ class BoxesHelperTest &lt; ActiveSupport::TestCase @@ -73,6 +74,7 @@ class BoxesHelperTest &lt; ActiveSupport::TestCase
73 box.save! 74 box.save!
74 expects(:display_block).with(b, '').never 75 expects(:display_block).with(b, '').never
75 stubs(:request).returns(request) 76 stubs(:request).returns(request)
  77 + stubs(:user).returns(nil)
76 stubs(:block_target).returns('') 78 stubs(:block_target).returns('')
77 expects(:locale).returns('en') 79 expects(:locale).returns('en')
78 display_box_content(box, '') 80 display_box_content(box, '')
@@ -111,8 +113,9 @@ class BoxesHelperTest &lt; ActiveSupport::TestCase @@ -111,8 +113,9 @@ class BoxesHelperTest &lt; ActiveSupport::TestCase
111 request.expects(:path).returns('/') 113 request.expects(:path).returns('/')
112 request.expects(:params).returns({}) 114 request.expects(:params).returns({})
113 stubs(:request).returns(request) 115 stubs(:request).returns(request)
  116 + stubs(:user).returns(nil)
114 expects(:locale).returns('en') 117 expects(:locale).returns('en')
115 - box_decorator.expects(:select_blocks).with([], {:article => nil, :request_path => '/', :locale => 'en', :params => {}}).returns([]) 118 + box_decorator.expects(:select_blocks).with([], {:article => nil, :request_path => '/', :locale => 'en', :params => {}, :user => nil}).returns([])
116 119
117 display_box_content(box, '') 120 display_box_content(box, '')
118 end 121 end
test/unit/comment_test.rb
@@ -468,8 +468,8 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -468,8 +468,8 @@ class CommentTest &lt; ActiveSupport::TestCase
468 end 468 end
469 end 469 end
470 470
471 -  
472 should 'delegate spam detection to plugins' do 471 should 'delegate spam detection to plugins' do
  472 + Noosfero::Plugin.stubs(:all).returns(['CommentTest::EverythingIsSpam'])
473 Environment.default.enable_plugin(EverythingIsSpam) 473 Environment.default.enable_plugin(EverythingIsSpam)
474 474
475 c1 = create_comment 475 c1 = create_comment
@@ -495,6 +495,7 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -495,6 +495,7 @@ class CommentTest &lt; ActiveSupport::TestCase
495 end 495 end
496 496
497 should 'notify plugins of comments being marked as spam' do 497 should 'notify plugins of comments being marked as spam' do
  498 + Noosfero::Plugin.stubs(:all).returns(['CommentTest::SpamNotification'])
498 Environment.default.enable_plugin(SpamNotification) 499 Environment.default.enable_plugin(SpamNotification)
499 500
500 c = create_comment 501 c = create_comment
@@ -506,6 +507,7 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -506,6 +507,7 @@ class CommentTest &lt; ActiveSupport::TestCase
506 end 507 end
507 508
508 should 'notify plugins of comments being marked as ham' do 509 should 'notify plugins of comments being marked as ham' do
  510 + Noosfero::Plugin.stubs(:all).returns(['CommentTest::SpamNotification'])
509 Environment.default.enable_plugin(SpamNotification) 511 Environment.default.enable_plugin(SpamNotification)
510 512
511 c = create_comment 513 c = create_comment
test/unit/forgot_password_helper_test.rb
@@ -22,6 +22,7 @@ class ForgotPasswordHelperTest &lt; ActionView::TestCase @@ -22,6 +22,7 @@ class ForgotPasswordHelperTest &lt; ActionView::TestCase
22 {:field => 'f3', :name => 'F3', :model => 'person'}] 22 {:field => 'f3', :name => 'F3', :model => 'person'}]
23 end 23 end
24 end 24 end
  25 + Noosfero::Plugin.stubs(:all).returns(['ForgotPasswordHelperTest::Plugin1', 'ForgotPasswordHelperTest::Plugin2'])
25 26
26 environment.enable_plugin(Plugin1) 27 environment.enable_plugin(Plugin1)
27 environment.enable_plugin(Plugin2) 28 environment.enable_plugin(Plugin2)
@@ -43,6 +44,7 @@ class ForgotPasswordHelperTest &lt; ActionView::TestCase @@ -43,6 +44,7 @@ class ForgotPasswordHelperTest &lt; ActionView::TestCase
43 {:field => 'f3', :name => 'F3', :model => 'person'}] 44 {:field => 'f3', :name => 'F3', :model => 'person'}]
44 end 45 end
45 end 46 end
  47 + Noosfero::Plugin.stubs(:all).returns(['ForgotPasswordHelperTest::Plugin1', 'ForgotPasswordHelperTest::Plugin2'])
46 48
47 environment.enable_plugin(Plugin1) 49 environment.enable_plugin(Plugin1)
48 environment.enable_plugin(Plugin2) 50 environment.enable_plugin(Plugin2)
@@ -64,6 +66,7 @@ class ForgotPasswordHelperTest &lt; ActionView::TestCase @@ -64,6 +66,7 @@ class ForgotPasswordHelperTest &lt; ActionView::TestCase
64 {:field => 'f3', :name => 'F3', :model => 'user'}] 66 {:field => 'f3', :name => 'F3', :model => 'user'}]
65 end 67 end
66 end 68 end
  69 + Noosfero::Plugin.stubs(:all).returns(['ForgotPasswordHelperTest::Plugin1', 'ForgotPasswordHelperTest::Plugin2'])
67 70
68 environment.enable_plugin(Plugin1) 71 environment.enable_plugin(Plugin1)
69 environment.enable_plugin(Plugin2) 72 environment.enable_plugin(Plugin2)
@@ -85,6 +88,7 @@ class ForgotPasswordHelperTest &lt; ActionView::TestCase @@ -85,6 +88,7 @@ class ForgotPasswordHelperTest &lt; ActionView::TestCase
85 {:field => 'f3', :name => 'F3', :model => 'user'}] 88 {:field => 'f3', :name => 'F3', :model => 'user'}]
86 end 89 end
87 end 90 end
  91 + Noosfero::Plugin.stubs(:all).returns(['ForgotPasswordHelperTest::Plugin1', 'ForgotPasswordHelperTest::Plugin2'])
88 92
89 environment.enable_plugin(Plugin1) 93 environment.enable_plugin(Plugin1)
90 environment.enable_plugin(Plugin2) 94 environment.enable_plugin(Plugin2)
test/unit/link_list_block_test.rb
@@ -39,6 +39,32 @@ class LinkListBlockTest &lt; ActiveSupport::TestCase @@ -39,6 +39,32 @@ class LinkListBlockTest &lt; ActiveSupport::TestCase
39 assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/test_profile/address'} 39 assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/test_profile/address'}
40 end 40 end
41 41
  42 + should 'replace {portal} with environment portal identifier' do
  43 + env = Environment.default
  44 + env.enable('use_portal_community')
  45 + portal = fast_create(Community, :identifier => 'portal-community', :environment_id => env.id)
  46 + env.portal_community = portal
  47 + env.save
  48 +
  49 + stubs(:environment).returns(env)
  50 + l = LinkListBlock.new(:links => [{:name => 'categ', :address => '/{portal}/address'}])
  51 + l.stubs(:owner).returns(env)
  52 + assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/portal-community/address'}
  53 + end
  54 +
  55 + should 'not change address if no {portal} there' do
  56 + env = Environment.default
  57 + env.enable('use_portal_community')
  58 + portal = fast_create(Community, :identifier => 'portal-community', :environment_id => env.id)
  59 + env.portal_community = portal
  60 + env.save
  61 +
  62 + stubs(:environment).returns(env)
  63 + l = LinkListBlock.new(:links => [{:name => 'categ', :address => '/address'}])
  64 + l.stubs(:owner).returns(env)
  65 + assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/address'}
  66 + end
  67 +
42 should 'display options for icons' do 68 should 'display options for icons' do
43 l = LinkListBlock.new 69 l = LinkListBlock.new
44 l.icons_options.each do |option| 70 l.icons_options.each do |option|
test/unit/macros_helper_test.rb
@@ -28,6 +28,7 @@ class MacrosHelperTest &lt; ActiveSupport::TestCase @@ -28,6 +28,7 @@ class MacrosHelperTest &lt; ActiveSupport::TestCase
28 end 28 end
29 29
30 def setup 30 def setup
  31 + Noosfero::Plugin.stubs(:all).returns(['MacrosHelperTest::Plugin1'])
31 @environment = Environment.default 32 @environment = Environment.default
32 @environment.enable_plugin(Plugin1) 33 @environment.enable_plugin(Plugin1)
33 @plugins = Noosfero::Plugin::Manager.new(@environment, self) 34 @plugins = Noosfero::Plugin::Manager.new(@environment, self)
@@ -129,4 +130,27 @@ class MacrosHelperTest &lt; ActiveSupport::TestCase @@ -129,4 +130,27 @@ class MacrosHelperTest &lt; ActiveSupport::TestCase
129 assert_equal 'macro_generator', macro_generator(Plugin1::Macro) 130 assert_equal 'macro_generator', macro_generator(Plugin1::Macro)
130 end 131 end
131 132
  133 + should 'get macro default generator' do
  134 + class Plugin1::Macro < Noosfero::Plugin::Macro
  135 + def self.configuration
  136 + { :params => [] }
  137 + end
  138 + end
  139 + assert_nothing_raised NoMethodError do
  140 + assert macro_generator(Plugin1::Macro)
  141 + end
  142 + end
  143 +
  144 + should 'can use a code reference as macro generator' do
  145 + class Plugin1::Macro < Noosfero::Plugin::Macro
  146 + def self.configuration
  147 + { :params => [], :generator => method(:macro_generator_method) }
  148 + end
  149 + def self.macro_generator_method(macro)
  150 + "macro generator method return"
  151 + end
  152 + end
  153 + assert_equal "macro generator method return", macro_generator(Plugin1::Macro)
  154 + end
  155 +
132 end 156 end
test/unit/person_test.rb
@@ -1255,6 +1255,7 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1255,6 +1255,7 @@ class PersonTest &lt; ActiveSupport::TestCase
1255 false 1255 false
1256 end 1256 end
1257 end 1257 end
  1258 + Noosfero::Plugin.stubs(:all).returns(['PersonTest::Plugin1', 'PersonTest::Plugin2'])
1258 1259
1259 e = Environment.default 1260 e = Environment.default
1260 e.enable_plugin(Plugin1.name) 1261 e.enable_plugin(Plugin1.name)
@@ -1424,6 +1425,7 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1424,6 +1425,7 @@ class PersonTest &lt; ActiveSupport::TestCase
1424 Profile.memberships_of(Person.find_by_identifier('person2')) 1425 Profile.memberships_of(Person.find_by_identifier('person2'))
1425 end 1426 end
1426 end 1427 end
  1428 + Noosfero::Plugin.stubs(:all).returns(['PersonTest::Plugin1', 'PersonTest::Plugin2'])
1427 1429
1428 Environment.default.enable_plugin(Plugin1) 1430 Environment.default.enable_plugin(Plugin1)
1429 Environment.default.enable_plugin(Plugin2) 1431 Environment.default.enable_plugin(Plugin2)
test/unit/plugin_manager_test.rb
@@ -26,6 +26,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -26,6 +26,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
26 class Plugin2 < Noosfero::Plugin; end; 26 class Plugin2 < Noosfero::Plugin; end;
27 class Plugin3 < Noosfero::Plugin; end; 27 class Plugin3 < Noosfero::Plugin; end;
28 class Plugin4 < Noosfero::Plugin; end; 28 class Plugin4 < Noosfero::Plugin; end;
  29 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3', 'PluginManagerTest::Plugin4'])
29 environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s, Plugin4.to_s]) 30 environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s, Plugin4.to_s])
30 Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin3.to_s, Plugin4.to_s]) 31 Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin3.to_s, Plugin4.to_s])
31 results = plugins.enabled_plugins.map { |instance| instance.class.to_s } 32 results = plugins.enabled_plugins.map { |instance| instance.class.to_s }
@@ -51,6 +52,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -51,6 +52,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
51 'Plugin 2 action.' 52 'Plugin 2 action.'
52 end 53 end
53 end 54 end
  55 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2'])
54 56
55 environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s]) 57 environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s])
56 58
@@ -83,6 +85,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -83,6 +85,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
83 'Plugin 3 action.' 85 'Plugin 3 action.'
84 end 86 end
85 end 87 end
  88 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3'])
86 89
87 environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s, Plugin3.to_s]) 90 environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s, Plugin3.to_s])
88 p1 = Plugin1.new 91 p1 = Plugin1.new
@@ -107,6 +110,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -107,6 +110,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
107 'Plugin3' 110 'Plugin3'
108 end 111 end
109 end 112 end
  113 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3'])
110 114
111 environment.enable_plugin(Plugin1.name) 115 environment.enable_plugin(Plugin1.name)
112 environment.enable_plugin(Plugin2.name) 116 environment.enable_plugin(Plugin2.name)
@@ -134,6 +138,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -134,6 +138,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
134 true 138 true
135 end 139 end
136 end 140 end
  141 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3'])
137 142
138 environment.enable_plugin(Plugin1.name) 143 environment.enable_plugin(Plugin1.name)
139 environment.enable_plugin(Plugin2.name) 144 environment.enable_plugin(Plugin2.name)
@@ -162,6 +167,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -162,6 +167,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
162 true 167 true
163 end 168 end
164 end 169 end
  170 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3'])
165 171
166 environment.enable_plugin(Plugin1.name) 172 environment.enable_plugin(Plugin1.name)
167 environment.enable_plugin(Plugin2.name) 173 environment.enable_plugin(Plugin2.name)
@@ -178,6 +184,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -178,6 +184,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
178 [Macro1, Macro2] 184 [Macro1, Macro2]
179 end 185 end
180 end 186 end
  187 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1'])
181 188
182 class Plugin1::Macro1 < Noosfero::Plugin::Macro 189 class Plugin1::Macro1 < Noosfero::Plugin::Macro
183 def convert(macro, source) 190 def convert(macro, source)
@@ -212,6 +219,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -212,6 +219,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
212 [v1 * v, v2 * v] 219 [v1 * v, v2 * v]
213 end 220 end
214 end 221 end
  222 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2'])
215 223
216 environment.enable_plugin(Plugin1) 224 environment.enable_plugin(Plugin1)
217 environment.enable_plugin(Plugin2) 225 environment.enable_plugin(Plugin2)
@@ -231,6 +239,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -231,6 +239,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
231 value * 5 239 value * 5
232 end 240 end
233 end 241 end
  242 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2'])
234 243
235 environment.enable_plugin(Plugin1) 244 environment.enable_plugin(Plugin1)
236 environment.enable_plugin(Plugin2) 245 environment.enable_plugin(Plugin2)
@@ -252,6 +261,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -252,6 +261,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
252 [v1 * v, v2 * v, 666] 261 [v1 * v, v2 * v, 666]
253 end 262 end
254 end 263 end
  264 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2'])
255 265
256 environment.enable_plugin(Plugin1) 266 environment.enable_plugin(Plugin1)
257 environment.enable_plugin(Plugin2) 267 environment.enable_plugin(Plugin2)
@@ -273,6 +283,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -273,6 +283,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
273 numbers.reject {|n| n<=5} 283 numbers.reject {|n| n<=5}
274 end 284 end
275 end 285 end
  286 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2'])
276 287
277 environment.enable_plugin(Plugin1) 288 environment.enable_plugin(Plugin1)
278 environment.enable_plugin(Plugin2) 289 environment.enable_plugin(Plugin2)
test/unit/plugin_test.rb
@@ -9,15 +9,9 @@ class PluginTest &lt; ActiveSupport::TestCase @@ -9,15 +9,9 @@ class PluginTest &lt; ActiveSupport::TestCase
9 9
10 include Noosfero::Plugin::HotSpot 10 include Noosfero::Plugin::HotSpot
11 11
12 - should 'keep the list of all loaded subclasses' do  
13 - class Plugin1 < Noosfero::Plugin  
14 - end  
15 -  
16 - class Plugin2 < Noosfero::Plugin  
17 - end  
18 -  
19 - assert_includes Noosfero::Plugin.all, Plugin1.to_s  
20 - assert_includes Noosfero::Plugin.all, Plugin2.to_s 12 + should 'keep the list of all available plugins' do
  13 + assert File.directory?(File.join(Rails.root, 'plugins', 'foo'))
  14 + assert_includes Noosfero::Plugin.all, 'FooPlugin'
21 end 15 end
22 16
23 should 'returns url to plugin management if plugin has admin_controller' do 17 should 'returns url to plugin management if plugin has admin_controller' do
test/unit/profile_test.rb
@@ -1790,6 +1790,7 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -1790,6 +1790,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1790 Person.members_of(Community.find_by_identifier('community2')) 1790 Person.members_of(Community.find_by_identifier('community2'))
1791 end 1791 end
1792 end 1792 end
  1793 + Noosfero::Plugin.stubs(:all).returns(['ProfileTest::Plugin1', 'ProfileTest::Plugin2'])
1793 Environment.default.enable_plugin(Plugin1) 1794 Environment.default.enable_plugin(Plugin1)
1794 Environment.default.enable_plugin(Plugin2) 1795 Environment.default.enable_plugin(Plugin2)
1795 1796
@@ -1947,6 +1948,7 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -1947,6 +1948,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1947 end 1948 end
1948 1949
1949 environment = Environment.default 1950 environment = Environment.default
  1951 + Noosfero::Plugin.stubs(:all).returns(['ProfileTest::Plugin1'])
1950 environment.enable_plugin(Plugin1) 1952 environment.enable_plugin(Plugin1)
1951 plugins = Noosfero::Plugin::Manager.new(environment, self) 1953 plugins = Noosfero::Plugin::Manager.new(environment, self)
1952 p = fast_create(Profile) 1954 p = fast_create(Profile)
test/unit/suggest_article_test.rb
@@ -7,6 +7,7 @@ class SuggestArticleTest &lt; ActiveSupport::TestCase @@ -7,6 +7,7 @@ class SuggestArticleTest &lt; ActiveSupport::TestCase
7 ActionMailer::Base.perform_deliveries = true 7 ActionMailer::Base.perform_deliveries = true
8 ActionMailer::Base.deliveries = [] 8 ActionMailer::Base.deliveries = []
9 @profile = create_user('test_user').person 9 @profile = create_user('test_user').person
  10 + Noosfero::Plugin.stubs(:all).returns(['SuggestArticleTest::EverythingIsSpam', 'SuggestArticleTest::SpamNotification'])
10 end 11 end
11 attr_reader :profile 12 attr_reader :profile
12 13
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