Commit af190be9024982c5d0fdd088782174420a3bf65c
Exists in
master
and in
27 other branches
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 | 80 | render :action => 'edit', :layout => false |
| 81 | 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 | 99 | def save |
| 84 | 100 | @block = boxes_holder.blocks.find(params[:id]) |
| 85 | 101 | @block.update_attributes(params[:block]) |
| ... | ... | @@ -99,6 +115,12 @@ class BoxOrganizerController < ApplicationController |
| 99 | 115 | end |
| 100 | 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 | 124 | protected :boxes_editor? |
| 103 | 125 | |
| 104 | 126 | end | ... | ... |
| ... | ... | @@ -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 < MyProfileController |
| 31 | 31 | end |
| 32 | 32 | |
| 33 | 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 | 35 | end |
| 42 | 36 | |
| 43 | 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 | 39 | end |
| 52 | 40 | |
| 53 | 41 | end | ... | ... |
app/controllers/my_profile/profile_design_controller.rb
app/controllers/public/account_controller.rb
| ... | ... | @@ -246,15 +246,19 @@ class AccountController < ApplicationController |
| 246 | 246 | end |
| 247 | 247 | end |
| 248 | 248 | |
| 249 | - def check_url | |
| 249 | + def check_valid_name | |
| 250 | 250 | @identifier = params[:identifier] |
| 251 | 251 | valid = Person.is_available?(@identifier, environment) |
| 252 | 252 | if valid |
| 253 | 253 | @status = _('This login name is available') |
| 254 | 254 | @status_class = 'validated' |
| 255 | - else | |
| 255 | + elsif !@identifier.empty? | |
| 256 | + @suggested_usernames = suggestion_based_on_username(@identifier) | |
| 256 | 257 | @status = _('This login name is unavailable') |
| 257 | 258 | @status_class = 'invalid' |
| 259 | + else | |
| 260 | + @status_class = 'invalid' | |
| 261 | + @status = _('This field can\'t be blank') | |
| 258 | 262 | end |
| 259 | 263 | render :partial => 'identifier_status' |
| 260 | 264 | end |
| ... | ... | @@ -287,6 +291,23 @@ class AccountController < ApplicationController |
| 287 | 291 | render :text => user_data.to_json, :layout => false, :content_type => "application/javascript" |
| 288 | 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 | 311 | protected |
| 291 | 312 | |
| 292 | 313 | def redirect? | ... | ... |
app/controllers/public/content_viewer_controller.rb
| ... | ... | @@ -113,6 +113,15 @@ class ContentViewerController < ApplicationController |
| 113 | 113 | @comments = @plugins.filter(:unavailable_comments, @comments) |
| 114 | 114 | @comments_count = @comments.count |
| 115 | 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 | 126 | if params[:slideshow] |
| 118 | 127 | render :action => 'slideshow', :layout => 'slideshow' | ... | ... |
app/helpers/account_helper.rb
| ... | ... | @@ -12,4 +12,17 @@ module AccountHelper |
| 12 | 12 | _('Checking if e-mail address is already taken...') |
| 13 | 13 | end |
| 14 | 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 | 28 | end | ... | ... |
app/helpers/boxes_helper.rb
| ... | ... | @@ -65,7 +65,7 @@ module BoxesHelper |
| 65 | 65 | end |
| 66 | 66 | |
| 67 | 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 | 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 | 70 | end |
| 71 | 71 | |
| ... | ... | @@ -212,13 +212,24 @@ module BoxesHelper |
| 212 | 212 | |
| 213 | 213 | if !block.main? |
| 214 | 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 | 216 | end |
| 217 | 217 | |
| 218 | 218 | if block.respond_to?(:help) |
| 219 | 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 | 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 | 233 | content_tag('div', buttons.join("\n") + tag('br', :style => 'clear: left'), :class => 'button-bar') |
| 223 | 234 | end |
| 224 | 235 | ... | ... |
app/helpers/macros_helper.rb
| ... | ... | @@ -20,14 +20,16 @@ module MacrosHelper |
| 20 | 20 | jQuery('<div>'+#{macro_configuration_dialog(macro).to_json}+'</div>').dialog({ |
| 21 | 21 | title: #{macro_title(macro).to_json}, |
| 22 | 22 | modal: true, |
| 23 | - buttons: [ | |
| 24 | - {text: #{_('Ok').to_json}, click: function(){ | |
| 23 | + buttons: { | |
| 24 | + #{_('Ok').to_json}: function(){ | |
| 25 | 25 | tinyMCE.activeEditor.execCommand('mceInsertContent', false, |
| 26 | 26 | (function(dialog){ #{macro_generator(macro)} })(this)); |
| 27 | 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 | 35 | end |
| ... | ... | @@ -57,7 +59,11 @@ module MacrosHelper |
| 57 | 59 | |
| 58 | 60 | def macro_generator(macro) |
| 59 | 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 | 67 | else |
| 62 | 68 | macro_default_generator(macro) |
| 63 | 69 | end |
| ... | ... | @@ -66,8 +72,7 @@ module MacrosHelper |
| 66 | 72 | |
| 67 | 73 | def macro_default_generator(macro) |
| 68 | 74 | code = "var params = {};" |
| 69 | - configuration = macro_configuration(macro) | |
| 70 | - configuration[:params].map do |field| | |
| 75 | + macro.configuration[:params].map do |field| | |
| 71 | 76 | code += "params.#{field[:name]} = jQuery('*[name=#{field[:name]}]', dialog).val();" |
| 72 | 77 | end |
| 73 | 78 | code + " | ... | ... |
| ... | ... | @@ -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 | 27 | hintText: #{options[:hint_text].to_json}, |
| 28 | 28 | noResultsText: #{options[:no_results_text].to_json}, |
| 29 | 29 | searchingText: #{options[:searching_text].to_json}, |
| 30 | - searchDelay: #{options[:serach_delay].to_json}, | |
| 30 | + searchDelay: #{options[:search_delay].to_json}, | |
| 31 | 31 | preventDuplicates: #{options[:prevent_duplicates].to_json}, |
| 32 | 32 | backspaceDeleteItem: #{options[:backspace_delete_item].to_json}, |
| 33 | 33 | queryParam: #{name.to_json}, | ... | ... |
app/models/block.rb
| ... | ... | @@ -16,17 +16,36 @@ class Block < ActiveRecord::Base |
| 16 | 16 | |
| 17 | 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 | 36 | # Determines whether a given block must be visible. Optionally a |
| 20 | 37 | # <tt>context</tt> must be specified. <tt>context</tt> must be a hash, and |
| 21 | 38 | # may contain the following keys: |
| 22 | 39 | # |
| 23 | 40 | # * <tt>:article</tt>: the article being viewed currently |
| 24 | 41 | # * <tt>:language</tt>: in which language the block will be displayed |
| 42 | + # * <tt>:user</tt>: the logged user | |
| 25 | 43 | def visible?(context = nil) |
| 26 | 44 | return false if display == 'never' |
| 27 | 45 | |
| 28 | 46 | if context |
| 29 | 47 | return false if language != 'all' && language != context[:locale] |
| 48 | + return false unless display_to_user?(context[:user]) | |
| 30 | 49 | |
| 31 | 50 | begin |
| 32 | 51 | return self.send("display_#{display}", context) |
| ... | ... | @@ -38,6 +57,10 @@ class Block < ActiveRecord::Base |
| 38 | 57 | true |
| 39 | 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 | 64 | def display_always(context) |
| 42 | 65 | true |
| 43 | 66 | end |
| ... | ... | @@ -68,6 +91,14 @@ class Block < ActiveRecord::Base |
| 68 | 91 | # the homepage of its owner. |
| 69 | 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 | 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 | 104 | # * <tt>'all'</tt>: the block is always displayed |
| ... | ... | @@ -171,12 +202,20 @@ class Block < ActiveRecord::Base |
| 171 | 202 | 'never' => __('Don\'t display'), |
| 172 | 203 | } |
| 173 | 204 | |
| 174 | - def display_options | |
| 205 | + def display_options_available | |
| 175 | 206 | DISPLAY_OPTIONS.keys |
| 176 | 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 | 219 | end |
| 181 | 220 | |
| 182 | 221 | def duplicate | ... | ... |
app/models/link_list_block.rb
| ... | ... | @@ -70,6 +70,8 @@ class LinkListBlock < Block |
| 70 | 70 | def expand_address(address) |
| 71 | 71 | add = if owner.respond_to?(:identifier) |
| 72 | 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 | 75 | else |
| 74 | 76 | address |
| 75 | 77 | end | ... | ... |
app/models/main_block.rb
app/models/national_region.rb
| ... | ... | @@ -12,7 +12,7 @@ class NationalRegion < ActiveRecord::Base |
| 12 | 12 | adtional_contions = ""; |
| 13 | 13 | |
| 14 | 14 | if like |
| 15 | - operator = "like" | |
| 15 | + operator = "ilike" | |
| 16 | 16 | find_return = :all |
| 17 | 17 | end |
| 18 | 18 | |
| ... | ... | @@ -41,7 +41,7 @@ class NationalRegion < ActiveRecord::Base |
| 41 | 41 | find_return = :first |
| 42 | 42 | |
| 43 | 43 | if like |
| 44 | - operator = "like" | |
| 44 | + operator = "ilike" | |
| 45 | 45 | find_return = :all |
| 46 | 46 | end |
| 47 | 47 | ... | ... |
app/models/text_article.rb
| ... | ... | @@ -20,4 +20,23 @@ class TextArticle < Article |
| 20 | 20 | def can_display_versions? |
| 21 | 21 | true |
| 22 | 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 | 42 | end | ... | ... |
app/views/account/_identifier_status.rhtml
| 1 | 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 | 12 | <script type="text/javascript"> |
| 4 | 13 | jQuery('#user_login').removeClass('<%= validation_classes %>'); |
| 5 | 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 | 20 | </script> |
| 7 | 21 | </div> | ... | ... |
app/views/account/_signup_form.rhtml
| ... | ... | @@ -7,6 +7,8 @@ |
| 7 | 7 | |
| 8 | 8 | <% @profile_data = @person %> |
| 9 | 9 | |
| 10 | +<%= javascript_include_tag('sign_up_password_rate') %> | |
| 11 | + | |
| 10 | 12 | <%= error_messages_for :user, :person, :header_message => _('The account could not be created') %> |
| 11 | 13 | |
| 12 | 14 | <% labelled_form_for :user, @user, :html => { :multipart => true, :id => 'signup-form', :honeypot => true } do |f| %> |
| ... | ... | @@ -35,24 +37,30 @@ |
| 35 | 37 | <%= required text_field(:user, :login, :id => 'user_login', |
| 36 | 38 | :onchange => 'this.value = convToValidUsername(this.value);') %> |
| 37 | 39 | <div id='url-check'><p> </p></div> |
| 40 | + <span id='checking-message' class='checking' style='display:none'><%= _('Checking availability of login name...') %></span> | |
| 38 | 41 | </div> |
| 39 | 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 | 43 | <br style="clear: both;" /> |
| 41 | 44 | </div> |
| 42 | 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 | 47 | <div id='signup-password'> |
| 53 | 48 | <%= required f.password_field(:password, :id => 'user_pw') %> |
| 54 | 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> </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 | 64 | </div> |
| 57 | 65 | |
| 58 | 66 | <div id='signup-password-confirmation'> |
| ... | ... | @@ -182,4 +190,9 @@ jQuery(function($) { |
| 182 | 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 | 198 | </script> | ... | ... |
app/views/box_organizer/_link_list_block.rhtml
| 1 | +<%= javascript_include_tag "edit-link-list.js" %> | |
| 2 | + | |
| 1 | 3 | <strong><%= _('Links') %></strong> |
| 2 | 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 | 35 | </div> |
| 22 | 36 | |
| 23 | 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 | 49 | end %> | ... | ... |
app/views/box_organizer/edit.rhtml
| ... | ... | @@ -7,13 +7,14 @@ |
| 7 | 7 | |
| 8 | 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 | 18 | </div> |
| 18 | 19 | |
| 19 | 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 | 80 | </h3> |
| 81 | 81 | <% end %> |
| 82 | 82 | |
| 83 | - <% if @page.accept_comments? && @comments.count > 1 %> | |
| 83 | + <% if @page.accept_comments? && @comments_count > 1 %> | |
| 84 | 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 | 103 | <% end %> |
| 86 | 104 | |
| 87 | 105 | <ul class="article-comments-list"> | ... | ... |
| ... | ... | @@ -0,0 +1 @@ |
| 1 | +<%= display_block(@block) %> | ... | ... |
| ... | ... | @@ -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> | ... | ... |
| ... | ... | @@ -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 | 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 | 20 | <%= optional_field(@person, 'nationality', f.text_field(:nationality, :rel => _('Nationality'))) %> |
| 21 | 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 | 24 | <%= optional_field(@person, 'zip_code', labelled_form_field(_('ZIP code'), text_field(:profile_data, :zip_code, :rel => _('ZIP code')))) %> |
| 25 | 25 | <%= optional_field(@person, 'address', labelled_form_field(_('Address (street and number)'), text_field(:profile_data, :address, :rel => _('Address')))) %> |
| 26 | 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 | 36 | </div> |
| 37 | 37 | <% end %> |
| 38 | 38 | |
| 39 | +<%= javascript_include_tag('city_state_validation') %> | |
| 39 | 40 | <script type='text/javascript'> |
| 40 | 41 | function toggle_text_field(id, span_id) { |
| 41 | 42 | if ($(id).value == "Others") { | ... | ... |
app/views/shared/_organization_custom_fields.rhtml
| ... | ... | @@ -13,8 +13,8 @@ |
| 13 | 13 | <%= optional_field(profile, 'address_reference', labelled_form_field(_('Address reference'), text_field(object_name, :address_reference))) %> |
| 14 | 14 | <%= optional_field(profile, 'district', labelled_form_field(_('District'), text_field(object_name, :district))) %> |
| 15 | 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 | 18 | <%= optional_field(profile, 'country', select_country(_('Country'), object_name, 'country', {:class => 'type-select'})) %> |
| 19 | 19 | <%= optional_field(profile, 'tag_list', f.text_field(:tag_list)) %> |
| 20 | 20 | |
| ... | ... | @@ -29,3 +29,4 @@ |
| 29 | 29 | <%= optional_field(profile, 'acronym', f.text_field(:acronym)) %> |
| 30 | 30 | <%= optional_field(profile, 'foundation_year', f.text_field(:foundation_year)) %> |
| 31 | 31 | <% end %> |
| 32 | +<%= javascript_include_tag('city_state_validation') %> | ... | ... |
config/routes.rb
| ... | ... | @@ -31,6 +31,9 @@ ActionController::Routing::Routes.draw do |map| |
| 31 | 31 | map.connect 'thumbnails/*stuff', :controller => 'not_found', :action => 'nothing' |
| 32 | 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 | 37 | # online documentation |
| 35 | 38 | map.doc 'doc', :controller => 'doc', :action => 'index' |
| 36 | 39 | map.doc_section 'doc/:section', :controller => 'doc', :action => 'section' | ... | ... |
features/categories_block.feature
| ... | ... | @@ -26,14 +26,9 @@ Feature: categories_block |
| 26 | 26 | And I am logged in as admin |
| 27 | 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 | 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 | 32 | And I check "Product" |
| 38 | 33 | When I press "Save" |
| 39 | 34 | Then I should see "Food" |
| ... | ... | @@ -44,8 +39,7 @@ Feature: categories_block |
| 44 | 39 | |
| 45 | 40 | @selenium |
| 46 | 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 | 43 | And I check "Product" |
| 50 | 44 | And I press "Save" |
| 51 | 45 | Then I should see "Food" |
| ... | ... | @@ -62,8 +56,7 @@ Feature: categories_block |
| 62 | 56 | |
| 63 | 57 | @selenium |
| 64 | 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 | 60 | And I check "Product" |
| 68 | 61 | And I press "Save" |
| 69 | 62 | Then I should see "Book" |
| ... | ... | @@ -73,16 +66,14 @@ Feature: categories_block |
| 73 | 66 | |
| 74 | 67 | @selenium |
| 75 | 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 | 70 | And I check "Generic category" |
| 79 | 71 | When I press "Save" |
| 80 | 72 | Then I should see "Wood" |
| 81 | 73 | |
| 82 | 74 | @selenium |
| 83 | 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 | 77 | And I check "Region" |
| 87 | 78 | When I press "Save" |
| 88 | 79 | Then I should see "Bahia" | ... | ... |
features/comment.feature
| ... | ... | @@ -97,3 +97,41 @@ Feature: comment |
| 97 | 97 | Given I am on /booking/article-to-comment |
| 98 | 98 | And I follow "Post a comment" |
| 99 | 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 | 29 | And I press "Log in" |
| 30 | 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 | 42 | Scenario: be redirected if user goes to signup page and is logged |
| 33 | 43 | Given the following users |
| 34 | 44 | | login | name | |
| 35 | - | joaosilva | Joao Silva | | |
| 45 | + | joaosilva | joao silva | | |
| 36 | 46 | Given I am logged in as "joaosilva" |
| 37 | 47 | And I go to signup page |
| 38 | 48 | Then I should be on joaosilva's control panel | ... | ... |
lib/noosfero/i18n.rb
| ... | ... | @@ -6,9 +6,15 @@ class Object |
| 6 | 6 | alias :ngettext :n_ |
| 7 | 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 | 16 | # translations in place? |
| 10 | 17 | locale_dir = Rails.root.join('locale') |
| 11 | -repos = [] | |
| 12 | 18 | if File.exists?(locale_dir) |
| 13 | 19 | repos << FastGettext::TranslationRepository.build('noosfero', :type => 'mo', :path => locale_dir) |
| 14 | 20 | repos << FastGettext::TranslationRepository.build('iso_3166', :type => 'mo', :path => locale_dir) | ... | ... |
lib/noosfero/plugin.rb
| ... | ... | @@ -16,14 +16,7 @@ class Noosfero::Plugin |
| 16 | 16 | end |
| 17 | 17 | |
| 18 | 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 | 20 | load_plugin dir |
| 28 | 21 | end |
| 29 | 22 | end |
| ... | ... | @@ -76,12 +69,19 @@ class Noosfero::Plugin |
| 76 | 69 | klass(plugin_name) |
| 77 | 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 | 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 | 85 | end |
| 86 | 86 | |
| 87 | 87 | def public_name | ... | ... |
plugins/community_track/lib/community_track_plugin/track_card_list_block.rb
plugins/pg_search/lib/ext/active_record.rb
| ... | ... | @@ -2,11 +2,9 @@ require_dependency 'active_record' |
| 2 | 2 | |
| 3 | 3 | class ActiveRecord::Base |
| 4 | 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 | 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 | 8 | else |
| 11 | 9 | raise "No searchable fields defined for #{self.name}" |
| 12 | 10 | end | ... | ... |
plugins/pg_search/test/unit/pg_search_plugin_test.rb
| ... | ... | @@ -21,6 +21,11 @@ class PgSearchPluginTest < ActiveSupport::TestCase |
| 21 | 21 | assert_includes search(Profile, 'admin deb'), profile2 |
| 22 | 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 | 29 | # TODO This feature is available only on Postgresql 9.0 |
| 25 | 30 | # http://www.postgresql.org/docs/9.0/static/unaccent.html |
| 26 | 31 | # should 'ignore accents' do | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 @@ |
| 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 | 94 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -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 | +} | ... | ... |
| ... | ... | @@ -0,0 +1 @@ |
| 1 | +require File.dirname(__FILE__) + '/../../../test/test_helper' | ... | ... |
| ... | ... | @@ -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 | 149 | \ No newline at end of file | ... | ... |
plugins/relevant_content/test/unit/relevant_content_block_test.rb
0 → 100644
| ... | ... | @@ -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 @@ |
| 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 @@ |
| 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 | 9 | \ No newline at end of file | ... | ... |
plugins/relevant_content/views/environment_design/relevant_content_plugin
0 → 120000
plugins/relevant_content/views/profile_design/relevant_content_plugin
0 → 120000
| ... | ... | @@ -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. | ... | ... |
| ... | ... | @@ -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 @@ |
| 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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 | 1 | /******************SMALL ICONS********************/ |
| 2 | +.icon-embed { background-image: url(Tango/16x16/apps/utilities-terminal.png) } | |
| 2 | 3 | .icon-edit { background-image: url(Tango/16x16/apps/text-editor.png) } |
| 3 | 4 | .icon-undo { background-image: url(Tango/16x16/actions/edit-undo.png) } |
| 4 | 5 | .icon-home { background-image: url(Tango/16x16/actions/go-home.png) } | ... | ... |
public/designs/themes/base/style.css
1.11 KB
public/javascripts/application.js
| ... | ... | @@ -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 | +} | ... | ... |
| ... | ... | @@ -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 | 22 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -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 | 40 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -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 | 122 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -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 | 1859 | text-decoration: none; |
| 1860 | 1860 | } |
| 1861 | 1861 | /* ==> blocks/link-list-block.css <<= */ |
| 1862 | - | |
| 1863 | 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 | 1927 | #content .link-list-block { |
| 1878 | 1928 | padding: 10px 0px 10px 10px; |
| ... | ... | @@ -5989,8 +6039,14 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { |
| 5989 | 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 | 6047 | #email-check, |
| 5993 | 6048 | #fake-check, |
| 6049 | +#password-rate, | |
| 5994 | 6050 | #password-check { |
| 5995 | 6051 | margin: -2px 16px -5px 13px; |
| 5996 | 6052 | text-align: right; |
| ... | ... | @@ -5999,10 +6055,20 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { |
| 5999 | 6055 | |
| 6000 | 6056 | #email-check p, |
| 6001 | 6057 | #fake-check p, |
| 6058 | +#password-rate p, | |
| 6002 | 6059 | #password-check p { |
| 6003 | 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 | 6072 | .available { |
| 6007 | 6073 | color: #88BD00; |
| 6008 | 6074 | } |
| ... | ... | @@ -6016,6 +6082,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { |
| 6016 | 6082 | } |
| 6017 | 6083 | |
| 6018 | 6084 | #email-check p, |
| 6085 | +#password-rate p, | |
| 6019 | 6086 | #password-check p, |
| 6020 | 6087 | #url-check p { |
| 6021 | 6088 | margin: 0; |
| ... | ... | @@ -6607,3 +6674,19 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { |
| 6607 | 6674 | .diff li.diff-block-info { |
| 6608 | 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 < ActionController::TestCase |
| 8 | 8 | # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead |
| 9 | 9 | # Then, you can remove it from this and the units test. |
| 10 | 10 | include AuthenticatedTestHelper |
| 11 | - | |
| 12 | 11 | all_fixtures |
| 13 | 12 | |
| 14 | 13 | def teardown |
| ... | ... | @@ -17,8 +16,8 @@ class AccountControllerTest < ActionController::TestCase |
| 17 | 16 | |
| 18 | 17 | def setup |
| 19 | 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 | 21 | disable_signup_bot_check |
| 23 | 22 | end |
| 24 | 23 | |
| ... | ... | @@ -656,21 +655,28 @@ class AccountControllerTest < ActionController::TestCase |
| 656 | 655 | assert_redirected_to :controller => 'home', :action => 'index' |
| 657 | 656 | end |
| 658 | 657 | |
| 659 | - should 'check_url is available on environment' do | |
| 658 | + should 'check_valid_name is available on environment' do | |
| 660 | 659 | env = fast_create(Environment, :name => 'Environment test') |
| 661 | 660 | @controller.expects(:environment).returns(env).at_least_once |
| 662 | 661 | profile = create_user('mylogin').person |
| 663 | - get :check_url, :identifier => 'mylogin' | |
| 662 | + get :check_valid_name, :identifier => 'mylogin' | |
| 664 | 663 | assert_equal 'validated', assigns(:status_class) |
| 665 | 664 | end |
| 666 | 665 | |
| 667 | 666 | should 'check if url is not available on environment' do |
| 668 | 667 | @controller.expects(:environment).returns(Environment.default).at_least_once |
| 669 | 668 | profile = create_user('mylogin').person |
| 670 | - get :check_url, :identifier => 'mylogin' | |
| 669 | + get :check_valid_name, :identifier => 'mylogin' | |
| 671 | 670 | assert_equal 'invalid', assigns(:status_class) |
| 672 | 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 | 680 | should 'check if e-mail is available on environment' do |
| 675 | 681 | env = fast_create(Environment, :name => 'Environment test') |
| 676 | 682 | @controller.expects(:environment).returns(env).at_least_once |
| ... | ... | @@ -699,6 +705,7 @@ class AccountControllerTest < ActionController::TestCase |
| 699 | 705 | {:test => 5} |
| 700 | 706 | end |
| 701 | 707 | end |
| 708 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | |
| 702 | 709 | |
| 703 | 710 | e = User.find_by_login('ze').environment |
| 704 | 711 | e.enable_plugin(Plugin1.name) |
| ... | ... | @@ -789,6 +796,7 @@ class AccountControllerTest < ActionController::TestCase |
| 789 | 796 | lambda {"<strong>Plugin2 text</strong>"} |
| 790 | 797 | end |
| 791 | 798 | end |
| 799 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | |
| 792 | 800 | |
| 793 | 801 | Environment.default.enable_plugin(Plugin1.name) |
| 794 | 802 | Environment.default.enable_plugin(Plugin2.name) |
| ... | ... | @@ -805,6 +813,7 @@ class AccountControllerTest < ActionController::TestCase |
| 805 | 813 | User.new(:login => 'testuser') |
| 806 | 814 | end |
| 807 | 815 | end |
| 816 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name]) | |
| 808 | 817 | Environment.default.enable_plugin(Plugin1.name) |
| 809 | 818 | |
| 810 | 819 | post :login, :user => {:login => "testuser"} |
| ... | ... | @@ -819,6 +828,7 @@ class AccountControllerTest < ActionController::TestCase |
| 819 | 828 | nil |
| 820 | 829 | end |
| 821 | 830 | end |
| 831 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name]) | |
| 822 | 832 | Environment.default.enable_plugin(Plugin1.name) |
| 823 | 833 | post :login, :user => {:login => 'johndoe', :password => 'test'} |
| 824 | 834 | assert session[:user] |
| ... | ... | @@ -832,6 +842,7 @@ class AccountControllerTest < ActionController::TestCase |
| 832 | 842 | false |
| 833 | 843 | end |
| 834 | 844 | end |
| 845 | + Noosfero::Plugin.stubs(:all).returns([TestRegistrationPlugin.name]) | |
| 835 | 846 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestRegistrationPlugin.new]) |
| 836 | 847 | |
| 837 | 848 | post :signup, :user => { :login => 'testuser', :password => '123456', :password_confirmation => '123456', :email => 'testuser@example.com' } |
| ... | ... | @@ -850,6 +861,7 @@ class AccountControllerTest < ActionController::TestCase |
| 850 | 861 | true |
| 851 | 862 | end |
| 852 | 863 | end |
| 864 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | |
| 853 | 865 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new]) |
| 854 | 866 | |
| 855 | 867 | get :login |
| ... | ... | @@ -863,6 +875,7 @@ class AccountControllerTest < ActionController::TestCase |
| 863 | 875 | false |
| 864 | 876 | end |
| 865 | 877 | end |
| 878 | + Noosfero::Plugin.stubs(:all).returns([TestRegistrationPlugin.name]) | |
| 866 | 879 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestRegistrationPlugin.new]) |
| 867 | 880 | |
| 868 | 881 | #Redirect on get action |
| ... | ... | @@ -886,6 +899,7 @@ class AccountControllerTest < ActionController::TestCase |
| 886 | 899 | true |
| 887 | 900 | end |
| 888 | 901 | end |
| 902 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.new, Plugin2.new]) | |
| 889 | 903 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new]) |
| 890 | 904 | |
| 891 | 905 | get :login |
| ... | ... | @@ -904,6 +918,7 @@ class AccountControllerTest < ActionController::TestCase |
| 904 | 918 | lambda {"<strong>Plugin2 text</strong>"} |
| 905 | 919 | end |
| 906 | 920 | end |
| 921 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | |
| 907 | 922 | |
| 908 | 923 | Environment.default.enable_plugin(Plugin1.name) |
| 909 | 924 | Environment.default.enable_plugin(Plugin2.name) |
| ... | ... | @@ -927,6 +942,30 @@ class AccountControllerTest < ActionController::TestCase |
| 927 | 942 | assert @response.body.blank? |
| 928 | 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 | 969 | protected |
| 931 | 970 | def new_user(options = {}, extra_options ={}) |
| 932 | 971 | data = {:profile_data => person_data} |
| ... | ... | @@ -955,4 +994,18 @@ class AccountControllerTest < ActionController::TestCase |
| 955 | 994 | environment.min_signup_delay = 0 |
| 956 | 995 | environment.save! |
| 957 | 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 | 1011 | end | ... | ... |
test/functional/application_controller_test.rb
| ... | ... | @@ -374,6 +374,8 @@ class ApplicationControllerTest < ActionController::TestCase |
| 374 | 374 | end |
| 375 | 375 | plugin2_path = '/plugin2/style.css' |
| 376 | 376 | |
| 377 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | |
| 378 | + | |
| 377 | 379 | environment = Environment.default |
| 378 | 380 | environment.enable_plugin(Plugin1.name) |
| 379 | 381 | environment.enable_plugin(Plugin2.name) |
| ... | ... | @@ -405,6 +407,8 @@ class ApplicationControllerTest < ActionController::TestCase |
| 405 | 407 | plugin2_path2 = '/plugin2/'+js2 |
| 406 | 408 | plugin2_path3 = '/plugin2/'+js3 |
| 407 | 409 | |
| 410 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | |
| 411 | + | |
| 408 | 412 | environment = Environment.default |
| 409 | 413 | environment.enable_plugin(Plugin1.name) |
| 410 | 414 | environment.enable_plugin(Plugin2.name) |
| ... | ... | @@ -428,6 +432,8 @@ class ApplicationControllerTest < ActionController::TestCase |
| 428 | 432 | end |
| 429 | 433 | end |
| 430 | 434 | |
| 435 | + Noosfero::Plugin.stubs(:all).returns([TestBodyBeginning1Plugin.name, TestBodyBeginning2Plugin.name]) | |
| 436 | + | |
| 431 | 437 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestBodyBeginning1Plugin.new, TestBodyBeginning2Plugin.new]) |
| 432 | 438 | |
| 433 | 439 | get :index |
| ... | ... | @@ -449,6 +455,8 @@ class ApplicationControllerTest < ActionController::TestCase |
| 449 | 455 | end |
| 450 | 456 | end |
| 451 | 457 | |
| 458 | + Noosfero::Plugin.stubs(:all).returns([TestHeadEnding1Plugin.name, TestHeadEnding2Plugin.name]) | |
| 459 | + | |
| 452 | 460 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestHeadEnding1Plugin.new, TestHeadEnding2Plugin.new]) |
| 453 | 461 | |
| 454 | 462 | get :index |
| ... | ... | @@ -513,6 +521,7 @@ class ApplicationControllerTest < ActionController::TestCase |
| 513 | 521 | :block => lambda {} } |
| 514 | 522 | end |
| 515 | 523 | end |
| 524 | + Noosfero::Plugin.stubs(:all).returns([FilterPlugin.name]) | |
| 516 | 525 | |
| 517 | 526 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([FilterPlugin.new]) |
| 518 | 527 | |
| ... | ... | @@ -531,6 +540,7 @@ class ApplicationControllerTest < ActionController::TestCase |
| 531 | 540 | :block => lambda {'plugin block called'} } |
| 532 | 541 | end |
| 533 | 542 | end |
| 543 | + Noosfero::Plugin.stubs(:all).returns([OtherFilterPlugin.name]) | |
| 534 | 544 | |
| 535 | 545 | environment1 = fast_create(Environment, :name => 'test environment') |
| 536 | 546 | environment1.enable_plugin(OtherFilterPlugin.name) | ... | ... |
test/functional/catalog_controller_test.rb
| ... | ... | @@ -91,6 +91,7 @@ class CatalogControllerTest < ActionController::TestCase |
| 91 | 91 | lambda {"<span id='plugin2'>This is Plugin2 speaking!</span>"} |
| 92 | 92 | end |
| 93 | 93 | end |
| 94 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | |
| 94 | 95 | |
| 95 | 96 | product = fast_create(Product, :profile_id => @enterprise.id) |
| 96 | 97 | environment = Environment.default | ... | ... |
test/functional/content_viewer_controller_test.rb
| ... | ... | @@ -1197,6 +1197,7 @@ class ContentViewerControllerTest < ActionController::TestCase |
| 1197 | 1197 | class Plugin2 < Noosfero::Plugin |
| 1198 | 1198 | def content_remove_edit(content); false; end |
| 1199 | 1199 | end |
| 1200 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | |
| 1200 | 1201 | |
| 1201 | 1202 | environment.enable_plugin(Plugin1.name) |
| 1202 | 1203 | environment.enable_plugin(Plugin2.name) |
| ... | ... | @@ -1213,6 +1214,7 @@ class ContentViewerControllerTest < ActionController::TestCase |
| 1213 | 1214 | class Plugin2 < Noosfero::Plugin |
| 1214 | 1215 | def content_expire_edit(content); nil; end |
| 1215 | 1216 | end |
| 1217 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | |
| 1216 | 1218 | |
| 1217 | 1219 | environment.enable_plugin(Plugin1.name) |
| 1218 | 1220 | environment.enable_plugin(Plugin2.name) |
| ... | ... | @@ -1258,6 +1260,7 @@ class ContentViewerControllerTest < ActionController::TestCase |
| 1258 | 1260 | } |
| 1259 | 1261 | end |
| 1260 | 1262 | end |
| 1263 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | |
| 1261 | 1264 | |
| 1262 | 1265 | Environment.default.enable_plugin(Plugin1.name) |
| 1263 | 1266 | Environment.default.enable_plugin(Plugin2.name) |
| ... | ... | @@ -1282,6 +1285,7 @@ class ContentViewerControllerTest < ActionController::TestCase |
| 1282 | 1285 | scope.where(:referrer => 'kernel.org') |
| 1283 | 1286 | end |
| 1284 | 1287 | end |
| 1288 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | |
| 1285 | 1289 | |
| 1286 | 1290 | Environment.default.enable_plugin(Plugin1) |
| 1287 | 1291 | Environment.default.enable_plugin(Plugin2) |
| ... | ... | @@ -1339,6 +1343,7 @@ class ContentViewerControllerTest < ActionController::TestCase |
| 1339 | 1343 | } |
| 1340 | 1344 | end |
| 1341 | 1345 | end |
| 1346 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | |
| 1342 | 1347 | |
| 1343 | 1348 | Environment.default.enable_plugin(Plugin1.name) |
| 1344 | 1349 | Environment.default.enable_plugin(Plugin2.name) | ... | ... |
| ... | ... | @@ -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 < ActionController::TestCase |
| 193 | 193 | {'plugin2' => 'Plugin 2'} |
| 194 | 194 | end |
| 195 | 195 | end |
| 196 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | |
| 196 | 197 | |
| 197 | 198 | environment = Environment.default |
| 198 | 199 | environment.enable_plugin(Plugin1.name) | ... | ... |
test/functional/environment_design_controller_test.rb
| ... | ... | @@ -370,4 +370,47 @@ class EnvironmentDesignControllerTest < ActionController::TestCase |
| 370 | 370 | assert @controller.instance_variable_get('@side_block_types').include?(CustomBlock8) |
| 371 | 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 | 416 | end | ... | ... |
test/functional/friends_controller_test.rb
test/functional/home_controller_test.rb
| ... | ... | @@ -107,6 +107,7 @@ class HomeControllerTest < ActionController::TestCase |
| 107 | 107 | lambda {"<a href='plugin2'>Plugin2 link</a>"} |
| 108 | 108 | end |
| 109 | 109 | end |
| 110 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | |
| 110 | 111 | |
| 111 | 112 | Environment.default.enable_plugin(Plugin1) |
| 112 | 113 | Environment.default.enable_plugin(Plugin2) |
| ... | ... | @@ -129,6 +130,7 @@ class HomeControllerTest < ActionController::TestCase |
| 129 | 130 | true |
| 130 | 131 | end |
| 131 | 132 | end |
| 133 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | |
| 132 | 134 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new]) |
| 133 | 135 | |
| 134 | 136 | get :index | ... | ... |
test/functional/memberships_controller_test.rb
| ... | ... | @@ -234,6 +234,7 @@ class MembershipsControllerTest < ActionController::TestCase |
| 234 | 234 | {'plugin2' => 'Plugin 2'} |
| 235 | 235 | end |
| 236 | 236 | end |
| 237 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | |
| 237 | 238 | |
| 238 | 239 | environment = Environment.default |
| 239 | 240 | environment.enable_plugin(Plugin1.name) | ... | ... |
test/functional/plugins_controller_test.rb
test/functional/profile_controller_test.rb
| ... | ... | @@ -1255,6 +1255,7 @@ class ProfileControllerTest < ActionController::TestCase |
| 1255 | 1255 | {:title => 'Plugin2 tab', :id => 'plugin2_tab', :content => lambda { 'Content from plugin2.' }} |
| 1256 | 1256 | end |
| 1257 | 1257 | end |
| 1258 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s]) | |
| 1258 | 1259 | |
| 1259 | 1260 | e = profile.environment |
| 1260 | 1261 | e.enable_plugin(Plugin1.name) | ... | ... |
test/functional/profile_design_controller_test.rb
| ... | ... | @@ -173,7 +173,8 @@ class ProfileDesignControllerTest < ActionController::TestCase |
| 173 | 173 | should 'have options to display blocks' do |
| 174 | 174 | get :edit, :profile => 'designtestuser', :id => @b1.id |
| 175 | 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 | 178 | end |
| 178 | 179 | end |
| 179 | 180 | |
| ... | ... | @@ -302,24 +303,42 @@ class ProfileDesignControllerTest < ActionController::TestCase |
| 302 | 303 | |
| 303 | 304 | should 'not edit main block with never option' do |
| 304 | 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 | 308 | end |
| 307 | 309 | |
| 308 | 310 | should 'not edit main block with home_page_only option' do |
| 309 | 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 | 314 | end |
| 312 | 315 | |
| 313 | 316 | should 'edit main block with always option' do |
| 314 | 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 | 320 | end |
| 317 | 321 | |
| 318 | 322 | should 'edit main block with except_home_page option' do |
| 319 | 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 | 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 | 344 | # END - tests for BoxOrganizerController features |
| ... | ... | @@ -739,7 +758,7 @@ class ProfileDesignControllerTest < ActionController::TestCase |
| 739 | 758 | should 'clone a block' do |
| 740 | 759 | block = ProfileImageBlock.create!(:box => profile.boxes.first) |
| 741 | 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 | 762 | assert_response :redirect |
| 744 | 763 | end |
| 745 | 764 | end | ... | ... |
test/functional/profile_editor_controller_test.rb
| ... | ... | @@ -868,6 +868,7 @@ class ProfileEditorControllerTest < ActionController::TestCase |
| 868 | 868 | {:title => "Plugin2 button", :icon => 'plugin2_icon', :url => 'plugin2_url'} |
| 869 | 869 | end |
| 870 | 870 | end |
| 871 | + Noosfero::Plugin.stubs(:all).returns([TestControlPanelButtons1.to_s, TestControlPanelButtons2.to_s]) | |
| 871 | 872 | |
| 872 | 873 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestControlPanelButtons1.new, TestControlPanelButtons2.new]) |
| 873 | 874 | |
| ... | ... | @@ -883,6 +884,7 @@ class ProfileEditorControllerTest < ActionController::TestCase |
| 883 | 884 | "<input id='field_added_by_plugin' value='value_of_field_added_by_plugin'/>" |
| 884 | 885 | end |
| 885 | 886 | end |
| 887 | + Noosfero::Plugin.stubs(:all).returns([TestProfileEditPlugin.to_s]) | |
| 886 | 888 | |
| 887 | 889 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestProfileEditPlugin.new]) |
| 888 | 890 | |
| ... | ... | @@ -911,6 +913,7 @@ class ProfileEditorControllerTest < ActionController::TestCase |
| 911 | 913 | lambda {"<strong>Plugin2 text</strong>"} |
| 912 | 914 | end |
| 913 | 915 | end |
| 916 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s]) | |
| 914 | 917 | |
| 915 | 918 | Environment.default.enable_plugin(Plugin1) |
| 916 | 919 | Environment.default.enable_plugin(Plugin2) |
| ... | ... | @@ -932,6 +935,7 @@ class ProfileEditorControllerTest < ActionController::TestCase |
| 932 | 935 | lambda {"<strong>Plugin2 text</strong>"} |
| 933 | 936 | end |
| 934 | 937 | end |
| 938 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s]) | |
| 935 | 939 | |
| 936 | 940 | Environment.default.enable_plugin(Plugin1) |
| 937 | 941 | Environment.default.enable_plugin(Plugin2) | ... | ... |
test/functional/search_controller_test.rb
| ... | ... | @@ -74,14 +74,14 @@ class SearchControllerTest < ActionController::TestCase |
| 74 | 74 | assert_includes assigns(:searches)[:articles][:results], art |
| 75 | 75 | end |
| 76 | 76 | |
| 77 | - should 'redirect contents to articles' do | |
| 77 | + should 'redirect contents to articles' do | |
| 78 | 78 | person = fast_create(Person) |
| 79 | 79 | art = create_article_with_optional_category('an article to be found', person) |
| 80 | 80 | |
| 81 | 81 | get 'contents', :query => 'article found' |
| 82 | - # full description to avoid deprecation warning | |
| 82 | + # full description to avoid deprecation warning | |
| 83 | 83 | assert_redirected_to :controller => :search, :action => :articles, :query => 'article found' |
| 84 | - end | |
| 84 | + end | |
| 85 | 85 | |
| 86 | 86 | # 'assets' outside any category |
| 87 | 87 | should 'list articles in general' do |
| ... | ... | @@ -163,6 +163,7 @@ class SearchControllerTest < ActionController::TestCase |
| 163 | 163 | lambda {"<span id='plugin2'>This is Plugin2 speaking!</span>"} |
| 164 | 164 | end |
| 165 | 165 | end |
| 166 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s]) | |
| 166 | 167 | |
| 167 | 168 | enterprise = fast_create(Enterprise) |
| 168 | 169 | prod_cat = fast_create(ProductCategory) |
| ... | ... | @@ -189,6 +190,7 @@ class SearchControllerTest < ActionController::TestCase |
| 189 | 190 | return { :name => _('Property2'), :content => lambda { link_to(product.name, '/plugin2') } } |
| 190 | 191 | end |
| 191 | 192 | end |
| 193 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s]) | |
| 192 | 194 | enterprise = fast_create(Enterprise) |
| 193 | 195 | prod_cat = fast_create(ProductCategory) |
| 194 | 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 < ActionController::TestCase |
| 257 | 259 | |
| 258 | 260 | should 'render specific action when only one asset is enabled' do |
| 259 | 261 | environment = Environment.default |
| 260 | - # article is not disabled | |
| 262 | + # article is not disabled | |
| 261 | 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 | 266 | environment.save! |
| 265 | 267 | @controller.stubs(:environment).returns(environment) |
| 266 | 268 | |
| ... | ... | @@ -272,25 +274,25 @@ class SearchControllerTest < ActionController::TestCase |
| 272 | 274 | assert !assigns(:searches).has_key?(:communities) |
| 273 | 275 | assert !assigns(:searches).has_key?(:products) |
| 274 | 276 | assert !assigns(:searches).has_key?(:events) |
| 275 | - end | |
| 277 | + end | |
| 276 | 278 | |
| 277 | 279 | should 'search all enabled assets in general search' do |
| 278 | 280 | ent1 = create_profile_with_optional_category(Enterprise, 'test enterprise') |
| 279 | 281 | prod_cat = ProductCategory.create!(:name => 'pctest', :environment => Environment.default) |
| 280 | 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 | 288 | get :index, :query => 'test' |
| 287 | 289 | |
| 288 | 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 | 297 | should 'display category image while in directory' do |
| 296 | 298 | parent = Category.create!(:name => 'category1', :environment => Environment.default) |
| ... | ... | @@ -316,8 +318,8 @@ class SearchControllerTest < ActionController::TestCase |
| 316 | 318 | person = create_user('someone').person |
| 317 | 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 | 324 | get :events, :day => ten_days_ago.day, :month => ten_days_ago.month, :year => ten_days_ago.year |
| 323 | 325 | assert_equal [ev1], assigns(:events) |
| ... | ... | @@ -327,7 +329,7 @@ class SearchControllerTest < ActionController::TestCase |
| 327 | 329 | person = create_user('someone').person |
| 328 | 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 | 333 | ev2 = create_event(person, :name => 'event 2', :start_date => ten_days_ago) |
| 332 | 334 | |
| 333 | 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 < ActionController::TestCase |
| 337 | 339 | |
| 338 | 340 | should 'return events of today when no date specified' do |
| 339 | 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 | 345 | get :events |
| 344 | 346 | |
| ... | ... | @@ -349,9 +351,9 @@ class SearchControllerTest < ActionController::TestCase |
| 349 | 351 | person = create_user('someone').person |
| 350 | 352 | |
| 351 | 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 | 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 | 358 | get :events |
| 357 | 359 | |
| ... | ... | @@ -373,7 +375,7 @@ class SearchControllerTest < ActionController::TestCase |
| 373 | 375 | should 'see the events paginated' do |
| 374 | 376 | person = create_user('testuser').person |
| 375 | 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 | 379 | end |
| 378 | 380 | get :events |
| 379 | 381 | assert_equal 20, assigns(:events).count |
| ... | ... | @@ -432,8 +434,8 @@ class SearchControllerTest < ActionController::TestCase |
| 432 | 434 | end |
| 433 | 435 | |
| 434 | 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 | 439 | ArticleCategorization.add_category_to_article(@category, a) |
| 438 | 440 | end |
| 439 | 441 | |
| ... | ... | @@ -579,55 +581,55 @@ class SearchControllerTest < ActionController::TestCase |
| 579 | 581 | assert_not_includes assigns(:searches)[:communities][:results], p1 |
| 580 | 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 | 586 | assert_redirected_to :controller => :search, :action => :articles |
| 585 | - get :assets, :asset => 'people' | |
| 587 | + get :assets, :asset => 'people' | |
| 586 | 588 | assert_redirected_to :controller => :search, :action => :people |
| 587 | - get :assets, :asset => 'communities' | |
| 589 | + get :assets, :asset => 'communities' | |
| 588 | 590 | assert_redirected_to :controller => :search, :action => :communities |
| 589 | - get :assets, :asset => 'products' | |
| 591 | + get :assets, :asset => 'products' | |
| 590 | 592 | assert_redirected_to :controller => :search, :action => :products |
| 591 | - get :assets, :asset => 'enterprises' | |
| 593 | + get :assets, :asset => 'enterprises' | |
| 592 | 594 | assert_redirected_to :controller => :search, :action => :enterprises |
| 593 | - get :assets, :asset => 'events' | |
| 595 | + get :assets, :asset => 'events' | |
| 594 | 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 | 601 | a = Article.create!(:name => 'my article', :profile_id => fast_create(Person).id) |
| 600 | 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 | 611 | should 'show tagged content' do |
| 610 | - @controller.stubs(:is_cache_expired?).returns(true) | |
| 612 | + @controller.stubs(:is_cache_expired?).returns(true) | |
| 611 | 613 | a = Article.create!(:name => 'my article', :profile_id => fast_create(Person).id) |
| 612 | 614 | a2 = Article.create!(:name => 'my article 2', :profile_id => fast_create(Person).id) |
| 613 | 615 | a.tag_list = ['one', 'two'] |
| 614 | 616 | a2.tag_list = ['two', 'three'] |
| 615 | - a.save_tags | |
| 617 | + a.save_tags | |
| 616 | 618 | a2.save_tags |
| 617 | 619 | |
| 618 | - get :tag, :tag => 'two' | |
| 620 | + get :tag, :tag => 'two' | |
| 619 | 621 | |
| 620 | 622 | assert_equivalent [a, a2], assigns(:searches)[:tag][:results] |
| 621 | 623 | |
| 622 | - get :tag, :tag => 'one' | |
| 624 | + get :tag, :tag => 'one' | |
| 623 | 625 | |
| 624 | 626 | assert_equivalent [a], assigns(:searches)[:tag][:results] |
| 625 | 627 | end |
| 626 | 628 | |
| 627 | 629 | should 'not show assets from other environments' do |
| 628 | 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 | 633 | art1 = Article.create!(:name => 'my article', :profile_id => p1.id) |
| 632 | 634 | art2 = Article.create!(:name => 'my article', :profile_id => p2.id) |
| 633 | 635 | |
| ... | ... | @@ -638,9 +640,9 @@ class SearchControllerTest < ActionController::TestCase |
| 638 | 640 | |
| 639 | 641 | should 'order articles by more recent' do |
| 640 | 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 | 647 | get :articles, :filter => :more_recent |
| 646 | 648 | ... | ... |
test/integration/routing_test.rb
| ... | ... | @@ -270,5 +270,8 @@ class RoutingTest < ActionController::IntegrationTest |
| 270 | 270 | assert_routing('/work/free-software/versions', :controller => 'content_viewer', :action => 'article_versions', :page => [ 'work', 'free-software'] ) |
| 271 | 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 | 277 | end | ... | ... |
| ... | ... | @@ -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 < ActiveSupport::TestCase |
| 676 | 676 | should 'parse macros' do |
| 677 | 677 | class Plugin1 < Noosfero::Plugin |
| 678 | 678 | end |
| 679 | + Noosfero::Plugin.stubs(:all).returns(['ApplicationHelperTest::Plugin1']) | |
| 679 | 680 | |
| 680 | 681 | class Plugin1::Macro1 < Noosfero::Plugin::Macro |
| 681 | 682 | def parse(params, inner_html, source) | ... | ... |
test/unit/block_test.rb
| ... | ... | @@ -223,6 +223,61 @@ class BlockTest < ActiveSupport::TestCase |
| 223 | 223 | assert !block.visible?(3) |
| 224 | 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 | 281 | should 'accept user as parameter on cache_key without change its value' do |
| 227 | 282 | person = fast_create(Person) |
| 228 | 283 | block = Block.new | ... | ... |
test/unit/boxes_helper_test.rb
| ... | ... | @@ -54,6 +54,7 @@ class BoxesHelperTest < ActiveSupport::TestCase |
| 54 | 54 | expects(:display_block).with(b, '') |
| 55 | 55 | stubs(:request).returns(request) |
| 56 | 56 | stubs(:block_target).returns('') |
| 57 | + stubs(:user).returns(nil) | |
| 57 | 58 | expects(:locale).returns('en') |
| 58 | 59 | with_box_decorator self do |
| 59 | 60 | display_box_content(box, '') |
| ... | ... | @@ -73,6 +74,7 @@ class BoxesHelperTest < ActiveSupport::TestCase |
| 73 | 74 | box.save! |
| 74 | 75 | expects(:display_block).with(b, '').never |
| 75 | 76 | stubs(:request).returns(request) |
| 77 | + stubs(:user).returns(nil) | |
| 76 | 78 | stubs(:block_target).returns('') |
| 77 | 79 | expects(:locale).returns('en') |
| 78 | 80 | display_box_content(box, '') |
| ... | ... | @@ -111,8 +113,9 @@ class BoxesHelperTest < ActiveSupport::TestCase |
| 111 | 113 | request.expects(:path).returns('/') |
| 112 | 114 | request.expects(:params).returns({}) |
| 113 | 115 | stubs(:request).returns(request) |
| 116 | + stubs(:user).returns(nil) | |
| 114 | 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 | 120 | display_box_content(box, '') |
| 118 | 121 | end | ... | ... |
test/unit/comment_test.rb
| ... | ... | @@ -468,8 +468,8 @@ class CommentTest < ActiveSupport::TestCase |
| 468 | 468 | end |
| 469 | 469 | end |
| 470 | 470 | |
| 471 | - | |
| 472 | 471 | should 'delegate spam detection to plugins' do |
| 472 | + Noosfero::Plugin.stubs(:all).returns(['CommentTest::EverythingIsSpam']) | |
| 473 | 473 | Environment.default.enable_plugin(EverythingIsSpam) |
| 474 | 474 | |
| 475 | 475 | c1 = create_comment |
| ... | ... | @@ -495,6 +495,7 @@ class CommentTest < ActiveSupport::TestCase |
| 495 | 495 | end |
| 496 | 496 | |
| 497 | 497 | should 'notify plugins of comments being marked as spam' do |
| 498 | + Noosfero::Plugin.stubs(:all).returns(['CommentTest::SpamNotification']) | |
| 498 | 499 | Environment.default.enable_plugin(SpamNotification) |
| 499 | 500 | |
| 500 | 501 | c = create_comment |
| ... | ... | @@ -506,6 +507,7 @@ class CommentTest < ActiveSupport::TestCase |
| 506 | 507 | end |
| 507 | 508 | |
| 508 | 509 | should 'notify plugins of comments being marked as ham' do |
| 510 | + Noosfero::Plugin.stubs(:all).returns(['CommentTest::SpamNotification']) | |
| 509 | 511 | Environment.default.enable_plugin(SpamNotification) |
| 510 | 512 | |
| 511 | 513 | c = create_comment | ... | ... |
test/unit/forgot_password_helper_test.rb
| ... | ... | @@ -22,6 +22,7 @@ class ForgotPasswordHelperTest < ActionView::TestCase |
| 22 | 22 | {:field => 'f3', :name => 'F3', :model => 'person'}] |
| 23 | 23 | end |
| 24 | 24 | end |
| 25 | + Noosfero::Plugin.stubs(:all).returns(['ForgotPasswordHelperTest::Plugin1', 'ForgotPasswordHelperTest::Plugin2']) | |
| 25 | 26 | |
| 26 | 27 | environment.enable_plugin(Plugin1) |
| 27 | 28 | environment.enable_plugin(Plugin2) |
| ... | ... | @@ -43,6 +44,7 @@ class ForgotPasswordHelperTest < ActionView::TestCase |
| 43 | 44 | {:field => 'f3', :name => 'F3', :model => 'person'}] |
| 44 | 45 | end |
| 45 | 46 | end |
| 47 | + Noosfero::Plugin.stubs(:all).returns(['ForgotPasswordHelperTest::Plugin1', 'ForgotPasswordHelperTest::Plugin2']) | |
| 46 | 48 | |
| 47 | 49 | environment.enable_plugin(Plugin1) |
| 48 | 50 | environment.enable_plugin(Plugin2) |
| ... | ... | @@ -64,6 +66,7 @@ class ForgotPasswordHelperTest < ActionView::TestCase |
| 64 | 66 | {:field => 'f3', :name => 'F3', :model => 'user'}] |
| 65 | 67 | end |
| 66 | 68 | end |
| 69 | + Noosfero::Plugin.stubs(:all).returns(['ForgotPasswordHelperTest::Plugin1', 'ForgotPasswordHelperTest::Plugin2']) | |
| 67 | 70 | |
| 68 | 71 | environment.enable_plugin(Plugin1) |
| 69 | 72 | environment.enable_plugin(Plugin2) |
| ... | ... | @@ -85,6 +88,7 @@ class ForgotPasswordHelperTest < ActionView::TestCase |
| 85 | 88 | {:field => 'f3', :name => 'F3', :model => 'user'}] |
| 86 | 89 | end |
| 87 | 90 | end |
| 91 | + Noosfero::Plugin.stubs(:all).returns(['ForgotPasswordHelperTest::Plugin1', 'ForgotPasswordHelperTest::Plugin2']) | |
| 88 | 92 | |
| 89 | 93 | environment.enable_plugin(Plugin1) |
| 90 | 94 | environment.enable_plugin(Plugin2) | ... | ... |
test/unit/link_list_block_test.rb
| ... | ... | @@ -39,6 +39,32 @@ class LinkListBlockTest < ActiveSupport::TestCase |
| 39 | 39 | assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/test_profile/address'} |
| 40 | 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 | 68 | should 'display options for icons' do |
| 43 | 69 | l = LinkListBlock.new |
| 44 | 70 | l.icons_options.each do |option| | ... | ... |
test/unit/macros_helper_test.rb
| ... | ... | @@ -28,6 +28,7 @@ class MacrosHelperTest < ActiveSupport::TestCase |
| 28 | 28 | end |
| 29 | 29 | |
| 30 | 30 | def setup |
| 31 | + Noosfero::Plugin.stubs(:all).returns(['MacrosHelperTest::Plugin1']) | |
| 31 | 32 | @environment = Environment.default |
| 32 | 33 | @environment.enable_plugin(Plugin1) |
| 33 | 34 | @plugins = Noosfero::Plugin::Manager.new(@environment, self) |
| ... | ... | @@ -129,4 +130,27 @@ class MacrosHelperTest < ActiveSupport::TestCase |
| 129 | 130 | assert_equal 'macro_generator', macro_generator(Plugin1::Macro) |
| 130 | 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 | 156 | end | ... | ... |
test/unit/person_test.rb
| ... | ... | @@ -1255,6 +1255,7 @@ class PersonTest < ActiveSupport::TestCase |
| 1255 | 1255 | false |
| 1256 | 1256 | end |
| 1257 | 1257 | end |
| 1258 | + Noosfero::Plugin.stubs(:all).returns(['PersonTest::Plugin1', 'PersonTest::Plugin2']) | |
| 1258 | 1259 | |
| 1259 | 1260 | e = Environment.default |
| 1260 | 1261 | e.enable_plugin(Plugin1.name) |
| ... | ... | @@ -1424,6 +1425,7 @@ class PersonTest < ActiveSupport::TestCase |
| 1424 | 1425 | Profile.memberships_of(Person.find_by_identifier('person2')) |
| 1425 | 1426 | end |
| 1426 | 1427 | end |
| 1428 | + Noosfero::Plugin.stubs(:all).returns(['PersonTest::Plugin1', 'PersonTest::Plugin2']) | |
| 1427 | 1429 | |
| 1428 | 1430 | Environment.default.enable_plugin(Plugin1) |
| 1429 | 1431 | Environment.default.enable_plugin(Plugin2) | ... | ... |
test/unit/plugin_manager_test.rb
| ... | ... | @@ -26,6 +26,7 @@ class PluginManagerTest < ActiveSupport::TestCase |
| 26 | 26 | class Plugin2 < Noosfero::Plugin; end; |
| 27 | 27 | class Plugin3 < Noosfero::Plugin; end; |
| 28 | 28 | class Plugin4 < Noosfero::Plugin; end; |
| 29 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3', 'PluginManagerTest::Plugin4']) | |
| 29 | 30 | environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s, Plugin4.to_s]) |
| 30 | 31 | Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin3.to_s, Plugin4.to_s]) |
| 31 | 32 | results = plugins.enabled_plugins.map { |instance| instance.class.to_s } |
| ... | ... | @@ -51,6 +52,7 @@ class PluginManagerTest < ActiveSupport::TestCase |
| 51 | 52 | 'Plugin 2 action.' |
| 52 | 53 | end |
| 53 | 54 | end |
| 55 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2']) | |
| 54 | 56 | |
| 55 | 57 | environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s]) |
| 56 | 58 | |
| ... | ... | @@ -83,6 +85,7 @@ class PluginManagerTest < ActiveSupport::TestCase |
| 83 | 85 | 'Plugin 3 action.' |
| 84 | 86 | end |
| 85 | 87 | end |
| 88 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3']) | |
| 86 | 89 | |
| 87 | 90 | environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s, Plugin3.to_s]) |
| 88 | 91 | p1 = Plugin1.new |
| ... | ... | @@ -107,6 +110,7 @@ class PluginManagerTest < ActiveSupport::TestCase |
| 107 | 110 | 'Plugin3' |
| 108 | 111 | end |
| 109 | 112 | end |
| 113 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3']) | |
| 110 | 114 | |
| 111 | 115 | environment.enable_plugin(Plugin1.name) |
| 112 | 116 | environment.enable_plugin(Plugin2.name) |
| ... | ... | @@ -134,6 +138,7 @@ class PluginManagerTest < ActiveSupport::TestCase |
| 134 | 138 | true |
| 135 | 139 | end |
| 136 | 140 | end |
| 141 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3']) | |
| 137 | 142 | |
| 138 | 143 | environment.enable_plugin(Plugin1.name) |
| 139 | 144 | environment.enable_plugin(Plugin2.name) |
| ... | ... | @@ -162,6 +167,7 @@ class PluginManagerTest < ActiveSupport::TestCase |
| 162 | 167 | true |
| 163 | 168 | end |
| 164 | 169 | end |
| 170 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3']) | |
| 165 | 171 | |
| 166 | 172 | environment.enable_plugin(Plugin1.name) |
| 167 | 173 | environment.enable_plugin(Plugin2.name) |
| ... | ... | @@ -178,6 +184,7 @@ class PluginManagerTest < ActiveSupport::TestCase |
| 178 | 184 | [Macro1, Macro2] |
| 179 | 185 | end |
| 180 | 186 | end |
| 187 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1']) | |
| 181 | 188 | |
| 182 | 189 | class Plugin1::Macro1 < Noosfero::Plugin::Macro |
| 183 | 190 | def convert(macro, source) |
| ... | ... | @@ -212,6 +219,7 @@ class PluginManagerTest < ActiveSupport::TestCase |
| 212 | 219 | [v1 * v, v2 * v] |
| 213 | 220 | end |
| 214 | 221 | end |
| 222 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2']) | |
| 215 | 223 | |
| 216 | 224 | environment.enable_plugin(Plugin1) |
| 217 | 225 | environment.enable_plugin(Plugin2) |
| ... | ... | @@ -231,6 +239,7 @@ class PluginManagerTest < ActiveSupport::TestCase |
| 231 | 239 | value * 5 |
| 232 | 240 | end |
| 233 | 241 | end |
| 242 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2']) | |
| 234 | 243 | |
| 235 | 244 | environment.enable_plugin(Plugin1) |
| 236 | 245 | environment.enable_plugin(Plugin2) |
| ... | ... | @@ -252,6 +261,7 @@ class PluginManagerTest < ActiveSupport::TestCase |
| 252 | 261 | [v1 * v, v2 * v, 666] |
| 253 | 262 | end |
| 254 | 263 | end |
| 264 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2']) | |
| 255 | 265 | |
| 256 | 266 | environment.enable_plugin(Plugin1) |
| 257 | 267 | environment.enable_plugin(Plugin2) |
| ... | ... | @@ -273,6 +283,7 @@ class PluginManagerTest < ActiveSupport::TestCase |
| 273 | 283 | numbers.reject {|n| n<=5} |
| 274 | 284 | end |
| 275 | 285 | end |
| 286 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2']) | |
| 276 | 287 | |
| 277 | 288 | environment.enable_plugin(Plugin1) |
| 278 | 289 | environment.enable_plugin(Plugin2) | ... | ... |
test/unit/plugin_test.rb
| ... | ... | @@ -9,15 +9,9 @@ class PluginTest < ActiveSupport::TestCase |
| 9 | 9 | |
| 10 | 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 | 15 | end |
| 22 | 16 | |
| 23 | 17 | should 'returns url to plugin management if plugin has admin_controller' do | ... | ... |
test/unit/profile_test.rb
| ... | ... | @@ -1790,6 +1790,7 @@ class ProfileTest < ActiveSupport::TestCase |
| 1790 | 1790 | Person.members_of(Community.find_by_identifier('community2')) |
| 1791 | 1791 | end |
| 1792 | 1792 | end |
| 1793 | + Noosfero::Plugin.stubs(:all).returns(['ProfileTest::Plugin1', 'ProfileTest::Plugin2']) | |
| 1793 | 1794 | Environment.default.enable_plugin(Plugin1) |
| 1794 | 1795 | Environment.default.enable_plugin(Plugin2) |
| 1795 | 1796 | |
| ... | ... | @@ -1947,6 +1948,7 @@ class ProfileTest < ActiveSupport::TestCase |
| 1947 | 1948 | end |
| 1948 | 1949 | |
| 1949 | 1950 | environment = Environment.default |
| 1951 | + Noosfero::Plugin.stubs(:all).returns(['ProfileTest::Plugin1']) | |
| 1950 | 1952 | environment.enable_plugin(Plugin1) |
| 1951 | 1953 | plugins = Noosfero::Plugin::Manager.new(environment, self) |
| 1952 | 1954 | p = fast_create(Profile) | ... | ... |
test/unit/suggest_article_test.rb
| ... | ... | @@ -7,6 +7,7 @@ class SuggestArticleTest < ActiveSupport::TestCase |
| 7 | 7 | ActionMailer::Base.perform_deliveries = true |
| 8 | 8 | ActionMailer::Base.deliveries = [] |
| 9 | 9 | @profile = create_user('test_user').person |
| 10 | + Noosfero::Plugin.stubs(:all).returns(['SuggestArticleTest::EverythingIsSpam', 'SuggestArticleTest::SpamNotification']) | |
| 10 | 11 | end |
| 11 | 12 | attr_reader :profile |
| 12 | 13 | ... | ... |
test/unit/text_article_test.rb
| ... | ... | @@ -37,4 +37,51 @@ class TextArticleTest < ActiveSupport::TestCase |
| 37 | 37 | assert_equal Blog.icon_name, TextArticle.icon_name(article) |
| 38 | 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 | 87 | end | ... | ... |