Commit 1182476c928ed1bd9d07130ae292298eb8236526
Exists in
master
and in
22 other branches
Merge branch 'rails235' into rails3
* rails235: (168 commits) L10n: support for custom locales enhancements: visualization of suggested usernames Allowing translation for url checking string Removed unnecessary lines on test Removed unit tests from functionals file Fixed html and test syntax Removed needless condition Fixed suggestions of usernames Test files should ends with "_test.rb" Added pagination on events_by_day on profile agenda Fix missing variable in funcional test Fix unit tests Change routes from embed controller Remove unused code Autocomplete fields on page load Blocks can returns a block of code to be evaluated Avoid randomness on tests comment-group-plugin: avoid randomness on tests community-track-plugin: fix tests by creating a profile with default boxes anti-spam-plugin-wrapper: ensure to load concrete wrappers ... Conflicts: app/helpers/application_helper.rb app/models/comment.rb app/models/contact.rb app/models/event.rb app/models/mailing.rb app/models/organization.rb app/models/organization_mailing.rb app/models/pending_task_notifier.rb app/models/person.rb app/models/profile.rb app/models/scrap.rb app/models/task_mailer.rb app/models/user.rb app/views/account/_signup_form.rhtml app/views/blocks/profile_image.rhtml app/views/blocks/profile_info.rhtml app/views/box_organizer/_link_list_block.rhtml app/views/box_organizer/edit.rhtml app/views/features/_manage_community_fields.rhtml app/views/features/_manage_enterprise_fields.rhtml app/views/features/_manage_person_fields.rhtml app/views/features/index.rhtml app/views/layouts/application-ng.rhtml app/views/users/_users_list.rhtml db/schema.rb features/forum.feature lib/feed_handler.rb lib/noosfero/plugin.rb plugins/community_track/test/functional/community_track_plugin_content_viewer_controller_test.rb plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb plugins/spaminator/lib/spaminator_plugin/mailer.rb test/functional/content_viewer_controller_test.rb test/functional/profile_controller_test.rb test/functional/profile_design_controller_test.rb test/functional/search_controller_test.rb test/unit/contact_sender_test.rb test/unit/content_viewer_helper_test.rb test/unit/environment_mailing_test.rb test/unit/mailing_test.rb test/unit/organization_mailing_test.rb test/unit/person_test.rb test/unit/profile_test.rb test/unit/uploaded_file_test.rb vendor/plugins/action_tracker/lib/action_tracker_model.rb
Showing
269 changed files
with
5981 additions
and
843 deletions
Show diff stats
AUTHORS
| @@ -7,6 +7,7 @@ Developers | @@ -7,6 +7,7 @@ Developers | ||
| 7 | ========== | 7 | ========== |
| 8 | 8 | ||
| 9 | Alan Freihof Tygel <alantygel@gmail.com> | 9 | Alan Freihof Tygel <alantygel@gmail.com> |
| 10 | +alcampelo <alcampelo@alcampelo.(none)> | ||
| 10 | Alessandro Palmeira <alessandro.palmeira@gmail.com> | 11 | Alessandro Palmeira <alessandro.palmeira@gmail.com> |
| 11 | Alessandro Palmeira + Caio C. Salgado <alessandro.palmeira@gmail.com> | 12 | Alessandro Palmeira + Caio C. Salgado <alessandro.palmeira@gmail.com> |
| 12 | Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com> | 13 | Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com> |
| @@ -38,6 +39,7 @@ Alessandro Palmeira + João M. M. Silva <alessandro.palmeira@gmail.com> | @@ -38,6 +39,7 @@ Alessandro Palmeira + João M. M. Silva <alessandro.palmeira@gmail.com> | ||
| 38 | Alessandro Palmeira + Paulo Meirelles <alessandro.palmeira@gmail.com> | 39 | Alessandro Palmeira + Paulo Meirelles <alessandro.palmeira@gmail.com> |
| 39 | Alessandro Palmeira + Paulo Meirelles + João M. M. da Silva <alessandro.palmeira@gmail.com> | 40 | Alessandro Palmeira + Paulo Meirelles + João M. M. da Silva <alessandro.palmeira@gmail.com> |
| 40 | Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com> | 41 | Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com> |
| 42 | +Ana Losnak <analosnak@gmail.com> | ||
| 41 | Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br> | 43 | Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br> |
| 42 | Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br> | 44 | Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br> |
| 43 | Antonio Terceiro <terceiro@colivre.coop.br> | 45 | Antonio Terceiro <terceiro@colivre.coop.br> |
| @@ -85,6 +87,7 @@ Daniel Alves + Rafael Manzo <rr.manzo@gmail.com> | @@ -85,6 +87,7 @@ Daniel Alves + Rafael Manzo <rr.manzo@gmail.com> | ||
| 85 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> | 87 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> |
| 86 | Daniel Bucher <daniel.bucher88@gmail.com> | 88 | Daniel Bucher <daniel.bucher88@gmail.com> |
| 87 | Daniel Cunha <daniel@colivre.coop.br> | 89 | Daniel Cunha <daniel@colivre.coop.br> |
| 90 | +David Carlos <ddavidcarlos1392@gmail.com> | ||
| 88 | diegoamc <diegoamc90@gmail.com> | 91 | diegoamc <diegoamc90@gmail.com> |
| 89 | Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com> | 92 | Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com> |
| 90 | Diego Araújo + Alessandro Palmeira + João M. M. da Silva <diegoamc90@gmail.com> | 93 | Diego Araújo + Alessandro Palmeira + João M. M. da Silva <diegoamc90@gmail.com> |
| @@ -114,12 +117,16 @@ Diego Martinez <diegoamc90@gmail.com> | @@ -114,12 +117,16 @@ Diego Martinez <diegoamc90@gmail.com> | ||
| 114 | Diego Martinez <diego@diego-K55A.(none)> | 117 | Diego Martinez <diego@diego-K55A.(none)> |
| 115 | Diego + Renan <renanteruoc@gmail.com> | 118 | Diego + Renan <renanteruoc@gmail.com> |
| 116 | Eduardo Tourinho Edington <eduardo.edington@serpro.gov.br> | 119 | Eduardo Tourinho Edington <eduardo.edington@serpro.gov.br> |
| 120 | +Fabio Teixeira <fabio1079@gmail.com> | ||
| 117 | Fernanda Lopes <nanda.listas+psl@gmail.com> | 121 | Fernanda Lopes <nanda.listas+psl@gmail.com> |
| 118 | Francisco Marcelo A. Lima Júnior <francisco.lima-junior@serpro.gov.br> | 122 | Francisco Marcelo A. Lima Júnior <francisco.lima-junior@serpro.gov.br> |
| 119 | Francisco Marcelo de Araujo Lima Junior <79350259591@serpro-1457614.(none)> | 123 | Francisco Marcelo de Araujo Lima Junior <79350259591@serpro-1457614.(none)> |
| 120 | Francisco Marcelo de Araújo Lima Júnior <francisco.lima-junior@serpro.gov.br> | 124 | Francisco Marcelo de Araújo Lima Júnior <francisco.lima-junior@serpro.gov.br> |
| 121 | Francisco Marcelo de Araújo Lima Júnior <maljunior@gmail.com> | 125 | Francisco Marcelo de Araújo Lima Júnior <maljunior@gmail.com> |
| 126 | +Gabriela Navarro <navarro1703@gmail.com> | ||
| 122 | Grazieno Pellegrino <grazieno@gmail.com> | 127 | Grazieno Pellegrino <grazieno@gmail.com> |
| 128 | +Gust <darksshades@hotmail.com> | ||
| 129 | +Hugo Melo <hugo@riseup.net> | ||
| 123 | Isaac Canan <isaac@intelletto.com.br> | 130 | Isaac Canan <isaac@intelletto.com.br> |
| 124 | Italo Valcy <italo@dcc.ufba.br> | 131 | Italo Valcy <italo@dcc.ufba.br> |
| 125 | Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com> | 132 | Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com> |
| @@ -202,6 +209,7 @@ Renan Teruo + Diego Araujo <renanteruoc@gmail.com> | @@ -202,6 +209,7 @@ Renan Teruo + Diego Araujo <renanteruoc@gmail.com> | ||
| 202 | Renan Teruo + Diego Araújo <renanteruoc@gmail.com> | 209 | Renan Teruo + Diego Araújo <renanteruoc@gmail.com> |
| 203 | Renan Teruo + Paulo Meirelles <renanteruoc@gmail.com> | 210 | Renan Teruo + Paulo Meirelles <renanteruoc@gmail.com> |
| 204 | Renan Teruo + Rafael Manzo <renanteruoc@gmail.com> | 211 | Renan Teruo + Rafael Manzo <renanteruoc@gmail.com> |
| 212 | +Rodrigo Souto + Ana Losnak + Daniel Bucher + Caio Almeida + Leandro Nunes + Daniela Feitosa + Mariel Zasso <noosfero-br@listas.softwarelivre.org> | ||
| 205 | Rodrigo Souto <diguliu@gmail.com> | 213 | Rodrigo Souto <diguliu@gmail.com> |
| 206 | Rodrigo Souto <rodrigo@colivre.coop.br> | 214 | Rodrigo Souto <rodrigo@colivre.coop.br> |
| 207 | Ronny Kursawe <kursawe.ronny@googlemail.com> | 215 | Ronny Kursawe <kursawe.ronny@googlemail.com> |
app/controllers/admin/environment_design_controller.rb
| @@ -3,6 +3,8 @@ class EnvironmentDesignController < BoxOrganizerController | @@ -3,6 +3,8 @@ class EnvironmentDesignController < BoxOrganizerController | ||
| 3 | protect 'edit_environment_design', :environment | 3 | protect 'edit_environment_design', :environment |
| 4 | 4 | ||
| 5 | def available_blocks | 5 | def available_blocks |
| 6 | + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
| 7 | + # the Noosfero core soon, see ActionItem3045 | ||
| 6 | @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ] | 8 | @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ] |
| 7 | @available_blocks += plugins.dispatch(:extra_blocks, :type => Environment) | 9 | @available_blocks += plugins.dispatch(:extra_blocks, :type => Environment) |
| 8 | end | 10 | end |
app/controllers/admin/users_controller.rb
| @@ -45,6 +45,20 @@ class UsersController < AdminController | @@ -45,6 +45,20 @@ class UsersController < AdminController | ||
| 45 | redirect_to :action => :index, :q => params[:q], :filter => params[:filter] | 45 | redirect_to :action => :index, :q => params[:q], :filter => params[:filter] |
| 46 | end | 46 | end |
| 47 | 47 | ||
| 48 | + | ||
| 49 | + def destroy_user | ||
| 50 | + if request.post? | ||
| 51 | + person = environment.people.find_by_id(params[:id]) | ||
| 52 | + if person && person.destroy | ||
| 53 | + session[:notice] = _('The profile was deleted.') | ||
| 54 | + else | ||
| 55 | + session[:notice] = _('Could not remove profile') | ||
| 56 | + end | ||
| 57 | + end | ||
| 58 | + redirect_to :action => :index, :q => params[:q], :filter => params[:filter] | ||
| 59 | + end | ||
| 60 | + | ||
| 61 | + | ||
| 48 | def download | 62 | def download |
| 49 | respond_to do |format| | 63 | respond_to do |format| |
| 50 | format.html | 64 | format.html |
app/controllers/box_organizer_controller.rb
| @@ -80,6 +80,22 @@ class BoxOrganizerController < ApplicationController | @@ -80,6 +80,22 @@ class BoxOrganizerController < ApplicationController | ||
| 80 | render :action => 'edit', :layout => false | 80 | render :action => 'edit', :layout => false |
| 81 | end | 81 | end |
| 82 | 82 | ||
| 83 | + def search_autocomplete | ||
| 84 | + if request.xhr? and params[:query] | ||
| 85 | + search = params[:query] | ||
| 86 | + path_list = if boxes_holder.is_a?(Environment) && boxes_holder.enabled?('use_portal_community') && boxes_holder.portal_community | ||
| 87 | + boxes_holder.portal_community.articles.find(:all, :conditions=>"name ILIKE '%#{search}%' or path ILIKE '%#{search}%'", :limit=>20).map { |content| "/{portal}/"+content.path } | ||
| 88 | + elsif boxes_holder.is_a?(Profile) | ||
| 89 | + boxes_holder.articles.find(:all, :conditions=>"name ILIKE '%#{search}%' or path ILIKE '%#{search}%'", :limit=>20).map { |content| "/{profile}/"+content.path } | ||
| 90 | + else | ||
| 91 | + [] | ||
| 92 | + end | ||
| 93 | + render :json => path_list.to_json | ||
| 94 | + else | ||
| 95 | + redirect_to "/" | ||
| 96 | + end | ||
| 97 | + end | ||
| 98 | + | ||
| 83 | def save | 99 | def save |
| 84 | @block = boxes_holder.blocks.find(params[:id]) | 100 | @block = boxes_holder.blocks.find(params[:id]) |
| 85 | @block.update_attributes(params[:block]) | 101 | @block.update_attributes(params[:block]) |
| @@ -99,6 +115,12 @@ class BoxOrganizerController < ApplicationController | @@ -99,6 +115,12 @@ class BoxOrganizerController < ApplicationController | ||
| 99 | end | 115 | end |
| 100 | end | 116 | end |
| 101 | 117 | ||
| 118 | + def clone_block | ||
| 119 | + block = Block.find(params[:id]) | ||
| 120 | + block.duplicate | ||
| 121 | + redirect_to :action => 'index' | ||
| 122 | + end | ||
| 123 | + | ||
| 102 | protected :boxes_editor? | 124 | protected :boxes_editor? |
| 103 | 125 | ||
| 104 | end | 126 | end |
| @@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
| 1 | +class EmbedController < ApplicationController | ||
| 2 | + layout 'embed' | ||
| 3 | + | ||
| 4 | + def block | ||
| 5 | + @block = Block.find(params[:id]) | ||
| 6 | + if !@block.embedable? || !@block.visible? | ||
| 7 | + render 'unavailable.rhtml', :status => 403 | ||
| 8 | + end | ||
| 9 | + rescue ActiveRecord::RecordNotFound | ||
| 10 | + render 'not_found.rhtml', :status => 404 | ||
| 11 | + end | ||
| 12 | + | ||
| 13 | +end |
app/controllers/my_profile/cms_controller.rb
| @@ -24,10 +24,16 @@ class CmsController < MyProfileController | @@ -24,10 +24,16 @@ class CmsController < MyProfileController | ||
| 24 | (user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile))) | 24 | (user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile))) |
| 25 | end | 25 | end |
| 26 | 26 | ||
| 27 | - protect_if :except => [:suggest_an_article, :set_home_page, :edit, :destroy, :publish, :upload_files] do |c, user, profile| | 27 | + protect_if :except => [:suggest_an_article, :set_home_page, :edit, :destroy, :publish, :upload_files, :new] do |c, user, profile| |
| 28 | user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)) | 28 | user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)) |
| 29 | end | 29 | end |
| 30 | 30 | ||
| 31 | + protect_if :only => :new do |c, user, profile| | ||
| 32 | + article = profile.articles.find_by_id(c.params[:parent_id]) | ||
| 33 | + (!article.nil? && (article.allow_create?(user) || article.parent.allow_create?(user))) || | ||
| 34 | + (user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile))) | ||
| 35 | + end | ||
| 36 | + | ||
| 31 | protect_if :only => [:destroy, :publish] do |c, user, profile| | 37 | protect_if :only => [:destroy, :publish] do |c, user, profile| |
| 32 | profile.articles.find(c.params[:id]).allow_post_content?(user) | 38 | profile.articles.find(c.params[:id]).allow_post_content?(user) |
| 33 | end | 39 | end |
| @@ -220,11 +226,10 @@ class CmsController < MyProfileController | @@ -220,11 +226,10 @@ class CmsController < MyProfileController | ||
| 220 | 226 | ||
| 221 | def update_categories | 227 | def update_categories |
| 222 | @object = params[:id] ? @profile.articles.find(params[:id]) : Article.new | 228 | @object = params[:id] ? @profile.articles.find(params[:id]) : Article.new |
| 229 | + @categories = @toplevel_categories = environment.top_level_categories | ||
| 223 | if params[:category_id] | 230 | if params[:category_id] |
| 224 | @current_category = Category.find(params[:category_id]) | 231 | @current_category = Category.find(params[:category_id]) |
| 225 | @categories = @current_category.children | 232 | @categories = @current_category.children |
| 226 | - else | ||
| 227 | - @categories = environment.top_level_categories.select{|i| !i.children.empty?} | ||
| 228 | end | 233 | end |
| 229 | render :partial => 'shared/select_categories', :locals => {:object_name => 'article', :multiple => true}, :layout => false | 234 | render :partial => 'shared/select_categories', :locals => {:object_name => 'article', :multiple => true}, :layout => false |
| 230 | end | 235 | end |
app/controllers/my_profile/maps_controller.rb
| @@ -31,23 +31,11 @@ class MapsController < MyProfileController | @@ -31,23 +31,11 @@ class MapsController < MyProfileController | ||
| 31 | end | 31 | end |
| 32 | 32 | ||
| 33 | def search_city | 33 | def search_city |
| 34 | - | ||
| 35 | - term = params[:term]; | ||
| 36 | - | ||
| 37 | - regions = NationalRegion.search_city(term + "%", true).map {|r|{ :label => r.city , :category => r.state}} | ||
| 38 | - | ||
| 39 | - render :json => regions | ||
| 40 | - | 34 | + render :json => MapsHelper.search_city(params[:term]) |
| 41 | end | 35 | end |
| 42 | 36 | ||
| 43 | def search_state | 37 | def search_state |
| 44 | - | ||
| 45 | - term = params[:term]; | ||
| 46 | - | ||
| 47 | - regions = NationalRegion.search_state(term + "%", true).map {|r|{ :label => r.state}} | ||
| 48 | - | ||
| 49 | - render :json => regions | ||
| 50 | - | 38 | + render :json => MapsHelper.search_state(params[:term]) |
| 51 | end | 39 | end |
| 52 | 40 | ||
| 53 | end | 41 | end |
app/controllers/my_profile/profile_design_controller.rb
| @@ -55,10 +55,4 @@ class ProfileDesignController < BoxOrganizerController | @@ -55,10 +55,4 @@ class ProfileDesignController < BoxOrganizerController | ||
| 55 | blocks | 55 | blocks |
| 56 | end | 56 | end |
| 57 | 57 | ||
| 58 | - def clone | ||
| 59 | - block = Block.find(params[:id]) | ||
| 60 | - block.duplicate | ||
| 61 | - redirect_to :action => 'index' | ||
| 62 | - end | ||
| 63 | - | ||
| 64 | end | 58 | end |
app/controllers/my_profile/profile_editor_controller.rb
| @@ -55,11 +55,10 @@ class ProfileEditorController < MyProfileController | @@ -55,11 +55,10 @@ class ProfileEditorController < MyProfileController | ||
| 55 | 55 | ||
| 56 | def update_categories | 56 | def update_categories |
| 57 | @object = profile | 57 | @object = profile |
| 58 | + @categories = @toplevel_categories = environment.top_level_categories | ||
| 58 | if params[:category_id] | 59 | if params[:category_id] |
| 59 | @current_category = Category.find(params[:category_id]) | 60 | @current_category = Category.find(params[:category_id]) |
| 60 | @categories = @current_category.children | 61 | @categories = @current_category.children |
| 61 | - else | ||
| 62 | - @categories = environment.top_level_categories.select{|i| !i.children.empty?} | ||
| 63 | end | 62 | end |
| 64 | render :partial => 'shared/select_categories', :locals => {:object_name => 'profile_data', :multiple => true}, :layout => false | 63 | render :partial => 'shared/select_categories', :locals => {:object_name => 'profile_data', :multiple => true}, :layout => false |
| 65 | end | 64 | end |
app/controllers/public/account_controller.rb
| @@ -69,6 +69,8 @@ class AccountController < ApplicationController | @@ -69,6 +69,8 @@ class AccountController < ApplicationController | ||
| 69 | session[:notice] = _("This environment doesn't allow user registration.") | 69 | session[:notice] = _("This environment doesn't allow user registration.") |
| 70 | end | 70 | end |
| 71 | 71 | ||
| 72 | + store_location(request.referer) unless params[:return_to] or session[:return_to] | ||
| 73 | + | ||
| 72 | @block_bot = !!session[:may_be_a_bot] | 74 | @block_bot = !!session[:may_be_a_bot] |
| 73 | @invitation_code = params[:invitation_code] | 75 | @invitation_code = params[:invitation_code] |
| 74 | begin | 76 | begin |
| @@ -77,6 +79,7 @@ class AccountController < ApplicationController | @@ -77,6 +79,7 @@ class AccountController < ApplicationController | ||
| 77 | @user.environment = environment | 79 | @user.environment = environment |
| 78 | @terms_of_use = environment.terms_of_use | 80 | @terms_of_use = environment.terms_of_use |
| 79 | @user.person_data = params[:profile_data] | 81 | @user.person_data = params[:profile_data] |
| 82 | + @user.return_to = session[:return_to] | ||
| 80 | @person = Person.new(params[:profile_data]) | 83 | @person = Person.new(params[:profile_data]) |
| 81 | @person.environment = @user.environment | 84 | @person.environment = @user.environment |
| 82 | if request.post? | 85 | if request.post? |
| @@ -98,7 +101,7 @@ class AccountController < ApplicationController | @@ -98,7 +101,7 @@ class AccountController < ApplicationController | ||
| 98 | end | 101 | end |
| 99 | if @user.activated? | 102 | if @user.activated? |
| 100 | self.current_user = @user | 103 | self.current_user = @user |
| 101 | - redirect_to '/' | 104 | + go_to_signup_initial_page |
| 102 | else | 105 | else |
| 103 | @register_pending = true | 106 | @register_pending = true |
| 104 | end | 107 | end |
| @@ -247,15 +250,19 @@ class AccountController < ApplicationController | @@ -247,15 +250,19 @@ class AccountController < ApplicationController | ||
| 247 | end | 250 | end |
| 248 | end | 251 | end |
| 249 | 252 | ||
| 250 | - def check_url | 253 | + def check_valid_name |
| 251 | @identifier = params[:identifier] | 254 | @identifier = params[:identifier] |
| 252 | valid = Person.is_available?(@identifier, environment) | 255 | valid = Person.is_available?(@identifier, environment) |
| 253 | if valid | 256 | if valid |
| 254 | @status = _('This login name is available') | 257 | @status = _('This login name is available') |
| 255 | @status_class = 'validated' | 258 | @status_class = 'validated' |
| 256 | - else | 259 | + elsif !@identifier.empty? |
| 260 | + @suggested_usernames = suggestion_based_on_username(@identifier) | ||
| 257 | @status = _('This login name is unavailable') | 261 | @status = _('This login name is unavailable') |
| 258 | @status_class = 'invalid' | 262 | @status_class = 'invalid' |
| 263 | + else | ||
| 264 | + @status_class = 'invalid' | ||
| 265 | + @status = _('This field can\'t be blank') | ||
| 259 | end | 266 | end |
| 260 | render :partial => 'identifier_status' | 267 | render :partial => 'identifier_status' |
| 261 | end | 268 | end |
| @@ -288,6 +295,23 @@ class AccountController < ApplicationController | @@ -288,6 +295,23 @@ class AccountController < ApplicationController | ||
| 288 | render :text => user_data.to_json, :layout => false, :content_type => "application/javascript" | 295 | render :text => user_data.to_json, :layout => false, :content_type => "application/javascript" |
| 289 | end | 296 | end |
| 290 | 297 | ||
| 298 | + def search_cities | ||
| 299 | + if request.xhr? and params[:state_name] and params[:city_name] | ||
| 300 | + render :json => MapsHelper.search_city(params[:city_name], params[:state_name]) | ||
| 301 | + else | ||
| 302 | + render :json => [].to_json | ||
| 303 | + end | ||
| 304 | + end | ||
| 305 | + | ||
| 306 | + def search_state | ||
| 307 | + if request.xhr? and params[:state_name] | ||
| 308 | + render :json => MapsHelper.search_state(params[:state_name]) | ||
| 309 | + else | ||
| 310 | + render :json => [].to_json | ||
| 311 | + end | ||
| 312 | + end | ||
| 313 | + | ||
| 314 | + | ||
| 291 | protected | 315 | protected |
| 292 | 316 | ||
| 293 | def redirect? | 317 | def redirect? |
| @@ -368,32 +392,29 @@ class AccountController < ApplicationController | @@ -368,32 +392,29 @@ class AccountController < ApplicationController | ||
| 368 | end | 392 | end |
| 369 | 393 | ||
| 370 | def go_to_initial_page | 394 | def go_to_initial_page |
| 395 | + if params[:redirection] | ||
| 396 | + session[:return_to] = @user.return_to | ||
| 397 | + @user.return_to = nil | ||
| 398 | + @user.save | ||
| 399 | + end | ||
| 400 | + | ||
| 371 | if params[:return_to] | 401 | if params[:return_to] |
| 372 | redirect_to params[:return_to] | 402 | redirect_to params[:return_to] |
| 373 | elsif environment.enabled?('allow_change_of_redirection_after_login') | 403 | elsif environment.enabled?('allow_change_of_redirection_after_login') |
| 374 | - case user.preferred_login_redirection | ||
| 375 | - when 'keep_on_same_page' | ||
| 376 | - redirect_back_or_default(user.admin_url) | ||
| 377 | - when 'site_homepage' | ||
| 378 | - redirect_to :controller => :home | ||
| 379 | - when 'user_profile_page' | ||
| 380 | - redirect_to user.public_profile_url | ||
| 381 | - when 'user_homepage' | ||
| 382 | - redirect_to user.url | ||
| 383 | - when 'user_control_panel' | ||
| 384 | - redirect_to user.admin_url | ||
| 385 | - else | ||
| 386 | - redirect_back_or_default(user.admin_url) | ||
| 387 | - end | 404 | + check_redirection_options(user, user.preferred_login_redirection, user.admin_url) |
| 388 | else | 405 | else |
| 389 | if environment == current_user.environment | 406 | if environment == current_user.environment |
| 390 | - redirect_back_or_default(user.admin_url) | 407 | + check_redirection_options(user, environment.redirection_after_login, user.admin_url) |
| 391 | else | 408 | else |
| 392 | redirect_back_or_default(:controller => 'home') | 409 | redirect_back_or_default(:controller => 'home') |
| 393 | end | 410 | end |
| 394 | end | 411 | end |
| 395 | end | 412 | end |
| 396 | 413 | ||
| 414 | + def go_to_signup_initial_page | ||
| 415 | + check_redirection_options(user, user.environment.redirection_after_signup, user.url) | ||
| 416 | + end | ||
| 417 | + | ||
| 397 | def redirect_if_logged_in | 418 | def redirect_if_logged_in |
| 398 | if logged_in? | 419 | if logged_in? |
| 399 | go_to_initial_page | 420 | go_to_initial_page |
| @@ -409,4 +430,22 @@ class AccountController < ApplicationController | @@ -409,4 +430,22 @@ class AccountController < ApplicationController | ||
| 409 | user | 430 | user |
| 410 | end | 431 | end |
| 411 | 432 | ||
| 433 | + protected | ||
| 434 | + | ||
| 435 | + def check_redirection_options(user, condition, default) | ||
| 436 | + case condition | ||
| 437 | + when 'keep_on_same_page' | ||
| 438 | + redirect_back_or_default(user.admin_url) | ||
| 439 | + when 'site_homepage' | ||
| 440 | + redirect_to :controller => :home | ||
| 441 | + when 'user_profile_page' | ||
| 442 | + redirect_to user.public_profile_url | ||
| 443 | + when 'user_homepage' | ||
| 444 | + redirect_to user.url | ||
| 445 | + when 'user_control_panel' | ||
| 446 | + redirect_to user.admin_url | ||
| 447 | + else | ||
| 448 | + redirect_back_or_default(default) | ||
| 449 | + end | ||
| 450 | + end | ||
| 412 | end | 451 | end |
app/controllers/public/content_viewer_controller.rb
| @@ -52,7 +52,7 @@ class ContentViewerController < ApplicationController | @@ -52,7 +52,7 @@ class ContentViewerController < ApplicationController | ||
| 52 | end | 52 | end |
| 53 | 53 | ||
| 54 | # At this point the page will be showed | 54 | # At this point the page will be showed |
| 55 | - @page.hit | 55 | + @page.hit unless user_is_a_bot? |
| 56 | 56 | ||
| 57 | @page = FilePresenter.for @page | 57 | @page = FilePresenter.for @page |
| 58 | 58 | ||
| @@ -113,6 +113,15 @@ class ContentViewerController < ApplicationController | @@ -113,6 +113,15 @@ class ContentViewerController < ApplicationController | ||
| 113 | @comments = @plugins.filter(:unavailable_comments, @comments) | 113 | @comments = @plugins.filter(:unavailable_comments, @comments) |
| 114 | @comments_count = @comments.count | 114 | @comments_count = @comments.count |
| 115 | @comments = @comments.without_reply.paginate(:per_page => per_page, :page => params[:comment_page] ) | 115 | @comments = @comments.without_reply.paginate(:per_page => per_page, :page => params[:comment_page] ) |
| 116 | + @comment_order = params[:comment_order].nil? ? 'oldest' : params[:comment_order] | ||
| 117 | + | ||
| 118 | + if request.xhr? and params[:comment_order] | ||
| 119 | + if @comment_order == 'newest' | ||
| 120 | + @comments = @comments.reverse | ||
| 121 | + end | ||
| 122 | + | ||
| 123 | + return render :partial => 'comment/comment', :collection => @comments | ||
| 124 | + end | ||
| 116 | 125 | ||
| 117 | if params[:slideshow] | 126 | if params[:slideshow] |
| 118 | render :action => 'slideshow', :layout => 'slideshow' | 127 | render :action => 'slideshow', :layout => 'slideshow' |
| @@ -178,4 +187,13 @@ class ContentViewerController < ApplicationController | @@ -178,4 +187,13 @@ class ContentViewerController < ApplicationController | ||
| 178 | allowed | 187 | allowed |
| 179 | end | 188 | end |
| 180 | 189 | ||
| 190 | + def user_is_a_bot? | ||
| 191 | + user_agent= request.env["HTTP_USER_AGENT"] | ||
| 192 | + user_agent.blank? || | ||
| 193 | + user_agent.match(/bot/) || | ||
| 194 | + user_agent.match(/spider/) || | ||
| 195 | + user_agent.match(/crawler/) || | ||
| 196 | + user_agent.match(/\(.*https?:\/\/.*\)/) | ||
| 197 | + end | ||
| 198 | + | ||
| 181 | end | 199 | end |
app/controllers/public/events_controller.rb
| @@ -7,11 +7,11 @@ class EventsController < PublicController | @@ -7,11 +7,11 @@ class EventsController < PublicController | ||
| 7 | @date = build_date(params[:year], params[:month], params[:day]) | 7 | @date = build_date(params[:year], params[:month], params[:day]) |
| 8 | 8 | ||
| 9 | if !params[:year] && !params[:month] && !params[:day] | 9 | if !params[:year] && !params[:month] && !params[:day] |
| 10 | - @events = profile.events.next_events_from_month(@date) | 10 | + @events = profile.events.next_events_from_month(@date).paginate(:per_page => per_page, :page => params[:page]) |
| 11 | end | 11 | end |
| 12 | 12 | ||
| 13 | if params[:year] || params[:month] | 13 | if params[:year] || params[:month] |
| 14 | - @events = profile.events.by_month(@date) | 14 | + @events = profile.events.by_month(@date).paginate(:per_page => per_page, :page => params[:page]) |
| 15 | end | 15 | end |
| 16 | 16 | ||
| 17 | events_in_range = profile.events.by_range((@date - 1.month).at_beginning_of_month .. (@date + 1.month).at_end_of_month) | 17 | events_in_range = profile.events.by_range((@date - 1.month).at_beginning_of_month .. (@date + 1.month).at_end_of_month) |
| @@ -21,7 +21,7 @@ class EventsController < PublicController | @@ -21,7 +21,7 @@ class EventsController < PublicController | ||
| 21 | 21 | ||
| 22 | def events_by_day | 22 | def events_by_day |
| 23 | @date = build_date(params[:year], params[:month], params[:day]) | 23 | @date = build_date(params[:year], params[:month], params[:day]) |
| 24 | - @events = profile.events.by_day(@date) | 24 | + @events = profile.events.by_day(@date).paginate(:per_page => per_page, :page => params[:page]) |
| 25 | render :partial => 'events' | 25 | render :partial => 'events' |
| 26 | end | 26 | end |
| 27 | 27 | ||
| @@ -29,4 +29,7 @@ class EventsController < PublicController | @@ -29,4 +29,7 @@ class EventsController < PublicController | ||
| 29 | 29 | ||
| 30 | include EventsHelper | 30 | include EventsHelper |
| 31 | 31 | ||
| 32 | + def per_page | ||
| 33 | + 20 | ||
| 34 | + end | ||
| 32 | end | 35 | end |
app/controllers/public/search_controller.rb
| @@ -99,14 +99,14 @@ class SearchController < PublicController | @@ -99,14 +99,14 @@ class SearchController < PublicController | ||
| 99 | @events = [] | 99 | @events = [] |
| 100 | if params[:day] || !params[:year] && !params[:month] | 100 | if params[:day] || !params[:year] && !params[:month] |
| 101 | @events = @category ? | 101 | @events = @category ? |
| 102 | - environment.events.by_day(@date).in_category(Category.find(@category_id)) : | ||
| 103 | - environment.events.by_day(@date) | 102 | + environment.events.by_day(@date).in_category(Category.find(@category_id)).paginate(:per_page => per_page, :page => params[:page]) : |
| 103 | + environment.events.by_day(@date).paginate(:per_page => per_page, :page => params[:page]) | ||
| 104 | end | 104 | end |
| 105 | 105 | ||
| 106 | if params[:year] || params[:month] | 106 | if params[:year] || params[:month] |
| 107 | @events = @category ? | 107 | @events = @category ? |
| 108 | - environment.events.by_month(@date).in_category(Category.find(@category_id)) : | ||
| 109 | - environment.events.by_month(@date) | 108 | + environment.events.by_month(@date).in_category(Category.find(@category_id)).paginate(:per_page => per_page, :page => params[:page]) : |
| 109 | + environment.events.by_month(@date).paginate(:per_page => per_page, :page => params[:page]) | ||
| 110 | end | 110 | end |
| 111 | 111 | ||
| 112 | @scope = date_range && params[:action] == 'events' ? environment.events.by_range(date_range) : environment.events | 112 | @scope = date_range && params[:action] == 'events' ? environment.events.by_range(date_range) : environment.events |
| @@ -139,7 +139,7 @@ class SearchController < PublicController | @@ -139,7 +139,7 @@ class SearchController < PublicController | ||
| 139 | 139 | ||
| 140 | def events_by_day | 140 | def events_by_day |
| 141 | @date = build_date(params[:year], params[:month], params[:day]) | 141 | @date = build_date(params[:year], params[:month], params[:day]) |
| 142 | - @events = environment.events.by_day(@date) | 142 | + @events = environment.events.by_day(@date).paginate(:per_page => per_page, :page => params[:page]) |
| 143 | render :partial => 'events/events' | 143 | render :partial => 'events/events' |
| 144 | end | 144 | end |
| 145 | 145 | ||
| @@ -224,4 +224,8 @@ class SearchController < PublicController | @@ -224,4 +224,8 @@ class SearchController < PublicController | ||
| 224 | @environment.send(klass.name.underscore.pluralize).visible.includes(relations) | 224 | @environment.send(klass.name.underscore.pluralize).visible.includes(relations) |
| 225 | end | 225 | end |
| 226 | 226 | ||
| 227 | + def per_page | ||
| 228 | + 20 | ||
| 229 | + end | ||
| 230 | + | ||
| 227 | end | 231 | end |
app/controllers/themes_controller.rb
| @@ -12,7 +12,7 @@ class ThemesController < ApplicationController | @@ -12,7 +12,7 @@ class ThemesController < ApplicationController | ||
| 12 | 12 | ||
| 13 | def index | 13 | def index |
| 14 | @environment = environment | 14 | @environment = environment |
| 15 | - @themes = environment.themes + Theme.approved_themes(target) | 15 | + @themes = (environment.themes + Theme.approved_themes(target)).sort_by { |t| t.name } |
| 16 | 16 | ||
| 17 | @current_theme = target.theme | 17 | @current_theme = target.theme |
| 18 | 18 |
app/helpers/account_helper.rb
| @@ -12,4 +12,17 @@ module AccountHelper | @@ -12,4 +12,17 @@ module AccountHelper | ||
| 12 | _('Checking if e-mail address is already taken...') | 12 | _('Checking if e-mail address is already taken...') |
| 13 | end | 13 | end |
| 14 | end | 14 | end |
| 15 | + | ||
| 16 | + def suggestion_based_on_username(requested_username='') | ||
| 17 | + return "" if requested_username.empty? | ||
| 18 | + usernames = [] | ||
| 19 | + 3.times do | ||
| 20 | + begin | ||
| 21 | + valid_name = requested_username + rand(1000).to_s | ||
| 22 | + end while (usernames.include?(valid_name) || !Person.is_available?(valid_name, environment)) | ||
| 23 | + usernames << valid_name | ||
| 24 | + end | ||
| 25 | + usernames | ||
| 26 | + end | ||
| 27 | + | ||
| 15 | end | 28 | end |
app/helpers/application_helper.rb
| @@ -605,49 +605,18 @@ module ApplicationHelper | @@ -605,49 +605,18 @@ module ApplicationHelper | ||
| 605 | end | 605 | end |
| 606 | 606 | ||
| 607 | attr_reader :environment | 607 | attr_reader :environment |
| 608 | + | ||
| 608 | def select_categories(object_name, title=nil, title_size=4) | 609 | def select_categories(object_name, title=nil, title_size=4) |
| 609 | return nil if environment.enabled?(:disable_categories) | 610 | return nil if environment.enabled?(:disable_categories) |
| 610 | if title.nil? | 611 | if title.nil? |
| 611 | title = _('Categories') | 612 | title = _('Categories') |
| 612 | end | 613 | end |
| 613 | 614 | ||
| 614 | - object = instance_variable_get("@#{object_name}") | ||
| 615 | - | ||
| 616 | - result = content_tag 'h'+title_size.to_s(), title | ||
| 617 | - result << javascript_tag( 'function open_close_cat( link ) { | ||
| 618 | - var div = link.parentNode.getElementsByTagName("div")[0]; | ||
| 619 | - var end = function(){ | ||
| 620 | - if ( div.style.display == "none" ) { | ||
| 621 | - this.link.className="button icon-button icon-down" | ||
| 622 | - } else { | ||
| 623 | - this.link.className="button icon-button icon-up-red" | ||
| 624 | - } | ||
| 625 | - } | ||
| 626 | - Effect.toggle( div, "slide", { link:link, div:div, afterFinish:end } ) | ||
| 627 | - }') | ||
| 628 | - environment.top_level_categories.select{|i| !i.children.empty?}.each do |toplevel| | ||
| 629 | - next unless object.accept_category?(toplevel) | ||
| 630 | - # FIXME | ||
| 631 | - ([toplevel] + toplevel.children_for_menu).each do |cat| | ||
| 632 | - if cat.top_level? | ||
| 633 | - result << '<div class="categorie_box">'.html_safe | ||
| 634 | - result << icon_button( :down, _('open'), '#', :onclick => 'open_close_cat(this); return false' ) | ||
| 635 | - result << content_tag('h5', toplevel.name) | ||
| 636 | - result << '<div style="display:none"><ul class="categories">'.html_safe | ||
| 637 | - else | ||
| 638 | - checkbox_id = "#{object_name}_#{cat.full_name.downcase.gsub(/\s+|\//, '_')}" | ||
| 639 | - result << content_tag('li', labelled_check_box( | ||
| 640 | - cat.full_name_without_leading(1, " → "), | ||
| 641 | - "#{object_name}[category_ids][]", cat.id, | ||
| 642 | - object.category_ids.include?(cat.id), :id => checkbox_id, | ||
| 643 | - :onchange => j('this.parentNode.className=(this.checked?"cat_checked":"")') ), | ||
| 644 | - :class => ( object.category_ids.include?(cat.id) ? 'cat_checked' : '' ) ) + "\n" | ||
| 645 | - end | ||
| 646 | - end | ||
| 647 | - result << '</ul></div></div>'.html_safe | ||
| 648 | - end | 615 | + @object = instance_variable_get("@#{object_name}") |
| 616 | + @categories = environment.top_level_categories | ||
| 649 | 617 | ||
| 650 | - content_tag('div', result) | 618 | + @current_categories = environment.top_level_categories.select{|i| !i.children.empty?} |
| 619 | + render :partial => 'shared/select_categories_top', :locals => {:object_name => object_name, :title => title, :title_size => title_size, :multiple => true, :categories_selected => @object.categories }, :layout => false | ||
| 651 | end | 620 | end |
| 652 | 621 | ||
| 653 | def theme_option(opt = nil) | 622 | def theme_option(opt = nil) |
| @@ -934,12 +903,11 @@ module ApplicationHelper | @@ -934,12 +903,11 @@ module ApplicationHelper | ||
| 934 | 903 | ||
| 935 | def page_title | 904 | def page_title |
| 936 | (@page ? @page.title + ' - ' : '') + | 905 | (@page ? @page.title + ' - ' : '') + |
| 937 | - (profile ? profile.short_name + ' - ' : '') + | ||
| 938 | (@topic ? @topic.title + ' - ' : '') + | 906 | (@topic ? @topic.title + ' - ' : '') + |
| 939 | (@section ? @section.title + ' - ' : '') + | 907 | (@section ? @section.title + ' - ' : '') + |
| 940 | (@toc ? _('Online Manual') + ' - ' : '') + | 908 | (@toc ? _('Online Manual') + ' - ' : '') + |
| 941 | (controller.controller_name == 'chat' ? _('Chat') + ' - ' : '') + | 909 | (controller.controller_name == 'chat' ? _('Chat') + ' - ' : '') + |
| 942 | - environment.name + | 910 | + (profile ? profile.short_name : environment.name) + |
| 943 | (@category ? " - #{@category.full_name}" : '') | 911 | (@category ? " - #{@category.full_name}" : '') |
| 944 | end | 912 | end |
| 945 | 913 |
app/helpers/article_helper.rb
| @@ -50,8 +50,14 @@ module ArticleHelper | @@ -50,8 +50,14 @@ module ArticleHelper | ||
| 50 | 'div', | 50 | 'div', |
| 51 | check_box(:article, :display_versions) + | 51 | check_box(:article, :display_versions) + |
| 52 | content_tag('label', _('I want this article to display a link to older versions'), :for => 'article_display_versions') | 52 | content_tag('label', _('I want this article to display a link to older versions'), :for => 'article_display_versions') |
| 53 | - ) : '') | 53 | + ) : '') + |
| 54 | 54 | ||
| 55 | + (article.forum? && article.profile.community? ? | ||
| 56 | + content_tag( | ||
| 57 | + 'div', | ||
| 58 | + check_box(:article, :allows_members_to_create_topics) + | ||
| 59 | + content_tag('label', _('Allow members to create topics'), :for => 'article_allows_members_to_create_topics') | ||
| 60 | + ) : '') | ||
| 55 | ) | 61 | ) |
| 56 | end | 62 | end |
| 57 | 63 |
app/helpers/boxes_helper.rb
| @@ -65,7 +65,7 @@ module BoxesHelper | @@ -65,7 +65,7 @@ module BoxesHelper | ||
| 65 | end | 65 | end |
| 66 | 66 | ||
| 67 | def display_box_content(box, main_content) | 67 | def display_box_content(box, main_content) |
| 68 | - context = { :article => @page, :request_path => request.path, :locale => locale, :params => request.params } | 68 | + context = { :article => @page, :request_path => request.path, :locale => locale, :params => request.params, :user => user } |
| 69 | box_decorator.select_blocks(box.blocks.includes(:box), context).map { |item| display_block(item, main_content) }.join("\n") + box_decorator.block_target(box) | 69 | box_decorator.select_blocks(box.blocks.includes(:box), context).map { |item| display_block(item, main_content) }.join("\n") + box_decorator.block_target(box) |
| 70 | end | 70 | end |
| 71 | 71 | ||
| @@ -212,13 +212,24 @@ module BoxesHelper | @@ -212,13 +212,24 @@ module BoxesHelper | ||
| 212 | 212 | ||
| 213 | if !block.main? | 213 | if !block.main? |
| 214 | buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')}) | 214 | buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')}) |
| 215 | - buttons << icon_button(:clone, _('Clone'), { :action => 'clone', :id => block.id }, { :method => 'post' }) | 215 | + buttons << icon_button(:clone, _('Clone'), { :action => 'clone_block', :id => block.id }, { :method => 'post' }) |
| 216 | end | 216 | end |
| 217 | 217 | ||
| 218 | if block.respond_to?(:help) | 218 | if block.respond_to?(:help) |
| 219 | buttons << thickbox_inline_popup_icon(:help, _('Help on this block'), {}, "help-on-box-#{block.id}") << content_tag('div', content_tag('h2', _('Help')) + content_tag('div', block.help, :style => 'margin-bottom: 1em;') + thickbox_close_button(_('Close')), :style => 'display: none;', :id => "help-on-box-#{block.id}") | 219 | buttons << thickbox_inline_popup_icon(:help, _('Help on this block'), {}, "help-on-box-#{block.id}") << content_tag('div', content_tag('h2', _('Help')) + content_tag('div', block.help, :style => 'margin-bottom: 1em;') + thickbox_close_button(_('Close')), :style => 'display: none;', :id => "help-on-box-#{block.id}") |
| 220 | end | 220 | end |
| 221 | 221 | ||
| 222 | + if block.embedable? | ||
| 223 | + embed_code = block.embed_code | ||
| 224 | + embed_code = instance_eval(&embed_code) if embed_code.respond_to?(:call) | ||
| 225 | + html = content_tag('div', | ||
| 226 | + content_tag('h2', _('Embed block code')) + | ||
| 227 | + content_tag('div', _('Below, you''ll see a field containing embed code for the block. Just copy the code and paste it into your website or blogging software.'), :style => 'margin-bottom: 1em;') + | ||
| 228 | + content_tag('textarea', embed_code, :style => 'margin-bottom: 1em; width:100%; height:40%;', :readonly => 'readonly') + | ||
| 229 | + thickbox_close_button(_('Close')), :style => 'display: none;', :id => "embed-code-box-#{block.id}") | ||
| 230 | + buttons << thickbox_inline_popup_icon(:embed, _('Embed code'), {}, "embed-code-box-#{block.id}") << html | ||
| 231 | + end | ||
| 232 | + | ||
| 222 | content_tag('div', buttons.join("\n") + tag('br', :style => 'clear: left'), :class => 'button-bar') | 233 | content_tag('div', buttons.join("\n") + tag('br', :style => 'clear: left'), :class => 'button-bar') |
| 223 | end | 234 | end |
| 224 | 235 |
app/helpers/categories_helper.rb
| @@ -48,4 +48,12 @@ module CategoriesHelper | @@ -48,4 +48,12 @@ module CategoriesHelper | ||
| 48 | labelled_form_field(_('Type of category'), select_tag('type', options_for_select(TYPES, value))) | 48 | labelled_form_field(_('Type of category'), select_tag('type', options_for_select(TYPES, value))) |
| 49 | end | 49 | end |
| 50 | 50 | ||
| 51 | + #FIXME make this test | ||
| 52 | + def selected_category_link(cat) | ||
| 53 | + content_tag('div', button_to_function_without_text(:remove, _('Remove'), nil) {|page| page["selected-category-#{cat.id}"].remove} + | ||
| 54 | + link_to_function(cat.full_name(' → '), nil, :id => "remove-selected-category-#{cat.id}-button", :class => 'select-subcategory-link') {|page| page["selected-category-#{cat.id}"].remove}, | ||
| 55 | + :class => 'selected-category' | ||
| 56 | + ) | ||
| 57 | + end | ||
| 58 | + | ||
| 51 | end | 59 | end |
app/helpers/comment_helper.rb
| @@ -2,7 +2,6 @@ module CommentHelper | @@ -2,7 +2,6 @@ module CommentHelper | ||
| 2 | 2 | ||
| 3 | def article_title(article, args = {}) | 3 | def article_title(article, args = {}) |
| 4 | title = article.title | 4 | title = article.title |
| 5 | - title = article.display_title if article.kind_of?(UploadedFile) && article.image? | ||
| 6 | title = content_tag('h1', h(title), :class => 'title') | 5 | title = content_tag('h1', h(title), :class => 'title') |
| 7 | if article.belongs_to_blog? | 6 | if article.belongs_to_blog? |
| 8 | unless args[:no_link] | 7 | unless args[:no_link] |
| @@ -22,6 +21,12 @@ module CommentHelper | @@ -22,6 +21,12 @@ module CommentHelper | ||
| 22 | title | 21 | title |
| 23 | end | 22 | end |
| 24 | 23 | ||
| 24 | + def comment_extra_contents(comment) | ||
| 25 | + @plugins.dispatch(:comment_extra_contents, comment).collect do |extra_content| | ||
| 26 | + extra_content.kind_of?(Proc) ? self.instance_eval(&extra_content) : extra_content | ||
| 27 | + end.join('\n') | ||
| 28 | + end | ||
| 29 | + | ||
| 25 | def comment_actions(comment) | 30 | def comment_actions(comment) |
| 26 | url = url_for(:profile => profile.identifier, :controller => :comment, :action => :check_actions, :id => comment.id) | 31 | url = url_for(:profile => profile.identifier, :controller => :comment, :action => :check_actions, :id => comment.id) |
| 27 | links = links_for_comment_actions(comment) | 32 | links = links_for_comment_actions(comment) |
app/helpers/content_viewer_helper.rb
| @@ -14,8 +14,7 @@ module ContentViewerHelper | @@ -14,8 +14,7 @@ module ContentViewerHelper | ||
| 14 | end | 14 | end |
| 15 | 15 | ||
| 16 | def article_title(article, args = {}) | 16 | def article_title(article, args = {}) |
| 17 | - title = article.display_title if article.kind_of?(UploadedFile) && article.image? | ||
| 18 | - title = article.title if title.blank? | 17 | + title = article.title |
| 19 | title = content_tag('h1', h(title), :class => 'title') | 18 | title = content_tag('h1', h(title), :class => 'title') |
| 20 | if article.belongs_to_blog? || article.belongs_to_forum? | 19 | if article.belongs_to_blog? || article.belongs_to_forum? |
| 21 | unless args[:no_link] | 20 | unless args[:no_link] |
| @@ -52,15 +51,6 @@ module ContentViewerHelper | @@ -52,15 +51,6 @@ module ContentViewerHelper | ||
| 52 | end | 51 | end |
| 53 | end | 52 | end |
| 54 | 53 | ||
| 55 | - def addthis_facebook_url(article) | ||
| 56 | - "http://www.facebook.com/sharer.php?s=100&p[title]=%{title}&p[summary]=%{summary}&p[url]=%{url}&p[images][0]=%{image}" % { | ||
| 57 | - :title => CGI.escape(article.title), | ||
| 58 | - :url => CGI.escape(url_for(article.url)), | ||
| 59 | - :summary => CGI.escape(truncate(strip_tags(article.body.to_s), :length => 300)), | ||
| 60 | - :image => CGI.escape(article.body_images_paths.first.to_s) | ||
| 61 | - } | ||
| 62 | - end | ||
| 63 | - | ||
| 64 | def addthis_image_tag | 54 | def addthis_image_tag |
| 65 | if File.exists?(Rails.root.join('public', theme_path, 'images', 'addthis.gif')) | 55 | if File.exists?(Rails.root.join('public', theme_path, 'images', 'addthis.gif')) |
| 66 | image_tag(File.join(theme_path, 'images', 'addthis.gif'), :border => 0, :alt => '') | 56 | image_tag(File.join(theme_path, 'images', 'addthis.gif'), :border => 0, :alt => '') |
app/helpers/layout_helper.rb
app/helpers/macros_helper.rb
| @@ -20,14 +20,16 @@ module MacrosHelper | @@ -20,14 +20,16 @@ module MacrosHelper | ||
| 20 | jQuery('<div>'+#{macro_configuration_dialog(macro).to_json}+'</div>').dialog({ | 20 | jQuery('<div>'+#{macro_configuration_dialog(macro).to_json}+'</div>').dialog({ |
| 21 | title: #{macro_title(macro).to_json}, | 21 | title: #{macro_title(macro).to_json}, |
| 22 | modal: true, | 22 | modal: true, |
| 23 | - buttons: [ | ||
| 24 | - {text: #{_('Ok').to_json}, click: function(){ | 23 | + buttons: { |
| 24 | + #{_('Ok').to_json}: function(){ | ||
| 25 | tinyMCE.activeEditor.execCommand('mceInsertContent', false, | 25 | tinyMCE.activeEditor.execCommand('mceInsertContent', false, |
| 26 | (function(dialog){ #{macro_generator(macro)} })(this)); | 26 | (function(dialog){ #{macro_generator(macro)} })(this)); |
| 27 | jQuery(this).dialog('close'); | 27 | jQuery(this).dialog('close'); |
| 28 | - }}, | ||
| 29 | - {text: #{_('Cancel').to_json}, click: function(){jQuery(this).dialog('close');}} | ||
| 30 | - ] | 28 | + }, |
| 29 | + #{_('Cancel').to_json}: function(){ | ||
| 30 | + jQuery(this).dialog('close'); | ||
| 31 | + } | ||
| 32 | + } | ||
| 31 | }); | 33 | }); |
| 32 | }" | 34 | }" |
| 33 | end | 35 | end |
| @@ -57,7 +59,11 @@ module MacrosHelper | @@ -57,7 +59,11 @@ module MacrosHelper | ||
| 57 | 59 | ||
| 58 | def macro_generator(macro) | 60 | def macro_generator(macro) |
| 59 | if macro.configuration[:generator] | 61 | if macro.configuration[:generator] |
| 60 | - macro.configuration[:generator] | 62 | + if macro.configuration[:generator].respond_to?(:call) |
| 63 | + macro.configuration[:generator].call(macro) | ||
| 64 | + else | ||
| 65 | + macro.configuration[:generator] | ||
| 66 | + end | ||
| 61 | else | 67 | else |
| 62 | macro_default_generator(macro) | 68 | macro_default_generator(macro) |
| 63 | end | 69 | end |
| @@ -66,8 +72,7 @@ module MacrosHelper | @@ -66,8 +72,7 @@ module MacrosHelper | ||
| 66 | 72 | ||
| 67 | def macro_default_generator(macro) | 73 | def macro_default_generator(macro) |
| 68 | code = "var params = {};" | 74 | code = "var params = {};" |
| 69 | - configuration = macro_configuration(macro) | ||
| 70 | - configuration[:params].map do |field| | 75 | + macro.configuration[:params].map do |field| |
| 71 | code += "params.#{field[:name]} = jQuery('*[name=#{field[:name]}]', dialog).val();" | 76 | code += "params.#{field[:name]} = jQuery('*[name=#{field[:name]}]', dialog).val();" |
| 72 | end | 77 | end |
| 73 | code + " | 78 | code + " |
| @@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
| 1 | +module MapsHelper | ||
| 2 | + def self.search_city term, state="" | ||
| 3 | + cities = if state.empty? | ||
| 4 | + NationalRegion.search_city(term + "%", true) | ||
| 5 | + else | ||
| 6 | + NationalRegion.search_city(term + "%", true, state) | ||
| 7 | + end | ||
| 8 | + cities.map {|r|{ :label => r.city , :category => r.state}} | ||
| 9 | + end | ||
| 10 | + | ||
| 11 | + def self.search_state term | ||
| 12 | + NationalRegion.search_state(term + "%", true).map {|r|{ :label => r.state}} | ||
| 13 | + end | ||
| 14 | +end |
app/helpers/token_helper.rb
| @@ -27,7 +27,7 @@ module TokenHelper | @@ -27,7 +27,7 @@ module TokenHelper | ||
| 27 | hintText: #{options[:hint_text].to_json}, | 27 | hintText: #{options[:hint_text].to_json}, |
| 28 | noResultsText: #{options[:no_results_text].to_json}, | 28 | noResultsText: #{options[:no_results_text].to_json}, |
| 29 | searchingText: #{options[:searching_text].to_json}, | 29 | searchingText: #{options[:searching_text].to_json}, |
| 30 | - searchDelay: #{options[:serach_delay].to_json}, | 30 | + searchDelay: #{options[:search_delay].to_json}, |
| 31 | preventDuplicates: #{options[:prevent_duplicates].to_json}, | 31 | preventDuplicates: #{options[:prevent_duplicates].to_json}, |
| 32 | backspaceDeleteItem: #{options[:backspace_delete_item].to_json}, | 32 | backspaceDeleteItem: #{options[:backspace_delete_item].to_json}, |
| 33 | queryParam: #{name.to_json}, | 33 | queryParam: #{name.to_json}, |
app/mailers/contact.rb
| @@ -46,7 +46,7 @@ class Contact | @@ -46,7 +46,7 @@ class Contact | ||
| 46 | to: contact.dest.notification_emails, | 46 | to: contact.dest.notification_emails, |
| 47 | reply_to: contact.email, | 47 | reply_to: contact.email, |
| 48 | subject: "[#{contact.dest.short_name(30)}] " + contact.subject, | 48 | subject: "[#{contact.dest.short_name(30)}] " + contact.subject, |
| 49 | - from: "#{contact.name} <#{contact.dest.environment.contact_email}>" | 49 | + from: "#{contact.name} <#{contact.dest.environment.noreply_email}>" |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | if contact.sender | 52 | if contact.sender |
app/mailers/mailing.rb
| @@ -20,7 +20,7 @@ class Mailing < ActiveRecord::Base | @@ -20,7 +20,7 @@ class Mailing < ActiveRecord::Base | ||
| 20 | end | 20 | end |
| 21 | 21 | ||
| 22 | def generate_from | 22 | def generate_from |
| 23 | - "#{source.name} <#{source.contact_email}>" | 23 | + "#{source.name} <#{if source.is_a? Environment then source.noreply_email else source.contact_email end}>" |
| 24 | end | 24 | end |
| 25 | 25 | ||
| 26 | def generate_subject | 26 | def generate_subject |
app/mailers/organization_mailing.rb
| 1 | class OrganizationMailing < Mailing | 1 | class OrganizationMailing < Mailing |
| 2 | 2 | ||
| 3 | def generate_from | 3 | def generate_from |
| 4 | - "#{person.name} <#{source.environment.contact_email}>" | 4 | + "#{person.name} <#{source.environment.noreply_email}>" |
| 5 | end | 5 | end |
| 6 | 6 | ||
| 7 | def recipients(offset=0, limit=100) | 7 | def recipients(offset=0, limit=100) |
app/mailers/pending_task_notifier.rb
| @@ -11,7 +11,7 @@ class PendingTaskNotifier < ActionMailer::Base | @@ -11,7 +11,7 @@ class PendingTaskNotifier < ActionMailer::Base | ||
| 11 | 11 | ||
| 12 | mail( | 12 | mail( |
| 13 | to: person.email, | 13 | to: person.email, |
| 14 | - from: "#{person.environment.name} <#{person.environment.contact_email}>", | 14 | + from: "#{person.environment.name} <#{person.environment.noreply_email}>", |
| 15 | subject: _("[%s] Pending tasks") % person.environment.name | 15 | subject: _("[%s] Pending tasks") % person.environment.name |
| 16 | ) | 16 | ) |
| 17 | end | 17 | end |
app/mailers/task_mailer.rb
| @@ -52,7 +52,7 @@ class TaskMailer < ActionMailer::Base | @@ -52,7 +52,7 @@ class TaskMailer < ActionMailer::Base | ||
| 52 | end | 52 | end |
| 53 | 53 | ||
| 54 | def self.generate_from(task) | 54 | def self.generate_from(task) |
| 55 | - "#{task.environment.name} <#{task.environment.contact_email}>" | 55 | + "#{task.environment.name} <#{task.environment.noreply_email}>" |
| 56 | end | 56 | end |
| 57 | 57 | ||
| 58 | def generate_environment_url(task, url = {}) | 58 | def generate_environment_url(task, url = {}) |
app/models/block.rb
| @@ -18,17 +18,36 @@ class Block < ActiveRecord::Base | @@ -18,17 +18,36 @@ class Block < ActiveRecord::Base | ||
| 18 | 18 | ||
| 19 | scope :enabled, :conditions => { :enabled => true } | 19 | scope :enabled, :conditions => { :enabled => true } |
| 20 | 20 | ||
| 21 | + def embedable? | ||
| 22 | + false | ||
| 23 | + end | ||
| 24 | + | ||
| 25 | + def embed_code | ||
| 26 | + me = self | ||
| 27 | + lambda do | ||
| 28 | + content_tag('iframe', '', | ||
| 29 | + :src => url_for(:controller => 'embed', :action => 'block', :id => me.id, :only_path => false), | ||
| 30 | + :frameborder => 0, | ||
| 31 | + :width => 1024, | ||
| 32 | + :height => 768, | ||
| 33 | + :class => "embed block #{me.class.name.to_css_class}" | ||
| 34 | + ) | ||
| 35 | + end | ||
| 36 | + end | ||
| 37 | + | ||
| 21 | # Determines whether a given block must be visible. Optionally a | 38 | # Determines whether a given block must be visible. Optionally a |
| 22 | # <tt>context</tt> must be specified. <tt>context</tt> must be a hash, and | 39 | # <tt>context</tt> must be specified. <tt>context</tt> must be a hash, and |
| 23 | # may contain the following keys: | 40 | # may contain the following keys: |
| 24 | # | 41 | # |
| 25 | # * <tt>:article</tt>: the article being viewed currently | 42 | # * <tt>:article</tt>: the article being viewed currently |
| 26 | # * <tt>:language</tt>: in which language the block will be displayed | 43 | # * <tt>:language</tt>: in which language the block will be displayed |
| 44 | + # * <tt>:user</tt>: the logged user | ||
| 27 | def visible?(context = nil) | 45 | def visible?(context = nil) |
| 28 | return false if display == 'never' | 46 | return false if display == 'never' |
| 29 | 47 | ||
| 30 | if context | 48 | if context |
| 31 | return false if language != 'all' && language != context[:locale] | 49 | return false if language != 'all' && language != context[:locale] |
| 50 | + return false unless display_to_user?(context[:user]) | ||
| 32 | 51 | ||
| 33 | begin | 52 | begin |
| 34 | return self.send("display_#{display}", context) | 53 | return self.send("display_#{display}", context) |
| @@ -40,6 +59,10 @@ class Block < ActiveRecord::Base | @@ -40,6 +59,10 @@ class Block < ActiveRecord::Base | ||
| 40 | true | 59 | true |
| 41 | end | 60 | end |
| 42 | 61 | ||
| 62 | + def display_to_user?(user) | ||
| 63 | + display_user == 'all' || (user.nil? && display_user == 'not_logged') || (user && display_user == 'logged') | ||
| 64 | + end | ||
| 65 | + | ||
| 43 | def display_always(context) | 66 | def display_always(context) |
| 44 | true | 67 | true |
| 45 | end | 68 | end |
| @@ -70,6 +93,14 @@ class Block < ActiveRecord::Base | @@ -70,6 +93,14 @@ class Block < ActiveRecord::Base | ||
| 70 | # the homepage of its owner. | 93 | # the homepage of its owner. |
| 71 | settings_items :display, :type => :string, :default => 'always' | 94 | settings_items :display, :type => :string, :default => 'always' |
| 72 | 95 | ||
| 96 | + | ||
| 97 | + # The condition for displaying a block to users. It can assume the following values: | ||
| 98 | + # | ||
| 99 | + # * <tt>'all'</tt>: the block is always displayed | ||
| 100 | + # * <tt>'logged'</tt>: the block is displayed to logged users only | ||
| 101 | + # * <tt>'not_logged'</tt>: the block is displayed only to not logged users | ||
| 102 | + settings_items :display_user, :type => :string, :default => 'all' | ||
| 103 | + | ||
| 73 | # The block can be configured to be displayed in all languages or in just one language. It can assume any locale of the environment: | 104 | # The block can be configured to be displayed in all languages or in just one language. It can assume any locale of the environment: |
| 74 | # | 105 | # |
| 75 | # * <tt>'all'</tt>: the block is always displayed | 106 | # * <tt>'all'</tt>: the block is always displayed |
| @@ -143,7 +174,7 @@ class Block < ActiveRecord::Base | @@ -143,7 +174,7 @@ class Block < ActiveRecord::Base | ||
| 143 | end | 174 | end |
| 144 | 175 | ||
| 145 | alias :active_record_cache_key :cache_key | 176 | alias :active_record_cache_key :cache_key |
| 146 | - def cache_key(language='en') | 177 | + def cache_key(language='en', user=nil) |
| 147 | active_record_cache_key+'-'+language | 178 | active_record_cache_key+'-'+language |
| 148 | end | 179 | end |
| 149 | 180 | ||
| @@ -173,12 +204,20 @@ class Block < ActiveRecord::Base | @@ -173,12 +204,20 @@ class Block < ActiveRecord::Base | ||
| 173 | 'never' => _('Don\'t display'), | 204 | 'never' => _('Don\'t display'), |
| 174 | } | 205 | } |
| 175 | 206 | ||
| 176 | - def display_options | 207 | + def display_options_available |
| 177 | DISPLAY_OPTIONS.keys | 208 | DISPLAY_OPTIONS.keys |
| 178 | end | 209 | end |
| 179 | 210 | ||
| 180 | - def display_option_label(option) | ||
| 181 | - DISPLAY_OPTIONS[option] | 211 | + def display_options |
| 212 | + DISPLAY_OPTIONS.slice(*display_options_available) | ||
| 213 | + end | ||
| 214 | + | ||
| 215 | + def display_user_options | ||
| 216 | + @display_user_options ||= { | ||
| 217 | + 'all' => __('All users'), | ||
| 218 | + 'logged' => __('Logged'), | ||
| 219 | + 'not_logged' => __('Not logged'), | ||
| 220 | + } | ||
| 182 | end | 221 | end |
| 183 | 222 | ||
| 184 | def duplicate | 223 | def duplicate |
app/models/box.rb
| @@ -28,6 +28,8 @@ class Box < ActiveRecord::Base | @@ -28,6 +28,8 @@ class Box < ActiveRecord::Base | ||
| 28 | CategoriesBlock, | 28 | CategoriesBlock, |
| 29 | CommunitiesBlock, | 29 | CommunitiesBlock, |
| 30 | EnterprisesBlock, | 30 | EnterprisesBlock, |
| 31 | + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
| 32 | + # the Noosfero core soon, see ActionItem3045 | ||
| 31 | EnvironmentStatisticsBlock, | 33 | EnvironmentStatisticsBlock, |
| 32 | FansBlock, | 34 | FansBlock, |
| 33 | FavoriteEnterprisesBlock, | 35 | FavoriteEnterprisesBlock, |
| @@ -54,6 +56,8 @@ class Box < ActiveRecord::Base | @@ -54,6 +56,8 @@ class Box < ActiveRecord::Base | ||
| 54 | CommunitiesBlock, | 56 | CommunitiesBlock, |
| 55 | DisabledEnterpriseMessageBlock, | 57 | DisabledEnterpriseMessageBlock, |
| 56 | EnterprisesBlock, | 58 | EnterprisesBlock, |
| 59 | + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
| 60 | + # the Noosfero core soon, see ActionItem3045 | ||
| 57 | EnvironmentStatisticsBlock, | 61 | EnvironmentStatisticsBlock, |
| 58 | FansBlock, | 62 | FansBlock, |
| 59 | FavoriteEnterprisesBlock, | 63 | FavoriteEnterprisesBlock, |
app/models/comment.rb
| @@ -170,6 +170,40 @@ class Comment < ActiveRecord::Base | @@ -170,6 +170,40 @@ class Comment < ActiveRecord::Base | ||
| 170 | body || '' | 170 | body || '' |
| 171 | end | 171 | end |
| 172 | 172 | ||
| 173 | + class Notifier < ActionMailer::Base | ||
| 174 | + def mail(comment) | ||
| 175 | + profile = comment.article.profile | ||
| 176 | + recipients comment.notification_emails | ||
| 177 | + from "#{profile.environment.name} <#{profile.environment.noreply_email}>" | ||
| 178 | + subject _("[%s] you got a new comment!") % [profile.environment.name] | ||
| 179 | + body :recipient => profile.nickname || profile.name, | ||
| 180 | + :sender => comment.author_name, | ||
| 181 | + :sender_link => comment.author_link, | ||
| 182 | + :article_title => comment.article.name, | ||
| 183 | + :comment_url => comment.url, | ||
| 184 | + :comment_title => comment.title, | ||
| 185 | + :comment_body => comment.body, | ||
| 186 | + :environment => profile.environment.name, | ||
| 187 | + :url => profile.environment.top_url | ||
| 188 | + end | ||
| 189 | + def mail_to_followers(comment, emails) | ||
| 190 | + profile = comment.article.profile | ||
| 191 | + bcc emails | ||
| 192 | + from "#{profile.environment.name} <#{profile.environment.noreply_email}>" | ||
| 193 | + subject _("[%s] %s commented on a content of %s") % [profile.environment.name, comment.author_name, profile.short_name] | ||
| 194 | + body :recipient => profile.nickname || profile.name, | ||
| 195 | + :sender => comment.author_name, | ||
| 196 | + :sender_link => comment.author_link, | ||
| 197 | + :article_title => comment.article.name, | ||
| 198 | + :comment_url => comment.url, | ||
| 199 | + :unsubscribe_url => comment.article.view_url.merge({:unfollow => true}), | ||
| 200 | + :comment_title => comment.title, | ||
| 201 | + :comment_body => comment.body, | ||
| 202 | + :environment => profile.environment.name, | ||
| 203 | + :url => profile.environment.top_url | ||
| 204 | + end | ||
| 205 | + end | ||
| 206 | + | ||
| 173 | def rejected? | 207 | def rejected? |
| 174 | @rejected | 208 | @rejected |
| 175 | end | 209 | end |
app/models/environment.rb
| @@ -147,6 +147,18 @@ class Environment < ActiveRecord::Base | @@ -147,6 +147,18 @@ class Environment < ActiveRecord::Base | ||
| 147 | end | 147 | end |
| 148 | validates_inclusion_of :redirection_after_login, :in => Environment.login_redirection_options.keys, :allow_nil => true | 148 | validates_inclusion_of :redirection_after_login, :in => Environment.login_redirection_options.keys, :allow_nil => true |
| 149 | 149 | ||
| 150 | + def self.signup_redirection_options | ||
| 151 | + { | ||
| 152 | + 'keep_on_same_page' => _('Stays on the same page the user was before signup.'), | ||
| 153 | + 'site_homepage' => _('Redirects the user to the environment homepage.'), | ||
| 154 | + 'user_profile_page' => _('Redirects the user to his profile page.'), | ||
| 155 | + 'user_homepage' => _('Redirects the user to his homepage.'), | ||
| 156 | + 'user_control_panel' => _('Redirects the user to his control panel.') | ||
| 157 | + } | ||
| 158 | + end | ||
| 159 | + validates_inclusion_of :redirection_after_signup, :in => Environment.signup_redirection_options.keys, :allow_nil => true | ||
| 160 | + | ||
| 161 | + | ||
| 150 | # ################################################# | 162 | # ################################################# |
| 151 | # Relationships and applied behaviour | 163 | # Relationships and applied behaviour |
| 152 | # ################################################# | 164 | # ################################################# |
| @@ -163,6 +175,8 @@ class Environment < ActiveRecord::Base | @@ -163,6 +175,8 @@ class Environment < ActiveRecord::Base | ||
| 163 | 175 | ||
| 164 | # "left" area | 176 | # "left" area |
| 165 | env.boxes[1].blocks << LoginBlock.new | 177 | env.boxes[1].blocks << LoginBlock.new |
| 178 | + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
| 179 | + # the Noosfero core soon, see ActionItem3045 | ||
| 166 | env.boxes[1].blocks << EnvironmentStatisticsBlock.new | 180 | env.boxes[1].blocks << EnvironmentStatisticsBlock.new |
| 167 | env.boxes[1].blocks << RecentDocumentsBlock.new | 181 | env.boxes[1].blocks << RecentDocumentsBlock.new |
| 168 | 182 | ||
| @@ -580,7 +594,7 @@ class Environment < ActiveRecord::Base | @@ -580,7 +594,7 @@ class Environment < ActiveRecord::Base | ||
| 580 | # only one environment can be the default one | 594 | # only one environment can be the default one |
| 581 | validates_uniqueness_of :is_default, :if => (lambda do |environment| environment.is_default? end), :message => N_('Only one Virtual Community can be the default one') | 595 | validates_uniqueness_of :is_default, :if => (lambda do |environment| environment.is_default? end), :message => N_('Only one Virtual Community can be the default one') |
| 582 | 596 | ||
| 583 | - validates_format_of :contact_email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda { |record| ! record.contact_email.blank? }) | 597 | + validates_format_of :contact_email, :noreply_email, :with => Noosfero::Constants::EMAIL_FORMAT, :allow_blank => true |
| 584 | 598 | ||
| 585 | xss_terminate :only => [ :message_for_disabled_enterprise ], :with => 'white_list', :on => 'validation' | 599 | xss_terminate :only => [ :message_for_disabled_enterprise ], :with => 'white_list', :on => 'validation' |
| 586 | 600 | ||
| @@ -768,7 +782,7 @@ class Environment < ActiveRecord::Base | @@ -768,7 +782,7 @@ class Environment < ActiveRecord::Base | ||
| 768 | end | 782 | end |
| 769 | 783 | ||
| 770 | def notification_emails | 784 | def notification_emails |
| 771 | - [contact_email.blank? ? nil : contact_email].compact + admins.map(&:email) | 785 | + [noreply_email.blank? ? nil : noreply_email].compact + admins.map(&:email) |
| 772 | end | 786 | end |
| 773 | 787 | ||
| 774 | after_create :create_templates | 788 | after_create :create_templates |
app/models/environment_statistics_block.rb
| 1 | +# TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
| 2 | +# the Noosfero core soon, see ActionItem3045 | ||
| 3 | + | ||
| 1 | class EnvironmentStatisticsBlock < Block | 4 | class EnvironmentStatisticsBlock < Block |
| 2 | 5 | ||
| 3 | def self.description | 6 | def self.description |
| 4 | - _('Environment stastistics') | 7 | + _('Environment stastistics (DEPRECATED)') |
| 5 | end | 8 | end |
| 6 | 9 | ||
| 7 | def default_title | 10 | def default_title |
app/models/event.rb
| @@ -43,15 +43,12 @@ class Event < Article | @@ -43,15 +43,12 @@ class Event < Article | ||
| 43 | scope :next_events_from_month, lambda { |date| | 43 | scope :next_events_from_month, lambda { |date| |
| 44 | date_temp = date.strftime("%Y-%m-%d") | 44 | date_temp = date.strftime("%Y-%m-%d") |
| 45 | { :conditions => ["start_date >= ?","#{date_temp}"], | 45 | { :conditions => ["start_date >= ?","#{date_temp}"], |
| 46 | - :limit => 10, | ||
| 47 | :order => 'start_date ASC' | 46 | :order => 'start_date ASC' |
| 48 | } | 47 | } |
| 49 | } | 48 | } |
| 50 | 49 | ||
| 51 | scope :by_month, lambda { |date| | 50 | scope :by_month, lambda { |date| |
| 52 | - date_temp = date.strftime("%Y-%m") | ||
| 53 | { :conditions => ["EXTRACT(YEAR FROM start_date) = ? AND EXTRACT(MONTH FROM start_date) = ?",date.year,date.month], | 51 | { :conditions => ["EXTRACT(YEAR FROM start_date) = ? AND EXTRACT(MONTH FROM start_date) = ?",date.year,date.month], |
| 54 | - :limit => 10, | ||
| 55 | :order => 'start_date ASC' | 52 | :order => 'start_date ASC' |
| 56 | } | 53 | } |
| 57 | } | 54 | } |
app/models/forum.rb
| @@ -7,6 +7,7 @@ class Forum < Folder | @@ -7,6 +7,7 @@ class Forum < Folder | ||
| 7 | 7 | ||
| 8 | settings_items :terms_of_use, :type => :string, :default => "" | 8 | settings_items :terms_of_use, :type => :string, :default => "" |
| 9 | settings_items :has_terms_of_use, :type => :boolean, :default => false | 9 | settings_items :has_terms_of_use, :type => :boolean, :default => false |
| 10 | + settings_items :allows_members_to_create_topics, :type => :boolean, :default => false | ||
| 10 | has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people' | 11 | has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people' |
| 11 | 12 | ||
| 12 | before_save do |forum| | 13 | before_save do |forum| |
| @@ -68,4 +69,11 @@ class Forum < Folder | @@ -68,4 +69,11 @@ class Forum < Folder | ||
| 68 | self.users_with_agreement.exists? user | 69 | self.users_with_agreement.exists? user |
| 69 | end | 70 | end |
| 70 | 71 | ||
| 72 | + def can_create_topic?(user, profile) | ||
| 73 | + return profile.community? && profile.members.include?(user) && self.allows_members_to_create_topics | ||
| 74 | + end | ||
| 75 | + | ||
| 76 | + def allow_create?(user) | ||
| 77 | + super || can_create_topic?(user, profile) | ||
| 78 | + end | ||
| 71 | end | 79 | end |
app/models/friendship.rb
| 1 | class Friendship < ActiveRecord::Base | 1 | class Friendship < ActiveRecord::Base |
| 2 | track_actions :new_friendship, :after_create, :keep_params => ["friend.name", "friend.url", "friend.profile_custom_icon"], :custom_user => :person | 2 | track_actions :new_friendship, :after_create, :keep_params => ["friend.name", "friend.url", "friend.profile_custom_icon"], :custom_user => :person |
| 3 | - | 3 | + |
| 4 | + extend CacheCounterHelper | ||
| 5 | + | ||
| 4 | belongs_to :person, :foreign_key => :person_id | 6 | belongs_to :person, :foreign_key => :person_id |
| 5 | belongs_to :friend, :class_name => 'Person', :foreign_key => 'friend_id' | 7 | belongs_to :friend, :class_name => 'Person', :foreign_key => 'friend_id' |
| 8 | + | ||
| 9 | + after_create do |friendship| | ||
| 10 | + update_cache_counter(:friends_count, friendship.person, 1) | ||
| 11 | + update_cache_counter(:friends_count, friendship.friend, 1) | ||
| 12 | + end | ||
| 13 | + | ||
| 14 | + after_destroy do |friendship| | ||
| 15 | + update_cache_counter(:friends_count, friendship.person, -1) | ||
| 16 | + update_cache_counter(:friends_count, friendship.friend, -1) | ||
| 17 | + end | ||
| 6 | end | 18 | end |
app/models/layout_template.rb
| @@ -16,15 +16,15 @@ class LayoutTemplate | @@ -16,15 +16,15 @@ class LayoutTemplate | ||
| 16 | end | 16 | end |
| 17 | 17 | ||
| 18 | def name | 18 | def name |
| 19 | - @config['name'] | 19 | + _ @config['name'] |
| 20 | end | 20 | end |
| 21 | 21 | ||
| 22 | def title | 22 | def title |
| 23 | - @config['title'] | 23 | + _ @config['title'] |
| 24 | end | 24 | end |
| 25 | 25 | ||
| 26 | def description | 26 | def description |
| 27 | - @config['description'] | 27 | + _ @config['description'] |
| 28 | end | 28 | end |
| 29 | 29 | ||
| 30 | def number_of_boxes | 30 | def number_of_boxes |
app/models/link_list_block.rb
| @@ -72,6 +72,8 @@ class LinkListBlock < Block | @@ -72,6 +72,8 @@ class LinkListBlock < Block | ||
| 72 | def expand_address(address) | 72 | def expand_address(address) |
| 73 | add = if owner.respond_to?(:identifier) | 73 | add = if owner.respond_to?(:identifier) |
| 74 | address.gsub('{profile}', owner.identifier) | 74 | address.gsub('{profile}', owner.identifier) |
| 75 | + elsif owner.is_a?(Environment) && owner.enabled?('use_portal_community') && owner.portal_community | ||
| 76 | + address.gsub('{portal}', owner.portal_community.identifier) | ||
| 75 | else | 77 | else |
| 76 | address | 78 | address |
| 77 | end | 79 | end |
app/models/main_block.rb
app/models/members_block.rb
| @@ -38,4 +38,15 @@ class MembersBlock < ProfileListBlock | @@ -38,4 +38,15 @@ class MembersBlock < ProfileListBlock | ||
| 38 | } | 38 | } |
| 39 | end | 39 | end |
| 40 | 40 | ||
| 41 | + def cache_key(language='en', user=nil) | ||
| 42 | + logged = '' | ||
| 43 | + if user | ||
| 44 | + logged += '-logged-in' | ||
| 45 | + if user.is_member_of? self.owner | ||
| 46 | + logged += '-member' | ||
| 47 | + end | ||
| 48 | + end | ||
| 49 | + super + logged | ||
| 50 | + end | ||
| 51 | + | ||
| 41 | end | 52 | end |
app/models/national_region.rb
| @@ -12,7 +12,7 @@ class NationalRegion < ActiveRecord::Base | @@ -12,7 +12,7 @@ class NationalRegion < ActiveRecord::Base | ||
| 12 | adtional_contions = ""; | 12 | adtional_contions = ""; |
| 13 | 13 | ||
| 14 | if like | 14 | if like |
| 15 | - operator = "like" | 15 | + operator = "ilike" |
| 16 | find_return = :all | 16 | find_return = :all |
| 17 | end | 17 | end |
| 18 | 18 | ||
| @@ -41,7 +41,7 @@ class NationalRegion < ActiveRecord::Base | @@ -41,7 +41,7 @@ class NationalRegion < ActiveRecord::Base | ||
| 41 | find_return = :first | 41 | find_return = :first |
| 42 | 42 | ||
| 43 | if like | 43 | if like |
| 44 | - operator = "like" | 44 | + operator = "ilike" |
| 45 | find_return = :all | 45 | find_return = :all |
| 46 | end | 46 | end |
| 47 | 47 |
app/models/organization.rb
| @@ -28,18 +28,7 @@ class Organization < Profile | @@ -28,18 +28,7 @@ class Organization < Profile | ||
| 28 | 28 | ||
| 29 | has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source' | 29 | has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source' |
| 30 | 30 | ||
| 31 | - scope :more_popular, | ||
| 32 | - :select => "#{Profile.qualified_column_names}, count(resource_id) as total", | ||
| 33 | - :group => Profile.qualified_column_names, | ||
| 34 | - :joins => "LEFT OUTER JOIN role_assignments ON profiles.id = role_assignments.resource_id", | ||
| 35 | - :order => "total DESC" | ||
| 36 | - | ||
| 37 | - scope :more_active, | ||
| 38 | - :select => "#{Profile.qualified_column_names}, count(action_tracker.id) as total", | ||
| 39 | - :joins => "LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.target_id", | ||
| 40 | - :group => Profile.qualified_column_names, | ||
| 41 | - :order => 'total DESC', | ||
| 42 | - :conditions => ['action_tracker.created_at >= ? OR action_tracker.id IS NULL', ActionTracker::Record::RECENT_DELAY.days.ago] | 31 | + scope :more_popular, :order => 'members_count DESC' |
| 43 | 32 | ||
| 44 | def validation_methodology | 33 | def validation_methodology |
| 45 | self.validation_info ? self.validation_info.validation_methodology : nil | 34 | self.validation_info ? self.validation_info.validation_methodology : nil |
app/models/person.rb
| @@ -59,18 +59,7 @@ class Person < Profile | @@ -59,18 +59,7 @@ class Person < Profile | ||
| 59 | has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people' | 59 | has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people' |
| 60 | has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions' | 60 | has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions' |
| 61 | 61 | ||
| 62 | - scope :more_popular, | ||
| 63 | - :select => "#{Profile.qualified_column_names}, count(friend_id) as total", | ||
| 64 | - :group => Profile.qualified_column_names, | ||
| 65 | - :joins => "LEFT OUTER JOIN friendships on profiles.id = friendships.person_id", | ||
| 66 | - :order => "total DESC" | ||
| 67 | - | ||
| 68 | - scope :more_active, | ||
| 69 | - :select => "#{Profile.qualified_column_names}, count(action_tracker.id) as total", | ||
| 70 | - :joins => "LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.user_id", | ||
| 71 | - :group => Profile.qualified_column_names, | ||
| 72 | - :order => 'total DESC', | ||
| 73 | - :conditions => ['action_tracker.created_at >= ? OR action_tracker.id IS NULL', ActionTracker::Record::RECENT_DELAY.days.ago] | 62 | + scope :more_popular, :order => 'friends_count DESC' |
| 74 | 63 | ||
| 75 | scope :abusers, :joins => :abuse_complaints, :conditions => ['tasks.status = 3'], :select => 'DISTINCT profiles.*' | 64 | scope :abusers, :joins => :abuse_complaints, :conditions => ['tasks.status = 3'], :select => 'DISTINCT profiles.*' |
| 76 | scope :non_abusers, :joins => "LEFT JOIN tasks ON profiles.id = tasks.requestor_id AND tasks.type='AbuseComplaint'", :conditions => ["tasks.status != 3 OR tasks.id is NULL"], :select => "DISTINCT profiles.*" | 65 | scope :non_abusers, :joins => "LEFT JOIN tasks ON profiles.id = tasks.requestor_id AND tasks.type='AbuseComplaint'", :conditions => ["tasks.status != 3 OR tasks.id is NULL"], :select => "DISTINCT profiles.*" |
| @@ -492,6 +481,17 @@ class Person < Profile | @@ -492,6 +481,17 @@ class Person < Profile | ||
| 492 | gravatar_profile_image_url(self.email, :size=>20, :d => gravatar_default) | 481 | gravatar_profile_image_url(self.email, :size=>20, :d => gravatar_default) |
| 493 | end | 482 | end |
| 494 | 483 | ||
| 484 | + settings_items :last_notification, :type => DateTime | ||
| 485 | + settings_items :notification_time, :type => :integer, :default => 0 | ||
| 486 | + | ||
| 487 | + def notifier | ||
| 488 | + @notifier ||= PersonNotifier.new(self) | ||
| 489 | + end | ||
| 490 | + | ||
| 491 | + after_update do |person| | ||
| 492 | + person.notifier.reschedule_next_notification_mail | ||
| 493 | + end | ||
| 494 | + | ||
| 495 | protected | 495 | protected |
| 496 | 496 | ||
| 497 | def followed_by?(profile) | 497 | def followed_by?(profile) |
| @@ -0,0 +1,89 @@ | @@ -0,0 +1,89 @@ | ||
| 1 | +class PersonNotifier | ||
| 2 | + | ||
| 3 | + def initialize(person) | ||
| 4 | + @person = person | ||
| 5 | + end | ||
| 6 | + | ||
| 7 | + def self.schedule_all_next_notification_mail | ||
| 8 | + Delayed::Job.enqueue(NotifyAllJob.new) unless NotifyAllJob.exists? | ||
| 9 | + end | ||
| 10 | + | ||
| 11 | + def schedule_next_notification_mail | ||
| 12 | + dispatch_notification_mail if !NotifyJob.exists?(@person.id) | ||
| 13 | + end | ||
| 14 | + | ||
| 15 | + def dispatch_notification_mail | ||
| 16 | + Delayed::Job.enqueue(NotifyJob.new(@person.id), nil, @person.notification_time.hours.from_now) if @person.notification_time>0 | ||
| 17 | + end | ||
| 18 | + | ||
| 19 | + def reschedule_next_notification_mail | ||
| 20 | + return nil unless @person.setting_changed?(:notification_time) || @person.setting_changed?(:last_notification) | ||
| 21 | + NotifyJob.find(@person.id).delete_all | ||
| 22 | + schedule_next_notification_mail | ||
| 23 | + end | ||
| 24 | + | ||
| 25 | + def notify | ||
| 26 | + if @person.notification_time && @person.notification_time > 0 | ||
| 27 | + from = @person.last_notification || DateTime.now - @person.notification_time.hours | ||
| 28 | + notifications = @person.tracked_notifications.find(:all, :conditions => ["created_at > ?", from]) | ||
| 29 | + Noosfero.with_locale @person.environment.default_language do | ||
| 30 | + Mailer::deliver_content_summary(@person, notifications) unless notifications.empty? | ||
| 31 | + end | ||
| 32 | + @person.settings[:last_notification] = DateTime.now | ||
| 33 | + @person.save! | ||
| 34 | + end | ||
| 35 | + end | ||
| 36 | + | ||
| 37 | + class NotifyAllJob | ||
| 38 | + def self.exists? | ||
| 39 | + Delayed::Job.where(:handler => "--- !ruby/object:PersonNotifier::NotifyAllJob {}\n\n").count > 0 | ||
| 40 | + end | ||
| 41 | + | ||
| 42 | + def perform | ||
| 43 | + Person.find_each {|person| person.notifier.schedule_next_notification_mail } | ||
| 44 | + end | ||
| 45 | + end | ||
| 46 | + | ||
| 47 | + class NotifyJob < Struct.new(:person_id) | ||
| 48 | + | ||
| 49 | + def self.exists?(person_id) | ||
| 50 | + !find(person_id).empty? | ||
| 51 | + end | ||
| 52 | + | ||
| 53 | + def self.find(person_id) | ||
| 54 | + Delayed::Job.where(:handler => "--- !ruby/struct:PersonNotifier::NotifyJob \nperson_id: #{person_id}\n") | ||
| 55 | + end | ||
| 56 | + | ||
| 57 | + def perform | ||
| 58 | + Person.find(person_id).notifier.notify | ||
| 59 | + end | ||
| 60 | + | ||
| 61 | + def on_permanent_failure | ||
| 62 | + person = Person.find(person_id) | ||
| 63 | + person.notifier.dispatch_notification_mail | ||
| 64 | + end | ||
| 65 | + | ||
| 66 | + end | ||
| 67 | + | ||
| 68 | + class Mailer < ActionMailer::Base | ||
| 69 | + | ||
| 70 | + add_template_helper(PersonNotifierHelper) | ||
| 71 | + | ||
| 72 | + def session | ||
| 73 | + {:theme => nil} | ||
| 74 | + end | ||
| 75 | + | ||
| 76 | + def content_summary(person, notifications) | ||
| 77 | + @current_theme = 'default' | ||
| 78 | + @profile = person | ||
| 79 | + recipients person.email | ||
| 80 | + from "#{@profile.environment.name} <#{@profile.environment.contact_email}>" | ||
| 81 | + subject _("[%s] Network Activity") % [@profile.environment.name] | ||
| 82 | + body :recipient => @profile.nickname || @profile.name, | ||
| 83 | + :environment => @profile.environment.name, | ||
| 84 | + :url => @profile.environment.top_url, | ||
| 85 | + :notifications => notifications | ||
| 86 | + content_type "text/html" | ||
| 87 | + end | ||
| 88 | + end | ||
| 89 | +end |
app/models/profile.rb
| @@ -100,10 +100,6 @@ class Profile < ActiveRecord::Base | @@ -100,10 +100,6 @@ class Profile < ActiveRecord::Base | ||
| 100 | members.order(:name) | 100 | members.order(:name) |
| 101 | end | 101 | end |
| 102 | 102 | ||
| 103 | - def members_count | ||
| 104 | - members.count | ||
| 105 | - end | ||
| 106 | - | ||
| 107 | class << self | 103 | class << self |
| 108 | def count_with_distinct(*args) | 104 | def count_with_distinct(*args) |
| 109 | options = args.last || {} | 105 | options = args.last || {} |
| @@ -126,10 +122,11 @@ class Profile < ActiveRecord::Base | @@ -126,10 +122,11 @@ class Profile < ActiveRecord::Base | ||
| 126 | 122 | ||
| 127 | scope :visible, :conditions => { :visible => true } | 123 | scope :visible, :conditions => { :visible => true } |
| 128 | scope :public, :conditions => { :visible => true, :public_profile => true } | 124 | scope :public, :conditions => { :visible => true, :public_profile => true } |
| 129 | - # Subclasses must override these methods | 125 | + |
| 126 | + # Subclasses must override this method | ||
| 130 | scope :more_popular | 127 | scope :more_popular |
| 131 | - scope :more_active | ||
| 132 | 128 | ||
| 129 | + scope :more_active, :order => 'activities_count DESC' | ||
| 133 | scope :more_recent, :order => "created_at DESC" | 130 | scope :more_recent, :order => "created_at DESC" |
| 134 | 131 | ||
| 135 | acts_as_trackable :dependent => :destroy | 132 | acts_as_trackable :dependent => :destroy |
| @@ -626,10 +623,10 @@ private :generate_url, :url_options | @@ -626,10 +623,10 @@ private :generate_url, :url_options | ||
| 626 | # Adds a person as member of this Profile. | 623 | # Adds a person as member of this Profile. |
| 627 | def add_member(person) | 624 | def add_member(person) |
| 628 | if self.has_members? | 625 | if self.has_members? |
| 629 | - if self.closed? && members_count > 0 | 626 | + if self.closed? && members.count > 0 |
| 630 | AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person) | 627 | AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person) |
| 631 | else | 628 | else |
| 632 | - self.affiliate(person, Profile::Roles.admin(environment.id)) if members_count == 0 | 629 | + self.affiliate(person, Profile::Roles.admin(environment.id)) if members.count == 0 |
| 633 | self.affiliate(person, Profile::Roles.member(environment.id)) | 630 | self.affiliate(person, Profile::Roles.member(environment.id)) |
| 634 | end | 631 | end |
| 635 | else | 632 | else |
app/models/scrap.rb
| @@ -17,7 +17,7 @@ class Scrap < ActiveRecord::Base | @@ -17,7 +17,7 @@ class Scrap < ActiveRecord::Base | ||
| 17 | 17 | ||
| 18 | scope :not_replies, :conditions => {:scrap_id => nil} | 18 | scope :not_replies, :conditions => {:scrap_id => nil} |
| 19 | 19 | ||
| 20 | - track_actions :leave_scrap, :after_create, :keep_params => ['sender.name', 'content', 'receiver.name', 'receiver.url'], :if => Proc.new{|s| s.sender != s.receiver && s.sender != s.top_root.receiver}, :custom_target => :action_tracker_target | 20 | + track_actions :leave_scrap, :after_create, :keep_params => ['sender.name', 'content', 'receiver.name', 'receiver.url'], :if => Proc.new{|s| s.sender != s.receiver && s.sender != s.top_root.receiver}, :custom_target => :action_tracker_target |
| 21 | 21 | ||
| 22 | track_actions :leave_scrap_to_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.sender == s.receiver} | 22 | track_actions :leave_scrap_to_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.sender == s.receiver} |
| 23 | 23 | ||
| @@ -57,4 +57,21 @@ class Scrap < ActiveRecord::Base | @@ -57,4 +57,21 @@ class Scrap < ActiveRecord::Base | ||
| 57 | sender != receiver && (is_root? ? root.receiver.receives_scrap_notification? : receiver.receives_scrap_notification?) | 57 | sender != receiver && (is_root? ? root.receiver.receives_scrap_notification? : receiver.receives_scrap_notification?) |
| 58 | end | 58 | end |
| 59 | 59 | ||
| 60 | + class Notifier < ActionMailer::Base | ||
| 61 | + def mail(scrap) | ||
| 62 | + sender, receiver = scrap.sender, scrap.receiver | ||
| 63 | + recipients receiver.email | ||
| 64 | + | ||
| 65 | + from "#{sender.environment.name} <#{sender.environment.noreply_email}>" | ||
| 66 | + subject _("[%s] You received a scrap!") % [sender.environment.name] | ||
| 67 | + body :recipient => receiver.name, | ||
| 68 | + :sender => sender.name, | ||
| 69 | + :sender_link => sender.url, | ||
| 70 | + :scrap_content => scrap.content, | ||
| 71 | + :wall_url => scrap.scrap_wall_url, | ||
| 72 | + :environment => sender.environment.name, | ||
| 73 | + :url => sender.environment.top_url | ||
| 74 | + end | ||
| 75 | + end | ||
| 76 | + | ||
| 60 | end | 77 | end |
app/models/text_article.rb
| @@ -22,4 +22,23 @@ class TextArticle < Article | @@ -22,4 +22,23 @@ class TextArticle < Article | ||
| 22 | def can_display_versions? | 22 | def can_display_versions? |
| 23 | true | 23 | true |
| 24 | end | 24 | end |
| 25 | + | ||
| 26 | + before_save :set_relative_path | ||
| 27 | + | ||
| 28 | + def set_relative_path | ||
| 29 | + parsed = Hpricot(self.body.to_s) | ||
| 30 | + parsed.search('img[@src]').map { |i| change_element_path(i, 'src') } | ||
| 31 | + parsed.search('a[@href]').map { |i| change_element_path(i, 'href') } | ||
| 32 | + self.body = parsed.to_s | ||
| 33 | + end | ||
| 34 | + | ||
| 35 | + def change_element_path(el, attribute) | ||
| 36 | + fullpath = /(https?):\/\/(#{environment.default_hostname})(:\d+)?(\/.*)/.match(el[attribute]) | ||
| 37 | + if fullpath | ||
| 38 | + domain = fullpath[2] | ||
| 39 | + path = fullpath[4] | ||
| 40 | + el[attribute] = path if domain == environment.default_hostname | ||
| 41 | + end | ||
| 42 | + end | ||
| 43 | + | ||
| 25 | end | 44 | end |
app/models/theme.rb
| @@ -42,17 +42,25 @@ class Theme | @@ -42,17 +42,25 @@ class Theme | ||
| 42 | end | 42 | end |
| 43 | 43 | ||
| 44 | def approved_themes(owner) | 44 | def approved_themes(owner) |
| 45 | - Dir.glob(File.join(system_themes_dir, '*')).select do |item| | ||
| 46 | - if File.exists?( File.join(item, 'theme.yml') ) | ||
| 47 | - config = YAML.load_file(File.join(item, 'theme.yml')) | ||
| 48 | - (config['owner_type'] == owner.class.base_class.name) && | ||
| 49 | - (config['owner_id'] == owner.id) || config['public'] | 45 | + Dir.glob(File.join(system_themes_dir, '*')).map do |item| |
| 46 | + next unless File.exists? File.join(item, 'theme.yml') | ||
| 47 | + id = File.basename item | ||
| 48 | + config = YAML.load_file File.join(item, 'theme.yml') | ||
| 49 | + | ||
| 50 | + approved = config['public'] | ||
| 51 | + unless approved | ||
| 52 | + begin | ||
| 53 | + approved = owner.kind_of?(config['owner_type'].constantize) | ||
| 54 | + rescue | ||
| 55 | + end | ||
| 56 | + approved &&= config['owner_id'] == owner.id if config['owner_id'].present? | ||
| 50 | end | 57 | end |
| 51 | - end.map do |desc| | ||
| 52 | - new(File.basename(desc)) | 58 | + |
| 59 | + [id, config] if approved | ||
| 60 | + end.compact.map do |id, config| | ||
| 61 | + new id, config | ||
| 53 | end | 62 | end |
| 54 | end | 63 | end |
| 55 | - | ||
| 56 | end | 64 | end |
| 57 | 65 | ||
| 58 | class DuplicatedIdentifier < Exception; end | 66 | class DuplicatedIdentifier < Exception; end |
app/models/uploaded_file.rb
| @@ -16,15 +16,12 @@ class UploadedFile < Article | @@ -16,15 +16,12 @@ class UploadedFile < Article | ||
| 16 | 16 | ||
| 17 | include ShortFilename | 17 | include ShortFilename |
| 18 | 18 | ||
| 19 | - settings_items :title, :type => 'string' | ||
| 20 | - xss_terminate :only => [ :title ] | ||
| 21 | - | ||
| 22 | - def title_with_default | ||
| 23 | - title_without_default || short_filename(name, 60) | 19 | + def title |
| 20 | + if self.name.present? then self.name else self.filename end | ||
| 21 | + end | ||
| 22 | + def title= value | ||
| 23 | + self.name = value | ||
| 24 | end | 24 | end |
| 25 | - alias_method_chain :title, :default | ||
| 26 | - | ||
| 27 | - validates_size_of :title, :maximum => 60, :if => (lambda { |file| !file.title.blank? }) | ||
| 28 | 25 | ||
| 29 | sanitize_filename | 26 | sanitize_filename |
| 30 | 27 | ||
| @@ -36,10 +33,6 @@ class UploadedFile < Article | @@ -36,10 +33,6 @@ class UploadedFile < Article | ||
| 36 | self.image? ? self.full_filename(:display).to_s.gsub(Rails.root.join('public').to_s, '') : nil | 33 | self.image? ? self.full_filename(:display).to_s.gsub(Rails.root.join('public').to_s, '') : nil |
| 37 | end | 34 | end |
| 38 | 35 | ||
| 39 | - def display_title | ||
| 40 | - title.blank? ? name : title | ||
| 41 | - end | ||
| 42 | - | ||
| 43 | def first_paragraph | 36 | def first_paragraph |
| 44 | '' | 37 | '' |
| 45 | end | 38 | end |
| @@ -113,7 +106,7 @@ class UploadedFile < Article | @@ -113,7 +106,7 @@ class UploadedFile < Article | ||
| 113 | alias :orig_set_filename :filename= | 106 | alias :orig_set_filename :filename= |
| 114 | def filename=(value) | 107 | def filename=(value) |
| 115 | orig_set_filename(value) | 108 | orig_set_filename(value) |
| 116 | - self.name = self.filename | 109 | + self.name ||= self.filename |
| 117 | end | 110 | end |
| 118 | 111 | ||
| 119 | def download_headers | 112 | def download_headers |
app/models/user.rb
| @@ -63,6 +63,44 @@ class User < ActiveRecord::Base | @@ -63,6 +63,44 @@ class User < ActiveRecord::Base | ||
| 63 | self.person.preferred_domain && self.person.preferred_domain.name || self.environment.default_hostname(true) | 63 | self.person.preferred_domain && self.person.preferred_domain.name || self.environment.default_hostname(true) |
| 64 | end | 64 | end |
| 65 | 65 | ||
| 66 | + class Mailer < ActionMailer::Base | ||
| 67 | + def activation_email_notify(user) | ||
| 68 | + user_email = "#{user.login}@#{user.email_domain}" | ||
| 69 | + recipients user_email | ||
| 70 | + from "#{user.environment.name} <#{user.environment.noreply_email}>" | ||
| 71 | + subject _("[%{environment}] Welcome to %{environment} mail!") % { :environment => user.environment.name } | ||
| 72 | + body :name => user.name, | ||
| 73 | + :email => user_email, | ||
| 74 | + :webmail => MailConf.webmail_url(user.login, user.email_domain), | ||
| 75 | + :environment => user.environment.name, | ||
| 76 | + :url => url_for(:host => user.environment.default_hostname, :controller => 'home') | ||
| 77 | + end | ||
| 78 | + | ||
| 79 | + def activation_code(user) | ||
| 80 | + recipients user.email | ||
| 81 | + | ||
| 82 | + from "#{user.environment.name} <#{user.environment.noreply_email}>" | ||
| 83 | + subject _("[%s] Activate your account") % [user.environment.name] | ||
| 84 | + body :recipient => user.name, | ||
| 85 | + :activation_code => user.activation_code, | ||
| 86 | + :environment => user.environment.name, | ||
| 87 | + :url => user.environment.top_url, | ||
| 88 | + :redirection => (true if user.return_to) | ||
| 89 | + end | ||
| 90 | + | ||
| 91 | + def signup_welcome_email(user) | ||
| 92 | + email_body = user.environment.signup_welcome_text_body.gsub('{user_name}', user.name) | ||
| 93 | + email_subject = user.environment.signup_welcome_text_subject | ||
| 94 | + | ||
| 95 | + content_type 'text/html' | ||
| 96 | + recipients user.email | ||
| 97 | + | ||
| 98 | + from "#{user.environment.name} <#{user.environment.noreply_email}>" | ||
| 99 | + subject email_subject.blank? ? _("Welcome to environment %s") % [user.environment.name] : email_subject | ||
| 100 | + body email_body | ||
| 101 | + end | ||
| 102 | + end | ||
| 103 | + | ||
| 66 | def signup! | 104 | def signup! |
| 67 | User.transaction do | 105 | User.transaction do |
| 68 | self.save! | 106 | self.save! |
| @@ -159,7 +197,7 @@ class User < ActiveRecord::Base | @@ -159,7 +197,7 @@ class User < ActiveRecord::Base | ||
| 159 | encryption_methods[sym] = block | 197 | encryption_methods[sym] = block |
| 160 | end | 198 | end |
| 161 | 199 | ||
| 162 | - # the encryption method used for this instance | 200 | + # the encryption method used for this instance |
| 163 | def encryption_method | 201 | def encryption_method |
| 164 | (password_type || User.system_encryption_method).to_sym | 202 | (password_type || User.system_encryption_method).to_sym |
| 165 | end | 203 | end |
| @@ -202,7 +240,7 @@ class User < ActiveRecord::Base | @@ -202,7 +240,7 @@ class User < ActiveRecord::Base | ||
| 202 | end | 240 | end |
| 203 | 241 | ||
| 204 | def remember_token? | 242 | def remember_token? |
| 205 | - remember_token_expires_at && Time.now.utc < remember_token_expires_at | 243 | + remember_token_expires_at && Time.now.utc < remember_token_expires_at |
| 206 | end | 244 | end |
| 207 | 245 | ||
| 208 | # These create and unset the fields required for remembering users between browser closes | 246 | # These create and unset the fields required for remembering users between browser closes |
| @@ -231,7 +269,7 @@ class User < ActiveRecord::Base | @@ -231,7 +269,7 @@ class User < ActiveRecord::Base | ||
| 231 | raise IncorrectPassword unless self.authenticated?(current) | 269 | raise IncorrectPassword unless self.authenticated?(current) |
| 232 | self.force_change_password!(new, confirmation) | 270 | self.force_change_password!(new, confirmation) |
| 233 | end | 271 | end |
| 234 | - | 272 | + |
| 235 | # Changes the password of a user without asking for the old password. This | 273 | # Changes the password of a user without asking for the old password. This |
| 236 | # method is intended to be used by the "I forgot my password", and must be | 274 | # method is intended to be used by the "I forgot my password", and must be |
| 237 | # used with care. | 275 | # used with care. |
| @@ -302,7 +340,7 @@ class User < ActiveRecord::Base | @@ -302,7 +340,7 @@ class User < ActiveRecord::Base | ||
| 302 | end | 340 | end |
| 303 | 341 | ||
| 304 | protected | 342 | protected |
| 305 | - # before filter | 343 | + # before filter |
| 306 | def encrypt_password | 344 | def encrypt_password |
| 307 | return if password.blank? | 345 | return if password.blank? |
| 308 | self.salt ||= Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record? | 346 | self.salt ||= Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record? |
app/sweepers/profile_sweeper.rb
| @@ -8,6 +8,8 @@ class ProfileSweeper # < ActiveRecord::Observer | @@ -8,6 +8,8 @@ class ProfileSweeper # < ActiveRecord::Observer | ||
| 8 | end | 8 | end |
| 9 | 9 | ||
| 10 | def after_create(profile) | 10 | def after_create(profile) |
| 11 | + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
| 12 | + # the Noosfero core soon, see ActionItem3045 | ||
| 11 | expire_statistics_block_cache(profile) | 13 | expire_statistics_block_cache(profile) |
| 12 | end | 14 | end |
| 13 | 15 | ||
| @@ -29,6 +31,8 @@ protected | @@ -29,6 +31,8 @@ protected | ||
| 29 | expire_blogs(profile) if profile.organization? | 31 | expire_blogs(profile) if profile.organization? |
| 30 | end | 32 | end |
| 31 | 33 | ||
| 34 | + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
| 35 | + # the Noosfero core soon, see ActionItem3045 | ||
| 32 | def expire_statistics_block_cache(profile) | 36 | def expire_statistics_block_cache(profile) |
| 33 | blocks = profile.environment.blocks.select { |b| b.kind_of?(EnvironmentStatisticsBlock) } | 37 | blocks = profile.environment.blocks.select { |b| b.kind_of?(EnvironmentStatisticsBlock) } |
| 34 | BlockSweeper.expire_blocks(blocks) | 38 | BlockSweeper.expire_blocks(blocks) |
app/views/account/_identifier_status.html.erb
| 1 | <div class='status-identifier'> | 1 | <div class='status-identifier'> |
| 2 | - <p><span class='<%= @status_class %>'><%= @status %></span></p> | 2 | + |
| 3 | + <span class='<%= @status_class %>'><%= @status %></span> | ||
| 4 | + <% if @suggested_usernames %> | ||
| 5 | + <div class='suggested_usernames'> | ||
| 6 | + <%= _('Available: ') %> | ||
| 7 | + <% @suggested_usernames.each do |username| %> | ||
| 8 | + <a href='#'><%= username %></a> | ||
| 9 | + <% end %> | ||
| 10 | + </div> | ||
| 11 | + <% end %> | ||
| 3 | <script type="text/javascript"> | 12 | <script type="text/javascript"> |
| 4 | jQuery('#user_login').removeClass('<%= validation_classes %>'); | 13 | jQuery('#user_login').removeClass('<%= validation_classes %>'); |
| 5 | jQuery('#user_login').addClass('<%= @status_class %>'); | 14 | jQuery('#user_login').addClass('<%= @status_class %>'); |
| 15 | + jQuery('.suggested_usernames a').click(function(e) { | ||
| 16 | + e.preventDefault(); | ||
| 17 | + | ||
| 18 | + fill_username(this.innerHTML); | ||
| 19 | + }); | ||
| 6 | </script> | 20 | </script> |
| 7 | </div> | 21 | </div> |
app/views/account/_signup_form.html.erb
| @@ -7,6 +7,8 @@ | @@ -7,6 +7,8 @@ | ||
| 7 | 7 | ||
| 8 | <% @profile_data = @person %> | 8 | <% @profile_data = @person %> |
| 9 | 9 | ||
| 10 | +<%= javascript_include_tag('sign_up_password_rate') %> | ||
| 11 | + | ||
| 10 | <%= error_messages_for :user, :person, :header_message => _('The account could not be created') %> | 12 | <%= error_messages_for :user, :person, :header_message => _('The account could not be created') %> |
| 11 | 13 | ||
| 12 | <%= labelled_form_for :user, @user, :html => { :multipart => true, :id => 'signup-form', :honeypot => true } do |f| %> | 14 | <%= labelled_form_for :user, @user, :html => { :multipart => true, :id => 'signup-form', :honeypot => true } do |f| %> |
| @@ -35,24 +37,30 @@ | @@ -35,24 +37,30 @@ | ||
| 35 | <%= required text_field(:user, :login, :id => 'user_login', | 37 | <%= required text_field(:user, :login, :id => 'user_login', |
| 36 | :onchange => 'this.value = convToValidUsername(this.value);') %> | 38 | :onchange => 'this.value = convToValidUsername(this.value);') %> |
| 37 | <div id='url-check'><p> </p></div> | 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 | </div> | 41 | </div> |
| 39 | <%= content_tag(:small, _('Choose your login name carefully! It will be your network access and you will not be able to change it later.'), :id => 'signup-balloon') %> | 42 | <%= content_tag(:small, _('Choose your login name carefully! It will be your network access and you will not be able to change it later.'), :id => 'signup-balloon') %> |
| 40 | <br style="clear: both;" /> | 43 | <br style="clear: both;" /> |
| 41 | </div> | 44 | </div> |
| 42 | </div> | 45 | </div> |
| 43 | - <%= observe_field 'user_login', | ||
| 44 | - :url => { :action => 'check_url' }, | ||
| 45 | - :with => 'identifier', | ||
| 46 | - :update => 'url-check', | ||
| 47 | - :loading => "jQuery('#user_login').removeClass('#{validation_classes}').addClass('checking'); | ||
| 48 | - jQuery('#url-check').html('<p><span class=\"checking\">#{checking_message(:url)}</span></p>');", | ||
| 49 | - :complete => "jQuery('#user_login').removeClass('checking')" | ||
| 50 | - %> | ||
| 51 | - | 46 | + <%= javascript_include_tag "signup_form" %> |
| 52 | <div id='signup-password'> | 47 | <div id='signup-password'> |
| 53 | <%= required f.password_field(:password, :id => 'user_pw') %> | 48 | <%= required f.password_field(:password, :id => 'user_pw') %> |
| 54 | <%= content_tag(:small,_('Choose a password that you can remember easily. It must have at least 4 characters.'), :id => 'password-balloon') %> | 49 | <%= content_tag(:small,_('Choose a password that you can remember easily. It must have at least 4 characters.'), :id => 'password-balloon') %> |
| 55 | - <div id='fake-check'><p> </p></div> | 50 | + <div id='password-rate'> |
| 51 | + <p><span class="invalid hidden" id='result-short'> | ||
| 52 | + <%=_('Short') %> | ||
| 53 | + </span></p> | ||
| 54 | + <p><span class="invalid hidden" id='result-bad'> | ||
| 55 | + <%=_('Bad') %> | ||
| 56 | + </span></p> | ||
| 57 | + <p><span class="invalid hidden" id='result-good'> | ||
| 58 | + <%=_('Good') %> | ||
| 59 | + </span></p> | ||
| 60 | + <p><span class="invalid hidden" id='result-strong'> | ||
| 61 | + <%=_('Strong') %> | ||
| 62 | + </span></p> | ||
| 63 | + </div> | ||
| 56 | </div> | 64 | </div> |
| 57 | 65 | ||
| 58 | <div id='signup-password-confirmation'> | 66 | <div id='signup-password-confirmation'> |
| @@ -182,4 +190,9 @@ jQuery(function($) { | @@ -182,4 +190,9 @@ jQuery(function($) { | ||
| 182 | else $(this).addClass('validated'); | 190 | else $(this).addClass('validated'); |
| 183 | }); | 191 | }); |
| 184 | }); | 192 | }); |
| 193 | + | ||
| 194 | +function fill_username(element){ | ||
| 195 | + jQuery('#url-check').html("<p><span class='checking'><%= _('This login name is available') %></span></p>") | ||
| 196 | + jQuery('#user_login').val(element).addClass('validated').removeClass('invalid') | ||
| 197 | +} | ||
| 185 | </script> | 198 | </script> |
app/views/admin_panel/_site_info.html.erb
| 1 | <%= required labelled_form_field(_('Site name'), text_field(:environment, :name)) %> | 1 | <%= required labelled_form_field(_('Site name'), text_field(:environment, :name)) %> |
| 2 | <%= labelled_form_field(_('Contact email'), text_field(:environment, :contact_email)) %> | 2 | <%= labelled_form_field(_('Contact email'), text_field(:environment, :contact_email)) %> |
| 3 | +<%= labelled_form_field(_('No reply email'), text_field(:environment, :noreply_email)) %> | ||
| 3 | <% themes_options = Theme.system_themes.map {|theme| [theme.name, theme.id] }.sort %> | 4 | <% themes_options = Theme.system_themes.map {|theme| [theme.name, theme.id] }.sort %> |
| 4 | <%= labelled_form_field(_('Theme'), select(:environment, :theme, options_for_select(themes_options, environment.theme))) %> | 5 | <%= labelled_form_field(_('Theme'), select(:environment, :theme, options_for_select(themes_options, environment.theme))) %> |
| 5 | <%= required f.text_field(:reports_lower_bound, :size => 3) %> | 6 | <%= required f.text_field(:reports_lower_bound, :size => 3) %> |
app/views/blocks/profile_image.html.erb
| 1 | <div class="vcard"> | 1 | <div class="vcard"> |
| 2 | 2 | ||
| 3 | -<p><%= block.title %></p> | 3 | +<% if block.title.present? %> |
| 4 | + <p><%= block.title %></p> | ||
| 5 | +<% end %> | ||
| 4 | 6 | ||
| 5 | <div class="profile-big-image"> | 7 | <div class="profile-big-image"> |
| 6 | <div class="profile-big-image-inner1"> | 8 | <div class="profile-big-image-inner1"> |
app/views/box_organizer/_link_list_block.html.erb
| 1 | +<%= javascript_include_tag "edit-link-list.js" %> | ||
| 2 | + | ||
| 1 | <strong><%= _('Links') %></strong> | 3 | <strong><%= _('Links') %></strong> |
| 2 | <div id='edit-link-list-block'> | 4 | <div id='edit-link-list-block'> |
| 3 | -<table id='links' class='noborder'> | ||
| 4 | - <tr> | ||
| 5 | - <th><%= _('Icon') %></th> | ||
| 6 | - <th><%= _('Name') %></th> | ||
| 7 | - <th><%= _('Address') %></th> | ||
| 8 | - <th><%= _('Title') %></th> | ||
| 9 | - <th><%= _('Target') %></th> | ||
| 10 | - </tr> | ||
| 11 | - <% for link in @block.links do %> | ||
| 12 | - <tr> | ||
| 13 | - <td><%= icon_selector(link['icon']) %></td> | ||
| 14 | - <td><%= text_field_tag 'block[links][][name]', link[:name], :class => 'link-name', :maxlength => 20 %></td> | ||
| 15 | - <td class='cel-address'><%= text_field_tag 'block[links][][address]', link[:address], :class => 'link-address' %></td> | ||
| 16 | - <td><%= text_field_tag 'block[links][][title]', link[:title], :class => 'link-title' %></td> | ||
| 17 | - <td><%= select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, link[:target])) %></td> | ||
| 18 | - </tr> | ||
| 19 | - <% end %> | ||
| 20 | -</table> | 5 | + <ul class='link-list-header'> |
| 6 | + <li class='link-list-icon'><%= _('Icon') %></li> | ||
| 7 | + <li class='link-list-name'><%= _('Name') %></li> | ||
| 8 | + <li class='link-list-address'><%= _('Address') %></li> | ||
| 9 | + <li class='link-list-target'><%= _('Target') %></li> | ||
| 10 | + </ul> | ||
| 11 | + <ul id="dropable-link-list"> | ||
| 12 | + <% for link in @block.links do %> | ||
| 13 | + <li> | ||
| 14 | + <ul class="link-list-row"> | ||
| 15 | + <li> | ||
| 16 | + <%= icon_selector(link['icon']) %> | ||
| 17 | + </li> | ||
| 18 | + <li> | ||
| 19 | + <%= text_field_tag 'block[links][][name]', link[:name], :class => 'link-name', :maxlength => 20 %> | ||
| 20 | + </li> | ||
| 21 | + <li> | ||
| 22 | + <%= text_field_tag 'block[links][][address]', link[:address], :class => 'link-address' %> | ||
| 23 | + </li> | ||
| 24 | + <li> | ||
| 25 | + <%= select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, link[:target])) %> | ||
| 26 | + </li> | ||
| 27 | + <li> | ||
| 28 | + <%= button_without_text(:delete, _('Delete'), "#" , :class=>"delete-link-list-row") %> | ||
| 29 | + </li> | ||
| 30 | + </ul> | ||
| 31 | + </li> | ||
| 32 | + <% end %> | ||
| 33 | + </ul> | ||
| 34 | + <input type="hidden" id="page_url" value="<%=url_for(:action=>'search_autocomplete')%>" /> | ||
| 21 | </div> | 35 | </div> |
| 22 | 36 | ||
| 23 | <%= link_to_function(_('New link'), nil, :class => 'button icon-add with-text') do |page| | 37 | <%= link_to_function(_('New link'), nil, :class => 'button icon-add with-text') do |page| |
| 24 | - page.insert_html :bottom, 'links', j(content_tag('tr', | ||
| 25 | - content_tag('td', icon_selector('ok')) + | ||
| 26 | - content_tag('td', text_field_tag('block[links][][name]', '', :maxlength => 20)) + | ||
| 27 | - content_tag('td', text_field_tag('block[links][][address]', nil, :class => 'link-address'), :class => 'cel-address') + | ||
| 28 | - content_tag('td', text_field_tag('block[links][][title]', '', :class => 'link-title')) + | ||
| 29 | - content_tag('td', select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, '_self'))) | 38 | + page.insert_html :bottom, 'dropable-link-list', content_tag('li', |
| 39 | + content_tag('ul', | ||
| 40 | + content_tag('li', icon_selector('ok')) + | ||
| 41 | + content_tag('li', text_field_tag('block[links][][name]', '', :maxlength => 20)) + | ||
| 42 | + content_tag('li', text_field_tag('block[links][][address]', nil, :class => 'link-address')) + | ||
| 43 | + content_tag('li', select_tag('block[links][][target]', | ||
| 44 | + options_for_select(LinkListBlock::TARGET_OPTIONS, '_self'))) + | ||
| 45 | + content_tag('li', button_without_text(:delete, _('Delete'), "#" , :class=>"delete-link-list-row")), | ||
| 46 | + :class=>"link-list-row new_link_row") | ||
| 30 | ) + | 47 | ) + |
| 31 | - javascript_tag("$('edit-link-list-block').scrollTop = $('edit-link-list-block').scrollHeight")) | 48 | + javascript_tag("new_link_action()") |
| 32 | end %> | 49 | end %> |
app/views/box_organizer/edit.html.erb
| @@ -7,13 +7,14 @@ | @@ -7,13 +7,14 @@ | ||
| 7 | 7 | ||
| 8 | <%= render :partial => partial_for_class(@block.class) %> | 8 | <%= render :partial => partial_for_class(@block.class) %> |
| 9 | 9 | ||
| 10 | - <%= labelled_form_field _('Display this block:'), '' %> | ||
| 11 | - <div style='margin-left: 10px'> | ||
| 12 | - <% @block.display_options.each do |option| %> | ||
| 13 | - <%= radio_button(:block, :display, option) %> | ||
| 14 | - <%= label_tag("block_display_#{option}", _(@block.display_option_label(option))) %> | ||
| 15 | - <br/> | ||
| 16 | - <% end %> | 10 | + <div class="display"> |
| 11 | + <%= labelled_form_field _('Display this block:'), | ||
| 12 | + select_tag('block[display]', options_from_collection_for_select(@block.display_options, :first, :last, @block.display)) | ||
| 13 | + %> | ||
| 14 | + </div> | ||
| 15 | + <div class="display_user"> | ||
| 16 | + <%= labelled_form_field _('Display to users:'), '' %> | ||
| 17 | + <%= select_tag('block[display_user]', options_from_collection_for_select(@block.display_user_options, :first, :last, @block.display_user)) %> | ||
| 17 | </div> | 18 | </div> |
| 18 | 19 | ||
| 19 | <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %> | 20 | <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %> |
| @@ -0,0 +1,8 @@ | @@ -0,0 +1,8 @@ | ||
| 1 | +<div id="addThis"> | ||
| 2 | + <script type="text/javascript"> | ||
| 3 | + addthis_pub = '<%= escape_javascript( NOOSFERO_CONF['addthis_pub'] ) %>'; | ||
| 4 | + addthis_logo = '<%= escape_javascript( NOOSFERO_CONF['addthis_logo'] ) %>'; | ||
| 5 | + addthis_options = '<%= escape_javascript( NOOSFERO_CONF['addthis_options'] ) %>'; | ||
| 6 | + </script> | ||
| 7 | + <a href="http://www.addthis.com/bookmark.php" id="bt_addThis" target="_blank" onmouseover="return addthis_open(this, '', '[URL]')" onmouseout="addthis_close()" onclick="return addthis_sendto()"><%= addthis_image_tag %></a> | ||
| 8 | +</div> |
app/views/content_viewer/_article_toolbar.html.erb
| @@ -26,7 +26,7 @@ | @@ -26,7 +26,7 @@ | ||
| 26 | <%= expirable_button @page, :spread, content, url if url %> | 26 | <%= expirable_button @page, :spread, content, url if url %> |
| 27 | <% end %> | 27 | <% end %> |
| 28 | 28 | ||
| 29 | - <% if !@page.gallery? && @page.allow_create?(user) %> | 29 | + <% if !@page.gallery? && (@page.allow_create?(user) || (@page.parent && @page.parent.allow_create?(user))) %> |
| 30 | <% if @page.translatable? && !@page.native_translation.language.blank? && !remove_content_button(:locale) %> | 30 | <% if @page.translatable? && !@page.native_translation.language.blank? && !remove_content_button(:locale) %> |
| 31 | <% content = _('Add translation') %> | 31 | <% content = _('Add translation') %> |
| 32 | <% parent_id = (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)) %> | 32 | <% parent_id = (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)) %> |
app/views/content_viewer/view_page.html.erb
| @@ -43,21 +43,7 @@ | @@ -43,21 +43,7 @@ | ||
| 43 | <%= render :partial => 'shared/disabled_enterprise' %> | 43 | <%= render :partial => 'shared/disabled_enterprise' %> |
| 44 | 44 | ||
| 45 | <% if NOOSFERO_CONF['addthis_enabled'] %> | 45 | <% if NOOSFERO_CONF['addthis_enabled'] %> |
| 46 | -<div id="addThis"> | ||
| 47 | -<script type="text/javascript"> | ||
| 48 | - addthis_pub = '<%= escape_javascript( NOOSFERO_CONF['addthis_pub'] ) %>'; | ||
| 49 | - addthis_logo = '<%= escape_javascript( NOOSFERO_CONF['addthis_logo'] ) %>'; | ||
| 50 | - addthis_config = { | ||
| 51 | - services_custom: { | ||
| 52 | - name: 'Facebook', | ||
| 53 | - url: '<%= addthis_facebook_url(@page) %>', | ||
| 54 | - icon: 'http://cache.addthiscdn.com/icons/v1/thumbs/facebook.gif' | ||
| 55 | - } | ||
| 56 | - }; | ||
| 57 | - addthis_options = '<%= escape_javascript( NOOSFERO_CONF['addthis_options'] ) %>'; | ||
| 58 | -</script> | ||
| 59 | -<a href="http://www.addthis.com/bookmark.php" id="bt_addThis" target="_blank" onmouseover="return addthis_open(this, '', '[URL]')" onmouseout="addthis_close()" onclick="return addthis_sendto()"><%= addthis_image_tag %></a> | ||
| 60 | -</div> | 46 | + <%= render :partial => 'addthis' %> |
| 61 | <% end %> | 47 | <% end %> |
| 62 | 48 | ||
| 63 | <% cache(@page.cache_key(params, user, language)) do %> | 49 | <% cache(@page.cache_key(params, user, language)) do %> |
| @@ -84,6 +70,8 @@ | @@ -84,6 +70,8 @@ | ||
| 84 | 70 | ||
| 85 | <%= display_source_info(@page) %> | 71 | <%= display_source_info(@page) %> |
| 86 | 72 | ||
| 73 | +<%= @plugins.dispatch(:article_extra_contents, @page).collect { |content| instance_eval(&content) }.join("") %> | ||
| 74 | + | ||
| 87 | <div class="comments" id="comments_list"> | 75 | <div class="comments" id="comments_list"> |
| 88 | 76 | ||
| 89 | <% if @page.accept_comments? || @comments_count > 0 %> | 77 | <% if @page.accept_comments? || @comments_count > 0 %> |
| @@ -92,8 +80,26 @@ | @@ -92,8 +80,26 @@ | ||
| 92 | </h3> | 80 | </h3> |
| 93 | <% end %> | 81 | <% end %> |
| 94 | 82 | ||
| 95 | - <% if @page.accept_comments? && @comments.count > 1 %> | 83 | + <% if @page.accept_comments? && @comments_count > 1 %> |
| 96 | <%= link_to(_('Post a comment'), '#', :class => 'display-comment-form', :id => 'top-post-comment-button', :onclick => "jQuery('#page-comment-form .display-comment-form').first().click();") %> | 84 | <%= link_to(_('Post a comment'), '#', :class => 'display-comment-form', :id => 'top-post-comment-button', :onclick => "jQuery('#page-comment-form .display-comment-form').first().click();") %> |
| 85 | + | ||
| 86 | + <%= hidden_field_tag("page_url", url_for(:controller=>'content_viewer', :action=>'view_page', :profile=>profile.identifier)) %> | ||
| 87 | + <%= javascript_include_tag "comment_order.js" %> | ||
| 88 | + <div class="comment-order"> | ||
| 89 | + <% form_tag({:controller=>'content_viewer' , :action=>'view_page'}, {:method=>'get', :id=>"form_order"}) do %> | ||
| 90 | + <%= select_tag 'comment_order', options_for_select({_('Oldest first')=>'oldest', _('Newest first')=>'newest'}, @comment_order) %> | ||
| 91 | + <% end %> | ||
| 92 | + </div> | ||
| 93 | + <% end %> | ||
| 94 | + | ||
| 95 | + <% if @page.accept_comments? and @comments.count > 1 %> | ||
| 96 | + <%= hidden_field_tag("page_url", url_for(:controller=>'content_viewer', :action=>'view_page', :profile=>profile.identifier)) %> | ||
| 97 | + <%= javascript_include_tag "comment_order.js" %> | ||
| 98 | + <div class="comment-order"> | ||
| 99 | + <% form_tag({:controller=>'content_viewer' , :action=>'view_page'}, {:method=>'get', :id=>"form_order"}) do %> | ||
| 100 | + <%= select_tag 'comment_order', options_for_select({_('Oldest first')=>'oldest', _('Newest first')=>'newest'}, @comment_order) %> | ||
| 101 | + <% end %> | ||
| 102 | + </div> | ||
| 97 | <% end %> | 103 | <% end %> |
| 98 | 104 | ||
| 99 | <ul class="article-comments-list"> | 105 | <ul class="article-comments-list"> |
| @@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
| 1 | +<%= display_block(@block) %> |
| @@ -0,0 +1,6 @@ | @@ -0,0 +1,6 @@ | ||
| 1 | +<div id='not-found'> | ||
| 2 | + <p> | ||
| 3 | + <%= _('You may have clicked an expired link or mistyped the address.') %> | ||
| 4 | + <%= _('If you clicked a link that was in another site, or was given to you by someone else, it would be nice if you tell them that their link is not valid anymore.') %> | ||
| 5 | + </p> | ||
| 6 | +</div> |
app/views/events/_events.html.erb
app/views/features/_manage_community_fields.html.erb
| 1 | -<h2><%= _('Manage community fields') %></h2> | ||
| 2 | - | ||
| 3 | <%= labelled_form_for(:environment, @environment, :url => {:action => 'manage_community_fields'}) do |f| %> | 1 | <%= labelled_form_for(:environment, @environment, :url => {:action => 'manage_community_fields'}) do |f| %> |
| 4 | 2 | ||
| 5 | <table id='community_fields_conf'> | 3 | <table id='community_fields_conf'> |
| @@ -9,21 +7,37 @@ | @@ -9,21 +7,37 @@ | ||
| 9 | <th><%= _('Required') %></th> | 7 | <th><%= _('Required') %></th> |
| 10 | <th><%= _('Display on creation?') %></th> | 8 | <th><%= _('Display on creation?') %></th> |
| 11 | </tr> | 9 | </tr> |
| 10 | + | ||
| 11 | + <tr class='manage-fields-batch-actions'> | ||
| 12 | + <td> | ||
| 13 | + <%= _("Check/Uncheck All")%> | ||
| 14 | + </td> | ||
| 15 | + <td> | ||
| 16 | + <input type="checkbox" id="community_active" /> | ||
| 17 | + </td> | ||
| 18 | + <td> | ||
| 19 | + <input type="checkbox" id="community_required" /> | ||
| 20 | + </td> | ||
| 21 | + <td> | ||
| 22 | + <input type="checkbox" id="community_signup" /> | ||
| 23 | + </td> | ||
| 24 | + </tr> | ||
| 25 | + | ||
| 12 | <% @community_fields.each do |field| %> | 26 | <% @community_fields.each do |field| %> |
| 13 | <tr> | 27 | <tr> |
| 14 | <td><label for="community_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> | 28 | <td><label for="community_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> |
| 15 | 29 | ||
| 16 | <td> | 30 | <td> |
| 17 | <%= hidden_field_tag "community_fields[#{field}][active]", false %> | 31 | <%= hidden_field_tag "community_fields[#{field}][active]", false %> |
| 18 | - <%= check_box_tag "community_fields[#{field}][active]", true, environment.custom_community_field(field, 'active'), :onclick => "$('community_fields[#{field}][required]').disabled=$('community_fields[#{field}][signup]').disabled=!this.checked;" %> | 32 | + <%= check_box_tag "community_fields[#{field}][active]", true, environment.custom_community_field(field, 'active'), :onclick => "active_action(this, 'community_fields[#{field}][required]', 'community_fields[#{field}][signup]')" %> |
| 19 | </td> | 33 | </td> |
| 20 | <td> | 34 | <td> |
| 21 | <%= hidden_field_tag "community_fields[#{field}][required]", false %> | 35 | <%= hidden_field_tag "community_fields[#{field}][required]", false %> |
| 22 | - <%= check_box_tag "community_fields[#{field}][required]", true, environment.custom_community_field(field, 'required'), :onclick => "if(this.checked) $('community_fields[#{field}][signup]').checked = true;" %> | 36 | + <%= check_box_tag "community_fields[#{field}][required]", true, environment.custom_community_field(field, 'required'), :onclick => "required_action('community_fields[#{field}][active]','community_fields[#{field}][required]', 'community_fields[#{field}][signup]')" %> |
| 23 | </td> | 37 | </td> |
| 24 | <td> | 38 | <td> |
| 25 | <%= hidden_field_tag "community_fields[#{field}][signup]", false %> | 39 | <%= hidden_field_tag "community_fields[#{field}][signup]", false %> |
| 26 | - <%= check_box_tag "community_fields[#{field}][signup]", true, environment.custom_community_field(field, 'signup'), :onclick => "if(!this.checked) $('community_fields[#{field}][required]').checked = false;" %> | 40 | + <%= check_box_tag "community_fields[#{field}][signup]", true, environment.custom_community_field(field, 'signup'), :onclick => "signup_action('community_fields[#{field}][active]','community_fields[#{field}][required]', 'community_fields[#{field}][signup]')" %> |
| 27 | </td> | 41 | </td> |
| 28 | 42 | ||
| 29 | </tr> | 43 | </tr> |
| @@ -31,18 +45,18 @@ | @@ -31,18 +45,18 @@ | ||
| 31 | </table> | 45 | </table> |
| 32 | 46 | ||
| 33 | <script type='text/javascript'> | 47 | <script type='text/javascript'> |
| 34 | - var trs = $$('#community_fields_conf tr'); | 48 | + var trs = jQuery('#community_fields_conf tr'); |
| 35 | var tr, td2; | 49 | var tr, td2; |
| 36 | - for ( var i=0; tr=trs[i]; i++ ) { | 50 | + for ( var i=2; tr=trs[i]; i++ ) { |
| 37 | if ( td2 = tr.getElementsByTagName('td')[1] ) { | 51 | if ( td2 = tr.getElementsByTagName('td')[1] ) { |
| 38 | - td2.getElementsByTagName('input')[0].onclick(); | 52 | + td2.getElementsByTagName('input')[1].onclick(); |
| 39 | } | 53 | } |
| 40 | } | 54 | } |
| 41 | </script> | 55 | </script> |
| 42 | 56 | ||
| 43 | <div> | 57 | <div> |
| 44 | <% button_bar do %> | 58 | <% button_bar do %> |
| 45 | - <%= submit_button('save', _('Save changes')) %> | 59 | + <%= submit_button('save', _('Save changes'), :id=>"save_community_fields") %> |
| 46 | <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> | 60 | <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> |
| 47 | <% end %> | 61 | <% end %> |
| 48 | </div> | 62 | </div> |
app/views/features/_manage_enterprise_fields.html.erb
| 1 | -<h2><%= _('Manage enterprise fields') %></h2> | ||
| 2 | - | ||
| 3 | <%= labelled_form_for(:environment, @environment, :url => {:action => 'manage_enterprise_fields'}) do |f| %> | 1 | <%= labelled_form_for(:environment, @environment, :url => {:action => 'manage_enterprise_fields'}) do |f| %> |
| 4 | 2 | ||
| 5 | <table id='enterprise_fields_conf'> | 3 | <table id='enterprise_fields_conf'> |
| @@ -9,21 +7,37 @@ | @@ -9,21 +7,37 @@ | ||
| 9 | <th><%= _('Required') %></th> | 7 | <th><%= _('Required') %></th> |
| 10 | <th><%= _('Display on registration?') %></th> | 8 | <th><%= _('Display on registration?') %></th> |
| 11 | </tr> | 9 | </tr> |
| 10 | + | ||
| 11 | + <tr class='manage-fields-batch-actions'> | ||
| 12 | + <td> | ||
| 13 | + <%= _("Check/Uncheck All")%> | ||
| 14 | + </td> | ||
| 15 | + <td> | ||
| 16 | + <input type="checkbox" id="enterprise_active" /> | ||
| 17 | + </td> | ||
| 18 | + <td> | ||
| 19 | + <input type="checkbox" id="enterprise_required" /> | ||
| 20 | + </td> | ||
| 21 | + <td> | ||
| 22 | + <input type="checkbox" id="enterprise_signup" /> | ||
| 23 | + </td> | ||
| 24 | + </tr> | ||
| 25 | + | ||
| 12 | <% @enterprise_fields.each do |field| %> | 26 | <% @enterprise_fields.each do |field| %> |
| 13 | <tr> | 27 | <tr> |
| 14 | 28 | ||
| 15 | <td><label for="enterprise_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> | 29 | <td><label for="enterprise_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> |
| 16 | <td> | 30 | <td> |
| 17 | <%= hidden_field_tag "enterprise_fields[#{field}][active]", false %> | 31 | <%= hidden_field_tag "enterprise_fields[#{field}][active]", false %> |
| 18 | - <%= check_box_tag "enterprise_fields[#{field}][active]", true, environment.custom_enterprise_field(field, 'active'), :onclick => "$('enterprise_fields[#{field}][required]').disabled=$('enterprise_fields[#{field}][signup]').disabled=!this.checked;" %> | 32 | + <%= check_box_tag "enterprise_fields[#{field}][active]", true, environment.custom_enterprise_field(field, 'active'), :onclick => "active_action(this, 'enterprise_fields[#{field}][required]', 'enterprise_fields[#{field}][signup]')" %> |
| 19 | </td> | 33 | </td> |
| 20 | <td> | 34 | <td> |
| 21 | <%= hidden_field_tag "enterprise_fields[#{field}][required]", false %> | 35 | <%= hidden_field_tag "enterprise_fields[#{field}][required]", false %> |
| 22 | - <%= check_box_tag "enterprise_fields[#{field}][required]", true, environment.custom_enterprise_field(field, 'required'), :onclick => "if(this.checked) $('enterprise_fields[#{field}][signup]').checked = true;" %> | 36 | + <%= check_box_tag "enterprise_fields[#{field}][required]", true, environment.custom_enterprise_field(field, 'required'), :onclick => "required_action('enterprise_fields[#{field}][active]','enterprise_fields[#{field}][required]', 'enterprise_fields[#{field}][signup]')" %> |
| 23 | </td> | 37 | </td> |
| 24 | <td> | 38 | <td> |
| 25 | <%= hidden_field_tag "enterprise_fields[#{field}][signup]", false %> | 39 | <%= hidden_field_tag "enterprise_fields[#{field}][signup]", false %> |
| 26 | - <%= check_box_tag "enterprise_fields[#{field}][signup]", true, environment.custom_enterprise_field(field, 'signup'), :onclick => "if(!this.checked) $('enterprise_fields[#{field}][required]').checked = false;" %> | 40 | + <%= check_box_tag "enterprise_fields[#{field}][signup]", true, environment.custom_enterprise_field(field, 'signup'), :onclick => "signup_action('enterprise_fields[#{field}][active]','enterprise_fields[#{field}][required]', 'enterprise_fields[#{field}][signup]')" %> |
| 27 | </td> | 41 | </td> |
| 28 | 42 | ||
| 29 | </tr> | 43 | </tr> |
| @@ -31,18 +45,18 @@ | @@ -31,18 +45,18 @@ | ||
| 31 | </table> | 45 | </table> |
| 32 | 46 | ||
| 33 | <script type='text/javascript'> | 47 | <script type='text/javascript'> |
| 34 | - var trs = $$('#enterprise_fields_conf tr'); | 48 | + var trs = jQuery('#enterprise_fields_conf tr'); |
| 35 | var tr, td2; | 49 | var tr, td2; |
| 36 | - for ( var i=0; tr=trs[i]; i++ ) { | 50 | + for ( var i=2; tr=trs[i]; i++ ) { |
| 37 | if ( td2 = tr.getElementsByTagName('td')[1] ) { | 51 | if ( td2 = tr.getElementsByTagName('td')[1] ) { |
| 38 | - td2.getElementsByTagName('input')[0].onclick(); | 52 | + td2.getElementsByTagName('input')[1].onclick(); |
| 39 | } | 53 | } |
| 40 | } | 54 | } |
| 41 | </script> | 55 | </script> |
| 42 | 56 | ||
| 43 | <div> | 57 | <div> |
| 44 | <% button_bar do %> | 58 | <% button_bar do %> |
| 45 | - <%= submit_button('save', _('Save changes')) %> | 59 | + <%= submit_button('save', _('Save changes'), :id=>"save_enterprise_fields") %> |
| 46 | <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> | 60 | <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> |
| 47 | <% end %> | 61 | <% end %> |
| 48 | </div> | 62 | </div> |
app/views/features/_manage_person_fields.html.erb
| 1 | -<h2><%= _('Manage person fields') %></h2> | ||
| 2 | - | ||
| 3 | <%= labelled_form_for(:environment, @environment, :url => {:action => 'manage_person_fields'}) do |f| %> | 1 | <%= labelled_form_for(:environment, @environment, :url => {:action => 'manage_person_fields'}) do |f| %> |
| 4 | 2 | ||
| 5 | <table id='person_fields_conf'> | 3 | <table id='person_fields_conf'> |
| @@ -9,31 +7,48 @@ | @@ -9,31 +7,48 @@ | ||
| 9 | <th><%= _('Required') %></th> | 7 | <th><%= _('Required') %></th> |
| 10 | <th><%= _('Display on signup?') %></th> | 8 | <th><%= _('Display on signup?') %></th> |
| 11 | </tr> | 9 | </tr> |
| 10 | + | ||
| 11 | + <tr class='manage-fields-batch-actions'> | ||
| 12 | + <td> | ||
| 13 | + <%= _("Check/Uncheck All")%> | ||
| 14 | + </td> | ||
| 15 | + <td> | ||
| 16 | + <input type="checkbox" id="person_active" /> | ||
| 17 | + </td> | ||
| 18 | + <td> | ||
| 19 | + <input type="checkbox" id="person_required" /> | ||
| 20 | + </td> | ||
| 21 | + <td> | ||
| 22 | + <input type="checkbox" id="person_signup" /> | ||
| 23 | + </td> | ||
| 24 | + </tr> | ||
| 25 | + | ||
| 12 | <% @person_fields.each do |field| %> | 26 | <% @person_fields.each do |field| %> |
| 13 | <tr> | 27 | <tr> |
| 14 | <td><label for="person_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> | 28 | <td><label for="person_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> |
| 15 | <td> | 29 | <td> |
| 16 | <%= hidden_field_tag "person_fields[#{field}][active]", false %> | 30 | <%= hidden_field_tag "person_fields[#{field}][active]", false %> |
| 17 | - <%= check_box_tag "person_fields[#{field}][active]", true, environment.custom_person_field(field, 'active'), :onclick => "$('person_fields[#{field}][required]').disabled=$('person_fields[#{field}][signup]').disabled=!this.checked;" %> | 31 | + <%= check_box_tag "person_fields[#{field}][active]", true, environment.custom_person_field(field, 'active'), :onclick => "active_action(this, 'person_fields[#{field}][required]', 'person_fields[#{field}][signup]')" %> |
| 18 | </td> | 32 | </td> |
| 19 | <td> | 33 | <td> |
| 20 | <%= hidden_field_tag "person_fields[#{field}][required]", false %> | 34 | <%= hidden_field_tag "person_fields[#{field}][required]", false %> |
| 21 | - <%= check_box_tag "person_fields[#{field}][required]", true, environment.custom_person_field(field, 'required'), :onclick => "if(this.checked) $('person_fields[#{field}][signup]').checked = true;" %> | 35 | + <%= check_box_tag "person_fields[#{field}][required]", true, environment.custom_person_field(field, 'required'), :onclick => "required_action('person_fields[#{field}][active]','person_fields[#{field}][required]', 'person_fields[#{field}][signup]')" %> |
| 22 | </td> | 36 | </td> |
| 23 | <td> | 37 | <td> |
| 24 | <%= hidden_field_tag "person_fields[#{field}][signup]", false %> | 38 | <%= hidden_field_tag "person_fields[#{field}][signup]", false %> |
| 25 | - <%= check_box_tag "person_fields[#{field}][signup]", true, environment.custom_person_field(field, 'signup'), :onclick => "if(!this.checked) $('person_fields[#{field}][required]').checked = false;" %> | 39 | + <%= check_box_tag "person_fields[#{field}][signup]", true, environment.custom_person_field(field, 'signup'), :onclick => "signup_action('person_fields[#{field}][active]','person_fields[#{field}][required]', 'person_fields[#{field}][signup]')" %> |
| 26 | </td> | 40 | </td> |
| 27 | </tr> | 41 | </tr> |
| 28 | <% end %> | 42 | <% end %> |
| 29 | </table> | 43 | </table> |
| 30 | 44 | ||
| 31 | <script type='text/javascript'>// <!-- | 45 | <script type='text/javascript'>// <!-- |
| 32 | - var trs = $$('#person_fields_conf tr'); | 46 | + var trs = jQuery('#person_fields_conf tr'); |
| 47 | + | ||
| 33 | var tr, td2; | 48 | var tr, td2; |
| 34 | - for ( var i=0; tr=trs[i]; i++ ) { | 49 | + for ( var i=2; tr=trs[i]; i++ ) { |
| 35 | if ( td2 = tr.getElementsByTagName('td')[1] ) { | 50 | if ( td2 = tr.getElementsByTagName('td')[1] ) { |
| 36 | - td2.getElementsByTagName('input')[0].onclick(); | 51 | + td2.getElementsByTagName('input')[1].onclick(); |
| 37 | } | 52 | } |
| 38 | } | 53 | } |
| 39 | // --> | 54 | // --> |
| @@ -41,7 +56,7 @@ | @@ -41,7 +56,7 @@ | ||
| 41 | 56 | ||
| 42 | <div> | 57 | <div> |
| 43 | <% button_bar do %> | 58 | <% button_bar do %> |
| 44 | - <%= submit_button('save', _('Save changes')) %> | 59 | + <%= submit_button('save', _('Save changes'), :id=>"save_person_fields") %> |
| 45 | <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> | 60 | <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> |
| 46 | <% end %> | 61 | <% end %> |
| 47 | </div> | 62 | </div> |
app/views/features/index.html.erb
| @@ -26,9 +26,13 @@ Check all the features you want to enable for your environment, uncheck all the | @@ -26,9 +26,13 @@ Check all the features you want to enable for your environment, uncheck all the | ||
| 26 | 26 | ||
| 27 | <h2><%= _('Configure features') %></h2> | 27 | <h2><%= _('Configure features') %></h2> |
| 28 | 28 | ||
| 29 | +<h3><%= _('Page to redirect after signup') %></h3> | ||
| 30 | + <%= select 'environment', 'redirection_after_signup', Environment.signup_redirection_options.map{|key,value|[value,key]} %> | ||
| 31 | +<hr/> | ||
| 29 | <h3><%= _('Page to redirect after login') %></h3> | 32 | <h3><%= _('Page to redirect after login') %></h3> |
| 30 | <%= select 'environment', 'redirection_after_login', Environment.login_redirection_options.map{|key,value|[value,key]} %> | 33 | <%= select 'environment', 'redirection_after_login', Environment.login_redirection_options.map{|key,value|[value,key]} %> |
| 31 | <hr/> | 34 | <hr/> |
| 35 | + | ||
| 32 | <h3><%= _('Organization Approval Method') %></h3> | 36 | <h3><%= _('Organization Approval Method') %></h3> |
| 33 | <%= select_organization_approval_method('environment', 'organization_approval_method') %> | 37 | <%= select_organization_approval_method('environment', 'organization_approval_method') %> |
| 34 | <hr/> | 38 | <hr/> |
app/views/features/manage_fields.html.erb
| 1 | -<%= render :partial => 'manage_person_fields' %> | 1 | +<h1><%= _('Manage fields displayed for profiles') %></h1> |
| 2 | 2 | ||
| 3 | -<% if !environment.enabled?('disable_asset_enterprises') %> | ||
| 4 | - <%= render :partial => 'manage_enterprise_fields' %> | 3 | +<% tabs = [] %> |
| 4 | +<% tabs << {:title => _("Person's fields"), :id => 'person-fields', | ||
| 5 | + :content => (render :partial => 'manage_person_fields')} %> | ||
| 6 | +<% tabs << {:title => _("Community's fields"), :id => 'community-fields', | ||
| 7 | + :content => (render :partial => 'manage_community_fields')} %> | ||
| 8 | +<% unless environment.enabled?('disable_asset_enterprises') %> | ||
| 9 | + <% tabs << {:title => _("Enterprise's fields"), :id => 'enterprise-fields', | ||
| 10 | + :content => (render :partial => 'manage_enterprise_fields')} %> | ||
| 5 | <% end %> | 11 | <% end %> |
| 6 | 12 | ||
| 7 | -<%= render :partial => 'manage_community_fields' %> | 13 | +<%= render_tabs(tabs) %> |
| 14 | + | ||
| 15 | +<%= javascript_include_tag "manage-fields.js" %> |
app/views/layouts/application-ng.html.erb
| @@ -6,6 +6,27 @@ | @@ -6,6 +6,27 @@ | ||
| 6 | <!--<meta http-equiv="refresh" content="1"/>--> | 6 | <!--<meta http-equiv="refresh" content="1"/>--> |
| 7 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | 7 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> |
| 8 | <meta name="description" content="<%= @environment.name %>" /> | 8 | <meta name="description" content="<%= @environment.name %>" /> |
| 9 | + | ||
| 10 | + <!-- Twitter Card --> | ||
| 11 | + <meta name="twitter:card" value="summary"> | ||
| 12 | + <meta name="twitter:title" content="<%= h page_title %>"> | ||
| 13 | + <meta name="twitter:description" content="<%= meta_description_tag(@page) %>"> | ||
| 14 | + | ||
| 15 | + <!-- Open Graph --> | ||
| 16 | + <meta property="og:type" content="<%= @page ? 'article' : 'website' %>"> | ||
| 17 | + <meta property="og:url" content="<%= @page ? url_for(@page.url) : @environment.top_url %>"> | ||
| 18 | + <meta property="og:title" content="<%= h page_title %>"> | ||
| 19 | + <meta property="og:site_name" content="<%= profile ? profile.name : @environment.name %>"> | ||
| 20 | + <meta property="og:description" content="<%= @page ? truncate(strip_tags(@page.body.to_s), :length => 200) : @environment.name %>"> | ||
| 21 | + | ||
| 22 | + <% if @page %> | ||
| 23 | + <meta property="article:published_time" content="<%= show_date(@page.published_at) %>"> | ||
| 24 | + <% @page.body_images_paths.each do |img| %> | ||
| 25 | + <meta name="twitter:image" content="<%= img.to_s %>"> | ||
| 26 | + <meta property="og:image" content="<%= img.to_s %>"> | ||
| 27 | + <% end %> | ||
| 28 | + <% end %> | ||
| 29 | + | ||
| 9 | <link rel="shortcut icon" href="<%= image_path(theme_favicon) %>" type="image/x-icon" /> | 30 | <link rel="shortcut icon" href="<%= image_path(theme_favicon) %>" type="image/x-icon" /> |
| 10 | <%= noosfero_javascript %> | 31 | <%= noosfero_javascript %> |
| 11 | <%= noosfero_stylesheets %> | 32 | <%= noosfero_stylesheets %> |
| @@ -0,0 +1,35 @@ | @@ -0,0 +1,35 @@ | ||
| 1 | +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
| 2 | +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%= html_language %>" lang="<%= html_language %>"> | ||
| 3 | + <head> | ||
| 4 | + <title>Noosfero embed block</title> | ||
| 5 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | ||
| 6 | + <%= noosfero_stylesheets %> | ||
| 7 | + <%= noosfero_javascript %> | ||
| 8 | + </head> | ||
| 9 | + <body class="<%= h body_classes %>"> | ||
| 10 | + <div id="embed"> | ||
| 11 | + <div id="wrap-1"> | ||
| 12 | + <div id="wrap-2"> | ||
| 13 | + <div id="content"> | ||
| 14 | + <div id="content-inner"> | ||
| 15 | + <div class="boxes" id="boxes"> | ||
| 16 | + <div class="box box-1" id="box-1"> | ||
| 17 | + <div class="blocks"> | ||
| 18 | + <%= yield %> | ||
| 19 | + </div> | ||
| 20 | + </div> | ||
| 21 | + </div> | ||
| 22 | + </div> | ||
| 23 | + </div> | ||
| 24 | + </div> | ||
| 25 | + </div> | ||
| 26 | + </div> | ||
| 27 | + | ||
| 28 | + <script type="text/javascript"> | ||
| 29 | + jQuery(document).ready(function(){ | ||
| 30 | + jQuery('a').attr('target','_blank'); | ||
| 31 | + }); | ||
| 32 | + </script> | ||
| 33 | + | ||
| 34 | + </body> | ||
| 35 | +</html> |
app/views/person_notifier/mailer/_add_member_in_community.rhtml
0 → 100644
| @@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
| 1 | +<%= render :partial => 'default_activity', :locals => { :activity => activity } %> |
| @@ -0,0 +1,33 @@ | @@ -0,0 +1,33 @@ | ||
| 1 | +<% Comment %> | ||
| 2 | +<% Profile %> | ||
| 3 | +<% Person %> | ||
| 4 | + | ||
| 5 | +<table style="background: #f0f0f1;border-bottom: 1px solid #d2d2d2 !important;border-top: 1px solid #fff;margin-bottom: 0;"> | ||
| 6 | +<tr> | ||
| 7 | + <td> | ||
| 8 | + <% if comment.author %> | ||
| 9 | + <%= link_to profile_image(comment.author, :minor), | ||
| 10 | + comment.author_url, | ||
| 11 | + :class => 'comment-picture', | ||
| 12 | + :title => comment.author_name | ||
| 13 | + %> | ||
| 14 | + <% end %> | ||
| 15 | + </td> | ||
| 16 | + <td> | ||
| 17 | + <%= comment.author.present? ? link_to(comment.author_name, comment.author.url, :style => "font-size: 12px; color: #333; font-weight: bold; text-decoration: none;") : content_tag('strong', comment.author_name) %> | ||
| 18 | + <% unless comment.title.blank? %> | ||
| 19 | + <span style="font-size: 12px;"><%= comment.title %></span><br/> | ||
| 20 | + <% end %> | ||
| 21 | + <span style="font-size: 10px;"><%= txt2html comment.body %></span><br/> | ||
| 22 | + <span style="font-size: 8px; color: #444444"><%= time_ago_as_sentence(comment.created_at) %></span> | ||
| 23 | + <br style="clear: both;" /> | ||
| 24 | + | ||
| 25 | + <% unless comment.replies.blank? %> | ||
| 26 | + <ul class="comment-replies"> | ||
| 27 | + <% comment.replies.each do |reply| %> | ||
| 28 | + <%= render :partial => 'comment', :locals => { :comment => reply } %> | ||
| 29 | + <% end %> | ||
| 30 | + </ul> | ||
| 31 | + <% end %> | ||
| 32 | + </td> | ||
| 33 | +</table> |
| @@ -0,0 +1,27 @@ | @@ -0,0 +1,27 @@ | ||
| 1 | +<table> | ||
| 2 | +<tr> | ||
| 3 | + <td> | ||
| 4 | + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %> | ||
| 5 | + </td> | ||
| 6 | + <td> | ||
| 7 | + <p style="width:550px"> | ||
| 8 | + <span style="font-size: 14px;"><%= link_to activity.user.short_name(20), activity.user.url %></span> | ||
| 9 | + <span style="font-size: 14px;"><%= _("has published on community %s") % link_to(activity.target.profile.short_name(20), activity.target.profile.url, :style => "color: #333; font-weight: bold; text-decoration: none;") if activity.target.profile.is_a?(Community) %></span> | ||
| 10 | + <span style="font-size: 10px; color: #444444; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> | ||
| 11 | + </p> | ||
| 12 | + <p> | ||
| 13 | + <span style="font-size: 14px;"><%= link_to(activity.params['name'], activity.params['url'], :style => "color: #333; font-weight: bold; text-decoration: none;") %></span> | ||
| 14 | + <br/> | ||
| 15 | + <span title='<%= activity.target.class.short_description %>' class='profile-activity-icon icon-new icon-new<%= activity.target.class.icon_name %>'></span> | ||
| 16 | + <%= image_tag(activity.params['first_image']) unless activity.params['first_image'].blank? %><%= strip_tags(truncate(activity.params['lead'], :length => 1000, :ommision => '...')).gsub(/(\xC2\xA0|\s)+/, ' ').gsub(/^\s+/, '') %> | ||
| 17 | + </p> | ||
| 18 | + <p><%= content_tag(:p, link_to(_('See complete forum'), activity.get_url), :class => 'see-forum') if activity.target.is_a?(Forum) %></p> | ||
| 19 | + </td> | ||
| 20 | +</tr> | ||
| 21 | +<tr> | ||
| 22 | + <td></td> | ||
| 23 | + <td> | ||
| 24 | + <%= render :partial => 'profile_comments', :locals => { :activity => activity } %> | ||
| 25 | + </td> | ||
| 26 | +</tr> | ||
| 27 | +</table> |
app/views/person_notifier/mailer/_default_activity.rhtml
0 → 100644
| @@ -0,0 +1,19 @@ | @@ -0,0 +1,19 @@ | ||
| 1 | +<table> | ||
| 2 | +<tr> | ||
| 3 | + <td> | ||
| 4 | + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %> | ||
| 5 | + </td> | ||
| 6 | + <td> | ||
| 7 | + <p style="width:550px"> | ||
| 8 | + <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span> | ||
| 9 | + <span style="font-size: 10px; color: #444444; float: right;"><%= time_ago_as_sentence(activity.created_at) %></span> | ||
| 10 | + </p> | ||
| 11 | + </td> | ||
| 12 | +</tr> | ||
| 13 | +<tr> | ||
| 14 | + <td></td> | ||
| 15 | + <td> | ||
| 16 | + <%= render :partial => 'profile_comments', :locals => { :activity => activity } %> | ||
| 17 | + </td> | ||
| 18 | +</tr> | ||
| 19 | +</table> |
| @@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
| 1 | +<%= render :partial => 'default_activity', :locals => { :activity => activity } %> |
| @@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
| 1 | +<%= render :partial => 'default_activity', :locals => { :activity => activity } %> |
app/views/person_notifier/mailer/_leave_scrap_to_self.rhtml
0 → 120000
| @@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
| 1 | +<%= render :partial => 'default_activity', :locals => { :activity => activity } %> |
app/views/person_notifier/mailer/_profile_comments.rhtml
0 → 100644
| @@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
| 1 | +<% if activity.comments_count > 2 %> | ||
| 2 | + <div style="font-size: 10px;"> | ||
| 3 | + <% if activity.params['url'].blank? %> | ||
| 4 | + <%= _("%s comments") % activity.comments_count %> | ||
| 5 | + <% else %> | ||
| 6 | + <%= link_to(_("View all %s comments") % activity.comments_count, activity.params['url']) %> | ||
| 7 | + <% end %> | ||
| 8 | + </div> | ||
| 9 | +<% else %> | ||
| 10 | + <ul> | ||
| 11 | + <%= render :partial => 'comment', :collection => activity.comments %> | ||
| 12 | + </ul> | ||
| 13 | +<% end %> |
app/views/person_notifier/mailer/_reply_scrap_on_self.rhtml
0 → 120000
| @@ -0,0 +1,15 @@ | @@ -0,0 +1,15 @@ | ||
| 1 | +<table> | ||
| 2 | + <tr> | ||
| 3 | + <td> | ||
| 4 | + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %> | ||
| 5 | + </td> | ||
| 6 | + <td> | ||
| 7 | + <p style="width:550px"> | ||
| 8 | + <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span> | ||
| 9 | + <span style="font-size: 10px; color: #444444; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> | ||
| 10 | + </p> | ||
| 11 | + </td> | ||
| 12 | +</tr> | ||
| 13 | +</table> | ||
| 14 | +<div title='<%= activity.target.class.short_description %>' class='profile-activity-icon icon-new icon-newgallery'></div> | ||
| 15 | +<br/> |
| @@ -0,0 +1,18 @@ | @@ -0,0 +1,18 @@ | ||
| 1 | +<h3><%= _("%s's network activity") % @profile.name %></h3> | ||
| 2 | +<br/> | ||
| 3 | +<div> | ||
| 4 | +<% @notifications.each do |activity| %> | ||
| 5 | + <div style="border-left:none;border-right:none;border-top:1px solid #ccc;border-bottom:none;padding:10px;width:600px"> | ||
| 6 | + <%= render :partial => activity.verb, :locals => { :activity => activity } rescue "cannot render notification for #{activity.verb}" %> | ||
| 7 | + </div> | ||
| 8 | +<% end %> | ||
| 9 | +</div> | ||
| 10 | + | ||
| 11 | +<div style="color:#444444;font-size:11px;"> | ||
| 12 | +<p><%= _("Greetings,") %></p> | ||
| 13 | +<br/> | ||
| 14 | +<p>--</p> | ||
| 15 | +<p><%= _('%s team.') % @environment %></p> | ||
| 16 | +<p><%= url_for @url %></p> | ||
| 17 | +</div> | ||
| 18 | +<br/> |
app/views/profile_editor/_person.html.erb
| @@ -19,3 +19,8 @@ | @@ -19,3 +19,8 @@ | ||
| 19 | <%= @plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_eval(&content) }.join("") %> | 19 | <%= @plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_eval(&content) }.join("") %> |
| 20 | 20 | ||
| 21 | <%= render :partial => 'person_form', :locals => {:f => f} %> | 21 | <%= render :partial => 'person_form', :locals => {:f => f} %> |
| 22 | + | ||
| 23 | + <h2><%= _('Notification options') %></h2> | ||
| 24 | + <div> | ||
| 25 | + <%= select_tag 'profile_data[notification_time]', options_for_select([[_('Disabled'), 0], [_('Hourly'), 1], [_('Half Day'), 12], [_('Daily'), 24]], @profile.notification_time) %> | ||
| 26 | + </div> |
app/views/profile_editor/_person_form.html.erb
| @@ -19,8 +19,8 @@ | @@ -19,8 +19,8 @@ | ||
| 19 | <%= optional_field(@person, 'birth_date', labelled_form_field(_('Birth date'), '<div class="select-birth-date">' + pick_date(:profile_data, :birth_date, {:start_year => (Date.today.year - 100), :end_year => (Date.today.year - 5)}) + '</div>')) %> | 19 | <%= optional_field(@person, 'birth_date', labelled_form_field(_('Birth date'), '<div class="select-birth-date">' + pick_date(:profile_data, :birth_date, {:start_year => (Date.today.year - 100), :end_year => (Date.today.year - 5)}) + '</div>')) %> |
| 20 | <%= optional_field(@person, 'nationality', f.text_field(:nationality, :rel => _('Nationality'))) %> | 20 | <%= optional_field(@person, 'nationality', f.text_field(:nationality, :rel => _('Nationality'))) %> |
| 21 | <%= optional_field(@person, 'country', select_country(_('Country'), 'profile_data', 'country', {:class => 'type-select'})) %> | 21 | <%= optional_field(@person, 'country', select_country(_('Country'), 'profile_data', 'country', {:class => 'type-select'})) %> |
| 22 | -<%= optional_field(@person, 'state', f.text_field(:state, :rel => _('State'))) %> | ||
| 23 | -<%= optional_field(@person, 'city', f.text_field(:city, :rel => _('City'))) %> | 22 | +<%= optional_field(@person, 'state', f.text_field(:state, :id => 'state_field', :rel => _('State'))) %> |
| 23 | +<%= optional_field(@person, 'city', f.text_field(:city, :id => 'city_field', :rel => _('City'))) %> | ||
| 24 | <%= optional_field(@person, 'zip_code', labelled_form_field(_('ZIP code'), text_field(:profile_data, :zip_code, :rel => _('ZIP code')))) %> | 24 | <%= optional_field(@person, 'zip_code', labelled_form_field(_('ZIP code'), text_field(:profile_data, :zip_code, :rel => _('ZIP code')))) %> |
| 25 | <%= optional_field(@person, 'address', labelled_form_field(_('Address (street and number)'), text_field(:profile_data, :address, :rel => _('Address')))) %> | 25 | <%= optional_field(@person, 'address', labelled_form_field(_('Address (street and number)'), text_field(:profile_data, :address, :rel => _('Address')))) %> |
| 26 | <%= optional_field(@person, 'address_reference', labelled_form_field(_('Address reference'), text_field(:profile_data, :address_reference, :rel => _('Address reference')))) %> | 26 | <%= optional_field(@person, 'address_reference', labelled_form_field(_('Address reference'), text_field(:profile_data, :address_reference, :rel => _('Address reference')))) %> |
| @@ -36,6 +36,7 @@ | @@ -36,6 +36,7 @@ | ||
| 36 | </div> | 36 | </div> |
| 37 | <% end %> | 37 | <% end %> |
| 38 | 38 | ||
| 39 | +<%= javascript_include_tag('city_state_validation') %> | ||
| 39 | <script type='text/javascript'> | 40 | <script type='text/javascript'> |
| 40 | function toggle_text_field(id, span_id) { | 41 | function toggle_text_field(id, span_id) { |
| 41 | if ($(id).value == "Others") { | 42 | if ($(id).value == "Others") { |
app/views/shared/_organization_custom_fields.html.erb
| @@ -13,8 +13,8 @@ | @@ -13,8 +13,8 @@ | ||
| 13 | <%= optional_field(profile, 'address_reference', labelled_form_field(_('Address reference'), text_field(object_name, :address_reference))) %> | 13 | <%= optional_field(profile, 'address_reference', labelled_form_field(_('Address reference'), text_field(object_name, :address_reference))) %> |
| 14 | <%= optional_field(profile, 'district', labelled_form_field(_('District'), text_field(object_name, :district))) %> | 14 | <%= optional_field(profile, 'district', labelled_form_field(_('District'), text_field(object_name, :district))) %> |
| 15 | <%= optional_field(profile, 'zip_code', labelled_form_field(_('ZIP code'), text_field(object_name, :zip_code))) %> | 15 | <%= optional_field(profile, 'zip_code', labelled_form_field(_('ZIP code'), text_field(object_name, :zip_code))) %> |
| 16 | -<%= optional_field(profile, 'city', f.text_field(:city)) %> | ||
| 17 | -<%= optional_field(profile, 'state', f.text_field(:state)) %> | 16 | +<%= optional_field(profile, 'city', f.text_field(:city, :id =>'city_field')) %> |
| 17 | +<%= optional_field(profile, 'state', f.text_field(:state,:id =>'state_field')) %> | ||
| 18 | <%= optional_field(profile, 'country', select_country(_('Country'), object_name, 'country', {:class => 'type-select'})) %> | 18 | <%= optional_field(profile, 'country', select_country(_('Country'), object_name, 'country', {:class => 'type-select'})) %> |
| 19 | <%= optional_field(profile, 'tag_list', f.text_field(:tag_list)) %> | 19 | <%= optional_field(profile, 'tag_list', f.text_field(:tag_list)) %> |
| 20 | 20 | ||
| @@ -29,3 +29,4 @@ | @@ -29,3 +29,4 @@ | ||
| 29 | <%= optional_field(profile, 'acronym', f.text_field(:acronym)) %> | 29 | <%= optional_field(profile, 'acronym', f.text_field(:acronym)) %> |
| 30 | <%= optional_field(profile, 'foundation_year', f.text_field(:foundation_year)) %> | 30 | <%= optional_field(profile, 'foundation_year', f.text_field(:foundation_year)) %> |
| 31 | <% end %> | 31 | <% end %> |
| 32 | +<%= javascript_include_tag('city_state_validation') %> |
app/views/shared/_select_categories.html.erb
| 1 | -<div id="category-ajax-selector"> | 1 | +<% extend CategoriesHelper %> |
| 2 | + | ||
| 2 | <% if !@current_category.nil? %> | 3 | <% if !@current_category.nil? %> |
| 3 | - <h3 class="box-title"><%= _('Current category:') %></h3> | ||
| 4 | <%= hidden_field_tag "#{object_name}[#{object_name}_category_id]", @current_category.id unless multiple %> | 4 | <%= hidden_field_tag "#{object_name}[#{object_name}_category_id]", @current_category.id unless multiple %> |
| 5 | + <%= hidden_field_tag "#{object_name}[category_ids][]", @current_category.id if multiple %> | ||
| 6 | + <%= button_to_remote_without_text(:back, _('Back'), | ||
| 7 | + { :update => "select-categories", | ||
| 8 | + :url => { :action => 'update_categories', :id => @object }, | ||
| 9 | + :loaded => visual_effect(:highlight, "select-categories") | ||
| 10 | + }, | ||
| 11 | + :id => 'cancel-category-button') %> | ||
| 5 | <% | 12 | <% |
| 6 | categories = [@current_category] | 13 | categories = [@current_category] |
| 7 | categories.push(@current_category) while @current_category = @current_category.parent | 14 | categories.push(@current_category) while @current_category = @current_category.parent |
| 8 | %> | 15 | %> |
| 9 | <%= categories.compact.reverse.map{|i| | 16 | <%= categories.compact.reverse.map{|i| |
| 10 | - link_to_remote(i.name, | 17 | + link_to_remote(i.name, |
| 11 | :update => "select-categories", | 18 | :update => "select-categories", |
| 12 | :url => { :action => 'update_categories', :category_id => i.id, :id => @object }, | 19 | :url => { :action => 'update_categories', :category_id => i.id, :id => @object }, |
| 13 | :loaded => visual_effect(:highlight, "select-categories"), | 20 | :loaded => visual_effect(:highlight, "select-categories"), |
| 14 | :class => 'select-current-category-link')}.join(' → ') | 21 | :class => 'select-current-category-link')}.join(' → ') |
| 15 | %> | 22 | %> |
| 16 | - <strong> | ||
| 17 | - <%= button_to_function_without_text(:save, _('Save'), nil, :id => 'save-category-button') do |page| | ||
| 18 | - page.insert_html :bottom, 'selected-categories', content_tag('li', categories.first.full_name + | 23 | + <%= button_to_function_without_text(:add, _('Add'), nil, :id => 'save-category-button') do |page| |
| 24 | + page.insert_html :bottom, 'selected-categories', content_tag('div', | ||
| 19 | hidden_field_tag("#{object_name}[category_ids][]", categories.first.id) + | 25 | hidden_field_tag("#{object_name}[category_ids][]", categories.first.id) + |
| 20 | - button_to_function_without_text(:cancel, _('Remove'), nil, :id => "remove-selected-category-#{categories.first.id}-button") {|page| page["selected-category-#{categories.first.id}"].remove}, :id => "selected-category-#{categories.first.id}") | 26 | + selected_category_link(categories.first), :id => "selected-category-#{categories.first.id}") |
| 27 | + page.replace_html 'select-categories', :partial => 'shared/select_subcategories', | ||
| 28 | + :locals => {:object_name => object_name, :categories => @toplevel_categories} | ||
| 21 | end if multiple %> | 29 | end if multiple %> |
| 22 | - <%= button_to_remote_without_text(:cancel, _('Cancel'), | ||
| 23 | - { :update => "select-categories", | ||
| 24 | - :url => { :action => 'update_categories', :id => @object }, | ||
| 25 | - :loaded => visual_effect(:highlight, "select-categories") | ||
| 26 | - }, | ||
| 27 | - :id => 'cancel-category-button') %> | ||
| 28 | - </strong> | ||
| 29 | -<% else %> | ||
| 30 | - <h3 class="box-title"><%= _('Select a category:') %></h3> | ||
| 31 | <% end %> | 30 | <% end %> |
| 32 | 31 | ||
| 33 | -<% if !@categories.empty? %> | ||
| 34 | - <h3><%= _('Categories:') %></h3> | ||
| 35 | - <% @categories.select{|i| !@object.respond_to?(:accept_category?) || @object.accept_category?(i)}.each do |category| %> | ||
| 36 | - <%= link_to_remote category.name, | ||
| 37 | - { :update => "select-categories", | ||
| 38 | - :url => { :action => "update_categories", :category_id => category.id, :id => @object}, | ||
| 39 | - :loaded => visual_effect(:highlight, "select-categories") | ||
| 40 | - }, | ||
| 41 | - :class => 'select-subcategory-link', | ||
| 42 | - :id => "select-category-#{category.id}-link" | ||
| 43 | - %> | ||
| 44 | - <% end %> | ||
| 45 | -<% end %> | 32 | +<div class="toplevel-categories"> |
| 33 | + <%= render :partial => 'shared/select_subcategories', :locals => {:object_name => object_name, :categories => @categories} %> | ||
| 46 | </div> | 34 | </div> |
| @@ -0,0 +1,26 @@ | @@ -0,0 +1,26 @@ | ||
| 1 | +<% categories_selected ||= nil %> | ||
| 2 | +<% title ||= nil %> | ||
| 3 | + | ||
| 4 | +<% extend CategoriesHelper %> | ||
| 5 | + | ||
| 6 | +<%= content_tag "h#{title_size}", title, :class => "box-title" %> | ||
| 7 | + | ||
| 8 | +<%= hidden_field_tag "#{object_name}[category_ids][]", nil %> | ||
| 9 | + | ||
| 10 | +<div id="category-ajax-selector"> | ||
| 11 | +<% unless categories_selected.nil? %> | ||
| 12 | +<div id="selected-categories"> | ||
| 13 | + <div class="label"><%= _('Selected categories:') %></div> | ||
| 14 | + <% categories_selected.each do |cat| %> | ||
| 15 | + <div id="selected-category-<%= cat.id %>"> | ||
| 16 | + <%= hidden_field_tag("#{object_name}[category_ids][]", cat.id) %> | ||
| 17 | + <%= selected_category_link(cat) %> | ||
| 18 | + </div> | ||
| 19 | + <% end %> | ||
| 20 | +</div> | ||
| 21 | +<% end %> | ||
| 22 | +<div id="select-categories"> | ||
| 23 | + <%= render :partial => 'shared/select_categories', :locals => {:object_name => object_name, :multiple => true, :categories_selected => categories_selected }, :layout => false %> | ||
| 24 | +</div> | ||
| 25 | + | ||
| 26 | +</div> |
| @@ -0,0 +1,16 @@ | @@ -0,0 +1,16 @@ | ||
| 1 | +<% if !categories.nil? && !categories.empty? && !@object.nil? %> | ||
| 2 | + <hr> | ||
| 3 | + <div class="category-helper-label"><%= _('Click to select a category') %></div> | ||
| 4 | + | ||
| 5 | + <% categories.select{|i| @object.accept_category?(i)}.each do |category| %> | ||
| 6 | + | ||
| 7 | + <%= link_to_remote category.name, | ||
| 8 | + { :update => "select-categories", | ||
| 9 | + :url => { :action => "update_categories", :category_id => category.id, :id => @object}, | ||
| 10 | + :loaded => visual_effect(:highlight, "select-categories") | ||
| 11 | + }, | ||
| 12 | + :class => 'select-subcategory-link', | ||
| 13 | + :id => "select-category-#{category.id}-link" | ||
| 14 | + %> | ||
| 15 | + <% end %> | ||
| 16 | +<% end %> |
app/views/shared/block.html.erb
| 1 | <% if block.cacheable? && use_cache %> | 1 | <% if block.cacheable? && use_cache %> |
| 2 | - <% cache_timeout(block.cache_key(language), block.timeout) do %> | 2 | + <% cache_timeout(block.cache_key(language, user), block.timeout) do %> |
| 3 | <%= display_block_content(block, user, main_content) %> | 3 | <%= display_block_content(block, user, main_content) %> |
| 4 | <% end %> | 4 | <% end %> |
| 5 | <% else %> | 5 | <% else %> |
app/views/themes/_select_template.html.erb
| @@ -12,7 +12,7 @@ | @@ -12,7 +12,7 @@ | ||
| 12 | "/designs/templates/#{template.id}/thumbnail.png", | 12 | "/designs/templates/#{template.id}/thumbnail.png", |
| 13 | :alt => _('The "%s" template')) + | 13 | :alt => _('The "%s" template')) + |
| 14 | '<div class="opt-info">'.html_safe + | 14 | '<div class="opt-info">'.html_safe + |
| 15 | - content_tag('strong', template.name, :class => 'name') + | 15 | + content_tag('strong', template.name, :title => template.title, :class => 'name') + |
| 16 | ' <br/> '.html_safe | 16 | ' <br/> '.html_safe |
| 17 | 17 | ||
| 18 | if @current_template == template.id # selected | 18 | if @current_template == template.id # selected |
app/views/user/mailer/activation_code.html.erb
| 1 | <%= _('Hi, %{recipient}!') % { :recipient => @recipient } %> | 1 | <%= _('Hi, %{recipient}!') % { :recipient => @recipient } %> |
| 2 | 2 | ||
| 3 | -<%= word_wrap(_('Welcome to %{environment}! To activate your account, follow the link: %{activation_url}') % { :environment => @environment, :activation_url => @url + url_for(:controller => :account, :action => :activate, :activation_code => @activation_code) }) %> | 3 | +<%= word_wrap(_('Welcome to %{environment}! To activate your account, follow the link: %{activation_url}') % { :environment => @environment, :activation_url => @url + url_for(:controller => :account, :action => :activate, :activation_code => @activation_code, :redirection => @redirection) }) %> |
| 4 | 4 | ||
| 5 | <%= _("Greetings,") %> | 5 | <%= _("Greetings,") %> |
| 6 | 6 |
app/views/users/_users_list.html.erb
| 1 | <div class="environment-users-results-header"> | 1 | <div class="environment-users-results-header"> |
| 2 | - <div id='environment-users-filter-title'><%= users_filter_title(@filter) %></div> | 2 | + <div id='environment-users-filter-title'><%= filter_title(@filter) %></div> |
| 3 | <%= filter_selector(@filter) %> | 3 | <%= filter_selector(@filter) %> |
| 4 | <div style="clear: both"></div> | 4 | <div style="clear: both"></div> |
| 5 | </div> | 5 | </div> |
| @@ -19,16 +19,17 @@ | @@ -19,16 +19,17 @@ | ||
| 19 | <td class='actions'> | 19 | <td class='actions'> |
| 20 | <div class="members-buttons-cell"> | 20 | <div class="members-buttons-cell"> |
| 21 | <% if p.is_admin? %> | 21 | <% if p.is_admin? %> |
| 22 | - <%= button_without_text :'reset-admin-role', _('Reset admin role'), :action => 'reset_admin_role', :id => p, :q => @q, :filter => @filter %> | 22 | + <%= button_without_text :'reset-admin-role', _('Reset admin role'), {:action => 'reset_admin_role', :id => p, :q => @q}, :filter => @filter, :confirm => _("Do you want to reset this user as administrator?") %> |
| 23 | <% else %> | 23 | <% else %> |
| 24 | - <%= button_without_text :'set-admin-role', _('Set admin role'), :action => 'set_admin_role', :id => p, :q => @q, :filter => @filter %> | 24 | + <%= button_without_text :'set-admin-role', _('Set admin role'), {:action => 'set_admin_role', :id => p, :q => @q}, :filter => @filter, :confirm => _("Do you want to set this user as administrator?") %> |
| 25 | <% end %> | 25 | <% end %> |
| 26 | <% if !p.user.activated? %> | 26 | <% if !p.user.activated? %> |
| 27 | - <%= button_without_text :'activate-user', _('Activate user'), :action => 'activate', :id => p, :q => @q, :filter => @filter %> | 27 | + <%= button_without_text :'activate-user', _('Activate user'), {:action => 'activate', :id => p, :q => @q}, :filter => @filter, :confirm => _("Do you want to activate this user?") %> |
| 28 | <% else %> | 28 | <% else %> |
| 29 | - <%= button_without_text :'deactivate-user', _('Deactivate user'), :action => 'deactivate', :id => p, :q => @q, :filter => @filter %> | 29 | + <%= button_without_text :'deactivate-user', _('Deactivate user'), {:action => 'deactivate', :id => p, :q => @q}, :filter => @filter, :confirm => _("Do you want to deactivate this user?") %> |
| 30 | <% end %> | 30 | <% end %> |
| 31 | - </div> | 31 | + <%= button_without_text :'delete', _('Remove'), {:action => :destroy_user, :id => p, :q => @q}, :method => :post, :filter => @filter, :confirm => _("Do you want to remove this user?") %> |
| 32 | + </div> | ||
| 32 | </td> | 33 | </td> |
| 33 | </tr> | 34 | </tr> |
| 34 | <% end %> | 35 | <% end %> |
| @@ -0,0 +1,6 @@ | @@ -0,0 +1,6 @@ | ||
| 1 | +if Delayed::Backend::ActiveRecord::Job.table_exists? | ||
| 2 | + job = Delayed::Backend::ActiveRecord::Job.all :conditions => ['handler LIKE ?', "%ActivitiesCounterCacheJob%"] | ||
| 3 | + if job.blank? | ||
| 4 | + Delayed::Backend::ActiveRecord::Job.enqueue(ActivitiesCounterCacheJob.new, -3) | ||
| 5 | + end | ||
| 6 | +end |
config/initializers/delayed_job_config.rb
| 1 | require 'delayed_job' | 1 | require 'delayed_job' |
| 2 | Delayed::Worker.backend = :active_record | 2 | Delayed::Worker.backend = :active_record |
| 3 | Delayed::Worker.max_attempts = 2 | 3 | Delayed::Worker.max_attempts = 2 |
| 4 | -Delayed::Worker.max_run_time = 10.minutes | 4 | + |
| 5 | +# TODO This is consuming ton of space on development with a postgres connection | ||
| 6 | +# error on the jobs. This must be verified before going into production. | ||
| 7 | +# Logging jobs backtraces | ||
| 8 | +#class Delayed::Worker | ||
| 9 | +# def handle_failed_job_with_loggin(job, error) | ||
| 10 | +# handle_failed_job_without_loggin(job,error) | ||
| 11 | +# Delayed::Worker.logger.error(error.message) | ||
| 12 | +# Delayed::Worker.logger.error(error.backtrace.join("\n")) | ||
| 13 | +# end | ||
| 14 | +# alias_method_chain :handle_failed_job, :loggin | ||
| 15 | +#end |
config/routes.rb
| @@ -31,6 +31,9 @@ Noosfero::Application.routes.draw do | @@ -31,6 +31,9 @@ Noosfero::Application.routes.draw do | ||
| 31 | match 'thumbnails(/*stuff)' => 'not_found#nothing' | 31 | match 'thumbnails(/*stuff)' => 'not_found#nothing' |
| 32 | match 'user_themes(/*stuff)' => 'not_found#nothing' | 32 | match 'user_themes(/*stuff)' => 'not_found#nothing' |
| 33 | 33 | ||
| 34 | + # embed controller | ||
| 35 | + map.embed 'embed/:action/:id', :controller => 'embed', :id => /\d+/ | ||
| 36 | + | ||
| 34 | # online documentation | 37 | # online documentation |
| 35 | match 'doc' => 'doc#index', :as => :doc | 38 | match 'doc' => 'doc#index', :as => :doc |
| 36 | match 'doc/:section' => 'doc#section', :as => :doc_section | 39 | match 'doc/:section' => 'doc#section', :as => :doc_section |
db/migrate/20140205191914_add_redirection_after_signup_to_environment.rb
0 → 100644
| @@ -0,0 +1,9 @@ | @@ -0,0 +1,9 @@ | ||
| 1 | +class AddRedirectionAfterSignupToEnvironment < ActiveRecord::Migration | ||
| 2 | + def self.up | ||
| 3 | + add_column :environments, :redirection_after_signup, :string, :default => 'keep_on_same_page' | ||
| 4 | + end | ||
| 5 | + | ||
| 6 | + def self.down | ||
| 7 | + remove_column :environments, :redirection_after_signup | ||
| 8 | + end | ||
| 9 | +end |
db/migrate/20140221142304_move_title_virtual_field_to_name_in_uploaded_file.rb
0 → 100644
| @@ -0,0 +1,12 @@ | @@ -0,0 +1,12 @@ | ||
| 1 | +class MoveTitleVirtualFieldToNameInUploadedFile < ActiveRecord::Migration | ||
| 2 | + def self.up | ||
| 3 | + UploadedFile.find_each do |uploaded_file| | ||
| 4 | + uploaded_file.name = uploaded_file.setting.delete :title | ||
| 5 | + uploaded_file.send :update_without_callbacks | ||
| 6 | + end | ||
| 7 | + end | ||
| 8 | + | ||
| 9 | + def self.down | ||
| 10 | + say "this migration can't be reverted" | ||
| 11 | + end | ||
| 12 | +end |
db/migrate/20140303173209_move_contact_email_to_noreply_email_at_environment.rb
0 → 100644
| @@ -0,0 +1,16 @@ | @@ -0,0 +1,16 @@ | ||
| 1 | +class MoveContactEmailToNoreplyEmailAtEnvironment < ActiveRecord::Migration | ||
| 2 | + def self.up | ||
| 3 | + add_column :environments, :noreply_email, :string | ||
| 4 | + Environment.reset_column_information | ||
| 5 | + | ||
| 6 | + Environment.find_each do |environment| | ||
| 7 | + environment.noreply_email = environment.contact_email | ||
| 8 | + environment.contact_email = nil | ||
| 9 | + environment.save! | ||
| 10 | + end | ||
| 11 | + end | ||
| 12 | + | ||
| 13 | + def self.down | ||
| 14 | + say "this migration can't be reverted" | ||
| 15 | + end | ||
| 16 | +end |
db/migrate/20140312132212_add_indexes_for_article_search.rb
0 → 100644
| @@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
| 1 | +class AddIndexesForArticleSearch < ActiveRecord::Migration | ||
| 2 | + def self.up | ||
| 3 | + add_index :articles, :created_at | ||
| 4 | + add_index :articles, :hits | ||
| 5 | + add_index :articles, :comments_count | ||
| 6 | + end | ||
| 7 | + | ||
| 8 | + def self.down | ||
| 9 | + remove_index :articles, :created_at | ||
| 10 | + remove_index :articles, :hits | ||
| 11 | + remove_index :articles, :comments_count | ||
| 12 | + end | ||
| 13 | +end |
db/migrate/20140312134218_add_indexes_for_profile_search.rb
0 → 100644
db/migrate/20140312141805_create_cache_counts_for_profiles.rb
0 → 100644
| @@ -0,0 +1,19 @@ | @@ -0,0 +1,19 @@ | ||
| 1 | +class CreateCacheCountsForProfiles < ActiveRecord::Migration | ||
| 2 | + def self.up | ||
| 3 | + add_column :profiles, :friends_count, :integer, :null => false, :default => 0 | ||
| 4 | + add_column :profiles, :members_count, :integer, :null => false, :default => 0 | ||
| 5 | + add_column :profiles, :activities_count, :integer, :null => false, :default => 0 | ||
| 6 | + add_index :profiles, :friends_count | ||
| 7 | + add_index :profiles, :members_count | ||
| 8 | + add_index :profiles, :activities_count | ||
| 9 | + end | ||
| 10 | + | ||
| 11 | + def self.down | ||
| 12 | + remove_column :profiles, :friends_count | ||
| 13 | + remove_column :profiles, :members_count | ||
| 14 | + remove_column :profiles, :activities_count | ||
| 15 | + remove_index :profiles, :friends_count | ||
| 16 | + remove_index :profiles, :members_count | ||
| 17 | + remove_index :profiles, :activities_count | ||
| 18 | + end | ||
| 19 | +end |
db/migrate/20140312144156_define_initial_value_for_profiles_friends_count.rb
0 → 100644
| @@ -0,0 +1,12 @@ | @@ -0,0 +1,12 @@ | ||
| 1 | +class DefineInitialValueForProfilesFriendsCount < ActiveRecord::Migration | ||
| 2 | + def self.up | ||
| 3 | + friends_counts = execute("SELECT profiles.id, count(profiles.id) FROM profiles INNER JOIN friendships ON ( profiles.id = friendships.friend_id AND profiles.type = E'Person') GROUP BY profiles.id;") | ||
| 4 | + friends_counts.each do |count| | ||
| 5 | + execute("UPDATE profiles SET friends_count=#{count['count'].to_i} WHERE profiles.id=#{count['id']};") | ||
| 6 | + end | ||
| 7 | + end | ||
| 8 | + | ||
| 9 | + def self.down | ||
| 10 | + execute("UPDATE profiles SET friends_count=0;") | ||
| 11 | + end | ||
| 12 | +end |
db/migrate/20140312151857_define_initial_value_for_profiles_activities_count.rb
0 → 100644
| @@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
| 1 | +class DefineInitialValueForProfilesActivitiesCount < ActiveRecord::Migration | ||
| 2 | + def self.up | ||
| 3 | + person_activities_counts = execute("SELECT profiles.id, count(action_tracker.id) as count FROM profiles LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.user_id WHERE (action_tracker.created_at >= '#{30.days.ago.to_s(:db)}') AND ( (profiles.type = 'Person' ) ) GROUP BY profiles.id;") | ||
| 4 | + organization_activities_counts = execute("SELECT profiles.id, count(action_tracker.id) as count FROM profiles LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.target_id WHERE (action_tracker.created_at >= '#{30.days.ago.to_s(:db)}') AND ( (profiles.type = 'Community' OR profiles.type = 'Enterprise' OR profiles.type = 'Organization' ) ) GROUP BY profiles.id;") | ||
| 5 | + activities_counts = person_activities_counts.entries + organization_activities_counts.entries | ||
| 6 | + activities_counts.each do |count| | ||
| 7 | + execute("UPDATE profiles SET activities_count=#{count['count'].to_i} WHERE profiles.id=#{count['id']};") | ||
| 8 | + end | ||
| 9 | + end | ||
| 10 | + | ||
| 11 | + def self.down | ||
| 12 | + execute("UPDATE profiles SET activities_count=0;") | ||
| 13 | + end | ||
| 14 | +end |
db/migrate/20140313213142_define_initial_value_for_profiles_members_count.rb
0 → 100644
| @@ -0,0 +1,12 @@ | @@ -0,0 +1,12 @@ | ||
| 1 | +class DefineInitialValueForProfilesMembersCount < ActiveRecord::Migration | ||
| 2 | + def self.up | ||
| 3 | + members_counts = execute("SELECT profiles.id, count(profiles.id) FROM profiles LEFT OUTER JOIN role_assignments ON profiles.id = role_assignments.resource_id WHERE (profiles.type = 'Organization' OR profiles.type = 'Community' OR profiles.type = 'Enterprise') GROUP BY profiles.id;") | ||
| 4 | + members_counts.each do |count| | ||
| 5 | + execute("UPDATE profiles SET members_count=#{count['count'].to_i} WHERE profiles.id=#{count['id']};") | ||
| 6 | + end | ||
| 7 | + end | ||
| 8 | + | ||
| 9 | + def self.down | ||
| 10 | + execute("UPDATE profiles SET members_count=0;") | ||
| 11 | + end | ||
| 12 | +end |
db/migrate/20140314200103_add_indexes_for_products_search.rb
0 → 100644
db/schema.rb
| @@ -11,7 +11,7 @@ | @@ -11,7 +11,7 @@ | ||
| 11 | # | 11 | # |
| 12 | # It's strongly recommended to check this file into your version control system. | 12 | # It's strongly recommended to check this file into your version control system. |
| 13 | 13 | ||
| 14 | -ActiveRecord::Schema.define(:version => 20140115190132) do | 14 | +ActiveRecord::Schema.define(:version => 20140314200103) do |
| 15 | 15 | ||
| 16 | create_table "abuse_reports", :force => true do |t| | 16 | create_table "abuse_reports", :force => true do |t| |
| 17 | t.integer "reporter_id" | 17 | t.integer "reporter_id" |
| @@ -142,6 +142,9 @@ ActiveRecord::Schema.define(:version => 20140115190132) do | @@ -142,6 +142,9 @@ ActiveRecord::Schema.define(:version => 20140115190132) do | ||
| 142 | t.integer "position" | 142 | t.integer "position" |
| 143 | end | 143 | end |
| 144 | 144 | ||
| 145 | + add_index "articles", ["comments_count"], :name => "index_articles_on_comments_count" | ||
| 146 | + add_index "articles", ["created_at"], :name => "index_articles_on_created_at" | ||
| 147 | + add_index "articles", ["hits"], :name => "index_articles_on_hits" | ||
| 145 | add_index "articles", ["name"], :name => "index_articles_on_name" | 148 | add_index "articles", ["name"], :name => "index_articles_on_name" |
| 146 | add_index "articles", ["parent_id"], :name => "index_articles_on_parent_id" | 149 | add_index "articles", ["parent_id"], :name => "index_articles_on_parent_id" |
| 147 | add_index "articles", ["profile_id"], :name => "index_articles_on_profile_id" | 150 | add_index "articles", ["profile_id"], :name => "index_articles_on_profile_id" |
| @@ -285,6 +288,8 @@ ActiveRecord::Schema.define(:version => 20140115190132) do | @@ -285,6 +288,8 @@ ActiveRecord::Schema.define(:version => 20140115190132) do | ||
| 285 | t.text "signup_welcome_text" | 288 | t.text "signup_welcome_text" |
| 286 | t.string "languages" | 289 | t.string "languages" |
| 287 | t.string "default_language" | 290 | t.string "default_language" |
| 291 | + t.string "redirection_after_signup", :default => "keep_on_same_page" | ||
| 292 | + t.string "noreply_email" | ||
| 288 | end | 293 | end |
| 289 | 294 | ||
| 290 | create_table "external_feeds", :force => true do |t| | 295 | create_table "external_feeds", :force => true do |t| |
| @@ -435,6 +440,7 @@ ActiveRecord::Schema.define(:version => 20140115190132) do | @@ -435,6 +440,7 @@ ActiveRecord::Schema.define(:version => 20140115190132) do | ||
| 435 | t.boolean "archived", :default => false | 440 | t.boolean "archived", :default => false |
| 436 | end | 441 | end |
| 437 | 442 | ||
| 443 | + add_index "products", ["created_at"], :name => "index_products_on_created_at" | ||
| 438 | add_index "products", ["product_category_id"], :name => "index_products_on_product_category_id" | 444 | add_index "products", ["product_category_id"], :name => "index_products_on_product_category_id" |
| 439 | add_index "products", ["profile_id"], :name => "index_products_on_profile_id" | 445 | add_index "products", ["profile_id"], :name => "index_products_on_profile_id" |
| 440 | 446 | ||
| @@ -473,10 +479,17 @@ ActiveRecord::Schema.define(:version => 20140115190132) do | @@ -473,10 +479,17 @@ ActiveRecord::Schema.define(:version => 20140115190132) do | ||
| 473 | t.string "redirection_after_login" | 479 | t.string "redirection_after_login" |
| 474 | t.string "personal_website" | 480 | t.string "personal_website" |
| 475 | t.string "jabber_id" | 481 | t.string "jabber_id" |
| 482 | + t.integer "friends_count", :default => 0, :null => false | ||
| 483 | + t.integer "members_count", :default => 0, :null => false | ||
| 484 | + t.integer "activities_count", :default => 0, :null => false | ||
| 476 | end | 485 | end |
| 477 | 486 | ||
| 487 | + add_index "profiles", ["activities_count"], :name => "index_profiles_on_activities_count" | ||
| 488 | + add_index "profiles", ["created_at"], :name => "index_profiles_on_created_at" | ||
| 478 | add_index "profiles", ["environment_id"], :name => "index_profiles_on_environment_id" | 489 | add_index "profiles", ["environment_id"], :name => "index_profiles_on_environment_id" |
| 490 | + add_index "profiles", ["friends_count"], :name => "index_profiles_on_friends_count" | ||
| 479 | add_index "profiles", ["identifier"], :name => "index_profiles_on_identifier" | 491 | add_index "profiles", ["identifier"], :name => "index_profiles_on_identifier" |
| 492 | + add_index "profiles", ["members_count"], :name => "index_profiles_on_members_count" | ||
| 480 | add_index "profiles", ["region_id"], :name => "index_profiles_on_region_id" | 493 | add_index "profiles", ["region_id"], :name => "index_profiles_on_region_id" |
| 481 | 494 | ||
| 482 | create_table "qualifier_certifiers", :force => true do |t| | 495 | create_table "qualifier_certifiers", :force => true do |t| |
| @@ -627,6 +640,7 @@ ActiveRecord::Schema.define(:version => 20140115190132) do | @@ -627,6 +640,7 @@ ActiveRecord::Schema.define(:version => 20140115190132) do | ||
| 627 | t.datetime "chat_status_at" | 640 | t.datetime "chat_status_at" |
| 628 | t.string "activation_code", :limit => 40 | 641 | t.string "activation_code", :limit => 40 |
| 629 | t.datetime "activated_at" | 642 | t.datetime "activated_at" |
| 643 | + t.string "return_to" | ||
| 630 | end | 644 | end |
| 631 | 645 | ||
| 632 | create_table "validation_infos", :force => true do |t| | 646 | create_table "validation_infos", :force => true do |t| |
debian/changelog
| 1 | +noosfero (0.47.0~rc1) squeeze-test; urgency=low | ||
| 2 | + | ||
| 3 | + * New features Release Candidate 1 | ||
| 4 | + | ||
| 5 | + -- Rodrigo Souto <rodrigo@colivre.coop.br> Thu, 20 Mar 2014 20:26:45 +0000 | ||
| 6 | + | ||
| 7 | +noosfero (0.46.2) unstable; urgency=low | ||
| 8 | + | ||
| 9 | + * Bugfix release | ||
| 10 | + | ||
| 11 | + -- Rodrigo Souto <rodrigo@colivre.coop.br> Wed, 19 Mar 2014 23:41:06 +0000 | ||
| 12 | + | ||
| 1 | noosfero (0.46.1) unstable; urgency=low | 13 | noosfero (0.46.1) unstable; urgency=low |
| 2 | 14 | ||
| 3 | * Bugfixes release | 15 | * Bugfixes release |
features/balloon.feature
| @@ -8,6 +8,7 @@ Feature: balloon | @@ -8,6 +8,7 @@ Feature: balloon | ||
| 8 | And the following communities | 8 | And the following communities |
| 9 | | identifier | name | | 9 | | identifier | name | |
| 10 | | sample | Sample | | 10 | | sample | Sample | |
| 11 | + And I am logged in as "joaosilva" | ||
| 11 | 12 | ||
| 12 | @selenium | 13 | @selenium |
| 13 | Scenario: I should not see trigger if not enabled | 14 | Scenario: I should not see trigger if not enabled |
features/categories_block.feature
| @@ -24,16 +24,12 @@ Feature: categories_block | @@ -24,16 +24,12 @@ Feature: categories_block | ||
| 24 | | owner | type | | 24 | | owner | type | |
| 25 | | environment | CategoriesBlock | | 25 | | environment | CategoriesBlock | |
| 26 | And I am logged in as admin | 26 | And I am logged in as admin |
| 27 | + And I go to /admin/environment_design | ||
| 28 | + And display ".button-bar" | ||
| 27 | 29 | ||
| 28 | - # Note that this @ignore-hidden-elements only works for seeing hidden | ||
| 29 | - # elements. It actually doesn't work for following hidden link or pressing | ||
| 30 | - # hidden buttons. That's why it's necessary to use this display hack to show | ||
| 31 | - # the link. | ||
| 32 | - @selenium @ignore-hidden-elements | 30 | + @selenium |
| 33 | Scenario: List just product categories | 31 | Scenario: List just product categories |
| 34 | - Given I go to /admin/environment_design | ||
| 35 | - And display ".categories-block .button-bar" | ||
| 36 | - And I follow "Edit" within ".categories-block" | 32 | + Given I follow "Edit" within ".categories-block" |
| 37 | And I check "Product" | 33 | And I check "Product" |
| 38 | When I press "Save" | 34 | When I press "Save" |
| 39 | Then I should see "Food" | 35 | Then I should see "Food" |
| @@ -42,11 +38,9 @@ Feature: categories_block | @@ -42,11 +38,9 @@ Feature: categories_block | ||
| 42 | And "Steak" should not be visible within "span#category-name" | 38 | And "Steak" should not be visible within "span#category-name" |
| 43 | And "Fiction" should not be visible within "span#category-name" | 39 | And "Fiction" should not be visible within "span#category-name" |
| 44 | 40 | ||
| 45 | - @selenium @ignore-hidden-elements | 41 | + @selenium |
| 46 | Scenario: Show submenu if it exists | 42 | Scenario: Show submenu if it exists |
| 47 | - Given I go to /admin/environment_design | ||
| 48 | - And display ".categories-block .button-bar" | ||
| 49 | - And I follow "Edit" within ".categories-block" | 43 | + Given I follow "Edit" within ".categories-block" |
| 50 | And I check "Product" | 44 | And I check "Product" |
| 51 | And I press "Save" | 45 | And I press "Save" |
| 52 | Then I should see "Food" | 46 | Then I should see "Food" |
| @@ -61,11 +55,9 @@ Feature: categories_block | @@ -61,11 +55,9 @@ Feature: categories_block | ||
| 61 | And I should see "Steak" | 55 | And I should see "Steak" |
| 62 | And I should not see "Fiction" | 56 | And I should not see "Fiction" |
| 63 | 57 | ||
| 64 | - @selenium @ignore-hidden-elements | 58 | + @selenium |
| 65 | Scenario: Show only one submenu per time | 59 | Scenario: Show only one submenu per time |
| 66 | - Given I go to /admin/environment_design | ||
| 67 | - And display ".categories-block .button-bar" | ||
| 68 | - And I follow "Edit" within ".categories-block" | 60 | + Given I follow "Edit" within ".categories-block" |
| 69 | And I check "Product" | 61 | And I check "Product" |
| 70 | And I press "Save" | 62 | And I press "Save" |
| 71 | Then I should see "Book" | 63 | Then I should see "Book" |
| @@ -73,20 +65,16 @@ Feature: categories_block | @@ -73,20 +65,16 @@ Feature: categories_block | ||
| 73 | When I follow "block_2_category_2" | 65 | When I follow "block_2_category_2" |
| 74 | Then I should see "Literature" | 66 | Then I should see "Literature" |
| 75 | 67 | ||
| 76 | - @selenium @ignore-hidden-elements | 68 | + @selenium |
| 77 | Scenario: List just general categories | 69 | Scenario: List just general categories |
| 78 | - Given I go to /admin/environment_design | ||
| 79 | - And display ".categories-block .button-bar" | ||
| 80 | - And I follow "Edit" within ".categories-block" | 70 | + Given I follow "Edit" within ".categories-block" |
| 81 | And I check "Generic category" | 71 | And I check "Generic category" |
| 82 | When I press "Save" | 72 | When I press "Save" |
| 83 | Then I should see "Wood" | 73 | Then I should see "Wood" |
| 84 | 74 | ||
| 85 | - @selenium @ignore-hidden-elements | 75 | + @selenium |
| 86 | Scenario: List just regions | 76 | Scenario: List just regions |
| 87 | - Given I go to /admin/environment_design | ||
| 88 | - And display ".categories-block .button-bar" | ||
| 89 | - And I follow "Edit" within ".categories-block" | 77 | + Given I follow "Edit" within ".categories-block" |
| 90 | And I check "Region" | 78 | And I check "Region" |
| 91 | When I press "Save" | 79 | When I press "Save" |
| 92 | Then I should see "Bahia" | 80 | Then I should see "Bahia" |
features/comment.feature
| @@ -39,7 +39,7 @@ Feature: comment | @@ -39,7 +39,7 @@ Feature: comment | ||
| 39 | When I press "Post comment" | 39 | When I press "Post comment" |
| 40 | Then I should see "Hey ho, let's go" | 40 | Then I should see "Hey ho, let's go" |
| 41 | 41 | ||
| 42 | - @selenium | 42 | + @selenium-fixme |
| 43 | Scenario: redirect to right place after comment a picture | 43 | Scenario: redirect to right place after comment a picture |
| 44 | Given the following files | 44 | Given the following files |
| 45 | | owner | file | mime | | 45 | | owner | file | mime | |
| @@ -97,3 +97,41 @@ Feature: comment | @@ -97,3 +97,41 @@ Feature: comment | ||
| 97 | Given I am on /booking/article-to-comment | 97 | Given I am on /booking/article-to-comment |
| 98 | And I follow "Post a comment" | 98 | And I follow "Post a comment" |
| 99 | Then "Post a comment" should not be visible within "#article" | 99 | Then "Post a comment" should not be visible within "#article" |
| 100 | + | ||
| 101 | + @selenium | ||
| 102 | + Scenario: the newest post from a forum should be displayed first. | ||
| 103 | + Given the following users | ||
| 104 | + | login | name | | ||
| 105 | + | joaosilva | Joao Silva | | ||
| 106 | + And the following forums | ||
| 107 | + | owner | name | | ||
| 108 | + | joaosilva | Forum | | ||
| 109 | + And the following articles | ||
| 110 | + | owner | name | parent | | ||
| 111 | + | joaosilva | Post one | Forum | | ||
| 112 | + And the following comments | ||
| 113 | + | article | author | title | body | | ||
| 114 | + | Post one | joaosilva | Hi all | Hi all | | ||
| 115 | + | Post one | joaosilva | Hello | Hello | | ||
| 116 | + When I go to /joaosilva/forum/post-one | ||
| 117 | + And I select "Newest first" from "comment_order" within ".comment-order" | ||
| 118 | + Then I should see "Hello" within ".article-comment" | ||
| 119 | + | ||
| 120 | + @selenium | ||
| 121 | + Scenario: the oldest post from a forum should be displayed first. | ||
| 122 | + Given the following users | ||
| 123 | + | login | name | | ||
| 124 | + | joaosilva | Joao Silva | | ||
| 125 | + And the following forums | ||
| 126 | + | owner | name | | ||
| 127 | + | joaosilva | Forum | | ||
| 128 | + And the following articles | ||
| 129 | + | owner | name | parent | | ||
| 130 | + | joaosilva | Post one | Forum | | ||
| 131 | + And the following comments | ||
| 132 | + | article | author | title | body | | ||
| 133 | + | Post one | joaosilva | Hi all | Hi all | | ||
| 134 | + | Post one | joaosilva | Hello | Hello | | ||
| 135 | + When I go to /joaosilva/forum/post-one | ||
| 136 | + And I select "Oldest first" from "comment_order" within ".comment-order" | ||
| 137 | + Then I should see "Hi all" within ".article-comment" |
features/events.feature
| @@ -244,3 +244,38 @@ Feature: events | @@ -244,3 +244,38 @@ Feature: events | ||
| 244 | Given I am on /profile/josesilva/events/2009/10 | 244 | Given I am on /profile/josesilva/events/2009/10 |
| 245 | When I follow "Oktoberfest" | 245 | When I follow "Oktoberfest" |
| 246 | Then I should see "Oktoberfest" | 246 | Then I should see "Oktoberfest" |
| 247 | + | ||
| 248 | + Scenario: list events paginated for a specific profile for the month | ||
| 249 | + Given I am logged in as admin | ||
| 250 | + And the following users | ||
| 251 | + | login | | ||
| 252 | + | josemanuel | | ||
| 253 | + And I am logged in as "josemanuel" | ||
| 254 | + And the following events | ||
| 255 | + | owner | name | start_date | | ||
| 256 | + | josemanuel | Event 5 | 2009-10-12 | | ||
| 257 | + | josemanuel | Event 3 | 2009-10-15 | | ||
| 258 | + | josemanuel | Test Event | 2009-10-15 | | ||
| 259 | + | josemanuel | Oktoberfest | 2009-10-19 | | ||
| 260 | + | josemanuel | WikiSym | 2009-10-21 | | ||
| 261 | + | josemanuel | Free Software | 2009-10-22 | | ||
| 262 | + | josemanuel | Rachel Birthday | 2009-10-23 | | ||
| 263 | + | josemanuel | Manuel Birthday | 2009-10-24 | | ||
| 264 | + | josemanuel | Michelle Birthday | 2009-10-25 | | ||
| 265 | + | josemanuel | Lecture Allien 10 | 2009-10-26 | | ||
| 266 | + | josemanuel | Lecture Allien 11 | 2009-10-26 | | ||
| 267 | + | josemanuel | Lecture Allien 12 | 2009-10-26 | | ||
| 268 | + | josemanuel | Lecture Allien 13 | 2009-10-26 | | ||
| 269 | + | josemanuel | Lecture Allien 14 | 2009-10-26 | | ||
| 270 | + | josemanuel | Lecture Allien 15 | 2009-10-26 | | ||
| 271 | + | josemanuel | Lecture Allien 16 | 2009-10-26 | | ||
| 272 | + | josemanuel | Lecture Allien 17 | 2009-10-26 | | ||
| 273 | + | josemanuel | Lecture Allien 18 | 2009-10-26 | | ||
| 274 | + | josemanuel | Lecture Allien 19 | 2009-10-26 | | ||
| 275 | + | josemanuel | Lecture Allien 20 | 2009-10-26 | | ||
| 276 | + | josemanuel | Party On | 2009-10-27 | | ||
| 277 | + | ||
| 278 | + When I am on /profile/josemanuel/events/2009/10 | ||
| 279 | + Then I should not see "Party On" within "#agenda-items" | ||
| 280 | + When I follow "Next" | ||
| 281 | + Then I should see "Party On" within "#agenda-items" |
features/forum.feature
| @@ -166,3 +166,121 @@ Feature: forum | @@ -166,3 +166,121 @@ Feature: forum | ||
| 166 | | Post one | joaosilva | Hi all | Hi all | | 166 | | Post one | joaosilva | Hi all | Hi all | |
| 167 | When I go to /joaosilva/forum | 167 | When I go to /joaosilva/forum |
| 168 | Then I should see "Joao" linking to "http://localhost/joaosilva/" | 168 | Then I should see "Joao" linking to "http://localhost/joaosilva/" |
| 169 | + | ||
| 170 | + @selenium | ||
| 171 | + Scenario: community member should be able to see the discussion topic button | ||
| 172 | + Given the following community | ||
| 173 | + | identifier | name | owner | | ||
| 174 | + | sample-community | Sample Community | joaosilva | | ||
| 175 | + And the following forums | ||
| 176 | + | owner | name | | ||
| 177 | + | sample-community | Forum | | ||
| 178 | + And the following users | ||
| 179 | + | login | name | | ||
| 180 | + | mariasilva | Maria Silva| | ||
| 181 | + And "Maria Silva" is a member of "Sample Community" | ||
| 182 | + And I am logged in as "joaosilva" | ||
| 183 | + When I go to /sample-community/forum | ||
| 184 | + And I follow "Configure forum" | ||
| 185 | + And I check "Allow member to create topics" | ||
| 186 | + And I press "Save" | ||
| 187 | + And I am logged in as "mariasilva" | ||
| 188 | + And I go to /sample-community/forum | ||
| 189 | + Then I should see "New discussion topic" | ||
| 190 | + | ||
| 191 | + @selenium | ||
| 192 | + Scenario: a non community member should not be able to see the discussion topic button | ||
| 193 | + Given the following community | ||
| 194 | + | identifier | name | owner | | ||
| 195 | + | sample-community | Sample Community | joaosilva | | ||
| 196 | + And the following forums | ||
| 197 | + | owner | name | | ||
| 198 | + | sample-community | Forum | | ||
| 199 | + And the following users | ||
| 200 | + | login | name | | ||
| 201 | + | mariasilva | Maria Silva| | ||
| 202 | + And I am logged in as "joaosilva" | ||
| 203 | + When I go to /sample-community/forum | ||
| 204 | + And I follow "Configure forum" | ||
| 205 | + And I check "Allow member to create topics" | ||
| 206 | + And I press "Save" | ||
| 207 | + And I am logged in as "mariasilva" | ||
| 208 | + And I go to /sample-community/forum | ||
| 209 | + Then I should not see "New discussion topic" | ||
| 210 | + | ||
| 211 | + @selenium | ||
| 212 | + Scenario: community member should not be able to see the discussion topic button | ||
| 213 | + Given the following community | ||
| 214 | + | identifier | name | owner | | ||
| 215 | + | sample-community | Sample Community | joaosilva | | ||
| 216 | + And the following forums | ||
| 217 | + | owner | name | | ||
| 218 | + | sample-community | Forum | | ||
| 219 | + And the following users | ||
| 220 | + | login | name | | ||
| 221 | + | mariasilva | Maria Silva| | ||
| 222 | + And "Maria Silva" is a member of "Sample Community" | ||
| 223 | + And I am logged in as "joaosilva" | ||
| 224 | + When I go to /sample-community/forum | ||
| 225 | + And I follow "Configure forum" | ||
| 226 | + And I uncheck "Allow member to create topics" | ||
| 227 | + And I press "Save" | ||
| 228 | + And I am logged in as "mariasilva" | ||
| 229 | + And I go to /sample-community/forum | ||
| 230 | + Then I should not see "New discussion topic" | ||
| 231 | + | ||
| 232 | + @selenium | ||
| 233 | + Scenario: community member should be able to create a topic with the discussion topic button | ||
| 234 | + Given the following community | ||
| 235 | + | identifier | name | owner | | ||
| 236 | + | sample-community | Sample Community | joaosilva | | ||
| 237 | + And the following forums | ||
| 238 | + | owner | name | | ||
| 239 | + | sample-community | Forum | | ||
| 240 | + And the following users | ||
| 241 | + | login | name | | ||
| 242 | + | mariasilva | Maria Silva| | ||
| 243 | + And "Maria Silva" is a member of "Sample Community" | ||
| 244 | + And I am logged in as "joaosilva" | ||
| 245 | + When I go to /sample-community/forum | ||
| 246 | + And I follow "Configure forum" | ||
| 247 | + And I check "Allow member to create topics" | ||
| 248 | + And I press "Save" | ||
| 249 | + And I am logged in as "mariasilva" | ||
| 250 | + And I go to /sample-community/forum | ||
| 251 | + And I follow "New discussion topic" | ||
| 252 | + And I follow "Text article with visual editor" | ||
| 253 | + And I fill in "Title" with "Test" | ||
| 254 | + And I press "Save" | ||
| 255 | + Then I should see "Test" | ||
| 256 | + | ||
| 257 | + @selenium | ||
| 258 | + Scenario: community member should be able to create a topic on a topic page | ||
| 259 | + Given the following community | ||
| 260 | + | identifier | name | owner | | ||
| 261 | + | sample-community | Sample Community | joaosilva | | ||
| 262 | + And the following forums | ||
| 263 | + | owner | name | | ||
| 264 | + | sample-community | Forum | | ||
| 265 | + And the following users | ||
| 266 | + | login | name | | ||
| 267 | + | mariasilva | Maria Silva| | ||
| 268 | + And "Maria Silva" is a member of "Sample Community" | ||
| 269 | + And I am logged in as "joaosilva" | ||
| 270 | + When I go to /sample-community/forum | ||
| 271 | + And I follow "Configure forum" | ||
| 272 | + And I check "Allow member to create topics" | ||
| 273 | + And I press "Save" | ||
| 274 | + And I am logged in as "mariasilva" | ||
| 275 | + And I go to /sample-community/forum | ||
| 276 | + And I follow "New discussion topic" | ||
| 277 | + And I follow "Text article with visual editor" | ||
| 278 | + And I fill in "Title" with "Test" | ||
| 279 | + And I press "Save" | ||
| 280 | + And I go to /sample-community/forum/test | ||
| 281 | + And I follow "New discussion topic" | ||
| 282 | + And I follow "Text article with visual editor" | ||
| 283 | + And I fill in "Title" with "Test inside the topic page" | ||
| 284 | + And I press "Save" | ||
| 285 | + And I go to /sample-community/forum | ||
| 286 | + Then I should see "Test inside the topic page" | ||
| 169 | \ No newline at end of file | 287 | \ No newline at end of file |
| @@ -0,0 +1,76 @@ | @@ -0,0 +1,76 @@ | ||
| 1 | +Feature: check all manage fields | ||
| 2 | + As an administrator | ||
| 3 | + I want to check and uncheck all person, enterprise and community's fields | ||
| 4 | + | ||
| 5 | + Background: | ||
| 6 | + Given the following users | ||
| 7 | + | login | name | | ||
| 8 | + | mariasilva | Maria Silva | | ||
| 9 | + And the following enterprises | ||
| 10 | + | identifier | owner | name | contact_email | contact_phone | enabled | | ||
| 11 | + | paper-street | mariasilva | Paper Street | marial.silva@workerbees.org | (288) 555-0153 | true | | ||
| 12 | + And the following community | ||
| 13 | + | identifier | name | | ||
| 14 | + | mycommunity | My Community | | ||
| 15 | + And I am logged in as admin | ||
| 16 | + And I go to /admin/features/manage_fields | ||
| 17 | + | ||
| 18 | + @selenium | ||
| 19 | + Scenario: check all active person fields | ||
| 20 | + Given I follow "Person's fields" | ||
| 21 | + And I check "person_active" | ||
| 22 | + And I press "save_person_fields" | ||
| 23 | + When I go to admin_user's control panel | ||
| 24 | + And I follow "Edit Profile" | ||
| 25 | + Then I should see "Custom area of study" | ||
| 26 | + | ||
| 27 | + @selenium | ||
| 28 | + Scenario: check all active enterprise fields | ||
| 29 | + Given I follow "Enterprise's fields" | ||
| 30 | + And I check "enterprise_active" | ||
| 31 | + And I press "save_enterprise_fields" | ||
| 32 | + When I go to paper-street's control panel | ||
| 33 | + And I follow "Enterprise Info and settings" | ||
| 34 | + Then I should see "Historic and current context" | ||
| 35 | + | ||
| 36 | + @selenium | ||
| 37 | + Scenario: check all active community fields | ||
| 38 | + Given I follow "Community's fields" | ||
| 39 | + And I check "community_active" | ||
| 40 | + And I press "save_community_fields" | ||
| 41 | + When I go to mycommunity's control panel | ||
| 42 | + And I follow "Community Info and settings" | ||
| 43 | + Then I should see "Economic activity" | ||
| 44 | + | ||
| 45 | + @selenium | ||
| 46 | + Scenario: uncheck Check/Uncheck All active person field | ||
| 47 | + Given I follow "Person's fields" | ||
| 48 | + And I check "person_active" | ||
| 49 | + And I press "save_person_fields" | ||
| 50 | + And I uncheck "person_active" | ||
| 51 | + And I press "save_person_fields" | ||
| 52 | + And I follow "Control panel" | ||
| 53 | + When I follow "Edit Profile" | ||
| 54 | + Then I should not see "Custom area of study" | ||
| 55 | + | ||
| 56 | + @selenium | ||
| 57 | + Scenario: uncheck Check/Uncheck All active community field | ||
| 58 | + Given I follow "Community's fields" | ||
| 59 | + And I check "community_active" | ||
| 60 | + And I press "save_community_fields" | ||
| 61 | + And I uncheck "community_active" | ||
| 62 | + And I press "save_community_fields" | ||
| 63 | + When I go to mycommunity's control panel | ||
| 64 | + And I follow "Community Info and settings" | ||
| 65 | + Then I should not see "Economic activity" | ||
| 66 | + | ||
| 67 | + @selenium | ||
| 68 | + Scenario: uncheck Check/Uncheck All active enterprise field | ||
| 69 | + Given I follow "Enterprise's fields" | ||
| 70 | + And I check "enterprise_active" | ||
| 71 | + And I press "save_enterprise_fields" | ||
| 72 | + And I uncheck "enterprise_active" | ||
| 73 | + And I press "save_enterprise_fields" | ||
| 74 | + When I go to paper-street's control panel | ||
| 75 | + And I follow "Enterprise Info and settings" | ||
| 76 | + Then I should not see "Historic and current context" |
| @@ -0,0 +1,47 @@ | @@ -0,0 +1,47 @@ | ||
| 1 | +Feature: manage users | ||
| 2 | + As an environment administrator | ||
| 3 | + I want to manage users | ||
| 4 | + In order to remove, activate, deactivate users, and set admin roles. | ||
| 5 | + | ||
| 6 | +Background: | ||
| 7 | + Given the following users | ||
| 8 | + | login | name | | ||
| 9 | + | joaosilva | Joao Silva | | ||
| 10 | + | paulosantos | Paulo Santos | | ||
| 11 | + Given I am logged in as admin | ||
| 12 | + Given I go to /admin/users | ||
| 13 | + | ||
| 14 | + @selenium | ||
| 15 | + Scenario: deactive user | ||
| 16 | + When I follow "Deactivate user" within "tr[title='Joao Silva']" | ||
| 17 | + And I confirm the "Do you want to deactivate this user?" dialog | ||
| 18 | + Then I should see "Activate user" within "tr[title='Joao Silva']" | ||
| 19 | + | ||
| 20 | + @selenium | ||
| 21 | + Scenario: activate user | ||
| 22 | + Given I follow "Deactivate user" within "tr[title='Paulo Santos']" | ||
| 23 | + Given I confirm the "Do you want to deactivate this user?" dialog | ||
| 24 | + When I follow "Activate user" within "tr[title='Paulo Santos']" | ||
| 25 | + And I confirm the "Do you want to activate this user?" dialog | ||
| 26 | + Then I should see "Deactivate user" within "tr[title='Paulo Santos']" | ||
| 27 | + | ||
| 28 | + @selenium | ||
| 29 | + Scenario: remove user | ||
| 30 | + When I follow "Remove" within "tr[title='Joao Silva']" | ||
| 31 | + And I confirm the "Do you want to remove this user?" dialog | ||
| 32 | + And I go to /admin/users | ||
| 33 | + Then I should not see "Joao Silva" | ||
| 34 | + | ||
| 35 | + @selenium | ||
| 36 | + Scenario: admin user | ||
| 37 | + When I follow "Set admin role" within "tr[title='Joao Silva']" | ||
| 38 | + And I confirm the "Do you want to set this user as administrator?" dialog | ||
| 39 | + Then I should see "Reset admin role" within "tr[title='Joao Silva']" | ||
| 40 | + | ||
| 41 | + @selenium | ||
| 42 | + Scenario: unadmin user | ||
| 43 | + Given I follow "Set admin role" within "tr[title='Paulo Santos']" | ||
| 44 | + And I confirm the "Do you want to set this user as administrator?" dialog | ||
| 45 | + When I follow "Reset admin role" within "tr[title='Paulo Santos']" | ||
| 46 | + And I confirm the "Do you want to reset this user as administrator?" dialog | ||
| 47 | + Then I should see "Set admin role" within "tr[title='Paulo Santos']" |
features/short_filename.feature
| @@ -1,21 +0,0 @@ | @@ -1,21 +0,0 @@ | ||
| 1 | -Feature: sitemap | ||
| 2 | - As a noosfero user | ||
| 3 | - I want to list articles | ||
| 4 | - | ||
| 5 | - Background: | ||
| 6 | - Given I am on the homepage | ||
| 7 | - And the following users | ||
| 8 | - | login | name | | ||
| 9 | - | joaosilva | Joao Silva | | ||
| 10 | - And the following files | ||
| 11 | - | owner | file | mime | | ||
| 12 | - | joaosilva | AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA.txt | text/plain | | ||
| 13 | - | ||
| 14 | - Scenario: view a folder page | ||
| 15 | - When I am on /profile/joaosilva/sitemap | ||
| 16 | - Then I should see "AGENDA_CULTURA_-_FESTA_DE_VAQUEIRO(...).txt" | ||
| 17 | - | ||
| 18 | - Scenario: view the CMS | ||
| 19 | - Given I am logged in as "joaosilva" | ||
| 20 | - When I am on /myprofile/joaosilva/cms | ||
| 21 | - Then I should see "AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_(...).txt" |
features/signup.feature
| @@ -3,7 +3,7 @@ Feature: signup | @@ -3,7 +3,7 @@ Feature: signup | ||
| 3 | I want to sign up to the site | 3 | I want to sign up to the site |
| 4 | So I can have fun using its features | 4 | So I can have fun using its features |
| 5 | 5 | ||
| 6 | -@selenium | 6 | + @selenium |
| 7 | Scenario: successfull registration | 7 | Scenario: successfull registration |
| 8 | Given I am on the homepage | 8 | Given I am on the homepage |
| 9 | When I follow "Login" | 9 | When I follow "Login" |
| @@ -29,10 +29,20 @@ Feature: signup | @@ -29,10 +29,20 @@ Feature: signup | ||
| 29 | And I press "Log in" | 29 | And I press "Log in" |
| 30 | Then I should be logged in as "josesilva" | 30 | Then I should be logged in as "josesilva" |
| 31 | 31 | ||
| 32 | + @selenium | ||
| 33 | + Scenario: show error message if username is already used | ||
| 34 | + Given the following users | ||
| 35 | + | login | | ||
| 36 | + | josesilva | | ||
| 37 | + When I go to signup page | ||
| 38 | + And I fill in "Username" with "josesilva" | ||
| 39 | + And I fill in "e-Mail" with "josesilva1" | ||
| 40 | + Then I should see "This login name is unavailable" | ||
| 41 | + | ||
| 32 | Scenario: be redirected if user goes to signup page and is logged | 42 | Scenario: be redirected if user goes to signup page and is logged |
| 33 | Given the following users | 43 | Given the following users |
| 34 | | login | name | | 44 | | login | name | |
| 35 | - | joaosilva | Joao Silva | | 45 | + | joaosilva | joao silva | |
| 36 | Given I am logged in as "joaosilva" | 46 | Given I am logged in as "joaosilva" |
| 37 | And I go to signup page | 47 | And I go to signup page |
| 38 | Then I should be on joaosilva's control panel | 48 | Then I should be on joaosilva's control panel |
| @@ -60,3 +70,183 @@ Feature: signup | @@ -60,3 +70,183 @@ Feature: signup | ||
| 60 | And I fill in "Name" with "" | 70 | And I fill in "Name" with "" |
| 61 | When I press "Save" | 71 | When I press "Save" |
| 62 | Then I should see "Name can't be blank" | 72 | Then I should see "Name can't be blank" |
| 73 | + | ||
| 74 | + @selenium | ||
| 75 | + Scenario: user should stay on same page after signup | ||
| 76 | + Given the environment is configured to stay on the same page after signup | ||
| 77 | + And feature "skip_new_user_email_confirmation" is enabled on environment | ||
| 78 | + And I am on /search/people | ||
| 79 | + When I follow "Sign up" | ||
| 80 | + And I fill in the following within ".no-boxes": | ||
| 81 | + | e-Mail | josesilva@example.com | | ||
| 82 | + | Username | josesilva | | ||
| 83 | + | Password | secret | | ||
| 84 | + | Password confirmation | secret | | ||
| 85 | + | Full name | José da Silva | | ||
| 86 | + And wait for the captcha signup time | ||
| 87 | + And I press "Create my account" | ||
| 88 | + Then I should be on /search/people | ||
| 89 | + | ||
| 90 | + @selenium | ||
| 91 | + Scenario: user should go to his homepage after signup | ||
| 92 | + Given the environment is configured to redirect to profile homepage after signup | ||
| 93 | + And feature "skip_new_user_email_confirmation" is enabled on environment | ||
| 94 | + And I am on /search/people | ||
| 95 | + When I follow "Sign up" | ||
| 96 | + And I fill in the following within ".no-boxes": | ||
| 97 | + | e-Mail | josesilva@example.com | | ||
| 98 | + | Username | josesilva | | ||
| 99 | + | Password | secret | | ||
| 100 | + | Password confirmation | secret | | ||
| 101 | + | Full name | José da Silva | | ||
| 102 | + And wait for the captcha signup time | ||
| 103 | + And I press "Create my account" | ||
| 104 | + Then I should be on josesilva's profile | ||
| 105 | + | ||
| 106 | + @selenium | ||
| 107 | + Scenario: user should go to his control panel after signup | ||
| 108 | + Given the environment is configured to redirect to profile control panel after signup | ||
| 109 | + And feature "skip_new_user_email_confirmation" is enabled on environment | ||
| 110 | + And I am on /search/people | ||
| 111 | + When I follow "Sign up" | ||
| 112 | + And I fill in the following within ".no-boxes": | ||
| 113 | + | e-Mail | josesilva@example.com | | ||
| 114 | + | Username | josesilva | | ||
| 115 | + | Password | secret | | ||
| 116 | + | Password confirmation | secret | | ||
| 117 | + | Full name | José da Silva | | ||
| 118 | + And wait for the captcha signup time | ||
| 119 | + And I press "Create my account" | ||
| 120 | + Then I should be on josesilva's control panel | ||
| 121 | + | ||
| 122 | + @selenium | ||
| 123 | + Scenario: user should go to his profile page after signup | ||
| 124 | + Given the environment is configured to redirect to user profile page after signup | ||
| 125 | + And feature "skip_new_user_email_confirmation" is enabled on environment | ||
| 126 | + And I am on /search/people | ||
| 127 | + When I follow "Sign up" | ||
| 128 | + And I fill in the following within ".no-boxes": | ||
| 129 | + | e-Mail | josesilva@example.com | | ||
| 130 | + | Username | josesilva | | ||
| 131 | + | Password | secret | | ||
| 132 | + | Password confirmation | secret | | ||
| 133 | + | Full name | José da Silva | | ||
| 134 | + And wait for the captcha signup time | ||
| 135 | + And I press "Create my account" | ||
| 136 | + Then I should be on josesilva's profile | ||
| 137 | + | ||
| 138 | + @selenium | ||
| 139 | + Scenario: user should go to the environment's homepage after signup | ||
| 140 | + Given the environment is configured to redirect to site homepage after signup | ||
| 141 | + And feature "skip_new_user_email_confirmation" is enabled on environment | ||
| 142 | + And I am on /search/people | ||
| 143 | + When I follow "Sign up" | ||
| 144 | + And I fill in the following within ".no-boxes": | ||
| 145 | + | e-Mail | josesilva@example.com | | ||
| 146 | + | Username | josesilva | | ||
| 147 | + | Password | secret | | ||
| 148 | + | Password confirmation | secret | | ||
| 149 | + | Full name | José da Silva | | ||
| 150 | + And wait for the captcha signup time | ||
| 151 | + And I press "Create my account" | ||
| 152 | + Then I should be on the homepage | ||
| 153 | + | ||
| 154 | + @selenium | ||
| 155 | + Scenario: user should stay on same page after following confirmation link | ||
| 156 | + Given the environment is configured to stay on the same page after login | ||
| 157 | + And feature "skip_new_user_email_confirmation" is disabled on environment | ||
| 158 | + And I am on /search/people | ||
| 159 | + When I follow "Sign up" | ||
| 160 | + And I fill in the following within ".no-boxes": | ||
| 161 | + | e-Mail | josesilva@example.com | | ||
| 162 | + | Username | josesilva | | ||
| 163 | + | Password | secret | | ||
| 164 | + | Password confirmation | secret | | ||
| 165 | + | Full name | José da Silva | | ||
| 166 | + And wait for the captcha signup time | ||
| 167 | + And I press "Create my account" | ||
| 168 | + And I go to josesilva's confirmation URL | ||
| 169 | + And I fill in "Username" with "josesilva" | ||
| 170 | + And I fill in "Password" with "secret" | ||
| 171 | + And I press "Log in" | ||
| 172 | + Then I should be on /search/people | ||
| 173 | + | ||
| 174 | + @selenium | ||
| 175 | + Scenario: user should go to his homepage after following confirmation link | ||
| 176 | + Given the environment is configured to redirect to profile homepage after login | ||
| 177 | + And feature "skip_new_user_email_confirmation" is disabled on environment | ||
| 178 | + And I am on /search/people | ||
| 179 | + When I follow "Sign up" | ||
| 180 | + And I fill in the following within ".no-boxes": | ||
| 181 | + | e-Mail | josesilva@example.com | | ||
| 182 | + | Username | josesilva | | ||
| 183 | + | Password | secret | | ||
| 184 | + | Password confirmation | secret | | ||
| 185 | + | Full name | José da Silva | | ||
| 186 | + And wait for the captcha signup time | ||
| 187 | + And I press "Create my account" | ||
| 188 | + And I go to josesilva's confirmation URL | ||
| 189 | + And I fill in "Username" with "josesilva" | ||
| 190 | + And I fill in "Password" with "secret" | ||
| 191 | + And I press "Log in" | ||
| 192 | + Then I should be on /profile/josesilva | ||
| 193 | + | ||
| 194 | + @selenium | ||
| 195 | + Scenario: user should go to his control panel after following confirmation link | ||
| 196 | + Given the environment is configured to redirect to profile control panel after login | ||
| 197 | + And feature "skip_new_user_email_confirmation" is disabled on environment | ||
| 198 | + And I am on /search/people | ||
| 199 | + When I follow "Sign up" | ||
| 200 | + And I fill in the following within ".no-boxes": | ||
| 201 | + | e-Mail | josesilva@example.com | | ||
| 202 | + | Username | josesilva | | ||
| 203 | + | Password | secret | | ||
| 204 | + | Password confirmation | secret | | ||
| 205 | + | Full name | José da Silva | | ||
| 206 | + And wait for the captcha signup time | ||
| 207 | + And I press "Create my account" | ||
| 208 | + And I go to josesilva's confirmation URL | ||
| 209 | + And I fill in "Username" with "josesilva" | ||
| 210 | + And I fill in "Password" with "secret" | ||
| 211 | + And I press "Log in" | ||
| 212 | + Then I should be on /myprofile/josesilva | ||
| 213 | + | ||
| 214 | + @selenium | ||
| 215 | + Scenario: user should go to his profile page after following confirmation link | ||
| 216 | + Given the environment is configured to redirect to user profile page after login | ||
| 217 | + And feature "skip_new_user_email_confirmation" is disabled on environment | ||
| 218 | + And I am on /search/people | ||
| 219 | + When I follow "Sign up" | ||
| 220 | + And I fill in the following within ".no-boxes": | ||
| 221 | + | e-Mail | josesilva@example.com | | ||
| 222 | + | Username | josesilva | | ||
| 223 | + | Password | secret | | ||
| 224 | + | Password confirmation | secret | | ||
| 225 | + | Full name | José da Silva | | ||
| 226 | + And wait for the captcha signup time | ||
| 227 | + And I press "Create my account" | ||
| 228 | + And I go to josesilva's confirmation URL | ||
| 229 | + And I fill in "Username" with "josesilva" | ||
| 230 | + And I fill in "Password" with "secret" | ||
| 231 | + And I press "Log in" | ||
| 232 | + Then I should be on /profile/josesilva | ||
| 233 | + | ||
| 234 | + @selenium | ||
| 235 | + Scenario: user should go to the environment homepage after following confirmation link | ||
| 236 | + Given the environment is configured to redirect to site homepage after login | ||
| 237 | + And feature "skip_new_user_email_confirmation" is disabled on environment | ||
| 238 | + And I am on /search/people | ||
| 239 | + When I follow "Sign up" | ||
| 240 | + And I fill in the following within ".no-boxes": | ||
| 241 | + | e-Mail | josesilva@example.com | | ||
| 242 | + | Username | josesilva | | ||
| 243 | + | Password | secret | | ||
| 244 | + | Password confirmation | secret | | ||
| 245 | + | Full name | José da Silva | | ||
| 246 | + And wait for the captcha signup time | ||
| 247 | + And I press "Create my account" | ||
| 248 | + And I go to josesilva's confirmation URL | ||
| 249 | + And I fill in "Username" with "josesilva" | ||
| 250 | + And I fill in "Password" with "secret" | ||
| 251 | + And I press "Log in" | ||
| 252 | + Then I should be on the homepage |
features/step_definitions/noosfero_steps.rb
| @@ -732,6 +732,24 @@ Given /^the profile (.*) is configured to (.*) after login$/ do |profile, option | @@ -732,6 +732,24 @@ Given /^the profile (.*) is configured to (.*) after login$/ do |profile, option | ||
| 732 | profile.save | 732 | profile.save |
| 733 | end | 733 | end |
| 734 | 734 | ||
| 735 | +Given /^the environment is configured to (.*) after signup$/ do |option| | ||
| 736 | + redirection = case option | ||
| 737 | + when 'stay on the same page' | ||
| 738 | + 'keep_on_same_page' | ||
| 739 | + when 'redirect to site homepage' | ||
| 740 | + 'site_homepage' | ||
| 741 | + when 'redirect to user profile page' | ||
| 742 | + 'user_profile_page' | ||
| 743 | + when 'redirect to profile homepage' | ||
| 744 | + 'user_homepage' | ||
| 745 | + when 'redirect to profile control panel' | ||
| 746 | + 'user_control_panel' | ||
| 747 | + end | ||
| 748 | + environment = Environment.default | ||
| 749 | + environment.redirection_after_signup = redirection | ||
| 750 | + environment.save | ||
| 751 | +end | ||
| 752 | + | ||
| 735 | When /^wait for the captcha signup time$/ do | 753 | When /^wait for the captcha signup time$/ do |
| 736 | environment = Environment.default | 754 | environment = Environment.default |
| 737 | sleep environment.min_signup_delay + 1 | 755 | sleep environment.min_signup_delay + 1 |
features/support/paths.rb
| @@ -111,6 +111,10 @@ module NavigationHelpers | @@ -111,6 +111,10 @@ module NavigationHelpers | ||
| 111 | when /the user data path/ | 111 | when /the user data path/ |
| 112 | '/account/user_data' | 112 | '/account/user_data' |
| 113 | 113 | ||
| 114 | + when /^(.+)'s confirmation URL/ | ||
| 115 | + user = User[$1] | ||
| 116 | + "/account/activate?activation_code=#{user.activation_code}&redirection=" + (user.return_to.nil? ? 'false' : 'true') | ||
| 117 | + | ||
| 114 | when /^(.+)'s members page/ | 118 | when /^(.+)'s members page/ |
| 115 | '/profile/%s/members' % profile_identifier($1) | 119 | '/profile/%s/members' % profile_identifier($1) |
| 116 | 120 |
| @@ -0,0 +1,11 @@ | @@ -0,0 +1,11 @@ | ||
| 1 | +class ActivitiesCounterCacheJob | ||
| 2 | + def perform | ||
| 3 | + person_activities_counts = ActiveRecord::Base.connection.execute("SELECT profiles.id, count(action_tracker.id) as count FROM profiles LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.user_id WHERE (action_tracker.created_at >= '#{ActionTracker::Record::RECENT_DELAY.days.ago.to_s(:db)}') AND ( (profiles.type = 'Person' ) ) GROUP BY profiles.id;") | ||
| 4 | + organization_activities_counts = ActiveRecord::Base.connection.execute("SELECT profiles.id, count(action_tracker.id) as count FROM profiles LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.target_id WHERE (action_tracker.created_at >= '#{ActionTracker::Record::RECENT_DELAY.days.ago.to_s(:db)}') AND ( (profiles.type = 'Community' OR profiles.type = 'Enterprise' OR profiles.type = 'Organization' ) ) GROUP BY profiles.id;") | ||
| 5 | + activities_counts = person_activities_counts.entries + organization_activities_counts.entries | ||
| 6 | + activities_counts.each do |count| | ||
| 7 | + ActiveRecord::Base.connection.execute("UPDATE profiles SET activities_count=#{count['count'].to_i} WHERE profiles.id=#{count['id']};") | ||
| 8 | + end | ||
| 9 | + Delayed::Job.enqueue(ActivitiesCounterCacheJob.new, -3, 1.day.from_now) | ||
| 10 | + end | ||
| 11 | +end |
lib/acts_as_having_settings.rb
| @@ -14,6 +14,17 @@ module ActsAsHavingSettings | @@ -14,6 +14,17 @@ module ActsAsHavingSettings | ||
| 14 | def #{settings_field} | 14 | def #{settings_field} |
| 15 | self[:#{settings_field}] ||= Hash.new | 15 | self[:#{settings_field}] ||= Hash.new |
| 16 | end | 16 | end |
| 17 | + | ||
| 18 | + def setting_changed?(setting_field) | ||
| 19 | + setting_field = setting_field.to_sym | ||
| 20 | + changed_settings = self.changes['#{settings_field}'] | ||
| 21 | + return false if changed_settings.nil? | ||
| 22 | + | ||
| 23 | + old_setting_value = changed_settings.first.nil? ? nil : changed_settings.first[setting_field] | ||
| 24 | + new_setting_value = changed_settings.last[setting_field] | ||
| 25 | + old_setting_value != new_setting_value | ||
| 26 | + end | ||
| 27 | + | ||
| 17 | before_save :symbolize_settings_keys | 28 | before_save :symbolize_settings_keys |
| 18 | private | 29 | private |
| 19 | def symbolize_settings_keys | 30 | def symbolize_settings_keys |
| @@ -36,11 +47,9 @@ module ActsAsHavingSettings | @@ -36,11 +47,9 @@ module ActsAsHavingSettings | ||
| 36 | val.nil? ? (#{default}.is_a?(String) ? gettext(#{default}) : #{default}) : val | 47 | val.nil? ? (#{default}.is_a?(String) ? gettext(#{default}) : #{default}) : val |
| 37 | end | 48 | end |
| 38 | def #{setting}=(value) | 49 | def #{setting}=(value) |
| 39 | - | ||
| 40 | - #UPGRADE Leandro: I add this line to save the serialize attribute | ||
| 41 | - send(self.class.settings_field.to_s + '_will_change!') | ||
| 42 | - | ||
| 43 | - send(self.class.settings_field)[:#{setting}] = self.class.acts_as_having_settings_type_cast(value, #{data_type.inspect}) | 50 | + h = send(self.class.settings_field).clone |
| 51 | + h[:#{setting}] = self.class.acts_as_having_settings_type_cast(value, #{data_type.inspect}) | ||
| 52 | + send(self.class.settings_field.to_s + '=', h) | ||
| 44 | end | 53 | end |
| 45 | CODE | 54 | CODE |
| 46 | end | 55 | end |
lib/feed_handler.rb
| @@ -51,7 +51,6 @@ class FeedHandler | @@ -51,7 +51,6 @@ class FeedHandler | ||
| 51 | end | 51 | end |
| 52 | 52 | ||
| 53 | def process(container) | 53 | def process(container) |
| 54 | - Rails.logger.info("Processing %s with id = %d" % [container.class.name, container.id]) | ||
| 55 | begin | 54 | begin |
| 56 | container.class.transaction do | 55 | container.class.transaction do |
| 57 | if container.update_errors > FeedHandler.max_errors && container.fetched_at < (Time.now - FeedHandler.disabled_period) | 56 | if container.update_errors > FeedHandler.max_errors && container.fetched_at < (Time.now - FeedHandler.disabled_period) |
lib/feed_updater.rb
| @@ -24,8 +24,8 @@ class FeedUpdater | @@ -24,8 +24,8 @@ class FeedUpdater | ||
| 24 | environment = Environment.default | 24 | environment = Environment.default |
| 25 | 25 | ||
| 26 | recipients NOOSFERO_CONF['exception_recipients'] | 26 | recipients NOOSFERO_CONF['exception_recipients'] |
| 27 | - from environment.contact_email | ||
| 28 | - reply_to environment.contact_email | 27 | + from environment.noreply_email |
| 28 | + reply_to environment.noreply_email | ||
| 29 | subject "[#{environment.name}] Feed-updater: #{error.message}" | 29 | subject "[#{environment.name}] Feed-updater: #{error.message}" |
| 30 | body render(:text => " | 30 | body render(:text => " |
| 31 | Container: | 31 | Container: |
lib/file_presenter.rb
| @@ -13,6 +13,10 @@ class FilePresenter | @@ -13,6 +13,10 @@ class FilePresenter | ||
| 13 | klass.accepts?(f) ? klass.new(f) : f | 13 | klass.accepts?(f) ? klass.new(f) : f |
| 14 | end | 14 | end |
| 15 | 15 | ||
| 16 | + def self.base_class | ||
| 17 | + Article | ||
| 18 | + end | ||
| 19 | + | ||
| 16 | def initialize(f) | 20 | def initialize(f) |
| 17 | @file = f | 21 | @file = f |
| 18 | end | 22 | end |
| @@ -31,6 +35,10 @@ class FilePresenter | @@ -31,6 +35,10 @@ class FilePresenter | ||
| 31 | self | 35 | self |
| 32 | end | 36 | end |
| 33 | 37 | ||
| 38 | + def kind_of?(klass) | ||
| 39 | + @file.kind_of?(klass) | ||
| 40 | + end | ||
| 41 | + | ||
| 34 | # This method must be overridden in subclasses. | 42 | # This method must be overridden in subclasses. |
| 35 | # | 43 | # |
| 36 | # If the class accepts the file, return a number that represents the | 44 | # If the class accepts the file, return a number that represents the |
| @@ -42,8 +50,17 @@ class FilePresenter | @@ -42,8 +50,17 @@ class FilePresenter | ||
| 42 | nil | 50 | nil |
| 43 | end | 51 | end |
| 44 | 52 | ||
| 53 | + def download?(view=nil) | ||
| 54 | + false | ||
| 55 | + end | ||
| 56 | + | ||
| 45 | def short_description | 57 | def short_description |
| 46 | - _("File (%s)") % content_type.sub(/^application\//, '').sub(/^x-/, '').sub(/^image\//, '') | 58 | + file_type = if content_type.present? |
| 59 | + content_type.sub(/^application\//, '').sub(/^x-/, '').sub(/^image\//, '') | ||
| 60 | + else | ||
| 61 | + _('Unknown') | ||
| 62 | + end | ||
| 63 | + _("File (%s)") % file_type | ||
| 47 | end | 64 | end |
| 48 | 65 | ||
| 49 | # Define the css classes to style the page fragment with the file related | 66 | # Define the css classes to style the page fragment with the file related |
lib/noosfero.rb
| @@ -4,7 +4,7 @@ require 'fast_gettext' | @@ -4,7 +4,7 @@ require 'fast_gettext' | ||
| 4 | 4 | ||
| 5 | module Noosfero | 5 | module Noosfero |
| 6 | PROJECT = 'noosfero' | 6 | PROJECT = 'noosfero' |
| 7 | - VERSION = '0.46.1' | 7 | + VERSION = '0.47.0~rc1' |
| 8 | 8 | ||
| 9 | def self.pattern_for_controllers_in_directory(dir) | 9 | def self.pattern_for_controllers_in_directory(dir) |
| 10 | disjunction = controllers_in_directory(dir).join('|') | 10 | disjunction = controllers_in_directory(dir).join('|') |
| @@ -0,0 +1,21 @@ | @@ -0,0 +1,21 @@ | ||
| 1 | +Rails.configuration.to_prepare do | ||
| 2 | + ActionTracker::Record.module_eval do | ||
| 3 | + extend CacheCounterHelper | ||
| 4 | + | ||
| 5 | + after_create do |record| | ||
| 6 | + update_cache_counter(:activities_count, record.user, 1) | ||
| 7 | + if record.target.kind_of?(Organization) | ||
| 8 | + update_cache_counter(:activities_count, record.target, 1) | ||
| 9 | + end | ||
| 10 | + end | ||
| 11 | + | ||
| 12 | + after_destroy do |record| | ||
| 13 | + if record.created_at >= ActionTracker::Record::RECENT_DELAY.days.ago | ||
| 14 | + update_cache_counter(:activities_count, record.user, -1) | ||
| 15 | + if record.target.kind_of?(Organization) | ||
| 16 | + update_cache_counter(:activities_count, record.target, -1) | ||
| 17 | + end | ||
| 18 | + end | ||
| 19 | + end | ||
| 20 | + end | ||
| 21 | +end |
lib/noosfero/i18n.rb
| @@ -6,9 +6,15 @@ class Object | @@ -6,9 +6,15 @@ class Object | ||
| 6 | alias :ngettext :n_ | 6 | alias :ngettext :n_ |
| 7 | end | 7 | end |
| 8 | 8 | ||
| 9 | + | ||
| 10 | +custom_locale_dir = Rails.root.join('custom_locales', Rails.env) | ||
| 11 | +repos = [] | ||
| 12 | +if File.exists?(custom_locale_dir) | ||
| 13 | + repos << FastGettext::TranslationRepository.build('environment', :type => 'po', :path => custom_locale_dir) | ||
| 14 | +end | ||
| 15 | + | ||
| 9 | # translations in place? | 16 | # translations in place? |
| 10 | locale_dir = Rails.root.join('locale') | 17 | locale_dir = Rails.root.join('locale') |
| 11 | -repos = [] | ||
| 12 | if File.exists?(locale_dir) | 18 | if File.exists?(locale_dir) |
| 13 | repos << FastGettext::TranslationRepository.build('noosfero', :type => 'mo', :path => locale_dir) | 19 | repos << FastGettext::TranslationRepository.build('noosfero', :type => 'mo', :path => locale_dir) |
| 14 | repos << FastGettext::TranslationRepository.build('iso_3166', :type => 'mo', :path => locale_dir) | 20 | repos << FastGettext::TranslationRepository.build('iso_3166', :type => 'mo', :path => locale_dir) |
lib/noosfero/plugin.rb
| @@ -389,6 +389,12 @@ class Noosfero::Plugin | @@ -389,6 +389,12 @@ class Noosfero::Plugin | ||
| 389 | [] | 389 | [] |
| 390 | end | 390 | end |
| 391 | 391 | ||
| 392 | + # -> Adds adicional content to article | ||
| 393 | + # returns = lambda block that creates html code | ||
| 394 | + def article_extra_contents(article) | ||
| 395 | + nil | ||
| 396 | + end | ||
| 397 | + | ||
| 392 | # -> Adds fields to the signup form | 398 | # -> Adds fields to the signup form |
| 393 | # returns = lambda block that creates html code | 399 | # returns = lambda block that creates html code |
| 394 | def signup_extra_contents | 400 | def signup_extra_contents |
| @@ -0,0 +1,29 @@ | @@ -0,0 +1,29 @@ | ||
| 1 | +Rails.configuration.to_prepare do | ||
| 2 | + RoleAssignment.module_eval do | ||
| 3 | + extend CacheCounterHelper | ||
| 4 | + | ||
| 5 | + after_create do |role_assignment| | ||
| 6 | + accessor = role_assignment.accessor | ||
| 7 | + resource = role_assignment.resource | ||
| 8 | + if resource.kind_of?(Organization) | ||
| 9 | + #FIXME This will only work as long as the role_assignment associations | ||
| 10 | + #happen only between profiles, due to the polymorphic column type. | ||
| 11 | + if resource.role_assignments.where(:accessor_id => accessor.id).count == 1 | ||
| 12 | + update_cache_counter(:members_count, resource, 1) | ||
| 13 | + end | ||
| 14 | + end | ||
| 15 | + end | ||
| 16 | + | ||
| 17 | + after_destroy do |role_assignment| | ||
| 18 | + accessor = role_assignment.accessor | ||
| 19 | + resource = role_assignment.resource | ||
| 20 | + if resource.kind_of?(Organization) | ||
| 21 | + #FIXME This will only work as long as the role_assignment associations | ||
| 22 | + #happen only between profiles, due to the polymorphic column type. | ||
| 23 | + if resource.role_assignments.where(:accessor_id => accessor.id).count == 0 | ||
| 24 | + update_cache_counter(:members_count, resource, -1) | ||
| 25 | + end | ||
| 26 | + end | ||
| 27 | + end | ||
| 28 | + end | ||
| 29 | +end |
lib/tasks/plugins_tests.rake
| @@ -25,51 +25,87 @@ def plugin_disabled_warning(plugin) | @@ -25,51 +25,87 @@ def plugin_disabled_warning(plugin) | ||
| 25 | puts "E: you should enable #{plugin} plugin before running it's tests!" | 25 | puts "E: you should enable #{plugin} plugin before running it's tests!" |
| 26 | end | 26 | end |
| 27 | 27 | ||
| 28 | -def run_tests(name, files_glob) | ||
| 29 | - files = Dir.glob(files_glob) | ||
| 30 | - if files.empty? | ||
| 31 | - puts "I: no tests to run (#{name})" | 28 | +def task2ext(task) |
| 29 | + (task == :selenium || task == :cucumber) ? :feature : :rb | ||
| 30 | +end | ||
| 31 | + | ||
| 32 | +def task2profile(task, plugin) | ||
| 33 | + if task == :cucumber | ||
| 34 | + return plugin | ||
| 35 | + elsif task == :selenium | ||
| 36 | + return "#{plugin}_selenium" | ||
| 32 | else | 37 | else |
| 33 | - sh 'testrb', '-Itest', *files | 38 | + return 'default' |
| 34 | end | 39 | end |
| 35 | end | 40 | end |
| 36 | 41 | ||
| 37 | -def run_cucumber(name, profile, files_glob) | ||
| 38 | - files = Dir.glob(files_glob) | ||
| 39 | - if files.empty? | ||
| 40 | - puts "I: no tests to run #{name}" | 42 | +def filename2plugin(filename) |
| 43 | + filename.split('/')[1] | ||
| 44 | +end | ||
| 45 | + | ||
| 46 | +def task2folder(task) | ||
| 47 | + result = case task.to_sym | ||
| 48 | + when :units | ||
| 49 | + :unit | ||
| 50 | + when :functionals | ||
| 51 | + :functional | ||
| 52 | + when :integration | ||
| 53 | + :integration | ||
| 54 | + when :cucumber | ||
| 55 | + :features | ||
| 56 | + when :selenium | ||
| 57 | + :features | ||
| 58 | + end | ||
| 59 | + | ||
| 60 | + return result | ||
| 61 | +end | ||
| 62 | + | ||
| 63 | +def run_test(name, files) | ||
| 64 | + files = Array(files) | ||
| 65 | + plugin = filename2plugin(files.first) | ||
| 66 | + if name == :cucumber || name == :selenium | ||
| 67 | + run_cucumber task2_profile(name, plugin), files | ||
| 41 | else | 68 | else |
| 42 | - sh 'xvfb-run', 'ruby', '-S', 'cucumber', '--profile', profile.to_s, '--format', ENV['CUCUMBER_FORMAT'] || 'progress' , *files | 69 | + run_testrb files |
| 43 | end | 70 | end |
| 44 | end | 71 | end |
| 45 | 72 | ||
| 46 | -def plugin_test_task(name, plugin, files_glob) | ||
| 47 | - desc "Run #{name} tests for #{plugin_name(plugin)}" | ||
| 48 | - task name => 'db:test:plugins:prepare' do |t| | ||
| 49 | - if plugin_enabled?(plugin) | ||
| 50 | - run_tests t.name, files_glob | ||
| 51 | - else | ||
| 52 | - plugin_disabled_warning(plugin) | 73 | +def run_testrb(files) |
| 74 | + sh 'testrb', '-Itest', *files | ||
| 75 | +end | ||
| 76 | + | ||
| 77 | +def run_cucumber(profile, files) | ||
| 78 | + sh 'xvfb-run', 'ruby', '-S', 'cucumber', '--profile', profile.to_s, '--format', ENV['CUCUMBER_FORMAT'] || 'progress' , *files | ||
| 79 | +end | ||
| 80 | + | ||
| 81 | +def custom_run(name, files, run=:individually) | ||
| 82 | + case run | ||
| 83 | + when :all | ||
| 84 | + run_test name, files | ||
| 85 | + when :individually | ||
| 86 | + files.each do |file| | ||
| 87 | + run_test name, file | ||
| 53 | end | 88 | end |
| 89 | + when :by_plugin | ||
| 54 | end | 90 | end |
| 55 | end | 91 | end |
| 56 | 92 | ||
| 57 | -def plugin_cucumber_task(name, plugin, files_glob) | ||
| 58 | - desc "Run #{name} tests for #{plugin_name(plugin)}" | ||
| 59 | - task name => 'db:test:plugins:prepare' do |t| | ||
| 60 | - if plugin_enabled?(plugin) | ||
| 61 | - run_cucumber t.name, plugin, files_glob | ||
| 62 | - else | ||
| 63 | - plugin_disabled_warning(plugin) | ||
| 64 | - end | 93 | +def run_tests(name, plugins, run=:individually) |
| 94 | + plugins = Array(plugins) | ||
| 95 | + glob = "plugins/{#{plugins.join(',')}}/test/#{task2folder(name)}/**/*.#{task2ext(name)}" | ||
| 96 | + files = Dir.glob(glob) | ||
| 97 | + if files.empty? | ||
| 98 | + puts "I: no tests to run #{name}" | ||
| 99 | + else | ||
| 100 | + custom_run(name, files, run) | ||
| 65 | end | 101 | end |
| 66 | end | 102 | end |
| 67 | 103 | ||
| 68 | -def plugin_selenium_task(name, plugin, files_glob) | 104 | +def plugin_test_task(name, plugin, run=:individually) |
| 69 | desc "Run #{name} tests for #{plugin_name(plugin)}" | 105 | desc "Run #{name} tests for #{plugin_name(plugin)}" |
| 70 | task name => 'db:test:plugins:prepare' do |t| | 106 | task name => 'db:test:plugins:prepare' do |t| |
| 71 | if plugin_enabled?(plugin) | 107 | if plugin_enabled?(plugin) |
| 72 | - run_cucumber t.name, "#{plugin}_selenium", files_glob | 108 | + run_tests(name, plugin, run) |
| 73 | else | 109 | else |
| 74 | plugin_disabled_warning(plugin) | 110 | plugin_disabled_warning(plugin) |
| 75 | end | 111 | end |
| @@ -98,28 +134,28 @@ namespace :test do | @@ -98,28 +134,28 @@ namespace :test do | ||
| 98 | namespace :noosfero_plugins do | 134 | namespace :noosfero_plugins do |
| 99 | all_plugins.each do |plugin| | 135 | all_plugins.each do |plugin| |
| 100 | namespace plugin do | 136 | namespace plugin do |
| 101 | - plugin_test_task :units, plugin, "plugins/#{plugin}/test/unit/**/*.rb" | ||
| 102 | - plugin_test_task :functionals, plugin, "plugins/#{plugin}/test/functional/**/*.rb" | ||
| 103 | - plugin_test_task :integration, plugin, "plugins/#{plugin}/test/integration/**/*.rb" | ||
| 104 | - plugin_cucumber_task :cucumber, plugin, "plugins/#{plugin}/features/**/*.feature" | ||
| 105 | - plugin_selenium_task :selenium, plugin, "plugins/#{plugin}/features/**/*.feature" | 137 | + plugin_test_task :units, plugin |
| 138 | + plugin_test_task :functionals, plugin | ||
| 139 | + plugin_test_task :integration, plugin | ||
| 140 | + plugin_test_task :cucumber, plugin | ||
| 141 | + plugin_test_task :selenium, plugin | ||
| 106 | end | 142 | end |
| 107 | 143 | ||
| 108 | test_sequence_task(plugin, plugin, "#{plugin}:units", "#{plugin}:functionals", "#{plugin}:integration", "#{plugin}:cucumber", "#{plugin}:selenium") | 144 | test_sequence_task(plugin, plugin, "#{plugin}:units", "#{plugin}:functionals", "#{plugin}:integration", "#{plugin}:cucumber", "#{plugin}:selenium") |
| 109 | end | 145 | end |
| 110 | 146 | ||
| 111 | - { :units => :unit , :functionals => :functional , :integration => :integration }.each do |taskname,folder| | 147 | + [:units, :functionals, :integration].each do |taskname| |
| 112 | task taskname => 'db:test:plugins:prepare' do |t| | 148 | task taskname => 'db:test:plugins:prepare' do |t| |
| 113 | - run_tests t.name, "plugins/{#{enabled_plugins.join(',')}}/test/#{folder}/**/*.rb" | 149 | + run_tests taskname, enabled_plugins |
| 114 | end | 150 | end |
| 115 | end | 151 | end |
| 116 | 152 | ||
| 117 | task :cucumber => 'db:test:plugins:prepare' do |t| | 153 | task :cucumber => 'db:test:plugins:prepare' do |t| |
| 118 | - run_cucumber t.name, :default, "plugins/{#{enabled_plugins.join(',')}}/test/features/**/*.features" | 154 | + run_tests :cucumber, enabled_plugins |
| 119 | end | 155 | end |
| 120 | 156 | ||
| 121 | task :selenium => 'db:test:plugins:prepare' do |t| | 157 | task :selenium => 'db:test:plugins:prepare' do |t| |
| 122 | - run_cucumber t.name, :selenium, "plugins/{#{enabled_plugins.join(',')}}/test/features/**/*.features" | 158 | + run_tests :selenium, enabled_plugins |
| 123 | end | 159 | end |
| 124 | 160 | ||
| 125 | task :temp_enable_all_plugins do | 161 | task :temp_enable_all_plugins do |
lib/tasks/release.rake
| @@ -146,8 +146,8 @@ EOF | @@ -146,8 +146,8 @@ EOF | ||
| 146 | version_name = new_version = ask(version_question) | 146 | version_name = new_version = ask(version_question) |
| 147 | 147 | ||
| 148 | if release_kind == 'test' | 148 | if release_kind == 'test' |
| 149 | - timestamp = Time.now.strftime('%Y%m%d%H%M%S') | ||
| 150 | - version_name += "~rc#{timestamp}" | 149 | + rc_version = ask('RC version', Time.now.strftime('%Y%m%d%H%M%S')) |
| 150 | + version_name += "~rc#{rc_version}" | ||
| 151 | end | 151 | end |
| 152 | release_message = ask("Release message") | 152 | release_message = ask("Release message") |
| 153 | 153 | ||
| @@ -218,6 +218,9 @@ EOF | @@ -218,6 +218,9 @@ EOF | ||
| 218 | task :release, :release_kind do |t, args| | 218 | task :release, :release_kind do |t, args| |
| 219 | release_kind = args[:release_kind] || 'stable' | 219 | release_kind = args[:release_kind] || 'stable' |
| 220 | 220 | ||
| 221 | + puts "==> Updating authors..." | ||
| 222 | + Rake::Task['noosfero:authors'].invoke | ||
| 223 | + | ||
| 221 | Rake::Task['noosfero:set_version'].invoke(release_kind) | 224 | Rake::Task['noosfero:set_version'].invoke(release_kind) |
| 222 | 225 | ||
| 223 | puts "==> Checking tags..." | 226 | puts "==> Checking tags..." |
| @@ -232,9 +235,6 @@ EOF | @@ -232,9 +235,6 @@ EOF | ||
| 232 | commit_changes(['public/500.html', 'public/503.html'], 'Updating public error pages') | 235 | commit_changes(['public/500.html', 'public/503.html'], 'Updating public error pages') |
| 233 | end | 236 | end |
| 234 | 237 | ||
| 235 | - puts "==> Updating authors..." | ||
| 236 | - Rake::Task['noosfero:authors'].invoke | ||
| 237 | - | ||
| 238 | puts "==> Checking repository..." | 238 | puts "==> Checking repository..." |
| 239 | Rake::Task['noosfero:check_repo'].invoke | 239 | Rake::Task['noosfero:check_repo'].invoke |
| 240 | 240 |
plugins/anti_spam/lib/anti_spam_plugin/wrapper.rb
| @@ -2,9 +2,10 @@ class AntiSpamPlugin::Wrapper < SimpleDelegator | @@ -2,9 +2,10 @@ class AntiSpamPlugin::Wrapper < SimpleDelegator | ||
| 2 | include Rakismet::Model | 2 | include Rakismet::Model |
| 3 | 3 | ||
| 4 | @@wrappers = [] | 4 | @@wrappers = [] |
| 5 | + cattr_accessor :wrappers | ||
| 5 | 6 | ||
| 6 | def self.wrap(object) | 7 | def self.wrap(object) |
| 7 | - wrapper = @@wrappers.find { |wrapper| wrapper.wraps?(object) } | 8 | + wrapper = wrappers.find { |wrapper| wrapper.wraps?(object) } |
| 8 | wrapper ? wrapper.new(object) : object | 9 | wrapper ? wrapper.new(object) : object |
| 9 | end | 10 | end |
| 10 | 11 | ||
| @@ -13,6 +14,10 @@ class AntiSpamPlugin::Wrapper < SimpleDelegator | @@ -13,6 +14,10 @@ class AntiSpamPlugin::Wrapper < SimpleDelegator | ||
| 13 | end | 14 | end |
| 14 | 15 | ||
| 15 | def self.inherited(child) | 16 | def self.inherited(child) |
| 16 | - @@wrappers << child | 17 | + wrappers << child |
| 17 | end | 18 | end |
| 18 | end | 19 | end |
| 20 | + | ||
| 21 | +Dir.glob(File.join(AntiSpamPlugin.root_path, 'lib', 'anti_spam_plugin', '*_wrapper.rb')) do |file| | ||
| 22 | + load(file) | ||
| 23 | +end |
plugins/comment_group/test/functional/comment_group_plugin_profile_controller_test.rb
| @@ -36,10 +36,10 @@ class CommentGroupPluginProfileControllerTest < ActionController::TestCase | @@ -36,10 +36,10 @@ class CommentGroupPluginProfileControllerTest < ActionController::TestCase | ||
| 36 | end | 36 | end |
| 37 | 37 | ||
| 38 | should 'show first page comments only' do | 38 | should 'show first page comments only' do |
| 39 | - comment1 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'secondpage', :group_id => 0) | ||
| 40 | - comment2 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'firstpage 1', :group_id => 0) | ||
| 41 | - comment3 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'firstpage 2', :group_id => 0) | ||
| 42 | - comment4 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'firstpage 3', :group_id => 0) | 39 | + comment1 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :created_at => Time.now, :body => 'secondpage', :group_id => 0) |
| 40 | + comment2 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :created_at => Time.now - 1.day, :body => 'firstpage 1', :group_id => 0) | ||
| 41 | + comment3 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :created_at => Time.now - 2.days, :body => 'firstpage 2', :group_id => 0) | ||
| 42 | + comment4 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :created_at => Time.now - 3.days, :body => 'firstpage 3', :group_id => 0) | ||
| 43 | xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0 | 43 | xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0 |
| 44 | assert_match /firstpage 1/, @response.body | 44 | assert_match /firstpage 1/, @response.body |
| 45 | assert_match /firstpage 2/, @response.body | 45 | assert_match /firstpage 2/, @response.body |
plugins/community_track/lib/community_track_plugin/track_card_list_block.rb
| @@ -12,4 +12,8 @@ class CommunityTrackPlugin::TrackCardListBlock < CommunityTrackPlugin::TrackList | @@ -12,4 +12,8 @@ class CommunityTrackPlugin::TrackCardListBlock < CommunityTrackPlugin::TrackList | ||
| 12 | 'track_card' | 12 | 'track_card' |
| 13 | end | 13 | end |
| 14 | 14 | ||
| 15 | + def embedable? | ||
| 16 | + true | ||
| 17 | + end | ||
| 18 | + | ||
| 15 | end | 19 | end |
plugins/community_track/test/functional/community_track_plugin_content_viewer_controller_test.rb
| @@ -10,7 +10,7 @@ end | @@ -10,7 +10,7 @@ end | ||
| 10 | class ContentViewerControllerTest < ActionController::TestCase | 10 | class ContentViewerControllerTest < ActionController::TestCase |
| 11 | 11 | ||
| 12 | def setup | 12 | def setup |
| 13 | - @profile = fast_create(Community) | 13 | + @profile = Community.create!(:name => 'Sample community', :identifier => 'sample-community') |
| 14 | @track = create_track('track', @profile) | 14 | @track = create_track('track', @profile) |
| 15 | @step = CommunityTrackPlugin::Step.create!(:name => 'step1', :body => 'body', :profile => @profile, :parent => @track, :published => false, :end_date => Date.today, :start_date => Date.today, :tool_type => TinyMceArticle.name) | 15 | @step = CommunityTrackPlugin::Step.create!(:name => 'step1', :body => 'body', :profile => @profile, :parent => @track, :published => false, :end_date => Date.today, :start_date => Date.today, :tool_type => TinyMceArticle.name) |
| 16 | 16 | ||
| @@ -87,43 +87,35 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -87,43 +87,35 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
| 87 | end | 87 | end |
| 88 | 88 | ||
| 89 | should 'render a div with block id for track list block' do | 89 | should 'render a div with block id for track list block' do |
| 90 | - box = fast_create(Box, :owner_id => @profile.id, :owner_type => @profile.class.name, :position => 1) | ||
| 91 | - @block = create(CommunityTrackPlugin::TrackListBlock, :box => box) | ||
| 92 | - @profile.boxes << box | 90 | + @block = CommunityTrackPlugin::TrackListBlock.create!(:box => @profile.boxes.last) |
| 93 | get :view_page, @step.url | 91 | get :view_page, @step.url |
| 94 | assert_tag :tag => 'div', :attributes => { :class => 'track_list', :id => "track_list_#{@block.id}" } | 92 | assert_tag :tag => 'div', :attributes => { :class => 'track_list', :id => "track_list_#{@block.id}" } |
| 95 | end | 93 | end |
| 96 | 94 | ||
| 97 | should 'render a div with block id for track card list block' do | 95 | should 'render a div with block id for track card list block' do |
| 98 | - box = fast_create(Box, :owner_id => @profile.id, :owner_type => @profile.class.name, :position => 1) | ||
| 99 | - @block = create(CommunityTrackPlugin::TrackCardListBlock, :box => box) | ||
| 100 | - @profile.boxes << box | 96 | + @block = CommunityTrackPlugin::TrackCardListBlock.create!(:box => @profile.boxes.last) |
| 101 | get :view_page, @step.url | 97 | get :view_page, @step.url |
| 102 | assert_tag :tag => 'div', :attributes => { :class => 'track_list', :id => "track_list_#{@block.id}" } | 98 | assert_tag :tag => 'div', :attributes => { :class => 'track_list', :id => "track_list_#{@block.id}" } |
| 103 | end | 99 | end |
| 104 | 100 | ||
| 105 | should 'render tracks in track list block' do | 101 | should 'render tracks in track list block' do |
| 106 | - box = fast_create(Box, :owner_id => @profile.id, :owner_type => @profile.class.name, :position => 1) | ||
| 107 | - @block = create(CommunityTrackPlugin::TrackListBlock, :box => box) | ||
| 108 | - @profile.boxes << box | 102 | + @block = CommunityTrackPlugin::TrackListBlock.create!(:box => @profile.boxes.last) |
| 109 | get :view_page, @step.url | 103 | get :view_page, @step.url |
| 104 | + file = File.open('result.html', 'w+') | ||
| 105 | + file.write(@response.body) | ||
| 106 | + file.close | ||
| 110 | assert_tag :tag => 'div', :attributes => { :class => "item category_#{@track.category_name}" }, :descendant => { :tag => 'div', :attributes => { :class => 'steps' }, :descendant => { :tag => 'span', :attributes => { :class => "step #{@block.status_class(@step)}" } } } | 107 | assert_tag :tag => 'div', :attributes => { :class => "item category_#{@track.category_name}" }, :descendant => { :tag => 'div', :attributes => { :class => 'steps' }, :descendant => { :tag => 'span', :attributes => { :class => "step #{@block.status_class(@step)}" } } } |
| 111 | end | 108 | end |
| 112 | 109 | ||
| 113 | should 'render tracks in track card list block' do | 110 | should 'render tracks in track card list block' do |
| 114 | - box = fast_create(Box, :owner_id => @profile.id, :owner_type => @profile.class.name, :position => 1) | ||
| 115 | - @block = create(CommunityTrackPlugin::TrackCardListBlock, :box => box) | ||
| 116 | - @profile.boxes << box | 111 | + @block = CommunityTrackPlugin::TrackCardListBlock.create!(:box => @profile.boxes.last) |
| 117 | get :view_page, @step.url | 112 | get :view_page, @step.url |
| 118 | assert_tag :tag => 'div', :attributes => { :class => "item_card category_#{@track.category_name}" }, :descendant => { :tag => 'div', :attributes => { :class => 'track_content' } } | 113 | assert_tag :tag => 'div', :attributes => { :class => "item_card category_#{@track.category_name}" }, :descendant => { :tag => 'div', :attributes => { :class => 'track_content' } } |
| 119 | assert_tag :tag => 'div', :attributes => { :class => "item_card category_#{@track.category_name}" }, :descendant => { :tag => 'div', :attributes => { :class => 'track_stats' } } | 114 | assert_tag :tag => 'div', :attributes => { :class => "item_card category_#{@track.category_name}" }, :descendant => { :tag => 'div', :attributes => { :class => 'track_stats' } } |
| 120 | end | 115 | end |
| 121 | 116 | ||
| 122 | should 'render link to display more tracks in track list block' do | 117 | should 'render link to display more tracks in track list block' do |
| 123 | - box = fast_create(Box, :owner_id => @profile.id, :owner_type => @profile.class.name, :position => 1) | ||
| 124 | - @block = create(CommunityTrackPlugin::TrackCardListBlock, :box => box) | ||
| 125 | - @profile.boxes << box | ||
| 126 | - | 118 | + @block = CommunityTrackPlugin::TrackCardListBlock.create!(:box => @profile.boxes.last) |
| 127 | (@block.limit+1).times { |i| create_track("track#{i}", @profile) } | 119 | (@block.limit+1).times { |i| create_track("track#{i}", @profile) } |
| 128 | 120 | ||
| 129 | get :view_page, @step.url | 121 | get :view_page, @step.url |
| @@ -131,9 +123,7 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -131,9 +123,7 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
| 131 | end | 123 | end |
| 132 | 124 | ||
| 133 | should 'render link to show all tracks in track list block' do | 125 | should 'render link to show all tracks in track list block' do |
| 134 | - box = fast_create(Box, :owner_id => @profile.id, :owner_type => @profile.class.name, :position => 1) | ||
| 135 | - @block = create(CommunityTrackPlugin::TrackCardListBlock, :box => box) | ||
| 136 | - @profile.boxes << box | 126 | + @block = CommunityTrackPlugin::TrackCardListBlock.create!(:box => @profile.boxes.last) |
| 137 | @block.more_another_page = true | 127 | @block.more_another_page = true |
| 138 | @block.save! | 128 | @block.save! |
| 139 | 129 |
plugins/context_content/views/blocks/_more.html.erb
| 1 | <% if contents.total_pages > 1 %> | 1 | <% if contents.total_pages > 1 %> |
| 2 | - <%= link_to_remote(nil, :url => {:id => block.id, :controller => 'context_content_plugin_profile', :action => 'view_content', :page => contents.previous_page, :article_id => article_id }, :html => {:class => "button icon-button icon-left #{contents.previous_page ? '':'disabled'}".strip}, :condition => "#{!contents.previous_page.nil?}", :success => "jQuery('#context_content_#{block.id}').effect('slide', {direction: 'left'});" )%> | ||
| 3 | - <%= link_to_remote(nil, :url => {:id => block.id, :controller => 'context_content_plugin_profile', :action => 'view_content', :page => contents.next_page, :article_id => article_id }, :html => {:class => "button icon-button icon-right #{contents.next_page ? '':'disabled'}".strip}, :condition => "#{!contents.next_page.nil?}", :success => "jQuery('#context_content_#{block.id}').effect('slide', {direction: 'right'});" )%> | 2 | + <%= link_to_remote(nil, :url => {:profile => block.owner.identifier, :id => block.id, :controller => 'context_content_plugin_profile', :action => 'view_content', :page => contents.previous_page, :article_id => article_id }, :html => {:class => "button icon-button icon-left #{contents.previous_page ? '':'disabled'}".strip}, :condition => "#{!contents.previous_page.nil?}", :success => "jQuery('#context_content_#{block.id}').effect('slide', {direction: 'left'});" )%> |
| 3 | + <%= link_to_remote(nil, :url => {:profile => block.owner.identifier, :id => block.id, :controller => 'context_content_plugin_profile', :action => 'view_content', :page => contents.next_page, :article_id => article_id }, :html => {:class => "button icon-button icon-right #{contents.next_page ? '':'disabled'}".strip}, :condition => "#{!contents.next_page.nil?}", :success => "jQuery('#context_content_#{block.id}').effect('slide', {direction: 'right'});" )%> | ||
| 4 | <% end %> | 4 | <% end %> |
plugins/display_content/lib/display_content_block.rb
| @@ -63,9 +63,12 @@ class DisplayContentBlock < Block | @@ -63,9 +63,12 @@ class DisplayContentBlock < Block | ||
| 63 | 63 | ||
| 64 | VALID_CONTENT = ['RawHTMLArticle', 'TextArticle', 'TextileArticle', 'TinyMceArticle', 'Folder', 'Blog', 'Forum'] | 64 | VALID_CONTENT = ['RawHTMLArticle', 'TextArticle', 'TextileArticle', 'TinyMceArticle', 'Folder', 'Blog', 'Forum'] |
| 65 | 65 | ||
| 66 | + include Noosfero::Plugin::HotSpot | ||
| 67 | + | ||
| 66 | def articles_of_parent(parent = nil) | 68 | def articles_of_parent(parent = nil) |
| 67 | return [] if self.holder.nil? | 69 | return [] if self.holder.nil? |
| 68 | - holder.articles.find(:all, :conditions => {:type => VALID_CONTENT, :parent_id => (parent.nil? ? nil : parent)}) | 70 | + types = VALID_CONTENT + plugins.dispatch(:content_types).map(&:name) |
| 71 | + holder.articles.find(:all, :conditions => {:type => types, :parent_id => (parent.nil? ? nil : parent)}) | ||
| 69 | end | 72 | end |
| 70 | 73 | ||
| 71 | def content(args={}) | 74 | def content(args={}) |
plugins/display_content/test/unit/display_content_block_test.rb
| @@ -238,6 +238,7 @@ class DisplayContentBlockTest < ActiveSupport::TestCase | @@ -238,6 +238,7 @@ class DisplayContentBlockTest < ActiveSupport::TestCase | ||
| 238 | block.nodes= [a1.id, a2.id, a3.id] | 238 | block.nodes= [a1.id, a2.id, a3.id] |
| 239 | box = mock() | 239 | box = mock() |
| 240 | box.stubs(:owner).returns(profile) | 240 | box.stubs(:owner).returns(profile) |
| 241 | + box.stubs(:environment).returns(Environment.default) | ||
| 241 | block.stubs(:box).returns(box) | 242 | block.stubs(:box).returns(box) |
| 242 | assert_equal [], [a1, a2] - block.articles_of_parent | 243 | assert_equal [], [a1, a2] - block.articles_of_parent |
| 243 | assert_equal [], block.articles_of_parent - [a1, a2] | 244 | assert_equal [], block.articles_of_parent - [a1, a2] |
| @@ -253,6 +254,7 @@ class DisplayContentBlockTest < ActiveSupport::TestCase | @@ -253,6 +254,7 @@ class DisplayContentBlockTest < ActiveSupport::TestCase | ||
| 253 | block = DisplayContentBlock.new | 254 | block = DisplayContentBlock.new |
| 254 | box = mock() | 255 | box = mock() |
| 255 | box.stubs(:owner).returns(profile) | 256 | box.stubs(:owner).returns(profile) |
| 257 | + box.stubs(:environment).returns(Environment.default) | ||
| 256 | block.stubs(:box).returns(box) | 258 | block.stubs(:box).returns(box) |
| 257 | assert_equal [], [a3] - block.articles_of_parent(a2) | 259 | assert_equal [], [a3] - block.articles_of_parent(a2) |
| 258 | assert_equal [], block.articles_of_parent(a2) - [a3] | 260 | assert_equal [], block.articles_of_parent(a2) - [a3] |
| @@ -270,6 +272,7 @@ class DisplayContentBlockTest < ActiveSupport::TestCase | @@ -270,6 +272,7 @@ class DisplayContentBlockTest < ActiveSupport::TestCase | ||
| 270 | box = mock() | 272 | box = mock() |
| 271 | block.stubs(:box).returns(box) | 273 | block.stubs(:box).returns(box) |
| 272 | box.stubs(:owner).returns(environment) | 274 | box.stubs(:owner).returns(environment) |
| 275 | + box.stubs(:environment).returns(Environment.default) | ||
| 273 | environment.stubs(:portal_community).returns(profile) | 276 | environment.stubs(:portal_community).returns(profile) |
| 274 | 277 | ||
| 275 | assert_equal [], [a1, a2] - block.articles_of_parent | 278 | assert_equal [], [a1, a2] - block.articles_of_parent |
| @@ -288,6 +291,7 @@ class DisplayContentBlockTest < ActiveSupport::TestCase | @@ -288,6 +291,7 @@ class DisplayContentBlockTest < ActiveSupport::TestCase | ||
| 288 | box = mock() | 291 | box = mock() |
| 289 | block.stubs(:box).returns(box) | 292 | block.stubs(:box).returns(box) |
| 290 | box.stubs(:owner).returns(environment) | 293 | box.stubs(:owner).returns(environment) |
| 294 | + box.stubs(:environment).returns(Environment.default) | ||
| 291 | environment.stubs(:portal_community).returns(profile) | 295 | environment.stubs(:portal_community).returns(profile) |
| 292 | 296 | ||
| 293 | assert_equal [], [a3] - block.articles_of_parent(a2) | 297 | assert_equal [], [a3] - block.articles_of_parent(a2) |
| @@ -301,6 +305,7 @@ class DisplayContentBlockTest < ActiveSupport::TestCase | @@ -301,6 +305,7 @@ class DisplayContentBlockTest < ActiveSupport::TestCase | ||
| 301 | box = mock() | 305 | box = mock() |
| 302 | block.stubs(:box).returns(box) | 306 | block.stubs(:box).returns(box) |
| 303 | box.stubs(:owner).returns(environment) | 307 | box.stubs(:owner).returns(environment) |
| 308 | + box.stubs(:environment).returns(Environment.default) | ||
| 304 | 309 | ||
| 305 | assert_equal [], block.articles_of_parent() | 310 | assert_equal [], block.articles_of_parent() |
| 306 | end | 311 | end |
| @@ -316,6 +321,7 @@ class DisplayContentBlockTest < ActiveSupport::TestCase | @@ -316,6 +321,7 @@ class DisplayContentBlockTest < ActiveSupport::TestCase | ||
| 316 | block = DisplayContentBlock.new | 321 | block = DisplayContentBlock.new |
| 317 | box = mock() | 322 | box = mock() |
| 318 | box.stubs(:owner).returns(profile) | 323 | box.stubs(:owner).returns(profile) |
| 324 | + box.stubs(:environment).returns(Environment.default) | ||
| 319 | block.stubs(:box).returns(box) | 325 | block.stubs(:box).returns(box) |
| 320 | assert_equal [], [a2] - block.articles_of_parent | 326 | assert_equal [], [a2] - block.articles_of_parent |
| 321 | assert_equal [], block.articles_of_parent - [a2] | 327 | assert_equal [], block.articles_of_parent - [a2] |
| @@ -334,6 +340,7 @@ class DisplayContentBlockTest < ActiveSupport::TestCase | @@ -334,6 +340,7 @@ class DisplayContentBlockTest < ActiveSupport::TestCase | ||
| 334 | block = DisplayContentBlock.new | 340 | block = DisplayContentBlock.new |
| 335 | box = mock() | 341 | box = mock() |
| 336 | box.stubs(:owner).returns(profile) | 342 | box.stubs(:owner).returns(profile) |
| 343 | + box.stubs(:environment).returns(Environment.default) | ||
| 337 | block.stubs(:box).returns(box) | 344 | block.stubs(:box).returns(box) |
| 338 | assert_equal [a1], block.articles_of_parent | 345 | assert_equal [a1], block.articles_of_parent |
| 339 | end | 346 | end |
| @@ -528,4 +535,28 @@ class DisplayContentBlockTest < ActiveSupport::TestCase | @@ -528,4 +535,28 @@ class DisplayContentBlockTest < ActiveSupport::TestCase | ||
| 528 | assert_equivalent [f1.id, a1.id, a2.id, a3.id], block.nodes | 535 | assert_equivalent [f1.id, a1.id, a2.id, a3.id], block.nodes |
| 529 | end | 536 | end |
| 530 | 537 | ||
| 538 | + should "test should return plugins articles in articles of parent method" do | ||
| 539 | + class PluginArticle < Article; end | ||
| 540 | + | ||
| 541 | + class Plugin1 < Noosfero::Plugin | ||
| 542 | + def content_types | ||
| 543 | + [PluginArticle] | ||
| 544 | + end | ||
| 545 | + end | ||
| 546 | + | ||
| 547 | + profile = create_user('testuser').person | ||
| 548 | + Article.delete_all | ||
| 549 | + a1 = fast_create(PluginArticle, :name => 'test article 1', :profile_id => profile.id) | ||
| 550 | + | ||
| 551 | + env = fast_create(Environment) | ||
| 552 | + env.enable_plugin(Plugin1) | ||
| 553 | + | ||
| 554 | + block = DisplayContentBlock.new | ||
| 555 | + box = mock() | ||
| 556 | + box.stubs(:owner).returns(profile) | ||
| 557 | + box.stubs(:environment).returns(env) | ||
| 558 | + block.stubs(:box).returns(box) | ||
| 559 | + assert_equal [a1], block.articles_of_parent | ||
| 560 | + end | ||
| 561 | + | ||
| 531 | end | 562 | end |
plugins/mark_comment_as_read/controllers/mark_comment_as_read_plugin_profile_controller.rb
0 → 100644
| @@ -0,0 +1,17 @@ | @@ -0,0 +1,17 @@ | ||
| 1 | +class MarkCommentAsReadPluginProfileController < ProfileController | ||
| 2 | + | ||
| 3 | + append_view_path File.join(File.dirname(__FILE__) + '/../views') | ||
| 4 | + | ||
| 5 | + def mark_as_read | ||
| 6 | + comment = Comment.find(params[:id]) | ||
| 7 | + comment.mark_as_read(user) | ||
| 8 | + render :text => {'ok' => true}.to_json, :content_type => 'application/json' | ||
| 9 | + end | ||
| 10 | + | ||
| 11 | + def mark_as_not_read | ||
| 12 | + comment = Comment.find(params[:id]) | ||
| 13 | + comment.mark_as_not_read(user) | ||
| 14 | + render :text => {'ok' => true}.to_json, :content_type => 'application/json' | ||
| 15 | + end | ||
| 16 | + | ||
| 17 | +end |
plugins/mark_comment_as_read/db/migrate/20130509184338_create_mark_comment_as_read_plugin.rb
0 → 100644
| @@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
| 1 | +class CreateMarkCommentAsReadPlugin < ActiveRecord::Migration | ||
| 2 | + def self.up | ||
| 3 | + create_table :mark_comment_as_read_plugin do |t| | ||
| 4 | + t.integer :comment_id | ||
| 5 | + t.integer :person_id | ||
| 6 | + end | ||
| 7 | + add_index :mark_comment_as_read_plugin, [:comment_id, :person_id], :unique => true | ||
| 8 | + end | ||
| 9 | + | ||
| 10 | + def self.down | ||
| 11 | + drop_table :mark_comment_as_read_plugin | ||
| 12 | + end | ||
| 13 | +end |
plugins/mark_comment_as_read/lib/mark_comment_as_read_plugin.rb
0 → 100644
| @@ -0,0 +1,45 @@ | @@ -0,0 +1,45 @@ | ||
| 1 | +require_dependency 'mark_comment_as_read_plugin/ext/comment' | ||
| 2 | + | ||
| 3 | +class MarkCommentAsReadPlugin < Noosfero::Plugin | ||
| 4 | + | ||
| 5 | + def self.plugin_name | ||
| 6 | + "MarkCommentAsReadPlugin" | ||
| 7 | + end | ||
| 8 | + | ||
| 9 | + def self.plugin_description | ||
| 10 | + _("Provide a button to mark a comment as read.") | ||
| 11 | + end | ||
| 12 | + | ||
| 13 | + def js_files | ||
| 14 | + 'mark_comment_as_read.js' | ||
| 15 | + end | ||
| 16 | + | ||
| 17 | + def stylesheet? | ||
| 18 | + true | ||
| 19 | + end | ||
| 20 | + | ||
| 21 | + def comment_actions(comment) | ||
| 22 | + lambda do | ||
| 23 | + [{:link => link_to_function(_('Mark as not read'), 'toggle_comment_read(this, %s, false);' % url_for(:controller => 'mark_comment_as_read_plugin_profile', :profile => profile.identifier, :action => 'mark_as_not_read', :id => comment.id).to_json, :class => 'comment-footer comment-footer-link comment-footer-hide comment-action-extra', :style => 'display: none', :id => "comment-action-mark-as-not-read-#{comment.id}")}, | ||
| 24 | + {:link => link_to_function(_('Mark as read'), 'toggle_comment_read(this, %s, true);' % url_for(:controller => 'mark_comment_as_read_plugin_profile', :profile => profile.identifier, :action => 'mark_as_read', :id => comment.id).to_json, :class => 'comment-footer comment-footer-link comment-footer-hide comment-action-extra', :style => 'display: none', :id => "comment-action-mark-as-read-#{comment.id}")}] if user | ||
| 25 | + end | ||
| 26 | + end | ||
| 27 | + | ||
| 28 | + def check_comment_actions(comment) | ||
| 29 | + lambda do | ||
| 30 | + if user | ||
| 31 | + comment.marked_as_read?(user) ? "#comment-action-mark-as-not-read-#{comment.id}" : "#comment-action-mark-as-read-#{comment.id}" | ||
| 32 | + end | ||
| 33 | + end | ||
| 34 | + end | ||
| 35 | + | ||
| 36 | + def article_extra_contents(article) | ||
| 37 | + lambda do | ||
| 38 | + if user | ||
| 39 | + ids = article.comments.marked_as_read(user).collect { |comment| comment.id} | ||
| 40 | + "<script type=\"text/javascript\">mark_comments_as_read(#{ids.to_json});</script>" if !ids.empty? | ||
| 41 | + end | ||
| 42 | + end | ||
| 43 | + end | ||
| 44 | + | ||
| 45 | +end |
plugins/mark_comment_as_read/lib/mark_comment_as_read_plugin/ext/comment.rb
0 → 100644
| @@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
| 1 | +require_dependency 'comment' | ||
| 2 | + | ||
| 3 | +class Comment | ||
| 4 | + | ||
| 5 | + has_many :read_comments, :class_name => 'MarkCommentAsReadPlugin::ReadComments' | ||
| 6 | + has_many :people, :through => :read_comments | ||
| 7 | + | ||
| 8 | + def mark_as_read(person) | ||
| 9 | + people << person | ||
| 10 | + end | ||
| 11 | + | ||
| 12 | + def mark_as_not_read(person) | ||
| 13 | + people.delete(person) | ||
| 14 | + end | ||
| 15 | + | ||
| 16 | + def marked_as_read?(person) | ||
| 17 | + person && people.find(:first, :conditions => {:id => person.id}) | ||
| 18 | + end | ||
| 19 | + | ||
| 20 | + def self.marked_as_read(person) | ||
| 21 | + find(:all, :joins => [:read_comments], :conditions => {:author_id => person.id}) | ||
| 22 | + end | ||
| 23 | + | ||
| 24 | +end |
plugins/mark_comment_as_read/lib/mark_comment_as_read_plugin/read_comments.rb
0 → 100644
plugins/mark_comment_as_read/public/mark_comment_as_read.js
0 → 100644
| @@ -0,0 +1,28 @@ | @@ -0,0 +1,28 @@ | ||
| 1 | +function mark_comments_as_read(comments) { | ||
| 2 | + jQuery(document).ready(function($) { | ||
| 3 | + for(var i=0; i<comments.length; i++) { | ||
| 4 | + $comment = jQuery('#comment-'+comments[i]); | ||
| 5 | + $comment.find('.comment-content').first().addClass('comment-mark-read'); | ||
| 6 | + } | ||
| 7 | + }); | ||
| 8 | +} | ||
| 9 | + | ||
| 10 | +function toggle_comment_read(button, url, mark) { | ||
| 11 | + var $ = jQuery; | ||
| 12 | + var $button = $(button); | ||
| 13 | + $button.addClass('comment-button-loading'); | ||
| 14 | + $.post(url, function(data) { | ||
| 15 | + if (data.ok) { | ||
| 16 | + var $comment = $button.closest('.article-comment'); | ||
| 17 | + var $content = $comment.find('.comment-content').first(); | ||
| 18 | + if(mark) | ||
| 19 | + $content.addClass('comment-mark-read'); | ||
| 20 | + else | ||
| 21 | + $content.removeClass('comment-mark-read'); | ||
| 22 | + $button.hide(); | ||
| 23 | + $button.removeClass('comment-button-loading'); | ||
| 24 | + return; | ||
| 25 | + } | ||
| 26 | + }); | ||
| 27 | +} | ||
| 28 | + |
plugins/mark_comment_as_read/test/functional/mark_comment_as_read_plugin_profile_controller_test.rb
0 → 100644
| @@ -0,0 +1,33 @@ | @@ -0,0 +1,33 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../../../../test/test_helper' | ||
| 2 | +require File.dirname(__FILE__) + '/../../controllers/mark_comment_as_read_plugin_profile_controller' | ||
| 3 | + | ||
| 4 | +# Re-raise errors caught by the controller. | ||
| 5 | +class MarkCommentAsReadPluginProfileController; def rescue_action(e) raise e end; end | ||
| 6 | + | ||
| 7 | +class MarkCommentAsReadPluginProfileControllerTest < ActionController::TestCase | ||
| 8 | + def setup | ||
| 9 | + @controller = MarkCommentAsReadPluginProfileController.new | ||
| 10 | + @request = ActionController::TestRequest.new | ||
| 11 | + @response = ActionController::TestResponse.new | ||
| 12 | + @profile = create_user('profile').person | ||
| 13 | + @article = TinyMceArticle.create!(:profile => @profile, :name => 'An article') | ||
| 14 | + @comment = Comment.new(:source => @article, :author => @profile, :body => 'test') | ||
| 15 | + @comment.save! | ||
| 16 | + login_as(@profile.identifier) | ||
| 17 | + environment = Environment.default | ||
| 18 | + environment.enable_plugin(MarkCommentAsReadPlugin) | ||
| 19 | + self.stubs(:user).returns(@profile) | ||
| 20 | + end | ||
| 21 | + | ||
| 22 | + attr_reader :profile, :comment | ||
| 23 | + | ||
| 24 | + should 'mark comment as read' do | ||
| 25 | + xhr :post, :mark_as_read, :profile => profile.identifier, :id => comment.id | ||
| 26 | + assert_match /\{\"ok\":true\}/, @response.body | ||
| 27 | + end | ||
| 28 | + | ||
| 29 | + should 'mark comment as not read' do | ||
| 30 | + xhr :post, :mark_as_not_read, :profile => profile.identifier, :id => comment.id | ||
| 31 | + assert_match /\{\"ok\":true\}/, @response.body | ||
| 32 | + end | ||
| 33 | +end |
plugins/mark_comment_as_read/test/unit/mark_comment_as_read_plugin/comment_test.rb
0 → 100644
| @@ -0,0 +1,38 @@ | @@ -0,0 +1,38 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../../../../../test/test_helper' | ||
| 2 | + | ||
| 3 | +class MarkCommentAsReadPlugin::CommentTest < ActiveSupport::TestCase | ||
| 4 | + | ||
| 5 | + def setup | ||
| 6 | + @person = create_user('user').person | ||
| 7 | + @article = TinyMceArticle.create!(:profile => @person, :name => 'An article') | ||
| 8 | + @comment = Comment.create!(:title => 'title', :body => 'body', :author_id => @person.id, :source => @article) | ||
| 9 | + end | ||
| 10 | + | ||
| 11 | + should 'mark comment as read' do | ||
| 12 | + assert !@comment.marked_as_read?(@person) | ||
| 13 | + @comment.mark_as_read(@person) | ||
| 14 | + assert @comment.marked_as_read?(@person) | ||
| 15 | + end | ||
| 16 | + | ||
| 17 | + should 'do not mark a comment as read again' do | ||
| 18 | + @comment.mark_as_read(@person) | ||
| 19 | + assert_raise ActiveRecord::StatementInvalid do | ||
| 20 | + @comment.mark_as_read(@person) | ||
| 21 | + end | ||
| 22 | + end | ||
| 23 | + | ||
| 24 | + should 'mark comment as not read' do | ||
| 25 | + @comment.mark_as_read(@person) | ||
| 26 | + assert @comment.marked_as_read?(@person) | ||
| 27 | + @comment.mark_as_not_read(@person) | ||
| 28 | + assert !@comment.marked_as_read?(@person) | ||
| 29 | + end | ||
| 30 | + | ||
| 31 | + should 'return comments marked as read for a user' do | ||
| 32 | + person2 = create_user('user2').person | ||
| 33 | + @comment.mark_as_read(@person) | ||
| 34 | + assert_equal [], @article.comments.marked_as_read(@person) - [@comment] | ||
| 35 | + assert_equal [], @article.comments.marked_as_read(person2) | ||
| 36 | + end | ||
| 37 | + | ||
| 38 | +end |
plugins/mark_comment_as_read/test/unit/mark_comment_as_read_test.rb
0 → 100644
| @@ -0,0 +1,87 @@ | @@ -0,0 +1,87 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../../../../test/test_helper' | ||
| 2 | + | ||
| 3 | +class MarkCommentAsReadPluginTest < ActiveSupport::TestCase | ||
| 4 | + | ||
| 5 | + include ActionView::Helpers::TagHelper | ||
| 6 | + include NoosferoTestHelper | ||
| 7 | + | ||
| 8 | + def setup | ||
| 9 | + @plugin = MarkCommentAsReadPlugin.new | ||
| 10 | + @person = create_user('user').person | ||
| 11 | + @article = TinyMceArticle.create!(:profile => @person, :name => 'An article') | ||
| 12 | + @comment = Comment.create!(:source => @article, :author => @person, :body => 'test') | ||
| 13 | + self.stubs(:user).returns(@person) | ||
| 14 | + self.stubs(:profile).returns(@person) | ||
| 15 | + end | ||
| 16 | + | ||
| 17 | + attr_reader :plugin, :comment | ||
| 18 | + | ||
| 19 | + should 'show link when person is logged in' do | ||
| 20 | + action = @plugin.comment_actions(@comment) | ||
| 21 | + link = self.instance_eval(&action) | ||
| 22 | + assert link | ||
| 23 | + end | ||
| 24 | + | ||
| 25 | + should 'do not show link when person is not logged in' do | ||
| 26 | + self.stubs(:user).returns(nil) | ||
| 27 | + action = @plugin.comment_actions(@comment) | ||
| 28 | + link = self.instance_eval(&action) | ||
| 29 | + assert !link | ||
| 30 | + end | ||
| 31 | + | ||
| 32 | + should 'return actions when comment is not read' do | ||
| 33 | + action = @plugin.comment_actions(@comment) | ||
| 34 | + links = self.instance_eval(&action) | ||
| 35 | + assert_equal 2, links.size | ||
| 36 | + end | ||
| 37 | + | ||
| 38 | + should 'return actions when comment is read' do | ||
| 39 | + @comment.mark_as_read(@person) | ||
| 40 | + action = @plugin.comment_actions(@comment) | ||
| 41 | + links = self.instance_eval(&action) | ||
| 42 | + assert_equal 2, links.size | ||
| 43 | + end | ||
| 44 | + | ||
| 45 | + should 'do not return any id when user is not logged in' do | ||
| 46 | + self.stubs(:user).returns(nil) | ||
| 47 | + action = @plugin.check_comment_actions(@comment) | ||
| 48 | + id = self.instance_eval(&action) | ||
| 49 | + assert !id | ||
| 50 | + end | ||
| 51 | + | ||
| 52 | + should 'return id of mark as not read link when comment is read' do | ||
| 53 | + @comment.mark_as_read(@person) | ||
| 54 | + action = @plugin.check_comment_actions(@comment) | ||
| 55 | + id = self.instance_eval(&action) | ||
| 56 | + assert_equal "#comment-action-mark-as-not-read-#{@comment.id}", id | ||
| 57 | + end | ||
| 58 | + | ||
| 59 | + should 'return id of mark as read link when comment is not read' do | ||
| 60 | + action = @plugin.check_comment_actions(@comment) | ||
| 61 | + id = self.instance_eval(&action) | ||
| 62 | + assert_equal "#comment-action-mark-as-read-#{@comment.id}", id | ||
| 63 | + end | ||
| 64 | + | ||
| 65 | + should 'return javascript to mark comment as read' do | ||
| 66 | + @comment.mark_as_read(@person) | ||
| 67 | + content = @plugin.article_extra_contents(@article) | ||
| 68 | + assert self.instance_eval(&content) | ||
| 69 | + end | ||
| 70 | + | ||
| 71 | + should 'do not return extra content if comment is not marked as read' do | ||
| 72 | + content = @plugin.article_extra_contents(@article) | ||
| 73 | + assert !self.instance_eval(&content) | ||
| 74 | + end | ||
| 75 | + | ||
| 76 | + should 'do not return extra content if user is not logged in' do | ||
| 77 | + @comment.mark_as_read(@person) | ||
| 78 | + self.stubs(:user).returns(nil) | ||
| 79 | + content = @plugin.article_extra_contents(@article) | ||
| 80 | + assert !self.instance_eval(&content) | ||
| 81 | + end | ||
| 82 | + | ||
| 83 | + def link_to_function(content, url, options = {}) | ||
| 84 | + link_to(content, url, options) | ||
| 85 | + end | ||
| 86 | + | ||
| 87 | +end |
plugins/pg_search/lib/ext/active_record.rb
| @@ -2,11 +2,9 @@ require_dependency 'active_record' | @@ -2,11 +2,9 @@ require_dependency 'active_record' | ||
| 2 | 2 | ||
| 3 | class ActiveRecord::Base | 3 | class ActiveRecord::Base |
| 4 | def self.pg_search_plugin_search(query) | 4 | def self.pg_search_plugin_search(query) |
| 5 | - query.gsub!(/\|/,' ') | ||
| 6 | - formatted_query = query.split.map{|w| w += ":*"}.join('|') | ||
| 7 | - | 5 | + filtered_query = query.gsub(/[\|\(\)\\\/\s\[\]'"*%&!:]/,' ').split.map{|w| w += ":*"}.join('|') |
| 8 | if defined?(self::SEARCHABLE_FIELDS) | 6 | if defined?(self::SEARCHABLE_FIELDS) |
| 9 | - where("to_tsvector('simple', #{pg_search_plugin_fields}) @@ to_tsquery('#{formatted_query}')") | 7 | + where("to_tsvector('simple', #{pg_search_plugin_fields}) @@ to_tsquery('#{filtered_query}')") |
| 10 | else | 8 | else |
| 11 | raise "No searchable fields defined for #{self.name}" | 9 | raise "No searchable fields defined for #{self.name}" |
| 12 | end | 10 | end |
plugins/pg_search/test/unit/pg_search_plugin_test.rb
| @@ -21,6 +21,11 @@ class PgSearchPluginTest < ActiveSupport::TestCase | @@ -21,6 +21,11 @@ class PgSearchPluginTest < ActiveSupport::TestCase | ||
| 21 | assert_includes search(Profile, 'admin deb'), profile2 | 21 | assert_includes search(Profile, 'admin deb'), profile2 |
| 22 | end | 22 | end |
| 23 | 23 | ||
| 24 | + should 'locate profile escaping special characters' do | ||
| 25 | + profile = fast_create(Profile, :name => 'John', :identifier => 'waterfall') | ||
| 26 | + assert_includes search(Profile, ') ( /\/\/\/\/\ o_o oOo o_o /\/\/\/\/\ ) ((tx waterfall)'), profile | ||
| 27 | + end | ||
| 28 | + | ||
| 24 | # TODO This feature is available only on Postgresql 9.0 | 29 | # TODO This feature is available only on Postgresql 9.0 |
| 25 | # http://www.postgresql.org/docs/9.0/static/unaccent.html | 30 | # http://www.postgresql.org/docs/9.0/static/unaccent.html |
| 26 | # should 'ignore accents' do | 31 | # should 'ignore accents' do |
plugins/recent_content/test/unit/recent_content_block_test.rb
| @@ -61,9 +61,9 @@ class RecentContentBlockTest < ActiveSupport::TestCase | @@ -61,9 +61,9 @@ class RecentContentBlockTest < ActiveSupport::TestCase | ||
| 61 | 61 | ||
| 62 | root = fast_create(Blog, :name => 'test-blog', :profile_id => profile.id) | 62 | root = fast_create(Blog, :name => 'test-blog', :profile_id => profile.id) |
| 63 | 63 | ||
| 64 | - a1 = fast_create(TextileArticle, :name => 'article #1', :profile_id => profile.id, :parent_id => root.id) | ||
| 65 | - a2 = fast_create(TextileArticle, :name => 'article #2', :profile_id => profile.id, :parent_id => root.id) | ||
| 66 | - a3 = fast_create(TextileArticle, :name => 'article #3', :profile_id => profile.id, :parent_id => root.id) | 64 | + a1 = fast_create(TextileArticle, :name => 'article #1', :profile_id => profile.id, :parent_id => root.id, :created_at => Time.now - 2.days) |
| 65 | + a2 = fast_create(TextileArticle, :name => 'article #2', :profile_id => profile.id, :parent_id => root.id, :created_at => Time.now - 1.days) | ||
| 66 | + a3 = fast_create(TextileArticle, :name => 'article #3', :profile_id => profile.id, :parent_id => root.id, :created_at => Time.now) | ||
| 67 | 67 | ||
| 68 | block = RecentContentBlock.new | 68 | block = RecentContentBlock.new |
| 69 | block.stubs(:holder).returns(profile) | 69 | block.stubs(:holder).returns(profile) |
| @@ -0,0 +1,95 @@ | @@ -0,0 +1,95 @@ | ||
| 1 | +require_dependency 'article' | ||
| 2 | + | ||
| 3 | +class Article | ||
| 4 | + | ||
| 5 | + named_scope :relevant_content, :conditions => ["articles.published = true and (articles.type != 'UploadedFile' and articles.type != 'Blog' and articles.type != 'RssFeed') OR articles.type is NULL"] | ||
| 6 | + | ||
| 7 | + def self.articles_columns | ||
| 8 | + Article.column_names.map {|c| "articles.#{c}"} .join(",") | ||
| 9 | + end | ||
| 10 | + | ||
| 11 | + def self.most_accessed(owner, limit = nil) | ||
| 12 | + conditions = owner.kind_of?(Environment) ? ["hits > 0"] : ["profile_id = ? and hits > 0", owner.id] | ||
| 13 | + result = Article.relevant_content.find( | ||
| 14 | + :all, | ||
| 15 | + :order => 'hits desc', | ||
| 16 | + :limit => limit, | ||
| 17 | + :conditions => conditions) | ||
| 18 | + result.paginate({:page => 1, :per_page => limit}) | ||
| 19 | + end | ||
| 20 | + | ||
| 21 | + def self.most_commented_relevant_content(owner, limit) | ||
| 22 | + conditions = owner.kind_of?(Environment) ? ["comments_count > 0"] : ["profile_id = ? and comments_count > 0", owner.id] | ||
| 23 | + result = Article.relevant_content.find( | ||
| 24 | + :all, | ||
| 25 | + :order => 'comments_count desc', | ||
| 26 | + :limit => limit, | ||
| 27 | + :conditions => conditions) | ||
| 28 | + result.paginate({:page => 1, :per_page => limit}) | ||
| 29 | + end | ||
| 30 | + | ||
| 31 | + def self.more_positive_votes(owner, limit = nil) | ||
| 32 | + conditions = owner.kind_of?(Environment) ? {'votes.voteable_type' => 'Article'} : ["profile_id = ? and votes.voteable_type = ? ", owner.id, 'Article'] | ||
| 33 | + result = Article.relevant_content.find( | ||
| 34 | + :all, | ||
| 35 | + :order => 'sum(vote) desc', | ||
| 36 | + :group => 'voteable_id, ' + articles_columns, | ||
| 37 | + :limit => limit, | ||
| 38 | + :having => ['sum(vote) > 0'], | ||
| 39 | + :conditions => conditions, | ||
| 40 | + :joins => 'INNER JOIN votes ON articles.id = votes.voteable_id') | ||
| 41 | + result.paginate({:page => 1, :per_page => limit}) | ||
| 42 | + end | ||
| 43 | + | ||
| 44 | + def self.more_negative_votes(owner, limit = nil) | ||
| 45 | + conditions = owner.kind_of?(Environment) ? {'votes.voteable_type' => 'Article'} : ["profile_id = ? and votes.voteable_type = 'Article' ", owner.id] | ||
| 46 | + result = Article.relevant_content.find( | ||
| 47 | + :all, | ||
| 48 | + :order => 'sum(vote) asc', | ||
| 49 | + :group => 'voteable_id, ' + articles_columns, | ||
| 50 | + :limit => limit, | ||
| 51 | + :having => ['sum(vote) < 0'], | ||
| 52 | + :conditions => conditions, | ||
| 53 | + :joins => 'INNER JOIN votes ON articles.id = votes.voteable_id' | ||
| 54 | + ) | ||
| 55 | + result.paginate({:page => 1, :per_page => limit}) | ||
| 56 | + end | ||
| 57 | + | ||
| 58 | + def self.most_liked(owner, limit = nil) | ||
| 59 | + conditions = owner.kind_of?(Environment) ? ["votes.voteable_type = 'Article' and vote > 0"] : ["votes.voteable_type = 'Article' and vote > 0 and profile_id = ? ", owner.id] | ||
| 60 | + result = Article.relevant_content.find( | ||
| 61 | + :all, | ||
| 62 | + :select => articles_columns, | ||
| 63 | + :order => 'count(voteable_id) desc', | ||
| 64 | + :group => 'voteable_id, ' + articles_columns, | ||
| 65 | + :limit => limit, | ||
| 66 | + :conditions => conditions, | ||
| 67 | + :joins => 'INNER JOIN votes ON articles.id = votes.voteable_id') | ||
| 68 | + result.paginate({:page => 1, :per_page => limit}) | ||
| 69 | + end | ||
| 70 | + | ||
| 71 | + def self.most_disliked(owner, limit = nil) | ||
| 72 | + conditions = owner.kind_of?(Environment) ? ["votes.voteable_type = 'Article' and vote < 0"] : ["votes.voteable_type = 'Article' and vote < 0 and profile_id = ? ", owner.id] | ||
| 73 | + result = Article.relevant_content.find( | ||
| 74 | + :all, | ||
| 75 | + :order => 'count(voteable_id) desc', | ||
| 76 | + :group => 'voteable_id, ' + articles_columns, | ||
| 77 | + :limit => limit, | ||
| 78 | + :conditions => conditions, | ||
| 79 | + :joins => 'INNER JOIN votes ON articles.id = votes.voteable_id') | ||
| 80 | + result.paginate({:page => 1, :per_page => limit}) | ||
| 81 | + end | ||
| 82 | + | ||
| 83 | + def self.most_voted(owner, limit = nil) | ||
| 84 | + conditions = owner.kind_of?(Environment) ? ["votes.voteable_type = 'Article'"] : ["votes.voteable_type = 'Article' and profile_id = ? ", owner.id] | ||
| 85 | + result = Article.relevant_content.find( | ||
| 86 | + :all, | ||
| 87 | + :select => articles_columns, | ||
| 88 | + :order => 'count(voteable_id) desc', | ||
| 89 | + :group => 'voteable_id, ' + articles_columns, | ||
| 90 | + :limit => limit, | ||
| 91 | + :conditions => conditions, | ||
| 92 | + :joins => 'INNER JOIN votes ON articles.id = votes.voteable_id') | ||
| 93 | + result.paginate({:page => 1, :per_page => limit}) | ||
| 94 | + end | ||
| 95 | +end |
| @@ -0,0 +1,21 @@ | @@ -0,0 +1,21 @@ | ||
| 1 | +class RelevantContentPlugin < Noosfero::Plugin | ||
| 2 | + | ||
| 3 | + def self.plugin_name | ||
| 4 | + "Relevant Content Plugin" | ||
| 5 | + end | ||
| 6 | + | ||
| 7 | + def self.plugin_description | ||
| 8 | + _("A plugin that lists the most accessed, most commented, most liked and most disliked contents.") | ||
| 9 | + end | ||
| 10 | + | ||
| 11 | + def self.extra_blocks | ||
| 12 | + { | ||
| 13 | + RelevantContentPlugin::RelevantContentBlock => {} | ||
| 14 | + } | ||
| 15 | + end | ||
| 16 | + | ||
| 17 | + def stylesheet? | ||
| 18 | + true | ||
| 19 | + end | ||
| 20 | + | ||
| 21 | +end |
plugins/relevant_content/lib/relevant_content_plugin/relevant_content_block.rb
0 → 100644
| @@ -0,0 +1,93 @@ | @@ -0,0 +1,93 @@ | ||
| 1 | +class RelevantContentPlugin::RelevantContentBlock < Block | ||
| 2 | + def self.description | ||
| 3 | + _('Relevant content') | ||
| 4 | + end | ||
| 5 | + | ||
| 6 | + def default_title | ||
| 7 | + _('Relevant content') | ||
| 8 | + end | ||
| 9 | + | ||
| 10 | + def help | ||
| 11 | + _('This block lists the most popular content.') | ||
| 12 | + end | ||
| 13 | + | ||
| 14 | + settings_items :limit, :type => :integer, :default => 5 | ||
| 15 | + settings_items :show_most_read, :type => :boolean, :default => 1 | ||
| 16 | + settings_items :show_most_commented, :type => :boolean, :default => 1 | ||
| 17 | + settings_items :show_most_liked, :type => :boolean, :default => 1 | ||
| 18 | + settings_items :show_most_disliked, :type => :boolean, :default => 0 | ||
| 19 | + settings_items :show_most_voted, :type => :boolean, :default => 1 | ||
| 20 | + | ||
| 21 | + include ActionController::UrlWriter | ||
| 22 | + def content(args={}) | ||
| 23 | + | ||
| 24 | + content = block_title(title) | ||
| 25 | + | ||
| 26 | + if self.show_most_read | ||
| 27 | + docs = Article.most_accessed(owner, self.limit) | ||
| 28 | + if !docs.blank? | ||
| 29 | + subcontent = "" | ||
| 30 | + subcontent += content_tag(:span, _("Most read articles"), :class=>"title mread") + "\n" | ||
| 31 | + subcontent += content_tag(:ul, docs.map {|item| content_tag('li', link_to(h(item.title), item.url))}.join("\n")) | ||
| 32 | + content += content_tag(:div, subcontent, :class=>"block mread") + "\n" | ||
| 33 | + end | ||
| 34 | + end | ||
| 35 | + | ||
| 36 | + if self.show_most_commented | ||
| 37 | + docs = Article.most_commented_relevant_content(owner, self.limit) | ||
| 38 | + if !docs.blank? | ||
| 39 | + subcontent = "" | ||
| 40 | + subcontent += content_tag(:span, _("Most commented articles"), :class=>"title mcommented") + "\n" | ||
| 41 | + subcontent += content_tag(:ul, docs.map {|item| content_tag('li', link_to(h(item.title), item.url))}.join("\n")) | ||
| 42 | + content += content_tag(:div, subcontent, :class=>"block mcommented") + "\n" | ||
| 43 | + end | ||
| 44 | + end | ||
| 45 | + | ||
| 46 | + if owner.kind_of?(Environment) | ||
| 47 | + env = owner | ||
| 48 | + else | ||
| 49 | + env = owner.environment | ||
| 50 | + end | ||
| 51 | + | ||
| 52 | + if env.plugin_enabled?(VotePlugin) | ||
| 53 | + if self.show_most_liked | ||
| 54 | + docs = Article.more_positive_votes(owner, self.limit) | ||
| 55 | + if !docs.blank? | ||
| 56 | + subcontent = "" | ||
| 57 | + subcontent += content_tag(:span, _("Most liked articles"), :class=>"title mliked") + "\n" | ||
| 58 | + subcontent += content_tag(:ul, docs.map {|item| content_tag('li', link_to(h(item.title), item.url))}.join("\n")) | ||
| 59 | + content += content_tag(:div, subcontent, :class=>"block mliked") + "\n" | ||
| 60 | + end | ||
| 61 | + end | ||
| 62 | + if self.show_most_disliked | ||
| 63 | + docs = Article.more_negative_votes(owner, self.limit) | ||
| 64 | + if !docs.blank? | ||
| 65 | + subcontent = "" | ||
| 66 | + subcontent += content_tag(:span, _("Most disliked articles"), :class=>"title mdisliked") + "\n" | ||
| 67 | + subcontent += content_tag(:ul, docs.map {|item| content_tag('li', link_to(h(item.title), item.url))}.join("\n")) | ||
| 68 | + content += content_tag(:div, subcontent, :class=>"block mdisliked") + "\n" | ||
| 69 | + end | ||
| 70 | + end | ||
| 71 | + | ||
| 72 | + if self.show_most_voted | ||
| 73 | + docs = Article.most_voted(owner, self.limit) | ||
| 74 | + if !docs.blank? | ||
| 75 | + subcontent = "" | ||
| 76 | + subcontent += content_tag(:span, _("Most voted articles"), :class=>"title mvoted") + "\n" | ||
| 77 | + subcontent += content_tag(:ul, docs.map {|item| content_tag('li', link_to(h(item.title), item.url))}.join("\n")) | ||
| 78 | + content += content_tag(:div, subcontent, :class=>"block mvoted") + "\n" | ||
| 79 | + end | ||
| 80 | + end | ||
| 81 | + end | ||
| 82 | + return content | ||
| 83 | + end | ||
| 84 | + | ||
| 85 | + def timeout | ||
| 86 | + 4.hours | ||
| 87 | + end | ||
| 88 | + | ||
| 89 | + def self.expire_on | ||
| 90 | + { :profile => [:article], :environment => [:article] } | ||
| 91 | + end | ||
| 92 | + | ||
| 93 | +end | ||
| 0 | \ No newline at end of file | 94 | \ No newline at end of file |
| @@ -0,0 +1,79 @@ | @@ -0,0 +1,79 @@ | ||
| 1 | +#content .relevant-content-plugin_relevant-content-block { | ||
| 2 | + padding: 10px 0px 10px 10px; | ||
| 3 | + word-wrap: break-word; | ||
| 4 | +} | ||
| 5 | + | ||
| 6 | +.relevant-content-plugin_relevant-content-block ul { | ||
| 7 | + margin: 0px; | ||
| 8 | + padding: 0px 0px 0px 20px; | ||
| 9 | +} | ||
| 10 | +.relevant-content-plugin_relevant-content-block li { | ||
| 11 | + margin: 0px; | ||
| 12 | + padding: 0px; | ||
| 13 | + list-style: none | ||
| 14 | +} | ||
| 15 | +.relevant-content-plugin_relevant-content-block a { | ||
| 16 | + text-decoration: none; | ||
| 17 | +} | ||
| 18 | +.relevant-content-plugin_relevant-content-block .block-footer-content { | ||
| 19 | + font-size: 10px; | ||
| 20 | +} | ||
| 21 | +.relevant-content-plugin_relevant-content-block .block-footer-content a:hover { | ||
| 22 | + text-decoration: underline; | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +.relevant-content-plugin_relevant-content-block p { | ||
| 26 | + text-align:center; | ||
| 27 | +} | ||
| 28 | + | ||
| 29 | +.relevant-content-plugin_relevant-content-block p.like{ | ||
| 30 | + background-image: url('images/positive-hand.png'); | ||
| 31 | + background-repeat: no-repeat; | ||
| 32 | + min-width: 50px; | ||
| 33 | + text-align:center; | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | +.relevant-content-plugin_relevant-content-block p.dislike{ | ||
| 37 | + background-image: url('images/negative-hand.png'); | ||
| 38 | + background-repeat: no-repeat; | ||
| 39 | + min-width: 50px; | ||
| 40 | + text-align:center; | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | + | ||
| 44 | +.relevant-content-plugin_relevant-content-block { | ||
| 45 | + //overflow: hidden; | ||
| 46 | + display: block; | ||
| 47 | + width: 100%; | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | + | ||
| 51 | +.relevant-content-cover img { | ||
| 52 | + width: 100%; | ||
| 53 | +} | ||
| 54 | + | ||
| 55 | +.relevant-content-plugin_relevant-content-block span.title { | ||
| 56 | + display: block; | ||
| 57 | + margin: 20px 0px 0px; | ||
| 58 | + padding: 0px 0px 0px 20px; | ||
| 59 | +} | ||
| 60 | + | ||
| 61 | +.relevant-content-plugin_relevant-content-block span.title.mread { | ||
| 62 | + | ||
| 63 | +} | ||
| 64 | + | ||
| 65 | +.relevant-content-plugin_relevant-content-block span.title.mcommented { | ||
| 66 | + | ||
| 67 | +} | ||
| 68 | + | ||
| 69 | +.relevant-content-plugin_relevant-content-block span.title.mliked { | ||
| 70 | + | ||
| 71 | +} | ||
| 72 | + | ||
| 73 | +.relevant-content-plugin_relevant-content-block span.title.mdisliked { | ||
| 74 | + | ||
| 75 | +} | ||
| 76 | + | ||
| 77 | +.relevant-content-plugin_relevant-content-block span.title.mvoted { | ||
| 78 | + | ||
| 79 | +} |
| @@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../../../test/test_helper' |
| @@ -0,0 +1,148 @@ | @@ -0,0 +1,148 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | + | ||
| 3 | +require 'comment_controller' | ||
| 4 | +# Re-raise errors caught by the controller. | ||
| 5 | +class CommentController; def rescue_action(e) raise e end; end | ||
| 6 | + | ||
| 7 | +class RelevantContentBlockTest < ActiveSupport::TestCase | ||
| 8 | + | ||
| 9 | + include AuthenticatedTestHelper | ||
| 10 | + fixtures :users, :environments | ||
| 11 | + | ||
| 12 | + def setup | ||
| 13 | + @controller = CommentController.new | ||
| 14 | + @request = ActionController::TestRequest.new | ||
| 15 | + @response = ActionController::TestResponse.new | ||
| 16 | + @profile = create_user('testinguser').person | ||
| 17 | + @environment = @profile.environment | ||
| 18 | + end | ||
| 19 | + attr_reader :profile, :environment | ||
| 20 | + | ||
| 21 | + def enable_vote_plugin | ||
| 22 | + enabled = false | ||
| 23 | + environment=Environment.default | ||
| 24 | + if Noosfero::Plugin.all.include?('VotePlugin') | ||
| 25 | + if not environment.enabled_plugins.include?(:vote) | ||
| 26 | + environment.enable_plugin(Vote) | ||
| 27 | + environment.save! | ||
| 28 | + end | ||
| 29 | + enabled = true | ||
| 30 | + end | ||
| 31 | + enabled | ||
| 32 | + end | ||
| 33 | + | ||
| 34 | + should 'list most commented articles' do | ||
| 35 | + Article.delete_all | ||
| 36 | + a1 = create(TextileArticle, :name => "art 1", :profile_id => profile.id) | ||
| 37 | + a2 = create(TextileArticle, :name => "art 2", :profile_id => profile.id) | ||
| 38 | + a3 = create(TextileArticle, :name => "art 3", :profile_id => profile.id) | ||
| 39 | + | ||
| 40 | + 2.times { Comment.create(:title => 'test', :body => 'asdsad', :author => profile, :source => a2).save! } | ||
| 41 | + 4.times { Comment.create(:title => 'test', :body => 'asdsad', :author => profile, :source => a3).save! } | ||
| 42 | + | ||
| 43 | + # should respect the order (more commented comes first) | ||
| 44 | + assert_equal a3.name, profile.articles.most_commented_relevant_content(Environment.default, 3).first.name | ||
| 45 | + # It is a2 instead of a1 since it does not list articles without comments | ||
| 46 | + assert_equal a2.name, profile.articles.most_commented_relevant_content(Environment.default, 3).last.name | ||
| 47 | + end | ||
| 48 | + | ||
| 49 | + | ||
| 50 | + should 'find the most voted' do | ||
| 51 | + if not enable_vote_plugin | ||
| 52 | + return | ||
| 53 | + end | ||
| 54 | + article = fast_create(Article, {:name=>'2 votes'}) | ||
| 55 | + 2.times{ | ||
| 56 | + person = fast_create(Person) | ||
| 57 | + person.vote_for(article) | ||
| 58 | + } | ||
| 59 | + article = fast_create(Article, {:name=>'10 votes'}) | ||
| 60 | + 10.times{ | ||
| 61 | + person = fast_create(Person) | ||
| 62 | + person.vote_for(article) | ||
| 63 | + } | ||
| 64 | + article = fast_create(Article, {:name=>'5 votes'}) | ||
| 65 | + 5.times{ | ||
| 66 | + person = fast_create(Person) | ||
| 67 | + person.vote_for(article) | ||
| 68 | + } | ||
| 69 | + articles = Article.most_voted(Environment.default, 5) | ||
| 70 | + assert_equal '10 votes', articles.first.name | ||
| 71 | + assert_equal '2 votes', articles.last.name | ||
| 72 | + end | ||
| 73 | + | ||
| 74 | + should 'list the most postive' do | ||
| 75 | + if not enable_vote_plugin | ||
| 76 | + return | ||
| 77 | + end | ||
| 78 | + article = fast_create(Article, {:name=>'23 votes for 20 votes against'}) | ||
| 79 | + 20.times{ | ||
| 80 | + person = fast_create(Person) | ||
| 81 | + person.vote_against(article) | ||
| 82 | + } | ||
| 83 | + 23.times{ | ||
| 84 | + person = fast_create(Person) | ||
| 85 | + person.vote_for(article) | ||
| 86 | + } | ||
| 87 | + article = fast_create(Article, {:name=>'10 votes for 5 votes against'}) | ||
| 88 | + 10.times{ | ||
| 89 | + person = fast_create(Person) | ||
| 90 | + person.vote_for(article) | ||
| 91 | + } | ||
| 92 | + 5.times{ | ||
| 93 | + person = fast_create(Person) | ||
| 94 | + person.vote_against(article) | ||
| 95 | + } | ||
| 96 | + article = fast_create(Article, {:name=>'2 votes against'}) | ||
| 97 | + 2.times{ | ||
| 98 | + person = fast_create(Person) | ||
| 99 | + person.vote_against(article) | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + article = fast_create(Article, {:name=>'7 votes for'}) | ||
| 103 | + 7.times{ | ||
| 104 | + person = fast_create(Person) | ||
| 105 | + person.vote_for(article) | ||
| 106 | + } | ||
| 107 | + articles = Article.more_positive_votes(Environment.default, 5) | ||
| 108 | + assert_equal '7 votes for', articles.first.name | ||
| 109 | + assert_equal '23 votes for 20 votes against', articles.last.name | ||
| 110 | + end | ||
| 111 | + | ||
| 112 | + should 'list the most negative' do | ||
| 113 | + if not enable_vote_plugin | ||
| 114 | + return | ||
| 115 | + end | ||
| 116 | + article = fast_create(Article, {:name=>'23 votes for 29 votes against'}) | ||
| 117 | + 29.times{ | ||
| 118 | + person = fast_create(Person) | ||
| 119 | + person.vote_against(article) | ||
| 120 | + } | ||
| 121 | + 23.times{ | ||
| 122 | + person = fast_create(Person) | ||
| 123 | + person.vote_for(article) | ||
| 124 | + } | ||
| 125 | + article = fast_create(Article, {:name=>'10 votes for 15 votes against'}) | ||
| 126 | + 10.times{ | ||
| 127 | + person = fast_create(Person) | ||
| 128 | + person.vote_for(article) | ||
| 129 | + } | ||
| 130 | + 15.times{ | ||
| 131 | + person = fast_create(Person) | ||
| 132 | + person.vote_against(article) | ||
| 133 | + } | ||
| 134 | + article = fast_create(Article, {:name=>'2 votes against'}) | ||
| 135 | + 2.times{ | ||
| 136 | + person = fast_create(Person) | ||
| 137 | + person.vote_against(article) | ||
| 138 | + } | ||
| 139 | + article = fast_create(Article, {:name=>'7 votes for'}) | ||
| 140 | + 7.times{ | ||
| 141 | + person = fast_create(Person) | ||
| 142 | + person.vote_for(article) | ||
| 143 | + } | ||
| 144 | + articles = Article.more_negative_votes(Environment.default, 5) | ||
| 145 | + assert_equal '23 votes for 29 votes against', articles.first.name | ||
| 146 | + assert_equal '2 votes against', articles.last.name | ||
| 147 | + end | ||
| 148 | +end | ||
| 0 | \ No newline at end of file | 149 | \ No newline at end of file |
plugins/relevant_content/test/unit/relevant_content_block_test.rb
0 → 100644
| @@ -0,0 +1,47 @@ | @@ -0,0 +1,47 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | + | ||
| 3 | +require 'comment_controller' | ||
| 4 | +# Re-raise errors caught by the controller. | ||
| 5 | +class CommentController; def rescue_action(e) raise e end; end | ||
| 6 | + | ||
| 7 | +class RelevantContentBlockTest < ActiveSupport::TestCase | ||
| 8 | + | ||
| 9 | + include AuthenticatedTestHelper | ||
| 10 | + fixtures :users, :environments | ||
| 11 | + | ||
| 12 | + def setup | ||
| 13 | + @controller = CommentController.new | ||
| 14 | + @request = ActionController::TestRequest.new | ||
| 15 | + @response = ActionController::TestResponse.new | ||
| 16 | + | ||
| 17 | + @profile = create_user('testinguser').person | ||
| 18 | + @environment = @profile.environment | ||
| 19 | + end | ||
| 20 | + attr_reader :profile, :environment | ||
| 21 | + | ||
| 22 | + should 'have a default title' do | ||
| 23 | + relevant_content_block = RelevantContentPlugin::RelevantContentBlock.new | ||
| 24 | + block = Block.new | ||
| 25 | + assert_not_equal block.default_title, relevant_content_block.default_title | ||
| 26 | + end | ||
| 27 | + | ||
| 28 | + should 'have a help tooltip' do | ||
| 29 | + relevant_content_block = RelevantContentPlugin::RelevantContentBlock.new | ||
| 30 | + block = Block.new | ||
| 31 | + assert_not_equal "", relevant_content_block.help | ||
| 32 | + end | ||
| 33 | + | ||
| 34 | + should 'describe itself' do | ||
| 35 | + assert_not_equal Block.description, RelevantContentPlugin::RelevantContentBlock.description | ||
| 36 | + end | ||
| 37 | + | ||
| 38 | + should 'is editable' do | ||
| 39 | + block = RelevantContentPlugin::RelevantContentBlock.new | ||
| 40 | + assert block.editable? | ||
| 41 | + end | ||
| 42 | + | ||
| 43 | + should 'expire' do | ||
| 44 | + assert_equal RelevantContentPlugin::RelevantContentBlock.expire_on, {:environment=>[:article], :profile=>[:article]} | ||
| 45 | + end | ||
| 46 | + | ||
| 47 | +end |
plugins/relevant_content/test/unit/relevant_content_plugin_test.rb
0 → 100644
| @@ -0,0 +1,29 @@ | @@ -0,0 +1,29 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | + | ||
| 3 | +class RelevantContentPluginTest < ActiveSupport::TestCase | ||
| 4 | + | ||
| 5 | + def setup | ||
| 6 | + @plugin = RelevantContentPlugin.new | ||
| 7 | + end | ||
| 8 | + | ||
| 9 | + should 'be a noosfero plugin' do | ||
| 10 | + assert_kind_of Noosfero::Plugin, @plugin | ||
| 11 | + end | ||
| 12 | + | ||
| 13 | + should 'have name' do | ||
| 14 | + assert_equal 'Relevant Content Plugin', RelevantContentPlugin.plugin_name | ||
| 15 | + end | ||
| 16 | + | ||
| 17 | + should 'have description' do | ||
| 18 | + assert_equal _("A plugin that lists the most accessed, most commented, most liked and most disliked contents."), RelevantContentPlugin.plugin_description | ||
| 19 | + end | ||
| 20 | + | ||
| 21 | + should 'have stylesheet' do | ||
| 22 | + assert @plugin.stylesheet? | ||
| 23 | + end | ||
| 24 | + | ||
| 25 | + should "return RelevantContentBlock in extra_blocks class method" do | ||
| 26 | + assert RelevantContentPlugin.extra_blocks.keys.include?(RelevantContentPlugin::RelevantContentBlock) | ||
| 27 | + end | ||
| 28 | + | ||
| 29 | +end |
plugins/relevant_content/views/box_organizer/relevant_content_plugin/_relevant_content_block.rhtml
0 → 100644
| @@ -0,0 +1,8 @@ | @@ -0,0 +1,8 @@ | ||
| 1 | +<div id='edit-relevant-content-block'> | ||
| 2 | + <%= labelled_form_field _('Limit of items per category'), text_field(:block, :limit, :size => 3) %> | ||
| 3 | + <%= labelled_check_box _('Display most accessed content'), "block[show_most_read]", 1 ,@block.show_most_read %><BR> | ||
| 4 | + <%= labelled_check_box _('Display most commented content'), "block[show_most_commented]", 1 ,@block.show_most_commented %><BR> | ||
| 5 | + <%= labelled_check_box _('Display most liked content'), "block[show_most_liked]", 1 ,@block.show_most_liked %><BR> | ||
| 6 | + <%= labelled_check_box _('Display most voted content'), "block[show_most_voted]", 1 ,@block.show_most_voted %><BR> | ||
| 7 | + <%= labelled_check_box _('Display most disliked content'), "block[show_most_disliked]", 1 , @block.show_most_disliked %><BR> | ||
| 8 | +</div> | ||
| 0 | \ No newline at end of file | 9 | \ No newline at end of file |
plugins/relevant_content/views/environment_design/relevant_content_plugin
0 → 120000
plugins/relevant_content/views/profile_design/relevant_content_plugin
0 → 120000
plugins/send_email/controllers/send_email_plugin_base_controller.rb
| @@ -3,7 +3,7 @@ module SendEmailPluginBaseController | @@ -3,7 +3,7 @@ module SendEmailPluginBaseController | ||
| 3 | if request.post? | 3 | if request.post? |
| 4 | @context_url = profile ? profile.url : {:host => environment.default_hostname, :controller => 'home'} | 4 | @context_url = profile ? profile.url : {:host => environment.default_hostname, :controller => 'home'} |
| 5 | @mail = SendEmailPlugin::Mail.new( | 5 | @mail = SendEmailPlugin::Mail.new( |
| 6 | - :from => environment.contact_email, | 6 | + :from => environment.noreply_email, |
| 7 | :to => params[:to], | 7 | :to => params[:to], |
| 8 | :message => params[:message], | 8 | :message => params[:message], |
| 9 | :environment => environment, | 9 | :environment => environment, |
plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb
| 1 | <h1> <%= _('Basket options') %> </h1> | 1 | <h1> <%= _('Basket options') %> </h1> |
| 2 | 2 | ||
| 3 | <%= form_for(:settings, @settings, :url => {:action => 'edit'}, :html => {:method => 'post'}) do |f| %> | 3 | <%= form_for(:settings, @settings, :url => {:action => 'edit'}, :html => {:method => 'post'}) do |f| %> |
| 4 | - <%= labelled_form_field(_('Enabled?'), f.check_box(:enabled)) %> | ||
| 5 | - <%= labelled_form_field(_('Delivery?'), f.check_box(:delivery)) %> | 4 | + <%= labelled_form_field(_('Enable shopping basket'), f.check_box(:enabled)) %> |
| 5 | + <%= labelled_form_field(_('Enable delivery fields on orders'), f.check_box(:delivery)) %> | ||
| 6 | <% display_delivery_settings = @settings.delivery ? 'auto' : 'none' %> | 6 | <% display_delivery_settings = @settings.delivery ? 'auto' : 'none' %> |
| 7 | <fieldset id='delivery_settings' style="display: <%= display_delivery_settings %>"><legend><%=_('Delivery')%></legend> | 7 | <fieldset id='delivery_settings' style="display: <%= display_delivery_settings %>"><legend><%=_('Delivery')%></legend> |
| 8 | <table> | 8 | <table> |
| @@ -33,8 +33,8 @@ | @@ -33,8 +33,8 @@ | ||
| 33 | </tr> | 33 | </tr> |
| 34 | </table> | 34 | </table> |
| 35 | 35 | ||
| 36 | - <%= labelled_form_field(_('Free delivery price:'), f.text_field(:free_delivery_price)) %> | ||
| 37 | - <%= content_tag('small', _('Empty stands for no free delivery price.')) %> | 36 | + <%= labelled_form_field(_("Order's minimum price for free delivery:"), f.text_field(:free_delivery_price)) %> |
| 37 | + <%= content_tag('small', _('Leave empty to always charge the delivery.')) %> | ||
| 38 | </fieldset> | 38 | </fieldset> |
| 39 | <br style='clear: both'/> | 39 | <br style='clear: both'/> |
| 40 | <br style='clear: both'/> | 40 | <br style='clear: both'/> |
plugins/spaminator/lib/spaminator_plugin/mailer.rb
| @@ -4,7 +4,7 @@ class SpaminatorPlugin::Mailer < Noosfero::Plugin::MailerBase | @@ -4,7 +4,7 @@ class SpaminatorPlugin::Mailer < Noosfero::Plugin::MailerBase | ||
| 4 | def inactive_person_notification(person) | 4 | def inactive_person_notification(person) |
| 5 | mail( | 5 | mail( |
| 6 | :to => person.email, | 6 | :to => person.email, |
| 7 | - :from => "#{person.environment.name} <#{person.environment.contact_email}>", | 7 | + :from => "#{person.environment.name} <#{person.environment.noreply_email}>", |
| 8 | :subject => _("[%s] You must reactivate your account.") % person.environment.name, | 8 | :subject => _("[%s] You must reactivate your account.") % person.environment.name, |
| 9 | :content_type => 'text/html', | 9 | :content_type => 'text/html', |
| 10 | :body => {:person => person, | 10 | :body => {:person => person, |
plugins/spaminator/test/unit/spaminator_plugin/mailer_test.rb
| @@ -14,7 +14,7 @@ class SpaminatorPlugin::MailerTest < ActiveSupport::TestCase | @@ -14,7 +14,7 @@ class SpaminatorPlugin::MailerTest < ActiveSupport::TestCase | ||
| 14 | attr_accessor :environment, :settings | 14 | attr_accessor :environment, :settings |
| 15 | 15 | ||
| 16 | should 'be able to send a inactive person notification message' do | 16 | should 'be able to send a inactive person notification message' do |
| 17 | - environment.contact_email = 'no-reply@noosfero.org' | 17 | + environment.noreply_email = 'no-reply@noosfero.org' |
| 18 | environment.save | 18 | environment.save |
| 19 | 19 | ||
| 20 | person = create_user('spammer').person | 20 | person = create_user('spammer').person |
| @@ -0,0 +1,54 @@ | @@ -0,0 +1,54 @@ | ||
| 1 | +README - Statistics (Statistics Plugin) | ||
| 2 | +================================ | ||
| 3 | + | ||
| 4 | +Statistics is a plugin to allow the user adds a block where you could see statistics of it's context. | ||
| 5 | + | ||
| 6 | +The Statistics block will be available for all layout columns of communities, peole, enterprises and environments. | ||
| 7 | + | ||
| 8 | +INSTALL | ||
| 9 | +======= | ||
| 10 | + | ||
| 11 | +Enable Plugin | ||
| 12 | +------------- | ||
| 13 | + | ||
| 14 | +Also, you need to enable Statistics Plugin at you Noosfero: | ||
| 15 | + | ||
| 16 | +cd <your_noosfero_dir> | ||
| 17 | +./script/noosfero-plugins enable statistics | ||
| 18 | + | ||
| 19 | +Active Plugin | ||
| 20 | +------------- | ||
| 21 | + | ||
| 22 | +As a Noosfero administrator user, go to administrator panel: | ||
| 23 | + | ||
| 24 | +- Click on "Enable/disable plugins" option | ||
| 25 | +- Click on "Statistics Plugin" check-box | ||
| 26 | + | ||
| 27 | +Running Statistics tests | ||
| 28 | +-------------------- | ||
| 29 | + | ||
| 30 | +$ rake test:noosfero_plugins:statistics | ||
| 31 | + | ||
| 32 | + | ||
| 33 | +Get Involved | ||
| 34 | +============ | ||
| 35 | + | ||
| 36 | +If you found any bug and/or want to collaborate, please send an e-mail to eduardo.edington@gmail.com | ||
| 37 | + | ||
| 38 | +LICENSE | ||
| 39 | +======= | ||
| 40 | + | ||
| 41 | +Copyright (c) The Author developers. | ||
| 42 | + | ||
| 43 | +See Noosfero license. | ||
| 44 | + | ||
| 45 | + | ||
| 46 | +AUTHORS | ||
| 47 | +======= | ||
| 48 | + | ||
| 49 | + Eduardo Tourinho Edington (eduardo.edington at gmail.com) | ||
| 50 | + | ||
| 51 | +ACKNOWLEDGMENTS | ||
| 52 | +=============== | ||
| 53 | + | ||
| 54 | +The author has been supported by Serpro |
| @@ -0,0 +1,146 @@ | @@ -0,0 +1,146 @@ | ||
| 1 | +class StatisticsBlock < Block | ||
| 2 | + | ||
| 3 | + settings_items :community_counter, :default => false | ||
| 4 | + settings_items :user_counter, :default => true | ||
| 5 | + settings_items :enterprise_counter, :default => false | ||
| 6 | + settings_items :category_counter, :default => false | ||
| 7 | + settings_items :tag_counter, :default => true | ||
| 8 | + settings_items :comment_counter, :default => true | ||
| 9 | + settings_items :hit_counter, :default => false | ||
| 10 | + settings_items :templates_ids_counter, Hash, :default => {} | ||
| 11 | + | ||
| 12 | + USER_COUNTERS = [:community_counter, :user_counter, :enterprise_counter, :tag_counter, :comment_counter, :hit_counter] | ||
| 13 | + COMMUNITY_COUNTERS = [:user_counter, :tag_counter, :comment_counter, :hit_counter] | ||
| 14 | + ENTERPRISE_COUNTERS = [:user_counter, :tag_counter, :comment_counter, :hit_counter] | ||
| 15 | + | ||
| 16 | + def self.description | ||
| 17 | + _('Statistics') | ||
| 18 | + end | ||
| 19 | + | ||
| 20 | + def default_title | ||
| 21 | + _('Statistics for %s') % owner.name | ||
| 22 | + end | ||
| 23 | + | ||
| 24 | + def is_visible? counter | ||
| 25 | + value = self.send(counter) | ||
| 26 | + value == '1' || value == true | ||
| 27 | + end | ||
| 28 | + | ||
| 29 | + def is_counter_available? counter | ||
| 30 | + if owner.kind_of?(Environment) | ||
| 31 | + true | ||
| 32 | + elsif owner.kind_of?(Person) | ||
| 33 | + USER_COUNTERS.include?(counter) | ||
| 34 | + elsif owner.kind_of?(Community) | ||
| 35 | + COMMUNITY_COUNTERS.include?(counter) | ||
| 36 | + elsif owner.kind_of?(Enterprise) | ||
| 37 | + ENTERPRISE_COUNTERS.include?(counter) | ||
| 38 | + end | ||
| 39 | + | ||
| 40 | + end | ||
| 41 | + | ||
| 42 | + def help | ||
| 43 | + _('This block presents some statistics about your context.') | ||
| 44 | + end | ||
| 45 | + | ||
| 46 | + def timeout | ||
| 47 | + 60.minutes | ||
| 48 | + end | ||
| 49 | + | ||
| 50 | + def environment | ||
| 51 | + if owner.kind_of?(Environment) | ||
| 52 | + owner | ||
| 53 | + elsif owner.kind_of?(Profile) | ||
| 54 | + owner.environment | ||
| 55 | + else | ||
| 56 | + nil | ||
| 57 | + end | ||
| 58 | + end | ||
| 59 | + | ||
| 60 | + def templates | ||
| 61 | + Community.templates(environment) | ||
| 62 | + end | ||
| 63 | + | ||
| 64 | + def is_template_counter_active? template_id | ||
| 65 | + self.templates_ids_counter[template_id.to_s].to_s == 'true' | ||
| 66 | + end | ||
| 67 | + | ||
| 68 | + def template_counter_count(template_id) | ||
| 69 | + owner.communities.visible.count(:conditions => {:template_id => template_id}) | ||
| 70 | + end | ||
| 71 | + | ||
| 72 | + def users | ||
| 73 | + if owner.kind_of?(Environment) | ||
| 74 | + owner.people.visible.count | ||
| 75 | + elsif owner.kind_of?(Organization) | ||
| 76 | + owner.members.visible.count | ||
| 77 | + elsif owner.kind_of?(Person) | ||
| 78 | + owner.friends.visible.count | ||
| 79 | + else | ||
| 80 | + 0 | ||
| 81 | + end | ||
| 82 | + end | ||
| 83 | + | ||
| 84 | + def enterprises | ||
| 85 | + if owner.kind_of?(Environment) || owner.kind_of?(Person) | ||
| 86 | + owner.enterprises.visible.count | ||
| 87 | + else | ||
| 88 | + 0 | ||
| 89 | + end | ||
| 90 | + end | ||
| 91 | + | ||
| 92 | + def communities | ||
| 93 | + if owner.kind_of?(Environment) || owner.kind_of?(Person) | ||
| 94 | + owner.communities.visible.count | ||
| 95 | + else | ||
| 96 | + 0 | ||
| 97 | + end | ||
| 98 | + end | ||
| 99 | + | ||
| 100 | + def categories | ||
| 101 | + if owner.kind_of?(Environment) then | ||
| 102 | + owner.categories.count | ||
| 103 | + else | ||
| 104 | + 0 | ||
| 105 | + end | ||
| 106 | + end | ||
| 107 | + | ||
| 108 | + def tags | ||
| 109 | + if owner.kind_of?(Environment) then | ||
| 110 | + owner.tag_counts.count | ||
| 111 | + elsif owner.kind_of?(Profile) then | ||
| 112 | + owner.article_tags.count | ||
| 113 | + else | ||
| 114 | + 0 | ||
| 115 | + end | ||
| 116 | + end | ||
| 117 | + | ||
| 118 | + def comments | ||
| 119 | + if owner.kind_of?(Environment) then | ||
| 120 | + owner.profiles.joins(:articles).sum(:comments_count).to_i | ||
| 121 | + elsif owner.kind_of?(Profile) then | ||
| 122 | + owner.articles.sum(:comments_count) | ||
| 123 | + else | ||
| 124 | + 0 | ||
| 125 | + end | ||
| 126 | + end | ||
| 127 | + | ||
| 128 | + def hits | ||
| 129 | + if owner.kind_of?(Environment) then | ||
| 130 | + owner.profiles.joins(:articles).sum(:hits).to_i | ||
| 131 | + elsif owner.kind_of?(Profile) then | ||
| 132 | + owner.articles.sum(:hits) | ||
| 133 | + else | ||
| 134 | + 0 | ||
| 135 | + end | ||
| 136 | + end | ||
| 137 | + | ||
| 138 | + def content(args={}) | ||
| 139 | + block = self | ||
| 140 | + | ||
| 141 | + lambda do | ||
| 142 | + render :file => 'statistics_block', :locals => { :block => block } | ||
| 143 | + end | ||
| 144 | + end | ||
| 145 | + | ||
| 146 | +end |
| @@ -0,0 +1,19 @@ | @@ -0,0 +1,19 @@ | ||
| 1 | +require_dependency File.dirname(__FILE__) + '/statistics_block' | ||
| 2 | + | ||
| 3 | +class StatisticsPlugin < Noosfero::Plugin | ||
| 4 | + | ||
| 5 | + def self.plugin_name | ||
| 6 | + "Statistics Plugin" | ||
| 7 | + end | ||
| 8 | + | ||
| 9 | + def self.plugin_description | ||
| 10 | + _("A plugin that adds a block where you can see statistics of it's context.") | ||
| 11 | + end | ||
| 12 | + | ||
| 13 | + def self.extra_blocks | ||
| 14 | + { | ||
| 15 | + StatisticsBlock => {} | ||
| 16 | + } | ||
| 17 | + end | ||
| 18 | + | ||
| 19 | +end |
plugins/statistics/test/functional/statistics_plugin_environment_design_controller_test.rb
0 → 100644
| @@ -0,0 +1,161 @@ | @@ -0,0 +1,161 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | + | ||
| 3 | +# Re-raise errors caught by the controller. | ||
| 4 | +class EnvironmentDesignController; def rescue_action(e) raise e end; end | ||
| 5 | + | ||
| 6 | +class EnvironmentDesignControllerTest < ActionController::TestCase | ||
| 7 | + | ||
| 8 | + def setup | ||
| 9 | + @controller = EnvironmentDesignController.new | ||
| 10 | + @request = ActionController::TestRequest.new | ||
| 11 | + @response = ActionController::TestResponse.new | ||
| 12 | + | ||
| 13 | + Environment.delete_all | ||
| 14 | + | ||
| 15 | + @environment = Environment.create(:name => 'testenv', :is_default => true) | ||
| 16 | + @environment.enabled_plugins = ['StatisticsPlugin'] | ||
| 17 | + @environment.save! | ||
| 18 | + | ||
| 19 | + user = create_user('testinguser') | ||
| 20 | + @environment.add_admin(user.person) | ||
| 21 | + | ||
| 22 | + StatisticsBlock.delete_all | ||
| 23 | + @box1 = Box.create!(:owner => @environment) | ||
| 24 | + @environment.boxes = [@box1] | ||
| 25 | + | ||
| 26 | + @block = StatisticsBlock.new | ||
| 27 | + @block.box = @box1 | ||
| 28 | + @block.save! | ||
| 29 | + | ||
| 30 | + login_as(user.login) | ||
| 31 | + end | ||
| 32 | + | ||
| 33 | + attr_accessor :block | ||
| 34 | + | ||
| 35 | + should 'be able to edit StatisticsBlock' do | ||
| 36 | + get :edit, :id => @block.id | ||
| 37 | + assert_tag :tag => 'input', :attributes => { :id => 'block_title' } | ||
| 38 | + end | ||
| 39 | + | ||
| 40 | + should 'be able to save StatisticsBlock' do | ||
| 41 | + get :edit, :id => @block.id | ||
| 42 | + post :save, :id => @block.id, :block => {:title => 'Statistics' } | ||
| 43 | + @block.reload | ||
| 44 | + assert_equal 'Statistics', @block.title | ||
| 45 | + end | ||
| 46 | + | ||
| 47 | + should 'be able to uncheck core counters' do | ||
| 48 | + @block.user_counter = true | ||
| 49 | + @block.community_counter = true | ||
| 50 | + @block.enterprise_counter = true | ||
| 51 | + @block.category_counter = true | ||
| 52 | + @block.tag_counter = true | ||
| 53 | + @block.comment_counter = true | ||
| 54 | + @block.hit_counter = true | ||
| 55 | + @block.save! | ||
| 56 | + get :edit, :id => @block.id | ||
| 57 | + post :save, :id => @block.id, :block => {:user_counter => '0', :community_counter => '0', :enterprise_counter => '0', | ||
| 58 | + :category_counter => '0', :tag_counter => '0', :comment_counter => '0', :hit_counter => '0' } | ||
| 59 | + @block.reload | ||
| 60 | + any_checked = @block.is_visible?('user_counter') || | ||
| 61 | + @block.is_visible?('community_counter') || | ||
| 62 | + @block.is_visible?('enterprise_counter') || | ||
| 63 | + @block.is_visible?('category_counter') || | ||
| 64 | + @block.is_visible?('tag_counter') || | ||
| 65 | + @block.is_visible?('comment_counter') || | ||
| 66 | + @block.is_visible?('hit_counter') | ||
| 67 | + assert_equal false, any_checked | ||
| 68 | + | ||
| 69 | + end | ||
| 70 | + | ||
| 71 | + should 'be able to check core counters' do | ||
| 72 | + @block.user_counter = false | ||
| 73 | + @block.community_counter = false | ||
| 74 | + @block.enterprise_counter = false | ||
| 75 | + @block.category_counter = false | ||
| 76 | + @block.tag_counter = false | ||
| 77 | + @block.comment_counter = false | ||
| 78 | + @block.hit_counter = false | ||
| 79 | + @block.save! | ||
| 80 | + get :edit, :id => @block.id | ||
| 81 | + post :save, :id => @block.id, :block => {:user_counter => '1', :community_counter => '1', :enterprise_counter => '1', | ||
| 82 | + :category_counter => '1', :tag_counter => '1', :comment_counter => '1', :hit_counter => '1' } | ||
| 83 | + @block.reload | ||
| 84 | + all_checked = @block.is_visible?('user_counter') && | ||
| 85 | + @block.is_visible?('community_counter') && | ||
| 86 | + @block.is_visible?('enterprise_counter') && | ||
| 87 | + @block.is_visible?('category_counter') && | ||
| 88 | + @block.is_visible?('tag_counter') && | ||
| 89 | + @block.is_visible?('comment_counter') && | ||
| 90 | + @block.is_visible?('hit_counter') | ||
| 91 | + assert all_checked | ||
| 92 | + | ||
| 93 | + end | ||
| 94 | + | ||
| 95 | + should 'be able to check template counters' do | ||
| 96 | + template = fast_create(Community, :name => 'Councils', :is_template => true, :environment_id => @environment.id) | ||
| 97 | + @block.templates_ids_counter = {template.id.to_s => 'false'} | ||
| 98 | + @block.save! | ||
| 99 | + get :edit, :id => @block.id | ||
| 100 | + post :save, :id => @block.id, :block => {:templates_ids_counter => {template.id.to_s => 'true'}} | ||
| 101 | + @block.reload | ||
| 102 | + | ||
| 103 | + assert @block.is_template_counter_active?(template.id) | ||
| 104 | + end | ||
| 105 | + | ||
| 106 | + should 'be able to uncheck template counters' do | ||
| 107 | + template = fast_create(Community, :name => 'Councils', :is_template => true, :environment_id => @environment.id) | ||
| 108 | + @block.templates_ids_counter = {template.id.to_s => 'true'} | ||
| 109 | + @block.save! | ||
| 110 | + get :edit, :id => @block.id | ||
| 111 | + post :save, :id => @block.id, :block => {:templates_ids_counter => {template.id.to_s => 'false'}} | ||
| 112 | + @block.reload | ||
| 113 | + | ||
| 114 | + assert_equal false, @block.is_template_counter_active?(template.id) | ||
| 115 | + end | ||
| 116 | + | ||
| 117 | + should 'input user counter be checked by default' do | ||
| 118 | + get :edit, :id => @block.id | ||
| 119 | + | ||
| 120 | + assert_tag :input, :attributes => {:id => 'block_user_counter', :checked => 'checked'} | ||
| 121 | + end | ||
| 122 | + | ||
| 123 | + should 'not input community counter be checked by default' do | ||
| 124 | + get :edit, :id => @block.id | ||
| 125 | + | ||
| 126 | + assert_tag :input, :attributes => {:id => 'block_community_counter'} | ||
| 127 | + assert_no_tag :input, :attributes => {:id => 'block_community_counter', :checked => 'checked'} | ||
| 128 | + end | ||
| 129 | + | ||
| 130 | + should 'not input enterprise counter be checked by default' do | ||
| 131 | + get :edit, :id => @block.id | ||
| 132 | + | ||
| 133 | + assert_tag :input, :attributes => {:id => 'block_enterprise_counter'} | ||
| 134 | + assert_no_tag :input, :attributes => {:id => 'block_enterprise_counter', :checked => 'checked'} | ||
| 135 | + end | ||
| 136 | + | ||
| 137 | + should 'not input category counter be checked by default' do | ||
| 138 | + get :edit, :id => @block.id | ||
| 139 | + | ||
| 140 | + assert_tag :input, :attributes => {:id => 'block_category_counter'} | ||
| 141 | + assert_no_tag :input, :attributes => {:id => 'block_category_counter', :checked => 'checked'} | ||
| 142 | + end | ||
| 143 | + | ||
| 144 | + should 'input tag counter be checked by default' do | ||
| 145 | + get :edit, :id => @block.id | ||
| 146 | + | ||
| 147 | + assert_tag :input, :attributes => {:id => 'block_tag_counter', :checked => 'checked'} | ||
| 148 | + end | ||
| 149 | + | ||
| 150 | + should 'input comment counter be checked by default' do | ||
| 151 | + get :edit, :id => @block.id | ||
| 152 | + | ||
| 153 | + assert_tag :input, :attributes => {:id => 'block_comment_counter', :checked => 'checked'} | ||
| 154 | + end | ||
| 155 | + | ||
| 156 | + should 'input hit counter not be checked by default' do | ||
| 157 | + get :edit, :id => @block.id | ||
| 158 | + | ||
| 159 | + assert_no_tag :input, :attributes => {:id => 'block_hit_counter', :checked => 'checked'} | ||
| 160 | + end | ||
| 161 | +end |
plugins/statistics/test/functional/statistics_plugin_home_controller_test.rb
0 → 100644
| @@ -0,0 +1,147 @@ | @@ -0,0 +1,147 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | + | ||
| 3 | +# Re-raise errors caught by the controller. | ||
| 4 | +class HomeController; def rescue_action(e) raise e end; end | ||
| 5 | + | ||
| 6 | +class HomeControllerTest < ActionController::TestCase | ||
| 7 | + | ||
| 8 | + def setup | ||
| 9 | + @controller = HomeController.new | ||
| 10 | + @request = ActionController::TestRequest.new | ||
| 11 | + @response = ActionController::TestResponse.new | ||
| 12 | + | ||
| 13 | + Environment.delete_all | ||
| 14 | + | ||
| 15 | + @environment = Environment.create(:name => 'testenv', :is_default => true) | ||
| 16 | + @environment.enabled_plugins = ['StatisticsPlugin'] | ||
| 17 | + @environment.save! | ||
| 18 | + | ||
| 19 | + user = create_user('testinguser') | ||
| 20 | + @environment.add_admin(user.person) | ||
| 21 | + | ||
| 22 | + StatisticsBlock.delete_all | ||
| 23 | + @box1 = Box.create!(:owner => @environment) | ||
| 24 | + @environment.boxes = [@box1] | ||
| 25 | + | ||
| 26 | + @block = StatisticsBlock.new | ||
| 27 | + @block.box = @box1 | ||
| 28 | + @block.save! | ||
| 29 | + | ||
| 30 | + login_as(user.login) | ||
| 31 | + end | ||
| 32 | + | ||
| 33 | + attr_accessor :block | ||
| 34 | + | ||
| 35 | + should 'display statistics-block-data class in environment block edition' do | ||
| 36 | + get :index | ||
| 37 | + | ||
| 38 | + assert_tag :div, :attributes => {:class => 'statistics-block-data'} | ||
| 39 | + end | ||
| 40 | + | ||
| 41 | + should 'display users class in statistics-block-data block' do | ||
| 42 | + get :index | ||
| 43 | + | ||
| 44 | + assert_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'users'} } | ||
| 45 | + end | ||
| 46 | + | ||
| 47 | + should 'not display users class in statistics-block-data block' do | ||
| 48 | + @block.user_counter = false | ||
| 49 | + @block.save! | ||
| 50 | + get :index | ||
| 51 | + | ||
| 52 | + assert_no_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'users'} } | ||
| 53 | + end | ||
| 54 | + | ||
| 55 | + should 'display communities class in statistics-block-data block' do | ||
| 56 | + @block.community_counter = true | ||
| 57 | + @block.save! | ||
| 58 | + get :index | ||
| 59 | + | ||
| 60 | + assert_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'communities'} } | ||
| 61 | + end | ||
| 62 | + | ||
| 63 | + should 'not display communities class in statistics-block-data block' do | ||
| 64 | + get :index | ||
| 65 | + | ||
| 66 | + assert_no_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'communities'} } | ||
| 67 | + end | ||
| 68 | + | ||
| 69 | + should 'display enterprises class in statistics-block-data block' do | ||
| 70 | + @block.enterprise_counter = true | ||
| 71 | + @block.save! | ||
| 72 | + get :index | ||
| 73 | + | ||
| 74 | + assert_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'enterprises'} } | ||
| 75 | + end | ||
| 76 | + | ||
| 77 | + should 'not display enterprises class in statistics-block-data block' do | ||
| 78 | + get :index | ||
| 79 | + | ||
| 80 | + assert_no_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'enterprises'} } | ||
| 81 | + end | ||
| 82 | + | ||
| 83 | + should 'display categories class in statistics-block-data block' do | ||
| 84 | + @block.category_counter = true | ||
| 85 | + @block.save! | ||
| 86 | + get :index | ||
| 87 | + | ||
| 88 | + assert_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'categories'} } | ||
| 89 | + end | ||
| 90 | + | ||
| 91 | + should 'not display categories class in statistics-block-data block' do | ||
| 92 | + get :index | ||
| 93 | + | ||
| 94 | + assert_no_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'categories'} } | ||
| 95 | + end | ||
| 96 | + | ||
| 97 | + should 'display tags class in statistics-block-data block' do | ||
| 98 | + get :index | ||
| 99 | + | ||
| 100 | + assert_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'tags'} } | ||
| 101 | + end | ||
| 102 | + | ||
| 103 | + should 'not display tags class in statistics-block-data block' do | ||
| 104 | + @block.tag_counter = false | ||
| 105 | + @block.save! | ||
| 106 | + get :index | ||
| 107 | + | ||
| 108 | + assert_no_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'tags'} } | ||
| 109 | + end | ||
| 110 | + | ||
| 111 | + should 'display comments class in statistics-block-data block' do | ||
| 112 | + get :index | ||
| 113 | + | ||
| 114 | + assert_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'comments'} } | ||
| 115 | + end | ||
| 116 | + | ||
| 117 | + should 'not display comments class in statistics-block-data block' do | ||
| 118 | + @block.comment_counter = false | ||
| 119 | + @block.save! | ||
| 120 | + get :index | ||
| 121 | + | ||
| 122 | + assert_no_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'comments'} } | ||
| 123 | + end | ||
| 124 | + | ||
| 125 | + should 'display hits class in statistics-block-data block' do | ||
| 126 | + @block.hit_counter = true | ||
| 127 | + @block.save! | ||
| 128 | + get :index | ||
| 129 | + | ||
| 130 | + assert_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'hits'} } | ||
| 131 | + end | ||
| 132 | + | ||
| 133 | + should 'not display hits class in statistics-block-data block' do | ||
| 134 | + get :index | ||
| 135 | + | ||
| 136 | + assert_no_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'hits'} } | ||
| 137 | + end | ||
| 138 | + | ||
| 139 | + should 'display template name in class in statistics-block-data block' do | ||
| 140 | + template = fast_create(Community, :name => 'Councils', :is_template => true, :environment_id => @environment.id) | ||
| 141 | + @block.templates_ids_counter = {template.id.to_s => 'true'} | ||
| 142 | + @block.save! | ||
| 143 | + get :index | ||
| 144 | + | ||
| 145 | + assert_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'councils'} } | ||
| 146 | + end | ||
| 147 | +end |
plugins/statistics/test/functional/statistics_plugin_profile_design_controller_test.rb
0 → 100644
| @@ -0,0 +1,85 @@ | @@ -0,0 +1,85 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | + | ||
| 3 | +# Re-raise errors caught by the controller. | ||
| 4 | +class ProfileDesignController; def rescue_action(e) raise e end; end | ||
| 5 | + | ||
| 6 | +class ProfileDesignControllerTest < ActionController::TestCase | ||
| 7 | + | ||
| 8 | + def setup | ||
| 9 | + @controller = ProfileDesignController.new | ||
| 10 | + @request = ActionController::TestRequest.new | ||
| 11 | + @response = ActionController::TestResponse.new | ||
| 12 | + | ||
| 13 | + Environment.delete_all | ||
| 14 | + | ||
| 15 | + @environment = Environment.create(:name => 'testenv', :is_default => true) | ||
| 16 | + @environment.enabled_plugins = ['StatisticsPlugin'] | ||
| 17 | + @environment.save! | ||
| 18 | + | ||
| 19 | + user = create_user('testinguser') | ||
| 20 | + @person = user.person | ||
| 21 | + @environment.add_admin(@person) | ||
| 22 | + | ||
| 23 | + StatisticsBlock.delete_all | ||
| 24 | + @box1 = Box.create!(:owner => @person) | ||
| 25 | + @environment.boxes = [@box1] | ||
| 26 | + | ||
| 27 | + @block = StatisticsBlock.new | ||
| 28 | + @block.box = @box1 | ||
| 29 | + @block.save! | ||
| 30 | + | ||
| 31 | + login_as(user.login) | ||
| 32 | + end | ||
| 33 | + | ||
| 34 | + attr_accessor :block | ||
| 35 | + | ||
| 36 | + should 'be able to edit StatisticsBlock' do | ||
| 37 | + get :edit, :id => @block.id, :profile => @person.identifier | ||
| 38 | + assert_tag :tag => 'input', :attributes => { :id => 'block_title' } | ||
| 39 | + end | ||
| 40 | + | ||
| 41 | + should 'be able to save StatisticsBlock' do | ||
| 42 | + get :edit, :id => @block.id, :profile => @person.identifier | ||
| 43 | + post :save, :id => @block.id, :block => {:title => 'Statistics' }, :profile => @person.identifier | ||
| 44 | + @block.reload | ||
| 45 | + assert_equal 'Statistics', @block.title | ||
| 46 | + end | ||
| 47 | + | ||
| 48 | + should 'be able to uncheck core counters' do | ||
| 49 | + @block.user_counter = true | ||
| 50 | + @block.tag_counter = true | ||
| 51 | + @block.comment_counter = true | ||
| 52 | + @block.hit_counter = true | ||
| 53 | + @block.save! | ||
| 54 | + get :edit, :id => @block.id, :profile => @person.identifier | ||
| 55 | + post :save, :id => @block.id, :block => {:user_counter => '0', :tag_counter => '0', :comment_counter => '0', :hit_counter => '0' }, :profile => @person.identifier | ||
| 56 | + @block.reload | ||
| 57 | + any_checked = @block.is_visible?('user_counter') || | ||
| 58 | + @block.is_visible?('tag_counter') || | ||
| 59 | + @block.is_visible?('comment_counter') || | ||
| 60 | + @block.is_visible?('hit_counter') | ||
| 61 | + assert_equal false, any_checked | ||
| 62 | + end | ||
| 63 | + | ||
| 64 | + should 'be able to check core counters' do | ||
| 65 | + @block.user_counter = false | ||
| 66 | + @block.community_counter = false | ||
| 67 | + @block.enterprise_counter = false | ||
| 68 | + @block.category_counter = false | ||
| 69 | + @block.tag_counter = false | ||
| 70 | + @block.comment_counter = false | ||
| 71 | + @block.hit_counter = false | ||
| 72 | + @block.save! | ||
| 73 | + get :edit, :id => @block.id, :profile => @person.identifier | ||
| 74 | + post :save, :id => @block.id, :block => {:user_counter => '1', | ||
| 75 | + :tag_counter => '1', :comment_counter => '1', :hit_counter => '1' }, :profile => @person.identifier | ||
| 76 | + @block.reload | ||
| 77 | + all_checked = @block.is_visible?('user_counter') && | ||
| 78 | + @block.is_visible?('tag_counter') && | ||
| 79 | + @block.is_visible?('comment_counter') && | ||
| 80 | + @block.is_visible?('hit_counter') | ||
| 81 | + assert all_checked | ||
| 82 | + | ||
| 83 | + end | ||
| 84 | + | ||
| 85 | +end |
| @@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../../../test/test_helper' |
| @@ -0,0 +1,336 @@ | @@ -0,0 +1,336 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | +class StatisticsBlockTest < ActiveSupport::TestCase | ||
| 3 | + | ||
| 4 | + ['user_counter', 'tag_counter', 'comment_counter'].map do |counter| | ||
| 5 | + should "#{counter} be true by default" do | ||
| 6 | + b = StatisticsBlock.new | ||
| 7 | + assert b.is_visible?(counter) | ||
| 8 | + end | ||
| 9 | + end | ||
| 10 | + | ||
| 11 | + ['community_counter', 'enterprise_counter', 'category_counter', 'hit_counter'].map do |counter| | ||
| 12 | + should "#{counter} be false by default" do | ||
| 13 | + b = StatisticsBlock.new | ||
| 14 | + assert !b.is_visible?(counter) | ||
| 15 | + end | ||
| 16 | + end | ||
| 17 | + | ||
| 18 | + should 'inherit from Block' do | ||
| 19 | + assert_kind_of Block, StatisticsBlock.new | ||
| 20 | + end | ||
| 21 | + | ||
| 22 | + should 'provide a default title' do | ||
| 23 | + block = StatisticsBlock.new | ||
| 24 | + | ||
| 25 | + owner = mock | ||
| 26 | + owner.expects(:name).returns('my environment') | ||
| 27 | + block.expects(:owner).returns(owner) | ||
| 28 | + assert_equal 'Statistics for my environment', block.title | ||
| 29 | + end | ||
| 30 | + | ||
| 31 | + should 'describe itself' do | ||
| 32 | + assert_not_equal StatisticsBlock.description, Block.description | ||
| 33 | + end | ||
| 34 | + | ||
| 35 | + should 'is_visible? return true if setting is true' do | ||
| 36 | + b = StatisticsBlock.new | ||
| 37 | + b.community_counter = true | ||
| 38 | + assert b.is_visible?('community_counter') | ||
| 39 | + end | ||
| 40 | + | ||
| 41 | + should 'is_visible? return false if setting is false' do | ||
| 42 | + b = StatisticsBlock.new | ||
| 43 | + b.community_counter = false | ||
| 44 | + assert !b.is_visible?('community_counter') | ||
| 45 | + end | ||
| 46 | + | ||
| 47 | + should 'templates return the Community templates of the Environment' do | ||
| 48 | + b = StatisticsBlock.new | ||
| 49 | + e = fast_create(Environment) | ||
| 50 | + | ||
| 51 | + t1 = fast_create(Community, :is_template => true, :environment_id => e.id) | ||
| 52 | + t2 = fast_create(Community, :is_template => true, :environment_id => e.id) | ||
| 53 | + fast_create(Community, :is_template => false) | ||
| 54 | + | ||
| 55 | + b.expects(:owner).at_least_once.returns(e) | ||
| 56 | + | ||
| 57 | + t = b.templates | ||
| 58 | + assert_equal [], [t1,t2] - t | ||
| 59 | + assert_equal [], t - [t1,t2] | ||
| 60 | + end | ||
| 61 | + | ||
| 62 | + should 'users return the amount of users of the Environment' do | ||
| 63 | + b = StatisticsBlock.new | ||
| 64 | + e = fast_create(Environment) | ||
| 65 | + | ||
| 66 | + fast_create(Person, :environment_id => e.id) | ||
| 67 | + fast_create(Person, :environment_id => e.id) | ||
| 68 | + fast_create(Person, :visible => false, :environment_id => e.id) | ||
| 69 | + | ||
| 70 | + b.expects(:owner).at_least_once.returns(e) | ||
| 71 | + | ||
| 72 | + assert_equal 2, b.users | ||
| 73 | + end | ||
| 74 | + | ||
| 75 | + should 'users return the amount of members of the community' do | ||
| 76 | + b = StatisticsBlock.new | ||
| 77 | + | ||
| 78 | + c1 = fast_create(Community) | ||
| 79 | + c1.add_member(fast_create(Person)) | ||
| 80 | + c1.add_member(fast_create(Person)) | ||
| 81 | + c1.add_member(fast_create(Person)) | ||
| 82 | + c1.add_member(fast_create(Person, :visible => false)) | ||
| 83 | + c1.add_member(fast_create(Person, :visible => false)) | ||
| 84 | + | ||
| 85 | + b.expects(:owner).at_least_once.returns(c1) | ||
| 86 | + assert_equal 3, b.users | ||
| 87 | + end | ||
| 88 | + | ||
| 89 | + should 'users return the amount of friends of the person' do | ||
| 90 | + b = StatisticsBlock.new | ||
| 91 | + | ||
| 92 | + p1 = fast_create(Person) | ||
| 93 | + p1.add_friend(fast_create(Person)) | ||
| 94 | + p1.add_friend(fast_create(Person)) | ||
| 95 | + p1.add_friend(fast_create(Person)) | ||
| 96 | + p1.add_friend(fast_create(Person, :visible => false)) | ||
| 97 | + p1.add_friend(fast_create(Person, :visible => false)) | ||
| 98 | + | ||
| 99 | + b.expects(:owner).at_least_once.returns(p1) | ||
| 100 | + assert_equal 3, b.users | ||
| 101 | + end | ||
| 102 | + | ||
| 103 | + should 'communities return the amount of communities of the Environment' do | ||
| 104 | + b = StatisticsBlock.new | ||
| 105 | + e = fast_create(Environment) | ||
| 106 | + | ||
| 107 | + fast_create(Community, :environment_id => e.id) | ||
| 108 | + fast_create(Community, :environment_id => e.id) | ||
| 109 | + fast_create(Community, :visible => false, :environment_id => e.id) | ||
| 110 | + | ||
| 111 | + b.expects(:owner).at_least_once.returns(e) | ||
| 112 | + | ||
| 113 | + assert_equal 2, b.communities | ||
| 114 | + end | ||
| 115 | + | ||
| 116 | + should 'enterprises return the amount of enterprises of the Environment' do | ||
| 117 | + b = StatisticsBlock.new | ||
| 118 | + e = fast_create(Environment) | ||
| 119 | + | ||
| 120 | + fast_create(Enterprise, :environment_id => e.id) | ||
| 121 | + fast_create(Enterprise, :environment_id => e.id) | ||
| 122 | + fast_create(Enterprise, :visible => false, :environment_id => e.id) | ||
| 123 | + | ||
| 124 | + b.expects(:owner).at_least_once.returns(e) | ||
| 125 | + | ||
| 126 | + assert_equal 2, b.enterprises | ||
| 127 | + end | ||
| 128 | + | ||
| 129 | + should 'categories return the amount of categories of the Environment' do | ||
| 130 | + b = StatisticsBlock.new | ||
| 131 | + e = fast_create(Environment) | ||
| 132 | + | ||
| 133 | + fast_create(Category, :environment_id => e.id) | ||
| 134 | + fast_create(Category, :environment_id => e.id) | ||
| 135 | + | ||
| 136 | + b.expects(:owner).at_least_once.returns(e) | ||
| 137 | + | ||
| 138 | + assert_equal 2, b.categories | ||
| 139 | + end | ||
| 140 | + | ||
| 141 | + should 'tags return the amount of tags of the Environment' do | ||
| 142 | + b = StatisticsBlock.new | ||
| 143 | + e = fast_create(Environment) | ||
| 144 | + | ||
| 145 | + p1 = fast_create(Person, :environment_id => e.id) | ||
| 146 | + a1 = fast_create(Article, :profile_id => p1.id) | ||
| 147 | + t1 = fast_create(Tag, :name => 'T1') | ||
| 148 | + t2 = fast_create(Tag, :name => 'T2') | ||
| 149 | + a1.tags << t1 | ||
| 150 | + a1.tags << t2 | ||
| 151 | + a2 = fast_create(Article, :profile_id => p1.id) | ||
| 152 | + t3 = fast_create(Tag, :name => 'T3') | ||
| 153 | + t4 = fast_create(Tag, :name => 'T4') | ||
| 154 | + a2.tags << t3 | ||
| 155 | + a2.tags << t4 | ||
| 156 | + | ||
| 157 | + b.expects(:owner).at_least_once.returns(e) | ||
| 158 | + | ||
| 159 | + assert_equal 4, b.tags | ||
| 160 | + end | ||
| 161 | + | ||
| 162 | + should 'tags return the amount of tags of the community' do | ||
| 163 | + b = StatisticsBlock.new | ||
| 164 | + e = fast_create(Environment) | ||
| 165 | + | ||
| 166 | + c1 = fast_create(Community, :environment_id => e.id) | ||
| 167 | + a1 = fast_create(Article, :profile_id => c1.id) | ||
| 168 | + t1 = fast_create(Tag, :name => 'T1') | ||
| 169 | + t2 = fast_create(Tag, :name => 'T2') | ||
| 170 | + a1.tags << t1 | ||
| 171 | + a1.tags << t2 | ||
| 172 | + a2 = fast_create(Article, :profile_id => c1.id) | ||
| 173 | + t3 = fast_create(Tag, :name => 'T3') | ||
| 174 | + t4 = fast_create(Tag, :name => 'T4') | ||
| 175 | + a2.tags << t3 | ||
| 176 | + a2.tags << t4 | ||
| 177 | + | ||
| 178 | + b.expects(:owner).at_least_once.returns(c1) | ||
| 179 | + | ||
| 180 | + assert_equal 4, b.tags | ||
| 181 | + end | ||
| 182 | + | ||
| 183 | + should 'tags return the amount of tags of the profile (person)' do | ||
| 184 | + b = StatisticsBlock.new | ||
| 185 | + e = fast_create(Environment) | ||
| 186 | + | ||
| 187 | + p1 = fast_create(Person, :environment_id => e.id) | ||
| 188 | + a1 = fast_create(Article, :profile_id => p1.id) | ||
| 189 | + t1 = fast_create(Tag, :name => 'T1') | ||
| 190 | + t2 = fast_create(Tag, :name => 'T2') | ||
| 191 | + a1.tags << t1 | ||
| 192 | + a1.tags << t2 | ||
| 193 | + a2 = fast_create(Article, :profile_id => p1.id) | ||
| 194 | + t3 = fast_create(Tag, :name => 'T3') | ||
| 195 | + t4 = fast_create(Tag, :name => 'T4') | ||
| 196 | + a2.tags << t3 | ||
| 197 | + a2.tags << t4 | ||
| 198 | + | ||
| 199 | + b.expects(:owner).at_least_once.returns(p1) | ||
| 200 | + | ||
| 201 | + assert_equal 4, b.tags | ||
| 202 | + end | ||
| 203 | + | ||
| 204 | + should 'comments return the amount of comments of the Environment' do | ||
| 205 | + b = StatisticsBlock.new | ||
| 206 | + e = fast_create(Environment) | ||
| 207 | + | ||
| 208 | + p1 = fast_create(Person, :environment_id => e.id) | ||
| 209 | + a1 = fast_create(Article, :profile_id => p1.id) | ||
| 210 | + | ||
| 211 | + Comment.create!(:source => a1, :body => 'C1', :author_id => 1) | ||
| 212 | + Comment.create!(:source => a1, :body => 'C2', :author_id => 1) | ||
| 213 | + | ||
| 214 | + a2 = fast_create(Article, :profile_id => p1.id) | ||
| 215 | + Comment.create!(:source => a2, :body => 'C3', :author_id => 1) | ||
| 216 | + Comment.create!(:source => a2, :body => 'C4', :author_id => 1) | ||
| 217 | + | ||
| 218 | + b.expects(:owner).at_least_once.returns(e) | ||
| 219 | + | ||
| 220 | + assert_equal 4, b.comments | ||
| 221 | + end | ||
| 222 | + | ||
| 223 | + should 'comments return the amount of comments of the community' do | ||
| 224 | + b = StatisticsBlock.new | ||
| 225 | + e = Environment.default | ||
| 226 | + | ||
| 227 | + c1 = fast_create(Community, :environment_id => e.id) | ||
| 228 | + a1 = fast_create(Article, :profile_id => c1.id) | ||
| 229 | + Comment.create!(:source => a1, :body => 'C1', :author_id => 1) | ||
| 230 | + Comment.create!(:source => a1, :body => 'C2', :author_id => 1) | ||
| 231 | + | ||
| 232 | + a2 = fast_create(Article, :profile_id => c1.id) | ||
| 233 | + Comment.create!(:source => a2, :body => 'C3', :author_id => 1) | ||
| 234 | + Comment.create!(:source => a2, :body => 'C4', :author_id => 1) | ||
| 235 | + | ||
| 236 | + b.expects(:owner).at_least_once.returns(c1) | ||
| 237 | + | ||
| 238 | + assert_equal 4, b.comments | ||
| 239 | + end | ||
| 240 | + | ||
| 241 | + should 'comments return the amount of comments of the profile (person)' do | ||
| 242 | + b = StatisticsBlock.new | ||
| 243 | + e = fast_create(Environment) | ||
| 244 | + | ||
| 245 | + p1 = fast_create(Person, :environment_id => e.id) | ||
| 246 | + a1 = fast_create(Article, :profile_id => p1.id) | ||
| 247 | + Comment.create!(:source => a1, :body => 'C1', :author_id => 1) | ||
| 248 | + Comment.create!(:source => a1, :body => 'C2', :author_id => 1) | ||
| 249 | + | ||
| 250 | + a2 = fast_create(Article, :profile_id => p1.id) | ||
| 251 | + Comment.create!(:source => a1, :body => 'C3', :author_id => 1) | ||
| 252 | + Comment.create!(:source => a1, :body => 'C4', :author_id => 1) | ||
| 253 | + | ||
| 254 | + b.expects(:owner).at_least_once.returns(p1) | ||
| 255 | + | ||
| 256 | + assert_equal 4, b.comments | ||
| 257 | + end | ||
| 258 | + | ||
| 259 | + should 'hits return the amount of hits of the Environment' do | ||
| 260 | + b = StatisticsBlock.new | ||
| 261 | + e = fast_create(Environment) | ||
| 262 | + | ||
| 263 | + p1 = fast_create(Person, :environment_id => e.id) | ||
| 264 | + a1 = fast_create(Article, :profile_id => p1.id, :hits => 2) | ||
| 265 | + a2 = fast_create(Article, :profile_id => p1.id, :hits => 5) | ||
| 266 | + | ||
| 267 | + b.expects(:owner).at_least_once.returns(e) | ||
| 268 | + | ||
| 269 | + assert_equal 7, b.hits | ||
| 270 | + end | ||
| 271 | + | ||
| 272 | + should 'hits return the amount of hits of the community' do | ||
| 273 | + b = StatisticsBlock.new | ||
| 274 | + e = fast_create(Environment) | ||
| 275 | + | ||
| 276 | + c1 = fast_create(Community, :environment_id => e.id) | ||
| 277 | + a1 = fast_create(Article, :profile_id => c1.id, :hits => 2) | ||
| 278 | + a2 = fast_create(Article, :profile_id => c1.id, :hits => 5) | ||
| 279 | + | ||
| 280 | + b.expects(:owner).at_least_once.returns(c1) | ||
| 281 | + | ||
| 282 | + assert_equal 7, b.hits | ||
| 283 | + end | ||
| 284 | + | ||
| 285 | + should 'hits return the amount of hits of the profile (person)' do | ||
| 286 | + b = StatisticsBlock.new | ||
| 287 | + e = fast_create(Environment) | ||
| 288 | + | ||
| 289 | + p1 = fast_create(Person, :environment_id => e.id) | ||
| 290 | + a1 = fast_create(Article, :profile_id => p1.id, :hits => 2) | ||
| 291 | + a2 = fast_create(Article, :profile_id => p1.id, :hits => 5) | ||
| 292 | + | ||
| 293 | + b.expects(:owner).at_least_once.returns(p1) | ||
| 294 | + | ||
| 295 | + assert_equal 7, b.hits | ||
| 296 | + end | ||
| 297 | + | ||
| 298 | + should 'is_counter_available? return true for all counters if owner is environment' do | ||
| 299 | + b = StatisticsBlock.new | ||
| 300 | + e = fast_create(Environment) | ||
| 301 | + | ||
| 302 | + b.expects(:owner).at_least_once.returns(e) | ||
| 303 | + | ||
| 304 | + assert b.is_counter_available?(:user_counter) | ||
| 305 | + end | ||
| 306 | + | ||
| 307 | + should 'is_template_counter_active? return true if setting is true' do | ||
| 308 | + b = StatisticsBlock.new | ||
| 309 | + b.templates_ids_counter = {'1' => 'true'} | ||
| 310 | + assert b.is_template_counter_active?(1) | ||
| 311 | + end | ||
| 312 | + | ||
| 313 | + should 'is_template_counter_active? return false if setting is false' do | ||
| 314 | + b = StatisticsBlock.new | ||
| 315 | + b.templates_ids_counter = {'1' => 'false'} | ||
| 316 | + assert !b.is_template_counter_active?(1) | ||
| 317 | + end | ||
| 318 | + | ||
| 319 | + should 'template_counter_count return the amount of communities of the Environment using a template' do | ||
| 320 | + b = StatisticsBlock.new | ||
| 321 | + e = fast_create(Environment) | ||
| 322 | + | ||
| 323 | + t1 = fast_create(Community, :is_template => true, :environment_id => e.id) | ||
| 324 | + t2 = fast_create(Community, :is_template => true, :environment_id => e.id) | ||
| 325 | + fast_create(Community, :is_template => false, :environment_id => e.id, :template_id => t1.id, :visible => true) | ||
| 326 | + fast_create(Community, :is_template => false, :environment_id => e.id, :template_id => t1.id, :visible => true) | ||
| 327 | + fast_create(Community, :is_template => false, :environment_id => e.id, :template_id => t1.id, :visible => false) | ||
| 328 | + | ||
| 329 | + fast_create(Community, :is_template => false, :environment_id => e.id, :template_id => t2.id, :visible => true) | ||
| 330 | + fast_create(Community, :is_template => false, :environment_id => e.id, :template_id => t2.id, :visible => false) | ||
| 331 | + | ||
| 332 | + b.expects(:owner).at_least_once.returns(e) | ||
| 333 | + | ||
| 334 | + assert_equal 2, b.template_counter_count(t1.id) | ||
| 335 | + end | ||
| 336 | +end |
| @@ -0,0 +1,9 @@ | @@ -0,0 +1,9 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | + | ||
| 3 | +class StatisticsPluginTest < ActiveSupport::TestCase | ||
| 4 | + | ||
| 5 | + should "return StatisticsBlock in extra_mlocks class method" do | ||
| 6 | + assert StatisticsPlugin.extra_blocks.keys.include?(StatisticsBlock) | ||
| 7 | + end | ||
| 8 | + | ||
| 9 | +end |
plugins/statistics/views/box_organizer/_statistics_block.rhtml
0 → 100644
| @@ -0,0 +1,32 @@ | @@ -0,0 +1,32 @@ | ||
| 1 | +<%= labelled_form_field check_box(:block, :user_counter) + _('Show user counter'), '' %> | ||
| 2 | + | ||
| 3 | +<% if @block.is_counter_available?(:community_counter) %> | ||
| 4 | +<%= labelled_form_field check_box(:block, :community_counter) + _('Show community counter'), '' %> | ||
| 5 | +<% end %> | ||
| 6 | + | ||
| 7 | +<% if @block.is_counter_available?(:enterprise_counter) %> | ||
| 8 | +<%= labelled_form_field check_box(:block, :enterprise_counter) + _('Show enterprise counter'), '' %> | ||
| 9 | +<% end %> | ||
| 10 | + | ||
| 11 | +<% if @block.is_counter_available?(:category_counter) %> | ||
| 12 | +<%= labelled_form_field check_box(:block, :category_counter) + _('Show category counter'), '' %> | ||
| 13 | +<% end %> | ||
| 14 | + | ||
| 15 | +<% if @block.is_counter_available?(:tag_counter) %> | ||
| 16 | +<%= labelled_form_field check_box(:block, :tag_counter) + _('Show tag counter'), '' %> | ||
| 17 | +<% end %> | ||
| 18 | + | ||
| 19 | +<% if @block.is_counter_available?(:comment_counter) %> | ||
| 20 | +<%= labelled_form_field check_box(:block, :comment_counter) + _('Show comment counter'), '' %> | ||
| 21 | +<% end %> | ||
| 22 | + | ||
| 23 | +<% if @block.is_counter_available?(:hit_counter) %> | ||
| 24 | +<%= labelled_form_field check_box(:block, :hit_counter) + _('Show hit counter'), '' %> | ||
| 25 | +<% end %> | ||
| 26 | + | ||
| 27 | +<% if @block.is_counter_available?(:templates_ids_counter) %> | ||
| 28 | +<% @block.templates.map do |item|%> | ||
| 29 | + <%= hidden_field_tag("block[templates_ids_counter][#{item.id}]", false)%> | ||
| 30 | + <%= labelled_form_field check_box_tag("block[templates_ids_counter][#{item.id}]", true, @block.is_template_counter_active?(item.id)) + _("Show counter for communities with template %s" % item.name), '' %> | ||
| 31 | +<% end %> | ||
| 32 | +<% end %> |
| @@ -0,0 +1,36 @@ | @@ -0,0 +1,36 @@ | ||
| 1 | +<h3 class="block-title"> | ||
| 2 | + <span><%=block.title%></span> | ||
| 3 | +</h3> | ||
| 4 | +<div class="statistics-block-data"> | ||
| 5 | + <ul> | ||
| 6 | + <% if block.is_visible?('user_counter') %> | ||
| 7 | + <li class="users"><span class="amount"><%= block.users%> </span><span class="label"><%= _('users')%></span></li> | ||
| 8 | + <% end %> | ||
| 9 | + <% if block.is_visible?('enterprise_counter') && !block.environment.enabled?('disable_asset_enterprises') %> | ||
| 10 | + <li class="enterprises"><span class="amount"><%= block.enterprises%> </span><span class="label"><%= _('enterprises')%></span></li> | ||
| 11 | + <% end %> | ||
| 12 | + <% if block.is_visible?('community_counter') %> | ||
| 13 | + <li class="communities"><span class="amount"><%= block.communities%> </span><span class="label"><%= _('communities')%></span></li> | ||
| 14 | + <% end %> | ||
| 15 | + <% if block.is_visible?('category_counter') %> | ||
| 16 | + <li class="categories"><span class="amount"><%= block.categories%> </span><span class="label"><%= _('categories')%></span></li> | ||
| 17 | + <% end %> | ||
| 18 | + <% if block.is_visible?('tag_counter') %> | ||
| 19 | + <li class="tags"><span class="amount"><%= block.tags%> </span><span class="label"><%= _('tags')%></span></li> | ||
| 20 | + <% end %> | ||
| 21 | + <% if block.is_visible?('comment_counter') %> | ||
| 22 | + <li class="comments"><span class="amount"><%= block.comments%> </span><span class="label"><%= _('comments')%></span></li> | ||
| 23 | + <% end %> | ||
| 24 | + <% if block.is_visible?('hit_counter') %> | ||
| 25 | + <li class="hits"><span class="amount"><%= block.hits%> </span><span class="label"><%= _('hits')%></span></li> | ||
| 26 | + <% end %> | ||
| 27 | + | ||
| 28 | + <% if block.owner.kind_of?(Environment) then %> | ||
| 29 | + <% block.templates.each do |item| %> | ||
| 30 | + <% if block.is_template_counter_active? item.id %> | ||
| 31 | + <li class="<%= item.name.to_slug%>"><span class="amount"><%= block.template_counter_count(item.id)%> </span><span class="label"><%= item.name%></span></li> | ||
| 32 | + <% end %> | ||
| 33 | + <% end %> | ||
| 34 | + <% end %> | ||
| 35 | + </ul> | ||
| 36 | +</div> |
plugins/tolerance_time/lib/tolerance_time_plugin/publication.rb
| @@ -5,8 +5,7 @@ class ToleranceTimePlugin::Publication < Noosfero::Plugin::ActiveRecord | @@ -5,8 +5,7 @@ class ToleranceTimePlugin::Publication < Noosfero::Plugin::ActiveRecord | ||
| 5 | 5 | ||
| 6 | class << self | 6 | class << self |
| 7 | def find_by_target(target) | 7 | def find_by_target(target) |
| 8 | - kind = target.kind_of?(Article) ? 'Article' : 'Comment' | ||
| 9 | - find_by_target_id_and_target_type(target.id, kind) | 8 | + find_by_target_id_and_target_type(target.id, target.class.base_class.name) |
| 10 | end | 9 | end |
| 11 | end | 10 | end |
| 12 | 11 |
| @@ -0,0 +1,39 @@ | @@ -0,0 +1,39 @@ | ||
| 1 | +h1. Variables Plugin | ||
| 2 | + | ||
| 3 | +A set of simple variables to be used in a macro context. | ||
| 4 | + | ||
| 5 | +h2. Usage | ||
| 6 | + | ||
| 7 | +* Create a HTML content using RawHTMLBlock, TinyMceArticle or other | ||
| 8 | + article with HTML support | ||
| 9 | +* Add a HTML div tag with css class "macro" (see Example) | ||
| 10 | +* Add inner that div tag the variable desired, like {profile} | ||
| 11 | + | ||
| 12 | +h2. Usage with TinyMceArticle | ||
| 13 | + | ||
| 14 | +The Noosfero's macros add a extra button in toolbar of the editor | ||
| 15 | +to use macros in a single way, that way this plugin add a option | ||
| 16 | +called "Variables" under this option. | ||
| 17 | + | ||
| 18 | +h2. Supported variables | ||
| 19 | + | ||
| 20 | +* {profile} - will be replaced by the identifier of the profile | ||
| 21 | +* {name} - will be replaced by the name of the profile | ||
| 22 | + | ||
| 23 | +h2. Example | ||
| 24 | + | ||
| 25 | +<pre> | ||
| 26 | +<div class="macro" data-macro="variables_plugin/profile"> | ||
| 27 | + the identifier of the profile = {profile} | ||
| 28 | + the name of the profile = {name} | ||
| 29 | +</div> | ||
| 30 | +</pre> | ||
| 31 | + | ||
| 32 | +h2. Info | ||
| 33 | + | ||
| 34 | +This plugin was inspired by the solution proposed by the Serpro in | ||
| 35 | +the merge-request #419 on the Gitorious: | ||
| 36 | + | ||
| 37 | +* https://gitorious.org/noosfero/noosfero/merge_requests/419 | ||
| 38 | + | ||
| 39 | +And improved by the guys from the UnB. |
| @@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
| 1 | +class VariablesPlugin < Noosfero::Plugin | ||
| 2 | + | ||
| 3 | + def self.plugin_name | ||
| 4 | + "Variables Plugin" | ||
| 5 | + end | ||
| 6 | + | ||
| 7 | + def self.plugin_description | ||
| 8 | + _("A set of simple variables to be used in a macro context") | ||
| 9 | + end | ||
| 10 | + | ||
| 11 | +end | ||
| 12 | + | ||
| 13 | +require_dependency 'variables_plugin/macros/profile' |
plugins/variables/lib/variables_plugin/macros/profile.rb
0 → 100644
| @@ -0,0 +1,37 @@ | @@ -0,0 +1,37 @@ | ||
| 1 | +ActionView::Base.sanitized_allowed_attributes += ['data-macro'] | ||
| 2 | + | ||
| 3 | +class VariablesPlugin::Profile < Noosfero::Plugin::Macro | ||
| 4 | + | ||
| 5 | + def self.configuration | ||
| 6 | + { | ||
| 7 | + :title => _('Variables'), | ||
| 8 | + :skip_dialog => false, | ||
| 9 | + :generator => method(:macro_default_generator), | ||
| 10 | + :params => [ | ||
| 11 | + { | ||
| 12 | + :name => 'variable', | ||
| 13 | + :label => _('Select the desired variable'), | ||
| 14 | + :type => 'select', | ||
| 15 | + :values => ['{profile}', '{name}'] | ||
| 16 | + } | ||
| 17 | + ], | ||
| 18 | + } | ||
| 19 | + end | ||
| 20 | + | ||
| 21 | + def self.macro_default_generator(macro) | ||
| 22 | + " | ||
| 23 | + '<div class=\"macro mceNonEditable\" data-macro=\"#{macro.identifier}\">' | ||
| 24 | + + jQuery('*[name=variable]', dialog).val() | ||
| 25 | + + '</div>'; | ||
| 26 | + " | ||
| 27 | + end | ||
| 28 | + | ||
| 29 | + def parse(params, inner_html, source) | ||
| 30 | + if context.profile | ||
| 31 | + inner_html.gsub!(/\{profile\}/, context.profile.identifier) | ||
| 32 | + inner_html.gsub!(/\{name\}/, context.profile.name) | ||
| 33 | + end | ||
| 34 | + inner_html | ||
| 35 | + end | ||
| 36 | + | ||
| 37 | +end |
| @@ -0,0 +1,41 @@ | @@ -0,0 +1,41 @@ | ||
| 1 | +class ProfileTest < ActiveSupport::TestCase | ||
| 2 | + | ||
| 3 | + def setup | ||
| 4 | + @macro = VariablesPlugin::Profile.new | ||
| 5 | + @macro.context = mock() | ||
| 6 | + @profile = fast_create(Community) | ||
| 7 | + @macro.context.stubs(:profile).returns(@profile) | ||
| 8 | + end | ||
| 9 | + | ||
| 10 | + attr_reader :macro, :profile | ||
| 11 | + | ||
| 12 | + should 'have a configuration' do | ||
| 13 | + assert VariablesPlugin::Profile.configuration | ||
| 14 | + end | ||
| 15 | + | ||
| 16 | + should 'substitute the {profile} variable by the profile idenfifier' do | ||
| 17 | + html = 'the profile identifier is {profile}' | ||
| 18 | + content = macro.parse({}, html, profile) | ||
| 19 | + assert_equal "the profile identifier is #{profile.identifier}", content | ||
| 20 | + end | ||
| 21 | + | ||
| 22 | + should 'substitute the {name} variable by the profile name' do | ||
| 23 | + html = 'the profile name is {name}' | ||
| 24 | + content = macro.parse({}, html, profile) | ||
| 25 | + assert_equal "the profile name is #{profile.name}", content | ||
| 26 | + end | ||
| 27 | + | ||
| 28 | + should 'do not change the content if the variable is not supported' do | ||
| 29 | + html = 'the variable {unsupported} is not supported' | ||
| 30 | + content = macro.parse({}, html, profile) | ||
| 31 | + assert_equal html, content | ||
| 32 | + end | ||
| 33 | + | ||
| 34 | + should 'do nothing out of profile context' do | ||
| 35 | + macro.context.stubs(:profile).returns(nil) | ||
| 36 | + html = 'there is no {support} out of profile context' | ||
| 37 | + content = macro.parse({}, html, profile) | ||
| 38 | + assert_equal html, content | ||
| 39 | + end | ||
| 40 | + | ||
| 41 | +end |
| @@ -0,0 +1,20 @@ | @@ -0,0 +1,20 @@ | ||
| 1 | +require 'test_helper' | ||
| 2 | + | ||
| 3 | +class VariablesPluginTest < ActiveSupport::TestCase | ||
| 4 | + | ||
| 5 | + def setup | ||
| 6 | + @environment = Environment.default | ||
| 7 | + @plugin = VariablesPlugin.new | ||
| 8 | + end | ||
| 9 | + | ||
| 10 | + attr_reader :environment, :plugin | ||
| 11 | + | ||
| 12 | + should 'have a name' do | ||
| 13 | + assert_not_equal Noosfero::Plugin.plugin_name, VariablesPlugin::plugin_name | ||
| 14 | + end | ||
| 15 | + | ||
| 16 | + should 'describe yourself' do | ||
| 17 | + assert_not_equal Noosfero::Plugin.plugin_description, VariablesPlugin::plugin_description | ||
| 18 | + end | ||
| 19 | + | ||
| 20 | +end |
po/eo/noosfero.po
| @@ -7,7 +7,7 @@ msgid "" | @@ -7,7 +7,7 @@ msgid "" | ||
| 7 | msgstr "" | 7 | msgstr "" |
| 8 | "Project-Id-Version: noosfero 0.45.2\n" | 8 | "Project-Id-Version: noosfero 0.45.2\n" |
| 9 | "POT-Creation-Date: 2014-01-17 18:26-0000\n" | 9 | "POT-Creation-Date: 2014-01-17 18:26-0000\n" |
| 10 | -"PO-Revision-Date: 2011-03-30 20:52-0300\n" | 10 | +"PO-Revision-Date: 2014-03-25 15:35+0000\n" |
| 11 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | 11 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
| 12 | "Language-Team: LANGUAGE <LL@li.org>\n" | 12 | "Language-Team: LANGUAGE <LL@li.org>\n" |
| 13 | "Language: eo\n" | 13 | "Language: eo\n" |
| @@ -107,7 +107,7 @@ msgstr "" | @@ -107,7 +107,7 @@ msgstr "" | ||
| 107 | #: app/views/blocks/profile_info_actions/_join_leave_community.rhtml:25 | 107 | #: app/views/blocks/profile_info_actions/_join_leave_community.rhtml:25 |
| 108 | #: app/views/profile/_private_profile.rhtml:10 | 108 | #: app/views/profile/_private_profile.rhtml:10 |
| 109 | msgid "Join" | 109 | msgid "Join" |
| 110 | -msgstr "" | 110 | +msgstr "Eniri" |
| 111 | 111 | ||
| 112 | #: app/helpers/application_helper.rb:554 | 112 | #: app/helpers/application_helper.rb:554 |
| 113 | #: app/views/blocks/profile_info_actions/_join_leave_community.rhtml:4 | 113 | #: app/views/blocks/profile_info_actions/_join_leave_community.rhtml:4 |
| @@ -291,7 +291,7 @@ msgstr "" | @@ -291,7 +291,7 @@ msgstr "" | ||
| 291 | 291 | ||
| 292 | #: app/helpers/application_helper.rb:1118 | 292 | #: app/helpers/application_helper.rb:1118 |
| 293 | msgid "See all" | 293 | msgid "See all" |
| 294 | -msgstr "" | 294 | +msgstr "Vidi ĉiujn" |
| 295 | 295 | ||
| 296 | #: app/helpers/application_helper.rb:1121 | 296 | #: app/helpers/application_helper.rb:1121 |
| 297 | msgid "<span>Manage</span> %s" | 297 | msgid "<span>Manage</span> %s" |
| @@ -678,11 +678,11 @@ msgstr "" | @@ -678,11 +678,11 @@ msgstr "" | ||
| 678 | 678 | ||
| 679 | #: app/helpers/forum_helper.rb:14 app/helpers/blog_helper.rb:23 | 679 | #: app/helpers/forum_helper.rb:14 app/helpers/blog_helper.rb:23 |
| 680 | msgid "« Newer posts" | 680 | msgid "« Newer posts" |
| 681 | -msgstr "" | 681 | +msgstr "« Pli freŝaj afiŝoj" |
| 682 | 682 | ||
| 683 | #: app/helpers/forum_helper.rb:15 app/helpers/blog_helper.rb:24 | 683 | #: app/helpers/forum_helper.rb:15 app/helpers/blog_helper.rb:24 |
| 684 | msgid "Older posts »" | 684 | msgid "Older posts »" |
| 685 | -msgstr "" | 685 | +msgstr "Malpli freŝaj afiŝoj »" |
| 686 | 686 | ||
| 687 | #: app/helpers/forum_helper.rb:18 | 687 | #: app/helpers/forum_helper.rb:18 |
| 688 | msgid "Discussion topic" | 688 | msgid "Discussion topic" |
| @@ -763,63 +763,63 @@ msgstr "" | @@ -763,63 +763,63 @@ msgstr "" | ||
| 763 | #: app/helpers/dates_helper.rb:7 app/helpers/forms_helper.rb:172 | 763 | #: app/helpers/dates_helper.rb:7 app/helpers/forms_helper.rb:172 |
| 764 | #: plugins/display_content/lib/display_content_block.rb:4 | 764 | #: plugins/display_content/lib/display_content_block.rb:4 |
| 765 | msgid "January" | 765 | msgid "January" |
| 766 | -msgstr "" | 766 | +msgstr "Januaro" |
| 767 | 767 | ||
| 768 | #: app/helpers/dates_helper.rb:8 app/helpers/forms_helper.rb:172 | 768 | #: app/helpers/dates_helper.rb:8 app/helpers/forms_helper.rb:172 |
| 769 | #: plugins/display_content/lib/display_content_block.rb:5 | 769 | #: plugins/display_content/lib/display_content_block.rb:5 |
| 770 | msgid "February" | 770 | msgid "February" |
| 771 | -msgstr "" | 771 | +msgstr "Februaro" |
| 772 | 772 | ||
| 773 | #: app/helpers/dates_helper.rb:9 app/helpers/forms_helper.rb:172 | 773 | #: app/helpers/dates_helper.rb:9 app/helpers/forms_helper.rb:172 |
| 774 | #: plugins/display_content/lib/display_content_block.rb:6 | 774 | #: plugins/display_content/lib/display_content_block.rb:6 |
| 775 | msgid "March" | 775 | msgid "March" |
| 776 | -msgstr "" | 776 | +msgstr "Marto" |
| 777 | 777 | ||
| 778 | #: app/helpers/dates_helper.rb:10 app/helpers/forms_helper.rb:172 | 778 | #: app/helpers/dates_helper.rb:10 app/helpers/forms_helper.rb:172 |
| 779 | #: plugins/display_content/lib/display_content_block.rb:7 | 779 | #: plugins/display_content/lib/display_content_block.rb:7 |
| 780 | msgid "April" | 780 | msgid "April" |
| 781 | -msgstr "" | 781 | +msgstr "Aprilo" |
| 782 | 782 | ||
| 783 | #: app/helpers/dates_helper.rb:11 app/helpers/forms_helper.rb:172 | 783 | #: app/helpers/dates_helper.rb:11 app/helpers/forms_helper.rb:172 |
| 784 | #: app/helpers/forms_helper.rb:173 | 784 | #: app/helpers/forms_helper.rb:173 |
| 785 | #: plugins/display_content/lib/display_content_block.rb:8 | 785 | #: plugins/display_content/lib/display_content_block.rb:8 |
| 786 | msgid "May" | 786 | msgid "May" |
| 787 | -msgstr "" | 787 | +msgstr "Majo" |
| 788 | 788 | ||
| 789 | #: app/helpers/dates_helper.rb:12 app/helpers/forms_helper.rb:172 | 789 | #: app/helpers/dates_helper.rb:12 app/helpers/forms_helper.rb:172 |
| 790 | #: plugins/display_content/lib/display_content_block.rb:9 | 790 | #: plugins/display_content/lib/display_content_block.rb:9 |
| 791 | msgid "June" | 791 | msgid "June" |
| 792 | -msgstr "" | 792 | +msgstr "Junio" |
| 793 | 793 | ||
| 794 | #: app/helpers/dates_helper.rb:13 app/helpers/forms_helper.rb:172 | 794 | #: app/helpers/dates_helper.rb:13 app/helpers/forms_helper.rb:172 |
| 795 | #: plugins/display_content/lib/display_content_block.rb:10 | 795 | #: plugins/display_content/lib/display_content_block.rb:10 |
| 796 | msgid "July" | 796 | msgid "July" |
| 797 | -msgstr "" | 797 | +msgstr "Julio" |
| 798 | 798 | ||
| 799 | #: app/helpers/dates_helper.rb:14 app/helpers/forms_helper.rb:172 | 799 | #: app/helpers/dates_helper.rb:14 app/helpers/forms_helper.rb:172 |
| 800 | #: plugins/display_content/lib/display_content_block.rb:11 | 800 | #: plugins/display_content/lib/display_content_block.rb:11 |
| 801 | msgid "August" | 801 | msgid "August" |
| 802 | -msgstr "" | 802 | +msgstr "Aŭgusto" |
| 803 | 803 | ||
| 804 | #: app/helpers/dates_helper.rb:15 app/helpers/forms_helper.rb:172 | 804 | #: app/helpers/dates_helper.rb:15 app/helpers/forms_helper.rb:172 |
| 805 | #: plugins/display_content/lib/display_content_block.rb:12 | 805 | #: plugins/display_content/lib/display_content_block.rb:12 |
| 806 | msgid "September" | 806 | msgid "September" |
| 807 | -msgstr "" | 807 | +msgstr "Septembro" |
| 808 | 808 | ||
| 809 | #: app/helpers/dates_helper.rb:16 app/helpers/forms_helper.rb:172 | 809 | #: app/helpers/dates_helper.rb:16 app/helpers/forms_helper.rb:172 |
| 810 | #: plugins/display_content/lib/display_content_block.rb:13 | 810 | #: plugins/display_content/lib/display_content_block.rb:13 |
| 811 | msgid "October" | 811 | msgid "October" |
| 812 | -msgstr "" | 812 | +msgstr "Oktobro" |
| 813 | 813 | ||
| 814 | #: app/helpers/dates_helper.rb:17 app/helpers/forms_helper.rb:172 | 814 | #: app/helpers/dates_helper.rb:17 app/helpers/forms_helper.rb:172 |
| 815 | #: plugins/display_content/lib/display_content_block.rb:14 | 815 | #: plugins/display_content/lib/display_content_block.rb:14 |
| 816 | msgid "November" | 816 | msgid "November" |
| 817 | -msgstr "" | 817 | +msgstr "Novembro" |
| 818 | 818 | ||
| 819 | #: app/helpers/dates_helper.rb:18 app/helpers/forms_helper.rb:172 | 819 | #: app/helpers/dates_helper.rb:18 app/helpers/forms_helper.rb:172 |
| 820 | #: plugins/display_content/lib/display_content_block.rb:15 | 820 | #: plugins/display_content/lib/display_content_block.rb:15 |
| 821 | msgid "December" | 821 | msgid "December" |
| 822 | -msgstr "" | 822 | +msgstr "Decembro" |
| 823 | 823 | ||
| 824 | #: app/helpers/dates_helper.rb:28 | 824 | #: app/helpers/dates_helper.rb:28 |
| 825 | #: plugins/display_content/lib/display_content_block.rb:153 | 825 | #: plugins/display_content/lib/display_content_block.rb:153 |
| @@ -834,7 +834,7 @@ msgstr "" | @@ -834,7 +834,7 @@ msgstr "" | ||
| 834 | #: app/helpers/dates_helper.rb:31 | 834 | #: app/helpers/dates_helper.rb:31 |
| 835 | #: plugins/display_content/lib/display_content_block.rb:156 | 835 | #: plugins/display_content/lib/display_content_block.rb:156 |
| 836 | msgid "%{month_name} %{day}, %{year}" | 836 | msgid "%{month_name} %{day}, %{year}" |
| 837 | -msgstr "" | 837 | +msgstr "La %{day}-a de %{month_name} %{year}" |
| 838 | 838 | ||
| 839 | #: app/helpers/dates_helper.rb:31 | 839 | #: app/helpers/dates_helper.rb:31 |
| 840 | #: plugins/display_content/lib/display_content_block.rb:156 | 840 | #: plugins/display_content/lib/display_content_block.rb:156 |
| @@ -8043,7 +8043,7 @@ msgstr "" | @@ -8043,7 +8043,7 @@ msgstr "" | ||
| 8043 | 8043 | ||
| 8044 | #: app/views/account/index_anonymous.rhtml:10 | 8044 | #: app/views/account/index_anonymous.rhtml:10 |
| 8045 | msgid "Sign up." | 8045 | msgid "Sign up." |
| 8046 | -msgstr "" | 8046 | +msgstr "Aliĝi" |
| 8047 | 8047 | ||
| 8048 | #: app/views/account/index_anonymous.rhtml:11 | 8048 | #: app/views/account/index_anonymous.rhtml:11 |
| 8049 | msgid "" | 8049 | msgid "" |
po/es/noosfero.po
| @@ -7,7 +7,7 @@ msgid "" | @@ -7,7 +7,7 @@ msgid "" | ||
| 7 | msgstr "" | 7 | msgstr "" |
| 8 | "Project-Id-Version: noosfero 0.45.2\n" | 8 | "Project-Id-Version: noosfero 0.45.2\n" |
| 9 | "POT-Creation-Date: 2014-01-17 18:26-0000\n" | 9 | "POT-Creation-Date: 2014-01-17 18:26-0000\n" |
| 10 | -"PO-Revision-Date: 2013-01-03 18:39-0300\n" | 10 | +"PO-Revision-Date: 2014-03-25 14:55+0000\n" |
| 11 | "Last-Translator: Luis David Aguilar Carlos <ludwig9003@gmail.com>,Freddy " | 11 | "Last-Translator: Luis David Aguilar Carlos <ludwig9003@gmail.com>,Freddy " |
| 12 | "Martín Hernández Facio <fmhf14@gmail.com>, Pedro Alonzo Ramírez Tovar <pedro." | 12 | "Martín Hernández Facio <fmhf14@gmail.com>, Pedro Alonzo Ramírez Tovar <pedro." |
| 13 | "alonzo709@gmail.com>\n" | 13 | "alonzo709@gmail.com>\n" |
| @@ -292,7 +292,6 @@ msgid "Next" | @@ -292,7 +292,6 @@ msgid "Next" | ||
| 292 | msgstr "Siguiente" | 292 | msgstr "Siguiente" |
| 293 | 293 | ||
| 294 | #: app/helpers/application_helper.rb:1118 | 294 | #: app/helpers/application_helper.rb:1118 |
| 295 | -#, fuzzy | ||
| 296 | msgid "See all" | 295 | msgid "See all" |
| 297 | msgstr "Ver todos" | 296 | msgstr "Ver todos" |
| 298 | 297 | ||
| @@ -690,11 +689,11 @@ msgstr "Configurar foro" | @@ -690,11 +689,11 @@ msgstr "Configurar foro" | ||
| 690 | 689 | ||
| 691 | #: app/helpers/forum_helper.rb:14 app/helpers/blog_helper.rb:23 | 690 | #: app/helpers/forum_helper.rb:14 app/helpers/blog_helper.rb:23 |
| 692 | msgid "« Newer posts" | 691 | msgid "« Newer posts" |
| 693 | -msgstr "« Entradas recientes" | 692 | +msgstr "« Noticias más nuevas" |
| 694 | 693 | ||
| 695 | #: app/helpers/forum_helper.rb:15 app/helpers/blog_helper.rb:24 | 694 | #: app/helpers/forum_helper.rb:15 app/helpers/blog_helper.rb:24 |
| 696 | msgid "Older posts »" | 695 | msgid "Older posts »" |
| 697 | -msgstr "Entradas antiguas »" | 696 | +msgstr "Noticias más viejas »" |
| 698 | 697 | ||
| 699 | #: app/helpers/forum_helper.rb:18 | 698 | #: app/helpers/forum_helper.rb:18 |
| 700 | msgid "Discussion topic" | 699 | msgid "Discussion topic" |
| @@ -841,15 +840,13 @@ msgstr "%{day} de %{month} %{year}" | @@ -841,15 +840,13 @@ msgstr "%{day} de %{month} %{year}" | ||
| 841 | 840 | ||
| 842 | #: app/helpers/dates_helper.rb:28 app/helpers/dates_helper.rb:40 | 841 | #: app/helpers/dates_helper.rb:28 app/helpers/dates_helper.rb:40 |
| 843 | #: plugins/display_content/lib/display_content_block.rb:153 | 842 | #: plugins/display_content/lib/display_content_block.rb:153 |
| 844 | -#, fuzzy | ||
| 845 | msgid "%{month}/%{day}" | 843 | msgid "%{month}/%{day}" |
| 846 | -msgstr "%{day} de %{month} %{year}" | 844 | +msgstr "%{day}/%{month}" |
| 847 | 845 | ||
| 848 | #: app/helpers/dates_helper.rb:31 | 846 | #: app/helpers/dates_helper.rb:31 |
| 849 | #: plugins/display_content/lib/display_content_block.rb:156 | 847 | #: plugins/display_content/lib/display_content_block.rb:156 |
| 850 | -#, fuzzy | ||
| 851 | msgid "%{month_name} %{day}, %{year}" | 848 | msgid "%{month_name} %{day}, %{year}" |
| 852 | -msgstr "%{day} de %{month} %{year}" | 849 | +msgstr "%{day} de %{month} de %{year}" |
| 853 | 850 | ||
| 854 | # LAs cadenas de este tipo NO se traducen | 851 | # LAs cadenas de este tipo NO se traducen |
| 855 | #: app/helpers/dates_helper.rb:31 | 852 | #: app/helpers/dates_helper.rb:31 |
| @@ -877,21 +874,19 @@ msgstr "%{month} %{year}" | @@ -877,21 +874,19 @@ msgstr "%{month} %{year}" | ||
| 877 | 874 | ||
| 878 | #: app/helpers/dates_helper.rb:53 | 875 | #: app/helpers/dates_helper.rb:53 |
| 879 | msgid "%{day} %{month} %{year}, %{hour}:%{minutes}" | 876 | msgid "%{day} %{month} %{year}, %{hour}:%{minutes}" |
| 880 | -msgstr "%{day} %{month} %{year}, %{hour}:%{minutes}" | 877 | +msgstr "%{day} de %{month} de %{year}, %{hour}:%{minutes}" |
| 881 | 878 | ||
| 882 | #: app/helpers/dates_helper.rb:65 | 879 | #: app/helpers/dates_helper.rb:65 |
| 883 | -#, fuzzy | ||
| 884 | msgid "from %{month} %{day1} to %{day2}, %{year}" | 880 | msgid "from %{month} %{day1} to %{day2}, %{year}" |
| 885 | -msgstr "%{day} de %{month} %{year}" | 881 | +msgstr "de %{day1} para %{day2} de %{month} de %{year}" |
| 886 | 882 | ||
| 887 | #: app/helpers/dates_helper.rb:72 | 883 | #: app/helpers/dates_helper.rb:72 |
| 888 | -#, fuzzy | ||
| 889 | msgid "from %{date1} to %{date2}, %{year}" | 884 | msgid "from %{date1} to %{date2}, %{year}" |
| 890 | -msgstr "Por %{author} el %{date}" | 885 | +msgstr "de %{date1} para %{date2} de %{year}" |
| 891 | 886 | ||
| 892 | #: app/helpers/dates_helper.rb:79 | 887 | #: app/helpers/dates_helper.rb:79 |
| 893 | msgid "from %{date1} to %{date2}" | 888 | msgid "from %{date1} to %{date2}" |
| 894 | -msgstr "Por %{author} el %{date}" | 889 | +msgstr "de %{date1} para %{date2}" |
| 895 | 890 | ||
| 896 | #: app/helpers/dates_helper.rb:89 app/helpers/forms_helper.rb:163 | 891 | #: app/helpers/dates_helper.rb:89 app/helpers/forms_helper.rb:163 |
| 897 | msgid "Sun" | 892 | msgid "Sun" |
po/it/noosfero.po
| @@ -8,7 +8,7 @@ msgid "" | @@ -8,7 +8,7 @@ msgid "" | ||
| 8 | msgstr "" | 8 | msgstr "" |
| 9 | "Project-Id-Version: noosfero 0.45.2\n" | 9 | "Project-Id-Version: noosfero 0.45.2\n" |
| 10 | "POT-Creation-Date: 2014-01-17 18:26-0000\n" | 10 | "POT-Creation-Date: 2014-01-17 18:26-0000\n" |
| 11 | -"PO-Revision-Date: 2012-06-05 10:27-0300\n" | 11 | +"PO-Revision-Date: 2014-03-25 15:39+0000\n" |
| 12 | "Last-Translator: Daniela Feitosa <danielafeitosa@colivre.coop.br>\n" | 12 | "Last-Translator: Daniela Feitosa <danielafeitosa@colivre.coop.br>\n" |
| 13 | "Language-Team: LANGUAGE TEAM <LL@li.org>\n" | 13 | "Language-Team: LANGUAGE TEAM <LL@li.org>\n" |
| 14 | "Language: it\n" | 14 | "Language: it\n" |
| @@ -109,7 +109,7 @@ msgstr "" | @@ -109,7 +109,7 @@ msgstr "" | ||
| 109 | #: app/views/blocks/profile_info_actions/_join_leave_community.rhtml:25 | 109 | #: app/views/blocks/profile_info_actions/_join_leave_community.rhtml:25 |
| 110 | #: app/views/profile/_private_profile.rhtml:10 | 110 | #: app/views/profile/_private_profile.rhtml:10 |
| 111 | msgid "Join" | 111 | msgid "Join" |
| 112 | -msgstr "" | 112 | +msgstr "Accedere" |
| 113 | 113 | ||
| 114 | #: app/helpers/application_helper.rb:554 | 114 | #: app/helpers/application_helper.rb:554 |
| 115 | #: app/views/blocks/profile_info_actions/_join_leave_community.rhtml:4 | 115 | #: app/views/blocks/profile_info_actions/_join_leave_community.rhtml:4 |
| @@ -752,63 +752,63 @@ msgstr "" | @@ -752,63 +752,63 @@ msgstr "" | ||
| 752 | #: app/helpers/dates_helper.rb:7 app/helpers/forms_helper.rb:172 | 752 | #: app/helpers/dates_helper.rb:7 app/helpers/forms_helper.rb:172 |
| 753 | #: plugins/display_content/lib/display_content_block.rb:4 | 753 | #: plugins/display_content/lib/display_content_block.rb:4 |
| 754 | msgid "January" | 754 | msgid "January" |
| 755 | -msgstr "" | 755 | +msgstr "gennaio" |
| 756 | 756 | ||
| 757 | #: app/helpers/dates_helper.rb:8 app/helpers/forms_helper.rb:172 | 757 | #: app/helpers/dates_helper.rb:8 app/helpers/forms_helper.rb:172 |
| 758 | #: plugins/display_content/lib/display_content_block.rb:5 | 758 | #: plugins/display_content/lib/display_content_block.rb:5 |
| 759 | msgid "February" | 759 | msgid "February" |
| 760 | -msgstr "" | 760 | +msgstr "febbraio" |
| 761 | 761 | ||
| 762 | #: app/helpers/dates_helper.rb:9 app/helpers/forms_helper.rb:172 | 762 | #: app/helpers/dates_helper.rb:9 app/helpers/forms_helper.rb:172 |
| 763 | #: plugins/display_content/lib/display_content_block.rb:6 | 763 | #: plugins/display_content/lib/display_content_block.rb:6 |
| 764 | msgid "March" | 764 | msgid "March" |
| 765 | -msgstr "" | 765 | +msgstr "marzo" |
| 766 | 766 | ||
| 767 | #: app/helpers/dates_helper.rb:10 app/helpers/forms_helper.rb:172 | 767 | #: app/helpers/dates_helper.rb:10 app/helpers/forms_helper.rb:172 |
| 768 | #: plugins/display_content/lib/display_content_block.rb:7 | 768 | #: plugins/display_content/lib/display_content_block.rb:7 |
| 769 | msgid "April" | 769 | msgid "April" |
| 770 | -msgstr "" | 770 | +msgstr "aprile" |
| 771 | 771 | ||
| 772 | #: app/helpers/dates_helper.rb:11 app/helpers/forms_helper.rb:172 | 772 | #: app/helpers/dates_helper.rb:11 app/helpers/forms_helper.rb:172 |
| 773 | #: app/helpers/forms_helper.rb:173 | 773 | #: app/helpers/forms_helper.rb:173 |
| 774 | #: plugins/display_content/lib/display_content_block.rb:8 | 774 | #: plugins/display_content/lib/display_content_block.rb:8 |
| 775 | msgid "May" | 775 | msgid "May" |
| 776 | -msgstr "" | 776 | +msgstr "maggio" |
| 777 | 777 | ||
| 778 | #: app/helpers/dates_helper.rb:12 app/helpers/forms_helper.rb:172 | 778 | #: app/helpers/dates_helper.rb:12 app/helpers/forms_helper.rb:172 |
| 779 | #: plugins/display_content/lib/display_content_block.rb:9 | 779 | #: plugins/display_content/lib/display_content_block.rb:9 |
| 780 | msgid "June" | 780 | msgid "June" |
| 781 | -msgstr "" | 781 | +msgstr "giugno" |
| 782 | 782 | ||
| 783 | #: app/helpers/dates_helper.rb:13 app/helpers/forms_helper.rb:172 | 783 | #: app/helpers/dates_helper.rb:13 app/helpers/forms_helper.rb:172 |
| 784 | #: plugins/display_content/lib/display_content_block.rb:10 | 784 | #: plugins/display_content/lib/display_content_block.rb:10 |
| 785 | msgid "July" | 785 | msgid "July" |
| 786 | -msgstr "" | 786 | +msgstr "luglio" |
| 787 | 787 | ||
| 788 | #: app/helpers/dates_helper.rb:14 app/helpers/forms_helper.rb:172 | 788 | #: app/helpers/dates_helper.rb:14 app/helpers/forms_helper.rb:172 |
| 789 | #: plugins/display_content/lib/display_content_block.rb:11 | 789 | #: plugins/display_content/lib/display_content_block.rb:11 |
| 790 | msgid "August" | 790 | msgid "August" |
| 791 | -msgstr "" | 791 | +msgstr "agosto" |
| 792 | 792 | ||
| 793 | #: app/helpers/dates_helper.rb:15 app/helpers/forms_helper.rb:172 | 793 | #: app/helpers/dates_helper.rb:15 app/helpers/forms_helper.rb:172 |
| 794 | #: plugins/display_content/lib/display_content_block.rb:12 | 794 | #: plugins/display_content/lib/display_content_block.rb:12 |
| 795 | msgid "September" | 795 | msgid "September" |
| 796 | -msgstr "" | 796 | +msgstr "settembre" |
| 797 | 797 | ||
| 798 | #: app/helpers/dates_helper.rb:16 app/helpers/forms_helper.rb:172 | 798 | #: app/helpers/dates_helper.rb:16 app/helpers/forms_helper.rb:172 |
| 799 | #: plugins/display_content/lib/display_content_block.rb:13 | 799 | #: plugins/display_content/lib/display_content_block.rb:13 |
| 800 | msgid "October" | 800 | msgid "October" |
| 801 | -msgstr "" | 801 | +msgstr "ottobre" |
| 802 | 802 | ||
| 803 | #: app/helpers/dates_helper.rb:17 app/helpers/forms_helper.rb:172 | 803 | #: app/helpers/dates_helper.rb:17 app/helpers/forms_helper.rb:172 |
| 804 | #: plugins/display_content/lib/display_content_block.rb:14 | 804 | #: plugins/display_content/lib/display_content_block.rb:14 |
| 805 | msgid "November" | 805 | msgid "November" |
| 806 | -msgstr "" | 806 | +msgstr "novembre" |
| 807 | 807 | ||
| 808 | #: app/helpers/dates_helper.rb:18 app/helpers/forms_helper.rb:172 | 808 | #: app/helpers/dates_helper.rb:18 app/helpers/forms_helper.rb:172 |
| 809 | #: plugins/display_content/lib/display_content_block.rb:15 | 809 | #: plugins/display_content/lib/display_content_block.rb:15 |
| 810 | msgid "December" | 810 | msgid "December" |
| 811 | -msgstr "" | 811 | +msgstr "dicembre" |
| 812 | 812 | ||
| 813 | #: app/helpers/dates_helper.rb:28 | 813 | #: app/helpers/dates_helper.rb:28 |
| 814 | #: plugins/display_content/lib/display_content_block.rb:153 | 814 | #: plugins/display_content/lib/display_content_block.rb:153 |
| @@ -823,7 +823,7 @@ msgstr "" | @@ -823,7 +823,7 @@ msgstr "" | ||
| 823 | #: app/helpers/dates_helper.rb:31 | 823 | #: app/helpers/dates_helper.rb:31 |
| 824 | #: plugins/display_content/lib/display_content_block.rb:156 | 824 | #: plugins/display_content/lib/display_content_block.rb:156 |
| 825 | msgid "%{month_name} %{day}, %{year}" | 825 | msgid "%{month_name} %{day}, %{year}" |
| 826 | -msgstr "" | 826 | +msgstr "%{day} %{month_name} %{year}" |
| 827 | 827 | ||
| 828 | #: app/helpers/dates_helper.rb:31 | 828 | #: app/helpers/dates_helper.rb:31 |
| 829 | #: plugins/display_content/lib/display_content_block.rb:156 | 829 | #: plugins/display_content/lib/display_content_block.rb:156 |
| @@ -8016,7 +8016,7 @@ msgstr "" | @@ -8016,7 +8016,7 @@ msgstr "" | ||
| 8016 | 8016 | ||
| 8017 | #: app/views/account/index_anonymous.rhtml:10 | 8017 | #: app/views/account/index_anonymous.rhtml:10 |
| 8018 | msgid "Sign up." | 8018 | msgid "Sign up." |
| 8019 | -msgstr "" | 8019 | +msgstr "Registro" |
| 8020 | 8020 | ||
| 8021 | #: app/views/account/index_anonymous.rhtml:11 | 8021 | #: app/views/account/index_anonymous.rhtml:11 |
| 8022 | msgid "" | 8022 | msgid "" |
po/pt/noosfero.po
| @@ -2875,6 +2875,30 @@ msgstr "Artigo de texto com linguagem de marcação Textile" | @@ -2875,6 +2875,30 @@ msgstr "Artigo de texto com linguagem de marcação Textile" | ||
| 2875 | msgid "Accessible alternative for visually impaired users." | 2875 | msgid "Accessible alternative for visually impaired users." |
| 2876 | msgstr "Alternativa acessível para usuários com deficiência visual." | 2876 | msgstr "Alternativa acessível para usuários com deficiência visual." |
| 2877 | 2877 | ||
| 2878 | +#: app/models/layout_template.rb | ||
| 2879 | +msgid "Left Bar" | ||
| 2880 | +msgstr "Uma barra à esquerda" | ||
| 2881 | + | ||
| 2882 | +#: app/models/layout_template.rb | ||
| 2883 | +msgid "2 Left Bars" | ||
| 2884 | +msgstr "Duas barras à esquerda" | ||
| 2885 | + | ||
| 2886 | +#: app/models/layout_template.rb | ||
| 2887 | +msgid "Left and Bottom Bar" | ||
| 2888 | +msgstr "Uma barra à esquerda e outra ao final" | ||
| 2889 | + | ||
| 2890 | +#: app/models/layout_template.rb | ||
| 2891 | +msgid "Right Bar" | ||
| 2892 | +msgstr "Uma barra à direita" | ||
| 2893 | + | ||
| 2894 | +#: app/models/layout_template.rb | ||
| 2895 | +msgid "Default" | ||
| 2896 | +msgstr "Padrão" | ||
| 2897 | + | ||
| 2898 | +#: app/models/layout_template.rb | ||
| 2899 | +msgid "No Sidebars" | ||
| 2900 | +msgstr "Nenhuma barra lateral" | ||
| 2901 | + | ||
| 2878 | #: app/models/login_block.rb:4 | 2902 | #: app/models/login_block.rb:4 |
| 2879 | msgid "Login/logout" | 2903 | msgid "Login/logout" |
| 2880 | msgstr "Login/Sair" | 2904 | msgstr "Login/Sair" |
| @@ -7219,8 +7243,8 @@ msgstr "Funcionalidade" | @@ -7219,8 +7243,8 @@ msgstr "Funcionalidade" | ||
| 7219 | 7243 | ||
| 7220 | #: app/views/features/index.rhtml:16 | 7244 | #: app/views/features/index.rhtml:16 |
| 7221 | #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb:4 | 7245 | #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb:4 |
| 7222 | -msgid "Enabled?" | ||
| 7223 | -msgstr "Habilitada?" | 7246 | +msgid "Enable shopping basket" |
| 7247 | +msgstr "Habilitar cesto de compras" | ||
| 7224 | 7248 | ||
| 7225 | #: app/views/features/index.rhtml:27 | 7249 | #: app/views/features/index.rhtml:27 |
| 7226 | msgid "Configure features" | 7250 | msgid "Configure features" |
| @@ -12462,8 +12486,8 @@ msgid "Basket options" | @@ -12462,8 +12486,8 @@ msgid "Basket options" | ||
| 12462 | msgstr "Opções do cesto" | 12486 | msgstr "Opções do cesto" |
| 12463 | 12487 | ||
| 12464 | #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb:5 | 12488 | #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb:5 |
| 12465 | -msgid "Delivery?" | ||
| 12466 | -msgstr "Entrega?" | 12489 | +msgid "Enable delivery fields on orders" |
| 12490 | +msgstr "Ativar campos de entrega para pedidos" | ||
| 12467 | 12491 | ||
| 12468 | #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb:10 | 12492 | #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb:10 |
| 12469 | msgid "Option" | 12493 | msgid "Option" |
| @@ -12480,12 +12504,12 @@ msgid "ADD NEW OPTION" | @@ -12480,12 +12504,12 @@ msgid "ADD NEW OPTION" | ||
| 12480 | msgstr "ADCIONAR NOVA OPÇÂO" | 12504 | msgstr "ADCIONAR NOVA OPÇÂO" |
| 12481 | 12505 | ||
| 12482 | #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb:36 | 12506 | #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb:36 |
| 12483 | -msgid "Free delivery price:" | ||
| 12484 | -msgstr "Preço de entrega grátis:" | 12507 | +msgid "Order's minimum price for free delivery:" |
| 12508 | +msgstr "Preço mínimo do pedido para entrega grátis:" | ||
| 12485 | 12509 | ||
| 12486 | #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb:37 | 12510 | #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb:37 |
| 12487 | -msgid "Empty stands for no free delivery price." | ||
| 12488 | -msgstr "Vazio significa sem preço de frete grátis." | 12511 | +msgid "Leave empty to always charge the delivery." |
| 12512 | +msgstr "Deixe vazio para sempre cobrar a entrega." | ||
| 12489 | 12513 | ||
| 12490 | #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/reports.html.erb:1 | 12514 | #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/reports.html.erb:1 |
| 12491 | msgid "Purchase Reports" | 12515 | msgid "Purchase Reports" |
public/designs/icons/tango/style.css
| 1 | /******************SMALL ICONS********************/ | 1 | /******************SMALL ICONS********************/ |
| 2 | +.icon-embed { background-image: url(Tango/16x16/apps/utilities-terminal.png) } | ||
| 2 | .icon-edit { background-image: url(Tango/16x16/apps/text-editor.png) } | 3 | .icon-edit { background-image: url(Tango/16x16/apps/text-editor.png) } |
| 3 | .icon-home { background-image: url(Tango/16x16/actions/go-home.png) } | 4 | .icon-home { background-image: url(Tango/16x16/actions/go-home.png) } |
| 4 | .icon-home-not { background-image: url(mod/16x16/actions/go-home-not.png) } | 5 | .icon-home-not { background-image: url(mod/16x16/actions/go-home-not.png) } |
public/designs/templates/leftbottom/config.yml
| 1 | -name: "Left and Bottom bar" | 1 | +name: "Left and Bottom Bar" |
| 2 | title: "Style 2 columns and a box at bottom of content" | 2 | title: "Style 2 columns and a box at bottom of content" |
| 3 | description: "A theme with 2 columns and a box below the content" | 3 | description: "A theme with 2 columns and a box below the content" |
| 4 | number_of_boxes: 3 | 4 | number_of_boxes: 3 |
public/designs/templates/nosidebars/config.yml
public/designs/themes/base/style.css
| @@ -1275,6 +1275,11 @@ hr.pre-posts, hr.sep-posts { | @@ -1275,6 +1275,11 @@ hr.pre-posts, hr.sep-posts { | ||
| 1275 | padding-right: 9px; | 1275 | padding-right: 9px; |
| 1276 | } | 1276 | } |
| 1277 | 1277 | ||
| 1278 | +.comment-order { | ||
| 1279 | + float: right; | ||
| 1280 | + display: block; | ||
| 1281 | +} | ||
| 1282 | + | ||
| 1278 | .comment-from-owner .comment-created-at { | 1283 | .comment-from-owner .comment-created-at { |
| 1279 | color: #333; | 1284 | color: #333; |
| 1280 | } | 1285 | } |
1.11 KB
| @@ -0,0 +1,60 @@ | @@ -0,0 +1,60 @@ | ||
| 1 | +(function($){ | ||
| 2 | + autoCompleteStateCity($); | ||
| 3 | + $('[id$="_country"]').change(function(){ | ||
| 4 | + autoCompleteStateCity($); | ||
| 5 | + }) | ||
| 6 | +})(jQuery); | ||
| 7 | + | ||
| 8 | +function autoCompleteStateCity($) { | ||
| 9 | + var country_selected = $('[id$="_country"] option:selected').val() | ||
| 10 | + if(country_selected == "BR") | ||
| 11 | + { | ||
| 12 | + $('#state_field').autocomplete({ | ||
| 13 | + source : function(request, response){ | ||
| 14 | + $.ajax({ | ||
| 15 | + type: "GET", | ||
| 16 | + url: '/account/search_state', | ||
| 17 | + data: {state_name: request.term}, | ||
| 18 | + success: function(result){ | ||
| 19 | + response(result); | ||
| 20 | + }, | ||
| 21 | + error: function(ajax, stat, errorThrown) { | ||
| 22 | + console.log('Link not found : ' + errorThrown); | ||
| 23 | + } | ||
| 24 | + }); | ||
| 25 | + }, | ||
| 26 | + | ||
| 27 | + minLength: 3 | ||
| 28 | + }); | ||
| 29 | + | ||
| 30 | + $('#city_field').autocomplete({ | ||
| 31 | + source : function(request, response){ | ||
| 32 | + $.ajax({ | ||
| 33 | + type: "GET", | ||
| 34 | + url: '/account/search_cities', | ||
| 35 | + data: {city_name: request.term, state_name: $("#state_field").val()}, | ||
| 36 | + success: function(result){ | ||
| 37 | + response(result); | ||
| 38 | + }, | ||
| 39 | + error: function(ajax, stat, errorThrown) { | ||
| 40 | + console.log('Link not found : ' + errorThrown); | ||
| 41 | + } | ||
| 42 | + }); | ||
| 43 | + }, | ||
| 44 | + | ||
| 45 | + minLength: 3 | ||
| 46 | + }); | ||
| 47 | + } | ||
| 48 | + else | ||
| 49 | + { | ||
| 50 | + if ($('#state_field').data('autocomplete')) { | ||
| 51 | + $('#state_field').autocomplete("destroy"); | ||
| 52 | + $('#state_field').removeData('autocomplete'); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + if ($('#city_field').data('autocomplete')) { | ||
| 56 | + $('#city_field').autocomplete("destroy"); | ||
| 57 | + $('#city_field').removeData('autocomplete'); | ||
| 58 | + } | ||
| 59 | + } | ||
| 60 | +} |
| @@ -0,0 +1,21 @@ | @@ -0,0 +1,21 @@ | ||
| 1 | +function send_order(order, url) { | ||
| 2 | + open_loading(DEFAULT_LOADING_MESSAGE); | ||
| 3 | + | ||
| 4 | + jQuery.ajax({ | ||
| 5 | + url:url, | ||
| 6 | + data: {"comment_order":order}, | ||
| 7 | + success: function(response) { | ||
| 8 | + close_loading(); | ||
| 9 | + jQuery(".article-comments-list").html(response); | ||
| 10 | + }, | ||
| 11 | + error: function() { close_loading() } | ||
| 12 | + }); | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | + | ||
| 16 | +jQuery(document).ready(function(){ | ||
| 17 | + jQuery("#comment_order").change(function(){ | ||
| 18 | + var url = jQuery("#page_url").val(); | ||
| 19 | + send_order(this.value, url); | ||
| 20 | + }); | ||
| 21 | +}); | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
| @@ -0,0 +1,39 @@ | @@ -0,0 +1,39 @@ | ||
| 1 | +function send_ajax(source_url) { | ||
| 2 | + jQuery(".link-address").autocomplete({ | ||
| 3 | + source : function(request, response){ | ||
| 4 | + jQuery.ajax({ | ||
| 5 | + type: "GET", | ||
| 6 | + url: source_url, | ||
| 7 | + data: {query: request.term}, | ||
| 8 | + success: function(result){ | ||
| 9 | + response(result); | ||
| 10 | + }, | ||
| 11 | + error: function(ajax, stat, errorThrown) { | ||
| 12 | + console.log('Link not found : ' + errorThrown); | ||
| 13 | + } | ||
| 14 | + }); | ||
| 15 | + }, | ||
| 16 | + | ||
| 17 | + minLength: 3 | ||
| 18 | + }); | ||
| 19 | +} | ||
| 20 | + | ||
| 21 | +function new_link_action(){ | ||
| 22 | + send_ajax(jQuery("#page_url").val()); | ||
| 23 | + | ||
| 24 | + jQuery(".delete-link-list-row").click(function(){ | ||
| 25 | + jQuery(this).parent().parent().remove(); | ||
| 26 | + return false; | ||
| 27 | + }); | ||
| 28 | + | ||
| 29 | + jQuery(document).scrollTop(jQuery('#dropable-link-list').scrollTop()); | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +jQuery(document).ready(function(){ | ||
| 33 | + new_link_action(); | ||
| 34 | + | ||
| 35 | + jQuery("#dropable-link-list").sortable({ | ||
| 36 | + revert: true, | ||
| 37 | + axis: "y" | ||
| 38 | + }); | ||
| 39 | +}); | ||
| 0 | \ No newline at end of file | 40 | \ No newline at end of file |
| @@ -0,0 +1,83 @@ | @@ -0,0 +1,83 @@ | ||
| 1 | +function update_active(name_active, name_required, name_signup) { | ||
| 2 | + var required = jQuery("input[name='" + name_required + "']")[1] | ||
| 3 | + var signup = jQuery("input[name='" + name_signup + "']")[1] | ||
| 4 | + var active = jQuery("input[name='" + name_active + "']")[1] | ||
| 5 | + | ||
| 6 | + if(required.checked || signup.checked) | ||
| 7 | + active.checked = true | ||
| 8 | +} | ||
| 9 | + | ||
| 10 | +function active_action(obj_active, name_required, name_signup) { | ||
| 11 | + var required = jQuery("input[name='" + name_required + "']")[0] | ||
| 12 | + var signup = jQuery("input[name='" + name_signup + "']")[0] | ||
| 13 | + | ||
| 14 | + required.disabled = signup.disabled = !obj_active.checked | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +function required_action(name_active, name_required, name_signup) { | ||
| 18 | + var obj_required = jQuery("input[name='" + name_required + "']")[1] | ||
| 19 | + | ||
| 20 | + if(obj_required.checked) { | ||
| 21 | + jQuery("input[name='" + name_signup + "']")[0].checked = true | ||
| 22 | + jQuery("input[name='" + name_signup + "']")[1].checked = true | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + update_active(name_active, name_required, name_signup) | ||
| 26 | +} | ||
| 27 | + | ||
| 28 | +function signup_action(name_active, name_required, name_signup) { | ||
| 29 | + var obj_signup = jQuery("input[name='" + name_signup + "']")[1] | ||
| 30 | + | ||
| 31 | + if(!obj_signup.checked) { | ||
| 32 | + jQuery("input[name='" + name_required + "']")[0].checked = false | ||
| 33 | + jQuery("input[name='" + name_required + "']")[1].checked = false | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + update_active(name_active, name_required, name_signup) | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | + | ||
| 40 | +jQuery(document).ready(function(){ | ||
| 41 | + function check_fields(check, table_id, start) { | ||
| 42 | + var checkboxes = jQuery("#" + table_id + " tbody tr td input[type='checkbox']") | ||
| 43 | + for (var i = start; i < checkboxes.length; i+=3) { | ||
| 44 | + checkboxes[i].checked = check | ||
| 45 | + } | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + function verify_checked(fields_id){ | ||
| 49 | + var checkboxes = jQuery("#" + fields_id + "_fields_conf tbody tr td input[type='checkbox']") | ||
| 50 | + for (var i = 2; i >= 0; i--) { | ||
| 51 | + var allchecked = true | ||
| 52 | + for (var j = i+3; j < checkboxes.length; j+=3) { | ||
| 53 | + if(!checkboxes[j].checked) { | ||
| 54 | + allchecked = false | ||
| 55 | + break | ||
| 56 | + } | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + var checkbox = jQuery(checkboxes[i+3]).attr("id").split("_") | ||
| 60 | + jQuery("#" + checkbox.first() + "_" + checkbox.last()).attr("checked", allchecked) | ||
| 61 | + } | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + function check_all(fields_id) { | ||
| 65 | + jQuery("#" + fields_id + "_active").click(function (){check_fields(this.checked, fields_id + "_fields_conf", 0)}) | ||
| 66 | + jQuery("#" + fields_id + "_required").click(function (){check_fields(this.checked, fields_id + "_fields_conf", 1)}) | ||
| 67 | + jQuery("#" + fields_id +"_signup").click(function (){check_fields(this.checked, fields_id + "_fields_conf", 2)}) | ||
| 68 | + verify_checked(fields_id) | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + check_all("person") | ||
| 72 | + check_all("enterprise") | ||
| 73 | + check_all("community") | ||
| 74 | + | ||
| 75 | + jQuery("input[type='checkbox']").click(function (){ | ||
| 76 | + var checkbox = jQuery(this).attr("id").split("_") | ||
| 77 | + verify_checked(checkbox.first()) | ||
| 78 | + | ||
| 79 | + if(this.checked == false) { | ||
| 80 | + jQuery("#" + checkbox.first() + "_" + checkbox.last()).attr("checked", false) | ||
| 81 | + } | ||
| 82 | + }) | ||
| 83 | +}) |
| @@ -0,0 +1,121 @@ | @@ -0,0 +1,121 @@ | ||
| 1 | +// This jQuery plugin is written by firas kassem [2007.04.05] and was modified to fit noosfero | ||
| 2 | +// Firas Kassem phiras.wordpress.com || phiras at gmail {dot} com | ||
| 3 | +// for more information : http://phiras.wordpress.com/2007/04/08/password-strength-meter-a-jquery-plugin/ | ||
| 4 | + | ||
| 5 | +var blankPass = -1 | ||
| 6 | +var shortPass = 0 | ||
| 7 | +var badPass = 1 | ||
| 8 | +var goodPass = 2 | ||
| 9 | +var strongPass = 3 | ||
| 10 | + | ||
| 11 | + | ||
| 12 | +function passwordStrength(password,username) | ||
| 13 | +{ | ||
| 14 | + score = 0 | ||
| 15 | + | ||
| 16 | + if(password.length == 0) return blankPass | ||
| 17 | + | ||
| 18 | + //password < 4 | ||
| 19 | + if (password.length < 4 ) { return shortPass } | ||
| 20 | + | ||
| 21 | + //password == username | ||
| 22 | + if (password.toLowerCase()==username.toLowerCase()) badPass | ||
| 23 | + | ||
| 24 | + //password length | ||
| 25 | + score += password.length * 4 | ||
| 26 | + score += ( checkRepetition(1,password).length - password.length ) * 1 | ||
| 27 | + score += ( checkRepetition(2,password).length - password.length ) * 1 | ||
| 28 | + score += ( checkRepetition(3,password).length - password.length ) * 1 | ||
| 29 | + score += ( checkRepetition(4,password).length - password.length ) * 1 | ||
| 30 | + | ||
| 31 | + //password has 3 numbers | ||
| 32 | + if (password.match(/(.*[0-9].*[0-9].*[0-9])/)) score += 5 | ||
| 33 | + | ||
| 34 | + //password has 2 sybols | ||
| 35 | + if (password.match(/(.*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~])/)) score += 5 | ||
| 36 | + | ||
| 37 | + //password has Upper and Lower chars | ||
| 38 | + if (password.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/)) score += 10 | ||
| 39 | + | ||
| 40 | + //password has number and chars | ||
| 41 | + if (password.match(/([a-zA-Z])/) && password.match(/([0-9])/)) score += 15 | ||
| 42 | + // | ||
| 43 | + //password has number and symbol | ||
| 44 | + if (password.match(/([!,@,#,$,%,^,&,*,?,_,~])/) && password.match(/([0-9])/)) score += 15 | ||
| 45 | + | ||
| 46 | + //password has char and symbol | ||
| 47 | + if (password.match(/([!,@,#,$,%,^,&,*,?,_,~])/) && password.match(/([a-zA-Z])/)) score += 15 | ||
| 48 | + | ||
| 49 | + //password is just a nubers or chars | ||
| 50 | + if (password.match(/^\w+$/) || password.match(/^\d+$/) ) score -= 10 | ||
| 51 | + | ||
| 52 | + //verifing 0 < score < 100 | ||
| 53 | + if ( score < 0 ) score = 0 | ||
| 54 | + if ( score > 100 ) score = 100 | ||
| 55 | + | ||
| 56 | + if (score < 34 ) return badPass | ||
| 57 | + if (score < 68 ) return goodPass | ||
| 58 | + return strongPass | ||
| 59 | +} | ||
| 60 | + | ||
| 61 | +function checkRepetition(pLen,str) | ||
| 62 | +{ | ||
| 63 | + res = "" | ||
| 64 | + for ( i=0; i<str.length ; i++ ) | ||
| 65 | + { | ||
| 66 | + repeated=true | ||
| 67 | + for (j=0;j < pLen && (j+i+pLen) < str.length;j++) | ||
| 68 | + repeated=repeated && (str.charAt(j+i)==str.charAt(j+i+pLen)) | ||
| 69 | + if (j<pLen) repeated=false | ||
| 70 | + if (repeated) | ||
| 71 | + { | ||
| 72 | + i+=pLen-1 | ||
| 73 | + repeated=false | ||
| 74 | + } | ||
| 75 | + else | ||
| 76 | + { | ||
| 77 | + res+=str.charAt(i) | ||
| 78 | + } | ||
| 79 | + } | ||
| 80 | + return res | ||
| 81 | +} | ||
| 82 | + | ||
| 83 | +jQuery(document).ready(function() { | ||
| 84 | + jQuery('#user_pw').keyup(function() | ||
| 85 | + { | ||
| 86 | + var result = passwordStrength(jQuery('#user_pw').val(),jQuery('#user_login').val()) | ||
| 87 | + if(result == blankPass) | ||
| 88 | + { | ||
| 89 | + showRateField('#result-blank') | ||
| 90 | + } else | ||
| 91 | + if(result == shortPass) | ||
| 92 | + { | ||
| 93 | + showRateField('#result-short') | ||
| 94 | + } else | ||
| 95 | + if( result == badPass ) | ||
| 96 | + { | ||
| 97 | + showRateField('#result-bad') | ||
| 98 | + } else | ||
| 99 | + if( result == goodPass ) | ||
| 100 | + { | ||
| 101 | + showRateField('#result-good') | ||
| 102 | + } else | ||
| 103 | + if( result == strongPass ) | ||
| 104 | + { | ||
| 105 | + showRateField('#result-strong') | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + }) | ||
| 109 | +}) | ||
| 110 | + | ||
| 111 | +function showRateField(validation) | ||
| 112 | +{ | ||
| 113 | + jQuery('#result-blank').addClass('hidden') | ||
| 114 | + jQuery('#result-short').addClass('hidden') | ||
| 115 | + jQuery('#result-bad').addClass('hidden') | ||
| 116 | + jQuery('#result-good').addClass('hidden') | ||
| 117 | + jQuery('#result-strong').addClass('hidden') | ||
| 118 | + | ||
| 119 | + jQuery(validation).removeClass('hidden') | ||
| 120 | + | ||
| 121 | +} | ||
| 0 | \ No newline at end of file | 122 | \ No newline at end of file |
| @@ -0,0 +1,23 @@ | @@ -0,0 +1,23 @@ | ||
| 1 | +function verifyLoginLoad() { | ||
| 2 | + jQuery('#user_login').removeClass('available unavailable valid validated invalid checking').addClass('checking'); | ||
| 3 | + jQuery('#url-check').html(jQuery('#checking-message').html()); | ||
| 4 | +} | ||
| 5 | + | ||
| 6 | +function verifyLoginAjax(value) { | ||
| 7 | + verifyLoginLoad(); | ||
| 8 | + | ||
| 9 | + jQuery.get( | ||
| 10 | + "/account/check_valid_name", | ||
| 11 | + {'identifier': encodeURIComponent(value)}, | ||
| 12 | + function(request){ | ||
| 13 | + jQuery('#user_login').removeClass('checking'); | ||
| 14 | + jQuery("#url-check").html(request); | ||
| 15 | + } | ||
| 16 | + ); | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +jQuery(document).ready(function(){ | ||
| 20 | + jQuery("#user_login").blur(function(){ | ||
| 21 | + verifyLoginAjax(this.value); | ||
| 22 | + }); | ||
| 23 | +}); |
public/stylesheets/application.css
| @@ -354,21 +354,32 @@ div.pending-tasks { | @@ -354,21 +354,32 @@ div.pending-tasks { | ||
| 354 | margin-bottom: 1px; | 354 | margin-bottom: 1px; |
| 355 | } | 355 | } |
| 356 | /* * * category ajax selector * * */ | 356 | /* * * category ajax selector * * */ |
| 357 | - | 357 | +#category-ajax-selector .category-helper-label { |
| 358 | + font-size: 16px; | ||
| 359 | + color: rgb(158, 158, 158); | ||
| 360 | + padding: 5px 0px; | ||
| 361 | +} | ||
| 358 | #category-ajax-selector { | 362 | #category-ajax-selector { |
| 359 | border: 1px solid #AAA; | 363 | border: 1px solid #AAA; |
| 360 | - background: #EEE; | ||
| 361 | - padding: 15px 0px 15px 20px; | ||
| 362 | - margin: 30px 0px 0px 0px; | 364 | + padding: 3px 10px 10px 10px; |
| 365 | + margin: 0px 0px 0px 0px; | ||
| 363 | position: relative; | 366 | position: relative; |
| 364 | - font-size: 18px; | 367 | + font-size: 10px; |
| 368 | + background-color: #fcfcf9; | ||
| 365 | } | 369 | } |
| 366 | #category-ajax-selector a { | 370 | #category-ajax-selector a { |
| 367 | - font-size: 14px; | 371 | + font-size: 12px; |
| 368 | } | 372 | } |
| 369 | -#category-ajax-selector h3 { | ||
| 370 | - margin: 10px 0px; | ||
| 371 | - font-size: 14px; | 373 | +#selected-categories { |
| 374 | + padding-bottom: 5px; | ||
| 375 | +} | ||
| 376 | +#selected-categories .label { | ||
| 377 | + font-size: 16px; | ||
| 378 | + margin-bottom: 10px; | ||
| 379 | + margin-top: 5px; | ||
| 380 | +} | ||
| 381 | +.selected-category { | ||
| 382 | + padding: 2px 0; | ||
| 372 | } | 383 | } |
| 373 | #category-ajax-selector .box-title { | 384 | #category-ajax-selector .box-title { |
| 374 | position: absolute; | 385 | position: absolute; |
| @@ -384,25 +395,32 @@ div.pending-tasks { | @@ -384,25 +395,32 @@ div.pending-tasks { | ||
| 384 | .msie6 #category-ajax-selector .box-title { | 395 | .msie6 #category-ajax-selector .box-title { |
| 385 | top: -29px; | 396 | top: -29px; |
| 386 | } | 397 | } |
| 387 | -#category-ajax-selector .select-subcategory-link { | 398 | +#category-ajax-selector .select-subcategory-link, |
| 399 | +.select-subcategory-link { | ||
| 388 | border: 1px solid #BBB; | 400 | border: 1px solid #BBB; |
| 389 | padding: 1px 3px; | 401 | padding: 1px 3px; |
| 390 | margin: 0px 1px; | 402 | margin: 0px 1px; |
| 391 | text-decoration: none; | 403 | text-decoration: none; |
| 392 | white-space: nowrap; | 404 | white-space: nowrap; |
| 393 | - font-size: 11px; | 405 | + font-size: 12px; |
| 406 | + line-height: 20px; | ||
| 407 | + border-radius: 3px; | ||
| 408 | +} | ||
| 409 | +#category-ajax-selector .selected-category .select-subcategory-link { | ||
| 410 | + border: 0; | ||
| 394 | } | 411 | } |
| 395 | -#category-ajax-selector .select-subcategory-link:hover { | 412 | +#category-ajax-selector .select-subcategory-link:hover, |
| 413 | +.select-subcategory-link:hover { | ||
| 396 | background-color: black; | 414 | background-color: black; |
| 397 | } | 415 | } |
| 398 | #category-ajax-selector .button { | 416 | #category-ajax-selector .button { |
| 399 | - display: block; | ||
| 400 | - position: absolute; | ||
| 401 | top: 4px; | 417 | top: 4px; |
| 402 | right: 2px; | 418 | right: 2px; |
| 403 | } | 419 | } |
| 404 | -#category-ajax-selector .icon-save { | ||
| 405 | - right: 25px; | 420 | +#category-ajax-selector hr { |
| 421 | + border: 0; | ||
| 422 | + border-bottom: 1px solid #EEE; | ||
| 423 | + margin-top: 15px; | ||
| 406 | } | 424 | } |
| 407 | #profile-header, #profile-footer { | 425 | #profile-header, #profile-footer { |
| 408 | clear: both; | 426 | clear: both; |
| @@ -1841,20 +1859,70 @@ a.button.disabled, input.disabled { | @@ -1841,20 +1859,70 @@ a.button.disabled, input.disabled { | ||
| 1841 | text-decoration: none; | 1859 | text-decoration: none; |
| 1842 | } | 1860 | } |
| 1843 | /* ==> blocks/link-list-block.css <<= */ | 1861 | /* ==> blocks/link-list-block.css <<= */ |
| 1844 | - | ||
| 1845 | #edit-link-list-block { | 1862 | #edit-link-list-block { |
| 1846 | - width: 820px; | 1863 | + width: 620px; |
| 1864 | + position: relative; | ||
| 1865 | + left: -24px; | ||
| 1847 | } | 1866 | } |
| 1848 | - | ||
| 1849 | -#edit-link-list-block table { | ||
| 1850 | - width: auto; | ||
| 1851 | - 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; | ||
| 1852 | } | 1873 | } |
| 1853 | -#edit-link-list-block table .cel-address { | ||
| 1854 | - 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; | ||
| 1855 | } | 1880 | } |
| 1856 | -#edit-link-list-block table .cel-address input { | ||
| 1857 | - 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; | ||
| 1858 | } | 1926 | } |
| 1859 | #content .link-list-block { | 1927 | #content .link-list-block { |
| 1860 | padding: 10px 0px 10px 10px; | 1928 | padding: 10px 0px 10px 10px; |
| @@ -3543,9 +3611,10 @@ div#article-parent { | @@ -3543,9 +3611,10 @@ div#article-parent { | ||
| 3543 | } | 3611 | } |
| 3544 | #agenda .agenda-calendar { | 3612 | #agenda .agenda-calendar { |
| 3545 | width: 50%; | 3613 | width: 50%; |
| 3614 | + display: inline-block; | ||
| 3546 | } | 3615 | } |
| 3547 | #agenda td, #agenda th { | 3616 | #agenda td, #agenda th { |
| 3548 | - padding: 15px; | 3617 | + padding: 10px; |
| 3549 | padding-right: 0px; | 3618 | padding-right: 0px; |
| 3550 | } | 3619 | } |
| 3551 | #agenda .agenda-calendar .previous-month td, #agenda .agenda-calendar .previous-month th, #agenda .agenda-calendar .next-month td, #agenda .agenda-calendar .next-month th { | 3620 | #agenda .agenda-calendar .previous-month td, #agenda .agenda-calendar .previous-month th, #agenda .agenda-calendar .next-month td, #agenda .agenda-calendar .next-month th { |
| @@ -3603,26 +3672,25 @@ div#article-parent { | @@ -3603,26 +3672,25 @@ div#article-parent { | ||
| 3603 | vertical-align: middle; | 3672 | vertical-align: middle; |
| 3604 | } | 3673 | } |
| 3605 | #agenda .agenda-calendar .current-month caption { | 3674 | #agenda .agenda-calendar .current-month caption { |
| 3606 | - margin-bottom: 10px; | 3675 | + margin: 10px 0px; |
| 3607 | } | 3676 | } |
| 3608 | #agenda #events-of-the-day { | 3677 | #agenda #events-of-the-day { |
| 3609 | - position: absolute; | ||
| 3610 | - left: 50%; | ||
| 3611 | width: 45%; | 3678 | width: 45%; |
| 3612 | - top: 0px; | ||
| 3613 | height: 100%; | 3679 | height: 100%; |
| 3614 | padding-left: 20px; | 3680 | padding-left: 20px; |
| 3681 | + display: inline-block; | ||
| 3682 | + vertical-align: top; | ||
| 3615 | } | 3683 | } |
| 3616 | #agenda #events-of-the-day #agenda-items { | 3684 | #agenda #events-of-the-day #agenda-items { |
| 3617 | display: block; | 3685 | display: block; |
| 3618 | overflow: auto; | 3686 | overflow: auto; |
| 3619 | overflow-x: hidden; | 3687 | overflow-x: hidden; |
| 3620 | - height: 80%; | 3688 | + height: 250px; |
| 3621 | background: white; | 3689 | background: white; |
| 3622 | border: none; | 3690 | border: none; |
| 3623 | } | 3691 | } |
| 3624 | #agenda-toolbar { | 3692 | #agenda-toolbar { |
| 3625 | - float: right; | 3693 | + text-align: right; |
| 3626 | font-variant: normal; | 3694 | font-variant: normal; |
| 3627 | font-weight: normal; | 3695 | font-weight: normal; |
| 3628 | } | 3696 | } |
| @@ -3645,6 +3713,9 @@ h1#agenda-title { | @@ -3645,6 +3713,9 @@ h1#agenda-title { | ||
| 3645 | display: block; | 3713 | display: block; |
| 3646 | margin-top: 10px; | 3714 | margin-top: 10px; |
| 3647 | } | 3715 | } |
| 3716 | +#agenda .pagination { | ||
| 3717 | + margin-top: 15px; | ||
| 3718 | +} | ||
| 3648 | /* ==> public/stylesheets/controller_favorite_enterprises.css <== */ | 3719 | /* ==> public/stylesheets/controller_favorite_enterprises.css <== */ |
| 3649 | 3720 | ||
| 3650 | /* ==> @import url(manage_contacts_list.css); <== */ | 3721 | /* ==> @import url(manage_contacts_list.css); <== */ |
| @@ -4196,6 +4267,11 @@ h1#agenda-title { | @@ -4196,6 +4267,11 @@ h1#agenda-title { | ||
| 4196 | display: block; | 4267 | display: block; |
| 4197 | float: left; | 4268 | float: left; |
| 4198 | } | 4269 | } |
| 4270 | + | ||
| 4271 | +.actions .members-buttons-cell { | ||
| 4272 | + width : 100px | ||
| 4273 | +} | ||
| 4274 | + | ||
| 4199 | .controller-profile_members .msie6 .button-bar a { | 4275 | .controller-profile_members .msie6 .button-bar a { |
| 4200 | position: relative; | 4276 | position: relative; |
| 4201 | } | 4277 | } |
| @@ -5964,8 +6040,14 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { | @@ -5964,8 +6040,14 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { | ||
| 5964 | text-align: right; | 6040 | text-align: right; |
| 5965 | } | 6041 | } |
| 5966 | 6042 | ||
| 6043 | +#url-check .suggested_usernames, | ||
| 6044 | +#url-check .suggested_usernames a { | ||
| 6045 | + color: #005000; | ||
| 6046 | +} | ||
| 6047 | + | ||
| 5967 | #email-check, | 6048 | #email-check, |
| 5968 | #fake-check, | 6049 | #fake-check, |
| 6050 | +#password-rate, | ||
| 5969 | #password-check { | 6051 | #password-check { |
| 5970 | margin: -2px 16px -5px 13px; | 6052 | margin: -2px 16px -5px 13px; |
| 5971 | text-align: right; | 6053 | text-align: right; |
| @@ -5974,10 +6056,20 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { | @@ -5974,10 +6056,20 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { | ||
| 5974 | 6056 | ||
| 5975 | #email-check p, | 6057 | #email-check p, |
| 5976 | #fake-check p, | 6058 | #fake-check p, |
| 6059 | +#password-rate p, | ||
| 5977 | #password-check p { | 6060 | #password-check p { |
| 5978 | margin: 0; | 6061 | margin: 0; |
| 5979 | } | 6062 | } |
| 5980 | 6063 | ||
| 6064 | +#password-rate { | ||
| 6065 | + font-weight:bold; | ||
| 6066 | +} | ||
| 6067 | + | ||
| 6068 | +.hidden { | ||
| 6069 | + visibility: hidden; | ||
| 6070 | + display: none; | ||
| 6071 | +} | ||
| 6072 | + | ||
| 5981 | .available { | 6073 | .available { |
| 5982 | color: #88BD00; | 6074 | color: #88BD00; |
| 5983 | } | 6075 | } |
| @@ -5991,6 +6083,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { | @@ -5991,6 +6083,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { | ||
| 5991 | } | 6083 | } |
| 5992 | 6084 | ||
| 5993 | #email-check p, | 6085 | #email-check p, |
| 6086 | +#password-rate p, | ||
| 5994 | #password-check p, | 6087 | #password-check p, |
| 5995 | #url-check p { | 6088 | #url-check p { |
| 5996 | margin: 0; | 6089 | margin: 0; |
| @@ -6488,3 +6581,31 @@ ul.article-versions li { | @@ -6488,3 +6581,31 @@ ul.article-versions li { | ||
| 6488 | font-size: 13px; | 6581 | font-size: 13px; |
| 6489 | padding: 3px 0px; | 6582 | padding: 3px 0px; |
| 6490 | } | 6583 | } |
| 6584 | + | ||
| 6585 | +/* * * Admin manage fields * * */ | ||
| 6586 | + | ||
| 6587 | +.controller-features .manage-fields-batch-actions, | ||
| 6588 | +.controller-features .manage-fields-batch-actions:hover { | ||
| 6589 | + border-bottom:solid 2px #000; | ||
| 6590 | + background-color: #EEE; | ||
| 6591 | +} | ||
| 6592 | + | ||
| 6593 | +.controller-features .manage-fields-batch-actions td { | ||
| 6594 | + font-style: italic; | ||
| 6595 | +} | ||
| 6596 | + | ||
| 6597 | +#signup-form #result-short { | ||
| 6598 | + color: red; | ||
| 6599 | +} | ||
| 6600 | + | ||
| 6601 | +#signup-form #result-bad { | ||
| 6602 | + color: #825A2C; | ||
| 6603 | +} | ||
| 6604 | + | ||
| 6605 | +#signup-form #result-good { | ||
| 6606 | + color: #32CD32; | ||
| 6607 | +} | ||
| 6608 | + | ||
| 6609 | +#signup-form #result-strong { | ||
| 6610 | + color: green; | ||
| 6611 | +} |
test/functional/account_controller_test.rb
| @@ -8,7 +8,6 @@ class AccountControllerTest < ActionController::TestCase | @@ -8,7 +8,6 @@ class AccountControllerTest < ActionController::TestCase | ||
| 8 | # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead | 8 | # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead |
| 9 | # Then, you can remove it from this and the units test. | 9 | # Then, you can remove it from this and the units test. |
| 10 | include AuthenticatedTestHelper | 10 | include AuthenticatedTestHelper |
| 11 | - | ||
| 12 | all_fixtures | 11 | all_fixtures |
| 13 | 12 | ||
| 14 | def teardown | 13 | def teardown |
| @@ -17,8 +16,8 @@ class AccountControllerTest < ActionController::TestCase | @@ -17,8 +16,8 @@ class AccountControllerTest < ActionController::TestCase | ||
| 17 | 16 | ||
| 18 | def setup | 17 | def setup |
| 19 | @controller = AccountController.new | 18 | @controller = AccountController.new |
| 20 | - @request = ActionController::TestRequest.new | ||
| 21 | - @response = ActionController::TestResponse.new | 19 | + @request = ActionController::TestRequest.new |
| 20 | + @response = ActionController::TestResponse.new | ||
| 22 | disable_signup_bot_check | 21 | disable_signup_bot_check |
| 23 | end | 22 | end |
| 24 | 23 | ||
| @@ -646,21 +645,28 @@ class AccountControllerTest < ActionController::TestCase | @@ -646,21 +645,28 @@ class AccountControllerTest < ActionController::TestCase | ||
| 646 | assert_redirected_to :controller => 'home', :action => 'index' | 645 | assert_redirected_to :controller => 'home', :action => 'index' |
| 647 | end | 646 | end |
| 648 | 647 | ||
| 649 | - should 'check_url is available on environment' do | 648 | + should 'check_valid_name is available on environment' do |
| 650 | env = fast_create(Environment, :name => 'Environment test') | 649 | env = fast_create(Environment, :name => 'Environment test') |
| 651 | @controller.expects(:environment).returns(env).at_least_once | 650 | @controller.expects(:environment).returns(env).at_least_once |
| 652 | profile = create_user('mylogin').person | 651 | profile = create_user('mylogin').person |
| 653 | - get :check_url, :identifier => 'mylogin' | 652 | + get :check_valid_name, :identifier => 'mylogin' |
| 654 | assert_equal 'validated', assigns(:status_class) | 653 | assert_equal 'validated', assigns(:status_class) |
| 655 | end | 654 | end |
| 656 | 655 | ||
| 657 | should 'check if url is not available on environment' do | 656 | should 'check if url is not available on environment' do |
| 658 | @controller.expects(:environment).returns(Environment.default).at_least_once | 657 | @controller.expects(:environment).returns(Environment.default).at_least_once |
| 659 | profile = create_user('mylogin').person | 658 | profile = create_user('mylogin').person |
| 660 | - get :check_url, :identifier => 'mylogin' | 659 | + get :check_valid_name, :identifier => 'mylogin' |
| 661 | assert_equal 'invalid', assigns(:status_class) | 660 | assert_equal 'invalid', assigns(:status_class) |
| 662 | end | 661 | end |
| 663 | 662 | ||
| 663 | + should 'suggest a list with three possible usernames' do | ||
| 664 | + profile = create_user('mylogin').person | ||
| 665 | + get :check_valid_name, :identifier => 'mylogin' | ||
| 666 | + | ||
| 667 | + assert_equal 3, assigns(:suggested_usernames).uniq.size | ||
| 668 | + end | ||
| 669 | + | ||
| 664 | should 'check if e-mail is available on environment' do | 670 | should 'check if e-mail is available on environment' do |
| 665 | env = fast_create(Environment, :name => 'Environment test') | 671 | env = fast_create(Environment, :name => 'Environment test') |
| 666 | @controller.expects(:environment).returns(env).at_least_once | 672 | @controller.expects(:environment).returns(env).at_least_once |
| @@ -689,6 +695,7 @@ class AccountControllerTest < ActionController::TestCase | @@ -689,6 +695,7 @@ class AccountControllerTest < ActionController::TestCase | ||
| 689 | {:test => 5} | 695 | {:test => 5} |
| 690 | end | 696 | end |
| 691 | end | 697 | end |
| 698 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | ||
| 692 | 699 | ||
| 693 | e = User.find_by_login('ze').environment | 700 | e = User.find_by_login('ze').environment |
| 694 | e.enable_plugin(Plugin1.name) | 701 | e.enable_plugin(Plugin1.name) |
| @@ -779,6 +786,7 @@ class AccountControllerTest < ActionController::TestCase | @@ -779,6 +786,7 @@ class AccountControllerTest < ActionController::TestCase | ||
| 779 | proc {"<strong>Plugin2 text</strong>"} | 786 | proc {"<strong>Plugin2 text</strong>"} |
| 780 | end | 787 | end |
| 781 | end | 788 | end |
| 789 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | ||
| 782 | 790 | ||
| 783 | Environment.default.enable_plugin(Plugin1.name) | 791 | Environment.default.enable_plugin(Plugin1.name) |
| 784 | Environment.default.enable_plugin(Plugin2.name) | 792 | Environment.default.enable_plugin(Plugin2.name) |
| @@ -795,6 +803,7 @@ class AccountControllerTest < ActionController::TestCase | @@ -795,6 +803,7 @@ class AccountControllerTest < ActionController::TestCase | ||
| 795 | User.new(:login => 'testuser') | 803 | User.new(:login => 'testuser') |
| 796 | end | 804 | end |
| 797 | end | 805 | end |
| 806 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name]) | ||
| 798 | Environment.default.enable_plugin(Plugin1.name) | 807 | Environment.default.enable_plugin(Plugin1.name) |
| 799 | 808 | ||
| 800 | post :login, :user => {:login => "testuser"} | 809 | post :login, :user => {:login => "testuser"} |
| @@ -809,6 +818,7 @@ class AccountControllerTest < ActionController::TestCase | @@ -809,6 +818,7 @@ class AccountControllerTest < ActionController::TestCase | ||
| 809 | nil | 818 | nil |
| 810 | end | 819 | end |
| 811 | end | 820 | end |
| 821 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name]) | ||
| 812 | Environment.default.enable_plugin(Plugin1.name) | 822 | Environment.default.enable_plugin(Plugin1.name) |
| 813 | post :login, :user => {:login => 'johndoe', :password => 'test'} | 823 | post :login, :user => {:login => 'johndoe', :password => 'test'} |
| 814 | assert session[:user] | 824 | assert session[:user] |
| @@ -822,6 +832,7 @@ class AccountControllerTest < ActionController::TestCase | @@ -822,6 +832,7 @@ class AccountControllerTest < ActionController::TestCase | ||
| 822 | false | 832 | false |
| 823 | end | 833 | end |
| 824 | end | 834 | end |
| 835 | + Noosfero::Plugin.stubs(:all).returns([TestRegistrationPlugin.name]) | ||
| 825 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestRegistrationPlugin.new]) | 836 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestRegistrationPlugin.new]) |
| 826 | 837 | ||
| 827 | post :signup, :user => { :login => 'testuser', :password => '123456', :password_confirmation => '123456', :email => 'testuser@example.com' } | 838 | post :signup, :user => { :login => 'testuser', :password => '123456', :password_confirmation => '123456', :email => 'testuser@example.com' } |
| @@ -840,6 +851,7 @@ class AccountControllerTest < ActionController::TestCase | @@ -840,6 +851,7 @@ class AccountControllerTest < ActionController::TestCase | ||
| 840 | true | 851 | true |
| 841 | end | 852 | end |
| 842 | end | 853 | end |
| 854 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | ||
| 843 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new]) | 855 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new]) |
| 844 | 856 | ||
| 845 | get :login | 857 | get :login |
| @@ -853,6 +865,7 @@ class AccountControllerTest < ActionController::TestCase | @@ -853,6 +865,7 @@ class AccountControllerTest < ActionController::TestCase | ||
| 853 | false | 865 | false |
| 854 | end | 866 | end |
| 855 | end | 867 | end |
| 868 | + Noosfero::Plugin.stubs(:all).returns([TestRegistrationPlugin.name]) | ||
| 856 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestRegistrationPlugin.new]) | 869 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestRegistrationPlugin.new]) |
| 857 | 870 | ||
| 858 | #Redirect on get action | 871 | #Redirect on get action |
| @@ -876,6 +889,7 @@ class AccountControllerTest < ActionController::TestCase | @@ -876,6 +889,7 @@ class AccountControllerTest < ActionController::TestCase | ||
| 876 | true | 889 | true |
| 877 | end | 890 | end |
| 878 | end | 891 | end |
| 892 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.new, Plugin2.new]) | ||
| 879 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new]) | 893 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new]) |
| 880 | 894 | ||
| 881 | get :login | 895 | get :login |
| @@ -894,6 +908,7 @@ class AccountControllerTest < ActionController::TestCase | @@ -894,6 +908,7 @@ class AccountControllerTest < ActionController::TestCase | ||
| 894 | proc {"<strong>Plugin2 text</strong>"} | 908 | proc {"<strong>Plugin2 text</strong>"} |
| 895 | end | 909 | end |
| 896 | end | 910 | end |
| 911 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | ||
| 897 | 912 | ||
| 898 | Environment.default.enable_plugin(Plugin1.name) | 913 | Environment.default.enable_plugin(Plugin1.name) |
| 899 | Environment.default.enable_plugin(Plugin2.name) | 914 | Environment.default.enable_plugin(Plugin2.name) |
| @@ -917,6 +932,30 @@ class AccountControllerTest < ActionController::TestCase | @@ -917,6 +932,30 @@ class AccountControllerTest < ActionController::TestCase | ||
| 917 | assert @response.body.blank? | 932 | assert @response.body.blank? |
| 918 | end | 933 | end |
| 919 | 934 | ||
| 935 | + should "Search for state" do | ||
| 936 | + create_state_and_city | ||
| 937 | + | ||
| 938 | + xhr :get, :search_state, :state_name=>"Rio Grande" | ||
| 939 | + | ||
| 940 | + json_response = ActiveSupport::JSON.decode(@response.body) | ||
| 941 | + label = json_response[0]['label'] | ||
| 942 | + | ||
| 943 | + assert_equal label, "Rio Grande do Sul" | ||
| 944 | + end | ||
| 945 | + | ||
| 946 | + should "Search for city" do | ||
| 947 | + create_state_and_city | ||
| 948 | + | ||
| 949 | + xhr :get, :search_cities, :state_name=>"Rio Grande do Sul", :city_name=>"Lavras" | ||
| 950 | + | ||
| 951 | + json_response = ActiveSupport::JSON.decode(@response.body) | ||
| 952 | + label = json_response[0]['label'] | ||
| 953 | + category = json_response[0]['category'] | ||
| 954 | + | ||
| 955 | + assert_equal category, "Rio Grande do Sul" | ||
| 956 | + assert_equal label, "Lavras do Sul" | ||
| 957 | + end | ||
| 958 | + | ||
| 920 | protected | 959 | protected |
| 921 | def new_user(options = {}, extra_options ={}) | 960 | def new_user(options = {}, extra_options ={}) |
| 922 | data = {:profile_data => person_data} | 961 | data = {:profile_data => person_data} |
| @@ -945,4 +984,18 @@ class AccountControllerTest < ActionController::TestCase | @@ -945,4 +984,18 @@ class AccountControllerTest < ActionController::TestCase | ||
| 945 | environment.min_signup_delay = 0 | 984 | environment.min_signup_delay = 0 |
| 946 | environment.save! | 985 | environment.save! |
| 947 | end | 986 | end |
| 987 | + | ||
| 988 | + def create_state_and_city | ||
| 989 | + city = 'Lavras do Sul' | ||
| 990 | + state = 'Rio Grande do Sul' | ||
| 991 | + | ||
| 992 | + parent_region = fast_create(NationalRegion, :name => state, | ||
| 993 | + :national_region_code => '43', | ||
| 994 | + :national_region_type_id => NationalRegionType::STATE) | ||
| 995 | + | ||
| 996 | + fast_create(NationalRegion, :name => city, | ||
| 997 | + :national_region_code => '431150', | ||
| 998 | + :national_region_type_id => NationalRegionType::CITY, | ||
| 999 | + :parent_national_region_code => parent_region.national_region_code) | ||
| 1000 | + end | ||
| 948 | end | 1001 | end |
test/functional/application_controller_test.rb
| @@ -234,7 +234,7 @@ class ApplicationControllerTest < ActionController::TestCase | @@ -234,7 +234,7 @@ class ApplicationControllerTest < ActionController::TestCase | ||
| 234 | get :index | 234 | get :index |
| 235 | 235 | ||
| 236 | assert_tag :tag => 'div', :attributes => { :id => 'theme-test-panel' }, :descendant => { | 236 | assert_tag :tag => 'div', :attributes => { :id => 'theme-test-panel' }, :descendant => { |
| 237 | - :tag => 'a', :attributes => { :href => '/myprofile/testinguser/themes/edit/my-test-theme'} | 237 | + :tag => 'a', :attributes => { :href => '/myprofile/testinguser/profile_themes/edit/my-test-theme'} |
| 238 | } | 238 | } |
| 239 | #{ :tag => 'a', :attributes => { :href => '/myprofile/testinguser/themes/stop_test/my-test-theme'} } | 239 | #{ :tag => 'a', :attributes => { :href => '/myprofile/testinguser/themes/stop_test/my-test-theme'} } |
| 240 | end | 240 | end |
| @@ -253,7 +253,7 @@ class ApplicationControllerTest < ActionController::TestCase | @@ -253,7 +253,7 @@ class ApplicationControllerTest < ActionController::TestCase | ||
| 253 | assert_no_tag :tag => 'a', :content => /Category 2/ | 253 | assert_no_tag :tag => 'a', :content => /Category 2/ |
| 254 | end | 254 | end |
| 255 | 255 | ||
| 256 | - should 'show name of article as title of page' do | 256 | + should 'show name of article as title of page without environment' do |
| 257 | p = create_user('test_user').person | 257 | p = create_user('test_user').person |
| 258 | a = p.articles.create!(:name => 'test article') | 258 | a = p.articles.create!(:name => 'test article') |
| 259 | 259 | ||
| @@ -261,17 +261,22 @@ class ApplicationControllerTest < ActionController::TestCase | @@ -261,17 +261,22 @@ class ApplicationControllerTest < ActionController::TestCase | ||
| 261 | @controller.instance_variable_set('@page', a) | 261 | @controller.instance_variable_set('@page', a) |
| 262 | 262 | ||
| 263 | get :index | 263 | get :index |
| 264 | - assert_tag 'title', :content => 'test article - ' + p.name + ' - ' + p.environment.name | 264 | + assert_tag 'title', :content => 'test article - ' + p.name |
| 265 | end | 265 | end |
| 266 | 266 | ||
| 267 | - should 'diplay name of profile in the title' do | 267 | + should 'diplay name of profile in the title without environment' do |
| 268 | p = create_user('test_user').person | 268 | p = create_user('test_user').person |
| 269 | p.name = 'Some Test User' | 269 | p.name = 'Some Test User' |
| 270 | p.save! | 270 | p.save! |
| 271 | @controller.instance_variable_set('@profile', p) | 271 | @controller.instance_variable_set('@profile', p) |
| 272 | 272 | ||
| 273 | get :index, :profile => p.identifier | 273 | get :index, :profile => p.identifier |
| 274 | - assert_tag 'title', :content => p.name + ' - ' + p.environment.name | 274 | + assert_tag 'title', :content => p.name |
| 275 | + end | ||
| 276 | + | ||
| 277 | + should 'display environment name in title when profile and page are not defined' do | ||
| 278 | + get :index | ||
| 279 | + assert_tag 'title', :content => assigns(:environment).name | ||
| 275 | end | 280 | end |
| 276 | 281 | ||
| 277 | should 'display menu links for my environment when logged in other environment' do | 282 | should 'display menu links for my environment when logged in other environment' do |
| @@ -314,7 +319,8 @@ class ApplicationControllerTest < ActionController::TestCase | @@ -314,7 +319,8 @@ class ApplicationControllerTest < ActionController::TestCase | ||
| 314 | end | 319 | end |
| 315 | 320 | ||
| 316 | should 'set html lang as the article language if an article is present and has a language' do | 321 | should 'set html lang as the article language if an article is present and has a language' do |
| 317 | - a = fast_create(Article, :name => 'test article', :language => 'fr') | 322 | + p = create_user('test_user').person |
| 323 | + a = fast_create(Article, :name => 'test article', :language => 'fr', :profile_id => p.id ) | ||
| 318 | @controller.instance_variable_set('@page', a) | 324 | @controller.instance_variable_set('@page', a) |
| 319 | FastGettext.stubs(:locale).returns('es') | 325 | FastGettext.stubs(:locale).returns('es') |
| 320 | get :index | 326 | get :index |
| @@ -328,7 +334,9 @@ class ApplicationControllerTest < ActionController::TestCase | @@ -328,7 +334,9 @@ class ApplicationControllerTest < ActionController::TestCase | ||
| 328 | end | 334 | end |
| 329 | 335 | ||
| 330 | should 'set html lang as locale if page has no language' do | 336 | should 'set html lang as locale if page has no language' do |
| 331 | - a = fast_create(Article, :name => 'test article', :language => nil) | 337 | + p = create_user('test_user').person |
| 338 | + a = fast_create(Article, :name => 'test article', :language => nil, :profile_id => p.id ) | ||
| 339 | + | ||
| 332 | @controller.instance_variable_set('@page', a) | 340 | @controller.instance_variable_set('@page', a) |
| 333 | FastGettext.stubs(:locale).returns('es') | 341 | FastGettext.stubs(:locale).returns('es') |
| 334 | get :index | 342 | get :index |
| @@ -356,6 +364,8 @@ class ApplicationControllerTest < ActionController::TestCase | @@ -356,6 +364,8 @@ class ApplicationControllerTest < ActionController::TestCase | ||
| 356 | end | 364 | end |
| 357 | plugin2_path = '/plugin2/style.css' | 365 | plugin2_path = '/plugin2/style.css' |
| 358 | 366 | ||
| 367 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | ||
| 368 | + | ||
| 359 | environment = Environment.default | 369 | environment = Environment.default |
| 360 | environment.enable_plugin(Plugin1.name) | 370 | environment.enable_plugin(Plugin1.name) |
| 361 | environment.enable_plugin(Plugin2.name) | 371 | environment.enable_plugin(Plugin2.name) |
| @@ -390,6 +400,8 @@ class ApplicationControllerTest < ActionController::TestCase | @@ -390,6 +400,8 @@ class ApplicationControllerTest < ActionController::TestCase | ||
| 390 | plugin2_path2 = '/plugin2/'+js2 | 400 | plugin2_path2 = '/plugin2/'+js2 |
| 391 | plugin2_path3 = '/plugin2/'+js3 | 401 | plugin2_path3 = '/plugin2/'+js3 |
| 392 | 402 | ||
| 403 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | ||
| 404 | + | ||
| 393 | environment = Environment.default | 405 | environment = Environment.default |
| 394 | environment.enable_plugin(Plugin1.name) | 406 | environment.enable_plugin(Plugin1.name) |
| 395 | environment.enable_plugin(Plugin2.name) | 407 | environment.enable_plugin(Plugin2.name) |
| @@ -418,6 +430,8 @@ class ApplicationControllerTest < ActionController::TestCase | @@ -418,6 +430,8 @@ class ApplicationControllerTest < ActionController::TestCase | ||
| 418 | end | 430 | end |
| 419 | end | 431 | end |
| 420 | 432 | ||
| 433 | + Noosfero::Plugin.stubs(:all).returns([TestBodyBeginning1Plugin.name, TestBodyBeginning2Plugin.name]) | ||
| 434 | + | ||
| 421 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestBodyBeginning1Plugin.new, TestBodyBeginning2Plugin.new]) | 435 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestBodyBeginning1Plugin.new, TestBodyBeginning2Plugin.new]) |
| 422 | 436 | ||
| 423 | get :index | 437 | get :index |
| @@ -442,6 +456,8 @@ class ApplicationControllerTest < ActionController::TestCase | @@ -442,6 +456,8 @@ class ApplicationControllerTest < ActionController::TestCase | ||
| 442 | end | 456 | end |
| 443 | end | 457 | end |
| 444 | 458 | ||
| 459 | + Noosfero::Plugin.stubs(:all).returns([TestHeadEnding1Plugin.name, TestHeadEnding2Plugin.name]) | ||
| 460 | + | ||
| 445 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestHeadEnding1Plugin.new, TestHeadEnding2Plugin.new]) | 461 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestHeadEnding1Plugin.new, TestHeadEnding2Plugin.new]) |
| 446 | 462 | ||
| 447 | get :index | 463 | get :index |
| @@ -506,6 +522,7 @@ class ApplicationControllerTest < ActionController::TestCase | @@ -506,6 +522,7 @@ class ApplicationControllerTest < ActionController::TestCase | ||
| 506 | :block => lambda {} } | 522 | :block => lambda {} } |
| 507 | end | 523 | end |
| 508 | end | 524 | end |
| 525 | + Noosfero::Plugin.stubs(:all).returns([FilterPlugin.name]) | ||
| 509 | 526 | ||
| 510 | Noosfero::Plugin.load_plugin_filters(FilterPlugin) | 527 | Noosfero::Plugin.load_plugin_filters(FilterPlugin) |
| 511 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([FilterPlugin.new]) | 528 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([FilterPlugin.new]) |
| @@ -525,6 +542,7 @@ class ApplicationControllerTest < ActionController::TestCase | @@ -525,6 +542,7 @@ class ApplicationControllerTest < ActionController::TestCase | ||
| 525 | :block => proc {'plugin block called'} } | 542 | :block => proc {'plugin block called'} } |
| 526 | end | 543 | end |
| 527 | end | 544 | end |
| 545 | + Noosfero::Plugin.stubs(:all).returns([OtherFilterPlugin.name]) | ||
| 528 | 546 | ||
| 529 | Noosfero::Plugin.load_plugin_filters(OtherFilterPlugin) | 547 | Noosfero::Plugin.load_plugin_filters(OtherFilterPlugin) |
| 530 | environment1 = fast_create(Environment, :name => 'test environment') | 548 | environment1 = fast_create(Environment, :name => 'test environment') |
| @@ -539,4 +557,18 @@ class ApplicationControllerTest < ActionController::TestCase | @@ -539,4 +557,18 @@ class ApplicationControllerTest < ActionController::TestCase | ||
| 539 | assert_equal nil, @controller.application_controller_test_other_filter_plugin_filter_plugin | 557 | assert_equal nil, @controller.application_controller_test_other_filter_plugin_filter_plugin |
| 540 | end | 558 | end |
| 541 | 559 | ||
| 560 | + should 'display meta tags for social media' do | ||
| 561 | + get :index | ||
| 562 | + assert_tag :tag => 'meta', :attributes => { :name => 'twitter:card', :value => 'summary' } | ||
| 563 | + assert_tag :tag => 'meta', :attributes => { :name => 'twitter:title', :content => assigns(:environment).name } | ||
| 564 | + assert_tag :tag => 'meta', :attributes => { :name => 'twitter:description', :content => assigns(:environment).name } | ||
| 565 | + assert_no_tag :tag => 'meta', :attributes => { :name => 'twitter:image' } | ||
| 566 | + assert_tag :tag => 'meta', :attributes => { :property => 'og:type', :content => 'website' } | ||
| 567 | + assert_tag :tag => 'meta', :attributes => { :property => 'og:url', :content => assigns(:environment).top_url } | ||
| 568 | + assert_tag :tag => 'meta', :attributes => { :property => 'og:title', :content => assigns(:environment).name } | ||
| 569 | + assert_tag :tag => 'meta', :attributes => { :property => 'og:site_name', :content => assigns(:environment).name } | ||
| 570 | + assert_tag :tag => 'meta', :attributes => { :property => 'og:description', :content => assigns(:environment).name } | ||
| 571 | + assert_no_tag :tag => 'meta', :attributes => { :property => 'article:published_time' } | ||
| 572 | + assert_no_tag :tag => 'meta', :attributes => { :property => 'og:image' } | ||
| 573 | + end | ||
| 542 | end | 574 | end |
test/functional/catalog_controller_test.rb
| @@ -91,6 +91,7 @@ class CatalogControllerTest < ActionController::TestCase | @@ -91,6 +91,7 @@ class CatalogControllerTest < ActionController::TestCase | ||
| 91 | proc {"<span id='plugin2'>This is Plugin2 speaking!</span>"} | 91 | proc {"<span id='plugin2'>This is Plugin2 speaking!</span>"} |
| 92 | end | 92 | end |
| 93 | end | 93 | end |
| 94 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | ||
| 94 | 95 | ||
| 95 | product = fast_create(Product, :profile_id => @enterprise.id) | 96 | product = fast_create(Product, :profile_id => @enterprise.id) |
| 96 | environment = Environment.default | 97 | environment = Environment.default |
test/functional/cms_controller_test.rb
| @@ -445,24 +445,23 @@ class CmsControllerTest < ActionController::TestCase | @@ -445,24 +445,23 @@ class CmsControllerTest < ActionController::TestCase | ||
| 445 | assert_tag :tag => 'h3', :content => /max size #{UploadedFile.max_size.to_humanreadable}/ | 445 | assert_tag :tag => 'h3', :content => /max size #{UploadedFile.max_size.to_humanreadable}/ |
| 446 | end | 446 | end |
| 447 | 447 | ||
| 448 | - should 'display link for selecting categories' do | ||
| 449 | - # FIXME | ||
| 450 | - assert true | ||
| 451 | - #env = Environment.default | ||
| 452 | - #top = env.categories.build(:display_in_menu => true, :name => 'Top-Level category'); top.save! | ||
| 453 | - #c1 = env.categories.build(:display_in_menu => true, :name => "Test category 1", :parent_id => top.id); c1.save! | ||
| 454 | - #c2 = env.categories.build(:display_in_menu => true, :name => "Test category 2", :parent_id => top.id); c2.save! | ||
| 455 | - #c3 = env.categories.build(:display_in_menu => true, :name => "Test Category 3", :parent_id => top.id); c3.save! | ||
| 456 | - | ||
| 457 | - #article = Article.new(:name => 'test') | ||
| 458 | - #article.profile = profile | ||
| 459 | - #article.save! | ||
| 460 | - | ||
| 461 | - #get :edit, :profile => profile.identifier, :id => article.id | ||
| 462 | - | ||
| 463 | - #[c1,c2,c3].each do |item| | ||
| 464 | - # assert_tag :tag => 'a', :attributes => { :id => "select-category-#{item.id}-link" } | ||
| 465 | - #end | 448 | + should 'display link for selecting top categories' do |
| 449 | + env = Environment.default | ||
| 450 | + top = env.categories.build(:display_in_menu => true, :name => 'Top-Level category'); top.save! | ||
| 451 | + top2 = env.categories.build(:display_in_menu => true, :name => 'Top-Level category 2'); top2.save! | ||
| 452 | + c1 = env.categories.build(:display_in_menu => true, :name => "Test category 1", :parent_id => top.id); c1.save! | ||
| 453 | + c2 = env.categories.build(:display_in_menu => true, :name => "Test category 2", :parent_id => top.id); c2.save! | ||
| 454 | + c3 = env.categories.build(:display_in_menu => true, :name => "Test Category 3", :parent_id => top.id); c3.save! | ||
| 455 | + | ||
| 456 | + article = Article.new(:name => 'test') | ||
| 457 | + article.profile = profile | ||
| 458 | + article.save! | ||
| 459 | + | ||
| 460 | + get :edit, :profile => profile.identifier, :id => article.id | ||
| 461 | + | ||
| 462 | + [top, top2].each do |item| | ||
| 463 | + assert_tag :tag => 'a', :attributes => { :id => "select-category-#{item.id}-link" } | ||
| 464 | + end | ||
| 466 | end | 465 | end |
| 467 | 466 | ||
| 468 | should 'be able to associate articles with categories' do | 467 | should 'be able to associate articles with categories' do |
test/functional/content_viewer_controller_test.rb
| @@ -72,9 +72,7 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -72,9 +72,7 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
| 72 | get :view_page, :profile => 'someone', :page => [ '500.html' ] | 72 | get :view_page, :profile => 'someone', :page => [ '500.html' ] |
| 73 | 73 | ||
| 74 | assert_response :success | 74 | assert_response :success |
| 75 | - assert_match /^text\/html/, @response.headers['Content-Type'] | ||
| 76 | - assert @response.headers['Content-Disposition'].present? | ||
| 77 | - assert_match /attachment/, @response.headers['Content-Disposition'] | 75 | + assert_match /#{html.public_filename}/, @response.body |
| 78 | end | 76 | end |
| 79 | 77 | ||
| 80 | should 'produce a download-link when article is not text/html' do | 78 | should 'produce a download-link when article is not text/html' do |
| @@ -577,14 +575,6 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -577,14 +575,6 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
| 577 | assert_template 'view_page' | 575 | assert_template 'view_page' |
| 578 | end | 576 | end |
| 579 | 577 | ||
| 580 | - should 'download data for image when not view' do | ||
| 581 | - file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :profile => profile) | ||
| 582 | - get :view_page, :profile => profile.identifier, :page => file.path | ||
| 583 | - | ||
| 584 | - assert_response :success | ||
| 585 | - assert_template nil | ||
| 586 | - end | ||
| 587 | - | ||
| 588 | should "display 'Upload files' when create children of image gallery" do | 578 | should "display 'Upload files' when create children of image gallery" do |
| 589 | login_as(profile.identifier) | 579 | login_as(profile.identifier) |
| 590 | f = Gallery.create!(:name => 'gallery', :profile => profile) | 580 | f = Gallery.create!(:name => 'gallery', :profile => profile) |
| @@ -741,16 +731,6 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -741,16 +731,6 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
| 741 | assert_tag :tag => 'li', :attributes => {:title => 'my img title', :class => 'image-gallery-item'}, :child => {:tag => 'span', :content => 'my img title'} | 731 | assert_tag :tag => 'li', :attributes => {:title => 'my img title', :class => 'image-gallery-item'}, :child => {:tag => 'span', :content => 'my img title'} |
| 742 | end | 732 | end |
| 743 | 733 | ||
| 744 | - should 'not allow html on title of the images' do | ||
| 745 | - login_as(profile.identifier) | ||
| 746 | - folder = fast_create(Gallery, :profile_id => profile.id) | ||
| 747 | - file = UploadedFile.create!(:title => '<b>my img title</b>', :profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) | ||
| 748 | - | ||
| 749 | - get :view_page, :profile => profile.identifier, :page => folder.path | ||
| 750 | - | ||
| 751 | - assert_tag :tag => 'li', :attributes => {:title => 'my img title', :class => 'image-gallery-item'}, :child => {:tag => 'span', :content => 'my img title'} | ||
| 752 | - end | ||
| 753 | - | ||
| 754 | should 'allow publisher owner view private articles' do | 734 | should 'allow publisher owner view private articles' do |
| 755 | c = Community.create!(:name => 'test_com') | 735 | c = Community.create!(:name => 'test_com') |
| 756 | u = create_user_with_permission('test_user', 'publish_content', c) | 736 | u = create_user_with_permission('test_user', 'publish_content', c) |
| @@ -1209,6 +1189,7 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -1209,6 +1189,7 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
| 1209 | class Plugin2 < Noosfero::Plugin | 1189 | class Plugin2 < Noosfero::Plugin |
| 1210 | def content_remove_edit(content); false; end | 1190 | def content_remove_edit(content); false; end |
| 1211 | end | 1191 | end |
| 1192 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | ||
| 1212 | 1193 | ||
| 1213 | environment.enable_plugin(Plugin1.name) | 1194 | environment.enable_plugin(Plugin1.name) |
| 1214 | environment.enable_plugin(Plugin2.name) | 1195 | environment.enable_plugin(Plugin2.name) |
| @@ -1225,6 +1206,7 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -1225,6 +1206,7 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
| 1225 | class Plugin2 < Noosfero::Plugin | 1206 | class Plugin2 < Noosfero::Plugin |
| 1226 | def content_expire_edit(content); nil; end | 1207 | def content_expire_edit(content); nil; end |
| 1227 | end | 1208 | end |
| 1209 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | ||
| 1228 | 1210 | ||
| 1229 | environment.enable_plugin(Plugin1.name) | 1211 | environment.enable_plugin(Plugin1.name) |
| 1230 | environment.enable_plugin(Plugin2.name) | 1212 | environment.enable_plugin(Plugin2.name) |
| @@ -1270,6 +1252,7 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -1270,6 +1252,7 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
| 1270 | } | 1252 | } |
| 1271 | end | 1253 | end |
| 1272 | end | 1254 | end |
| 1255 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | ||
| 1273 | 1256 | ||
| 1274 | Environment.default.enable_plugin(Plugin1.name) | 1257 | Environment.default.enable_plugin(Plugin1.name) |
| 1275 | Environment.default.enable_plugin(Plugin2.name) | 1258 | Environment.default.enable_plugin(Plugin2.name) |
| @@ -1294,6 +1277,7 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -1294,6 +1277,7 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
| 1294 | scope.where(:referrer => 'kernel.org') | 1277 | scope.where(:referrer => 'kernel.org') |
| 1295 | end | 1278 | end |
| 1296 | end | 1279 | end |
| 1280 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | ||
| 1297 | 1281 | ||
| 1298 | Environment.default.enable_plugin(Plugin1) | 1282 | Environment.default.enable_plugin(Plugin1) |
| 1299 | Environment.default.enable_plugin(Plugin2) | 1283 | Environment.default.enable_plugin(Plugin2) |
| @@ -1351,6 +1335,7 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -1351,6 +1335,7 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
| 1351 | } | 1335 | } |
| 1352 | end | 1336 | end |
| 1353 | end | 1337 | end |
| 1338 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | ||
| 1354 | 1339 | ||
| 1355 | Environment.default.enable_plugin(Plugin1.name) | 1340 | Environment.default.enable_plugin(Plugin1.name) |
| 1356 | Environment.default.enable_plugin(Plugin2.name) | 1341 | Environment.default.enable_plugin(Plugin2.name) |
| @@ -1365,8 +1350,47 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -1365,8 +1350,47 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
| 1365 | 1350 | ||
| 1366 | should 'display link to download of non-recognized file types on its page' do | 1351 | should 'display link to download of non-recognized file types on its page' do |
| 1367 | file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/test.txt', 'bin/unknown'), :profile => profile) | 1352 | file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/test.txt', 'bin/unknown'), :profile => profile) |
| 1368 | - get :view_page, file.url.merge(:view=>:true) | ||
| 1369 | - assert_match /this is a sample text file/, @response.body | 1353 | + get :view_page, file.url |
| 1354 | + assert_match /#{file.public_filename}/, @response.body | ||
| 1355 | + end | ||
| 1356 | + | ||
| 1357 | + should 'not count hit from bots' do | ||
| 1358 | + article = fast_create(Article, :profile_id => profile.id) | ||
| 1359 | + assert_no_difference article, :hits do | ||
| 1360 | + @request.env['HTTP_USER_AGENT'] = 'bot' | ||
| 1361 | + get 'view_page', :profile => profile.identifier, :page => article.path.split('/') | ||
| 1362 | + @request.env['HTTP_USER_AGENT'] = 'spider' | ||
| 1363 | + get 'view_page', :profile => profile.identifier, :page => article.path.split('/') | ||
| 1364 | + @request.env['HTTP_USER_AGENT'] = 'crawler' | ||
| 1365 | + get 'view_page', :profile => profile.identifier, :page => article.path.split('/') | ||
| 1366 | + @request.env['HTTP_USER_AGENT'] = '(http://some-crawler.com)' | ||
| 1367 | + get 'view_page', :profile => profile.identifier, :page => article.path.split('/') | ||
| 1368 | + article.reload | ||
| 1369 | + end | ||
| 1370 | + end | ||
| 1371 | + | ||
| 1372 | + should 'add meta tags with article info' do | ||
| 1373 | + a = TinyMceArticle.create(:name => 'Article to be shared', :body => 'This article should be shared with all social networks', :profile => profile) | ||
| 1374 | + | ||
| 1375 | + get :view_page, :profile => profile.identifier, :page => [ a.name.to_slug ] | ||
| 1376 | + | ||
| 1377 | + assert_tag :tag => 'meta', :attributes => { :name => 'twitter:title', :content => /#{a.name} - #{a.profile.name}/ } | ||
| 1378 | + assert_tag :tag => 'meta', :attributes => { :name => 'twitter:description', :content => a.body } | ||
| 1379 | + assert_no_tag :tag => 'meta', :attributes => { :name => 'twitter:image' } | ||
| 1380 | + assert_tag :tag => 'meta', :attributes => { :property => 'og:type', :content => 'article' } | ||
| 1381 | + assert_tag :tag => 'meta', :attributes => { :property => 'og:url', :content => /\/#{profile.identifier}\/#{a.name.to_slug}/ } | ||
| 1382 | + assert_tag :tag => 'meta', :attributes => { :property => 'og:title', :content => /#{a.name} - #{a.profile.name}/ } | ||
| 1383 | + assert_tag :tag => 'meta', :attributes => { :property => 'og:site_name', :content => a.profile.name } | ||
| 1384 | + assert_tag :tag => 'meta', :attributes => { :property => 'og:description', :content => a.body } | ||
| 1385 | + assert_no_tag :tag => 'meta', :attributes => { :property => 'og:image' } | ||
| 1386 | + end | ||
| 1387 | + | ||
| 1388 | + should 'add meta tags with article images' do | ||
| 1389 | + a = TinyMceArticle.create(:name => 'Article to be shared with images', :body => 'This article should be shared with all social networks <img src="/images/x.png" />', :profile => profile) | ||
| 1390 | + | ||
| 1391 | + get :view_page, :profile => profile.identifier, :page => [ a.name.to_slug ] | ||
| 1392 | + assert_tag :tag => 'meta', :attributes => { :name => 'twitter:image', :content => /\/images\/x.png/ } | ||
| 1393 | + assert_tag :tag => 'meta', :attributes => { :property => 'og:image', :content => /\/images\/x.png/ } | ||
| 1370 | end | 1394 | end |
| 1371 | 1395 | ||
| 1372 | end | 1396 | end |
| @@ -0,0 +1,39 @@ | @@ -0,0 +1,39 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | + | ||
| 3 | +class EmbedControllerTest < ActionController::TestCase | ||
| 4 | + | ||
| 5 | + def setup | ||
| 6 | + login_as(create_admin_user(Environment.default)) | ||
| 7 | + @block = LoginBlock.create! | ||
| 8 | + @block.class.any_instance.stubs(:embedable?).returns(true) | ||
| 9 | + @environment = Environment.default | ||
| 10 | + @environment.boxes.create! | ||
| 11 | + @environment.boxes.first.blocks << @block | ||
| 12 | + end | ||
| 13 | + | ||
| 14 | + should 'be able to get embed block' do | ||
| 15 | + get :block, :id => @block.id | ||
| 16 | + assert_tag :tag => 'div', :attributes => { :id => "block-#{@block.id}" } | ||
| 17 | + end | ||
| 18 | + | ||
| 19 | + should 'display error message when not found block' do | ||
| 20 | + Block.delete_all | ||
| 21 | + get :block, :id => 1 | ||
| 22 | + assert_tag :tag => 'div', :attributes => { :id => "not-found" } | ||
| 23 | + end | ||
| 24 | + | ||
| 25 | + should 'display error message when block is not visible/public' do | ||
| 26 | + @block.display = 'never' | ||
| 27 | + assert @block.save | ||
| 28 | + get :block, :id => @block.id | ||
| 29 | + assert_tag :tag => 'div', :attributes => { :id => "unavailable" } | ||
| 30 | + end | ||
| 31 | + | ||
| 32 | + should 'display error message when block is not embedable' do | ||
| 33 | + @block.class.any_instance.stubs(:embedable?).returns(false) | ||
| 34 | + get :block, :id => @block.id | ||
| 35 | + assert_tag :tag => 'div', :attributes => { :id => "unavailable" } | ||
| 36 | + end | ||
| 37 | + | ||
| 38 | + | ||
| 39 | +end |
test/functional/enterprise_registration_controller_test.rb
| @@ -193,6 +193,7 @@ class EnterpriseRegistrationControllerTest < ActionController::TestCase | @@ -193,6 +193,7 @@ class EnterpriseRegistrationControllerTest < ActionController::TestCase | ||
| 193 | {'plugin2' => 'Plugin 2'} | 193 | {'plugin2' => 'Plugin 2'} |
| 194 | end | 194 | end |
| 195 | end | 195 | end |
| 196 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | ||
| 196 | 197 | ||
| 197 | environment = Environment.default | 198 | environment = Environment.default |
| 198 | environment.enable_plugin(Plugin1.name) | 199 | environment.enable_plugin(Plugin1.name) |
test/functional/environment_design_controller_test.rb
| @@ -6,6 +6,8 @@ class EnvironmentDesignController; def rescue_action(e) raise e end; end | @@ -6,6 +6,8 @@ class EnvironmentDesignController; def rescue_action(e) raise e end; end | ||
| 6 | 6 | ||
| 7 | class EnvironmentDesignControllerTest < ActionController::TestCase | 7 | class EnvironmentDesignControllerTest < ActionController::TestCase |
| 8 | 8 | ||
| 9 | + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
| 10 | + # the Noosfero core soon, see ActionItem3045 | ||
| 9 | ALL_BLOCKS = [ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ] | 11 | ALL_BLOCKS = [ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ] |
| 10 | 12 | ||
| 11 | def setup | 13 | def setup |
| @@ -83,6 +85,8 @@ class EnvironmentDesignControllerTest < ActionController::TestCase | @@ -83,6 +85,8 @@ class EnvironmentDesignControllerTest < ActionController::TestCase | ||
| 83 | assert_tag :tag => 'p', :attributes => { :id => 'no_portal_community' } | 85 | assert_tag :tag => 'p', :attributes => { :id => 'no_portal_community' } |
| 84 | end | 86 | end |
| 85 | 87 | ||
| 88 | + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
| 89 | + # the Noosfero core soon, see ActionItem3045 | ||
| 86 | should 'be able to edit EnvironmentStatisticsBlock' do | 90 | should 'be able to edit EnvironmentStatisticsBlock' do |
| 87 | login_as(create_admin_user(Environment.default)) | 91 | login_as(create_admin_user(Environment.default)) |
| 88 | b = EnvironmentStatisticsBlock.create! | 92 | b = EnvironmentStatisticsBlock.create! |
| @@ -366,4 +370,47 @@ class EnvironmentDesignControllerTest < ActionController::TestCase | @@ -366,4 +370,47 @@ class EnvironmentDesignControllerTest < ActionController::TestCase | ||
| 366 | assert @controller.instance_variable_get('@side_block_types').include?(CustomBlock8) | 370 | assert @controller.instance_variable_get('@side_block_types').include?(CustomBlock8) |
| 367 | end | 371 | end |
| 368 | 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 | + | ||
| 369 | end | 416 | end |
test/functional/events_controller_test.rb
| @@ -38,4 +38,20 @@ class EventsControllerTest < ActionController::TestCase | @@ -38,4 +38,20 @@ class EventsControllerTest < ActionController::TestCase | ||
| 38 | assert_tag :tag =>'a', :attributes => {:href => "/profile/#{profile.identifier}/events/#{next_month.year}/#{next_month.month}"}, :content => next_month_name | 38 | assert_tag :tag =>'a', :attributes => {:href => "/profile/#{profile.identifier}/events/#{next_month.year}/#{next_month.month}"}, :content => next_month_name |
| 39 | end | 39 | end |
| 40 | 40 | ||
| 41 | + should 'see the events paginated' do | ||
| 42 | + 30.times do |i| | ||
| 43 | + profile.events << Event.new(:name => "Lesson #{i}", :start_date => Date.today) | ||
| 44 | + end | ||
| 45 | + get :events, :profile => profile.identifier | ||
| 46 | + assert_equal 20, assigns(:events).count | ||
| 47 | + end | ||
| 48 | + | ||
| 49 | + should 'show events of specific day' do | ||
| 50 | + profile.events << Event.new(:name => 'Joao Birthday', :start_date => Date.new(2009, 10, 28)) | ||
| 51 | + | ||
| 52 | + get :events_by_day, :profile => profile.identifier, :year => 2009, :month => 10, :day => 28 | ||
| 53 | + | ||
| 54 | + assert_tag :tag => 'a', :content => /Joao Birthday/ | ||
| 55 | + end | ||
| 56 | + | ||
| 41 | end | 57 | end |
test/functional/friends_controller_test.rb
| @@ -68,6 +68,7 @@ class FriendsControllerTest < ActionController::TestCase | @@ -68,6 +68,7 @@ class FriendsControllerTest < ActionController::TestCase | ||
| 68 | false | 68 | false |
| 69 | end | 69 | end |
| 70 | end | 70 | end |
| 71 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | ||
| 71 | 72 | ||
| 72 | e = profile.environment | 73 | e = profile.environment |
| 73 | e.enable_plugin(Plugin1.name) | 74 | e.enable_plugin(Plugin1.name) |
test/functional/home_controller_test.rb
| @@ -107,6 +107,7 @@ class HomeControllerTest < ActionController::TestCase | @@ -107,6 +107,7 @@ class HomeControllerTest < ActionController::TestCase | ||
| 107 | proc {"<a href='plugin2'>Plugin2 link</a>"} | 107 | proc {"<a href='plugin2'>Plugin2 link</a>"} |
| 108 | end | 108 | end |
| 109 | end | 109 | end |
| 110 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | ||
| 110 | 111 | ||
| 111 | Environment.default.enable_plugin(Plugin1) | 112 | Environment.default.enable_plugin(Plugin1) |
| 112 | Environment.default.enable_plugin(Plugin2) | 113 | Environment.default.enable_plugin(Plugin2) |
| @@ -129,6 +130,7 @@ class HomeControllerTest < ActionController::TestCase | @@ -129,6 +130,7 @@ class HomeControllerTest < ActionController::TestCase | ||
| 129 | true | 130 | true |
| 130 | end | 131 | end |
| 131 | end | 132 | end |
| 133 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | ||
| 132 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new]) | 134 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new]) |
| 133 | 135 | ||
| 134 | get :index | 136 | get :index |
test/functional/invite_controller_test.rb
| @@ -7,6 +7,7 @@ class InviteControllerTest < ActionController::TestCase | @@ -7,6 +7,7 @@ class InviteControllerTest < ActionController::TestCase | ||
| 7 | @friend = create_user('thefriend').person | 7 | @friend = create_user('thefriend').person |
| 8 | @community = fast_create(Community) | 8 | @community = fast_create(Community) |
| 9 | login_as ('testuser') | 9 | login_as ('testuser') |
| 10 | + Delayed::Job.destroy_all | ||
| 10 | end | 11 | end |
| 11 | attr_accessor :profile, :friend, :community | 12 | attr_accessor :profile, :friend, :community |
| 12 | 13 | ||
| @@ -230,7 +231,8 @@ class InviteControllerTest < ActionController::TestCase | @@ -230,7 +231,8 @@ class InviteControllerTest < ActionController::TestCase | ||
| 230 | 231 | ||
| 231 | contact_list = ContactList.create | 232 | contact_list = ContactList.create |
| 232 | post :select_friends, :profile => profile.identifier, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "manual", :mail_template => "click: <url>", :contact_list => contact_list.id | 233 | post :select_friends, :profile => profile.identifier, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "manual", :mail_template => "click: <url>", :contact_list => contact_list.id |
| 233 | - assert_equal 'pt', Delayed::Job.first.payload_object.locale | 234 | + job = Delayed::Job.where("handler LIKE '%InvitationJob%'").first |
| 235 | + assert_equal 'pt', job.payload_object.locale | ||
| 234 | end | 236 | end |
| 235 | 237 | ||
| 236 | private | 238 | private |
test/functional/memberships_controller_test.rb
| @@ -234,6 +234,7 @@ class MembershipsControllerTest < ActionController::TestCase | @@ -234,6 +234,7 @@ class MembershipsControllerTest < ActionController::TestCase | ||
| 234 | {'plugin2' => 'Plugin 2'} | 234 | {'plugin2' => 'Plugin 2'} |
| 235 | end | 235 | end |
| 236 | end | 236 | end |
| 237 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) | ||
| 237 | 238 | ||
| 238 | environment = Environment.default | 239 | environment = Environment.default |
| 239 | environment.enable_plugin(Plugin1.name) | 240 | environment.enable_plugin(Plugin1.name) |
test/functional/plugins_controller_test.rb
| @@ -47,7 +47,7 @@ class PluginsControllerTest < ActionController::TestCase | @@ -47,7 +47,7 @@ class PluginsControllerTest < ActionController::TestCase | ||
| 47 | end | 47 | end |
| 48 | end | 48 | end |
| 49 | 49 | ||
| 50 | - Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s,Plugin2.to_s]) | 50 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s]) |
| 51 | 51 | ||
| 52 | get :index | 52 | get :index |
| 53 | 53 |
test/functional/profile_controller_test.rb
| @@ -766,21 +766,25 @@ class ProfileControllerTest < ActionController::TestCase | @@ -766,21 +766,25 @@ class ProfileControllerTest < ActionController::TestCase | ||
| 766 | p1= fast_create(Person) | 766 | p1= fast_create(Person) |
| 767 | p2= fast_create(Person) | 767 | p2= fast_create(Person) |
| 768 | assert !p1.is_a_friend?(p2) | 768 | assert !p1.is_a_friend?(p2) |
| 769 | + | ||
| 769 | p3= fast_create(Person) | 770 | p3= fast_create(Person) |
| 770 | p3.add_friend(p1) | 771 | p3.add_friend(p1) |
| 771 | assert p3.is_a_friend?(p1) | 772 | assert p3.is_a_friend?(p1) |
| 772 | - ActionTracker::Record.destroy_all | 773 | + |
| 774 | + ActionTracker::Record.delete_all | ||
| 775 | + | ||
| 773 | UserStampSweeper.any_instance.stubs(:current_user).returns(p1) | 776 | UserStampSweeper.any_instance.stubs(:current_user).returns(p1) |
| 774 | - create(Scrap, defaults_for_scrap(:sender => p1, :receiver => p1)) | 777 | + create(Scrap,defaults_for_scrap(:sender => p1, :receiver => p1)) |
| 775 | a1 = ActionTracker::Record.last | 778 | a1 = ActionTracker::Record.last |
| 779 | + | ||
| 776 | UserStampSweeper.any_instance.stubs(:current_user).returns(p2) | 780 | UserStampSweeper.any_instance.stubs(:current_user).returns(p2) |
| 777 | create(Scrap, defaults_for_scrap(:sender => p2, :receiver => p3)) | 781 | create(Scrap, defaults_for_scrap(:sender => p2, :receiver => p3)) |
| 778 | a2 = ActionTracker::Record.last | 782 | a2 = ActionTracker::Record.last |
| 783 | + | ||
| 779 | UserStampSweeper.any_instance.stubs(:current_user).returns(p3) | 784 | UserStampSweeper.any_instance.stubs(:current_user).returns(p3) |
| 780 | create(Scrap, defaults_for_scrap(:sender => p3, :receiver => p1)) | 785 | create(Scrap, defaults_for_scrap(:sender => p3, :receiver => p1)) |
| 781 | a3 = ActionTracker::Record.last | 786 | a3 = ActionTracker::Record.last |
| 782 | 787 | ||
| 783 | - | ||
| 784 | @controller.stubs(:logged_in?).returns(true) | 788 | @controller.stubs(:logged_in?).returns(true) |
| 785 | user = mock() | 789 | user = mock() |
| 786 | user.stubs(:person).returns(p3) | 790 | user.stubs(:person).returns(p3) |
| @@ -790,24 +794,29 @@ class ProfileControllerTest < ActionController::TestCase | @@ -790,24 +794,29 @@ class ProfileControllerTest < ActionController::TestCase | ||
| 790 | 794 | ||
| 791 | process_delayed_job_queue | 795 | process_delayed_job_queue |
| 792 | get :index, :profile => p1.identifier | 796 | get :index, :profile => p1.identifier |
| 793 | - assert_not_nil assigns(:network_activities) | ||
| 794 | - assert_equivalent [a1,a3], assigns(:network_activities) | 797 | + |
| 798 | + assert_equivalent [a1,a3].map(&:id), assigns(:network_activities).map(&:id) | ||
| 795 | end | 799 | end |
| 796 | 800 | ||
| 797 | should 'the network activity be visible only to profile followers' do | 801 | should 'the network activity be visible only to profile followers' do |
| 798 | p1= fast_create(Person) | 802 | p1= fast_create(Person) |
| 799 | p2= fast_create(Person) | 803 | p2= fast_create(Person) |
| 800 | assert !p1.is_a_friend?(p2) | 804 | assert !p1.is_a_friend?(p2) |
| 805 | + | ||
| 801 | p3= fast_create(Person) | 806 | p3= fast_create(Person) |
| 802 | p3.add_friend(p1) | 807 | p3.add_friend(p1) |
| 803 | assert p3.is_a_friend?(p1) | 808 | assert p3.is_a_friend?(p1) |
| 804 | - ActionTracker::Record.destroy_all | 809 | + |
| 810 | + ActionTracker::Record.delete_all | ||
| 811 | + | ||
| 805 | UserStampSweeper.any_instance.stubs(:current_user).returns(p1) | 812 | UserStampSweeper.any_instance.stubs(:current_user).returns(p1) |
| 806 | create(Scrap, defaults_for_scrap(:sender => p1, :receiver => p1)) | 813 | create(Scrap, defaults_for_scrap(:sender => p1, :receiver => p1)) |
| 807 | a1 = ActionTracker::Record.last | 814 | a1 = ActionTracker::Record.last |
| 815 | + | ||
| 808 | UserStampSweeper.any_instance.stubs(:current_user).returns(p2) | 816 | UserStampSweeper.any_instance.stubs(:current_user).returns(p2) |
| 809 | create(Scrap, defaults_for_scrap(:sender => p2, :receiver => p3)) | 817 | create(Scrap, defaults_for_scrap(:sender => p2, :receiver => p3)) |
| 810 | a2 = ActionTracker::Record.last | 818 | a2 = ActionTracker::Record.last |
| 819 | + | ||
| 811 | UserStampSweeper.any_instance.stubs(:current_user).returns(p3) | 820 | UserStampSweeper.any_instance.stubs(:current_user).returns(p3) |
| 812 | create(Scrap, defaults_for_scrap(:sender => p3, :receiver => p1)) | 821 | create(Scrap, defaults_for_scrap(:sender => p3, :receiver => p1)) |
| 813 | a3 = ActionTracker::Record.last | 822 | a3 = ActionTracker::Record.last |
| @@ -817,8 +826,9 @@ class ProfileControllerTest < ActionController::TestCase | @@ -817,8 +826,9 @@ class ProfileControllerTest < ActionController::TestCase | ||
| 817 | user.stubs(:person).returns(p2) | 826 | user.stubs(:person).returns(p2) |
| 818 | user.stubs(:login).returns('some') | 827 | user.stubs(:login).returns('some') |
| 819 | @controller.stubs(:current_user).returns(user) | 828 | @controller.stubs(:current_user).returns(user) |
| 829 | + | ||
| 820 | get :index, :profile => p1.identifier | 830 | get :index, :profile => p1.identifier |
| 821 | - assert_equal [], assigns(:network_activities) | 831 | + assert assigns(:network_activities).blank? |
| 822 | 832 | ||
| 823 | user = mock() | 833 | user = mock() |
| 824 | user.stubs(:person).returns(p3) | 834 | user.stubs(:person).returns(p3) |
| @@ -826,6 +836,7 @@ class ProfileControllerTest < ActionController::TestCase | @@ -826,6 +836,7 @@ class ProfileControllerTest < ActionController::TestCase | ||
| 826 | @controller.stubs(:current_user).returns(user) | 836 | @controller.stubs(:current_user).returns(user) |
| 827 | Person.any_instance.stubs(:follows?).returns(true) | 837 | Person.any_instance.stubs(:follows?).returns(true) |
| 828 | process_delayed_job_queue | 838 | process_delayed_job_queue |
| 839 | + | ||
| 829 | get :index, :profile => p3.identifier | 840 | get :index, :profile => p3.identifier |
| 830 | assert_equivalent [a1,a3], assigns(:network_activities) | 841 | assert_equivalent [a1,a3], assigns(:network_activities) |
| 831 | end | 842 | end |
| @@ -1241,6 +1252,7 @@ class ProfileControllerTest < ActionController::TestCase | @@ -1241,6 +1252,7 @@ class ProfileControllerTest < ActionController::TestCase | ||
| 1241 | {:title => 'Plugin2 tab', :id => 'plugin2_tab', :content => proc { 'Content from plugin2.' }} | 1252 | {:title => 'Plugin2 tab', :id => 'plugin2_tab', :content => proc { 'Content from plugin2.' }} |
| 1242 | end | 1253 | end |
| 1243 | end | 1254 | end |
| 1255 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s]) | ||
| 1244 | 1256 | ||
| 1245 | e = profile.environment | 1257 | e = profile.environment |
| 1246 | e.enable_plugin(Plugin1.name) | 1258 | e.enable_plugin(Plugin1.name) |
test/functional/profile_design_controller_test.rb
| @@ -173,7 +173,8 @@ class ProfileDesignControllerTest < ActionController::TestCase | @@ -173,7 +173,8 @@ class ProfileDesignControllerTest < ActionController::TestCase | ||
| 173 | should 'have options to display blocks' do | 173 | should 'have options to display blocks' do |
| 174 | get :edit, :profile => 'designtestuser', :id => @b1.id | 174 | get :edit, :profile => 'designtestuser', :id => @b1.id |
| 175 | %w[always home_page_only except_home_page never].each do |option| | 175 | %w[always home_page_only except_home_page never].each do |option| |
| 176 | - assert_tag :input, :attributes => { :type => 'radio', :value => option} | 176 | + assert_tag :select, :attributes => {:name => 'block[display]'}, |
| 177 | + :descendant => {:tag => 'option', :attributes => {:value => option}} | ||
| 177 | end | 178 | end |
| 178 | end | 179 | end |
| 179 | 180 | ||
| @@ -302,24 +303,42 @@ class ProfileDesignControllerTest < ActionController::TestCase | @@ -302,24 +303,42 @@ class ProfileDesignControllerTest < ActionController::TestCase | ||
| 302 | 303 | ||
| 303 | should 'not edit main block with never option' do | 304 | should 'not edit main block with never option' do |
| 304 | get :edit, :profile => 'designtestuser', :id => @b4.id | 305 | get :edit, :profile => 'designtestuser', :id => @b4.id |
| 305 | - assert_no_tag :input, :attributes => { :type => 'radio', :value => 'never'} | 306 | + assert_no_tag :select, :attributes => {:name => 'block[display]'}, |
| 307 | + :descendant => {:tag => 'option', :attributes => {:value => 'never'}} | ||
| 306 | end | 308 | end |
| 307 | 309 | ||
| 308 | should 'not edit main block with home_page_only option' do | 310 | should 'not edit main block with home_page_only option' do |
| 309 | get :edit, :profile => 'designtestuser', :id => @b4.id | 311 | get :edit, :profile => 'designtestuser', :id => @b4.id |
| 310 | - assert_no_tag :input, :attributes => { :type => 'radio', :value => 'home_page_only'} | 312 | + assert_no_tag :select, :attributes => {:name => 'block[display]'}, |
| 313 | + :descendant => {:tag => 'option', :attributes => {:value => 'home_page_only'}} | ||
| 311 | end | 314 | end |
| 312 | 315 | ||
| 313 | should 'edit main block with always option' do | 316 | should 'edit main block with always option' do |
| 314 | get :edit, :profile => 'designtestuser', :id => @b4.id | 317 | get :edit, :profile => 'designtestuser', :id => @b4.id |
| 315 | - assert_tag :input, :attributes => { :type => 'radio', :value => 'always'} | 318 | + assert_tag :select, :attributes => {:name => 'block[display]'}, |
| 319 | + :descendant => {:tag => 'option', :attributes => {:value => 'always'}} | ||
| 316 | end | 320 | end |
| 317 | 321 | ||
| 318 | should 'edit main block with except_home_page option' do | 322 | should 'edit main block with except_home_page option' do |
| 319 | get :edit, :profile => 'designtestuser', :id => @b4.id | 323 | get :edit, :profile => 'designtestuser', :id => @b4.id |
| 320 | - assert_tag :input, :attributes => { :type => 'radio', :value => 'except_home_page'} | 324 | + assert_tag :select, :attributes => {:name=> 'block[display]'}, |
| 325 | + :descendant => {:tag => 'option', :attributes => {:value => 'except_home_page'}} | ||
| 321 | end | 326 | end |
| 322 | 327 | ||
| 328 | + should 'return a list of paths related to the words used in the query search' do | ||
| 329 | + article1 = fast_create(Article, :profile_id => @profile.id, :name => "Some thing") | ||
| 330 | + article2 = fast_create(Article, :profile_id => @profile.id, :name => "Some article") | ||
| 331 | + article3 = fast_create(Article, :profile_id => @profile.id, :name => "Not an article") | ||
| 332 | + | ||
| 333 | + xhr :get, :search_autocomplete, :profile => 'designtestuser' , :query => 'Some' | ||
| 334 | + | ||
| 335 | + json_response = ActiveSupport::JSON.decode(@response.body) | ||
| 336 | + | ||
| 337 | + assert_response :success | ||
| 338 | + assert_equal json_response.include?("/{profile}/"+article1.path), true | ||
| 339 | + assert_equal json_response.include?("/{profile}/"+article2.path), true | ||
| 340 | + assert_equal json_response.include?("/{profile}/"+article3.path), false | ||
| 341 | + end | ||
| 323 | 342 | ||
| 324 | ###################################################### | 343 | ###################################################### |
| 325 | # END - tests for BoxOrganizerController features | 344 | # END - tests for BoxOrganizerController features |
| @@ -739,7 +758,7 @@ class ProfileDesignControllerTest < ActionController::TestCase | @@ -739,7 +758,7 @@ class ProfileDesignControllerTest < ActionController::TestCase | ||
| 739 | should 'clone a block' do | 758 | should 'clone a block' do |
| 740 | block = create(ProfileImageBlock, :box => profile.boxes.first) | 759 | block = create(ProfileImageBlock, :box => profile.boxes.first) |
| 741 | assert_difference 'ProfileImageBlock.count', 1 do | 760 | assert_difference 'ProfileImageBlock.count', 1 do |
| 742 | - post :clone, :id => block.id, :profile => profile.identifier | 761 | + post :clone_block, :id => block.id, :profile => profile.identifier |
| 743 | assert_response :redirect | 762 | assert_response :redirect |
| 744 | end | 763 | end |
| 745 | end | 764 | end |
test/functional/profile_editor_controller_test.rb
| @@ -73,7 +73,8 @@ class ProfileEditorControllerTest < ActionController::TestCase | @@ -73,7 +73,8 @@ class ProfileEditorControllerTest < ActionController::TestCase | ||
| 73 | get :edit, :profile => profile.identifier | 73 | get :edit, :profile => profile.identifier |
| 74 | assert_response :success | 74 | assert_response :success |
| 75 | assert_template 'edit' | 75 | assert_template 'edit' |
| 76 | - assert_tag :tag => 'input', :attributes => {:name => 'profile_data[category_ids][]', :value => cat2.id} | 76 | + assert_tag :tag => 'input', :attributes => {:name => 'profile_data[category_ids][]'} |
| 77 | + assert_tag :tag => 'a', :attributes => { :class => 'select-subcategory-link', :id => "select-category-#{cat1.id}-link" } | ||
| 77 | end | 78 | end |
| 78 | 79 | ||
| 79 | should 'save categorization of profile' do | 80 | should 'save categorization of profile' do |
| @@ -237,7 +238,7 @@ class ProfileEditorControllerTest < ActionController::TestCase | @@ -237,7 +238,7 @@ class ProfileEditorControllerTest < ActionController::TestCase | ||
| 237 | cat2 = Environment.default.categories.create!(:display_in_menu => true, :name => 'sub category', :parent_id => cat1.id) | 238 | cat2 = Environment.default.categories.create!(:display_in_menu => true, :name => 'sub category', :parent_id => cat1.id) |
| 238 | person = create_user('testuser').person | 239 | person = create_user('testuser').person |
| 239 | get :edit, :profile => 'testuser' | 240 | get :edit, :profile => 'testuser' |
| 240 | - assert_tag :tag => 'input', :attributes => { :type => 'checkbox', :name => 'profile_data[category_ids][]', :value => cat2.id} | 241 | + assert_tag :tag => 'a', :attributes => { :class => 'select-subcategory-link', :id => "select-category-#{cat1.id}-link" } |
| 241 | end | 242 | end |
| 242 | 243 | ||
| 243 | should 'render edit template' do | 244 | should 'render edit template' do |
| @@ -868,6 +869,7 @@ class ProfileEditorControllerTest < ActionController::TestCase | @@ -868,6 +869,7 @@ class ProfileEditorControllerTest < ActionController::TestCase | ||
| 868 | {:title => "Plugin2 button", :icon => 'plugin2_icon', :url => 'plugin2_url'} | 869 | {:title => "Plugin2 button", :icon => 'plugin2_icon', :url => 'plugin2_url'} |
| 869 | end | 870 | end |
| 870 | end | 871 | end |
| 872 | + Noosfero::Plugin.stubs(:all).returns([TestControlPanelButtons1.to_s, TestControlPanelButtons2.to_s]) | ||
| 871 | 873 | ||
| 872 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestControlPanelButtons1.new, TestControlPanelButtons2.new]) | 874 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestControlPanelButtons1.new, TestControlPanelButtons2.new]) |
| 873 | 875 | ||
| @@ -883,6 +885,7 @@ class ProfileEditorControllerTest < ActionController::TestCase | @@ -883,6 +885,7 @@ class ProfileEditorControllerTest < ActionController::TestCase | ||
| 883 | "<input id='field_added_by_plugin' value='value_of_field_added_by_plugin'/>" | 885 | "<input id='field_added_by_plugin' value='value_of_field_added_by_plugin'/>" |
| 884 | end | 886 | end |
| 885 | end | 887 | end |
| 888 | + Noosfero::Plugin.stubs(:all).returns([TestProfileEditPlugin.to_s]) | ||
| 886 | 889 | ||
| 887 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestProfileEditPlugin.new]) | 890 | Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestProfileEditPlugin.new]) |
| 888 | 891 | ||
| @@ -911,6 +914,7 @@ class ProfileEditorControllerTest < ActionController::TestCase | @@ -911,6 +914,7 @@ class ProfileEditorControllerTest < ActionController::TestCase | ||
| 911 | proc {"<strong>Plugin2 text</strong>"} | 914 | proc {"<strong>Plugin2 text</strong>"} |
| 912 | end | 915 | end |
| 913 | end | 916 | end |
| 917 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s]) | ||
| 914 | 918 | ||
| 915 | Environment.default.enable_plugin(Plugin1) | 919 | Environment.default.enable_plugin(Plugin1) |
| 916 | Environment.default.enable_plugin(Plugin2) | 920 | Environment.default.enable_plugin(Plugin2) |
| @@ -932,6 +936,7 @@ class ProfileEditorControllerTest < ActionController::TestCase | @@ -932,6 +936,7 @@ class ProfileEditorControllerTest < ActionController::TestCase | ||
| 932 | proc {"<strong>Plugin2 text</strong>"} | 936 | proc {"<strong>Plugin2 text</strong>"} |
| 933 | end | 937 | end |
| 934 | end | 938 | end |
| 939 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s]) | ||
| 935 | 940 | ||
| 936 | Environment.default.enable_plugin(Plugin1) | 941 | Environment.default.enable_plugin(Plugin1) |
| 937 | Environment.default.enable_plugin(Plugin2) | 942 | Environment.default.enable_plugin(Plugin2) |
test/functional/search_controller_test.rb
| @@ -76,14 +76,14 @@ class SearchControllerTest < ActionController::TestCase | @@ -76,14 +76,14 @@ class SearchControllerTest < ActionController::TestCase | ||
| 76 | assert_includes assigns(:searches)[:articles][:results], art | 76 | assert_includes assigns(:searches)[:articles][:results], art |
| 77 | end | 77 | end |
| 78 | 78 | ||
| 79 | - should 'redirect contents to articles' do | 79 | + should 'redirect contents to articles' do |
| 80 | person = fast_create(Person) | 80 | person = fast_create(Person) |
| 81 | art = create_article_with_optional_category('an article to be found', person) | 81 | art = create_article_with_optional_category('an article to be found', person) |
| 82 | 82 | ||
| 83 | get 'contents', :query => 'article found' | 83 | get 'contents', :query => 'article found' |
| 84 | - # full description to avoid deprecation warning | 84 | + # full description to avoid deprecation warning |
| 85 | assert_redirected_to :controller => :search, :action => :articles, :query => 'article found' | 85 | assert_redirected_to :controller => :search, :action => :articles, :query => 'article found' |
| 86 | - end | 86 | + end |
| 87 | 87 | ||
| 88 | # 'assets' outside any category | 88 | # 'assets' outside any category |
| 89 | should 'list articles in general' do | 89 | should 'list articles in general' do |
| @@ -167,6 +167,7 @@ class SearchControllerTest < ActionController::TestCase | @@ -167,6 +167,7 @@ class SearchControllerTest < ActionController::TestCase | ||
| 167 | proc {"<span id='plugin2'>This is Plugin2 speaking!</span>"} | 167 | proc {"<span id='plugin2'>This is Plugin2 speaking!</span>"} |
| 168 | end | 168 | end |
| 169 | end | 169 | end |
| 170 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s]) | ||
| 170 | 171 | ||
| 171 | enterprise = fast_create(Enterprise) | 172 | enterprise = fast_create(Enterprise) |
| 172 | prod_cat = fast_create(ProductCategory) | 173 | prod_cat = fast_create(ProductCategory) |
| @@ -193,6 +194,7 @@ class SearchControllerTest < ActionController::TestCase | @@ -193,6 +194,7 @@ class SearchControllerTest < ActionController::TestCase | ||
| 193 | return { :name => _('Property2'), :content => proc { link_to(product.name, '/plugin2') } } | 194 | return { :name => _('Property2'), :content => proc { link_to(product.name, '/plugin2') } } |
| 194 | end | 195 | end |
| 195 | end | 196 | end |
| 197 | + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s]) | ||
| 196 | enterprise = fast_create(Enterprise) | 198 | enterprise = fast_create(Enterprise) |
| 197 | prod_cat = fast_create(ProductCategory) | 199 | prod_cat = fast_create(ProductCategory) |
| 198 | product = fast_create(Product, {:profile_id => enterprise.id, :name => "produto1", :product_category_id => prod_cat.id}, :search => true) | 200 | product = fast_create(Product, {:profile_id => enterprise.id, :name => "produto1", :product_category_id => prod_cat.id}, :search => true) |
| @@ -261,10 +263,10 @@ class SearchControllerTest < ActionController::TestCase | @@ -261,10 +263,10 @@ class SearchControllerTest < ActionController::TestCase | ||
| 261 | 263 | ||
| 262 | should 'render specific action when only one asset is enabled' do | 264 | should 'render specific action when only one asset is enabled' do |
| 263 | environment = Environment.default | 265 | environment = Environment.default |
| 264 | - # article is not disabled | 266 | + # article is not disabled |
| 265 | [:enterprises, :people, :communities, :products, :events].select do |key, name| | 267 | [:enterprises, :people, :communities, :products, :events].select do |key, name| |
| 266 | - environment.enable('disable_asset_' + key.to_s) | ||
| 267 | - end | 268 | + environment.enable('disable_asset_' + key.to_s) |
| 269 | + end | ||
| 268 | environment.save! | 270 | environment.save! |
| 269 | @controller.stubs(:environment).returns(environment) | 271 | @controller.stubs(:environment).returns(environment) |
| 270 | 272 | ||
| @@ -276,25 +278,25 @@ class SearchControllerTest < ActionController::TestCase | @@ -276,25 +278,25 @@ class SearchControllerTest < ActionController::TestCase | ||
| 276 | assert !assigns(:searches).has_key?(:communities) | 278 | assert !assigns(:searches).has_key?(:communities) |
| 277 | assert !assigns(:searches).has_key?(:products) | 279 | assert !assigns(:searches).has_key?(:products) |
| 278 | assert !assigns(:searches).has_key?(:events) | 280 | assert !assigns(:searches).has_key?(:events) |
| 279 | - end | 281 | + end |
| 280 | 282 | ||
| 281 | should 'search all enabled assets in general search' do | 283 | should 'search all enabled assets in general search' do |
| 282 | ent1 = create_profile_with_optional_category(Enterprise, 'test enterprise') | 284 | ent1 = create_profile_with_optional_category(Enterprise, 'test enterprise') |
| 283 | prod_cat = create(ProductCategory, :name => 'pctest', :environment => Environment.default) | 285 | prod_cat = create(ProductCategory, :name => 'pctest', :environment => Environment.default) |
| 284 | prod = ent1.products.create!(:name => 'test product', :product_category => prod_cat) | 286 | prod = ent1.products.create!(:name => 'test product', :product_category => prod_cat) |
| 285 | - art = create(Article, :name => 'test article', :profile_id => fast_create(Person).id) | ||
| 286 | - per = create(Person, :name => 'test person', :identifier => 'test-person', :user_id => fast_create(User).id) | ||
| 287 | - com = Community.create!(:name => 'test community') | ||
| 288 | - eve = create(Event, :name => 'test event', :profile_id => fast_create(Person).id) | 287 | + art = create(Article, :name => 'test article', :profile_id => fast_create(Person).id) |
| 288 | + per = create(Person, :name => 'test person', :identifier => 'test-person', :user_id => fast_create(User).id) | ||
| 289 | + com = create(Community, :name => 'test community') | ||
| 290 | + eve = create(Event, :name => 'test event', :profile_id => fast_create(Person).id) | ||
| 289 | 291 | ||
| 290 | get :index, :query => 'test' | 292 | get :index, :query => 'test' |
| 291 | 293 | ||
| 292 | [:articles, :enterprises, :people, :communities, :products, :events].select do |key, name| | 294 | [:articles, :enterprises, :people, :communities, :products, :events].select do |key, name| |
| 293 | - !assigns(:environment).enabled?('disable_asset_' + key.to_s) | ||
| 294 | - end.each do |asset| | ||
| 295 | - assert !assigns(:searches)[asset][:results].empty? | ||
| 296 | - end | ||
| 297 | - end | 295 | + !assigns(:environment).enabled?('disable_asset_' + key.to_s) |
| 296 | + end.each do |asset| | ||
| 297 | + assert !assigns(:searches)[asset][:results].empty? | ||
| 298 | + end | ||
| 299 | + end | ||
| 298 | 300 | ||
| 299 | should 'display category image while in directory' do | 301 | should 'display category image while in directory' do |
| 300 | parent = Category.create!(:name => 'category1', :environment => Environment.default) | 302 | parent = Category.create!(:name => 'category1', :environment => Environment.default) |
| @@ -320,8 +322,8 @@ class SearchControllerTest < ActionController::TestCase | @@ -320,8 +322,8 @@ class SearchControllerTest < ActionController::TestCase | ||
| 320 | person = create_user('someone').person | 322 | person = create_user('someone').person |
| 321 | ten_days_ago = Date.today - 10.day | 323 | ten_days_ago = Date.today - 10.day |
| 322 | 324 | ||
| 323 | - ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], :start_date => ten_days_ago) | ||
| 324 | - ev2 = create_event(person, :name => 'event 2', :category_ids => [@category.id], :start_date => Date.today - 2.month) | 325 | + ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], :start_date => ten_days_ago) |
| 326 | + ev2 = create_event(person, :name => 'event 2', :category_ids => [@category.id], :start_date => Date.today - 2.month) | ||
| 325 | 327 | ||
| 326 | get :events, :day => ten_days_ago.day, :month => ten_days_ago.month, :year => ten_days_ago.year | 328 | get :events, :day => ten_days_ago.day, :month => ten_days_ago.month, :year => ten_days_ago.year |
| 327 | assert_equal [ev1], assigns(:events) | 329 | assert_equal [ev1], assigns(:events) |
| @@ -331,7 +333,7 @@ class SearchControllerTest < ActionController::TestCase | @@ -331,7 +333,7 @@ class SearchControllerTest < ActionController::TestCase | ||
| 331 | person = create_user('someone').person | 333 | person = create_user('someone').person |
| 332 | ten_days_ago = Date.today - 10.day | 334 | ten_days_ago = Date.today - 10.day |
| 333 | 335 | ||
| 334 | - ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], :start_date => ten_days_ago) | 336 | + ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], :start_date => ten_days_ago) |
| 335 | ev2 = create_event(person, :name => 'event 2', :start_date => ten_days_ago) | 337 | ev2 = create_event(person, :name => 'event 2', :start_date => ten_days_ago) |
| 336 | 338 | ||
| 337 | get :events, :day => ten_days_ago.day, :month => ten_days_ago.month, :year => ten_days_ago.year, :category_path => @category.path.split('/') | 339 | get :events, :day => ten_days_ago.day, :month => ten_days_ago.month, :year => ten_days_ago.year, :category_path => @category.path.split('/') |
| @@ -341,8 +343,8 @@ class SearchControllerTest < ActionController::TestCase | @@ -341,8 +343,8 @@ class SearchControllerTest < ActionController::TestCase | ||
| 341 | 343 | ||
| 342 | should 'return events of today when no date specified' do | 344 | should 'return events of today when no date specified' do |
| 343 | person = create_user('someone').person | 345 | person = create_user('someone').person |
| 344 | - ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], :start_date => Date.today) | ||
| 345 | - ev2 = create_event(person, :name => 'event 2', :category_ids => [@category.id], :start_date => Date.today - 2.month) | 346 | + ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], :start_date => Date.today) |
| 347 | + ev2 = create_event(person, :name => 'event 2', :category_ids => [@category.id], :start_date => Date.today - 2.month) | ||
| 346 | 348 | ||
| 347 | get :events | 349 | get :events |
| 348 | 350 | ||
| @@ -353,9 +355,9 @@ class SearchControllerTest < ActionController::TestCase | @@ -353,9 +355,9 @@ class SearchControllerTest < ActionController::TestCase | ||
| 353 | person = create_user('someone').person | 355 | person = create_user('someone').person |
| 354 | 356 | ||
| 355 | ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], | 357 | ev1 = create_event(person, :name => 'event 1', :category_ids => [@category.id], |
| 356 | - :start_date => Date.today + 2.month) | 358 | + :start_date => Date.today + 2.month) |
| 357 | ev2 = create_event(person, :name => 'event 2', :category_ids => [@category.id], | 359 | ev2 = create_event(person, :name => 'event 2', :category_ids => [@category.id], |
| 358 | - :start_date => Date.today + 2.day) | 360 | + :start_date => Date.today + 2.day) |
| 359 | 361 | ||
| 360 | get :events | 362 | get :events |
| 361 | 363 | ||
| @@ -374,6 +376,15 @@ class SearchControllerTest < ActionController::TestCase | @@ -374,6 +376,15 @@ class SearchControllerTest < ActionController::TestCase | ||
| 374 | assert_equal [ 'upcoming event 1' ], assigns(:searches)[:events][:results].map(&:name) | 376 | assert_equal [ 'upcoming event 1' ], assigns(:searches)[:events][:results].map(&:name) |
| 375 | end | 377 | end |
| 376 | 378 | ||
| 379 | + should 'see the events paginated' do | ||
| 380 | + person = create_user('testuser').person | ||
| 381 | + 30.times do |i| | ||
| 382 | + create_event(person, :name => "Event #{i}", :start_date => Date.today) | ||
| 383 | + end | ||
| 384 | + get :events | ||
| 385 | + assert_equal 20, assigns(:events).count | ||
| 386 | + end | ||
| 387 | + | ||
| 377 | %w[ people enterprises articles events communities products ].each do |asset| | 388 | %w[ people enterprises articles events communities products ].each do |asset| |
| 378 | should "render asset-specific template when searching for #{asset}" do | 389 | should "render asset-specific template when searching for #{asset}" do |
| 379 | get "#{asset}" | 390 | get "#{asset}" |
| @@ -427,8 +438,8 @@ class SearchControllerTest < ActionController::TestCase | @@ -427,8 +438,8 @@ class SearchControllerTest < ActionController::TestCase | ||
| 427 | end | 438 | end |
| 428 | 439 | ||
| 429 | should 'show link to article asset in the see all foot link of the articles block in the category page' do | 440 | should 'show link to article asset in the see all foot link of the articles block in the category page' do |
| 430 | - (1..SearchController::MULTIPLE_SEARCH_LIMIT+1).each do |i| | ||
| 431 | - a = create_user("test#{i}").person.articles.create!(:name => "article #{i} to be found") | 441 | + (1..SearchController::MULTIPLE_SEARCH_LIMIT+1).each do |i| |
| 442 | + a = create_user("test#{i}").person.articles.create!(:name => "article #{i} to be found") | ||
| 432 | ArticleCategorization.add_category_to_article(@category, a) | 443 | ArticleCategorization.add_category_to_article(@category, a) |
| 433 | end | 444 | end |
| 434 | 445 | ||
| @@ -553,9 +564,9 @@ class SearchControllerTest < ActionController::TestCase | @@ -553,9 +564,9 @@ class SearchControllerTest < ActionController::TestCase | ||
| 553 | c2 = create(Community, :name => 'Testing community 2') | 564 | c2 = create(Community, :name => 'Testing community 2') |
| 554 | c3 = create(Community, :name => 'Testing community 3') | 565 | c3 = create(Community, :name => 'Testing community 3') |
| 555 | ActionTracker::Record.delete_all | 566 | ActionTracker::Record.delete_all |
| 556 | - fast_create(ActionTracker::Record, :target_id => c1, :user_type => 'Profile', :user_id => person, :created_at => Time.now) | ||
| 557 | - fast_create(ActionTracker::Record, :target_id => c2, :user_type => 'Profile', :user_id => person, :created_at => Time.now) | ||
| 558 | - fast_create(ActionTracker::Record, :target_id => c2, :user_type => 'Profile', :user_id => person, :created_at => Time.now) | 567 | + ActionTracker::Record.create!(:target => c1, :user => person, :created_at => Time.now, :verb => 'leave_scrap') |
| 568 | + ActionTracker::Record.create!(:target => c2, :user => person, :created_at => Time.now, :verb => 'leave_scrap') | ||
| 569 | + ActionTracker::Record.create!(:target => c2, :user => person, :created_at => Time.now, :verb => 'leave_scrap') | ||
| 559 | get :communities, :filter => 'more_active' | 570 | get :communities, :filter => 'more_active' |
| 560 | assert_equal [c2,c1,c3] , assigns(:searches)[:communities][:results] | 571 | assert_equal [c2,c1,c3] , assigns(:searches)[:communities][:results] |
| 561 | end | 572 | end |
| @@ -574,55 +585,55 @@ class SearchControllerTest < ActionController::TestCase | @@ -574,55 +585,55 @@ class SearchControllerTest < ActionController::TestCase | ||
| 574 | assert_not_includes assigns(:searches)[:communities][:results], p1 | 585 | assert_not_includes assigns(:searches)[:communities][:results], p1 |
| 575 | end | 586 | end |
| 576 | 587 | ||
| 577 | - should 'keep old urls working' do | ||
| 578 | - get :assets, :asset => 'articles' | 588 | + should 'keep old urls working' do |
| 589 | + get :assets, :asset => 'articles' | ||
| 579 | assert_redirected_to :controller => :search, :action => :articles | 590 | assert_redirected_to :controller => :search, :action => :articles |
| 580 | - get :assets, :asset => 'people' | 591 | + get :assets, :asset => 'people' |
| 581 | assert_redirected_to :controller => :search, :action => :people | 592 | assert_redirected_to :controller => :search, :action => :people |
| 582 | - get :assets, :asset => 'communities' | 593 | + get :assets, :asset => 'communities' |
| 583 | assert_redirected_to :controller => :search, :action => :communities | 594 | assert_redirected_to :controller => :search, :action => :communities |
| 584 | - get :assets, :asset => 'products' | 595 | + get :assets, :asset => 'products' |
| 585 | assert_redirected_to :controller => :search, :action => :products | 596 | assert_redirected_to :controller => :search, :action => :products |
| 586 | - get :assets, :asset => 'enterprises' | 597 | + get :assets, :asset => 'enterprises' |
| 587 | assert_redirected_to :controller => :search, :action => :enterprises | 598 | assert_redirected_to :controller => :search, :action => :enterprises |
| 588 | - get :assets, :asset => 'events' | 599 | + get :assets, :asset => 'events' |
| 589 | assert_redirected_to :controller => :search, :action => :events | 600 | assert_redirected_to :controller => :search, :action => :events |
| 590 | - end | 601 | + end |
| 591 | 602 | ||
| 592 | - should 'show tag cloud' do | ||
| 593 | - @controller.stubs(:is_cache_expired?).returns(true) | 603 | + should 'show tag cloud' do |
| 604 | + @controller.stubs(:is_cache_expired?).returns(true) | ||
| 594 | a = create(Article, :name => 'my article', :profile_id => fast_create(Person).id) | 605 | a = create(Article, :name => 'my article', :profile_id => fast_create(Person).id) |
| 595 | a.tag_list = ['one', 'two'] | 606 | a.tag_list = ['one', 'two'] |
| 596 | - a.save_tags | 607 | + a.save_tags |
| 597 | 608 | ||
| 598 | - get :tags | 609 | + get :tags |
| 599 | 610 | ||
| 600 | - assert assigns(:tags)["two"] = 1 | ||
| 601 | - assert assigns(:tags)["one"] = 1 | ||
| 602 | - end | 611 | + assert assigns(:tags)["two"] = 1 |
| 612 | + assert assigns(:tags)["one"] = 1 | ||
| 613 | + end | ||
| 603 | 614 | ||
| 604 | should 'show tagged content' do | 615 | should 'show tagged content' do |
| 605 | - @controller.stubs(:is_cache_expired?).returns(true) | 616 | + @controller.stubs(:is_cache_expired?).returns(true) |
| 606 | a = Article.create!(:name => 'my article', :profile => fast_create(Person)) | 617 | a = Article.create!(:name => 'my article', :profile => fast_create(Person)) |
| 607 | a2 = Article.create!(:name => 'my article 2', :profile => fast_create(Person)) | 618 | a2 = Article.create!(:name => 'my article 2', :profile => fast_create(Person)) |
| 608 | a.tag_list = ['one', 'two'] | 619 | a.tag_list = ['one', 'two'] |
| 609 | a2.tag_list = ['two', 'three'] | 620 | a2.tag_list = ['two', 'three'] |
| 610 | - a.save_tags | 621 | + a.save_tags |
| 611 | a2.save_tags | 622 | a2.save_tags |
| 612 | 623 | ||
| 613 | - get :tag, :tag => 'two' | 624 | + get :tag, :tag => 'two' |
| 614 | 625 | ||
| 615 | assert_equivalent [a, a2], assigns(:searches)[:tag][:results] | 626 | assert_equivalent [a, a2], assigns(:searches)[:tag][:results] |
| 616 | 627 | ||
| 617 | - get :tag, :tag => 'one' | 628 | + get :tag, :tag => 'one' |
| 618 | 629 | ||
| 619 | assert_equivalent [a], assigns(:searches)[:tag][:results] | 630 | assert_equivalent [a], assigns(:searches)[:tag][:results] |
| 620 | end | 631 | end |
| 621 | 632 | ||
| 622 | should 'not show assets from other environments' do | 633 | should 'not show assets from other environments' do |
| 623 | other_env = Environment.create!(:name => 'Another environment') | 634 | other_env = Environment.create!(:name => 'Another environment') |
| 624 | - p1 = create(Person, :name => 'Hildebrando', :identifier => 'hild', :user_id => fast_create(User).id, :environment_id => other_env.id) | ||
| 625 | - p2 = create(Person, :name => 'Adamastor', :identifier => 'adam', :user_id => fast_create(User).id) | 635 | + p1 = create(Person, :name => 'Hildebrando', :identifier => 'hild', :user_id => fast_create(User).id, :environment_id => other_env.id) |
| 636 | + p2 = create(Person, :name => 'Adamastor', :identifier => 'adam', :user_id => fast_create(User).id) | ||
| 626 | art1 = create(Article, :name => 'my article', :profile_id => p1.id) | 637 | art1 = create(Article, :name => 'my article', :profile_id => p1.id) |
| 627 | art2 = create(Article, :name => 'my article', :profile_id => p2.id) | 638 | art2 = create(Article, :name => 'my article', :profile_id => p2.id) |
| 628 | 639 | ||
| @@ -633,9 +644,9 @@ class SearchControllerTest < ActionController::TestCase | @@ -633,9 +644,9 @@ class SearchControllerTest < ActionController::TestCase | ||
| 633 | 644 | ||
| 634 | should 'order articles by more recent' do | 645 | should 'order articles by more recent' do |
| 635 | Article.destroy_all | 646 | Article.destroy_all |
| 636 | - art1 = create(Article, :name => 'review C', :profile_id => fast_create(Person).id, :created_at => Time.now-1.days) | ||
| 637 | - art2 = create(Article, :name => 'review A', :profile_id => fast_create(Person).id, :created_at => Time.now) | ||
| 638 | - art3 = create(Article, :name => 'review B', :profile_id => fast_create(Person).id, :created_at => Time.now-2.days) | 647 | + art1 = create(Article, :name => 'review C', :profile_id => fast_create(Person).id, :created_at => Time.now-1.days) |
| 648 | + art2 = create(Article, :name => 'review A', :profile_id => fast_create(Person).id, :created_at => Time.now) | ||
| 649 | + art3 = create(Article, :name => 'review B', :profile_id => fast_create(Person).id, :created_at => Time.now-2.days) | ||
| 639 | 650 | ||
| 640 | get :articles, :filter => :more_recent | 651 | get :articles, :filter => :more_recent |
| 641 | 652 |
test/functional/users_controller_test.rb
| @@ -133,4 +133,20 @@ class UsersControllerTest < ActionController::TestCase | @@ -133,4 +133,20 @@ class UsersControllerTest < ActionController::TestCase | ||
| 133 | assert_equal 'name;email', @response.body.split("\n")[0] | 133 | assert_equal 'name;email', @response.body.split("\n")[0] |
| 134 | end | 134 | end |
| 135 | 135 | ||
| 136 | + should 'be able to remove a person' do | ||
| 137 | + person = fast_create(Person, :environment_id => environment.id) | ||
| 138 | + assert_difference Person, :count, -1 do | ||
| 139 | + post :destroy_user, :id => person.id | ||
| 140 | + end | ||
| 141 | + end | ||
| 142 | + | ||
| 143 | + should 'not crash if user does not exist' do | ||
| 144 | + person = fast_create(Person) | ||
| 145 | + | ||
| 146 | + assert_no_difference Person, :count do | ||
| 147 | + post :destroy_user, :id => 99999 | ||
| 148 | + end | ||
| 149 | + assert_redirected_to :action => 'index' | ||
| 150 | + end | ||
| 151 | + | ||
| 136 | end | 152 | end |
test/integration/routing_test.rb
| @@ -268,5 +268,8 @@ class RoutingTest < ActionController::IntegrationTest | @@ -268,5 +268,8 @@ class RoutingTest < ActionController::IntegrationTest | ||
| 268 | assert_routing('http://www.example.com/work/free-software/versions', :controller => 'content_viewer', :action => 'article_versions', :page => 'work/free-software') | 268 | assert_routing('http://www.example.com/work/free-software/versions', :controller => 'content_viewer', :action => 'article_versions', :page => 'work/free-software') |
| 269 | end | 269 | end |
| 270 | 270 | ||
| 271 | + should 'have route to get HTML code of Blocks to embed' do | ||
| 272 | + assert_routing('/embed/block/12345', :controller => 'embed', :action => 'block', :id => '12345') | ||
| 273 | + end | ||
| 271 | 274 | ||
| 272 | end | 275 | end |
test/test_helper.rb
| @@ -184,7 +184,7 @@ class ActiveSupport::TestCase | @@ -184,7 +184,7 @@ class ActiveSupport::TestCase | ||
| 184 | if reference.first == value | 184 | if reference.first == value |
| 185 | reference.shift | 185 | reference.shift |
| 186 | else | 186 | else |
| 187 | - assert false, "'#{value}' was found before it should be on: #{original.inspect}" | 187 | + assert false, "'#{value.inspect}' was found before it should be on: #{original.inspect}" |
| 188 | end | 188 | end |
| 189 | end | 189 | end |
| 190 | end | 190 | end |
| @@ -0,0 +1,21 @@ | @@ -0,0 +1,21 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | + | ||
| 3 | +class AccountHelperTest < ActiveSupport::TestCase | ||
| 4 | + | ||
| 5 | + include AccountHelper | ||
| 6 | + include ActionView::Helpers::TagHelper | ||
| 7 | + | ||
| 8 | + should 'not suggest usernames if username is empty' do | ||
| 9 | + assert_equal '', suggestion_based_on_username | ||
| 10 | + end | ||
| 11 | + | ||
| 12 | + should 'suggest valid usernames' do | ||
| 13 | + ze = create_user('ze').person | ||
| 14 | + stubs(:environment).returns(ze.environment) | ||
| 15 | + suggestions = suggestion_based_on_username('ze') | ||
| 16 | + suggestions.each do |suggestion| | ||
| 17 | + assert_equal true, Person.is_available?(suggestion, ze.environment) | ||
| 18 | + end | ||
| 19 | + end | ||
| 20 | + | ||
| 21 | +end |
| @@ -0,0 +1,64 @@ | @@ -0,0 +1,64 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | + | ||
| 3 | +class ActionTrackerExtTest < ActiveSupport::TestCase | ||
| 4 | + should 'increase person activities_count on new activity' do | ||
| 5 | + person = fast_create(Person) | ||
| 6 | + assert_difference person, :activities_count, 1 do | ||
| 7 | + ActionTracker::Record.create! :verb => :leave_scrap, :user => person, :target => fast_create(Profile) | ||
| 8 | + person.reload | ||
| 9 | + end | ||
| 10 | + end | ||
| 11 | + | ||
| 12 | + should 'decrease person activities_count on activity removal' do | ||
| 13 | + person = fast_create(Person) | ||
| 14 | + record = ActionTracker::Record.create! :verb => :leave_scrap, :user => person, :target => fast_create(Profile) | ||
| 15 | + person.reload | ||
| 16 | + assert_difference person, :activities_count, -1 do | ||
| 17 | + record.destroy | ||
| 18 | + person.reload | ||
| 19 | + end | ||
| 20 | + end | ||
| 21 | + | ||
| 22 | + should 'not decrease person activities_count on activity removal after the recent delay' do | ||
| 23 | + person = fast_create(Person) | ||
| 24 | + record = ActionTracker::Record.create! :verb => :leave_scrap, :user => person, :target => fast_create(Profile) | ||
| 25 | + record.created_at = record.created_at - ActionTracker::Record::RECENT_DELAY.days - 1.day | ||
| 26 | + record.save! | ||
| 27 | + person.reload | ||
| 28 | + assert_no_difference person, :activities_count do | ||
| 29 | + record.destroy | ||
| 30 | + person.reload | ||
| 31 | + end | ||
| 32 | + end | ||
| 33 | + | ||
| 34 | + should 'increase organization activities_count on new activity' do | ||
| 35 | + person = fast_create(Person) | ||
| 36 | + organization = fast_create(Organization) | ||
| 37 | + assert_difference organization, :activities_count, 1 do | ||
| 38 | + ActionTracker::Record.create! :verb => :leave_scrap, :user => person, :target => organization | ||
| 39 | + organization.reload | ||
| 40 | + end | ||
| 41 | + end | ||
| 42 | + | ||
| 43 | + should 'decrease organization activities_count on activity removal' do | ||
| 44 | + person = fast_create(Person) | ||
| 45 | + organization = fast_create(Organization) | ||
| 46 | + record = ActionTracker::Record.create! :verb => :leave_scrap, :user => person, :target => organization | ||
| 47 | + organization.reload | ||
| 48 | + assert_difference organization, :activities_count, -1 do | ||
| 49 | + record.destroy | ||
| 50 | + organization.reload | ||
| 51 | + end | ||
| 52 | + end | ||
| 53 | + | ||
| 54 | + should 'not decrease organization activities_count on activity removal after the recent delay' do | ||
| 55 | + person = fast_create(Person) | ||
| 56 | + organization = fast_create(Organization) | ||
| 57 | + record = ActionTracker::Record.create! :verb => :leave_scrap, :user => person, :target => organization, :created_at => (ActionTracker::Record::RECENT_DELAY + 1).days.ago | ||
| 58 | + organization.reload | ||
| 59 | + assert_no_difference organization, :activities_count do | ||
| 60 | + record.destroy | ||
| 61 | + organization.reload | ||
| 62 | + end | ||
| 63 | + end | ||
| 64 | +end |
| @@ -0,0 +1,36 @@ | @@ -0,0 +1,36 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | + | ||
| 3 | +class ActivitiesCounterCacheJobTest < ActiveSupport::TestCase | ||
| 4 | + | ||
| 5 | + should 'correctly update the person activities counter cache' do | ||
| 6 | + person = create_user('person').person | ||
| 7 | + ActionTracker::Record.create!(:user => person, :verb => 'create_article') | ||
| 8 | + ActionTracker::Record.create!(:user => person, :verb => 'create_article') | ||
| 9 | + person.reload | ||
| 10 | + assert_equal 2, person.activities_count | ||
| 11 | + | ||
| 12 | + person.activities_count = 0 | ||
| 13 | + person.save! | ||
| 14 | + job = ActivitiesCounterCacheJob.new | ||
| 15 | + job.perform | ||
| 16 | + person.reload | ||
| 17 | + assert_equal 2, person.activities_count | ||
| 18 | + end | ||
| 19 | + | ||
| 20 | + should 'correctly update the organization activities counter cache' do | ||
| 21 | + person = create_user('person').person | ||
| 22 | + organization = Organization.create!(:name => 'Organization1', :identifier => 'organization1') | ||
| 23 | + ActionTracker::Record.create!(:user => person, :verb => 'create_article', :target => organization) | ||
| 24 | + ActionTracker::Record.create!(:user => person, :verb => 'create_article', :target => organization) | ||
| 25 | + organization.reload | ||
| 26 | + assert_equal 2, organization.activities_count | ||
| 27 | + | ||
| 28 | + organization.activities_count = 0 | ||
| 29 | + organization.save! | ||
| 30 | + job = ActivitiesCounterCacheJob.new | ||
| 31 | + job.perform | ||
| 32 | + organization.reload | ||
| 33 | + assert_equal 2, organization.activities_count | ||
| 34 | + end | ||
| 35 | + | ||
| 36 | +end |
test/unit/acts_as_having_settings_test.rb
| @@ -80,4 +80,38 @@ class ActsAsHavingSettingsTest < ActiveSupport::TestCase | @@ -80,4 +80,38 @@ class ActsAsHavingSettingsTest < ActiveSupport::TestCase | ||
| 80 | assert obj.save | 80 | assert obj.save |
| 81 | end | 81 | end |
| 82 | 82 | ||
| 83 | + should 'setting_changed be true if a setting passed as parameter was changed' do | ||
| 84 | + obj = TestClass.new | ||
| 85 | + obj.flag = true | ||
| 86 | + assert obj.setting_changed? 'flag' | ||
| 87 | + end | ||
| 88 | + | ||
| 89 | + should 'setting_changed be false if a setting passed as parameter was not changed' do | ||
| 90 | + obj = TestClass.new | ||
| 91 | + assert !obj.setting_changed?('flag') | ||
| 92 | + end | ||
| 93 | + | ||
| 94 | + should 'setting_changed be false if a setting passed as parameter was changed with the same value' do | ||
| 95 | + obj = TestClass.new | ||
| 96 | + obj.flag = true | ||
| 97 | + obj.save | ||
| 98 | + obj.flag = true | ||
| 99 | + assert !obj.setting_changed?('flag') | ||
| 100 | + end | ||
| 101 | + | ||
| 102 | + should 'setting_changed be false if a setting passed as parameter was not changed but another setting is changed' do | ||
| 103 | + obj = TestClass.new(:name => 'some name') | ||
| 104 | + obj.save | ||
| 105 | + obj.name = 'antoher nme' | ||
| 106 | + assert !obj.setting_changed?('flag') | ||
| 107 | + end | ||
| 108 | + | ||
| 109 | + should 'setting_changed be true for all changed fields' do | ||
| 110 | + obj = TestClass.new(:name => 'some name', :flag => false) | ||
| 111 | + obj.save | ||
| 112 | + obj.name = 'another nme' | ||
| 113 | + obj.flag = true | ||
| 114 | + assert obj.setting_changed?('flag') | ||
| 115 | + assert obj.setting_changed?('name') | ||
| 116 | + end | ||
| 83 | end | 117 | end |
test/unit/application_helper_test.rb
| @@ -452,6 +452,22 @@ class ApplicationHelperTest < ActionView::TestCase | @@ -452,6 +452,22 @@ class ApplicationHelperTest < ActionView::TestCase | ||
| 452 | assert_match(/Community nick/, page_title) | 452 | assert_match(/Community nick/, page_title) |
| 453 | end | 453 | end |
| 454 | 454 | ||
| 455 | + should 'not display environment name if is a profile' do | ||
| 456 | + stubs(:environment).returns(Environment.default) | ||
| 457 | + @controller = ApplicationController.new | ||
| 458 | + | ||
| 459 | + c = fast_create(Community, :name => 'Community for tests', :nickname => 'Community nick', :identifier => 'test_comm') | ||
| 460 | + stubs(:profile).returns(c) | ||
| 461 | + assert_equal c.short_name, page_title | ||
| 462 | + end | ||
| 463 | + | ||
| 464 | + should 'display only environment if no profile and page' do | ||
| 465 | + stubs(:environment).returns(Environment.default) | ||
| 466 | + @controller = ApplicationController.new | ||
| 467 | + | ||
| 468 | + assert_equal Environment.default.name, page_title | ||
| 469 | + end | ||
| 470 | + | ||
| 455 | should 'gravatar default parameter' do | 471 | should 'gravatar default parameter' do |
| 456 | profile = mock | 472 | profile = mock |
| 457 | profile.stubs(:theme).returns('some-theme') | 473 | profile.stubs(:theme).returns('some-theme') |
| @@ -646,6 +662,7 @@ class ApplicationHelperTest < ActionView::TestCase | @@ -646,6 +662,7 @@ class ApplicationHelperTest < ActionView::TestCase | ||
| 646 | should 'parse macros' do | 662 | should 'parse macros' do |
| 647 | class Plugin1 < Noosfero::Plugin | 663 | class Plugin1 < Noosfero::Plugin |
| 648 | end | 664 | end |
| 665 | + Noosfero::Plugin.stubs(:all).returns(['ApplicationHelperTest::Plugin1']) | ||
| 649 | 666 | ||
| 650 | class Plugin1::Macro1 < Noosfero::Plugin::Macro | 667 | class Plugin1::Macro1 < Noosfero::Plugin::Macro |
| 651 | def parse(params, inner_html, source) | 668 | def parse(params, inner_html, source) |
test/unit/article_test.rb
| @@ -1632,10 +1632,10 @@ class ArticleTest < ActiveSupport::TestCase | @@ -1632,10 +1632,10 @@ class ArticleTest < ActiveSupport::TestCase | ||
| 1632 | 1632 | ||
| 1633 | should 'not allow all community members to edit by default' do | 1633 | should 'not allow all community members to edit by default' do |
| 1634 | community = fast_create(Community) | 1634 | community = fast_create(Community) |
| 1635 | - admin = create_user('community-admin').person | ||
| 1636 | - member = create_user.person | ||
| 1637 | - | 1635 | + admin = fast_create(Person) |
| 1636 | + member = fast_create(Person) | ||
| 1638 | community.add_admin(admin) | 1637 | community.add_admin(admin) |
| 1638 | + community.reload | ||
| 1639 | community.add_member(member) | 1639 | community.add_member(member) |
| 1640 | a = build(Article, :profile => community) | 1640 | a = build(Article, :profile => community) |
| 1641 | 1641 |
test/unit/block_test.rb
| @@ -222,4 +222,66 @@ class BlockTest < ActiveSupport::TestCase | @@ -222,4 +222,66 @@ class BlockTest < ActiveSupport::TestCase | ||
| 222 | assert block.visible?(2) | 222 | assert block.visible?(2) |
| 223 | assert !block.visible?(3) | 223 | assert !block.visible?(3) |
| 224 | end | 224 | end |
| 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 | + | ||
| 281 | + should 'accept user as parameter on cache_key without change its value' do | ||
| 282 | + person = fast_create(Person) | ||
| 283 | + block = Block.new | ||
| 284 | + assert_equal block.cache_key('en'), block.cache_key('en', person) | ||
| 285 | + end | ||
| 286 | + | ||
| 225 | end | 287 | end |
test/unit/box_test.rb
| @@ -33,6 +33,8 @@ class BoxTest < ActiveSupport::TestCase | @@ -33,6 +33,8 @@ class BoxTest < ActiveSupport::TestCase | ||
| 33 | assert blocks.include?('categories-block') | 33 | assert blocks.include?('categories-block') |
| 34 | assert blocks.include?('communities-block') | 34 | assert blocks.include?('communities-block') |
| 35 | assert blocks.include?('enterprises-block') | 35 | assert blocks.include?('enterprises-block') |
| 36 | + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
| 37 | + # the Noosfero core soon, see ActionItem3045 | ||
| 36 | assert blocks.include?('environment-statistics-block') | 38 | assert blocks.include?('environment-statistics-block') |
| 37 | assert blocks.include?('fans-block') | 39 | assert blocks.include?('fans-block') |
| 38 | assert blocks.include?('favorite-enterprises-block') | 40 | assert blocks.include?('favorite-enterprises-block') |
| @@ -65,6 +67,8 @@ class BoxTest < ActiveSupport::TestCase | @@ -65,6 +67,8 @@ class BoxTest < ActiveSupport::TestCase | ||
| 65 | assert blocks.include?('communities-block') | 67 | assert blocks.include?('communities-block') |
| 66 | assert blocks.include?('disabled-enterprise-message-block') | 68 | assert blocks.include?('disabled-enterprise-message-block') |
| 67 | assert blocks.include?('enterprises-block') | 69 | assert blocks.include?('enterprises-block') |
| 70 | + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
| 71 | + # the Noosfero core soon, see ActionItem3045 | ||
| 68 | assert blocks.include?('environment-statistics-block') | 72 | assert blocks.include?('environment-statistics-block') |
| 69 | assert blocks.include?('fans-block') | 73 | assert blocks.include?('fans-block') |
| 70 | assert blocks.include?('favorite-enterprises-block') | 74 | assert blocks.include?('favorite-enterprises-block') |
test/unit/boxes_helper_test.rb
| @@ -53,6 +53,7 @@ class BoxesHelperTest < ActionView::TestCase | @@ -53,6 +53,7 @@ class BoxesHelperTest < ActionView::TestCase | ||
| 53 | expects(:display_block).with(b, '') | 53 | expects(:display_block).with(b, '') |
| 54 | stubs(:request).returns(request) | 54 | stubs(:request).returns(request) |
| 55 | stubs(:block_target).returns('') | 55 | stubs(:block_target).returns('') |
| 56 | + stubs(:user).returns(nil) | ||
| 56 | expects(:locale).returns('en') | 57 | expects(:locale).returns('en') |
| 57 | with_box_decorator self do | 58 | with_box_decorator self do |
| 58 | display_box_content(box, '') | 59 | display_box_content(box, '') |
| @@ -72,6 +73,7 @@ class BoxesHelperTest < ActionView::TestCase | @@ -72,6 +73,7 @@ class BoxesHelperTest < ActionView::TestCase | ||
| 72 | box.save! | 73 | box.save! |
| 73 | expects(:display_block).with(b, '').never | 74 | expects(:display_block).with(b, '').never |
| 74 | stubs(:request).returns(request) | 75 | stubs(:request).returns(request) |
| 76 | + stubs(:user).returns(nil) | ||
| 75 | stubs(:block_target).returns('') | 77 | stubs(:block_target).returns('') |
| 76 | expects(:locale).returns('en') | 78 | expects(:locale).returns('en') |
| 77 | display_box_content(box, '') | 79 | display_box_content(box, '') |
| @@ -110,8 +112,9 @@ class BoxesHelperTest < ActionView::TestCase | @@ -110,8 +112,9 @@ class BoxesHelperTest < ActionView::TestCase | ||
| 110 | request.expects(:path).returns('/') | 112 | request.expects(:path).returns('/') |
| 111 | request.expects(:params).returns({}) | 113 | request.expects(:params).returns({}) |
| 112 | stubs(:request).returns(request) | 114 | stubs(:request).returns(request) |
| 115 | + stubs(:user).returns(nil) | ||
| 113 | expects(:locale).returns('en') | 116 | expects(:locale).returns('en') |
| 114 | - box_decorator.expects(:select_blocks).with([], {:article => nil, :request_path => '/', :locale => 'en', :params => {}}).returns([]) | 117 | + box_decorator.expects(:select_blocks).with([], {:article => nil, :request_path => '/', :locale => 'en', :params => {}, :user => nil}).returns([]) |
| 115 | 118 | ||
| 116 | display_box_content(box, '') | 119 | display_box_content(box, '') |
| 117 | end | 120 | end |
test/unit/comment_test.rb
| @@ -468,8 +468,8 @@ class CommentTest < ActiveSupport::TestCase | @@ -468,8 +468,8 @@ class CommentTest < ActiveSupport::TestCase | ||
| 468 | end | 468 | end |
| 469 | end | 469 | end |
| 470 | 470 | ||
| 471 | - | ||
| 472 | should 'delegate spam detection to plugins' do | 471 | should 'delegate spam detection to plugins' do |
| 472 | + Noosfero::Plugin.stubs(:all).returns(['CommentTest::EverythingIsSpam']) | ||
| 473 | Environment.default.enable_plugin(EverythingIsSpam) | 473 | Environment.default.enable_plugin(EverythingIsSpam) |
| 474 | 474 | ||
| 475 | c1 = create_comment | 475 | c1 = create_comment |
| @@ -495,6 +495,7 @@ class CommentTest < ActiveSupport::TestCase | @@ -495,6 +495,7 @@ class CommentTest < ActiveSupport::TestCase | ||
| 495 | end | 495 | end |
| 496 | 496 | ||
| 497 | should 'notify plugins of comments being marked as spam' do | 497 | should 'notify plugins of comments being marked as spam' do |
| 498 | + Noosfero::Plugin.stubs(:all).returns(['CommentTest::SpamNotification']) | ||
| 498 | Environment.default.enable_plugin(SpamNotification) | 499 | Environment.default.enable_plugin(SpamNotification) |
| 499 | 500 | ||
| 500 | c = create_comment | 501 | c = create_comment |
| @@ -506,6 +507,7 @@ class CommentTest < ActiveSupport::TestCase | @@ -506,6 +507,7 @@ class CommentTest < ActiveSupport::TestCase | ||
| 506 | end | 507 | end |
| 507 | 508 | ||
| 508 | should 'notify plugins of comments being marked as ham' do | 509 | should 'notify plugins of comments being marked as ham' do |
| 510 | + Noosfero::Plugin.stubs(:all).returns(['CommentTest::SpamNotification']) | ||
| 509 | Environment.default.enable_plugin(SpamNotification) | 511 | Environment.default.enable_plugin(SpamNotification) |
| 510 | 512 | ||
| 511 | c = create_comment | 513 | c = create_comment |
test/unit/community_test.rb
| @@ -216,8 +216,8 @@ class CommunityTest < ActiveSupport::TestCase | @@ -216,8 +216,8 @@ class CommunityTest < ActiveSupport::TestCase | ||
| 216 | community = fast_create(Community) | 216 | community = fast_create(Community) |
| 217 | community.closed = true | 217 | community.closed = true |
| 218 | community.save | 218 | community.save |
| 219 | - | ||
| 220 | community.add_member(fast_create(Person)) | 219 | community.add_member(fast_create(Person)) |
| 220 | + community.reload | ||
| 221 | 221 | ||
| 222 | community.stubs(:notification_emails).returns(['sample@example.org']) | 222 | community.stubs(:notification_emails).returns(['sample@example.org']) |
| 223 | 223 |
test/unit/contact_sender_test.rb
| @@ -16,7 +16,7 @@ class ContactSenderTest < ActiveSupport::TestCase | @@ -16,7 +16,7 @@ class ContactSenderTest < ActiveSupport::TestCase | ||
| 16 | ent.contact_email = 'contact@invalid.com' | 16 | ent.contact_email = 'contact@invalid.com' |
| 17 | c = build(Contact, :dest => ent) | 17 | c = build(Contact, :dest => ent) |
| 18 | response = Contact::Sender.notification(c).deliver | 18 | response = Contact::Sender.notification(c).deliver |
| 19 | - assert_equal Environment.default.contact_email, response.from.first.to_s | 19 | + assert_equal Environment.default.noreply_email, response.from.first.to_s |
| 20 | assert_equal "[#{ent.name}] #{c.subject}", response.subject | 20 | assert_equal "[#{ent.name}] #{c.subject}", response.subject |
| 21 | end | 21 | end |
| 22 | 22 | ||
| @@ -27,7 +27,7 @@ class ContactSenderTest < ActiveSupport::TestCase | @@ -27,7 +27,7 @@ class ContactSenderTest < ActiveSupport::TestCase | ||
| 27 | response = Contact::Sender.notification(c).deliver | 27 | response = Contact::Sender.notification(c).deliver |
| 28 | assert_includes response.to, c.dest.contact_email | 28 | assert_includes response.to, c.dest.contact_email |
| 29 | end | 29 | end |
| 30 | - | 30 | + |
| 31 | should 'deliver mail to admins of enterprise' do | 31 | should 'deliver mail to admins of enterprise' do |
| 32 | admin = create_user('admin_test').person | 32 | admin = create_user('admin_test').person |
| 33 | ent = Environment.default.enterprises.create!(:name => 'my enterprise', :identifier => 'myent') | 33 | ent = Environment.default.enterprises.create!(:name => 'my enterprise', :identifier => 'myent') |
test/unit/contact_test.rb
| @@ -44,11 +44,14 @@ class ContactTest < ActiveSupport::TestCase | @@ -44,11 +44,14 @@ class ContactTest < ActiveSupport::TestCase | ||
| 44 | assert !c.deliver | 44 | assert !c.deliver |
| 45 | end | 45 | end |
| 46 | 46 | ||
| 47 | - should 'use sender name and environment contact_email on from' do | 47 | + should 'use sender name and environment noreply_email on from' do |
| 48 | ent = fast_create(Enterprise, :name => 'my enterprise', :identifier => 'myent') | 48 | ent = fast_create(Enterprise, :name => 'my enterprise', :identifier => 'myent') |
| 49 | + env = ent.environment | ||
| 50 | + env.noreply_email = 'noreply@sample.org' | ||
| 51 | + env.save! | ||
| 49 | c = Contact.new(:name => 'john', :email => 'john@invalid.com', :subject => 'hi', :message => 'hi, all', :dest => ent) | 52 | c = Contact.new(:name => 'john', :email => 'john@invalid.com', :subject => 'hi', :message => 'hi, all', :dest => ent) |
| 50 | email = c.deliver | 53 | email = c.deliver |
| 51 | - assert_equal "#{c.name} <#{ent.environment.contact_email}>", email['from'].to_s | 54 | + assert_equal "#{c.name} <#{ent.environment.noreply_email}>", email['from'].to_s |
| 52 | end | 55 | end |
| 53 | 56 | ||
| 54 | should 'add dest name on subject' do | 57 | should 'add dest name on subject' do |
test/unit/content_viewer_helper_test.rb
| @@ -89,38 +89,6 @@ class ContentViewerHelperTest < ActionView::TestCase | @@ -89,38 +89,6 @@ class ContentViewerHelperTest < ActionView::TestCase | ||
| 89 | assert_no_match /feed/, result | 89 | assert_no_match /feed/, result |
| 90 | end | 90 | end |
| 91 | 91 | ||
| 92 | - should 'generate facebook addthis url for article' do | ||
| 93 | - Environment.any_instance.stubs(:default_hostname).returns('noosfero.org') | ||
| 94 | - [TextileArticle, Blog, Folder, Gallery, UploadedFile, Forum, Event, TextArticle, TinyMceArticle].each do |model| | ||
| 95 | - a = build(model, :body => 'Some text here.', :profile => profile) | ||
| 96 | - assert_equal "http://www.facebook.com/sharer.php?s=100&p[title]=#{a.name.gsub(' ','+')}&p[summary]=Some+text+here.&p[url]=http%3A%2F%2Fnoosfero.org%2Fblog_helper_test%2F#{a.slug}&p[images][0]=", addthis_facebook_url(a) | ||
| 97 | - end | ||
| 98 | - end | ||
| 99 | - | ||
| 100 | - should 'generate facebook addthis url without body' do | ||
| 101 | - Environment.any_instance.stubs(:default_hostname).returns('noosfero.org') | ||
| 102 | - a = build(TinyMceArticle, :body => nil, :profile => profile) | ||
| 103 | - assert_equal "http://www.facebook.com/sharer.php?s=100&p[title]=#{a.name.gsub(' ','+')}&p[summary]=&p[url]=http%3A%2F%2Fnoosfero.org%2Fblog_helper_test%2F#{a.slug}&p[images][0]=", addthis_facebook_url(a) | ||
| 104 | - end | ||
| 105 | - | ||
| 106 | - should 'generate facebook addthis url without tags in body' do | ||
| 107 | - Environment.any_instance.stubs(:default_hostname).returns('noosfero.org') | ||
| 108 | - a = build(TinyMceArticle, :body => '<p>This <b class="bold">is</b> a test</p>', :profile => profile) | ||
| 109 | - assert_equal "http://www.facebook.com/sharer.php?s=100&p[title]=#{a.name.gsub(' ','+')}&p[summary]=This+is+a+test&p[url]=http%3A%2F%2Fnoosfero.org%2Fblog_helper_test%2F#{a.slug}&p[images][0]=", addthis_facebook_url(a) | ||
| 110 | - end | ||
| 111 | - | ||
| 112 | - should 'generate facebook addthis url with truncated body' do | ||
| 113 | - Environment.any_instance.stubs(:default_hostname).returns('noosfero.org') | ||
| 114 | - a = build(TinyMceArticle, :body => 'test' * 76, :profile => profile) | ||
| 115 | - assert_equal "http://www.facebook.com/sharer.php?s=100&p[title]=#{a.name.gsub(' ','+')}&p[summary]=#{'test' * 74}t...&p[url]=http%3A%2F%2Fnoosfero.org%2Fblog_helper_test%2F#{a.slug}&p[images][0]=", addthis_facebook_url(a) | ||
| 116 | - end | ||
| 117 | - | ||
| 118 | - should 'generate facebook addthis url for tinymce article with images' do | ||
| 119 | - Environment.any_instance.stubs(:default_hostname).returns('noosfero.org') | ||
| 120 | - a = build(TinyMceArticle, :body => '<p>This <b class="bold">is</b> a <img src="/images/x.png" />test</p>', :profile => profile) | ||
| 121 | - assert_equal "http://www.facebook.com/sharer.php?s=100&p[title]=#{a.name.gsub(' ','+')}&p[summary]=This+is+a+test&p[url]=http%3A%2F%2Fnoosfero.org%2Fblog_helper_test%2F#{a.slug}&p[images][0]=http%3A%2F%2Fnoosfero.org%2Fimages%2Fx.png", addthis_facebook_url(a) | ||
| 122 | - end | ||
| 123 | - | ||
| 124 | should 'theme provides addthis custom icon' do | 92 | should 'theme provides addthis custom icon' do |
| 125 | stubs(:session).returns({:theme => 'base'}) | 93 | stubs(:session).returns({:theme => 'base'}) |
| 126 | File.expects(:exists?).with(anything).returns(true) | 94 | File.expects(:exists?).with(anything).returns(true) |
test/unit/enterprise_test.rb
| @@ -101,6 +101,7 @@ class EnterpriseTest < ActiveSupport::TestCase | @@ -101,6 +101,7 @@ class EnterpriseTest < ActiveSupport::TestCase | ||
| 101 | enterprise = fast_create(Enterprise) | 101 | enterprise = fast_create(Enterprise) |
| 102 | member = fast_create(Person) | 102 | member = fast_create(Person) |
| 103 | enterprise.add_member(member) | 103 | enterprise.add_member(member) |
| 104 | + enterprise.reload | ||
| 104 | 105 | ||
| 105 | person = fast_create(Person) | 106 | person = fast_create(Person) |
| 106 | enterprise.stubs(:notification_emails).returns(['sample@example.org']) | 107 | enterprise.stubs(:notification_emails).returns(['sample@example.org']) |
test/unit/environment_mailing_test.rb
| @@ -50,7 +50,7 @@ class EnvironmentMailingTest < ActiveSupport::TestCase | @@ -50,7 +50,7 @@ class EnvironmentMailingTest < ActiveSupport::TestCase | ||
| 50 | mailing = new_mailing(environment).tap do |m| | 50 | mailing = new_mailing(environment).tap do |m| |
| 51 | m.person = person_1 | 51 | m.person = person_1 |
| 52 | end | 52 | end |
| 53 | - assert_equal "#{environment.name} <#{environment.contact_email}>", mailing.generate_from | 53 | + assert_equal "#{environment.name} <#{environment.noreply_email}>", mailing.generate_from |
| 54 | end | 54 | end |
| 55 | 55 | ||
| 56 | should 'deliver mailing to each recipient after create' do | 56 | should 'deliver mailing to each recipient after create' do |
test/unit/environment_statistics_block_test.rb
| 1 | +# TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
| 2 | +# the Noosfero core soon, see ActionItem3045 | ||
| 3 | + | ||
| 1 | require File.dirname(__FILE__) + '/../test_helper' | 4 | require File.dirname(__FILE__) + '/../test_helper' |
| 2 | 5 | ||
| 3 | class EnvironmentStatisticsBlockTest < ActiveSupport::TestCase | 6 | class EnvironmentStatisticsBlockTest < ActiveSupport::TestCase |
| @@ -36,7 +39,7 @@ class EnvironmentStatisticsBlockTest < ActiveSupport::TestCase | @@ -36,7 +39,7 @@ class EnvironmentStatisticsBlockTest < ActiveSupport::TestCase | ||
| 36 | assert_match(/2 users/, content) | 39 | assert_match(/2 users/, content) |
| 37 | assert_match(/One community/, content) | 40 | assert_match(/One community/, content) |
| 38 | end | 41 | end |
| 39 | - | 42 | + |
| 40 | should 'generate statistics including private profiles' do | 43 | should 'generate statistics including private profiles' do |
| 41 | env = create(Environment) | 44 | env = create(Environment) |
| 42 | user1 = create_user('testuser1', :environment_id => env.id) | 45 | user1 = create_user('testuser1', :environment_id => env.id) |
test/unit/environment_test.rb
| @@ -1219,6 +1219,27 @@ class EnvironmentTest < ActiveSupport::TestCase | @@ -1219,6 +1219,27 @@ class EnvironmentTest < ActiveSupport::TestCase | ||
| 1219 | end | 1219 | end |
| 1220 | end | 1220 | end |
| 1221 | 1221 | ||
| 1222 | + should 'return a Hash on signup redirection options' do | ||
| 1223 | + assert_kind_of Hash, Environment.signup_redirection_options | ||
| 1224 | + end | ||
| 1225 | + | ||
| 1226 | + should 'respond to redirection after signup' do | ||
| 1227 | + assert_respond_to Environment.new, :redirection_after_signup | ||
| 1228 | + end | ||
| 1229 | + | ||
| 1230 | + should 'allow only environment signup redirection options' do | ||
| 1231 | + environment = fast_create(Environment) | ||
| 1232 | + environment.redirection_after_signup = 'invalid_option' | ||
| 1233 | + environment.save | ||
| 1234 | + assert environment.errors.invalid?(:redirection_after_signup) | ||
| 1235 | + | ||
| 1236 | + Environment.signup_redirection_options.keys.each do |redirection| | ||
| 1237 | + environment.redirection_after_signup = redirection | ||
| 1238 | + environment.save | ||
| 1239 | + assert !environment.errors.invalid?(:redirection_after_signup) | ||
| 1240 | + end | ||
| 1241 | + end | ||
| 1242 | + | ||
| 1222 | should 'respond to signup_welcome_text' do | 1243 | should 'respond to signup_welcome_text' do |
| 1223 | assert_respond_to Environment.new, :signup_welcome_text | 1244 | assert_respond_to Environment.new, :signup_welcome_text |
| 1224 | end | 1245 | end |
test/unit/file_presenter_test.rb
| @@ -58,4 +58,20 @@ class FilePresenterTest < ActiveSupport::TestCase | @@ -58,4 +58,20 @@ class FilePresenterTest < ActiveSupport::TestCase | ||
| 58 | end | 58 | end |
| 59 | end | 59 | end |
| 60 | 60 | ||
| 61 | + should 'pass kind_of? to the encapsulated file' do | ||
| 62 | + f = FilePresenter.for(UploadedFile.new) | ||
| 63 | + assert f.kind_of?(UploadedFile) | ||
| 64 | + end | ||
| 65 | + | ||
| 66 | + should 'not crash with uploaded_file short description without content_type' do | ||
| 67 | + f = FilePresenter.for(UploadedFile.new) | ||
| 68 | + assert_nothing_raised do | ||
| 69 | + f.short_description | ||
| 70 | + end | ||
| 71 | + end | ||
| 72 | + | ||
| 73 | + should 'show unknown type when file doesn\'t have a content_type' do | ||
| 74 | + f = FilePresenter.for(UploadedFile.new) | ||
| 75 | + assert_match /Unknown/, f.short_description | ||
| 76 | + end | ||
| 61 | end | 77 | end |
test/unit/forgot_password_helper_test.rb
| @@ -22,6 +22,7 @@ class ForgotPasswordHelperTest < ActionView::TestCase | @@ -22,6 +22,7 @@ class ForgotPasswordHelperTest < ActionView::TestCase | ||
| 22 | {:field => 'f3', :name => 'F3', :model => 'person'}] | 22 | {:field => 'f3', :name => 'F3', :model => 'person'}] |
| 23 | end | 23 | end |
| 24 | end | 24 | end |
| 25 | + Noosfero::Plugin.stubs(:all).returns(['ForgotPasswordHelperTest::Plugin1', 'ForgotPasswordHelperTest::Plugin2']) | ||
| 25 | 26 | ||
| 26 | environment.enable_plugin(Plugin1) | 27 | environment.enable_plugin(Plugin1) |
| 27 | environment.enable_plugin(Plugin2) | 28 | environment.enable_plugin(Plugin2) |
| @@ -43,6 +44,7 @@ class ForgotPasswordHelperTest < ActionView::TestCase | @@ -43,6 +44,7 @@ class ForgotPasswordHelperTest < ActionView::TestCase | ||
| 43 | {:field => 'f3', :name => 'F3', :model => 'person'}] | 44 | {:field => 'f3', :name => 'F3', :model => 'person'}] |
| 44 | end | 45 | end |
| 45 | end | 46 | end |
| 47 | + Noosfero::Plugin.stubs(:all).returns(['ForgotPasswordHelperTest::Plugin1', 'ForgotPasswordHelperTest::Plugin2']) | ||
| 46 | 48 | ||
| 47 | environment.enable_plugin(Plugin1) | 49 | environment.enable_plugin(Plugin1) |
| 48 | environment.enable_plugin(Plugin2) | 50 | environment.enable_plugin(Plugin2) |
| @@ -64,6 +66,7 @@ class ForgotPasswordHelperTest < ActionView::TestCase | @@ -64,6 +66,7 @@ class ForgotPasswordHelperTest < ActionView::TestCase | ||
| 64 | {:field => 'f3', :name => 'F3', :model => 'user'}] | 66 | {:field => 'f3', :name => 'F3', :model => 'user'}] |
| 65 | end | 67 | end |
| 66 | end | 68 | end |
| 69 | + Noosfero::Plugin.stubs(:all).returns(['ForgotPasswordHelperTest::Plugin1', 'ForgotPasswordHelperTest::Plugin2']) | ||
| 67 | 70 | ||
| 68 | environment.enable_plugin(Plugin1) | 71 | environment.enable_plugin(Plugin1) |
| 69 | environment.enable_plugin(Plugin2) | 72 | environment.enable_plugin(Plugin2) |
| @@ -85,6 +88,7 @@ class ForgotPasswordHelperTest < ActionView::TestCase | @@ -85,6 +88,7 @@ class ForgotPasswordHelperTest < ActionView::TestCase | ||
| 85 | {:field => 'f3', :name => 'F3', :model => 'user'}] | 88 | {:field => 'f3', :name => 'F3', :model => 'user'}] |
| 86 | end | 89 | end |
| 87 | end | 90 | end |
| 91 | + Noosfero::Plugin.stubs(:all).returns(['ForgotPasswordHelperTest::Plugin1', 'ForgotPasswordHelperTest::Plugin2']) | ||
| 88 | 92 | ||
| 89 | environment.enable_plugin(Plugin1) | 93 | environment.enable_plugin(Plugin1) |
| 90 | environment.enable_plugin(Plugin2) | 94 | environment.enable_plugin(Plugin2) |
test/unit/link_list_block_test.rb
| @@ -39,6 +39,32 @@ class LinkListBlockTest < ActiveSupport::TestCase | @@ -39,6 +39,32 @@ class LinkListBlockTest < ActiveSupport::TestCase | ||
| 39 | assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/test_profile/address'} | 39 | assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/test_profile/address'} |
| 40 | end | 40 | end |
| 41 | 41 | ||
| 42 | + should 'replace {portal} with environment portal identifier' do | ||
| 43 | + env = Environment.default | ||
| 44 | + env.enable('use_portal_community') | ||
| 45 | + portal = fast_create(Community, :identifier => 'portal-community', :environment_id => env.id) | ||
| 46 | + env.portal_community = portal | ||
| 47 | + env.save | ||
| 48 | + | ||
| 49 | + stubs(:environment).returns(env) | ||
| 50 | + l = LinkListBlock.new(:links => [{:name => 'categ', :address => '/{portal}/address'}]) | ||
| 51 | + l.stubs(:owner).returns(env) | ||
| 52 | + assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/portal-community/address'} | ||
| 53 | + end | ||
| 54 | + | ||
| 55 | + should 'not change address if no {portal} there' do | ||
| 56 | + env = Environment.default | ||
| 57 | + env.enable('use_portal_community') | ||
| 58 | + portal = fast_create(Community, :identifier => 'portal-community', :environment_id => env.id) | ||
| 59 | + env.portal_community = portal | ||
| 60 | + env.save | ||
| 61 | + | ||
| 62 | + stubs(:environment).returns(env) | ||
| 63 | + l = LinkListBlock.new(:links => [{:name => 'categ', :address => '/address'}]) | ||
| 64 | + l.stubs(:owner).returns(env) | ||
| 65 | + assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/address'} | ||
| 66 | + end | ||
| 67 | + | ||
| 42 | should 'display options for icons' do | 68 | should 'display options for icons' do |
| 43 | l = LinkListBlock.new | 69 | l = LinkListBlock.new |
| 44 | l.icons_options.each do |option| | 70 | l.icons_options.each do |option| |
test/unit/macros_helper_test.rb
| @@ -28,6 +28,7 @@ class MacrosHelperTest < ActionView::TestCase | @@ -28,6 +28,7 @@ class MacrosHelperTest < ActionView::TestCase | ||
| 28 | end | 28 | end |
| 29 | 29 | ||
| 30 | def setup | 30 | def setup |
| 31 | + Noosfero::Plugin.stubs(:all).returns(['MacrosHelperTest::Plugin1']) | ||
| 31 | @environment = Environment.default | 32 | @environment = Environment.default |
| 32 | @environment.enable_plugin(Plugin1) | 33 | @environment.enable_plugin(Plugin1) |
| 33 | @plugins = Noosfero::Plugin::Manager.new(@environment, self) | 34 | @plugins = Noosfero::Plugin::Manager.new(@environment, self) |
| @@ -129,4 +130,27 @@ class MacrosHelperTest < ActionView::TestCase | @@ -129,4 +130,27 @@ class MacrosHelperTest < ActionView::TestCase | ||
| 129 | assert_equal 'macro_generator', macro_generator(Plugin1::Macro) | 130 | assert_equal 'macro_generator', macro_generator(Plugin1::Macro) |
| 130 | end | 131 | end |
| 131 | 132 | ||
| 133 | + should 'get macro default generator' do | ||
| 134 | + class Plugin1::Macro < Noosfero::Plugin::Macro | ||
| 135 | + def self.configuration | ||
| 136 | + { :params => [] } | ||
| 137 | + end | ||
| 138 | + end | ||
| 139 | + assert_nothing_raised NoMethodError do | ||
| 140 | + assert macro_generator(Plugin1::Macro) | ||
| 141 | + end | ||
| 142 | + end | ||
| 143 | + | ||
| 144 | + should 'can use a code reference as macro generator' do | ||
| 145 | + class Plugin1::Macro < Noosfero::Plugin::Macro | ||
| 146 | + def self.configuration | ||
| 147 | + { :params => [], :generator => method(:macro_generator_method) } | ||
| 148 | + end | ||
| 149 | + def self.macro_generator_method(macro) | ||
| 150 | + "macro generator method return" | ||
| 151 | + end | ||
| 152 | + end | ||
| 153 | + assert_equal "macro generator method return", macro_generator(Plugin1::Macro) | ||
| 154 | + end | ||
| 155 | + | ||
| 132 | end | 156 | end |
test/unit/mailing_test.rb
| @@ -74,7 +74,7 @@ class MailingTest < ActiveSupport::TestCase | @@ -74,7 +74,7 @@ class MailingTest < ActiveSupport::TestCase | ||
| 74 | should 'display name and email on generate_from' do | 74 | should 'display name and email on generate_from' do |
| 75 | person = Person['user_one'] | 75 | person = Person['user_one'] |
| 76 | mailing = build(Mailing, :source => environment, :person => person) | 76 | mailing = build(Mailing, :source => environment, :person => person) |
| 77 | - assert_equal "#{environment.name} <#{environment.contact_email}>", mailing.generate_from | 77 | + assert_equal "#{environment.name} <#{environment.noreply_email}>", mailing.generate_from |
| 78 | end | 78 | end |
| 79 | 79 | ||
| 80 | should 'generate subject' do | 80 | should 'generate subject' do |
test/unit/members_block_test.rb
| @@ -35,4 +35,28 @@ class MembersBlockTest < ActiveSupport::TestCase | @@ -35,4 +35,28 @@ class MembersBlockTest < ActiveSupport::TestCase | ||
| 35 | assert_same list, block.profiles | 35 | assert_same list, block.profiles |
| 36 | end | 36 | end |
| 37 | 37 | ||
| 38 | + should 'use logged-in to compose cache key' do | ||
| 39 | + person = fast_create(Person) | ||
| 40 | + community = fast_create(Community) | ||
| 41 | + block = MembersBlock.create | ||
| 42 | + block.expects(:owner).returns(community) | ||
| 43 | + | ||
| 44 | + assert_match(/-logged-in/,block.cache_key('en', person)) | ||
| 45 | + end | ||
| 46 | + | ||
| 47 | + should 'use logged-in and member to compose cache key for members' do | ||
| 48 | + person = fast_create(Person) | ||
| 49 | + community = fast_create(Community) | ||
| 50 | + community.add_member person | ||
| 51 | + block = MembersBlock.create | ||
| 52 | + block.expects(:owner).returns(community) | ||
| 53 | + | ||
| 54 | + assert_match(/-logged-in-member/,block.cache_key('en', person)) | ||
| 55 | + end | ||
| 56 | + | ||
| 57 | + should 'not change block cache key if user is nil' do | ||
| 58 | + block = MembersBlock.new | ||
| 59 | + assert_equal block.cache_key('en'), block.cache_key('en', nil) | ||
| 60 | + end | ||
| 61 | + | ||
| 38 | end | 62 | end |
test/unit/organization_mailing_test.rb
| @@ -42,7 +42,7 @@ class OrganizationMailingTest < ActiveSupport::TestCase | @@ -42,7 +42,7 @@ class OrganizationMailingTest < ActiveSupport::TestCase | ||
| 42 | 42 | ||
| 43 | should 'display name and email on generate_from' do | 43 | should 'display name and email on generate_from' do |
| 44 | mailing = build(OrganizationMailing, :source => community, :person => person) | 44 | mailing = build(OrganizationMailing, :source => community, :person => person) |
| 45 | - assert_equal "#{person.name} <#{community.environment.contact_email}>", mailing.generate_from | 45 | + assert_equal "#{person.name} <#{community.environment.noreply_email}>", mailing.generate_from |
| 46 | end | 46 | end |
| 47 | 47 | ||
| 48 | should 'generate subject' do | 48 | should 'generate subject' do |
| @@ -61,19 +61,22 @@ class OrganizationMailingTest < ActiveSupport::TestCase | @@ -61,19 +61,22 @@ class OrganizationMailingTest < ActiveSupport::TestCase | ||
| 61 | end | 61 | end |
| 62 | 62 | ||
| 63 | should 'deliver mailing to each member after create' do | 63 | should 'deliver mailing to each member after create' do |
| 64 | - create(OrganizationMailing, :source => community, :subject => 'Hello', :body => 'We have some news', :person => person) | 64 | + mailing = create(OrganizationMailing, :source => community, :subject => 'Hello', :body => 'We have some news', :person => person) |
| 65 | + community.reload | ||
| 65 | process_delayed_job_queue | 66 | process_delayed_job_queue |
| 66 | - assert_equal community.members.compact.count, ActionMailer::Base.deliveries.count | 67 | + assert_equal 2, ActionMailer::Base.deliveries.count |
| 67 | end | 68 | end |
| 68 | 69 | ||
| 69 | should 'deliver mailing when there are many mailings created' do | 70 | should 'deliver mailing when there are many mailings created' do |
| 70 | 50.times { create(OrganizationMailing, :source => community, :subject => 'Hello', :body => 'We have some news', :person => person) } | 71 | 50.times { create(OrganizationMailing, :source => community, :subject => 'Hello', :body => 'We have some news', :person => person) } |
| 72 | + community.reload | ||
| 71 | process_delayed_job_queue | 73 | process_delayed_job_queue |
| 72 | - assert_equal 50*community.members.compact.count, ActionMailer::Base.deliveries.count | 74 | + assert_equal 50*community.members_count, ActionMailer::Base.deliveries.count |
| 73 | end | 75 | end |
| 74 | 76 | ||
| 75 | should 'create mailing sent to each recipient after delivering mailing' do | 77 | should 'create mailing sent to each recipient after delivering mailing' do |
| 76 | mailing = create(OrganizationMailing, :source => community, :subject => 'Hello', :body => 'We have some news', :person => person) | 78 | mailing = create(OrganizationMailing, :source => community, :subject => 'Hello', :body => 'We have some news', :person => person) |
| 79 | + community.reload | ||
| 77 | assert_difference 'MailingSent.count', 2 do | 80 | assert_difference 'MailingSent.count', 2 do |
| 78 | process_delayed_job_queue | 81 | process_delayed_job_queue |
| 79 | end | 82 | end |
test/unit/organization_test.rb
| @@ -302,18 +302,17 @@ class OrganizationTest < ActiveSupport::TestCase | @@ -302,18 +302,17 @@ class OrganizationTest < ActiveSupport::TestCase | ||
| 302 | end | 302 | end |
| 303 | 303 | ||
| 304 | should 'find more popular organizations' do | 304 | should 'find more popular organizations' do |
| 305 | - Organization.delete_all | ||
| 306 | o1 = fast_create(Organization) | 305 | o1 = fast_create(Organization) |
| 307 | o2 = fast_create(Organization) | 306 | o2 = fast_create(Organization) |
| 308 | 307 | ||
| 309 | p1 = fast_create(Person) | 308 | p1 = fast_create(Person) |
| 310 | p2 = fast_create(Person) | 309 | p2 = fast_create(Person) |
| 311 | o1.add_member(p1) | 310 | o1.add_member(p1) |
| 312 | - assert_equal [o1,o2] , Organization.more_popular | 311 | + assert_order [o1,o2] , Organization.more_popular |
| 313 | 312 | ||
| 314 | o2.add_member(p1) | 313 | o2.add_member(p1) |
| 315 | o2.add_member(p2) | 314 | o2.add_member(p2) |
| 316 | - assert_equal [o2,o1] , Organization.more_popular | 315 | + assert_order [o2,o1] , Organization.more_popular |
| 317 | end | 316 | end |
| 318 | 317 | ||
| 319 | should 'list organizations that have no members in more popular list' do | 318 | should 'list organizations that have no members in more popular list' do |
| @@ -331,6 +330,7 @@ class OrganizationTest < ActiveSupport::TestCase | @@ -331,6 +330,7 @@ class OrganizationTest < ActiveSupport::TestCase | ||
| 331 | person = fast_create(Person) | 330 | person = fast_create(Person) |
| 332 | organization = fast_create(Organization) | 331 | organization = fast_create(Organization) |
| 333 | organization.add_member(person) | 332 | organization.add_member(person) |
| 333 | + organization.reload | ||
| 334 | 334 | ||
| 335 | assert_equal "one member", organization.more_popular_label | 335 | assert_equal "one member", organization.more_popular_label |
| 336 | end | 336 | end |
| @@ -342,47 +342,30 @@ class OrganizationTest < ActiveSupport::TestCase | @@ -342,47 +342,30 @@ class OrganizationTest < ActiveSupport::TestCase | ||
| 342 | 342 | ||
| 343 | organization.add_member(person1) | 343 | organization.add_member(person1) |
| 344 | organization.add_member(person2) | 344 | organization.add_member(person2) |
| 345 | + organization.reload | ||
| 345 | assert_equal "2 members", organization.more_popular_label | 346 | assert_equal "2 members", organization.more_popular_label |
| 346 | 347 | ||
| 347 | person3 = fast_create(Person) | 348 | person3 = fast_create(Person) |
| 348 | organization.add_member(person3) | 349 | organization.add_member(person3) |
| 350 | + organization.reload | ||
| 349 | assert_equal "3 members", organization.more_popular_label | 351 | assert_equal "3 members", organization.more_popular_label |
| 350 | end | 352 | end |
| 351 | 353 | ||
| 352 | should 'find more active organizations' do | 354 | should 'find more active organizations' do |
| 353 | person = fast_create(Person) | 355 | person = fast_create(Person) |
| 354 | - Organization.destroy_all | ||
| 355 | p1 = fast_create(Organization) | 356 | p1 = fast_create(Organization) |
| 356 | p2 = fast_create(Organization) | 357 | p2 = fast_create(Organization) |
| 357 | p3 = fast_create(Organization) | 358 | p3 = fast_create(Organization) |
| 358 | 359 | ||
| 359 | ActionTracker::Record.destroy_all | 360 | ActionTracker::Record.destroy_all |
| 360 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => Time.now, :target_id => p1.id) | ||
| 361 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => Time.now, :target_id => p2.id) | ||
| 362 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => Time.now, :target_id => p2.id) | ||
| 363 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => Time.now, :target_id => p3.id) | ||
| 364 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => Time.now, :target_id => p3.id) | ||
| 365 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => Time.now, :target_id => p3.id) | 361 | + ActionTracker::Record.create!(:user => person, :target => p1, :verb => 'leave_scrap') |
| 362 | + ActionTracker::Record.create!(:user => person, :target => p2, :verb => 'leave_scrap') | ||
| 363 | + ActionTracker::Record.create!(:user => person, :target => p2, :verb => 'leave_scrap') | ||
| 364 | + ActionTracker::Record.create!(:user => person, :target => p3, :verb => 'leave_scrap') | ||
| 365 | + ActionTracker::Record.create!(:user => person, :target => p3, :verb => 'leave_scrap') | ||
| 366 | + ActionTracker::Record.create!(:user => person, :target => p3, :verb => 'leave_scrap') | ||
| 366 | 367 | ||
| 367 | - assert_equal [p3,p2,p1] , Organization.more_active | ||
| 368 | - end | ||
| 369 | - | ||
| 370 | - should 'more active profile take in consideration only actions created only in the recent delay interval' do | ||
| 371 | - ActionTracker::Record.destroy_all | ||
| 372 | - recent_delay = ActionTracker::Record::RECENT_DELAY.days.ago | ||
| 373 | - | ||
| 374 | - person = fast_create(Person) | ||
| 375 | - Organization.destroy_all | ||
| 376 | - p1 = fast_create(Organization) | ||
| 377 | - p2 = fast_create(Organization) | ||
| 378 | - | ||
| 379 | - ActionTracker::Record.destroy_all | ||
| 380 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => recent_delay, :target_id => p1.id) | ||
| 381 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => recent_delay, :target_id => p1.id) | ||
| 382 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => recent_delay, :target_id => p2.id) | ||
| 383 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => recent_delay - 1.day, :target_id => p2.id) | ||
| 384 | - | ||
| 385 | - assert_equal [p1,p2] , Organization.more_active | 368 | + assert_order [p3,p2,p1] , Organization.more_active |
| 386 | end | 369 | end |
| 387 | 370 | ||
| 388 | should 'list profiles that have no actions in more active list' do | 371 | should 'list profiles that have no actions in more active list' do |
| @@ -422,4 +405,24 @@ class OrganizationTest < ActiveSupport::TestCase | @@ -422,4 +405,24 @@ class OrganizationTest < ActiveSupport::TestCase | ||
| 422 | assert !organization.visible | 405 | assert !organization.visible |
| 423 | end | 406 | end |
| 424 | 407 | ||
| 408 | + should 'increase members_count on new membership' do | ||
| 409 | + member = fast_create(Person) | ||
| 410 | + organization = fast_create(Organization) | ||
| 411 | + assert_difference organization, :members_count, 1 do | ||
| 412 | + organization.add_member(member) | ||
| 413 | + organization.reload | ||
| 414 | + end | ||
| 415 | + end | ||
| 416 | + | ||
| 417 | + should 'decrease members_count on membership removal' do | ||
| 418 | + member = fast_create(Person) | ||
| 419 | + organization = fast_create(Organization) | ||
| 420 | + organization.add_member(member) | ||
| 421 | + organization.reload | ||
| 422 | + assert_difference organization, :members_count, -1 do | ||
| 423 | + organization.remove_member(member) | ||
| 424 | + organization.reload | ||
| 425 | + end | ||
| 426 | + end | ||
| 427 | + | ||
| 425 | end | 428 | end |
| @@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | + | ||
| 3 | +class PersonNotifierHelperTest < ActiveSupport::TestCase | ||
| 4 | + | ||
| 5 | + include PersonNotifierHelper | ||
| 6 | + include ActionView::Helpers::TagHelper | ||
| 7 | + | ||
| 8 | + def setup | ||
| 9 | + @profile = mock | ||
| 10 | + @env = Environment.new | ||
| 11 | + end | ||
| 12 | + attr_reader :profile, :env | ||
| 13 | + | ||
| 14 | + should 'append top url of environment at image path' do | ||
| 15 | + profile.expects(:environment).returns(env).at_least_once | ||
| 16 | + assert_match /src="http:\/\/localhost\/image.png"/, image_tag("/image.png") | ||
| 17 | + end | ||
| 18 | + | ||
| 19 | + should 'return original path if do not have an environment' do | ||
| 20 | + profile.expects(:environment).returns(nil).at_least_once | ||
| 21 | + assert_match /src="\/image.png"/, image_tag("/image.png") | ||
| 22 | + end | ||
| 23 | + | ||
| 24 | +end |
| @@ -0,0 +1,213 @@ | @@ -0,0 +1,213 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | + | ||
| 3 | +class PersonNotifierTest < ActiveSupport::TestCase | ||
| 4 | + FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures' | ||
| 5 | + CHARSET = "utf-8" | ||
| 6 | + | ||
| 7 | + def setup | ||
| 8 | + ActionMailer::Base.delivery_method = :test | ||
| 9 | + ActionMailer::Base.perform_deliveries = true | ||
| 10 | + ActionMailer::Base.deliveries = [] | ||
| 11 | + Person.destroy_all | ||
| 12 | + @admin = create_user('adminuser').person | ||
| 13 | + @member = create_user('member').person | ||
| 14 | + @admin.notification_time = 24 | ||
| 15 | + @member.notification_time = 24 | ||
| 16 | + @admin.save! | ||
| 17 | + @member.save! | ||
| 18 | + @community = fast_create(Community) | ||
| 19 | + @community.add_member(@admin) | ||
| 20 | + @article = fast_create(TextileArticle, :name => 'Article test', :profile_id => @community.id, :notify_comments => false) | ||
| 21 | + Delayed::Job.delete_all | ||
| 22 | + notify | ||
| 23 | + ActionMailer::Base.deliveries = [] | ||
| 24 | + end | ||
| 25 | + | ||
| 26 | + should 'deliver mail to community members' do | ||
| 27 | + @community.add_member(@member) | ||
| 28 | + notify | ||
| 29 | + sent = ActionMailer::Base.deliveries.first | ||
| 30 | + assert_equal [@member.email], sent.to | ||
| 31 | + end | ||
| 32 | + | ||
| 33 | + should 'do not send mail if do not have notifications' do | ||
| 34 | + @community.add_member(@member) | ||
| 35 | + ActionTracker::Record.delete_all | ||
| 36 | + notify | ||
| 37 | + assert ActionMailer::Base.deliveries.empty? | ||
| 38 | + end | ||
| 39 | + | ||
| 40 | + should 'do not send mail to people not joined to community' do | ||
| 41 | + Comment.create!(:author => @admin, :title => 'test comment 2', :body => 'body 2!', :source => @article) | ||
| 42 | + notify | ||
| 43 | + assert ActionMailer::Base.deliveries.blank? | ||
| 44 | + end | ||
| 45 | + | ||
| 46 | + should 'display author name in delivered mail' do | ||
| 47 | + @community.add_member(@member) | ||
| 48 | + Comment.create!(:author => @admin, :title => 'test comment', :body => 'body!', :source => @article) | ||
| 49 | + notify | ||
| 50 | + sent = ActionMailer::Base.deliveries.first | ||
| 51 | + assert_match /#{@admin.name}/, sent.body | ||
| 52 | + end | ||
| 53 | + | ||
| 54 | + should 'do not include comment created before last notification' do | ||
| 55 | + @community.add_member(@member) | ||
| 56 | + ActionTracker::Record.delete_all | ||
| 57 | + comment = Comment.create!(:author => @admin, :title => 'test comment', :body => 'body!', :source => @article ) | ||
| 58 | + @member.last_notification = DateTime.now + 1.day | ||
| 59 | + notify | ||
| 60 | + assert ActionMailer::Base.deliveries.empty? | ||
| 61 | + end | ||
| 62 | + | ||
| 63 | + should 'update last notification date' do | ||
| 64 | + Comment.create!(:author => @admin, :title => 'test comment 2', :body => 'body 2!', :source => @article) | ||
| 65 | + @community.add_member(@member) | ||
| 66 | + initial_notification = @member.last_notification | ||
| 67 | + notify | ||
| 68 | + assert @member.last_notification > initial_notification | ||
| 69 | + end | ||
| 70 | + | ||
| 71 | + should 'reschedule after notification' do | ||
| 72 | + Comment.create!(:author => @admin, :title => 'test comment 2', :body => 'body 2!', :source => @article) | ||
| 73 | + @community.add_member(@member) | ||
| 74 | + assert PersonNotifier::NotifyJob.find(@member.id).blank? | ||
| 75 | + notify | ||
| 76 | + assert PersonNotifier::NotifyJob.find(@member.id) | ||
| 77 | + end | ||
| 78 | + | ||
| 79 | + should 'schedule next mail at notification time' do | ||
| 80 | + @member.notification_time = 12 | ||
| 81 | + @member.notifier.schedule_next_notification_mail | ||
| 82 | + assert_equal @member.notification_time, DateTime.now.hour - Delayed::Job.first.run_at.hour | ||
| 83 | + end | ||
| 84 | + | ||
| 85 | + should 'do not schedule duplicated notification mail' do | ||
| 86 | + @member.notification_time = 12 | ||
| 87 | + @member.notifier.schedule_next_notification_mail | ||
| 88 | + @member.notifier.schedule_next_notification_mail | ||
| 89 | + assert_equal 1, Delayed::Job.count | ||
| 90 | + end | ||
| 91 | + | ||
| 92 | + should 'do not schedule next mail if notification time is zero' do | ||
| 93 | + @member.notification_time = 0 | ||
| 94 | + @member.notifier.schedule_next_notification_mail | ||
| 95 | + assert_equal 0, Delayed::Job.count | ||
| 96 | + end | ||
| 97 | + | ||
| 98 | + should 'schedule next notifications for all person with notification time greater than zero' do | ||
| 99 | + @member.notification_time = 1 | ||
| 100 | + @admin.notification_time = 0 | ||
| 101 | + @admin.save! | ||
| 102 | + @member.save! | ||
| 103 | + Delayed::Job.delete_all | ||
| 104 | + PersonNotifier.schedule_all_next_notification_mail | ||
| 105 | + process_delayed_job_queue | ||
| 106 | + assert_equal 1, Delayed::Job.count | ||
| 107 | + end | ||
| 108 | + | ||
| 109 | + should 'do not create duplicated job' do | ||
| 110 | + PersonNotifier.schedule_all_next_notification_mail | ||
| 111 | + PersonNotifier.schedule_all_next_notification_mail | ||
| 112 | + assert_equal 1, Delayed::Job.count | ||
| 113 | + end | ||
| 114 | + | ||
| 115 | + should 'schedule after update and set a valid notification time' do | ||
| 116 | + @member.notification_time = 0 | ||
| 117 | + @member.save! | ||
| 118 | + assert_equal 0, Delayed::Job.count | ||
| 119 | + @member.notification_time = 12 | ||
| 120 | + @member.save! | ||
| 121 | + assert_equal 1, Delayed::Job.count | ||
| 122 | + end | ||
| 123 | + | ||
| 124 | + should 'reschedule with changed notification time' do | ||
| 125 | + @member.notification_time = 2 | ||
| 126 | + @member.save! | ||
| 127 | + assert_equal 1, Delayed::Job.count | ||
| 128 | + @member.notification_time = 12 | ||
| 129 | + @member.save! | ||
| 130 | + assert_equal 1, Delayed::Job.count | ||
| 131 | + assert_equal @member.notification_time, DateTime.now.hour - Delayed::Job.first.run_at.hour | ||
| 132 | + end | ||
| 133 | + | ||
| 134 | + should 'display error message if fail to render a notificiation' do | ||
| 135 | + @community.add_member(@member) | ||
| 136 | + Comment.create!(:author => @admin, :title => 'test comment', :body => 'body!', :source => @article) | ||
| 137 | + ActionTracker::Record.any_instance.stubs(:verb).returns("some_invalid_verb") | ||
| 138 | + notify | ||
| 139 | + sent = ActionMailer::Base.deliveries.first | ||
| 140 | + assert_match /cannot render notification for some_invalid_verb/, sent.body | ||
| 141 | + end | ||
| 142 | + | ||
| 143 | + ActionTrackerConfig.verb_names.each do |verb| | ||
| 144 | + should "render notification for verb #{verb}" do | ||
| 145 | + action = mock() | ||
| 146 | + action.stubs(:verb).returns(verb) | ||
| 147 | + action.stubs(:user).returns(@member) | ||
| 148 | + action.stubs(:created_at).returns(DateTime.now) | ||
| 149 | + action.stubs(:target).returns(fast_create(Forum)) | ||
| 150 | + action.stubs(:comments_count).returns(0) | ||
| 151 | + action.stubs(:comments).returns([]) | ||
| 152 | + action.stubs(:params).returns({'name' => 'home', 'url' => '/', 'lead' => ''}) | ||
| 153 | + action.stubs(:get_url).returns('') | ||
| 154 | + | ||
| 155 | + notifications = [] | ||
| 156 | + notifications.stubs(:find).returns([action]) | ||
| 157 | + Person.any_instance.stubs(:tracked_notifications).returns(notifications) | ||
| 158 | + | ||
| 159 | + notify | ||
| 160 | + sent = ActionMailer::Base.deliveries.first | ||
| 161 | + assert_no_match /cannot render notification for #{verb}/, sent.body | ||
| 162 | + end | ||
| 163 | + end | ||
| 164 | + | ||
| 165 | + should 'exists? method in NotifyAllJob return false if there is no instance of this class created' do | ||
| 166 | + Delayed::Job.enqueue(PersonNotifier::NotifyJob.new) | ||
| 167 | + assert !PersonNotifier::NotifyAllJob.exists? | ||
| 168 | + end | ||
| 169 | + | ||
| 170 | + should 'exists? method in NotifyAllJob return false if there is no jobs created' do | ||
| 171 | + assert !PersonNotifier::NotifyAllJob.exists? | ||
| 172 | + end | ||
| 173 | + | ||
| 174 | + should 'exists? method in NotifyAllJob return true if there is at least one instance of this class' do | ||
| 175 | + Delayed::Job.enqueue(PersonNotifier::NotifyAllJob.new) | ||
| 176 | + assert PersonNotifier::NotifyAllJob.exists? | ||
| 177 | + end | ||
| 178 | + | ||
| 179 | + should 'perform create NotifyJob for all users with notification_time' do | ||
| 180 | + Delayed::Job.enqueue(PersonNotifier::NotifyAllJob.new) | ||
| 181 | + process_delayed_job_queue | ||
| 182 | + assert_equal 2, Delayed::Job.count | ||
| 183 | + end | ||
| 184 | + | ||
| 185 | + should 'perform create NotifyJob for all users with notification_time defined greater than zero' do | ||
| 186 | + @member.notification_time = 1 | ||
| 187 | + @admin.notification_time = 0 | ||
| 188 | + @admin.save! | ||
| 189 | + @member.save! | ||
| 190 | + Delayed::Job.delete_all | ||
| 191 | + Delayed::Job.enqueue(PersonNotifier::NotifyAllJob.new) | ||
| 192 | + process_delayed_job_queue | ||
| 193 | + assert_equal 1, Delayed::Job.count | ||
| 194 | + end | ||
| 195 | + | ||
| 196 | + should 'NotifyJob failed jobs create a new NotifyJob on permanent failure' do | ||
| 197 | + Delayed::Job.enqueue(PersonNotifier::NotifyJob.new(@member.id)) | ||
| 198 | + | ||
| 199 | + PersonNotifier.any_instance.stubs(:notify).raises('error') | ||
| 200 | + | ||
| 201 | + process_delayed_job_queue | ||
| 202 | + jobs = Delayed::Job.all | ||
| 203 | + | ||
| 204 | + assert 1, jobs.select{|j| j.failed?}.size | ||
| 205 | + assert 1, jobs.select{|j| !j.failed?}.size | ||
| 206 | + end | ||
| 207 | + | ||
| 208 | + def notify | ||
| 209 | + process_delayed_job_queue | ||
| 210 | + @member.notifier.notify | ||
| 211 | + end | ||
| 212 | + | ||
| 213 | +end |
test/unit/person_test.rb
| @@ -405,15 +405,14 @@ class PersonTest < ActiveSupport::TestCase | @@ -405,15 +405,14 @@ class PersonTest < ActiveSupport::TestCase | ||
| 405 | 405 | ||
| 406 | should 'not allow simple member to view group pending tasks' do | 406 | should 'not allow simple member to view group pending tasks' do |
| 407 | community = fast_create(Community) | 407 | community = fast_create(Community) |
| 408 | + admin = fast_create(Person) | ||
| 409 | + community.add_member(admin) | ||
| 408 | member = fast_create(Person) | 410 | member = fast_create(Person) |
| 411 | + community.reload | ||
| 409 | community.add_member(member) | 412 | community.add_member(member) |
| 410 | - | ||
| 411 | community.tasks << Task.new | 413 | community.tasks << Task.new |
| 412 | 414 | ||
| 413 | - person = fast_create(Person) | ||
| 414 | - community.add_member(person) | ||
| 415 | - | ||
| 416 | - assert_not_includes Person.with_pending_tasks, person | 415 | + assert_not_includes Person.with_pending_tasks, member |
| 417 | end | 416 | end |
| 418 | 417 | ||
| 419 | should 'person has organization pending tasks' do | 418 | should 'person has organization pending tasks' do |
| @@ -643,16 +642,18 @@ class PersonTest < ActiveSupport::TestCase | @@ -643,16 +642,18 @@ class PersonTest < ActiveSupport::TestCase | ||
| 643 | end | 642 | end |
| 644 | 643 | ||
| 645 | should 'find more popular people' do | 644 | should 'find more popular people' do |
| 645 | + extend CacheCounterHelper | ||
| 646 | + | ||
| 646 | Person.delete_all | 647 | Person.delete_all |
| 647 | p1 = fast_create(Person) | 648 | p1 = fast_create(Person) |
| 648 | p2 = fast_create(Person) | 649 | p2 = fast_create(Person) |
| 649 | p3 = fast_create(Person) | 650 | p3 = fast_create(Person) |
| 650 | 651 | ||
| 651 | - p1.add_friend(p2) | ||
| 652 | - p2.add_friend(p1) | ||
| 653 | - p2.add_friend(p3) | ||
| 654 | - assert_equal p2, Person.more_popular.all[0] | ||
| 655 | - assert_equal p1, Person.more_popular.all[1] | 652 | + update_cache_counter(:friends_count, p1, 1) |
| 653 | + update_cache_counter(:friends_count, p2, 2) | ||
| 654 | + update_cache_counter(:friends_count, p3, 3) | ||
| 655 | + | ||
| 656 | + assert_order [p3, p2, p1], Person.more_popular | ||
| 656 | end | 657 | end |
| 657 | 658 | ||
| 658 | should 'list people that have no friends in more popular list' do | 659 | should 'list people that have no friends in more popular list' do |
| @@ -892,6 +893,7 @@ class PersonTest < ActiveSupport::TestCase | @@ -892,6 +893,7 @@ class PersonTest < ActiveSupport::TestCase | ||
| 892 | p1 = fast_create(Person) | 893 | p1 = fast_create(Person) |
| 893 | p2 = fast_create(Person) | 894 | p2 = fast_create(Person) |
| 894 | p3 = fast_create(Person) | 895 | p3 = fast_create(Person) |
| 896 | + p4 = fast_create(Person) | ||
| 895 | 897 | ||
| 896 | community.add_member(p1) | 898 | community.add_member(p1) |
| 897 | assert p1.is_member_of?(community) | 899 | assert p1.is_member_of?(community) |
| @@ -902,14 +904,15 @@ class PersonTest < ActiveSupport::TestCase | @@ -902,14 +904,15 @@ class PersonTest < ActiveSupport::TestCase | ||
| 902 | 904 | ||
| 903 | action_tracker = fast_create(ActionTracker::Record, :verb => 'create_article') | 905 | action_tracker = fast_create(ActionTracker::Record, :verb => 'create_article') |
| 904 | action_tracker.target = community | 906 | action_tracker.target = community |
| 907 | + action_tracker.user = p4 | ||
| 905 | action_tracker.save! | 908 | action_tracker.save! |
| 906 | ActionTrackerNotification.delete_all | 909 | ActionTrackerNotification.delete_all |
| 907 | - assert_difference 'ActionTrackerNotification.count', 3 do | 910 | + assert_difference 'ActionTrackerNotification.count', 4 do |
| 908 | Person.notify_activity(action_tracker) | 911 | Person.notify_activity(action_tracker) |
| 909 | process_delayed_job_queue | 912 | process_delayed_job_queue |
| 910 | end | 913 | end |
| 911 | ActionTrackerNotification.all.map{|a|a.profile}.map do |profile| | 914 | ActionTrackerNotification.all.map{|a|a.profile}.map do |profile| |
| 912 | - assert [community,p1,p3].include?(profile) | 915 | + assert [community,p1,p3,p4].include?(profile) |
| 913 | end | 916 | end |
| 914 | end | 917 | end |
| 915 | 918 | ||
| @@ -1012,9 +1015,9 @@ class PersonTest < ActiveSupport::TestCase | @@ -1012,9 +1015,9 @@ class PersonTest < ActiveSupport::TestCase | ||
| 1012 | 1015 | ||
| 1013 | should 'the community specific notification created when a member joins community could not be propagated to members' do | 1016 | should 'the community specific notification created when a member joins community could not be propagated to members' do |
| 1014 | ActionTracker::Record.delete_all | 1017 | ActionTracker::Record.delete_all |
| 1015 | - p1 = create_user('test_user').person | ||
| 1016 | - p2 = create_user('test_user').person | ||
| 1017 | - p3 = create_user('test_user').person | 1018 | + p1 = create_user('p1').person |
| 1019 | + p2 = create_user('p2').person | ||
| 1020 | + p3 = create_user('p3').person | ||
| 1018 | c = fast_create(Community, :name => "Foo") | 1021 | c = fast_create(Community, :name => "Foo") |
| 1019 | c.add_member(p1) | 1022 | c.add_member(p1) |
| 1020 | process_delayed_job_queue | 1023 | process_delayed_job_queue |
| @@ -1134,30 +1137,14 @@ class PersonTest < ActiveSupport::TestCase | @@ -1134,30 +1137,14 @@ class PersonTest < ActiveSupport::TestCase | ||
| 1134 | p3 = fast_create(Person) | 1137 | p3 = fast_create(Person) |
| 1135 | 1138 | ||
| 1136 | ActionTracker::Record.destroy_all | 1139 | ActionTracker::Record.destroy_all |
| 1137 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p1, :created_at => Time.now) | ||
| 1138 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p2, :created_at => Time.now) | ||
| 1139 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p2, :created_at => Time.now) | ||
| 1140 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p3, :created_at => Time.now) | ||
| 1141 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p3, :created_at => Time.now) | ||
| 1142 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p3, :created_at => Time.now) | 1140 | + ActionTracker::Record.create!(:user => p1, :verb => 'leave_scrap') |
| 1141 | + ActionTracker::Record.create!(:user => p2, :verb => 'leave_scrap') | ||
| 1142 | + ActionTracker::Record.create!(:user => p2, :verb => 'leave_scrap') | ||
| 1143 | + ActionTracker::Record.create!(:user => p3, :verb => 'leave_scrap') | ||
| 1144 | + ActionTracker::Record.create!(:user => p3, :verb => 'leave_scrap') | ||
| 1145 | + ActionTracker::Record.create!(:user => p3, :verb => 'leave_scrap') | ||
| 1143 | 1146 | ||
| 1144 | - assert_equal [p3,p2,p1] , Person.more_active | ||
| 1145 | - end | ||
| 1146 | - | ||
| 1147 | - should 'more active profile take in consideration only actions created only in the recent delay interval' do | ||
| 1148 | - Person.delete_all | ||
| 1149 | - ActionTracker::Record.destroy_all | ||
| 1150 | - recent_delay = ActionTracker::Record::RECENT_DELAY.days.ago | ||
| 1151 | - | ||
| 1152 | - p1 = fast_create(Person) | ||
| 1153 | - p2 = fast_create(Person) | ||
| 1154 | - | ||
| 1155 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p1, :created_at => recent_delay) | ||
| 1156 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p1, :created_at => recent_delay) | ||
| 1157 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p2, :created_at => recent_delay) | ||
| 1158 | - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p2, :created_at => recent_delay - 1.day) | ||
| 1159 | - | ||
| 1160 | - assert_equal [p1,p2], Person.more_active | 1147 | + assert_order [p3,p2,p1] , Person.more_active |
| 1161 | end | 1148 | end |
| 1162 | 1149 | ||
| 1163 | should 'list profiles that have no actions in more active list' do | 1150 | should 'list profiles that have no actions in more active list' do |
| @@ -1269,6 +1256,7 @@ class PersonTest < ActiveSupport::TestCase | @@ -1269,6 +1256,7 @@ class PersonTest < ActiveSupport::TestCase | ||
| 1269 | false | 1256 | false |
| 1270 | end | 1257 | end |
| 1271 | end | 1258 | end |
| 1259 | + Noosfero::Plugin.stubs(:all).returns(['PersonTest::Plugin1', 'PersonTest::Plugin2']) | ||
| 1272 | 1260 | ||
| 1273 | e = Environment.default | 1261 | e = Environment.default |
| 1274 | e.enable_plugin(Plugin1.name) | 1262 | e.enable_plugin(Plugin1.name) |
| @@ -1415,6 +1403,17 @@ class PersonTest < ActiveSupport::TestCase | @@ -1415,6 +1403,17 @@ class PersonTest < ActiveSupport::TestCase | ||
| 1415 | assert_equal person.activities, [] | 1403 | assert_equal person.activities, [] |
| 1416 | end | 1404 | end |
| 1417 | 1405 | ||
| 1406 | + should 'person notifier be PersonNotifier class' do | ||
| 1407 | + p = Person.new | ||
| 1408 | + assert p.notifier.kind_of?(PersonNotifier) | ||
| 1409 | + end | ||
| 1410 | + | ||
| 1411 | + should 'reschedule next notification after update' do | ||
| 1412 | + p = fast_create(Person, :user_id => fast_create(User).id) | ||
| 1413 | + PersonNotifier.any_instance.expects(:reschedule_next_notification_mail).once | ||
| 1414 | + assert p.update_attribute(:name, 'Person name changed') | ||
| 1415 | + end | ||
| 1416 | + | ||
| 1418 | should 'merge memberships of plugins to original memberships' do | 1417 | should 'merge memberships of plugins to original memberships' do |
| 1419 | class Plugin1 < Noosfero::Plugin | 1418 | class Plugin1 < Noosfero::Plugin |
| 1420 | def person_memberships(person) | 1419 | def person_memberships(person) |
| @@ -1427,6 +1426,7 @@ class PersonTest < ActiveSupport::TestCase | @@ -1427,6 +1426,7 @@ class PersonTest < ActiveSupport::TestCase | ||
| 1427 | Profile.memberships_of(Person.find_by_identifier('person2')) | 1426 | Profile.memberships_of(Person.find_by_identifier('person2')) |
| 1428 | end | 1427 | end |
| 1429 | end | 1428 | end |
| 1429 | + Noosfero::Plugin.stubs(:all).returns(['PersonTest::Plugin1', 'PersonTest::Plugin2']) | ||
| 1430 | 1430 | ||
| 1431 | Environment.default.enable_plugin(Plugin1) | 1431 | Environment.default.enable_plugin(Plugin1) |
| 1432 | Environment.default.enable_plugin(Plugin2) | 1432 | Environment.default.enable_plugin(Plugin2) |
| @@ -1447,4 +1447,30 @@ class PersonTest < ActiveSupport::TestCase | @@ -1447,4 +1447,30 @@ class PersonTest < ActiveSupport::TestCase | ||
| 1447 | assert_equal 3, original_person.memberships.count | 1447 | assert_equal 3, original_person.memberships.count |
| 1448 | end | 1448 | end |
| 1449 | 1449 | ||
| 1450 | + should 'increase friends_count on new friendship' do | ||
| 1451 | + person = create_user('person').person | ||
| 1452 | + friend = create_user('friend').person | ||
| 1453 | + assert_difference person, :friends_count, 1 do | ||
| 1454 | + assert_difference friend, :friends_count, 1 do | ||
| 1455 | + person.add_friend(friend) | ||
| 1456 | + friend.reload | ||
| 1457 | + end | ||
| 1458 | + person.reload | ||
| 1459 | + end | ||
| 1460 | + end | ||
| 1461 | + | ||
| 1462 | + should 'decrease friends_count on friendship removal' do | ||
| 1463 | + person = create_user('person').person | ||
| 1464 | + friend = create_user('friend').person | ||
| 1465 | + person.add_friend(friend) | ||
| 1466 | + friend.reload | ||
| 1467 | + person.reload | ||
| 1468 | + assert_difference person, :friends_count, -1 do | ||
| 1469 | + assert_difference friend, :friends_count, -1 do | ||
| 1470 | + person.remove_friend(friend) | ||
| 1471 | + friend.reload | ||
| 1472 | + end | ||
| 1473 | + person.reload | ||
| 1474 | + end | ||
| 1475 | + end | ||
| 1450 | end | 1476 | end |
test/unit/plugin_manager_test.rb
| @@ -26,6 +26,7 @@ class PluginManagerTest < ActiveSupport::TestCase | @@ -26,6 +26,7 @@ class PluginManagerTest < ActiveSupport::TestCase | ||
| 26 | class Plugin2 < Noosfero::Plugin; end; | 26 | class Plugin2 < Noosfero::Plugin; end; |
| 27 | class Plugin3 < Noosfero::Plugin; end; | 27 | class Plugin3 < Noosfero::Plugin; end; |
| 28 | class Plugin4 < Noosfero::Plugin; end; | 28 | class Plugin4 < Noosfero::Plugin; end; |
| 29 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3', 'PluginManagerTest::Plugin4']) | ||
| 29 | environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s, Plugin4.to_s]) | 30 | environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s, Plugin4.to_s]) |
| 30 | Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin3.to_s, Plugin4.to_s]) | 31 | Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin3.to_s, Plugin4.to_s]) |
| 31 | results = plugins.enabled_plugins.map { |instance| instance.class.to_s } | 32 | results = plugins.enabled_plugins.map { |instance| instance.class.to_s } |
| @@ -51,6 +52,7 @@ class PluginManagerTest < ActiveSupport::TestCase | @@ -51,6 +52,7 @@ class PluginManagerTest < ActiveSupport::TestCase | ||
| 51 | 'Plugin 2 action.' | 52 | 'Plugin 2 action.' |
| 52 | end | 53 | end |
| 53 | end | 54 | end |
| 55 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2']) | ||
| 54 | 56 | ||
| 55 | environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s]) | 57 | environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s]) |
| 56 | 58 | ||
| @@ -83,6 +85,7 @@ class PluginManagerTest < ActiveSupport::TestCase | @@ -83,6 +85,7 @@ class PluginManagerTest < ActiveSupport::TestCase | ||
| 83 | 'Plugin 3 action.' | 85 | 'Plugin 3 action.' |
| 84 | end | 86 | end |
| 85 | end | 87 | end |
| 88 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3']) | ||
| 86 | 89 | ||
| 87 | environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s, Plugin3.to_s]) | 90 | environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s, Plugin3.to_s]) |
| 88 | p1 = Plugin1.new | 91 | p1 = Plugin1.new |
| @@ -107,6 +110,7 @@ class PluginManagerTest < ActiveSupport::TestCase | @@ -107,6 +110,7 @@ class PluginManagerTest < ActiveSupport::TestCase | ||
| 107 | 'Plugin3' | 110 | 'Plugin3' |
| 108 | end | 111 | end |
| 109 | end | 112 | end |
| 113 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3']) | ||
| 110 | 114 | ||
| 111 | environment.enable_plugin(Plugin1.name) | 115 | environment.enable_plugin(Plugin1.name) |
| 112 | environment.enable_plugin(Plugin2.name) | 116 | environment.enable_plugin(Plugin2.name) |
| @@ -134,6 +138,7 @@ class PluginManagerTest < ActiveSupport::TestCase | @@ -134,6 +138,7 @@ class PluginManagerTest < ActiveSupport::TestCase | ||
| 134 | true | 138 | true |
| 135 | end | 139 | end |
| 136 | end | 140 | end |
| 141 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3']) | ||
| 137 | 142 | ||
| 138 | environment.enable_plugin(Plugin1.name) | 143 | environment.enable_plugin(Plugin1.name) |
| 139 | environment.enable_plugin(Plugin2.name) | 144 | environment.enable_plugin(Plugin2.name) |
| @@ -162,6 +167,7 @@ class PluginManagerTest < ActiveSupport::TestCase | @@ -162,6 +167,7 @@ class PluginManagerTest < ActiveSupport::TestCase | ||
| 162 | true | 167 | true |
| 163 | end | 168 | end |
| 164 | end | 169 | end |
| 170 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3']) | ||
| 165 | 171 | ||
| 166 | environment.enable_plugin(Plugin1.name) | 172 | environment.enable_plugin(Plugin1.name) |
| 167 | environment.enable_plugin(Plugin2.name) | 173 | environment.enable_plugin(Plugin2.name) |
| @@ -178,6 +184,7 @@ class PluginManagerTest < ActiveSupport::TestCase | @@ -178,6 +184,7 @@ class PluginManagerTest < ActiveSupport::TestCase | ||
| 178 | [Macro1, Macro2] | 184 | [Macro1, Macro2] |
| 179 | end | 185 | end |
| 180 | end | 186 | end |
| 187 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1']) | ||
| 181 | 188 | ||
| 182 | class Plugin1::Macro1 < Noosfero::Plugin::Macro | 189 | class Plugin1::Macro1 < Noosfero::Plugin::Macro |
| 183 | def convert(macro, source) | 190 | def convert(macro, source) |
| @@ -212,6 +219,7 @@ class PluginManagerTest < ActiveSupport::TestCase | @@ -212,6 +219,7 @@ class PluginManagerTest < ActiveSupport::TestCase | ||
| 212 | [v1 * v, v2 * v] | 219 | [v1 * v, v2 * v] |
| 213 | end | 220 | end |
| 214 | end | 221 | end |
| 222 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2']) | ||
| 215 | 223 | ||
| 216 | environment.enable_plugin(Plugin1) | 224 | environment.enable_plugin(Plugin1) |
| 217 | environment.enable_plugin(Plugin2) | 225 | environment.enable_plugin(Plugin2) |
| @@ -231,6 +239,7 @@ class PluginManagerTest < ActiveSupport::TestCase | @@ -231,6 +239,7 @@ class PluginManagerTest < ActiveSupport::TestCase | ||
| 231 | value * 5 | 239 | value * 5 |
| 232 | end | 240 | end |
| 233 | end | 241 | end |
| 242 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2']) | ||
| 234 | 243 | ||
| 235 | environment.enable_plugin(Plugin1) | 244 | environment.enable_plugin(Plugin1) |
| 236 | environment.enable_plugin(Plugin2) | 245 | environment.enable_plugin(Plugin2) |
| @@ -252,6 +261,7 @@ class PluginManagerTest < ActiveSupport::TestCase | @@ -252,6 +261,7 @@ class PluginManagerTest < ActiveSupport::TestCase | ||
| 252 | [v1 * v, v2 * v, 666] | 261 | [v1 * v, v2 * v, 666] |
| 253 | end | 262 | end |
| 254 | end | 263 | end |
| 264 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2']) | ||
| 255 | 265 | ||
| 256 | environment.enable_plugin(Plugin1) | 266 | environment.enable_plugin(Plugin1) |
| 257 | environment.enable_plugin(Plugin2) | 267 | environment.enable_plugin(Plugin2) |
| @@ -273,6 +283,7 @@ class PluginManagerTest < ActiveSupport::TestCase | @@ -273,6 +283,7 @@ class PluginManagerTest < ActiveSupport::TestCase | ||
| 273 | numbers.reject {|n| n<=5} | 283 | numbers.reject {|n| n<=5} |
| 274 | end | 284 | end |
| 275 | end | 285 | end |
| 286 | + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2']) | ||
| 276 | 287 | ||
| 277 | environment.enable_plugin(Plugin1) | 288 | environment.enable_plugin(Plugin1) |
| 278 | environment.enable_plugin(Plugin2) | 289 | environment.enable_plugin(Plugin2) |
test/unit/plugin_test.rb
| @@ -9,15 +9,9 @@ class PluginTest < ActiveSupport::TestCase | @@ -9,15 +9,9 @@ class PluginTest < ActiveSupport::TestCase | ||
| 9 | 9 | ||
| 10 | include Noosfero::Plugin::HotSpot | 10 | include Noosfero::Plugin::HotSpot |
| 11 | 11 | ||
| 12 | - should 'keep the list of all loaded subclasses' do | ||
| 13 | - class Plugin1 < Noosfero::Plugin | ||
| 14 | - end | ||
| 15 | - | ||
| 16 | - class Plugin2 < Noosfero::Plugin | ||
| 17 | - end | ||
| 18 | - | ||
| 19 | - assert_includes Noosfero::Plugin.all, Plugin1.to_s | ||
| 20 | - assert_includes Noosfero::Plugin.all, Plugin2.to_s | 12 | + should 'keep the list of all available plugins' do |
| 13 | + assert File.directory?(File.join(Rails.root, 'plugins', 'foo')) | ||
| 14 | + assert_includes Noosfero::Plugin.all, 'FooPlugin' | ||
| 21 | end | 15 | end |
| 22 | 16 | ||
| 23 | should 'returns url to plugin management if plugin has admin_controller' do | 17 | should 'returns url to plugin management if plugin has admin_controller' do |
| @@ -496,4 +490,29 @@ class PluginTest < ActiveSupport::TestCase | @@ -496,4 +490,29 @@ class PluginTest < ActiveSupport::TestCase | ||
| 496 | end | 490 | end |
| 497 | end | 491 | end |
| 498 | 492 | ||
| 493 | + should 'comment_actions be nil if the comment is nil' do | ||
| 494 | + class SomePlugin < Noosfero::Plugin; end | ||
| 495 | + plugin = SomePlugin.new | ||
| 496 | + assert_nil plugin.comment_actions(nil) | ||
| 497 | + end | ||
| 498 | + | ||
| 499 | + should 'comment_actions be nil by default' do | ||
| 500 | + class SomePlugin < Noosfero::Plugin; end | ||
| 501 | + plugin = SomePlugin.new | ||
| 502 | + assert_nil plugin.comment_actions(Comment.new) | ||
| 503 | + end | ||
| 504 | + | ||
| 505 | + should 'check_comment_actions be an empty array if the comment is nil' do | ||
| 506 | + class SomePlugin < Noosfero::Plugin; end | ||
| 507 | + plugin = SomePlugin.new | ||
| 508 | + assert_equal [], plugin.check_comment_actions(nil) | ||
| 509 | + end | ||
| 510 | + | ||
| 511 | + | ||
| 512 | + should 'check_comment_actions be an empty array by default' do | ||
| 513 | + class SomePlugin < Noosfero::Plugin; end | ||
| 514 | + plugin = SomePlugin.new | ||
| 515 | + assert_equal [], plugin.check_comment_actions(Comment.new) | ||
| 516 | + end | ||
| 517 | + | ||
| 499 | end | 518 | end |
test/unit/profile_test.rb
| @@ -364,7 +364,7 @@ class ProfileTest < ActiveSupport::TestCase | @@ -364,7 +364,7 @@ class ProfileTest < ActiveSupport::TestCase | ||
| 364 | t2 = c.tasks.build; t2.save!; t2.finish | 364 | t2 = c.tasks.build; t2.save!; t2.finish |
| 365 | t3 = c.tasks.build; t3.save!; t3.finish | 365 | t3 = c.tasks.build; t3.save!; t3.finish |
| 366 | 366 | ||
| 367 | - assert_equal [t2, t3], c.tasks.finished | 367 | + assert_equivalent [t2, t3], c.tasks.finished |
| 368 | end | 368 | end |
| 369 | 369 | ||
| 370 | should 'responds to categories' do | 370 | should 'responds to categories' do |
| @@ -1689,6 +1689,7 @@ class ProfileTest < ActiveSupport::TestCase | @@ -1689,6 +1689,7 @@ class ProfileTest < ActiveSupport::TestCase | ||
| 1689 | person = fast_create(Person) | 1689 | person = fast_create(Person) |
| 1690 | community = fast_create(Community) | 1690 | community = fast_create(Community) |
| 1691 | community.add_member(person) | 1691 | community.add_member(person) |
| 1692 | + community.reload | ||
| 1692 | 1693 | ||
| 1693 | assert_equal 1, community.members_count | 1694 | assert_equal 1, community.members_count |
| 1694 | end | 1695 | end |
| @@ -1812,6 +1813,7 @@ class ProfileTest < ActiveSupport::TestCase | @@ -1812,6 +1813,7 @@ class ProfileTest < ActiveSupport::TestCase | ||
| 1812 | Person.members_of(Community.find_by_identifier('community2')) | 1813 | Person.members_of(Community.find_by_identifier('community2')) |
| 1813 | end | 1814 | end |
| 1814 | end | 1815 | end |
| 1816 | + Noosfero::Plugin.stubs(:all).returns(['ProfileTest::Plugin1', 'ProfileTest::Plugin2']) | ||
| 1815 | Environment.default.enable_plugin(Plugin1) | 1817 | Environment.default.enable_plugin(Plugin1) |
| 1816 | Environment.default.enable_plugin(Plugin2) | 1818 | Environment.default.enable_plugin(Plugin2) |
| 1817 | 1819 | ||
| @@ -1824,6 +1826,7 @@ class ProfileTest < ActiveSupport::TestCase | @@ -1824,6 +1826,7 @@ class ProfileTest < ActiveSupport::TestCase | ||
| 1824 | original_community.add_member(original_member) | 1826 | original_community.add_member(original_member) |
| 1825 | community1.add_member(plugin1_member) | 1827 | community1.add_member(plugin1_member) |
| 1826 | community2.add_member(plugin2_member) | 1828 | community2.add_member(plugin2_member) |
| 1829 | + original_community.reload | ||
| 1827 | 1830 | ||
| 1828 | assert_includes original_community.members, original_member | 1831 | assert_includes original_community.members, original_member |
| 1829 | assert_includes original_community.members, plugin1_member | 1832 | assert_includes original_community.members, plugin1_member |
| @@ -1968,6 +1971,7 @@ class ProfileTest < ActiveSupport::TestCase | @@ -1968,6 +1971,7 @@ class ProfileTest < ActiveSupport::TestCase | ||
| 1968 | end | 1971 | end |
| 1969 | 1972 | ||
| 1970 | environment = Environment.default | 1973 | environment = Environment.default |
| 1974 | + Noosfero::Plugin.stubs(:all).returns(['ProfileTest::Plugin1']) | ||
| 1971 | environment.enable_plugin(Plugin1) | 1975 | environment.enable_plugin(Plugin1) |
| 1972 | plugins = Noosfero::Plugin::Manager.new(environment, self) | 1976 | plugins = Noosfero::Plugin::Manager.new(environment, self) |
| 1973 | p = fast_create(Profile) | 1977 | p = fast_create(Profile) |
| @@ -0,0 +1,29 @@ | @@ -0,0 +1,29 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | + | ||
| 3 | +class RoleAssignmentExtTest < ActiveSupport::TestCase | ||
| 4 | + should 'increase organization members_count only on the first role_assignment' do | ||
| 5 | + role1 = Role.create!(:name => 'role1') | ||
| 6 | + role2 = Role.create!(:name => 'role2') | ||
| 7 | + member = create_user('person').person | ||
| 8 | + organization = Organization.create!(:name => 'Organization', :identifier => 'organization') | ||
| 9 | + assert_difference organization, :members_count, 1 do | ||
| 10 | + RoleAssignment.create!(:accessor => member, :resource => organization, :role => role1) | ||
| 11 | + RoleAssignment.create!(:accessor => member, :resource => organization, :role => role2) | ||
| 12 | + organization.reload | ||
| 13 | + end | ||
| 14 | + end | ||
| 15 | + | ||
| 16 | + should 'decrease organization members_count only on the last role_assignment' do | ||
| 17 | + role1 = Role.create!(:name => 'role1') | ||
| 18 | + role2 = Role.create!(:name => 'role2') | ||
| 19 | + member = create_user('person').person | ||
| 20 | + organization = Organization.create!(:name => 'Organization', :identifier => 'organization') | ||
| 21 | + RoleAssignment.create!(:accessor => member, :resource => organization, :role => role1) | ||
| 22 | + RoleAssignment.create!(:accessor => member, :resource => organization, :role => role2) | ||
| 23 | + organization.reload | ||
| 24 | + assert_difference organization, :members_count, -1 do | ||
| 25 | + organization.role_assignments.destroy_all | ||
| 26 | + organization.reload | ||
| 27 | + end | ||
| 28 | + end | ||
| 29 | +end |
test/unit/suggest_article_test.rb
| @@ -7,6 +7,7 @@ class SuggestArticleTest < ActiveSupport::TestCase | @@ -7,6 +7,7 @@ class SuggestArticleTest < ActiveSupport::TestCase | ||
| 7 | ActionMailer::Base.perform_deliveries = true | 7 | ActionMailer::Base.perform_deliveries = true |
| 8 | ActionMailer::Base.deliveries = [] | 8 | ActionMailer::Base.deliveries = [] |
| 9 | @profile = create_user('test_user').person | 9 | @profile = create_user('test_user').person |
| 10 | + Noosfero::Plugin.stubs(:all).returns(['SuggestArticleTest::EverythingIsSpam', 'SuggestArticleTest::SpamNotification']) | ||
| 10 | end | 11 | end |
| 11 | attr_reader :profile | 12 | attr_reader :profile |
| 12 | 13 |
test/unit/tags_helper_test.rb
| @@ -21,12 +21,14 @@ class TagsHelperTest < ActiveSupport::TestCase | @@ -21,12 +21,14 @@ class TagsHelperTest < ActiveSupport::TestCase | ||
| 21 | 21 | ||
| 22 | should 'order tags alphabetically with special characters' do | 22 | should 'order tags alphabetically with special characters' do |
| 23 | result = tag_cloud( | 23 | result = tag_cloud( |
| 24 | - { 'aula'=>9, 'área'=>2, 'area'=>2, 'avião'=>2, 'armário'=>2, | ||
| 25 | - 'A'=>1, 'Á'=>1, 'AB'=>1, 'ÁA'=>1 }, | 24 | + { 'area'=>9, 'área'=>2, 'base'=>2, 'báse' => 3, |
| 25 | + 'A'=>1, 'Á'=>1, 'zebra'=>1, 'zebrá'=>1 }, | ||
| 26 | :id, | 26 | :id, |
| 27 | { :host=>'noosfero.org', :controller=>'test', :action=>'tag' } | 27 | { :host=>'noosfero.org', :controller=>'test', :action=>'tag' } |
| 28 | ) | 28 | ) |
| 29 | - assert_equal %w(A Á ÁA AB area área armário aula avião).join("\n"), result | 29 | + result = result.split("\n") |
| 30 | + assert_order ['Á', 'área', 'báse', 'zebrá'], result | ||
| 31 | + assert_order ['A', 'area', 'base', 'zebra'], result | ||
| 30 | end | 32 | end |
| 31 | 33 | ||
| 32 | end | 34 | end |
test/unit/task_mailer_test.rb
| @@ -22,7 +22,7 @@ class TaskMailerTest < ActiveSupport::TestCase | @@ -22,7 +22,7 @@ class TaskMailerTest < ActiveSupport::TestCase | ||
| 22 | requestor.expects(:name).returns('my name') | 22 | requestor.expects(:name).returns('my name') |
| 23 | 23 | ||
| 24 | environment = mock() | 24 | environment = mock() |
| 25 | - environment.expects(:contact_email).returns('sender@example.com') | 25 | + environment.expects(:noreply_email).returns('sender@example.com') |
| 26 | environment.expects(:default_hostname).returns('example.com') | 26 | environment.expects(:default_hostname).returns('example.com') |
| 27 | environment.expects(:name).returns('example').at_least_once | 27 | environment.expects(:name).returns('example').at_least_once |
| 28 | 28 | ||
| @@ -45,7 +45,7 @@ class TaskMailerTest < ActiveSupport::TestCase | @@ -45,7 +45,7 @@ class TaskMailerTest < ActiveSupport::TestCase | ||
| 45 | requestor.expects(:name).returns('my name') | 45 | requestor.expects(:name).returns('my name') |
| 46 | 46 | ||
| 47 | environment = mock() | 47 | environment = mock() |
| 48 | - environment.expects(:contact_email).returns('sender@example.com') | 48 | + environment.expects(:noreply_email).returns('sender@example.com') |
| 49 | environment.expects(:default_hostname).returns('example.com') | 49 | environment.expects(:default_hostname).returns('example.com') |
| 50 | environment.expects(:name).returns('example').at_least_once | 50 | environment.expects(:name).returns('example').at_least_once |
| 51 | 51 | ||
| @@ -69,7 +69,7 @@ class TaskMailerTest < ActiveSupport::TestCase | @@ -69,7 +69,7 @@ class TaskMailerTest < ActiveSupport::TestCase | ||
| 69 | requestor.expects(:name).returns('my name') | 69 | requestor.expects(:name).returns('my name') |
| 70 | 70 | ||
| 71 | environment = mock() | 71 | environment = mock() |
| 72 | - environment.expects(:contact_email).returns('sender@example.com') | 72 | + environment.expects(:noreply_email).returns('sender@example.com') |
| 73 | environment.expects(:default_hostname).returns('example.com') | 73 | environment.expects(:default_hostname).returns('example.com') |
| 74 | environment.expects(:name).returns('example').at_least_once | 74 | environment.expects(:name).returns('example').at_least_once |
| 75 | 75 | ||
| @@ -105,7 +105,7 @@ class TaskMailerTest < ActiveSupport::TestCase | @@ -105,7 +105,7 @@ class TaskMailerTest < ActiveSupport::TestCase | ||
| 105 | requestor.stubs(:public_profile_url).returns('requestor_path') | 105 | requestor.stubs(:public_profile_url).returns('requestor_path') |
| 106 | 106 | ||
| 107 | environment = mock() | 107 | environment = mock() |
| 108 | - environment.expects(:contact_email).returns('sender@example.com') | 108 | + environment.expects(:noreply_email).returns('sender@example.com') |
| 109 | environment.expects(:default_hostname).returns('example.com') | 109 | environment.expects(:default_hostname).returns('example.com') |
| 110 | environment.expects(:name).returns('example').at_least_once | 110 | environment.expects(:name).returns('example').at_least_once |
| 111 | 111 | ||
| @@ -124,11 +124,11 @@ class TaskMailerTest < ActiveSupport::TestCase | @@ -124,11 +124,11 @@ class TaskMailerTest < ActiveSupport::TestCase | ||
| 124 | assert !ActionMailer::Base.deliveries.empty? | 124 | assert !ActionMailer::Base.deliveries.empty? |
| 125 | end | 125 | end |
| 126 | 126 | ||
| 127 | - should 'use environment name and contact email' do | 127 | + should 'use environment name and no-reply email' do |
| 128 | task = mock | 128 | task = mock |
| 129 | environment = mock | 129 | environment = mock |
| 130 | environment.expects(:name).returns('My name') | 130 | environment.expects(:name).returns('My name') |
| 131 | - environment.expects(:contact_email).returns('email@example.com') | 131 | + environment.expects(:noreply_email).returns('email@example.com') |
| 132 | 132 | ||
| 133 | task.expects(:environment).returns(environment).at_least_once | 133 | task.expects(:environment).returns(environment).at_least_once |
| 134 | 134 |
test/unit/text_article_test.rb
| @@ -38,4 +38,51 @@ class TextArticleTest < ActiveSupport::TestCase | @@ -38,4 +38,51 @@ class TextArticleTest < ActiveSupport::TestCase | ||
| 38 | assert_equal Blog.icon_name, TextArticle.icon_name(article) | 38 | assert_equal Blog.icon_name, TextArticle.icon_name(article) |
| 39 | end | 39 | end |
| 40 | 40 | ||
| 41 | + should 'change image path to relative' do | ||
| 42 | + person = create_user('testuser').person | ||
| 43 | + article = TextArticle.new(:profile => person, :name => 'test') | ||
| 44 | + env = Environment.default | ||
| 45 | + article.body = "<img src=\"http://#{env.default_hostname}/test.png\" />" | ||
| 46 | + article.save! | ||
| 47 | + assert_equal "<img src=\"/test.png\" />", article.body | ||
| 48 | + end | ||
| 49 | + | ||
| 50 | + should 'change link to relative path' do | ||
| 51 | + person = create_user('testuser').person | ||
| 52 | + article = TextArticle.new(:profile => person, :name => 'test') | ||
| 53 | + env = Environment.default | ||
| 54 | + article.body = "<a href=\"http://#{env.default_hostname}/test\">test</a>" | ||
| 55 | + article.save! | ||
| 56 | + assert_equal "<a href=\"/test\">test</a>", article.body | ||
| 57 | + end | ||
| 58 | + | ||
| 59 | + should 'change image path to relative for domain with https' do | ||
| 60 | + person = create_user('testuser').person | ||
| 61 | + article = TextArticle.new(:profile => person, :name => 'test') | ||
| 62 | + env = Environment.default | ||
| 63 | + article.body = "<img src=\"https://#{env.default_hostname}/test.png\" />" | ||
| 64 | + article.save! | ||
| 65 | + assert_equal "<img src=\"/test.png\" />", article.body | ||
| 66 | + end | ||
| 67 | + | ||
| 68 | + should 'change image path to relative for domain with port' do | ||
| 69 | + person = create_user('testuser').person | ||
| 70 | + article = TextArticle.new(:profile => person, :name => 'test') | ||
| 71 | + env = Environment.default | ||
| 72 | + article.body = "<img src=\"http://#{env.default_hostname}:3000/test.png\" />" | ||
| 73 | + article.save! | ||
| 74 | + assert_equal "<img src=\"/test.png\" />", article.body | ||
| 75 | + end | ||
| 76 | + | ||
| 77 | + should 'change image path to relative for domain with www' do | ||
| 78 | + person = create_user('testuser').person | ||
| 79 | + article = TextArticle.new(:profile => person, :name => 'test') | ||
| 80 | + env = Environment.default | ||
| 81 | + env.force_www = true | ||
| 82 | + env.save! | ||
| 83 | + article.body = "<img src=\"http://#{env.default_hostname}:3000/test.png\" />" | ||
| 84 | + article.save! | ||
| 85 | + assert_equal "<img src=\"/test.png\" />", article.body | ||
| 86 | + end | ||
| 87 | + | ||
| 41 | end | 88 | end |
test/unit/theme_test.rb
| @@ -191,4 +191,22 @@ class ThemeTest < ActiveSupport::TestCase | @@ -191,4 +191,22 @@ class ThemeTest < ActiveSupport::TestCase | ||
| 191 | assert ! Theme.new('test').public | 191 | assert ! Theme.new('test').public |
| 192 | end | 192 | end |
| 193 | 193 | ||
| 194 | + should 'not crash with nil or invalid owner_type' do | ||
| 195 | + profile = fast_create(Profile) | ||
| 196 | + Theme.stubs(:system_themes_dir).returns(TMP_THEMES_DIR) | ||
| 197 | + | ||
| 198 | + t1 = Theme.new('t1').save | ||
| 199 | + t1.send(:write_config) | ||
| 200 | + t2 = Theme.new('t2', {:owner_type => nil}).save | ||
| 201 | + t2.send(:write_config) | ||
| 202 | + t3 = Theme.new('t3', {:owner_type => 'InvalidClass'}).save | ||
| 203 | + t3.send(:write_config) | ||
| 204 | + | ||
| 205 | + assert_nothing_raised do | ||
| 206 | + themes = Theme.approved_themes(profile) | ||
| 207 | + assert_not_includes themes, t1 | ||
| 208 | + assert_not_includes themes, t2 | ||
| 209 | + assert_not_includes themes, t3 | ||
| 210 | + end | ||
| 211 | + end | ||
| 194 | end | 212 | end |
test/unit/uploaded_file_test.rb
| @@ -31,6 +31,13 @@ class UploadedFileTest < ActiveSupport::TestCase | @@ -31,6 +31,13 @@ class UploadedFileTest < ActiveSupport::TestCase | ||
| 31 | assert_equal 'test.txt', file.name | 31 | assert_equal 'test.txt', file.name |
| 32 | end | 32 | end |
| 33 | 33 | ||
| 34 | + should 'not set filename on name if name is already set' do | ||
| 35 | + file = UploadedFile.new | ||
| 36 | + file.name = "Some name" | ||
| 37 | + file.filename = 'test.txt' | ||
| 38 | + assert_equal 'Some name', file.name | ||
| 39 | + end | ||
| 40 | + | ||
| 34 | should 'provide file content as data' do | 41 | should 'provide file content as data' do |
| 35 | file = UploadedFile.new | 42 | file = UploadedFile.new |
| 36 | file.expects(:full_filename).returns('myfilename') | 43 | file.expects(:full_filename).returns('myfilename') |
| @@ -121,23 +128,13 @@ class UploadedFileTest < ActiveSupport::TestCase | @@ -121,23 +128,13 @@ class UploadedFileTest < ActiveSupport::TestCase | ||
| 121 | assert_equal 'my title', build(UploadedFile, :title => 'my title').title | 128 | assert_equal 'my title', build(UploadedFile, :title => 'my title').title |
| 122 | end | 129 | end |
| 123 | 130 | ||
| 124 | - should 'limit title to 140 characters' do | ||
| 125 | - upload = UploadedFile.new | ||
| 126 | - | ||
| 127 | - upload.title = '+' * 61; upload.valid? | ||
| 128 | - assert upload.errors[:title] | ||
| 129 | - | ||
| 130 | - upload.title = '+' * 60; upload.valid? | ||
| 131 | - assert_blank upload.errors[:title] | ||
| 132 | - end | ||
| 133 | - | ||
| 134 | should 'always provide a display title' do | 131 | should 'always provide a display title' do |
| 135 | upload = build(UploadedFile, :uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain')) | 132 | upload = build(UploadedFile, :uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain')) |
| 136 | - assert_equal 'test.txt', upload.display_title | 133 | + assert_equal 'test.txt', upload.title |
| 137 | upload.title = 'My text file' | 134 | upload.title = 'My text file' |
| 138 | - assert_equal 'My text file', upload.display_title | 135 | + assert_equal 'My text file', upload.title |
| 139 | upload.title = '' | 136 | upload.title = '' |
| 140 | - assert_equal 'test.txt', upload.display_title | 137 | + assert_equal 'test.txt', upload.title |
| 141 | end | 138 | end |
| 142 | 139 | ||
| 143 | should 'use name as title by default' do | 140 | should 'use name as title by default' do |
| @@ -327,6 +324,7 @@ class UploadedFileTest < ActiveSupport::TestCase | @@ -327,6 +324,7 @@ class UploadedFileTest < ActiveSupport::TestCase | ||
| 327 | end | 324 | end |
| 328 | 325 | ||
| 329 | should 'group trackers activity of image\'s upload' do | 326 | should 'group trackers activity of image\'s upload' do |
| 327 | + ActionTracker::Record.delete_all | ||
| 330 | gallery = fast_create(Gallery, :profile_id => profile.id) | 328 | gallery = fast_create(Gallery, :profile_id => profile.id) |
| 331 | 329 | ||
| 332 | image1 = create(UploadedFile, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => gallery, :profile => profile) | 330 | image1 = create(UploadedFile, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => gallery, :profile => profile) |
vendor/plugins/monkey_patches/rescue_delayed_job_crashes/init.rb
| @@ -5,8 +5,8 @@ Delayed::Worker.module_eval do | @@ -5,8 +5,8 @@ Delayed::Worker.module_eval do | ||
| 5 | environment = Environment.default | 5 | environment = Environment.default |
| 6 | 6 | ||
| 7 | recipients NOOSFERO_CONF['exception_recipients'] | 7 | recipients NOOSFERO_CONF['exception_recipients'] |
| 8 | - from environment.contact_email | ||
| 9 | - reply_to environment.contact_email | 8 | + from environment.noreply_email |
| 9 | + reply_to environment.noreply_email | ||
| 10 | subject "[#{environment.name}] DelayedJob ##{job.id}: #{error.message}" | 10 | subject "[#{environment.name}] DelayedJob ##{job.id}: #{error.message}" |
| 11 | body render(:text => " | 11 | body render(:text => " |
| 12 | Job: | 12 | Job: |