Commit 37b0a694516853a657e4f6eebf652210a7692fa6

Authored by Joenio Costa
2 parents 1249505f 4bceb5e5

Merge branch 'rails235' into AI3031-community_track_embed_block

Conflicts:
	test/unit/block_test.rb
Showing 230 changed files with 4737 additions and 681 deletions   Show diff stats
@@ -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 &lt;alessandro.palmeira@gmail.com&gt; @@ -38,6 +39,7 @@ Alessandro Palmeira + João M. M. Silva &lt;alessandro.palmeira@gmail.com&gt;
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 &lt;rr.manzo@gmail.com&gt; @@ -85,6 +87,7 @@ Daniel Alves + Rafael Manzo &lt;rr.manzo@gmail.com&gt;
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 &lt;diegoamc90@gmail.com&gt; @@ -114,12 +117,16 @@ Diego Martinez &lt;diegoamc90@gmail.com&gt;
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 &lt;renanteruoc@gmail.com&gt; @@ -202,6 +209,7 @@ Renan Teruo + Diego Araujo &lt;renanteruoc@gmail.com&gt;
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 &lt; BoxOrganizerController @@ -3,6 +3,8 @@ class EnvironmentDesignController &lt; 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 &lt; AdminController @@ -45,6 +45,20 @@ class UsersController &lt; 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 &lt; ApplicationController @@ -80,6 +80,22 @@ class BoxOrganizerController &lt; 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 &lt; ApplicationController @@ -99,6 +115,12 @@ class BoxOrganizerController &lt; ApplicationController
99 end 115 end
100 end 116 end
101 117
  118 + def clone_block
  119 + block = Block.find(params[:id])
  120 + block.duplicate
  121 + redirect_to :action => 'index'
  122 + end
  123 +
102 protected :boxes_editor? 124 protected :boxes_editor?
103 125
104 end 126 end
app/controllers/my_profile/cms_controller.rb
@@ -24,10 +24,16 @@ class CmsController &lt; MyProfileController @@ -24,10 +24,16 @@ class CmsController &lt; 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
@@ -221,11 +227,10 @@ class CmsController &lt; MyProfileController @@ -221,11 +227,10 @@ class CmsController &lt; MyProfileController
221 227
222 def update_categories 228 def update_categories
223 @object = params[:id] ? @profile.articles.find(params[:id]) : Article.new 229 @object = params[:id] ? @profile.articles.find(params[:id]) : Article.new
  230 + @categories = @toplevel_categories = environment.top_level_categories
224 if params[:category_id] 231 if params[:category_id]
225 @current_category = Category.find(params[:category_id]) 232 @current_category = Category.find(params[:category_id])
226 @categories = @current_category.children 233 @categories = @current_category.children
227 - else  
228 - @categories = environment.top_level_categories.select{|i| !i.children.empty?}  
229 end 234 end
230 render :partial => 'shared/select_categories', :locals => {:object_name => 'article', :multiple => true}, :layout => false 235 render :partial => 'shared/select_categories', :locals => {:object_name => 'article', :multiple => true}, :layout => false
231 end 236 end
app/controllers/my_profile/profile_design_controller.rb
@@ -55,10 +55,4 @@ class ProfileDesignController &lt; BoxOrganizerController @@ -55,10 +55,4 @@ class ProfileDesignController &lt; BoxOrganizerController
55 blocks 55 blocks
56 end 56 end
57 57
58 - def clone  
59 - block = Block.find(params[:id])  
60 - block.duplicate  
61 - redirect_to :action => 'index'  
62 - end  
63 -  
64 end 58 end
app/controllers/my_profile/profile_editor_controller.rb
@@ -55,11 +55,10 @@ class ProfileEditorController &lt; MyProfileController @@ -55,11 +55,10 @@ class ProfileEditorController &lt; 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 &lt; ApplicationController @@ -69,6 +69,8 @@ class AccountController &lt; 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 &lt; ApplicationController @@ -77,6 +79,7 @@ class AccountController &lt; 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 &lt; ApplicationController @@ -98,7 +101,7 @@ class AccountController &lt; 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
@@ -368,32 +371,29 @@ class AccountController &lt; ApplicationController @@ -368,32 +371,29 @@ class AccountController &lt; ApplicationController
368 end 371 end
369 372
370 def go_to_initial_page 373 def go_to_initial_page
  374 + if params[:redirection]
  375 + session[:return_to] = @user.return_to
  376 + @user.return_to = nil
  377 + @user.save
  378 + end
  379 +
371 if params[:return_to] 380 if params[:return_to]
372 redirect_to params[:return_to] 381 redirect_to params[:return_to]
373 elsif environment.enabled?('allow_change_of_redirection_after_login') 382 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 383 + check_redirection_options(user, user.preferred_login_redirection, user.admin_url)
388 else 384 else
389 if environment == current_user.environment 385 if environment == current_user.environment
390 - redirect_back_or_default(user.admin_url) 386 + check_redirection_options(user, environment.redirection_after_login, user.admin_url)
391 else 387 else
392 redirect_back_or_default(:controller => 'home') 388 redirect_back_or_default(:controller => 'home')
393 end 389 end
394 end 390 end
395 end 391 end
396 392
  393 + def go_to_signup_initial_page
  394 + check_redirection_options(user, user.environment.redirection_after_signup, user.url)
  395 + end
  396 +
397 def redirect_if_logged_in 397 def redirect_if_logged_in
398 if logged_in? 398 if logged_in?
399 go_to_initial_page 399 go_to_initial_page
@@ -409,4 +409,22 @@ class AccountController &lt; ApplicationController @@ -409,4 +409,22 @@ class AccountController &lt; ApplicationController
409 user 409 user
410 end 410 end
411 411
  412 + protected
  413 +
  414 + def check_redirection_options(user, condition, default)
  415 + case condition
  416 + when 'keep_on_same_page'
  417 + redirect_back_or_default(user.admin_url)
  418 + when 'site_homepage'
  419 + redirect_to :controller => :home
  420 + when 'user_profile_page'
  421 + redirect_to user.public_profile_url
  422 + when 'user_homepage'
  423 + redirect_to user.url
  424 + when 'user_control_panel'
  425 + redirect_to user.admin_url
  426 + else
  427 + redirect_back_or_default(default)
  428 + end
  429 + end
412 end 430 end
app/controllers/public/content_viewer_controller.rb
@@ -111,6 +111,15 @@ class ContentViewerController &lt; ApplicationController @@ -111,6 +111,15 @@ class ContentViewerController &lt; ApplicationController
111 @comments = @plugins.filter(:unavailable_comments, @comments) 111 @comments = @plugins.filter(:unavailable_comments, @comments)
112 @comments_count = @comments.count 112 @comments_count = @comments.count
113 @comments = @comments.without_reply.paginate(:per_page => per_page, :page => params[:comment_page] ) 113 @comments = @comments.without_reply.paginate(:per_page => per_page, :page => params[:comment_page] )
  114 + @comment_order = params[:comment_order].nil? ? 'oldest' : params[:comment_order]
  115 +
  116 + if request.xhr? and params[:comment_order]
  117 + if @comment_order == 'newest'
  118 + @comments = @comments.reverse
  119 + end
  120 +
  121 + return render :partial => 'comment/comment', :collection => @comments
  122 + end
114 123
115 if params[:slideshow] 124 if params[:slideshow]
116 render :action => 'slideshow', :layout => 'slideshow' 125 render :action => 'slideshow', :layout => 'slideshow'
app/controllers/public/events_controller.rb
@@ -7,11 +7,11 @@ class EventsController &lt; PublicController @@ -7,11 +7,11 @@ class EventsController &lt; 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)
@@ -29,4 +29,7 @@ class EventsController &lt; PublicController @@ -29,4 +29,7 @@ class EventsController &lt; 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/profile_controller.rb
@@ -304,14 +304,6 @@ class ProfileController &lt; PublicController @@ -304,14 +304,6 @@ class ProfileController &lt; PublicController
304 end 304 end
305 end 305 end
306 306
307 - def profile_info  
308 - begin  
309 - @block = profile.blocks.find(params[:block_id])  
310 - rescue  
311 - render :text => _('Profile information could not be loaded')  
312 - end  
313 - end  
314 -  
315 def report_abuse 307 def report_abuse
316 @abuse_report = AbuseReport.new 308 @abuse_report = AbuseReport.new
317 render :layout => false 309 render :layout => false
app/controllers/public/search_controller.rb
@@ -99,14 +99,14 @@ class SearchController &lt; PublicController @@ -99,14 +99,14 @@ class SearchController &lt; 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 &lt; PublicController @@ -139,7 +139,7 @@ class SearchController &lt; 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 &lt; PublicController @@ -224,4 +224,8 @@ class SearchController &lt; 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 &lt; ApplicationController @@ -12,7 +12,7 @@ class ThemesController &lt; 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/application_helper.rb
@@ -608,49 +608,18 @@ module ApplicationHelper @@ -608,49 +608,18 @@ module ApplicationHelper
608 end 608 end
609 609
610 attr_reader :environment 610 attr_reader :environment
  611 +
611 def select_categories(object_name, title=nil, title_size=4) 612 def select_categories(object_name, title=nil, title_size=4)
612 return nil if environment.enabled?(:disable_categories) 613 return nil if environment.enabled?(:disable_categories)
613 if title.nil? 614 if title.nil?
614 title = _('Categories') 615 title = _('Categories')
615 end 616 end
616 617
617 - object = instance_variable_get("@#{object_name}")  
618 -  
619 - result = content_tag 'h'+title_size.to_s(), title  
620 - result << javascript_tag( 'function open_close_cat( link ) {  
621 - var div = link.parentNode.getElementsByTagName("div")[0];  
622 - var end = function(){  
623 - if ( div.style.display == "none" ) {  
624 - this.link.className="button icon-button icon-down"  
625 - } else {  
626 - this.link.className="button icon-button icon-up-red"  
627 - }  
628 - }  
629 - Effect.toggle( div, "slide", { link:link, div:div, afterFinish:end } )  
630 - }')  
631 - environment.top_level_categories.select{|i| !i.children.empty?}.each do |toplevel|  
632 - next unless object.accept_category?(toplevel)  
633 - # FIXME  
634 - ([toplevel] + toplevel.children_for_menu).each do |cat|  
635 - if cat.top_level?  
636 - result << '<div class="categorie_box">'.html_safe  
637 - result << icon_button( :down, _('open'), '#', :onclick => 'open_close_cat(this); return false' )  
638 - result << content_tag('h5', toplevel.name)  
639 - result << '<div style="display:none"><ul class="categories">'.html_safe  
640 - else  
641 - checkbox_id = "#{object_name}_#{cat.full_name.downcase.gsub(/\s+|\//, '_')}"  
642 - result << content_tag('li', labelled_check_box(  
643 - cat.full_name_without_leading(1, " &rarr; "),  
644 - "#{object_name}[category_ids][]", cat.id,  
645 - object.category_ids.include?(cat.id), :id => checkbox_id,  
646 - :onchange => 'this.parentNode.className=(this.checked?"cat_checked":"")' ),  
647 - :class => ( object.category_ids.include?(cat.id) ? 'cat_checked' : '' ) ) + "\n"  
648 - end  
649 - end  
650 - result << '</ul></div></div>'.html_safe  
651 - end 618 + @object = instance_variable_get("@#{object_name}")
  619 + @categories = environment.top_level_categories
652 620
653 - content_tag('div', result) 621 + @current_categories = environment.top_level_categories.select{|i| !i.children.empty?}
  622 + 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
654 end 623 end
655 624
656 def theme_option(opt = nil) 625 def theme_option(opt = nil)
@@ -920,12 +889,11 @@ module ApplicationHelper @@ -920,12 +889,11 @@ module ApplicationHelper
920 889
921 def page_title 890 def page_title
922 (@page ? @page.title + ' - ' : '') + 891 (@page ? @page.title + ' - ' : '') +
923 - (profile ? profile.short_name + ' - ' : '') +  
924 (@topic ? @topic.title + ' - ' : '') + 892 (@topic ? @topic.title + ' - ' : '') +
925 (@section ? @section.title + ' - ' : '') + 893 (@section ? @section.title + ' - ' : '') +
926 (@toc ? _('Online Manual') + ' - ' : '') + 894 (@toc ? _('Online Manual') + ' - ' : '') +
927 (@controller.controller_name == 'chat' ? _('Chat') + ' - ' : '') + 895 (@controller.controller_name == 'chat' ? _('Chat') + ' - ' : '') +
928 - environment.name + 896 + (profile ? profile.short_name : environment.name) +
929 (@category ? " - #{@category.full_name}" : '') 897 (@category ? " - #{@category.full_name}" : '')
930 end 898 end
931 899
app/helpers/article_helper.rb
@@ -49,8 +49,14 @@ module ArticleHelper @@ -49,8 +49,14 @@ module ArticleHelper
49 'div', 49 'div',
50 check_box(:article, :display_versions) + 50 check_box(:article, :display_versions) +
51 content_tag('label', _('I want this article to display a link to older versions'), :for => 'article_display_versions') 51 content_tag('label', _('I want this article to display a link to older versions'), :for => 'article_display_versions')
52 - ) : '') 52 + ) : '') +
53 53
  54 + (article.forum? && article.profile.community? ?
  55 + content_tag(
  56 + 'div',
  57 + check_box(:article, :allows_members_to_create_topics) +
  58 + content_tag('label', _('Allow members to create topics'), :for => 'article_allows_members_to_create_topics')
  59 + ) : '')
54 ) 60 )
55 end 61 end
56 62
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,7 +212,7 @@ module BoxesHelper @@ -212,7 +212,7 @@ 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)
app/helpers/cache_counter_helper.rb 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +module CacheCounterHelper
  2 + def update_cache_counter(name, object, value)
  3 + if object.present?
  4 + object.class.update_counters(object.id, name => value)
  5 + end
  6 + end
  7 +end
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(' &rarr; '), 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?(File.join(Rails.root, 'public', theme_path, 'images', 'addthis.gif')) 55 if File.exists?(File.join(Rails.root, '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
@@ -90,5 +90,8 @@ module LayoutHelper @@ -90,5 +90,8 @@ module LayoutHelper
90 end 90 end
91 end 91 end
92 92
  93 + def meta_description_tag(article=nil)
  94 + article ? truncate(strip_tags(article.body.to_s), :length => 200) : environment.name
  95 + end
93 end 96 end
94 97
app/helpers/macros_helper.rb
@@ -20,14 +20,16 @@ module MacrosHelper @@ -20,14 +20,16 @@ module MacrosHelper
20 jQuery('<div>'+#{macro_configuration_dialog(macro).to_json}+'</div>').dialog({ 20 jQuery('<div>'+#{macro_configuration_dialog(macro).to_json}+'</div>').dialog({
21 title: #{macro_title(macro).to_json}, 21 title: #{macro_title(macro).to_json},
22 modal: true, 22 modal: true,
23 - buttons: [  
24 - {text: #{_('Ok').to_json}, click: function(){ 23 + buttons: {
  24 + #{_('Ok').to_json}: function(){
25 tinyMCE.activeEditor.execCommand('mceInsertContent', false, 25 tinyMCE.activeEditor.execCommand('mceInsertContent', false,
26 (function(dialog){ #{macro_generator(macro)} })(this)); 26 (function(dialog){ #{macro_generator(macro)} })(this));
27 jQuery(this).dialog('close'); 27 jQuery(this).dialog('close');
28 - }},  
29 - {text: #{_('Cancel').to_json}, click: function(){jQuery(this).dialog('close');}}  
30 - ] 28 + },
  29 + #{_('Cancel').to_json}: function(){
  30 + jQuery(this).dialog('close');
  31 + }
  32 + }
31 }); 33 });
32 }" 34 }"
33 end 35 end
@@ -57,7 +59,11 @@ module MacrosHelper @@ -57,7 +59,11 @@ module MacrosHelper
57 59
58 def macro_generator(macro) 60 def macro_generator(macro)
59 if macro.configuration[:generator] 61 if macro.configuration[:generator]
60 - macro.configuration[:generator] 62 + if macro.configuration[:generator].respond_to?(:call)
  63 + macro.configuration[:generator].call(macro)
  64 + else
  65 + macro.configuration[:generator]
  66 + end
61 else 67 else
62 macro_default_generator(macro) 68 macro_default_generator(macro)
63 end 69 end
@@ -66,8 +72,7 @@ module MacrosHelper @@ -66,8 +72,7 @@ module MacrosHelper
66 72
67 def macro_default_generator(macro) 73 def macro_default_generator(macro)
68 code = "var params = {};" 74 code = "var params = {};"
69 - configuration = macro_configuration(macro)  
70 - configuration[:params].map do |field| 75 + macro.configuration[:params].map do |field|
71 code += "params.#{field[:name]} = jQuery('*[name=#{field[:name]}]', dialog).val();" 76 code += "params.#{field[:name]} = jQuery('*[name=#{field[:name]}]', dialog).val();"
72 end 77 end
73 code + " 78 code + "
app/helpers/person_notifier_helper.rb 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +module PersonNotifierHelper
  2 +
  3 + include ApplicationHelper
  4 +
  5 + private
  6 +
  7 + def path_to_image(source)
  8 + top_url + source
  9 + end
  10 +
  11 + def top_url
  12 + top_url = @profile.environment ? @profile.environment.top_url : ''
  13 + end
  14 +
  15 +end
app/helpers/token_helper.rb
@@ -27,7 +27,7 @@ module TokenHelper @@ -27,7 +27,7 @@ module TokenHelper
27 hintText: #{options[:hint_text].to_json}, 27 hintText: #{options[:hint_text].to_json},
28 noResultsText: #{options[:no_results_text].to_json}, 28 noResultsText: #{options[:no_results_text].to_json},
29 searchingText: #{options[:searching_text].to_json}, 29 searchingText: #{options[:searching_text].to_json},
30 - searchDelay: #{options[:serach_delay].to_json}, 30 + searchDelay: #{options[:search_delay].to_json},
31 preventDuplicates: #{options[:prevent_duplicates].to_json}, 31 preventDuplicates: #{options[:prevent_duplicates].to_json},
32 backspaceDeleteItem: #{options[:backspace_delete_item].to_json}, 32 backspaceDeleteItem: #{options[:backspace_delete_item].to_json},
33 queryParam: #{name.to_json}, 33 queryParam: #{name.to_json},
app/models/block.rb
@@ -30,11 +30,13 @@ class Block &lt; ActiveRecord::Base @@ -30,11 +30,13 @@ class Block &lt; ActiveRecord::Base
30 # 30 #
31 # * <tt>:article</tt>: the article being viewed currently 31 # * <tt>:article</tt>: the article being viewed currently
32 # * <tt>:language</tt>: in which language the block will be displayed 32 # * <tt>:language</tt>: in which language the block will be displayed
  33 + # * <tt>:user</tt>: the logged user
33 def visible?(context = nil) 34 def visible?(context = nil)
34 return false if display == 'never' 35 return false if display == 'never'
35 36
36 if context 37 if context
37 return false if language != 'all' && language != context[:locale] 38 return false if language != 'all' && language != context[:locale]
  39 + return false unless display_to_user?(context[:user])
38 40
39 begin 41 begin
40 return self.send("display_#{display}", context) 42 return self.send("display_#{display}", context)
@@ -46,6 +48,10 @@ class Block &lt; ActiveRecord::Base @@ -46,6 +48,10 @@ class Block &lt; ActiveRecord::Base
46 true 48 true
47 end 49 end
48 50
  51 + def display_to_user?(user)
  52 + display_user == 'all' || (user.nil? && display_user == 'not_logged') || (user && display_user == 'logged')
  53 + end
  54 +
49 def display_always(context) 55 def display_always(context)
50 true 56 true
51 end 57 end
@@ -76,6 +82,14 @@ class Block &lt; ActiveRecord::Base @@ -76,6 +82,14 @@ class Block &lt; ActiveRecord::Base
76 # the homepage of its owner. 82 # the homepage of its owner.
77 settings_items :display, :type => :string, :default => 'always' 83 settings_items :display, :type => :string, :default => 'always'
78 84
  85 +
  86 + # The condition for displaying a block to users. It can assume the following values:
  87 + #
  88 + # * <tt>'all'</tt>: the block is always displayed
  89 + # * <tt>'logged'</tt>: the block is displayed to logged users only
  90 + # * <tt>'not_logged'</tt>: the block is displayed only to not logged users
  91 + settings_items :display_user, :type => :string, :default => 'all'
  92 +
79 # The block can be configured to be displayed in all languages or in just one language. It can assume any locale of the environment: 93 # The block can be configured to be displayed in all languages or in just one language. It can assume any locale of the environment:
80 # 94 #
81 # * <tt>'all'</tt>: the block is always displayed 95 # * <tt>'all'</tt>: the block is always displayed
@@ -149,7 +163,7 @@ class Block &lt; ActiveRecord::Base @@ -149,7 +163,7 @@ class Block &lt; ActiveRecord::Base
149 end 163 end
150 164
151 alias :active_record_cache_key :cache_key 165 alias :active_record_cache_key :cache_key
152 - def cache_key(language='en') 166 + def cache_key(language='en', user=nil)
153 active_record_cache_key+'-'+language 167 active_record_cache_key+'-'+language
154 end 168 end
155 169
@@ -179,12 +193,20 @@ class Block &lt; ActiveRecord::Base @@ -179,12 +193,20 @@ class Block &lt; ActiveRecord::Base
179 'never' => __('Don\'t display'), 193 'never' => __('Don\'t display'),
180 } 194 }
181 195
182 - def display_options 196 + def display_options_available
183 DISPLAY_OPTIONS.keys 197 DISPLAY_OPTIONS.keys
184 end 198 end
185 199
186 - def display_option_label(option)  
187 - DISPLAY_OPTIONS[option] 200 + def display_options
  201 + DISPLAY_OPTIONS.slice(*display_options_available)
  202 + end
  203 +
  204 + def display_user_options
  205 + @display_user_options ||= {
  206 + 'all' => __('All users'),
  207 + 'logged' => __('Logged'),
  208 + 'not_logged' => __('Not logged'),
  209 + }
188 end 210 end
189 211
190 def duplicate 212 def duplicate
app/models/box.rb
@@ -26,6 +26,8 @@ class Box &lt; ActiveRecord::Base @@ -26,6 +26,8 @@ class Box &lt; ActiveRecord::Base
26 CategoriesBlock, 26 CategoriesBlock,
27 CommunitiesBlock, 27 CommunitiesBlock,
28 EnterprisesBlock, 28 EnterprisesBlock,
  29 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  30 + # the Noosfero core soon, see ActionItem3045
29 EnvironmentStatisticsBlock, 31 EnvironmentStatisticsBlock,
30 FansBlock, 32 FansBlock,
31 FavoriteEnterprisesBlock, 33 FavoriteEnterprisesBlock,
@@ -52,6 +54,8 @@ class Box &lt; ActiveRecord::Base @@ -52,6 +54,8 @@ class Box &lt; ActiveRecord::Base
52 CommunitiesBlock, 54 CommunitiesBlock,
53 DisabledEnterpriseMessageBlock, 55 DisabledEnterpriseMessageBlock,
54 EnterprisesBlock, 56 EnterprisesBlock,
  57 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  58 + # the Noosfero core soon, see ActionItem3045
55 EnvironmentStatisticsBlock, 59 EnvironmentStatisticsBlock,
56 FansBlock, 60 FansBlock,
57 FavoriteEnterprisesBlock, 61 FavoriteEnterprisesBlock,
app/models/comment.rb
@@ -172,7 +172,7 @@ class Comment &lt; ActiveRecord::Base @@ -172,7 +172,7 @@ class Comment &lt; ActiveRecord::Base
172 def mail(comment) 172 def mail(comment)
173 profile = comment.article.profile 173 profile = comment.article.profile
174 recipients comment.notification_emails 174 recipients comment.notification_emails
175 - from "#{profile.environment.name} <#{profile.environment.contact_email}>" 175 + from "#{profile.environment.name} <#{profile.environment.noreply_email}>"
176 subject _("[%s] you got a new comment!") % [profile.environment.name] 176 subject _("[%s] you got a new comment!") % [profile.environment.name]
177 body :recipient => profile.nickname || profile.name, 177 body :recipient => profile.nickname || profile.name,
178 :sender => comment.author_name, 178 :sender => comment.author_name,
@@ -187,7 +187,7 @@ class Comment &lt; ActiveRecord::Base @@ -187,7 +187,7 @@ class Comment &lt; ActiveRecord::Base
187 def mail_to_followers(comment, emails) 187 def mail_to_followers(comment, emails)
188 profile = comment.article.profile 188 profile = comment.article.profile
189 bcc emails 189 bcc emails
190 - from "#{profile.environment.name} <#{profile.environment.contact_email}>" 190 + from "#{profile.environment.name} <#{profile.environment.noreply_email}>"
191 subject _("[%s] %s commented on a content of %s") % [profile.environment.name, comment.author_name, profile.short_name] 191 subject _("[%s] %s commented on a content of %s") % [profile.environment.name, comment.author_name, profile.short_name]
192 body :recipient => profile.nickname || profile.name, 192 body :recipient => profile.nickname || profile.name,
193 :sender => comment.author_name, 193 :sender => comment.author_name,
app/models/contact.rb
@@ -26,7 +26,7 @@ class Contact &lt; ActiveRecord::Base #WithoutTable @@ -26,7 +26,7 @@ class Contact &lt; ActiveRecord::Base #WithoutTable
26 content_type 'text/html' 26 content_type 'text/html'
27 emails = contact.dest.notification_emails 27 emails = contact.dest.notification_emails
28 recipients emails 28 recipients emails
29 - from "#{contact.name} <#{contact.dest.environment.contact_email}>" 29 + from "#{contact.name} <#{contact.dest.environment.noreply_email}>"
30 reply_to contact.email 30 reply_to contact.email
31 if contact.sender 31 if contact.sender
32 headers 'X-Noosfero-Sender' => contact.sender.identifier 32 headers 'X-Noosfero-Sender' => contact.sender.identifier
app/models/environment.rb
@@ -145,6 +145,18 @@ class Environment &lt; ActiveRecord::Base @@ -145,6 +145,18 @@ class Environment &lt; ActiveRecord::Base
145 end 145 end
146 validates_inclusion_of :redirection_after_login, :in => Environment.login_redirection_options.keys, :allow_nil => true 146 validates_inclusion_of :redirection_after_login, :in => Environment.login_redirection_options.keys, :allow_nil => true
147 147
  148 + def self.signup_redirection_options
  149 + {
  150 + 'keep_on_same_page' => _('Stays on the same page the user was before signup.'),
  151 + 'site_homepage' => _('Redirects the user to the environment homepage.'),
  152 + 'user_profile_page' => _('Redirects the user to his profile page.'),
  153 + 'user_homepage' => _('Redirects the user to his homepage.'),
  154 + 'user_control_panel' => _('Redirects the user to his control panel.')
  155 + }
  156 + end
  157 + validates_inclusion_of :redirection_after_signup, :in => Environment.signup_redirection_options.keys, :allow_nil => true
  158 +
  159 +
148 # ################################################# 160 # #################################################
149 # Relationships and applied behaviour 161 # Relationships and applied behaviour
150 # ################################################# 162 # #################################################
@@ -161,6 +173,8 @@ class Environment &lt; ActiveRecord::Base @@ -161,6 +173,8 @@ class Environment &lt; ActiveRecord::Base
161 173
162 # "left" area 174 # "left" area
163 env.boxes[1].blocks << LoginBlock.new 175 env.boxes[1].blocks << LoginBlock.new
  176 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  177 + # the Noosfero core soon, see ActionItem3045
164 env.boxes[1].blocks << EnvironmentStatisticsBlock.new 178 env.boxes[1].blocks << EnvironmentStatisticsBlock.new
165 env.boxes[1].blocks << RecentDocumentsBlock.new 179 env.boxes[1].blocks << RecentDocumentsBlock.new
166 180
@@ -592,7 +606,7 @@ class Environment &lt; ActiveRecord::Base @@ -592,7 +606,7 @@ class Environment &lt; ActiveRecord::Base
592 # only one environment can be the default one 606 # only one environment can be the default one
593 validates_uniqueness_of :is_default, :if => (lambda do |environment| environment.is_default? end), :message => N_('Only one Virtual Community can be the default one') 607 validates_uniqueness_of :is_default, :if => (lambda do |environment| environment.is_default? end), :message => N_('Only one Virtual Community can be the default one')
594 608
595 - validates_format_of :contact_email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda { |record| ! record.contact_email.blank? }) 609 + validates_format_of :contact_email, :noreply_email, :with => Noosfero::Constants::EMAIL_FORMAT, :allow_blank => true
596 610
597 xss_terminate :only => [ :message_for_disabled_enterprise ], :with => 'white_list', :on => 'validation' 611 xss_terminate :only => [ :message_for_disabled_enterprise ], :with => 'white_list', :on => 'validation'
598 612
@@ -779,7 +793,7 @@ class Environment &lt; ActiveRecord::Base @@ -779,7 +793,7 @@ class Environment &lt; ActiveRecord::Base
779 end 793 end
780 794
781 def notification_emails 795 def notification_emails
782 - [contact_email.blank? ? nil : contact_email].compact + admins.map(&:email) 796 + [noreply_email.blank? ? nil : noreply_email].compact + admins.map(&:email)
783 end 797 end
784 798
785 after_create :create_templates 799 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
@@ -38,15 +38,12 @@ class Event &lt; Article @@ -38,15 +38,12 @@ class Event &lt; Article
38 named_scope :next_events_from_month, lambda { |date| 38 named_scope :next_events_from_month, lambda { |date|
39 date_temp = date.strftime("%Y-%m-%d") 39 date_temp = date.strftime("%Y-%m-%d")
40 { :conditions => ["start_date >= ?","#{date_temp}"], 40 { :conditions => ["start_date >= ?","#{date_temp}"],
41 - :limit => 10,  
42 :order => 'start_date ASC' 41 :order => 'start_date ASC'
43 } 42 }
44 } 43 }
45 44
46 named_scope :by_month, lambda { |date| 45 named_scope :by_month, lambda { |date|
47 - date_temp = date.strftime("%Y-%m")  
48 { :conditions => ["EXTRACT(YEAR FROM start_date) = ? AND EXTRACT(MONTH FROM start_date) = ?",date.year,date.month], 46 { :conditions => ["EXTRACT(YEAR FROM start_date) = ? AND EXTRACT(MONTH FROM start_date) = ?",date.year,date.month],
49 - :limit => 10,  
50 :order => 'start_date ASC' 47 :order => 'start_date ASC'
51 } 48 }
52 } 49 }
app/models/forum.rb
@@ -5,6 +5,7 @@ class Forum &lt; Folder @@ -5,6 +5,7 @@ class Forum &lt; Folder
5 5
6 settings_items :terms_of_use, :type => :string, :default => "" 6 settings_items :terms_of_use, :type => :string, :default => ""
7 settings_items :has_terms_of_use, :type => :boolean, :default => false 7 settings_items :has_terms_of_use, :type => :boolean, :default => false
  8 + settings_items :allows_members_to_create_topics, :type => :boolean, :default => false
8 has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people' 9 has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people'
9 10
10 before_save do |forum| 11 before_save do |forum|
@@ -66,4 +67,11 @@ class Forum &lt; Folder @@ -66,4 +67,11 @@ class Forum &lt; Folder
66 self.users_with_agreement.exists? user 67 self.users_with_agreement.exists? user
67 end 68 end
68 69
  70 + def can_create_topic?(user, profile)
  71 + return profile.community? && profile.members.include?(user) && self.allows_members_to_create_topics
  72 + end
  73 +
  74 + def allow_create?(user)
  75 + super || can_create_topic?(user, profile)
  76 + end
69 end 77 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
@@ -70,6 +70,8 @@ class LinkListBlock &lt; Block @@ -70,6 +70,8 @@ class LinkListBlock &lt; Block
70 def expand_address(address) 70 def expand_address(address)
71 add = if owner.respond_to?(:identifier) 71 add = if owner.respond_to?(:identifier)
72 address.gsub('{profile}', owner.identifier) 72 address.gsub('{profile}', owner.identifier)
  73 + elsif owner.is_a?(Environment) && owner.enabled?('use_portal_community') && owner.portal_community
  74 + address.gsub('{portal}', owner.portal_community.identifier)
73 else 75 else
74 address 76 address
75 end 77 end
app/models/mailing.rb
@@ -17,7 +17,7 @@ class Mailing &lt; ActiveRecord::Base @@ -17,7 +17,7 @@ class Mailing &lt; ActiveRecord::Base
17 end 17 end
18 18
19 def generate_from 19 def generate_from
20 - "#{source.name} <#{source.contact_email}>" 20 + "#{source.name} <#{if source.is_a? Environment then source.noreply_email else source.contact_email end}>"
21 end 21 end
22 22
23 def generate_subject 23 def generate_subject
app/models/main_block.rb
@@ -24,7 +24,7 @@ class MainBlock &lt; Block @@ -24,7 +24,7 @@ class MainBlock &lt; Block
24 false 24 false
25 end 25 end
26 26
27 - def display_options 27 + def display_options_available
28 ['always', 'except_home_page'] 28 ['always', 'except_home_page']
29 end 29 end
30 30
app/models/members_block.rb
@@ -36,4 +36,15 @@ class MembersBlock &lt; ProfileListBlock @@ -36,4 +36,15 @@ class MembersBlock &lt; ProfileListBlock
36 } 36 }
37 end 37 end
38 38
  39 + def cache_key(language='en', user=nil)
  40 + logged = ''
  41 + if user
  42 + logged += '-logged-in'
  43 + if user.is_member_of? self.owner
  44 + logged += '-member'
  45 + end
  46 + end
  47 + super + logged
  48 + end
  49 +
39 end 50 end
app/models/organization.rb
@@ -26,18 +26,7 @@ class Organization &lt; Profile @@ -26,18 +26,7 @@ class Organization &lt; Profile
26 26
27 has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source' 27 has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source'
28 28
29 - named_scope :more_popular,  
30 - :select => "#{Profile.qualified_column_names}, count(resource_id) as total",  
31 - :group => Profile.qualified_column_names,  
32 - :joins => "LEFT OUTER JOIN role_assignments ON profiles.id = role_assignments.resource_id",  
33 - :order => "total DESC"  
34 -  
35 - named_scope :more_active,  
36 - :select => "#{Profile.qualified_column_names}, count(action_tracker.id) as total",  
37 - :joins => "LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.target_id",  
38 - :group => Profile.qualified_column_names,  
39 - :order => 'total DESC',  
40 - :conditions => ['action_tracker.created_at >= ? OR action_tracker.id IS NULL', ActionTracker::Record::RECENT_DELAY.days.ago] 29 + named_scope :more_popular, :order => 'members_count DESC'
41 30
42 def validation_methodology 31 def validation_methodology
43 self.validation_info ? self.validation_info.validation_methodology : nil 32 self.validation_info ? self.validation_info.validation_methodology : nil
app/models/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/models/pending_task_notifier.rb
@@ -2,7 +2,7 @@ class PendingTaskNotifier &lt; ActionMailer::Base @@ -2,7 +2,7 @@ class PendingTaskNotifier &lt; ActionMailer::Base
2 2
3 def notification(person) 3 def notification(person)
4 recipients person.email 4 recipients person.email
5 - from "#{person.environment.name} <#{person.environment.contact_email}>" 5 + from "#{person.environment.name} <#{person.environment.noreply_email}>"
6 subject _("[%s] Pending tasks") % person.environment.name 6 subject _("[%s] Pending tasks") % person.environment.name
7 body :person => person, 7 body :person => person,
8 :tasks => person.tasks.pending, 8 :tasks => person.tasks.pending,
app/models/person.rb
@@ -71,18 +71,7 @@ class Person &lt; Profile @@ -71,18 +71,7 @@ class Person &lt; Profile
71 has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people' 71 has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people'
72 has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions' 72 has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions'
73 73
74 - named_scope :more_popular,  
75 - :select => "#{Profile.qualified_column_names}, count(friend_id) as total",  
76 - :group => Profile.qualified_column_names,  
77 - :joins => "LEFT OUTER JOIN friendships on profiles.id = friendships.person_id",  
78 - :order => "total DESC"  
79 -  
80 - named_scope :more_active,  
81 - :select => "#{Profile.qualified_column_names}, count(action_tracker.id) as total",  
82 - :joins => "LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.user_id",  
83 - :group => Profile.qualified_column_names,  
84 - :order => 'total DESC',  
85 - :conditions => ['action_tracker.created_at >= ? OR action_tracker.id IS NULL', ActionTracker::Record::RECENT_DELAY.days.ago] 74 + named_scope :more_popular, :order => 'friends_count DESC'
86 75
87 named_scope :abusers, :joins => :abuse_complaints, :conditions => ['tasks.status = 3'], :select => 'DISTINCT profiles.*' 76 named_scope :abusers, :joins => :abuse_complaints, :conditions => ['tasks.status = 3'], :select => 'DISTINCT profiles.*'
88 named_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.*" 77 named_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.*"
@@ -501,6 +490,17 @@ class Person &lt; Profile @@ -501,6 +490,17 @@ class Person &lt; Profile
501 gravatar_profile_image_url(self.email, :size=>20, :d => gravatar_default) 490 gravatar_profile_image_url(self.email, :size=>20, :d => gravatar_default)
502 end 491 end
503 492
  493 + settings_items :last_notification, :type => DateTime
  494 + settings_items :notification_time, :type => :integer, :default => 0
  495 +
  496 + def notifier
  497 + @notifier ||= PersonNotifier.new(self)
  498 + end
  499 +
  500 + after_update do |person|
  501 + person.notifier.reschedule_next_notification_mail
  502 + end
  503 +
504 protected 504 protected
505 505
506 def followed_by?(profile) 506 def followed_by?(profile)
app/models/person_notifier.rb 0 → 100644
@@ -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
@@ -92,10 +92,6 @@ class Profile &lt; ActiveRecord::Base @@ -92,10 +92,6 @@ class Profile &lt; ActiveRecord::Base
92 members.order(:name) 92 members.order(:name)
93 end 93 end
94 94
95 - def members_count  
96 - members.count  
97 - end  
98 -  
99 class << self 95 class << self
100 def count_with_distinct(*args) 96 def count_with_distinct(*args)
101 options = args.last || {} 97 options = args.last || {}
@@ -118,10 +114,11 @@ class Profile &lt; ActiveRecord::Base @@ -118,10 +114,11 @@ class Profile &lt; ActiveRecord::Base
118 114
119 named_scope :visible, :conditions => { :visible => true } 115 named_scope :visible, :conditions => { :visible => true }
120 named_scope :public, :conditions => { :visible => true, :public_profile => true } 116 named_scope :public, :conditions => { :visible => true, :public_profile => true }
121 - # Subclasses must override these methods 117 +
  118 + # Subclasses must override this method
122 named_scope :more_popular 119 named_scope :more_popular
123 - named_scope :more_active  
124 120
  121 + named_scope :more_active, :order => 'activities_count DESC'
125 named_scope :more_recent, :order => "created_at DESC" 122 named_scope :more_recent, :order => "created_at DESC"
126 123
127 acts_as_trackable :dependent => :destroy 124 acts_as_trackable :dependent => :destroy
@@ -616,10 +613,10 @@ private :generate_url, :url_options @@ -616,10 +613,10 @@ private :generate_url, :url_options
616 # Adds a person as member of this Profile. 613 # Adds a person as member of this Profile.
617 def add_member(person) 614 def add_member(person)
618 if self.has_members? 615 if self.has_members?
619 - if self.closed? && members_count > 0 616 + if self.closed? && members.count > 0
620 AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person) 617 AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person)
621 else 618 else
622 - self.affiliate(person, Profile::Roles.admin(environment.id)) if members_count == 0 619 + self.affiliate(person, Profile::Roles.admin(environment.id)) if members.count == 0
623 self.affiliate(person, Profile::Roles.member(environment.id)) 620 self.affiliate(person, Profile::Roles.member(environment.id))
624 end 621 end
625 else 622 else
app/models/scrap.rb
@@ -14,7 +14,7 @@ class Scrap &lt; ActiveRecord::Base @@ -14,7 +14,7 @@ class Scrap &lt; ActiveRecord::Base
14 14
15 named_scope :not_replies, :conditions => {:scrap_id => nil} 15 named_scope :not_replies, :conditions => {:scrap_id => nil}
16 16
17 - 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 17 + 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
18 18
19 track_actions :leave_scrap_to_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.sender == s.receiver} 19 track_actions :leave_scrap_to_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.sender == s.receiver}
20 20
@@ -59,7 +59,7 @@ class Scrap &lt; ActiveRecord::Base @@ -59,7 +59,7 @@ class Scrap &lt; ActiveRecord::Base
59 sender, receiver = scrap.sender, scrap.receiver 59 sender, receiver = scrap.sender, scrap.receiver
60 recipients receiver.email 60 recipients receiver.email
61 61
62 - from "#{sender.environment.name} <#{sender.environment.contact_email}>" 62 + from "#{sender.environment.name} <#{sender.environment.noreply_email}>"
63 subject _("[%s] You received a scrap!") % [sender.environment.name] 63 subject _("[%s] You received a scrap!") % [sender.environment.name]
64 body :recipient => receiver.name, 64 body :recipient => receiver.name,
65 :sender => sender.name, 65 :sender => sender.name,
app/models/task_mailer.rb
@@ -60,7 +60,7 @@ class TaskMailer &lt; ActionMailer::Base @@ -60,7 +60,7 @@ class TaskMailer &lt; ActionMailer::Base
60 end 60 end
61 61
62 def self.generate_from(task) 62 def self.generate_from(task)
63 - "#{task.environment.name} <#{task.environment.contact_email}>" 63 + "#{task.environment.name} <#{task.environment.noreply_email}>"
64 end 64 end
65 65
66 def generate_environment_url(task, url = {}) 66 def generate_environment_url(task, url = {})
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
@@ -12,15 +12,12 @@ class UploadedFile &lt; Article @@ -12,15 +12,12 @@ class UploadedFile &lt; Article
12 12
13 include ShortFilename 13 include ShortFilename
14 14
15 - settings_items :title, :type => 'string'  
16 - xss_terminate :only => [ :title ]  
17 -  
18 - def title_with_default  
19 - title_without_default || short_filename(name, 60) 15 + def title
  16 + if self.name.present? then self.name else self.filename end
  17 + end
  18 + def title= value
  19 + self.name = value
20 end 20 end
21 - alias_method_chain :title, :default  
22 -  
23 - validates_size_of :title, :maximum => 60, :if => (lambda { |file| !file.title.blank? })  
24 21
25 sanitize_filename 22 sanitize_filename
26 23
@@ -32,10 +29,6 @@ class UploadedFile &lt; Article @@ -32,10 +29,6 @@ class UploadedFile &lt; Article
32 self.image? ? self.full_filename(:display).gsub(File.join(RAILS_ROOT, 'public'), '') : nil 29 self.image? ? self.full_filename(:display).gsub(File.join(RAILS_ROOT, 'public'), '') : nil
33 end 30 end
34 31
35 - def display_title  
36 - title.blank? ? name : title  
37 - end  
38 -  
39 def first_paragraph 32 def first_paragraph
40 '' 33 ''
41 end 34 end
@@ -109,7 +102,7 @@ class UploadedFile &lt; Article @@ -109,7 +102,7 @@ class UploadedFile &lt; Article
109 alias :orig_set_filename :filename= 102 alias :orig_set_filename :filename=
110 def filename=(value) 103 def filename=(value)
111 orig_set_filename(value) 104 orig_set_filename(value)
112 - self.name = self.filename 105 + self.name ||= self.filename
113 end 106 end
114 107
115 def download_headers 108 def download_headers
app/models/user.rb
@@ -54,7 +54,7 @@ class User &lt; ActiveRecord::Base @@ -54,7 +54,7 @@ class User &lt; ActiveRecord::Base
54 def activation_email_notify(user) 54 def activation_email_notify(user)
55 user_email = "#{user.login}@#{user.email_domain}" 55 user_email = "#{user.login}@#{user.email_domain}"
56 recipients user_email 56 recipients user_email
57 - from "#{user.environment.name} <#{user.environment.contact_email}>" 57 + from "#{user.environment.name} <#{user.environment.noreply_email}>"
58 subject _("[%{environment}] Welcome to %{environment} mail!") % { :environment => user.environment.name } 58 subject _("[%{environment}] Welcome to %{environment} mail!") % { :environment => user.environment.name }
59 body :name => user.name, 59 body :name => user.name,
60 :email => user_email, 60 :email => user_email,
@@ -66,12 +66,13 @@ class User &lt; ActiveRecord::Base @@ -66,12 +66,13 @@ class User &lt; ActiveRecord::Base
66 def activation_code(user) 66 def activation_code(user)
67 recipients user.email 67 recipients user.email
68 68
69 - from "#{user.environment.name} <#{user.environment.contact_email}>" 69 + from "#{user.environment.name} <#{user.environment.noreply_email}>"
70 subject _("[%s] Activate your account") % [user.environment.name] 70 subject _("[%s] Activate your account") % [user.environment.name]
71 body :recipient => user.name, 71 body :recipient => user.name,
72 :activation_code => user.activation_code, 72 :activation_code => user.activation_code,
73 :environment => user.environment.name, 73 :environment => user.environment.name,
74 - :url => user.environment.top_url 74 + :url => user.environment.top_url,
  75 + :redirection => (true if user.return_to)
75 end 76 end
76 77
77 def signup_welcome_email(user) 78 def signup_welcome_email(user)
@@ -81,7 +82,7 @@ class User &lt; ActiveRecord::Base @@ -81,7 +82,7 @@ class User &lt; ActiveRecord::Base
81 content_type 'text/html' 82 content_type 'text/html'
82 recipients user.email 83 recipients user.email
83 84
84 - from "#{user.environment.name} <#{user.environment.contact_email}>" 85 + from "#{user.environment.name} <#{user.environment.noreply_email}>"
85 subject email_subject.blank? ? _("Welcome to environment %s") % [user.environment.name] : email_subject 86 subject email_subject.blank? ? _("Welcome to environment %s") % [user.environment.name] : email_subject
86 body email_body 87 body email_body
87 end 88 end
@@ -93,7 +94,7 @@ class User &lt; ActiveRecord::Base @@ -93,7 +94,7 @@ class User &lt; ActiveRecord::Base
93 self.person.save! 94 self.person.save!
94 end 95 end
95 end 96 end
96 - 97 +
97 has_one :person, :dependent => :destroy 98 has_one :person, :dependent => :destroy
98 belongs_to :environment 99 belongs_to :environment
99 100
@@ -183,7 +184,7 @@ class User &lt; ActiveRecord::Base @@ -183,7 +184,7 @@ class User &lt; ActiveRecord::Base
183 encryption_methods[sym] = block 184 encryption_methods[sym] = block
184 end 185 end
185 186
186 - # the encryption method used for this instance 187 + # the encryption method used for this instance
187 def encryption_method 188 def encryption_method
188 (password_type || User.system_encryption_method).to_sym 189 (password_type || User.system_encryption_method).to_sym
189 end 190 end
@@ -226,7 +227,7 @@ class User &lt; ActiveRecord::Base @@ -226,7 +227,7 @@ class User &lt; ActiveRecord::Base
226 end 227 end
227 228
228 def remember_token? 229 def remember_token?
229 - remember_token_expires_at && Time.now.utc < remember_token_expires_at 230 + remember_token_expires_at && Time.now.utc < remember_token_expires_at
230 end 231 end
231 232
232 # These create and unset the fields required for remembering users between browser closes 233 # These create and unset the fields required for remembering users between browser closes
@@ -255,7 +256,7 @@ class User &lt; ActiveRecord::Base @@ -255,7 +256,7 @@ class User &lt; ActiveRecord::Base
255 raise IncorrectPassword unless self.authenticated?(current) 256 raise IncorrectPassword unless self.authenticated?(current)
256 self.force_change_password!(new, confirmation) 257 self.force_change_password!(new, confirmation)
257 end 258 end
258 - 259 +
259 # Changes the password of a user without asking for the old password. This 260 # Changes the password of a user without asking for the old password. This
260 # method is intended to be used by the "I forgot my password", and must be 261 # method is intended to be used by the "I forgot my password", and must be
261 # used with care. 262 # used with care.
@@ -326,7 +327,7 @@ class User &lt; ActiveRecord::Base @@ -326,7 +327,7 @@ class User &lt; ActiveRecord::Base
326 end 327 end
327 328
328 protected 329 protected
329 - # before filter 330 + # before filter
330 def encrypt_password 331 def encrypt_password
331 return if password.blank? 332 return if password.blank?
332 self.salt ||= Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record? 333 self.salt ||= Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
app/sweepers/profile_sweeper.rb
@@ -8,6 +8,8 @@ class ProfileSweeper # &lt; ActiveRecord::Observer @@ -8,6 +8,8 @@ class ProfileSweeper # &lt; 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/_signup_form.rhtml
@@ -7,6 +7,8 @@ @@ -7,6 +7,8 @@
7 7
8 <% @profile_data = @person %> 8 <% @profile_data = @person %>
9 9
  10 +<%= javascript_include_tag('sign_up_password_rate') %>
  11 +
10 <%= error_messages_for :user, :person, :header_message => _('The account could not be created') %> 12 <%= error_messages_for :user, :person, :header_message => _('The account could not be created') %>
11 13
12 <% labelled_form_for :user, @user, :html => { :multipart => true, :id => 'signup-form', :honeypot => true } do |f| %> 14 <% labelled_form_for :user, @user, :html => { :multipart => true, :id => 'signup-form', :honeypot => true } do |f| %>
@@ -52,7 +54,20 @@ @@ -52,7 +54,20 @@
52 <div id='signup-password'> 54 <div id='signup-password'>
53 <%= required f.password_field(:password, :id => 'user_pw') %> 55 <%= 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') %> 56 <%= content_tag(:small,_('Choose a password that you can remember easily. It must have at least 4 characters.'), :id => 'password-balloon') %>
55 - <div id='fake-check'><p>&nbsp;</p></div> 57 + <div id='password-rate'>
  58 + <p><span class="invalid hidden" id='result-short'>
  59 + <%=_('Short') %>
  60 + </span></p>
  61 + <p><span class="invalid hidden" id='result-bad'>
  62 + <%=_('Bad') %>
  63 + </span></p>
  64 + <p><span class="invalid hidden" id='result-good'>
  65 + <%=_('Good') %>
  66 + </span></p>
  67 + <p><span class="invalid hidden" id='result-strong'>
  68 + <%=_('Strong') %>
  69 + </span></p>
  70 + </div>
56 </div> 71 </div>
57 72
58 <div id='signup-password-confirmation'> 73 <div id='signup-password-confirmation'>
@@ -182,4 +197,5 @@ jQuery(function($) { @@ -182,4 +197,5 @@ jQuery(function($) {
182 else $(this).addClass('validated'); 197 else $(this).addClass('validated');
183 }); 198 });
184 }); 199 });
  200 +
185 </script> 201 </script>
app/views/admin_panel/_site_info.rhtml
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.rhtml
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">
@@ -16,7 +18,7 @@ @@ -16,7 +18,7 @@
16 18
17 <% if !user.nil? and user.has_permission?('edit_profile', profile) %> 19 <% if !user.nil? and user.has_permission?('edit_profile', profile) %>
18 <div class='admin-link'> 20 <div class='admin-link'>
19 - <%= link_to _('Control panel'), :controller => 'profile_editor' %> 21 + <%= link_to _('Control panel'), block.owner.admin_url %>
20 </div> 22 </div>
21 <% end %> 23 <% end %>
22 24
app/views/blocks/profile_info.rhtml
@@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
21 <li><%= link_to(_('Products/Services'), :controller => 'catalog', :profile => block.owner.identifier) %></li> 21 <li><%= link_to(_('Products/Services'), :controller => 'catalog', :profile => block.owner.identifier) %></li>
22 <% end %> 22 <% end %>
23 <% if !user.nil? and user.has_permission?('edit_profile', profile) %> 23 <% if !user.nil? and user.has_permission?('edit_profile', profile) %>
24 - <li><%= link_to _('Control panel'), :controller => 'profile_editor' %></li> 24 + <li><%= link_to _('Control panel'), block.owner.admin_url %></li>
25 <% end %> 25 <% end %>
26 <% if profile.person? %> 26 <% if profile.person? %>
27 <li><%= _('Since %{year}/%{month}') % { :year => block.owner.created_at.year, :month => block.owner.created_at.month } %></li> 27 <li><%= _('Since %{year}/%{month}') % { :year => block.owner.created_at.year, :month => block.owner.created_at.month } %></li>
@@ -40,7 +40,7 @@ @@ -40,7 +40,7 @@
40 <% end %> 40 <% end %>
41 41
42 <div class="profile-info-options"> 42 <div class="profile-info-options">
43 - <%= render :file => view_for_profile_actions(@block.owner.class) %> 43 + <%= render :file => view_for_profile_actions(block.owner.class) %>
44 </div> 44 </div>
45 45
46 </div><!-- end class="vcard" --> 46 </div><!-- end class="vcard" -->
app/views/box_organizer/_link_list_block.rhtml
  1 +<%= javascript_include_tag "edit-link-list.js" %>
  2 +
1 <strong><%= _('Links') %></strong> 3 <strong><%= _('Links') %></strong>
2 <div id='edit-link-list-block'> 4 <div id='edit-link-list-block'>
3 -<table id='links' class='noborder'>  
4 - <tr>  
5 - <th><%= _('Icon') %></th>  
6 - <th><%= _('Name') %></th>  
7 - <th><%= _('Address') %></th>  
8 - <th><%= _('Title') %></th>  
9 - <th><%= _('Target') %></th>  
10 - </tr>  
11 - <% for link in @block.links do %>  
12 - <tr>  
13 - <td><%= icon_selector(link['icon']) %></td>  
14 - <td><%= text_field_tag 'block[links][][name]', link[:name], :class => 'link-name', :maxlength => 20 %></td>  
15 - <td class='cel-address'><%= text_field_tag 'block[links][][address]', link[:address], :class => 'link-address' %></td>  
16 - <td><%= text_field_tag 'block[links][][title]', link[:title], :class => 'link-title' %></td>  
17 - <td><%= select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, link[:target])) %></td>  
18 - </tr>  
19 - <% end %>  
20 -</table> 5 + <ul class='link-list-header'>
  6 + <li class='link-list-icon'><%= _('Icon') %></li>
  7 + <li class='link-list-name'><%= _('Name') %></li>
  8 + <li class='link-list-address'><%= _('Address') %></li>
  9 + <li class='link-list-target'><%= _('Target') %></li>
  10 + </ul>
  11 + <ul id="dropable-link-list">
  12 + <% for link in @block.links do %>
  13 + <li>
  14 + <ul class="link-list-row">
  15 + <li>
  16 + <%= icon_selector(link['icon']) %>
  17 + </li>
  18 + <li>
  19 + <%= text_field_tag 'block[links][][name]', link[:name], :class => 'link-name', :maxlength => 20 %>
  20 + </li>
  21 + <li>
  22 + <%= text_field_tag 'block[links][][address]', link[:address], :class => 'link-address' %>
  23 + </li>
  24 + <li>
  25 + <%= select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, link[:target])) %>
  26 + </li>
  27 + <li>
  28 + <%= button_without_text(:delete, _('Delete'), "#" , :class=>"delete-link-list-row") %>
  29 + </li>
  30 + </ul>
  31 + </li>
  32 + <% end %>
  33 + </ul>
  34 + <input type="hidden" id="page_url" value="<%=url_for(:action=>'search_autocomplete')%>" />
21 </div> 35 </div>
22 36
23 <%= link_to_function(_('New link'), nil, :class => 'button icon-add with-text') do |page| 37 <%= link_to_function(_('New link'), nil, :class => 'button icon-add with-text') do |page|
24 - page.insert_html :bottom, 'links', content_tag('tr',  
25 - content_tag('td', icon_selector('ok')) +  
26 - content_tag('td', text_field_tag('block[links][][name]', '', :maxlength => 20)) +  
27 - content_tag('td', text_field_tag('block[links][][address]', nil, :class => 'link-address'), :class => 'cel-address') +  
28 - content_tag('td', text_field_tag('block[links][][title]', '', :class => 'link-title')) +  
29 - content_tag('td', select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, '_self'))) 38 + page.insert_html :bottom, 'dropable-link-list', content_tag('li',
  39 + content_tag('ul',
  40 + content_tag('li', icon_selector('ok')) +
  41 + content_tag('li', text_field_tag('block[links][][name]', '', :maxlength => 20)) +
  42 + content_tag('li', text_field_tag('block[links][][address]', nil, :class => 'link-address')) +
  43 + content_tag('li', select_tag('block[links][][target]',
  44 + options_for_select(LinkListBlock::TARGET_OPTIONS, '_self'))) +
  45 + content_tag('li', button_without_text(:delete, _('Delete'), "#" , :class=>"delete-link-list-row")),
  46 + :class=>"link-list-row new_link_row")
30 ) + 47 ) +
31 - javascript_tag("$('edit-link-list-block').scrollTop = $('edit-link-list-block').scrollHeight") 48 + javascript_tag("new_link_action()")
32 end %> 49 end %>
app/views/box_organizer/edit.rhtml
@@ -7,13 +7,14 @@ @@ -7,13 +7,14 @@
7 7
8 <%= render :partial => partial_for_class(@block.class) %> 8 <%= render :partial => partial_for_class(@block.class) %>
9 9
10 - <%= labelled_form_field _('Display this block:'), '' %>  
11 - <div style='margin-left: 10px'>  
12 - <% @block.display_options.each do |option| %>  
13 - <%= radio_button(:block, :display, option) %>  
14 - <%= label_tag("block_display_#{option}", _(@block.display_option_label(option))) %>  
15 - <br/>  
16 - <% end %> 10 + <div class="display">
  11 + <%= labelled_form_field _('Display this block:'),
  12 + select_tag('block[display]', options_from_collection_for_select(@block.display_options, :first, :last, @block.display))
  13 + %>
  14 + </div>
  15 + <div class="display_user">
  16 + <%= labelled_form_field _('Display to users:'), '' %>
  17 + <%= select_tag('block[display_user]', options_from_collection_for_select(@block.display_user_options, :first, :last, @block.display_user)) %>
17 </div> 18 </div>
18 19
19 <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %> 20 <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %>
app/views/content_viewer/_addthis.rhtml 0 → 100644
@@ -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.rhtml
@@ -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.rhtml
@@ -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">
app/views/events/_events.rhtml
1 -<%= list_events(@date, @events) %>  
2 \ No newline at end of file 1 \ No newline at end of file
  2 +<%= list_events(@date, @events) %>
  3 +
  4 +<%= pagination_links @events, :param_name => 'page' %>
app/views/features/_manage_community_fields.rhtml
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.rhtml
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.rhtml
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.rhtml
@@ -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.rhtml
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.rhtml
@@ -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 %>
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 } %>
app/views/person_notifier/mailer/_comment.rhtml 0 → 100644
@@ -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>
app/views/person_notifier/mailer/_create_article.rhtml 0 → 100644
@@ -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>
app/views/person_notifier/mailer/_join_community.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'default_activity', :locals => { :activity => activity } %>
app/views/person_notifier/mailer/_leave_scrap.rhtml 0 → 100644
@@ -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 +_leave_scrap.rhtml
0 \ No newline at end of file 2 \ No newline at end of file
app/views/person_notifier/mailer/_new_friendship.rhtml 0 → 100644
@@ -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 @@ @@ -0,0 +1 @@
  1 +_leave_scrap.rhtml
0 \ No newline at end of file 2 \ No newline at end of file
app/views/person_notifier/mailer/_upload_image.rhtml 0 → 100644
@@ -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/>
app/views/person_notifier/mailer/content_summary.rhtml 0 → 100644
@@ -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.rhtml
@@ -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/shared/_select_categories.rhtml
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(' &rarr; ') 21 :class => 'select-current-category-link')}.join(' &rarr; ')
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 %> &nbsp;  
45 -<% end %> 32 +<div class="toplevel-categories">
  33 + <%= render :partial => 'shared/select_subcategories', :locals => {:object_name => object_name, :categories => @categories} %>
46 </div> 34 </div>
app/views/shared/_select_categories_top.rhtml 0 → 100644
@@ -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>
app/views/shared/_select_subcategories.rhtml 0 → 100644
@@ -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.rhtml
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.rhtml
@@ -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.rhtml
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.rhtml
@@ -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 %>
config/initializers/activities_counter_cache.rb 0 → 100644
@@ -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 Delayed::Worker.backend = :active_record 1 Delayed::Worker.backend = :active_record
2 Delayed::Worker.max_attempts = 2 2 Delayed::Worker.max_attempts = 2
3 -Delayed::Worker.max_run_time = 10.minutes 3 +
  4 +# TODO This is consuming ton of space on development with a postgres connection
  5 +# error on the jobs. This must be verified before going into production.
  6 +# Logging jobs backtraces
  7 +#class Delayed::Worker
  8 +# def handle_failed_job_with_loggin(job, error)
  9 +# handle_failed_job_without_loggin(job,error)
  10 +# Delayed::Worker.logger.error(error.message)
  11 +# Delayed::Worker.logger.error(error.backtrace.join("\n"))
  12 +# end
  13 +# alias_method_chain :handle_failed_job, :loggin
  14 +#end
config/initializers/noosfero_extensions.rb 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +require 'noosfero/role_assignment_ext'
  2 +require 'noosfero/action_tracker_ext'
config/initializers/person_notification.rb 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +if Delayed::Backend::ActiveRecord::Job.table_exists?
  2 + PersonNotifier.schedule_all_next_notification_mail
  3 +end
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
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +class AddIndexesForProfileSearch < ActiveRecord::Migration
  2 + def self.up
  3 + add_index :profiles, :created_at
  4 + end
  5 +
  6 + def self.down
  7 + remove_index :profiles, :created_at
  8 + end
  9 +end
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/20140312184749_add_return_to_to_users.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +class AddReturnToToUsers < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :users, :return_to, :string
  4 + end
  5 +
  6 + def self.down
  7 + remove_column :users, :return_to, :string
  8 + end
  9 +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
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +class AddIndexesForProductsSearch < ActiveRecord::Migration
  2 + def self.up
  3 + add_index :products, :created_at
  4 + end
  5 +
  6 + def self.down
  7 + remove_index :products, :created_at
  8 + end
  9 +end
1 -# This file is auto-generated from the current state of the database. Instead of editing this file, 1 +# This file is auto-generated from the current state of the database. Instead of editing this file,
2 # please use the migrations feature of Active Record to incrementally modify your database, and 2 # please use the migrations feature of Active Record to incrementally modify your database, and
3 # then regenerate this schema definition. 3 # then regenerate this schema definition.
4 # 4 #
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 # 9 #
10 # It's strongly recommended to check this file into your version control system. 10 # It's strongly recommended to check this file into your version control system.
11 11
12 -ActiveRecord::Schema.define(:version => 20140108132730) do 12 +ActiveRecord::Schema.define(:version => 20140314200103) do
13 13
14 create_table "abuse_reports", :force => true do |t| 14 create_table "abuse_reports", :force => true do |t|
15 t.integer "reporter_id" 15 t.integer "reporter_id"
@@ -140,6 +140,9 @@ ActiveRecord::Schema.define(:version =&gt; 20140108132730) do @@ -140,6 +140,9 @@ ActiveRecord::Schema.define(:version =&gt; 20140108132730) do
140 t.integer "position" 140 t.integer "position"
141 end 141 end
142 142
  143 + add_index "articles", ["comments_count"], :name => "index_articles_on_comments_count"
  144 + add_index "articles", ["created_at"], :name => "index_articles_on_created_at"
  145 + add_index "articles", ["hits"], :name => "index_articles_on_hits"
143 add_index "articles", ["name"], :name => "index_articles_on_name" 146 add_index "articles", ["name"], :name => "index_articles_on_name"
144 add_index "articles", ["parent_id"], :name => "index_articles_on_parent_id" 147 add_index "articles", ["parent_id"], :name => "index_articles_on_parent_id"
145 add_index "articles", ["profile_id"], :name => "index_articles_on_profile_id" 148 add_index "articles", ["profile_id"], :name => "index_articles_on_profile_id"
@@ -282,6 +285,8 @@ ActiveRecord::Schema.define(:version =&gt; 20140108132730) do @@ -282,6 +285,8 @@ ActiveRecord::Schema.define(:version =&gt; 20140108132730) do
282 t.text "signup_welcome_text" 285 t.text "signup_welcome_text"
283 t.string "languages" 286 t.string "languages"
284 t.string "default_language" 287 t.string "default_language"
  288 + t.string "redirection_after_signup", :default => "keep_on_same_page"
  289 + t.string "noreply_email"
285 end 290 end
286 291
287 create_table "external_feeds", :force => true do |t| 292 create_table "external_feeds", :force => true do |t|
@@ -432,6 +437,7 @@ ActiveRecord::Schema.define(:version =&gt; 20140108132730) do @@ -432,6 +437,7 @@ ActiveRecord::Schema.define(:version =&gt; 20140108132730) do
432 t.boolean "archived", :default => false 437 t.boolean "archived", :default => false
433 end 438 end
434 439
  440 + add_index "products", ["created_at"], :name => "index_products_on_created_at"
435 add_index "products", ["product_category_id"], :name => "index_products_on_product_category_id" 441 add_index "products", ["product_category_id"], :name => "index_products_on_product_category_id"
436 add_index "products", ["profile_id"], :name => "index_products_on_profile_id" 442 add_index "products", ["profile_id"], :name => "index_products_on_profile_id"
437 443
@@ -470,10 +476,17 @@ ActiveRecord::Schema.define(:version =&gt; 20140108132730) do @@ -470,10 +476,17 @@ ActiveRecord::Schema.define(:version =&gt; 20140108132730) do
470 t.string "redirection_after_login" 476 t.string "redirection_after_login"
471 t.string "personal_website" 477 t.string "personal_website"
472 t.string "jabber_id" 478 t.string "jabber_id"
  479 + t.integer "friends_count", :default => 0, :null => false
  480 + t.integer "members_count", :default => 0, :null => false
  481 + t.integer "activities_count", :default => 0, :null => false
473 end 482 end
474 483
  484 + add_index "profiles", ["activities_count"], :name => "index_profiles_on_activities_count"
  485 + add_index "profiles", ["created_at"], :name => "index_profiles_on_created_at"
475 add_index "profiles", ["environment_id"], :name => "index_profiles_on_environment_id" 486 add_index "profiles", ["environment_id"], :name => "index_profiles_on_environment_id"
  487 + add_index "profiles", ["friends_count"], :name => "index_profiles_on_friends_count"
476 add_index "profiles", ["identifier"], :name => "index_profiles_on_identifier" 488 add_index "profiles", ["identifier"], :name => "index_profiles_on_identifier"
  489 + add_index "profiles", ["members_count"], :name => "index_profiles_on_members_count"
477 add_index "profiles", ["region_id"], :name => "index_profiles_on_region_id" 490 add_index "profiles", ["region_id"], :name => "index_profiles_on_region_id"
478 491
479 create_table "qualifier_certifiers", :force => true do |t| 492 create_table "qualifier_certifiers", :force => true do |t|
@@ -619,6 +632,7 @@ ActiveRecord::Schema.define(:version =&gt; 20140108132730) do @@ -619,6 +632,7 @@ ActiveRecord::Schema.define(:version =&gt; 20140108132730) do
619 t.datetime "chat_status_at" 632 t.datetime "chat_status_at"
620 t.string "activation_code", :limit => 40 633 t.string "activation_code", :limit => 40
621 t.datetime "activated_at" 634 t.datetime "activated_at"
  635 + t.string "return_to"
622 end 636 end
623 637
624 create_table "validation_infos", :force => true do |t| 638 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/comment.feature
@@ -97,3 +97,41 @@ Feature: comment @@ -97,3 +97,41 @@ Feature: comment
97 Given I am on /booking/article-to-comment 97 Given I am on /booking/article-to-comment
98 And I follow "Post a comment" 98 And I follow "Post a comment"
99 Then "Post a comment" should not be visible within "#article" 99 Then "Post a comment" should not be visible within "#article"
  100 +
  101 + @selenium
  102 + Scenario: the newest post from a forum should be displayed first.
  103 + Given the following users
  104 + | login | name |
  105 + | joaosilva | Joao Silva |
  106 + And the following forums
  107 + | owner | name |
  108 + | joaosilva | Forum |
  109 + And the following articles
  110 + | owner | name | parent |
  111 + | joaosilva | Post one | Forum |
  112 + And the following comments
  113 + | article | author | title | body |
  114 + | Post one | joaosilva | Hi all | Hi all |
  115 + | Post one | joaosilva | Hello | Hello |
  116 + When I go to /joaosilva/forum/post-one
  117 + And I select "Newest first" from "comment_order" within ".comment-order"
  118 + Then I should see "Hello" within ".article-comment"
  119 +
  120 + @selenium
  121 + Scenario: the oldest post from a forum should be displayed first.
  122 + Given the following users
  123 + | login | name |
  124 + | joaosilva | Joao Silva |
  125 + And the following forums
  126 + | owner | name |
  127 + | joaosilva | Forum |
  128 + And the following articles
  129 + | owner | name | parent |
  130 + | joaosilva | Post one | Forum |
  131 + And the following comments
  132 + | article | author | title | body |
  133 + | Post one | joaosilva | Hi all | Hi all |
  134 + | Post one | joaosilva | Hello | Hello |
  135 + When I go to /joaosilva/forum/post-one
  136 + And I select "Oldest first" from "comment_order" within ".comment-order"
  137 + Then I should see "Hi all" within ".article-comment"
100 \ No newline at end of file 138 \ No newline at end of file
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
features/manage_fields.feature 0 → 100644
@@ -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"
features/manage_users.feature 0 → 100644
@@ -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/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"
@@ -60,3 +60,183 @@ Feature: signup @@ -60,3 +60,183 @@ Feature: signup
60 And I fill in "Name" with "" 60 And I fill in "Name" with ""
61 When I press "Save" 61 When I press "Save"
62 Then I should see "Name can't be blank" 62 Then I should see "Name can't be blank"
  63 +
  64 + @selenium
  65 + Scenario: user should stay on same page after signup
  66 + Given the environment is configured to stay on the same page after signup
  67 + And feature "skip_new_user_email_confirmation" is enabled on environment
  68 + And I am on /search/people
  69 + When I follow "Sign up"
  70 + And I fill in the following within ".no-boxes":
  71 + | e-Mail | josesilva@example.com |
  72 + | Username | josesilva |
  73 + | Password | secret |
  74 + | Password confirmation | secret |
  75 + | Full name | José da Silva |
  76 + And wait for the captcha signup time
  77 + And I press "Create my account"
  78 + Then I should be on /search/people
  79 +
  80 + @selenium
  81 + Scenario: user should go to his homepage after signup
  82 + Given the environment is configured to redirect to profile homepage after signup
  83 + And feature "skip_new_user_email_confirmation" is enabled on environment
  84 + And I am on /search/people
  85 + When I follow "Sign up"
  86 + And I fill in the following within ".no-boxes":
  87 + | e-Mail | josesilva@example.com |
  88 + | Username | josesilva |
  89 + | Password | secret |
  90 + | Password confirmation | secret |
  91 + | Full name | José da Silva |
  92 + And wait for the captcha signup time
  93 + And I press "Create my account"
  94 + Then I should be on josesilva's profile
  95 +
  96 + @selenium
  97 + Scenario: user should go to his control panel after signup
  98 + Given the environment is configured to redirect to profile control panel after signup
  99 + And feature "skip_new_user_email_confirmation" is enabled on environment
  100 + And I am on /search/people
  101 + When I follow "Sign up"
  102 + And I fill in the following within ".no-boxes":
  103 + | e-Mail | josesilva@example.com |
  104 + | Username | josesilva |
  105 + | Password | secret |
  106 + | Password confirmation | secret |
  107 + | Full name | José da Silva |
  108 + And wait for the captcha signup time
  109 + And I press "Create my account"
  110 + Then I should be on josesilva's control panel
  111 +
  112 + @selenium
  113 + Scenario: user should go to his profile page after signup
  114 + Given the environment is configured to redirect to user profile page after signup
  115 + And feature "skip_new_user_email_confirmation" is enabled on environment
  116 + And I am on /search/people
  117 + When I follow "Sign up"
  118 + And I fill in the following within ".no-boxes":
  119 + | e-Mail | josesilva@example.com |
  120 + | Username | josesilva |
  121 + | Password | secret |
  122 + | Password confirmation | secret |
  123 + | Full name | José da Silva |
  124 + And wait for the captcha signup time
  125 + And I press "Create my account"
  126 + Then I should be on josesilva's profile
  127 +
  128 + @selenium
  129 + Scenario: user should go to the environment's homepage after signup
  130 + Given the environment is configured to redirect to site homepage after signup
  131 + And feature "skip_new_user_email_confirmation" is enabled on environment
  132 + And I am on /search/people
  133 + When I follow "Sign up"
  134 + And I fill in the following within ".no-boxes":
  135 + | e-Mail | josesilva@example.com |
  136 + | Username | josesilva |
  137 + | Password | secret |
  138 + | Password confirmation | secret |
  139 + | Full name | José da Silva |
  140 + And wait for the captcha signup time
  141 + And I press "Create my account"
  142 + Then I should be on the homepage
  143 +
  144 + @selenium
  145 + Scenario: user should stay on same page after following confirmation link
  146 + Given the environment is configured to stay on the same page after login
  147 + And feature "skip_new_user_email_confirmation" is disabled on environment
  148 + And I am on /search/people
  149 + When I follow "Sign up"
  150 + And I fill in the following within ".no-boxes":
  151 + | e-Mail | josesilva@example.com |
  152 + | Username | josesilva |
  153 + | Password | secret |
  154 + | Password confirmation | secret |
  155 + | Full name | José da Silva |
  156 + And wait for the captcha signup time
  157 + And I press "Create my account"
  158 + And I go to josesilva's confirmation URL
  159 + And I fill in "Username" with "josesilva"
  160 + And I fill in "Password" with "secret"
  161 + And I press "Log in"
  162 + Then I should be on /search/people
  163 +
  164 + @selenium
  165 + Scenario: user should go to his homepage after following confirmation link
  166 + Given the environment is configured to redirect to profile homepage after login
  167 + And feature "skip_new_user_email_confirmation" is disabled on environment
  168 + And I am on /search/people
  169 + When I follow "Sign up"
  170 + And I fill in the following within ".no-boxes":
  171 + | e-Mail | josesilva@example.com |
  172 + | Username | josesilva |
  173 + | Password | secret |
  174 + | Password confirmation | secret |
  175 + | Full name | José da Silva |
  176 + And wait for the captcha signup time
  177 + And I press "Create my account"
  178 + And I go to josesilva's confirmation URL
  179 + And I fill in "Username" with "josesilva"
  180 + And I fill in "Password" with "secret"
  181 + And I press "Log in"
  182 + Then I should be on /profile/josesilva
  183 +
  184 + @selenium
  185 + Scenario: user should go to his control panel after following confirmation link
  186 + Given the environment is configured to redirect to profile control panel after login
  187 + And feature "skip_new_user_email_confirmation" is disabled on environment
  188 + And I am on /search/people
  189 + When I follow "Sign up"
  190 + And I fill in the following within ".no-boxes":
  191 + | e-Mail | josesilva@example.com |
  192 + | Username | josesilva |
  193 + | Password | secret |
  194 + | Password confirmation | secret |
  195 + | Full name | José da Silva |
  196 + And wait for the captcha signup time
  197 + And I press "Create my account"
  198 + And I go to josesilva's confirmation URL
  199 + And I fill in "Username" with "josesilva"
  200 + And I fill in "Password" with "secret"
  201 + And I press "Log in"
  202 + Then I should be on /myprofile/josesilva
  203 +
  204 + @selenium
  205 + Scenario: user should go to his profile page after following confirmation link
  206 + Given the environment is configured to redirect to user profile page after login
  207 + And feature "skip_new_user_email_confirmation" is disabled on environment
  208 + And I am on /search/people
  209 + When I follow "Sign up"
  210 + And I fill in the following within ".no-boxes":
  211 + | e-Mail | josesilva@example.com |
  212 + | Username | josesilva |
  213 + | Password | secret |
  214 + | Password confirmation | secret |
  215 + | Full name | José da Silva |
  216 + And wait for the captcha signup time
  217 + And I press "Create my account"
  218 + And I go to josesilva's confirmation URL
  219 + And I fill in "Username" with "josesilva"
  220 + And I fill in "Password" with "secret"
  221 + And I press "Log in"
  222 + Then I should be on /profile/josesilva
  223 +
  224 + @selenium
  225 + Scenario: user should go to the environment homepage after following confirmation link
  226 + Given the environment is configured to redirect to site homepage after login
  227 + And feature "skip_new_user_email_confirmation" is disabled on environment
  228 + And I am on /search/people
  229 + When I follow "Sign up"
  230 + And I fill in the following within ".no-boxes":
  231 + | e-Mail | josesilva@example.com |
  232 + | Username | josesilva |
  233 + | Password | secret |
  234 + | Password confirmation | secret |
  235 + | Full name | José da Silva |
  236 + And wait for the captcha signup time
  237 + And I press "Create my account"
  238 + And I go to josesilva's confirmation URL
  239 + And I fill in "Username" with "josesilva"
  240 + And I fill in "Password" with "secret"
  241 + And I press "Log in"
  242 + Then I should be on the homepage
features/step_definitions/noosfero_steps.rb
@@ -738,6 +738,24 @@ Given /^the profile (.*) is configured to (.*) after login$/ do |profile, option @@ -738,6 +738,24 @@ Given /^the profile (.*) is configured to (.*) after login$/ do |profile, option
738 profile.save 738 profile.save
739 end 739 end
740 740
  741 +Given /^the environment is configured to (.*) after signup$/ do |option|
  742 + redirection = case option
  743 + when 'stay on the same page'
  744 + 'keep_on_same_page'
  745 + when 'redirect to site homepage'
  746 + 'site_homepage'
  747 + when 'redirect to user profile page'
  748 + 'user_profile_page'
  749 + when 'redirect to profile homepage'
  750 + 'user_homepage'
  751 + when 'redirect to profile control panel'
  752 + 'user_control_panel'
  753 + end
  754 + environment = Environment.default
  755 + environment.redirection_after_signup = redirection
  756 + environment.save
  757 +end
  758 +
741 When /^wait for the captcha signup time$/ do 759 When /^wait for the captcha signup time$/ do
742 environment = Environment.default 760 environment = Environment.default
743 sleep environment.min_signup_delay + 1 761 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
lib/activities_counter_cache_job.rb 0 → 100644
@@ -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_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
@@ -43,7 +51,12 @@ class FilePresenter @@ -43,7 +51,12 @@ class FilePresenter
43 end 51 end
44 52
45 def short_description 53 def short_description
46 - _("File (%s)") % content_type.sub(/^application\//, '').sub(/^x-/, '').sub(/^image\//, '') 54 + file_type = if content_type.present?
  55 + content_type.sub(/^application\//, '').sub(/^x-/, '').sub(/^image\//, '')
  56 + else
  57 + _('Unknown')
  58 + end
  59 + _("File (%s)") % file_type
47 end 60 end
48 61
49 # Define the css classes to style the page fragment with the file related 62 # Define the css classes to style the page fragment with the file related
lib/noosfero.rb
@@ -3,7 +3,7 @@ require &#39;fast_gettext&#39; @@ -3,7 +3,7 @@ require &#39;fast_gettext&#39;
3 3
4 module Noosfero 4 module Noosfero
5 PROJECT = 'noosfero' 5 PROJECT = 'noosfero'
6 - VERSION = '0.46.1' 6 + VERSION = '0.47.0~rc1'
7 7
8 def self.pattern_for_controllers_in_directory(dir) 8 def self.pattern_for_controllers_in_directory(dir)
9 disjunction = controllers_in_directory(dir).join('|') 9 disjunction = controllers_in_directory(dir).join('|')
lib/noosfero/action_tracker_ext.rb 0 → 100644
@@ -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/plugin.rb
@@ -16,14 +16,7 @@ class Noosfero::Plugin @@ -16,14 +16,7 @@ class Noosfero::Plugin
16 end 16 end
17 17
18 def init_system 18 def init_system
19 - enabled_plugins = Dir.glob(File.join(Rails.root, 'config', 'plugins', '*'))  
20 - if Rails.env.test? && !enabled_plugins.include?(File.join(Rails.root, 'config', 'plugins', 'foo'))  
21 - enabled_plugins << File.join(Rails.root, 'plugins', 'foo')  
22 - end  
23 -  
24 - enabled_plugins.select do |entry|  
25 - File.directory?(entry)  
26 - end.each do |dir| 19 + available_plugins.each do |dir|
27 load_plugin dir 20 load_plugin dir
28 end 21 end
29 end 22 end
@@ -76,12 +69,19 @@ class Noosfero::Plugin @@ -76,12 +69,19 @@ class Noosfero::Plugin
76 klass(plugin_name) 69 klass(plugin_name)
77 end 70 end
78 71
79 - def all  
80 - @all ||= [] 72 + def available_plugins
  73 + unless @available_plugins
  74 + path = File.join(Rails.root, 'config', 'plugins', '*')
  75 + @available_plugins = Dir.glob(path).select{ |i| File.directory?(i) }
  76 + if Rails.env.test? && !@available_plugins.include?(File.join(Rails.root, 'config', 'plugins', 'foo'))
  77 + @available_plugins << File.join(Rails.root, 'plugins', 'foo')
  78 + end
  79 + end
  80 + @available_plugins
81 end 81 end
82 82
83 - def inherited(subclass)  
84 - all << subclass.to_s unless all.include?(subclass.to_s) 83 + def all
  84 + @all ||= available_plugins.map{ |dir| (File.basename(dir) + "_plugin").camelize }
85 end 85 end
86 86
87 def public_name 87 def public_name
@@ -349,6 +349,12 @@ class Noosfero::Plugin @@ -349,6 +349,12 @@ class Noosfero::Plugin
349 [] 349 []
350 end 350 end
351 351
  352 + # -> Adds adicional content to article
  353 + # returns = lambda block that creates html code
  354 + def article_extra_contents(article)
  355 + nil
  356 + end
  357 +
352 # -> Adds fields to the signup form 358 # -> Adds fields to the signup form
353 # returns = lambda block that creates html code 359 # returns = lambda block that creates html code
354 def signup_extra_contents 360 def signup_extra_contents
lib/noosfero/role_assignment_ext.rb 0 → 100644
@@ -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/release.rake
@@ -144,8 +144,8 @@ EOF @@ -144,8 +144,8 @@ EOF
144 version_name = new_version = ask(version_question) 144 version_name = new_version = ask(version_question)
145 145
146 if release_kind == 'test' 146 if release_kind == 'test'
147 - timestamp = Time.now.strftime('%Y%m%d%H%M%S')  
148 - version_name += "~rc#{timestamp}" 147 + rc_version = ask('RC version', Time.now.strftime('%Y%m%d%H%M%S'))
  148 + version_name += "~rc#{rc_version}"
149 end 149 end
150 release_message = ask("Release message") 150 release_message = ask("Release message")
151 151
@@ -216,6 +216,9 @@ EOF @@ -216,6 +216,9 @@ EOF
216 task :release, :release_kind do |t, args| 216 task :release, :release_kind do |t, args|
217 release_kind = args[:release_kind] || 'stable' 217 release_kind = args[:release_kind] || 'stable'
218 218
  219 + puts "==> Updating authors..."
  220 + Rake::Task['noosfero:authors'].invoke
  221 +
219 Rake::Task['noosfero:set_version'].invoke(release_kind) 222 Rake::Task['noosfero:set_version'].invoke(release_kind)
220 223
221 puts "==> Checking tags..." 224 puts "==> Checking tags..."
@@ -230,9 +233,6 @@ EOF @@ -230,9 +233,6 @@ EOF
230 commit_changes(['public/500.html', 'public/503.html'], 'Updating public error pages') 233 commit_changes(['public/500.html', 'public/503.html'], 'Updating public error pages')
231 end 234 end
232 235
233 - puts "==> Updating authors..."  
234 - Rake::Task['noosfero:authors'].invoke  
235 -  
236 puts "==> Checking repository..." 236 puts "==> Checking repository..."
237 Rake::Task['noosfero:check_repo'].invoke 237 Rake::Task['noosfero:check_repo'].invoke
238 238
plugins/comment_classification/lib/comment_classification_plugin.rb
@@ -46,10 +46,6 @@ class CommentClassificationPlugin &lt; Noosfero::Plugin @@ -46,10 +46,6 @@ class CommentClassificationPlugin &lt; Noosfero::Plugin
46 end 46 end
47 end 47 end
48 48
49 - def js_files  
50 - 'comment_classification.js'  
51 - end  
52 -  
53 def stylesheet? 49 def stylesheet?
54 true 50 true
55 end 51 end
plugins/context_content/views/blocks/_more.rhtml
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
@@ -61,9 +61,12 @@ class DisplayContentBlock &lt; Block @@ -61,9 +61,12 @@ class DisplayContentBlock &lt; Block
61 61
62 VALID_CONTENT = ['RawHTMLArticle', 'TextArticle', 'TextileArticle', 'TinyMceArticle', 'Folder', 'Blog', 'Forum'] 62 VALID_CONTENT = ['RawHTMLArticle', 'TextArticle', 'TextileArticle', 'TinyMceArticle', 'Folder', 'Blog', 'Forum']
63 63
  64 + include Noosfero::Plugin::HotSpot
  65 +
64 def articles_of_parent(parent = nil) 66 def articles_of_parent(parent = nil)
65 return [] if self.holder.nil? 67 return [] if self.holder.nil?
66 - holder.articles.find(:all, :conditions => {:type => VALID_CONTENT, :parent_id => (parent.nil? ? nil : parent)}) 68 + types = VALID_CONTENT + plugins.dispatch(:content_types).map(&:name)
  69 + holder.articles.find(:all, :conditions => {:type => types, :parent_id => (parent.nil? ? nil : parent)})
67 end 70 end
68 71
69 include ActionController::UrlWriter 72 include ActionController::UrlWriter
plugins/display_content/test/unit/display_content_block_test.rb
@@ -238,6 +238,7 @@ class DisplayContentBlockTest &lt; ActiveSupport::TestCase @@ -238,6 +238,7 @@ class DisplayContentBlockTest &lt; 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 &lt; ActiveSupport::TestCase @@ -253,6 +254,7 @@ class DisplayContentBlockTest &lt; 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 &lt; ActiveSupport::TestCase @@ -270,6 +272,7 @@ class DisplayContentBlockTest &lt; 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 &lt; ActiveSupport::TestCase @@ -288,6 +291,7 @@ class DisplayContentBlockTest &lt; 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 &lt; ActiveSupport::TestCase @@ -301,6 +305,7 @@ class DisplayContentBlockTest &lt; 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 &lt; ActiveSupport::TestCase @@ -316,6 +321,7 @@ class DisplayContentBlockTest &lt; 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 &lt; ActiveSupport::TestCase @@ -334,6 +340,7 @@ class DisplayContentBlockTest &lt; 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
@@ -526,4 +533,28 @@ class DisplayContentBlockTest &lt; ActiveSupport::TestCase @@ -526,4 +533,28 @@ class DisplayContentBlockTest &lt; ActiveSupport::TestCase
526 assert_equivalent [f1.id, a1.id, a2.id, a3.id], block.nodes 533 assert_equivalent [f1.id, a1.id, a2.id, a3.id], block.nodes
527 end 534 end
528 535
  536 + should "test should return plugins articles in articles of parent method" do
  537 + class PluginArticle < Article; end
  538 +
  539 + class Plugin1 < Noosfero::Plugin
  540 + def content_types
  541 + [PluginArticle]
  542 + end
  543 + end
  544 +
  545 + profile = create_user('testuser').person
  546 + Article.delete_all
  547 + a1 = fast_create(PluginArticle, :name => 'test article 1', :profile_id => profile.id)
  548 +
  549 + env = fast_create(Environment)
  550 + env.enable_plugin(Plugin1)
  551 +
  552 + block = DisplayContentBlock.new
  553 + box = mock()
  554 + box.stubs(:owner).returns(profile)
  555 + box.stubs(:environment).returns(env)
  556 + block.stubs(:box).returns(box)
  557 + assert_equal [a1], block.articles_of_parent
  558 + end
  559 +
529 end 560 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
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +class MarkCommentAsReadPlugin::ReadComments < Noosfero::Plugin::ActiveRecord
  2 + set_table_name 'mark_comment_as_read_plugin'
  3 + belongs_to :comment
  4 + belongs_to :person
  5 +
  6 + validates_presence_of :comment, :person
  7 +end
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/public/style.css 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +.article-comments-list .comment-mark-read .comment-text, .article-comments-list .comment-mark-read h4, .article-comments-list .comment-mark-read .comment-picture {
  2 + opacity: 0.2;
  3 +}
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 &#39;active_record&#39; @@ -2,11 +2,9 @@ require_dependency &#39;active_record&#39;
2 2
3 class ActiveRecord::Base 3 class ActiveRecord::Base
4 def self.pg_search_plugin_search(query) 4 def self.pg_search_plugin_search(query)
5 - query.gsub!(/\|/,' ')  
6 - formatted_query = query.split.map{|w| w += ":*"}.join('|')  
7 - 5 + filtered_query = query.gsub(/[\|\(\)\\\/\s\[\]'"*%&!:]/,' ').split.map{|w| w += ":*"}.join('|')
8 if defined?(self::SEARCHABLE_FIELDS) 6 if defined?(self::SEARCHABLE_FIELDS)
9 - where("to_tsvector('simple', #{pg_search_plugin_fields}) @@ to_tsquery('#{formatted_query}')") 7 + where("to_tsvector('simple', #{pg_search_plugin_fields}) @@ to_tsquery('#{filtered_query}')")
10 else 8 else
11 raise "No searchable fields defined for #{self.name}" 9 raise "No searchable fields defined for #{self.name}"
12 end 10 end
plugins/pg_search/test/unit/pg_search_plugin_test.rb
@@ -21,6 +21,11 @@ class PgSearchPluginTest &lt; ActiveSupport::TestCase @@ -21,6 +21,11 @@ class PgSearchPluginTest &lt; ActiveSupport::TestCase
21 assert_includes search(Profile, 'admin deb'), profile2 21 assert_includes search(Profile, 'admin deb'), profile2
22 end 22 end
23 23
  24 + should 'locate profile escaping special characters' do
  25 + profile = fast_create(Profile, :name => 'John', :identifier => 'waterfall')
  26 + assert_includes search(Profile, ') ( /\/\/\/\/\ o_o oOo o_o /\/\/\/\/\ ) ((tx waterfall)'), profile
  27 + end
  28 +
24 # TODO This feature is available only on Postgresql 9.0 29 # TODO This feature is available only on Postgresql 9.0
25 # http://www.postgresql.org/docs/9.0/static/unaccent.html 30 # http://www.postgresql.org/docs/9.0/static/unaccent.html
26 # should 'ignore accents' do 31 # should 'ignore accents' do
plugins/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
@@ -2,7 +2,7 @@ class SpaminatorPlugin::Mailer &lt; Noosfero::Plugin::MailerBase @@ -2,7 +2,7 @@ class SpaminatorPlugin::Mailer &lt; Noosfero::Plugin::MailerBase
2 2
3 def inactive_person_notification(person) 3 def inactive_person_notification(person)
4 recipients person.email 4 recipients person.email
5 - from "#{person.environment.name} <#{person.environment.contact_email}>" 5 + from "#{person.environment.name} <#{person.environment.noreply_email}>"
6 subject _("[%s] You must reactivate your account.") % person.environment.name 6 subject _("[%s] You must reactivate your account.") % person.environment.name
7 content_type 'text/html' 7 content_type 'text/html'
8 body :person => person, 8 body :person => person,
plugins/spaminator/test/unit/spaminator_plugin/mailer_test.rb
@@ -14,7 +14,7 @@ class SpaminatorPlugin::MailerTest &lt; ActiveSupport::TestCase @@ -14,7 +14,7 @@ class SpaminatorPlugin::MailerTest &lt; 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
plugins/statistics/README 0 → 100644
@@ -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
plugins/statistics/lib/statistics_block.rb 0 → 100644
@@ -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
plugins/statistics/lib/statistics_plugin.rb 0 → 100644
@@ -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
plugins/statistics/test/test_helper.rb 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +require File.dirname(__FILE__) + '/../../../test/test_helper'
plugins/statistics/test/unit/statistics_block_test.rb 0 → 100644
@@ -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
plugins/statistics/test/unit/statistics_plugin_test.rb 0 → 100644
@@ -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 %>
plugins/statistics/views/environment_design 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +box_organizer
0 \ No newline at end of file 2 \ No newline at end of file
plugins/statistics/views/profile_design 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +box_organizer
0 \ No newline at end of file 2 \ No newline at end of file
plugins/statistics/views/statistics_block.rhtml 0 → 100644
@@ -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 &lt; Noosfero::Plugin::ActiveRecord @@ -5,8 +5,7 @@ class ToleranceTimePlugin::Publication &lt; 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
plugins/variables/doc/variables.textile 0 → 100644
@@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
  1 +h1. Variables Plugin
  2 +
  3 +A set of simple variables to be used in a macro context.
  4 +
  5 +h2. Usage
  6 +
  7 +* Create a HTML content using RawHTMLBlock, TinyMceArticle or other
  8 + article with HTML support
  9 +* Add a HTML div tag with css class "macro" (see Example)
  10 +* Add inner that div tag the variable desired, like {profile}
  11 +
  12 +h2. Usage with TinyMceArticle
  13 +
  14 +The Noosfero's macros add a extra button in toolbar of the editor
  15 +to use macros in a single way, that way this plugin add a option
  16 +called "Variables" under this option.
  17 +
  18 +h2. Supported variables
  19 +
  20 +* {profile} - will be replaced by the identifier of the profile
  21 +* {name} - will be replaced by the name of the profile
  22 +
  23 +h2. Example
  24 +
  25 +<pre>
  26 +<div class="macro" data-macro="variables_plugin/profile">
  27 + the identifier of the profile = {profile}
  28 + the name of the profile = {name}
  29 +</div>
  30 +</pre>
  31 +
  32 +h2. Info
  33 +
  34 +This plugin was inspired by the solution proposed by the Serpro in
  35 +the merge-request #419 on the Gitorious:
  36 +
  37 +* https://gitorious.org/noosfero/noosfero/merge_requests/419
  38 +
  39 +And improved by the guys from the UnB.
plugins/variables/lib/variables_plugin.rb 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +class VariablesPlugin < Noosfero::Plugin
  2 +
  3 + def self.plugin_name
  4 + "Variables Plugin"
  5 + end
  6 +
  7 + def self.plugin_description
  8 + _("A set of simple variables to be used in a macro context")
  9 + end
  10 +
  11 +end
  12 +
  13 +require_dependency 'variables_plugin/macros/profile'
plugins/variables/lib/variables_plugin/macros/profile.rb 0 → 100644
@@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
  1 +ActionView::Base.sanitized_allowed_attributes += ['data-macro']
  2 +
  3 +class VariablesPlugin::Profile < Noosfero::Plugin::Macro
  4 +
  5 + def self.configuration
  6 + {
  7 + :title => _('Variables'),
  8 + :skip_dialog => false,
  9 + :generator => method(:macro_default_generator),
  10 + :params => [
  11 + {
  12 + :name => 'variable',
  13 + :label => _('Select the desired variable'),
  14 + :type => 'select',
  15 + :values => ['{profile}', '{name}']
  16 + }
  17 + ],
  18 + }
  19 + end
  20 +
  21 + def self.macro_default_generator(macro)
  22 + "
  23 + '<div class=\"macro mceNonEditable\" data-macro=\"#{macro.identifier}\">'
  24 + + jQuery('*[name=variable]', dialog).val()
  25 + + '</div>';
  26 + "
  27 + end
  28 +
  29 + def parse(params, inner_html, source)
  30 + if context.profile
  31 + inner_html.gsub!(/\{profile\}/, context.profile.identifier)
  32 + inner_html.gsub!(/\{name\}/, context.profile.name)
  33 + end
  34 + inner_html
  35 + end
  36 +
  37 +end
plugins/variables/test/unit/profile_test.rb 0 → 100644
@@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
  1 +class ProfileTest < ActiveSupport::TestCase
  2 +
  3 + def setup
  4 + @macro = VariablesPlugin::Profile.new
  5 + @macro.context = mock()
  6 + @profile = fast_create(Community)
  7 + @macro.context.stubs(:profile).returns(@profile)
  8 + end
  9 +
  10 + attr_reader :macro, :profile
  11 +
  12 + should 'have a configuration' do
  13 + assert VariablesPlugin::Profile.configuration
  14 + end
  15 +
  16 + should 'substitute the {profile} variable by the profile idenfifier' do
  17 + html = 'the profile identifier is {profile}'
  18 + content = macro.parse({}, html, profile)
  19 + assert_equal "the profile identifier is #{profile.identifier}", content
  20 + end
  21 +
  22 + should 'substitute the {name} variable by the profile name' do
  23 + html = 'the profile name is {name}'
  24 + content = macro.parse({}, html, profile)
  25 + assert_equal "the profile name is #{profile.name}", content
  26 + end
  27 +
  28 + should 'do not change the content if the variable is not supported' do
  29 + html = 'the variable {unsupported} is not supported'
  30 + content = macro.parse({}, html, profile)
  31 + assert_equal html, content
  32 + end
  33 +
  34 + should 'do nothing out of profile context' do
  35 + macro.context.stubs(:profile).returns(nil)
  36 + html = 'there is no {support} out of profile context'
  37 + content = macro.parse({}, html, profile)
  38 + assert_equal html, content
  39 + end
  40 +
  41 +end
plugins/variables/test/unit/variables_plugin_test.rb 0 → 100644
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +require 'test_helper'
  2 +
  3 +class VariablesPluginTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @environment = Environment.default
  7 + @plugin = VariablesPlugin.new
  8 + end
  9 +
  10 + attr_reader :environment, :plugin
  11 +
  12 + should 'have a name' do
  13 + assert_not_equal Noosfero::Plugin.plugin_name, VariablesPlugin::plugin_name
  14 + end
  15 +
  16 + should 'describe yourself' do
  17 + assert_not_equal Noosfero::Plugin.plugin_description, VariablesPlugin::plugin_description
  18 + end
  19 +
  20 +end
po/eo/noosfero.po
@@ -7,7 +7,7 @@ msgid &quot;&quot; @@ -7,7 +7,7 @@ msgid &quot;&quot;
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 &quot;&quot; @@ -107,7 +107,7 @@ msgstr &quot;&quot;
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 &quot;&quot; @@ -291,7 +291,7 @@ msgstr &quot;&quot;
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 &quot;&quot; @@ -678,11 +678,11 @@ msgstr &quot;&quot;
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 "&laquo; Newer posts" 680 msgid "&laquo; Newer posts"
681 -msgstr "" 681 +msgstr "&laquo; 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 &raquo;" 684 msgid "Older posts &raquo;"
685 -msgstr "" 685 +msgstr "Malpli freŝaj afiŝoj &raquo"
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 &quot;&quot; @@ -763,63 +763,63 @@ msgstr &quot;&quot;
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 &quot;&quot; @@ -834,7 +834,7 @@ msgstr &quot;&quot;
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 &quot;&quot; @@ -8043,7 +8043,7 @@ msgstr &quot;&quot;
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 &quot;&quot; @@ -7,7 +7,7 @@ msgid &quot;&quot;
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 &quot;Next&quot; @@ -292,7 +292,6 @@ msgid &quot;Next&quot;
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 &quot;Configurar foro&quot; @@ -690,11 +689,11 @@ msgstr &quot;Configurar foro&quot;
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 "&laquo; Newer posts" 691 msgid "&laquo; Newer posts"
693 -msgstr "&laquo; Entradas recientes" 692 +msgstr "&laquo; 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 &raquo;" 695 msgid "Older posts &raquo;"
697 -msgstr "Entradas antiguas &raquo;" 696 +msgstr "Noticias más viejas &raquo;"
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 &quot;%{day} de %{month} %{year}&quot; @@ -841,15 +840,13 @@ msgstr &quot;%{day} de %{month} %{year}&quot;
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 &quot;%{month} %{year}&quot; @@ -877,21 +874,19 @@ msgstr &quot;%{month} %{year}&quot;
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 &quot;&quot; @@ -8,7 +8,7 @@ msgid &quot;&quot;
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 &quot;&quot; @@ -109,7 +109,7 @@ msgstr &quot;&quot;
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 &quot;&quot; @@ -752,63 +752,63 @@ msgstr &quot;&quot;
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 &quot;&quot; @@ -823,7 +823,7 @@ msgstr &quot;&quot;
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 &quot;&quot; @@ -8016,7 +8016,7 @@ msgstr &quot;&quot;
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 &quot;Artigo de texto com linguagem de marcação Textile&quot; @@ -2875,6 +2875,30 @@ msgstr &quot;Artigo de texto com linguagem de marcação Textile&quot;
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 &quot;Funcionalidade&quot; @@ -7219,8 +7243,8 @@ msgstr &quot;Funcionalidade&quot;
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 &quot;Basket options&quot; @@ -12462,8 +12486,8 @@ msgid &quot;Basket options&quot;
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 &quot;ADD NEW OPTION&quot; @@ -12480,12 +12504,12 @@ msgid &quot;ADD NEW OPTION&quot;
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/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
1 -name: "No Side Bars" 1 +name: "No Sidebars"
2 title: "No sidebars, only content" 2 title: "No sidebars, only content"
3 description: "A template without sidebars, only content" 3 description: "A template without sidebars, only content"
4 number_of_boxes: 1 4 number_of_boxes: 1
public/designs/themes/base/style.css
@@ -1275,6 +1275,11 @@ hr.pre-posts, hr.sep-posts { @@ -1275,6 +1275,11 @@ hr.pre-posts, hr.sep-posts {
1275 padding-right: 9px; 1275 padding-right: 9px;
1276 } 1276 }
1277 1277
  1278 +.comment-order {
  1279 + float: right;
  1280 + display: block;
  1281 +}
  1282 +
1278 .comment-from-owner .comment-created-at { 1283 .comment-from-owner .comment-created-at {
1279 color: #333; 1284 color: #333;
1280 } 1285 }
public/images/drag-and-drop.png 0 → 100644

1.11 KB

public/javascripts/application.js
@@ -1101,4 +1101,4 @@ jQuery(document).ready(function(){ @@ -1101,4 +1101,4 @@ jQuery(document).ready(function(){
1101 jQuery("#article_has_terms_of_use").click(function(){ 1101 jQuery("#article_has_terms_of_use").click(function(){
1102 showHideTermsOfUse(); 1102 showHideTermsOfUse();
1103 }); 1103 });
1104 -});  
1105 \ No newline at end of file 1104 \ No newline at end of file
  1105 +});
public/javascripts/comment_order.js 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +function send_order(order, url) {
  2 + open_loading(DEFAULT_LOADING_MESSAGE);
  3 +
  4 + jQuery.ajax({
  5 + url:url,
  6 + data: {"comment_order":order},
  7 + success: function(response) {
  8 + close_loading();
  9 + jQuery(".article-comments-list").html(response);
  10 + },
  11 + error: function() { close_loading() }
  12 + });
  13 +}
  14 +
  15 +
  16 +jQuery(document).ready(function(){
  17 + jQuery("#comment_order").change(function(){
  18 + var url = jQuery("#page_url").val();
  19 + send_order(this.value, url);
  20 + });
  21 +});
0 \ No newline at end of file 22 \ No newline at end of file
public/javascripts/edit-link-list.js 0 → 100644
@@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
  1 +function send_ajax(source_url) {
  2 + jQuery(".link-address").autocomplete({
  3 + source : function(request, response){
  4 + jQuery.ajax({
  5 + type: "GET",
  6 + url: source_url,
  7 + data: {query: request.term},
  8 + success: function(result){
  9 + response(result);
  10 + },
  11 + error: function(ajax, stat, errorThrown) {
  12 + console.log('Link not found : ' + errorThrown);
  13 + }
  14 + });
  15 + },
  16 +
  17 + minLength: 3
  18 + });
  19 +}
  20 +
  21 +function new_link_action(){
  22 + send_ajax(jQuery("#page_url").val());
  23 +
  24 + jQuery(".delete-link-list-row").click(function(){
  25 + jQuery(this).parent().parent().remove();
  26 + return false;
  27 + });
  28 +
  29 + jQuery(document).scrollTop(jQuery('#dropable-link-list').scrollTop());
  30 +}
  31 +
  32 +jQuery(document).ready(function(){
  33 + new_link_action();
  34 +
  35 + jQuery("#dropable-link-list").sortable({
  36 + revert: true,
  37 + axis: "y"
  38 + });
  39 +});
0 \ No newline at end of file 40 \ No newline at end of file
public/javascripts/manage-fields.js 0 → 100644
@@ -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 +})
public/javascripts/sign_up_password_rate.js 0 → 100644
@@ -0,0 +1,121 @@ @@ -0,0 +1,121 @@
  1 +// This jQuery plugin is written by firas kassem [2007.04.05] and was modified to fit noosfero
  2 +// Firas Kassem phiras.wordpress.com || phiras at gmail {dot} com
  3 +// for more information : http://phiras.wordpress.com/2007/04/08/password-strength-meter-a-jquery-plugin/
  4 +
  5 +var blankPass = -1
  6 +var shortPass = 0
  7 +var badPass = 1
  8 +var goodPass = 2
  9 +var strongPass = 3
  10 +
  11 +
  12 +function passwordStrength(password,username)
  13 +{
  14 + score = 0
  15 +
  16 + if(password.length == 0) return blankPass
  17 +
  18 + //password < 4
  19 + if (password.length < 4 ) { return shortPass }
  20 +
  21 + //password == username
  22 + if (password.toLowerCase()==username.toLowerCase()) badPass
  23 +
  24 + //password length
  25 + score += password.length * 4
  26 + score += ( checkRepetition(1,password).length - password.length ) * 1
  27 + score += ( checkRepetition(2,password).length - password.length ) * 1
  28 + score += ( checkRepetition(3,password).length - password.length ) * 1
  29 + score += ( checkRepetition(4,password).length - password.length ) * 1
  30 +
  31 + //password has 3 numbers
  32 + if (password.match(/(.*[0-9].*[0-9].*[0-9])/)) score += 5
  33 +
  34 + //password has 2 sybols
  35 + if (password.match(/(.*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~])/)) score += 5
  36 +
  37 + //password has Upper and Lower chars
  38 + if (password.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/)) score += 10
  39 +
  40 + //password has number and chars
  41 + if (password.match(/([a-zA-Z])/) && password.match(/([0-9])/)) score += 15
  42 + //
  43 + //password has number and symbol
  44 + if (password.match(/([!,@,#,$,%,^,&,*,?,_,~])/) && password.match(/([0-9])/)) score += 15
  45 +
  46 + //password has char and symbol
  47 + if (password.match(/([!,@,#,$,%,^,&,*,?,_,~])/) && password.match(/([a-zA-Z])/)) score += 15
  48 +
  49 + //password is just a nubers or chars
  50 + if (password.match(/^\w+$/) || password.match(/^\d+$/) ) score -= 10
  51 +
  52 + //verifing 0 < score < 100
  53 + if ( score < 0 ) score = 0
  54 + if ( score > 100 ) score = 100
  55 +
  56 + if (score < 34 ) return badPass
  57 + if (score < 68 ) return goodPass
  58 + return strongPass
  59 +}
  60 +
  61 +function checkRepetition(pLen,str)
  62 +{
  63 + res = ""
  64 + for ( i=0; i<str.length ; i++ )
  65 + {
  66 + repeated=true
  67 + for (j=0;j < pLen && (j+i+pLen) < str.length;j++)
  68 + repeated=repeated && (str.charAt(j+i)==str.charAt(j+i+pLen))
  69 + if (j<pLen) repeated=false
  70 + if (repeated)
  71 + {
  72 + i+=pLen-1
  73 + repeated=false
  74 + }
  75 + else
  76 + {
  77 + res+=str.charAt(i)
  78 + }
  79 + }
  80 + return res
  81 +}
  82 +
  83 +jQuery(document).ready(function() {
  84 + jQuery('#user_pw').keyup(function()
  85 + {
  86 + var result = passwordStrength(jQuery('#user_pw').val(),jQuery('#user_login').val())
  87 + if(result == blankPass)
  88 + {
  89 + showRateField('#result-blank')
  90 + } else
  91 + if(result == shortPass)
  92 + {
  93 + showRateField('#result-short')
  94 + } else
  95 + if( result == badPass )
  96 + {
  97 + showRateField('#result-bad')
  98 + } else
  99 + if( result == goodPass )
  100 + {
  101 + showRateField('#result-good')
  102 + } else
  103 + if( result == strongPass )
  104 + {
  105 + showRateField('#result-strong')
  106 + }
  107 +
  108 + })
  109 +})
  110 +
  111 +function showRateField(validation)
  112 +{
  113 + jQuery('#result-blank').addClass('hidden')
  114 + jQuery('#result-short').addClass('hidden')
  115 + jQuery('#result-bad').addClass('hidden')
  116 + jQuery('#result-good').addClass('hidden')
  117 + jQuery('#result-strong').addClass('hidden')
  118 +
  119 + jQuery(validation).removeClass('hidden')
  120 +
  121 +}
0 \ No newline at end of file 122 \ No newline at end of file
public/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 }
@@ -5966,6 +6042,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { @@ -5966,6 +6042,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
5966 6042
5967 #email-check, 6043 #email-check,
5968 #fake-check, 6044 #fake-check,
  6045 +#password-rate,
5969 #password-check { 6046 #password-check {
5970 margin: -2px 16px -5px 13px; 6047 margin: -2px 16px -5px 13px;
5971 text-align: right; 6048 text-align: right;
@@ -5974,10 +6051,20 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { @@ -5974,10 +6051,20 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
5974 6051
5975 #email-check p, 6052 #email-check p,
5976 #fake-check p, 6053 #fake-check p,
  6054 +#password-rate p,
5977 #password-check p { 6055 #password-check p {
5978 margin: 0; 6056 margin: 0;
5979 } 6057 }
5980 6058
  6059 +#password-rate {
  6060 + font-weight:bold;
  6061 +}
  6062 +
  6063 +.hidden {
  6064 + visibility: hidden;
  6065 + display: none;
  6066 +}
  6067 +
5981 .available { 6068 .available {
5982 color: #88BD00; 6069 color: #88BD00;
5983 } 6070 }
@@ -5991,6 +6078,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { @@ -5991,6 +6078,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
5991 } 6078 }
5992 6079
5993 #email-check p, 6080 #email-check p,
  6081 +#password-rate p,
5994 #password-check p, 6082 #password-check p,
5995 #url-check p { 6083 #url-check p {
5996 margin: 0; 6084 margin: 0;
@@ -6488,3 +6576,31 @@ ul.article-versions li { @@ -6488,3 +6576,31 @@ ul.article-versions li {
6488 font-size: 13px; 6576 font-size: 13px;
6489 padding: 3px 0px; 6577 padding: 3px 0px;
6490 } 6578 }
  6579 +
  6580 +/* * * Admin manage fields * * */
  6581 +
  6582 +.controller-features .manage-fields-batch-actions,
  6583 +.controller-features .manage-fields-batch-actions:hover {
  6584 + border-bottom:solid 2px #000;
  6585 + background-color: #EEE;
  6586 +}
  6587 +
  6588 +.controller-features .manage-fields-batch-actions td {
  6589 + font-style: italic;
  6590 +}
  6591 +
  6592 +#signup-form #result-short {
  6593 + color: red;
  6594 +}
  6595 +
  6596 +#signup-form #result-bad {
  6597 + color: #825A2C;
  6598 +}
  6599 +
  6600 +#signup-form #result-good {
  6601 + color: #32CD32;
  6602 +}
  6603 +
  6604 +#signup-form #result-strong {
  6605 + color: green;
  6606 +}
test/functional/account_controller_test.rb
@@ -689,6 +689,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -689,6 +689,7 @@ class AccountControllerTest &lt; ActionController::TestCase
689 {:test => 5} 689 {:test => 5}
690 end 690 end
691 end 691 end
  692 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
692 693
693 e = User.find_by_login('ze').environment 694 e = User.find_by_login('ze').environment
694 e.enable_plugin(Plugin1.name) 695 e.enable_plugin(Plugin1.name)
@@ -779,6 +780,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -779,6 +780,7 @@ class AccountControllerTest &lt; ActionController::TestCase
779 lambda {"<strong>Plugin2 text</strong>"} 780 lambda {"<strong>Plugin2 text</strong>"}
780 end 781 end
781 end 782 end
  783 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
782 784
783 Environment.default.enable_plugin(Plugin1.name) 785 Environment.default.enable_plugin(Plugin1.name)
784 Environment.default.enable_plugin(Plugin2.name) 786 Environment.default.enable_plugin(Plugin2.name)
@@ -795,6 +797,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -795,6 +797,7 @@ class AccountControllerTest &lt; ActionController::TestCase
795 User.new(:login => 'testuser') 797 User.new(:login => 'testuser')
796 end 798 end
797 end 799 end
  800 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name])
798 Environment.default.enable_plugin(Plugin1.name) 801 Environment.default.enable_plugin(Plugin1.name)
799 802
800 post :login, :user => {:login => "testuser"} 803 post :login, :user => {:login => "testuser"}
@@ -809,6 +812,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -809,6 +812,7 @@ class AccountControllerTest &lt; ActionController::TestCase
809 nil 812 nil
810 end 813 end
811 end 814 end
  815 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name])
812 Environment.default.enable_plugin(Plugin1.name) 816 Environment.default.enable_plugin(Plugin1.name)
813 post :login, :user => {:login => 'johndoe', :password => 'test'} 817 post :login, :user => {:login => 'johndoe', :password => 'test'}
814 assert session[:user] 818 assert session[:user]
@@ -822,6 +826,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -822,6 +826,7 @@ class AccountControllerTest &lt; ActionController::TestCase
822 false 826 false
823 end 827 end
824 end 828 end
  829 + Noosfero::Plugin.stubs(:all).returns([TestRegistrationPlugin.name])
825 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestRegistrationPlugin.new]) 830 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestRegistrationPlugin.new])
826 831
827 post :signup, :user => { :login => 'testuser', :password => '123456', :password_confirmation => '123456', :email => 'testuser@example.com' } 832 post :signup, :user => { :login => 'testuser', :password => '123456', :password_confirmation => '123456', :email => 'testuser@example.com' }
@@ -840,6 +845,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -840,6 +845,7 @@ class AccountControllerTest &lt; ActionController::TestCase
840 true 845 true
841 end 846 end
842 end 847 end
  848 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
843 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new]) 849 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new])
844 850
845 get :login 851 get :login
@@ -853,6 +859,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -853,6 +859,7 @@ class AccountControllerTest &lt; ActionController::TestCase
853 false 859 false
854 end 860 end
855 end 861 end
  862 + Noosfero::Plugin.stubs(:all).returns([TestRegistrationPlugin.name])
856 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestRegistrationPlugin.new]) 863 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestRegistrationPlugin.new])
857 864
858 #Redirect on get action 865 #Redirect on get action
@@ -876,6 +883,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -876,6 +883,7 @@ class AccountControllerTest &lt; ActionController::TestCase
876 true 883 true
877 end 884 end
878 end 885 end
  886 + Noosfero::Plugin.stubs(:all).returns([Plugin1.new, Plugin2.new])
879 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new]) 887 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new])
880 888
881 get :login 889 get :login
@@ -894,6 +902,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -894,6 +902,7 @@ class AccountControllerTest &lt; ActionController::TestCase
894 lambda {"<strong>Plugin2 text</strong>"} 902 lambda {"<strong>Plugin2 text</strong>"}
895 end 903 end
896 end 904 end
  905 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
897 906
898 Environment.default.enable_plugin(Plugin1.name) 907 Environment.default.enable_plugin(Plugin1.name)
899 Environment.default.enable_plugin(Plugin2.name) 908 Environment.default.enable_plugin(Plugin2.name)
test/functional/application_controller_test.rb
@@ -233,7 +233,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -233,7 +233,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase
233 get :index 233 get :index
234 234
235 assert_tag :tag => 'div', :attributes => { :id => 'theme-test-panel' }, :descendant => { 235 assert_tag :tag => 'div', :attributes => { :id => 'theme-test-panel' }, :descendant => {
236 - :tag => 'a', :attributes => { :href => '/myprofile/testinguser/themes/edit/my-test-theme'} 236 + :tag => 'a', :attributes => { :href => '/myprofile/testinguser/profile_themes/edit/my-test-theme'}
237 } 237 }
238 #{ :tag => 'a', :attributes => { :href => '/myprofile/testinguser/themes/stop_test/my-test-theme'} } 238 #{ :tag => 'a', :attributes => { :href => '/myprofile/testinguser/themes/stop_test/my-test-theme'} }
239 end 239 end
@@ -263,7 +263,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -263,7 +263,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase
263 assert_no_tag :tag => 'a', :content => /Category 2/ 263 assert_no_tag :tag => 'a', :content => /Category 2/
264 end 264 end
265 265
266 - should 'show name of article as title of page' do 266 + should 'show name of article as title of page without environment' do
267 p = create_user('test_user').person 267 p = create_user('test_user').person
268 a = p.articles.create!(:name => 'test article') 268 a = p.articles.create!(:name => 'test article')
269 269
@@ -271,17 +271,22 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -271,17 +271,22 @@ class ApplicationControllerTest &lt; ActionController::TestCase
271 @controller.instance_variable_set('@page', a) 271 @controller.instance_variable_set('@page', a)
272 272
273 get :index 273 get :index
274 - assert_tag 'title', :content => 'test article - ' + p.name + ' - ' + p.environment.name 274 + assert_tag 'title', :content => 'test article - ' + p.name
275 end 275 end
276 276
277 - should 'diplay name of profile in the title' do 277 + should 'diplay name of profile in the title without environment' do
278 p = create_user('test_user').person 278 p = create_user('test_user').person
279 p.name = 'Some Test User' 279 p.name = 'Some Test User'
280 p.save! 280 p.save!
281 @controller.instance_variable_set('@profile', p) 281 @controller.instance_variable_set('@profile', p)
282 282
283 get :index, :profile => p.identifier 283 get :index, :profile => p.identifier
284 - assert_tag 'title', :content => p.name + ' - ' + p.environment.name 284 + assert_tag 'title', :content => p.name
  285 + end
  286 +
  287 + should 'display environment name in title when profile and page are not defined' do
  288 + get :index
  289 + assert_tag 'title', :content => assigns(:environment).name
285 end 290 end
286 291
287 should 'display menu links for my environment when logged in other environment' do 292 should 'display menu links for my environment when logged in other environment' do
@@ -324,7 +329,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -324,7 +329,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase
324 end 329 end
325 330
326 should 'set html lang as the article language if an article is present and has a language' do 331 should 'set html lang as the article language if an article is present and has a language' do
327 - a = fast_create(Article, :name => 'test article', :language => 'fr') 332 + p = create_user('test_user').person
  333 + a = fast_create(Article, :name => 'test article', :language => 'fr', :profile_id => p.id )
328 @controller.instance_variable_set('@page', a) 334 @controller.instance_variable_set('@page', a)
329 FastGettext.stubs(:locale).returns('es') 335 FastGettext.stubs(:locale).returns('es')
330 get :index 336 get :index
@@ -338,7 +344,9 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -338,7 +344,9 @@ class ApplicationControllerTest &lt; ActionController::TestCase
338 end 344 end
339 345
340 should 'set html lang as locale if page has no language' do 346 should 'set html lang as locale if page has no language' do
341 - a = fast_create(Article, :name => 'test article', :language => nil) 347 + p = create_user('test_user').person
  348 + a = fast_create(Article, :name => 'test article', :language => nil, :profile_id => p.id )
  349 +
342 @controller.instance_variable_set('@page', a) 350 @controller.instance_variable_set('@page', a)
343 FastGettext.stubs(:locale).returns('es') 351 FastGettext.stubs(:locale).returns('es')
344 get :index 352 get :index
@@ -366,6 +374,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -366,6 +374,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase
366 end 374 end
367 plugin2_path = '/plugin2/style.css' 375 plugin2_path = '/plugin2/style.css'
368 376
  377 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
  378 +
369 environment = Environment.default 379 environment = Environment.default
370 environment.enable_plugin(Plugin1.name) 380 environment.enable_plugin(Plugin1.name)
371 environment.enable_plugin(Plugin2.name) 381 environment.enable_plugin(Plugin2.name)
@@ -397,6 +407,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -397,6 +407,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase
397 plugin2_path2 = '/plugin2/'+js2 407 plugin2_path2 = '/plugin2/'+js2
398 plugin2_path3 = '/plugin2/'+js3 408 plugin2_path3 = '/plugin2/'+js3
399 409
  410 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
  411 +
400 environment = Environment.default 412 environment = Environment.default
401 environment.enable_plugin(Plugin1.name) 413 environment.enable_plugin(Plugin1.name)
402 environment.enable_plugin(Plugin2.name) 414 environment.enable_plugin(Plugin2.name)
@@ -423,6 +435,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -423,6 +435,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase
423 end 435 end
424 end 436 end
425 437
  438 + Noosfero::Plugin.stubs(:all).returns([TestBodyBeginning1Plugin.name, TestBodyBeginning2Plugin.name])
  439 +
426 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestBodyBeginning1Plugin.new, TestBodyBeginning2Plugin.new]) 440 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestBodyBeginning1Plugin.new, TestBodyBeginning2Plugin.new])
427 441
428 get :index 442 get :index
@@ -447,6 +461,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -447,6 +461,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase
447 end 461 end
448 end 462 end
449 463
  464 + Noosfero::Plugin.stubs(:all).returns([TestHeadEnding1Plugin.name, TestHeadEnding2Plugin.name])
  465 +
450 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestHeadEnding1Plugin.new, TestHeadEnding2Plugin.new]) 466 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestHeadEnding1Plugin.new, TestHeadEnding2Plugin.new])
451 467
452 get :index 468 get :index
@@ -511,6 +527,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -511,6 +527,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase
511 :block => lambda {} } 527 :block => lambda {} }
512 end 528 end
513 end 529 end
  530 + Noosfero::Plugin.stubs(:all).returns([FilterPlugin.name])
514 531
515 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([FilterPlugin.new]) 532 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([FilterPlugin.new])
516 533
@@ -529,6 +546,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -529,6 +546,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase
529 :block => lambda {'plugin block called'} } 546 :block => lambda {'plugin block called'} }
530 end 547 end
531 end 548 end
  549 + Noosfero::Plugin.stubs(:all).returns([OtherFilterPlugin.name])
532 550
533 environment1 = fast_create(Environment, :name => 'test environment') 551 environment1 = fast_create(Environment, :name => 'test environment')
534 environment1.enable_plugin(OtherFilterPlugin.name) 552 environment1.enable_plugin(OtherFilterPlugin.name)
@@ -542,4 +560,18 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -542,4 +560,18 @@ class ApplicationControllerTest &lt; ActionController::TestCase
542 assert_equal nil, @controller.application_controller_test_other_filter_plugin_filter_plugin 560 assert_equal nil, @controller.application_controller_test_other_filter_plugin_filter_plugin
543 end 561 end
544 562
  563 + should 'display meta tags for social media' do
  564 + get :index
  565 + assert_tag :tag => 'meta', :attributes => { :name => 'twitter:card', :value => 'summary' }
  566 + assert_tag :tag => 'meta', :attributes => { :name => 'twitter:title', :content => assigns(:environment).name }
  567 + assert_tag :tag => 'meta', :attributes => { :name => 'twitter:description', :content => assigns(:environment).name }
  568 + assert_no_tag :tag => 'meta', :attributes => { :name => 'twitter:image' }
  569 + assert_tag :tag => 'meta', :attributes => { :property => 'og:type', :content => 'website' }
  570 + assert_tag :tag => 'meta', :attributes => { :property => 'og:url', :content => assigns(:environment).top_url }
  571 + assert_tag :tag => 'meta', :attributes => { :property => 'og:title', :content => assigns(:environment).name }
  572 + assert_tag :tag => 'meta', :attributes => { :property => 'og:site_name', :content => assigns(:environment).name }
  573 + assert_tag :tag => 'meta', :attributes => { :property => 'og:description', :content => assigns(:environment).name }
  574 + assert_no_tag :tag => 'meta', :attributes => { :property => 'article:published_time' }
  575 + assert_no_tag :tag => 'meta', :attributes => { :property => 'og:image' }
  576 + end
545 end 577 end
test/functional/catalog_controller_test.rb
@@ -91,6 +91,7 @@ class CatalogControllerTest &lt; ActionController::TestCase @@ -91,6 +91,7 @@ class CatalogControllerTest &lt; ActionController::TestCase
91 lambda {"<span id='plugin2'>This is Plugin2 speaking!</span>"} 91 lambda {"<span id='plugin2'>This is Plugin2 speaking!</span>"}
92 end 92 end
93 end 93 end
  94 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
94 95
95 product = fast_create(Product, :profile_id => @enterprise.id) 96 product = fast_create(Product, :profile_id => @enterprise.id)
96 environment = Environment.default 97 environment = Environment.default
test/functional/cms_controller_test.rb
@@ -451,24 +451,23 @@ class CmsControllerTest &lt; ActionController::TestCase @@ -451,24 +451,23 @@ class CmsControllerTest &lt; ActionController::TestCase
451 assert_tag :tag => 'h3', :content => /max size #{UploadedFile.max_size.to_humanreadable}/ 451 assert_tag :tag => 'h3', :content => /max size #{UploadedFile.max_size.to_humanreadable}/
452 end 452 end
453 453
454 - should 'display link for selecting categories' do  
455 - # FIXME  
456 - assert true  
457 - #env = Environment.default  
458 - #top = env.categories.build(:display_in_menu => true, :name => 'Top-Level category'); top.save!  
459 - #c1 = env.categories.build(:display_in_menu => true, :name => "Test category 1", :parent_id => top.id); c1.save!  
460 - #c2 = env.categories.build(:display_in_menu => true, :name => "Test category 2", :parent_id => top.id); c2.save!  
461 - #c3 = env.categories.build(:display_in_menu => true, :name => "Test Category 3", :parent_id => top.id); c3.save!  
462 -  
463 - #article = Article.new(:name => 'test')  
464 - #article.profile = profile  
465 - #article.save!  
466 -  
467 - #get :edit, :profile => profile.identifier, :id => article.id  
468 -  
469 - #[c1,c2,c3].each do |item|  
470 - # assert_tag :tag => 'a', :attributes => { :id => "select-category-#{item.id}-link" }  
471 - #end 454 + should 'display link for selecting top categories' do
  455 + env = Environment.default
  456 + top = env.categories.build(:display_in_menu => true, :name => 'Top-Level category'); top.save!
  457 + top2 = env.categories.build(:display_in_menu => true, :name => 'Top-Level category 2'); top2.save!
  458 + c1 = env.categories.build(:display_in_menu => true, :name => "Test category 1", :parent_id => top.id); c1.save!
  459 + c2 = env.categories.build(:display_in_menu => true, :name => "Test category 2", :parent_id => top.id); c2.save!
  460 + c3 = env.categories.build(:display_in_menu => true, :name => "Test Category 3", :parent_id => top.id); c3.save!
  461 +
  462 + article = Article.new(:name => 'test')
  463 + article.profile = profile
  464 + article.save!
  465 +
  466 + get :edit, :profile => profile.identifier, :id => article.id
  467 +
  468 + [top, top2].each do |item|
  469 + assert_tag :tag => 'a', :attributes => { :id => "select-category-#{item.id}-link" }
  470 + end
472 end 471 end
473 472
474 should 'be able to associate articles with categories' do 473 should 'be able to associate articles with categories' do
test/functional/content_viewer_controller_test.rb
@@ -741,16 +741,6 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -741,16 +741,6 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
741 assert_tag :tag => 'li', :attributes => {:title => 'my img title', :class => 'image-gallery-item'}, :child => {:tag => 'span', :content => 'my img title'} 741 assert_tag :tag => 'li', :attributes => {:title => 'my img title', :class => 'image-gallery-item'}, :child => {:tag => 'span', :content => 'my img title'}
742 end 742 end
743 743
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.explode_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 744 should 'allow publisher owner view private articles' do
755 c = Community.create!(:name => 'test_com') 745 c = Community.create!(:name => 'test_com')
756 u = create_user_with_permission('test_user', 'publish_content', c) 746 u = create_user_with_permission('test_user', 'publish_content', c)
@@ -1209,6 +1199,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1209,6 +1199,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1209 class Plugin2 < Noosfero::Plugin 1199 class Plugin2 < Noosfero::Plugin
1210 def content_remove_edit(content); false; end 1200 def content_remove_edit(content); false; end
1211 end 1201 end
  1202 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
1212 1203
1213 environment.enable_plugin(Plugin1.name) 1204 environment.enable_plugin(Plugin1.name)
1214 environment.enable_plugin(Plugin2.name) 1205 environment.enable_plugin(Plugin2.name)
@@ -1225,6 +1216,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1225,6 +1216,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1225 class Plugin2 < Noosfero::Plugin 1216 class Plugin2 < Noosfero::Plugin
1226 def content_expire_edit(content); nil; end 1217 def content_expire_edit(content); nil; end
1227 end 1218 end
  1219 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
1228 1220
1229 environment.enable_plugin(Plugin1.name) 1221 environment.enable_plugin(Plugin1.name)
1230 environment.enable_plugin(Plugin2.name) 1222 environment.enable_plugin(Plugin2.name)
@@ -1270,6 +1262,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1270,6 +1262,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1270 } 1262 }
1271 end 1263 end
1272 end 1264 end
  1265 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
1273 1266
1274 Environment.default.enable_plugin(Plugin1.name) 1267 Environment.default.enable_plugin(Plugin1.name)
1275 Environment.default.enable_plugin(Plugin2.name) 1268 Environment.default.enable_plugin(Plugin2.name)
@@ -1294,6 +1287,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1294,6 +1287,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1294 scope.where(:referrer => 'kernel.org') 1287 scope.where(:referrer => 'kernel.org')
1295 end 1288 end
1296 end 1289 end
  1290 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
1297 1291
1298 Environment.default.enable_plugin(Plugin1) 1292 Environment.default.enable_plugin(Plugin1)
1299 Environment.default.enable_plugin(Plugin2) 1293 Environment.default.enable_plugin(Plugin2)
@@ -1351,6 +1345,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1351,6 +1345,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1351 } 1345 }
1352 end 1346 end
1353 end 1347 end
  1348 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
1354 1349
1355 Environment.default.enable_plugin(Plugin1.name) 1350 Environment.default.enable_plugin(Plugin1.name)
1356 Environment.default.enable_plugin(Plugin2.name) 1351 Environment.default.enable_plugin(Plugin2.name)
@@ -1369,4 +1364,28 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1369,4 +1364,28 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1369 assert_match /this is a sample text file/, @response.body 1364 assert_match /this is a sample text file/, @response.body
1370 end 1365 end
1371 1366
  1367 + should 'add meta tags with article info' do
  1368 + a = TinyMceArticle.create(:name => 'Article to be shared', :body => 'This article should be shared with all social networks', :profile => profile)
  1369 +
  1370 + get :view_page, :profile => profile.identifier, :page => [ a.name.to_slug ]
  1371 +
  1372 + assert_tag :tag => 'meta', :attributes => { :name => 'twitter:title', :content => /#{a.name} - #{a.profile.name}/ }
  1373 + assert_tag :tag => 'meta', :attributes => { :name => 'twitter:description', :content => a.body }
  1374 + assert_no_tag :tag => 'meta', :attributes => { :name => 'twitter:image' }
  1375 + assert_tag :tag => 'meta', :attributes => { :property => 'og:type', :content => 'article' }
  1376 + assert_tag :tag => 'meta', :attributes => { :property => 'og:url', :content => /\/#{profile.identifier}\/#{a.name.to_slug}/ }
  1377 + assert_tag :tag => 'meta', :attributes => { :property => 'og:title', :content => /#{a.name} - #{a.profile.name}/ }
  1378 + assert_tag :tag => 'meta', :attributes => { :property => 'og:site_name', :content => a.profile.name }
  1379 + assert_tag :tag => 'meta', :attributes => { :property => 'og:description', :content => a.body }
  1380 + assert_no_tag :tag => 'meta', :attributes => { :property => 'og:image' }
  1381 + end
  1382 +
  1383 + should 'add meta tags with article images' do
  1384 + 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)
  1385 +
  1386 + get :view_page, :profile => profile.identifier, :page => [ a.name.to_slug ]
  1387 + assert_tag :tag => 'meta', :attributes => { :name => 'twitter:image', :content => /\/images\/x.png/ }
  1388 + assert_tag :tag => 'meta', :attributes => { :property => 'og:image', :content => /\/images\/x.png/ }
  1389 + end
  1390 +
1372 end 1391 end
test/functional/enterprise_registration_controller_test.rb
@@ -193,6 +193,7 @@ class EnterpriseRegistrationControllerTest &lt; ActionController::TestCase @@ -193,6 +193,7 @@ class EnterpriseRegistrationControllerTest &lt; ActionController::TestCase
193 {'plugin2' => 'Plugin 2'} 193 {'plugin2' => 'Plugin 2'}
194 end 194 end
195 end 195 end
  196 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
196 197
197 environment = Environment.default 198 environment = Environment.default
198 environment.enable_plugin(Plugin1.name) 199 environment.enable_plugin(Plugin1.name)
test/functional/environment_design_controller_test.rb
@@ -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 &lt; ActionController::TestCase @@ -83,6 +85,8 @@ class EnvironmentDesignControllerTest &lt; 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 &lt; ActionController::TestCase @@ -366,4 +370,47 @@ class EnvironmentDesignControllerTest &lt; 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,12 @@ class EventsControllerTest &lt; ActionController::TestCase @@ -38,4 +38,12 @@ class EventsControllerTest &lt; 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 +
41 end 49 end
test/functional/friends_controller_test.rb
@@ -68,6 +68,7 @@ class FriendsControllerTest &lt; ActionController::TestCase @@ -68,6 +68,7 @@ class FriendsControllerTest &lt; ActionController::TestCase
68 false 68 false
69 end 69 end
70 end 70 end
  71 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
71 72
72 e = profile.environment 73 e = profile.environment
73 e.enable_plugin(Plugin1.name) 74 e.enable_plugin(Plugin1.name)
test/functional/home_controller_test.rb
@@ -107,6 +107,7 @@ class HomeControllerTest &lt; ActionController::TestCase @@ -107,6 +107,7 @@ class HomeControllerTest &lt; ActionController::TestCase
107 lambda {"<a href='plugin2'>Plugin2 link</a>"} 107 lambda {"<a href='plugin2'>Plugin2 link</a>"}
108 end 108 end
109 end 109 end
  110 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
110 111
111 Environment.default.enable_plugin(Plugin1) 112 Environment.default.enable_plugin(Plugin1)
112 Environment.default.enable_plugin(Plugin2) 113 Environment.default.enable_plugin(Plugin2)
@@ -129,6 +130,7 @@ class HomeControllerTest &lt; ActionController::TestCase @@ -129,6 +130,7 @@ class HomeControllerTest &lt; ActionController::TestCase
129 true 130 true
130 end 131 end
131 end 132 end
  133 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
132 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new]) 134 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new, Plugin2.new])
133 135
134 get :index 136 get :index
test/functional/invite_controller_test.rb
@@ -7,6 +7,7 @@ class InviteControllerTest &lt; ActionController::TestCase @@ -7,6 +7,7 @@ class InviteControllerTest &lt; 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 &lt; ActionController::TestCase @@ -230,7 +231,8 @@ class InviteControllerTest &lt; 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 &lt; ActionController::TestCase @@ -234,6 +234,7 @@ class MembershipsControllerTest &lt; ActionController::TestCase
234 {'plugin2' => 'Plugin 2'} 234 {'plugin2' => 'Plugin 2'}
235 end 235 end
236 end 236 end
  237 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
237 238
238 environment = Environment.default 239 environment = Environment.default
239 environment.enable_plugin(Plugin1.name) 240 environment.enable_plugin(Plugin1.name)
test/functional/plugins_controller_test.rb
@@ -47,7 +47,7 @@ class PluginsControllerTest &lt; ActionController::TestCase @@ -47,7 +47,7 @@ class PluginsControllerTest &lt; ActionController::TestCase
47 end 47 end
48 end 48 end
49 49
50 - Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s,Plugin2.to_s]) 50 + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s])
51 51
52 get :index 52 get :index
53 53
test/functional/profile_controller_test.rb
@@ -176,7 +176,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -176,7 +176,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
176 should 'not show Leave This Community button for non-registered users' do 176 should 'not show Leave This Community button for non-registered users' do
177 community = Community.create!(:name => 'my test community') 177 community = Community.create!(:name => 'my test community')
178 community.boxes.first.blocks << block = ProfileInfoBlock.create! 178 community.boxes.first.blocks << block = ProfileInfoBlock.create!
179 - get :profile_info, :profile => community.identifier, :block_id => block.id 179 + get :index, :profile => community.identifier
180 assert_no_match /\/profile\/#{@profile.identifier}\/leave/, @response.body 180 assert_no_match /\/profile\/#{@profile.identifier}\/leave/, @response.body
181 end 181 end
182 182
@@ -206,7 +206,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -206,7 +206,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
206 friend = create_user_full('friendtestuser').person 206 friend = create_user_full('friendtestuser').person
207 friend.user.activate 207 friend.user.activate
208 friend.boxes.first.blocks << block = ProfileInfoBlock.create! 208 friend.boxes.first.blocks << block = ProfileInfoBlock.create!
209 - get :profile_info, :profile => friend.identifier, :block_id => block.id 209 + get :index, :profile => friend.identifier
210 assert_match /Add friend/, @response.body 210 assert_match /Add friend/, @response.body
211 end 211 end
212 212
@@ -215,7 +215,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -215,7 +215,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
215 friend = create_user_full('friendtestuser').person 215 friend = create_user_full('friendtestuser').person
216 friend.boxes.first.blocks << block = ProfileInfoBlock.create! 216 friend.boxes.first.blocks << block = ProfileInfoBlock.create!
217 AddFriend.create!(:person => @profile, :friend => friend) 217 AddFriend.create!(:person => @profile, :friend => friend)
218 - get :profile_info, :profile => friend.identifier, :block_id => block.id 218 + get :index, :profile => friend.identifier
219 assert_no_match /Add friend/, @response.body 219 assert_no_match /Add friend/, @response.body
220 end 220 end
221 221
@@ -226,7 +226,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -226,7 +226,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
226 @profile.add_friend(friend) 226 @profile.add_friend(friend)
227 @profile.friends.reload 227 @profile.friends.reload
228 assert @profile.is_a_friend?(friend) 228 assert @profile.is_a_friend?(friend)
229 - get :profile_info, :profile => friend.identifier, :block_id => block.id 229 + get :index, :profile => friend.identifier
230 assert_no_match /Add friend/, @response.body 230 assert_no_match /Add friend/, @response.body
231 end 231 end
232 232
@@ -301,13 +301,13 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -301,13 +301,13 @@ class ProfileControllerTest &lt; ActionController::TestCase
301 should 'display contact us for enterprises' do 301 should 'display contact us for enterprises' do
302 ent = Enterprise.create!(:name => 'my test enterprise', :identifier => 'my-test-enterprise') 302 ent = Enterprise.create!(:name => 'my test enterprise', :identifier => 'my-test-enterprise')
303 ent.boxes.first.blocks << block = ProfileInfoBlock.create! 303 ent.boxes.first.blocks << block = ProfileInfoBlock.create!
304 - get :profile_info, :profile => 'my-test-enterprise', :block_id => block.id 304 + get :index, :profile => 'my-test-enterprise'
305 assert_match /\/contact\/my-test-enterprise\/new/, @response.body 305 assert_match /\/contact\/my-test-enterprise\/new/, @response.body
306 end 306 end
307 307
308 should 'not display contact us for non-enterprises' do 308 should 'not display contact us for non-enterprises' do
309 @profile.boxes.first.blocks << block = ProfileInfoBlock.create! 309 @profile.boxes.first.blocks << block = ProfileInfoBlock.create!
310 - get :profile_info, :profile => @profile.identifier, :block_id => block.id 310 + get :index, :profile => @profile.identifier
311 assert_no_match /\/contact\/#{@profile.identifier}\/new/, @response.body 311 assert_no_match /\/contact\/#{@profile.identifier}\/new/, @response.body
312 end 312 end
313 313
@@ -315,7 +315,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -315,7 +315,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
315 ent = Enterprise.create! :name => 'my test enterprise', :identifier => 'my-test-enterprise' 315 ent = Enterprise.create! :name => 'my test enterprise', :identifier => 'my-test-enterprise'
316 ent.boxes.first.blocks << block = ProfileInfoBlock.create! 316 ent.boxes.first.blocks << block = ProfileInfoBlock.create!
317 ent.update_attribute(:enable_contact_us, false) 317 ent.update_attribute(:enable_contact_us, false)
318 - get :profile_info, :profile => 'my-test-enterprise', :block_id => block.id 318 + get :index, :profile => 'my-test-enterprise'
319 assert_no_match /\/contact\/my-test-enterprise\/new/, @response.body 319 assert_no_match /\/contact\/my-test-enterprise\/new/, @response.body
320 end 320 end
321 321
@@ -328,7 +328,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -328,7 +328,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
328 env.disable('disable_contact_person') 328 env.disable('disable_contact_person')
329 env.save! 329 env.save!
330 login_as(@profile.identifier) 330 login_as(@profile.identifier)
331 - get :profile_info, :profile => friend.identifier, :block_id => block.id 331 + get :index, :profile => friend.identifier
332 assert_match /\/contact\/#{friend.identifier}\/new/, @response.body 332 assert_match /\/contact\/#{friend.identifier}\/new/, @response.body
333 end 333 end
334 334
@@ -336,7 +336,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -336,7 +336,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
336 nofriend = create_user_full('no_friend').person 336 nofriend = create_user_full('no_friend').person
337 nofriend.boxes.first.blocks << block = ProfileInfoBlock.create! 337 nofriend.boxes.first.blocks << block = ProfileInfoBlock.create!
338 login_as(@profile.identifier) 338 login_as(@profile.identifier)
339 - get :profile_info, :profile => nofriend.identifier, :block_id => block.id 339 + get :index, :profile => nofriend.identifier
340 assert_no_match /\/contact\/#{nofriend.identifier}\/new/, @response.body 340 assert_no_match /\/contact\/#{nofriend.identifier}\/new/, @response.body
341 end 341 end
342 342
@@ -349,7 +349,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -349,7 +349,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
349 env.save! 349 env.save!
350 @profile.add_friend(friend) 350 @profile.add_friend(friend)
351 login_as(@profile.identifier) 351 login_as(@profile.identifier)
352 - get :profile_info, :profile => friend.identifier, :block_id => block.id 352 + get :index, :profile => friend.identifier
353 assert_match /\/contact\/#{friend.identifier}\/new/, @response.body 353 assert_match /\/contact\/#{friend.identifier}\/new/, @response.body
354 end 354 end
355 355
@@ -361,7 +361,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -361,7 +361,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
361 env.save! 361 env.save!
362 @profile.add_friend(friend) 362 @profile.add_friend(friend)
363 login_as(@profile.identifier) 363 login_as(@profile.identifier)
364 - get :profile_info, :profile => friend.identifier, :block_id => block.id 364 + get :index, :profile => friend.identifier
365 assert_no_match /\/contact\/#{friend.identifier}\/new/, @response.body 365 assert_no_match /\/contact\/#{friend.identifier}\/new/, @response.body
366 end 366 end
367 367
@@ -373,7 +373,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -373,7 +373,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
373 env.save! 373 env.save!
374 community.add_member(@profile) 374 community.add_member(@profile)
375 login_as(@profile.identifier) 375 login_as(@profile.identifier)
376 - get :profile_info, :profile => community.identifier, :block_id => block.id 376 + get :index, :profile => community.identifier
377 assert_match /\/contact\/#{community.identifier}\/new/, @response.body 377 assert_match /\/contact\/#{community.identifier}\/new/, @response.body
378 end 378 end
379 379
@@ -385,7 +385,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -385,7 +385,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
385 env.save! 385 env.save!
386 community.add_member(@profile) 386 community.add_member(@profile)
387 login_as(@profile.identifier) 387 login_as(@profile.identifier)
388 - get :profile_info, :profile => community.identifier, :block_id => block.id 388 + get :index, :profile => community.identifier
389 assert_no_match /\/contact\/#{community.identifier}\/new/, @response.body 389 assert_no_match /\/contact\/#{community.identifier}\/new/, @response.body
390 end 390 end
391 391
@@ -766,23 +766,28 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -766,23 +766,28 @@ class ProfileControllerTest &lt; ActionController::TestCase
766 end 766 end
767 767
768 should 'see all the activities in the current profile network' do 768 should 'see all the activities in the current profile network' do
769 - p1= Person.first 769 + p1= fast_create(Person)
770 p2= fast_create(Person) 770 p2= fast_create(Person)
771 assert !p1.is_a_friend?(p2) 771 assert !p1.is_a_friend?(p2)
  772 +
772 p3= fast_create(Person) 773 p3= fast_create(Person)
773 p3.add_friend(p1) 774 p3.add_friend(p1)
774 assert p3.is_a_friend?(p1) 775 assert p3.is_a_friend?(p1)
775 - ActionTracker::Record.destroy_all 776 +
  777 + ActionTracker::Record.delete_all
  778 +
  779 + UserStampSweeper.any_instance.stubs(:current_user).returns(p1)
776 Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1)) 780 Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1))
777 a1 = ActionTracker::Record.last 781 a1 = ActionTracker::Record.last
  782 +
778 UserStampSweeper.any_instance.stubs(:current_user).returns(p2) 783 UserStampSweeper.any_instance.stubs(:current_user).returns(p2)
779 Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3)) 784 Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3))
780 a2 = ActionTracker::Record.last 785 a2 = ActionTracker::Record.last
  786 +
781 UserStampSweeper.any_instance.stubs(:current_user).returns(p3) 787 UserStampSweeper.any_instance.stubs(:current_user).returns(p3)
782 Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1)) 788 Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1))
783 a3 = ActionTracker::Record.last 789 a3 = ActionTracker::Record.last
784 790
785 -  
786 @controller.stubs(:logged_in?).returns(true) 791 @controller.stubs(:logged_in?).returns(true)
787 user = mock() 792 user = mock()
788 user.stubs(:person).returns(p3) 793 user.stubs(:person).returns(p3)
@@ -792,24 +797,29 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -792,24 +797,29 @@ class ProfileControllerTest &lt; ActionController::TestCase
792 797
793 process_delayed_job_queue 798 process_delayed_job_queue
794 get :index, :profile => p1.identifier 799 get :index, :profile => p1.identifier
795 - assert_not_nil assigns(:network_activities)  
796 - assert_equal [], [a1,a3] - assigns(:network_activities)  
797 - assert_equal assigns(:network_activities) - [a1, a3], [] 800 +
  801 + assert_equivalent [a1,a3].map(&:id), assigns(:network_activities).map(&:id)
798 end 802 end
799 803
800 should 'the network activity be visible only to profile followers' do 804 should 'the network activity be visible only to profile followers' do
801 - p1= Person.first 805 + p1= fast_create(Person)
802 p2= fast_create(Person) 806 p2= fast_create(Person)
803 assert !p1.is_a_friend?(p2) 807 assert !p1.is_a_friend?(p2)
  808 +
804 p3= fast_create(Person) 809 p3= fast_create(Person)
805 p3.add_friend(p1) 810 p3.add_friend(p1)
806 assert p3.is_a_friend?(p1) 811 assert p3.is_a_friend?(p1)
807 - ActionTracker::Record.destroy_all 812 +
  813 + ActionTracker::Record.delete_all
  814 +
  815 + UserStampSweeper.any_instance.stubs(:current_user).returns(p1)
808 Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1)) 816 Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1))
809 a1 = ActionTracker::Record.last 817 a1 = ActionTracker::Record.last
  818 +
810 UserStampSweeper.any_instance.stubs(:current_user).returns(p2) 819 UserStampSweeper.any_instance.stubs(:current_user).returns(p2)
811 Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3)) 820 Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3))
812 a2 = ActionTracker::Record.last 821 a2 = ActionTracker::Record.last
  822 +
813 UserStampSweeper.any_instance.stubs(:current_user).returns(p3) 823 UserStampSweeper.any_instance.stubs(:current_user).returns(p3)
814 Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1)) 824 Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1))
815 a3 = ActionTracker::Record.last 825 a3 = ActionTracker::Record.last
@@ -819,8 +829,9 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -819,8 +829,9 @@ class ProfileControllerTest &lt; ActionController::TestCase
819 user.stubs(:person).returns(p2) 829 user.stubs(:person).returns(p2)
820 user.stubs(:login).returns('some') 830 user.stubs(:login).returns('some')
821 @controller.stubs(:current_user).returns(user) 831 @controller.stubs(:current_user).returns(user)
  832 +
822 get :index, :profile => p1.identifier 833 get :index, :profile => p1.identifier
823 - assert_equal [], assigns(:network_activities) 834 + assert assigns(:network_activities).blank?
824 835
825 user = mock() 836 user = mock()
826 user.stubs(:person).returns(p3) 837 user.stubs(:person).returns(p3)
@@ -828,9 +839,9 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -828,9 +839,9 @@ class ProfileControllerTest &lt; ActionController::TestCase
828 @controller.stubs(:current_user).returns(user) 839 @controller.stubs(:current_user).returns(user)
829 Person.any_instance.stubs(:follows?).returns(true) 840 Person.any_instance.stubs(:follows?).returns(true)
830 process_delayed_job_queue 841 process_delayed_job_queue
  842 +
831 get :index, :profile => p3.identifier 843 get :index, :profile => p3.identifier
832 - assert_equal [], [a1,a3] - assigns(:network_activities)  
833 - assert_equal assigns(:network_activities) - [a1, a3], [] 844 + assert_equivalent [a1,a3], assigns(:network_activities)
834 end 845 end
835 846
836 should 'the network activity be paginated' do 847 should 'the network activity be paginated' do
@@ -1244,6 +1255,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -1244,6 +1255,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
1244 {:title => 'Plugin2 tab', :id => 'plugin2_tab', :content => lambda { 'Content from plugin2.' }} 1255 {:title => 'Plugin2 tab', :id => 'plugin2_tab', :content => lambda { 'Content from plugin2.' }}
1245 end 1256 end
1246 end 1257 end
  1258 + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s])
1247 1259
1248 e = profile.environment 1260 e = profile.environment
1249 e.enable_plugin(Plugin1.name) 1261 e.enable_plugin(Plugin1.name)
test/functional/profile_design_controller_test.rb
@@ -173,7 +173,8 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase @@ -173,7 +173,8 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase
173 should 'have options to display blocks' do 173 should 'have options to display blocks' do
174 get :edit, :profile => 'designtestuser', :id => @b1.id 174 get :edit, :profile => 'designtestuser', :id => @b1.id
175 %w[always home_page_only except_home_page never].each do |option| 175 %w[always home_page_only except_home_page never].each do |option|
176 - assert_tag :input, :attributes => { :type => 'radio', :value => option} 176 + assert_tag :select, :attributes => {:name => 'block[display]'},
  177 + :descendant => {:tag => 'option', :attributes => {:value => option}}
177 end 178 end
178 end 179 end
179 180
@@ -302,24 +303,42 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase @@ -302,24 +303,42 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase
302 303
303 should 'not edit main block with never option' do 304 should 'not edit main block with never option' do
304 get :edit, :profile => 'designtestuser', :id => @b4.id 305 get :edit, :profile => 'designtestuser', :id => @b4.id
305 - assert_no_tag :input, :attributes => { :type => 'radio', :value => 'never'} 306 + assert_no_tag :select, :attributes => {:name => 'block[display]'},
  307 + :descendant => {:tag => 'option', :attributes => {:value => 'never'}}
306 end 308 end
307 309
308 should 'not edit main block with home_page_only option' do 310 should 'not edit main block with home_page_only option' do
309 get :edit, :profile => 'designtestuser', :id => @b4.id 311 get :edit, :profile => 'designtestuser', :id => @b4.id
310 - assert_no_tag :input, :attributes => { :type => 'radio', :value => 'home_page_only'} 312 + assert_no_tag :select, :attributes => {:name => 'block[display]'},
  313 + :descendant => {:tag => 'option', :attributes => {:value => 'home_page_only'}}
311 end 314 end
312 315
313 should 'edit main block with always option' do 316 should 'edit main block with always option' do
314 get :edit, :profile => 'designtestuser', :id => @b4.id 317 get :edit, :profile => 'designtestuser', :id => @b4.id
315 - assert_tag :input, :attributes => { :type => 'radio', :value => 'always'} 318 + assert_tag :select, :attributes => {:name => 'block[display]'},
  319 + :descendant => {:tag => 'option', :attributes => {:value => 'always'}}
316 end 320 end
317 321
318 should 'edit main block with except_home_page option' do 322 should 'edit main block with except_home_page option' do
319 get :edit, :profile => 'designtestuser', :id => @b4.id 323 get :edit, :profile => 'designtestuser', :id => @b4.id
320 - assert_tag :input, :attributes => { :type => 'radio', :value => 'except_home_page'} 324 + assert_tag :select, :attributes => {:name=> 'block[display]'},
  325 + :descendant => {:tag => 'option', :attributes => {:value => 'except_home_page'}}
321 end 326 end
322 327
  328 + should 'return a list of paths related to the words used in the query search' do
  329 + article1 = fast_create(Article, :profile_id => @profile.id, :name => "Some thing")
  330 + article2 = fast_create(Article, :profile_id => @profile.id, :name => "Some article")
  331 + article3 = fast_create(Article, :profile_id => @profile.id, :name => "Not an article")
  332 +
  333 + xhr :get, :search_autocomplete, :profile => 'designtestuser' , :query => 'Some'
  334 +
  335 + json_response = ActiveSupport::JSON.decode(@response.body)
  336 +
  337 + assert_response :success
  338 + assert_equal json_response.include?("/{profile}/"+article1.path), true
  339 + assert_equal json_response.include?("/{profile}/"+article2.path), true
  340 + assert_equal json_response.include?("/{profile}/"+article3.path), false
  341 + end
323 342
324 ###################################################### 343 ######################################################
325 # END - tests for BoxOrganizerController features 344 # END - tests for BoxOrganizerController features
@@ -739,7 +758,7 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase @@ -739,7 +758,7 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase
739 should 'clone a block' do 758 should 'clone a block' do
740 block = ProfileImageBlock.create!(:box => profile.boxes.first) 759 block = ProfileImageBlock.create!(:box => profile.boxes.first)
741 assert_difference ProfileImageBlock, :count, 1 do 760 assert_difference ProfileImageBlock, :count, 1 do
742 - post :clone, :id => block.id, :profile => profile.identifier 761 + post :clone_block, :id => block.id, :profile => profile.identifier
743 assert_response :redirect 762 assert_response :redirect
744 end 763 end
745 end 764 end
test/functional/profile_editor_controller_test.rb
@@ -73,7 +73,8 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase @@ -73,7 +73,8 @@ class ProfileEditorControllerTest &lt; 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
@@ -236,7 +237,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase @@ -236,7 +237,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
236 cat2 = Environment.default.categories.create!(:display_in_menu => true, :name => 'sub category', :parent => cat1) 237 cat2 = Environment.default.categories.create!(:display_in_menu => true, :name => 'sub category', :parent => cat1)
237 person = create_user('testuser').person 238 person = create_user('testuser').person
238 get :edit, :profile => 'testuser' 239 get :edit, :profile => 'testuser'
239 - assert_tag :tag => 'input', :attributes => { :type => 'checkbox', :name => 'profile_data[category_ids][]', :value => cat2.id} 240 + assert_tag :tag => 'a', :attributes => { :class => 'select-subcategory-link', :id => "select-category-#{cat1.id}-link" }
240 end 241 end
241 242
242 should 'render edit template' do 243 should 'render edit template' do
@@ -867,6 +868,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase @@ -867,6 +868,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
867 {:title => "Plugin2 button", :icon => 'plugin2_icon', :url => 'plugin2_url'} 868 {:title => "Plugin2 button", :icon => 'plugin2_icon', :url => 'plugin2_url'}
868 end 869 end
869 end 870 end
  871 + Noosfero::Plugin.stubs(:all).returns([TestControlPanelButtons1.to_s, TestControlPanelButtons2.to_s])
870 872
871 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestControlPanelButtons1.new, TestControlPanelButtons2.new]) 873 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestControlPanelButtons1.new, TestControlPanelButtons2.new])
872 874
@@ -882,6 +884,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase @@ -882,6 +884,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
882 "<input id='field_added_by_plugin' value='value_of_field_added_by_plugin'/>" 884 "<input id='field_added_by_plugin' value='value_of_field_added_by_plugin'/>"
883 end 885 end
884 end 886 end
  887 + Noosfero::Plugin.stubs(:all).returns([TestProfileEditPlugin.to_s])
885 888
886 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestProfileEditPlugin.new]) 889 Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestProfileEditPlugin.new])
887 890
@@ -910,6 +913,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase @@ -910,6 +913,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
910 lambda {"<strong>Plugin2 text</strong>"} 913 lambda {"<strong>Plugin2 text</strong>"}
911 end 914 end
912 end 915 end
  916 + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s])
913 917
914 Environment.default.enable_plugin(Plugin1) 918 Environment.default.enable_plugin(Plugin1)
915 Environment.default.enable_plugin(Plugin2) 919 Environment.default.enable_plugin(Plugin2)
@@ -931,6 +935,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase @@ -931,6 +935,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
931 lambda {"<strong>Plugin2 text</strong>"} 935 lambda {"<strong>Plugin2 text</strong>"}
932 end 936 end
933 end 937 end
  938 + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s])
934 939
935 Environment.default.enable_plugin(Plugin1) 940 Environment.default.enable_plugin(Plugin1)
936 Environment.default.enable_plugin(Plugin2) 941 Environment.default.enable_plugin(Plugin2)
test/functional/search_controller_test.rb
@@ -163,6 +163,7 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -163,6 +163,7 @@ class SearchControllerTest &lt; ActionController::TestCase
163 lambda {"<span id='plugin2'>This is Plugin2 speaking!</span>"} 163 lambda {"<span id='plugin2'>This is Plugin2 speaking!</span>"}
164 end 164 end
165 end 165 end
  166 + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s])
166 167
167 enterprise = fast_create(Enterprise) 168 enterprise = fast_create(Enterprise)
168 prod_cat = fast_create(ProductCategory) 169 prod_cat = fast_create(ProductCategory)
@@ -189,6 +190,7 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -189,6 +190,7 @@ class SearchControllerTest &lt; ActionController::TestCase
189 return { :name => _('Property2'), :content => lambda { link_to(product.name, '/plugin2') } } 190 return { :name => _('Property2'), :content => lambda { link_to(product.name, '/plugin2') } }
190 end 191 end
191 end 192 end
  193 + Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s])
192 enterprise = fast_create(Enterprise) 194 enterprise = fast_create(Enterprise)
193 prod_cat = fast_create(ProductCategory) 195 prod_cat = fast_create(ProductCategory)
194 product = fast_create(Product, {:profile_id => enterprise.id, :name => "produto1", :product_category_id => prod_cat.id}, :search => true) 196 product = fast_create(Product, {:profile_id => enterprise.id, :name => "produto1", :product_category_id => prod_cat.id}, :search => true)
@@ -370,6 +372,14 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -370,6 +372,14 @@ class SearchControllerTest &lt; ActionController::TestCase
370 assert_equal [ 'upcoming event 1' ], assigns(:searches)[:events][:results].map(&:name) 372 assert_equal [ 'upcoming event 1' ], assigns(:searches)[:events][:results].map(&:name)
371 end 373 end
372 374
  375 + should 'see the events paginated' do
  376 + 30.times do |i|
  377 + create_event(person, :name => "Event #{i}", :start_date => Date.today)
  378 + end
  379 + get :events
  380 + assert_equal 20, assigns(:events).count
  381 + end
  382 +
373 %w[ people enterprises articles events communities products ].each do |asset| 383 %w[ people enterprises articles events communities products ].each do |asset|
374 should "render asset-specific template when searching for #{asset}" do 384 should "render asset-specific template when searching for #{asset}" do
375 get "#{asset}" 385 get "#{asset}"
@@ -549,9 +559,9 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -549,9 +559,9 @@ class SearchControllerTest &lt; ActionController::TestCase
549 c2 = create(Community, :name => 'Testing community 2') 559 c2 = create(Community, :name => 'Testing community 2')
550 c3 = create(Community, :name => 'Testing community 3') 560 c3 = create(Community, :name => 'Testing community 3')
551 ActionTracker::Record.delete_all 561 ActionTracker::Record.delete_all
552 - fast_create(ActionTracker::Record, :target_id => c1, :user_type => 'Profile', :user_id => person, :created_at => Time.now)  
553 - fast_create(ActionTracker::Record, :target_id => c2, :user_type => 'Profile', :user_id => person, :created_at => Time.now)  
554 - fast_create(ActionTracker::Record, :target_id => c2, :user_type => 'Profile', :user_id => person, :created_at => Time.now) 562 + ActionTracker::Record.create!(:target => c1, :user => person, :created_at => Time.now, :verb => 'leave_scrap')
  563 + ActionTracker::Record.create!(:target => c2, :user => person, :created_at => Time.now, :verb => 'leave_scrap')
  564 + ActionTracker::Record.create!(:target => c2, :user => person, :created_at => Time.now, :verb => 'leave_scrap')
555 get :communities, :filter => 'more_active' 565 get :communities, :filter => 'more_active'
556 assert_equal [c2,c1,c3] , assigns(:searches)[:communities][:results] 566 assert_equal [c2,c1,c3] , assigns(:searches)[:communities][:results]
557 end 567 end
test/functional/users_controller_test.rb
@@ -133,4 +133,20 @@ class UsersControllerTest &lt; ActionController::TestCase @@ -133,4 +133,20 @@ class UsersControllerTest &lt; 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/test_helper.rb
@@ -183,7 +183,7 @@ class ActiveSupport::TestCase @@ -183,7 +183,7 @@ class ActiveSupport::TestCase
183 if reference.first == value 183 if reference.first == value
184 reference.shift 184 reference.shift
185 else 185 else
186 - assert false, "'#{value}' was found before it should be on: #{original.inspect}" 186 + assert false, "'#{value.inspect}' was found before it should be on: #{original.inspect}"
187 end 187 end
188 end 188 end
189 end 189 end
test/unit/action_tracker_ext_test.rb 0 → 100644
@@ -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
test/unit/activities_counter_cache_job_test.rb 0 → 100644
@@ -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 &lt; ActiveSupport::TestCase @@ -80,4 +80,38 @@ class ActsAsHavingSettingsTest &lt; 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
@@ -466,6 +466,22 @@ class ApplicationHelperTest &lt; ActiveSupport::TestCase @@ -466,6 +466,22 @@ class ApplicationHelperTest &lt; ActiveSupport::TestCase
466 assert_match(/Community nick/, page_title) 466 assert_match(/Community nick/, page_title)
467 end 467 end
468 468
  469 + should 'not display environment name if is a profile' do
  470 + stubs(:environment).returns(Environment.default)
  471 + @controller = ApplicationController.new
  472 +
  473 + c = fast_create(Community, :name => 'Community for tests', :nickname => 'Community nick', :identifier => 'test_comm')
  474 + stubs(:profile).returns(c)
  475 + assert_equal c.short_name, page_title
  476 + end
  477 +
  478 + should 'display only environment if no profile and page' do
  479 + stubs(:environment).returns(Environment.default)
  480 + @controller = ApplicationController.new
  481 +
  482 + assert_equal Environment.default.name, page_title
  483 + end
  484 +
469 should 'gravatar default parameter' do 485 should 'gravatar default parameter' do
470 profile = mock 486 profile = mock
471 profile.stubs(:theme).returns('some-theme') 487 profile.stubs(:theme).returns('some-theme')
@@ -660,6 +676,7 @@ class ApplicationHelperTest &lt; ActiveSupport::TestCase @@ -660,6 +676,7 @@ class ApplicationHelperTest &lt; ActiveSupport::TestCase
660 should 'parse macros' do 676 should 'parse macros' do
661 class Plugin1 < Noosfero::Plugin 677 class Plugin1 < Noosfero::Plugin
662 end 678 end
  679 + Noosfero::Plugin.stubs(:all).returns(['ApplicationHelperTest::Plugin1'])
663 680
664 class Plugin1::Macro1 < Noosfero::Plugin::Macro 681 class Plugin1::Macro1 < Noosfero::Plugin::Macro
665 def parse(params, inner_html, source) 682 def parse(params, inner_html, source)
test/unit/article_test.rb
@@ -1630,10 +1630,10 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1630,10 +1630,10 @@ class ArticleTest &lt; ActiveSupport::TestCase
1630 1630
1631 should 'not allow all community members to edit by default' do 1631 should 'not allow all community members to edit by default' do
1632 community = fast_create(Community) 1632 community = fast_create(Community)
1633 - admin = create_user('community-admin').person  
1634 - member = create_user.person  
1635 - 1633 + admin = fast_create(Person)
  1634 + member = fast_create(Person)
1636 community.add_admin(admin) 1635 community.add_admin(admin)
  1636 + community.reload
1637 community.add_member(member) 1637 community.add_member(member)
1638 a = Article.new(:profile => community) 1638 a = Article.new(:profile => community)
1639 1639
test/unit/block_test.rb
@@ -232,4 +232,55 @@ class BlockTest &lt; ActiveSupport::TestCase @@ -232,4 +232,55 @@ class BlockTest &lt; ActiveSupport::TestCase
232 assert_equal "<iframe src='http://myblogtest.com/embed/block/1' frameborder='0' width='1024' height='768' class='embed block block'></iframe>", b.embed_code('http://myblogtest.com/embed/block/1') 232 assert_equal "<iframe src='http://myblogtest.com/embed/block/1' frameborder='0' width='1024' height='768' class='embed block block'></iframe>", b.embed_code('http://myblogtest.com/embed/block/1')
233 end 233 end
234 234
  235 + should 'default value for display_user is all' do
  236 + block = Block.new
  237 + assert_equal 'all', block.display_user
  238 + end
  239 +
  240 + should 'display block to not logged users for display_user = all' do
  241 + block = Block.new
  242 + assert block.display_to_user?(nil)
  243 + end
  244 +
  245 + should 'display block to logged users for display_user = all' do
  246 + block = Block.new
  247 + assert block.display_to_user?(User.new)
  248 + end
  249 +
  250 + should 'display block to logged users for display_user = logged' do
  251 + block = Block.new
  252 + block.display_user = 'logged'
  253 + assert block.display_to_user?(User.new)
  254 + end
  255 +
  256 + should 'do not display block to logged users for display_user = not_logged' do
  257 + block = Block.new
  258 + block.display_user = 'not_logged'
  259 + assert !block.display_to_user?(User.new)
  260 + end
  261 +
  262 + should 'do not display block to not logged users for display_user = logged' do
  263 + block = Block.new
  264 + block.display_user = 'logged'
  265 + assert !block.display_to_user?(nil)
  266 + end
  267 +
  268 + should 'display block to not logged users for display_user = not_logged' do
  269 + block = Block.new
  270 + block.display_user = 'not_logged'
  271 + assert block.display_to_user?(nil)
  272 + end
  273 +
  274 + should 'not be visible if display_to_user? is false' do
  275 + block = Block.new
  276 + block.expects(:display_to_user?).once.returns(false)
  277 + assert !block.visible?({})
  278 + end
  279 +
  280 + should 'accept user as parameter on cache_key without change its value' do
  281 + person = fast_create(Person)
  282 + block = Block.new
  283 + assert_equal block.cache_key('en'), block.cache_key('en', person)
  284 + end
  285 +
235 end 286 end
test/unit/box_test.rb
@@ -33,6 +33,8 @@ class BoxTest &lt; ActiveSupport::TestCase @@ -33,6 +33,8 @@ class BoxTest &lt; 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 &lt; ActiveSupport::TestCase @@ -65,6 +67,8 @@ class BoxTest &lt; 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
@@ -54,6 +54,7 @@ class BoxesHelperTest &lt; ActiveSupport::TestCase @@ -54,6 +54,7 @@ class BoxesHelperTest &lt; ActiveSupport::TestCase
54 expects(:display_block).with(b, '') 54 expects(:display_block).with(b, '')
55 stubs(:request).returns(request) 55 stubs(:request).returns(request)
56 stubs(:block_target).returns('') 56 stubs(:block_target).returns('')
  57 + stubs(:user).returns(nil)
57 expects(:locale).returns('en') 58 expects(:locale).returns('en')
58 with_box_decorator self do 59 with_box_decorator self do
59 display_box_content(box, '') 60 display_box_content(box, '')
@@ -73,6 +74,7 @@ class BoxesHelperTest &lt; ActiveSupport::TestCase @@ -73,6 +74,7 @@ class BoxesHelperTest &lt; ActiveSupport::TestCase
73 box.save! 74 box.save!
74 expects(:display_block).with(b, '').never 75 expects(:display_block).with(b, '').never
75 stubs(:request).returns(request) 76 stubs(:request).returns(request)
  77 + stubs(:user).returns(nil)
76 stubs(:block_target).returns('') 78 stubs(:block_target).returns('')
77 expects(:locale).returns('en') 79 expects(:locale).returns('en')
78 display_box_content(box, '') 80 display_box_content(box, '')
@@ -111,8 +113,9 @@ class BoxesHelperTest &lt; ActiveSupport::TestCase @@ -111,8 +113,9 @@ class BoxesHelperTest &lt; ActiveSupport::TestCase
111 request.expects(:path).returns('/') 113 request.expects(:path).returns('/')
112 request.expects(:params).returns({}) 114 request.expects(:params).returns({})
113 stubs(:request).returns(request) 115 stubs(:request).returns(request)
  116 + stubs(:user).returns(nil)
114 expects(:locale).returns('en') 117 expects(:locale).returns('en')
115 - box_decorator.expects(:select_blocks).with([], {:article => nil, :request_path => '/', :locale => 'en', :params => {}}).returns([]) 118 + box_decorator.expects(:select_blocks).with([], {:article => nil, :request_path => '/', :locale => 'en', :params => {}, :user => nil}).returns([])
116 119
117 display_box_content(box, '') 120 display_box_content(box, '')
118 end 121 end
test/unit/comment_test.rb
@@ -468,8 +468,8 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -468,8 +468,8 @@ class CommentTest &lt; ActiveSupport::TestCase
468 end 468 end
469 end 469 end
470 470
471 -  
472 should 'delegate spam detection to plugins' do 471 should 'delegate spam detection to plugins' do
  472 + Noosfero::Plugin.stubs(:all).returns(['CommentTest::EverythingIsSpam'])
473 Environment.default.enable_plugin(EverythingIsSpam) 473 Environment.default.enable_plugin(EverythingIsSpam)
474 474
475 c1 = create_comment 475 c1 = create_comment
@@ -495,6 +495,7 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -495,6 +495,7 @@ class CommentTest &lt; ActiveSupport::TestCase
495 end 495 end
496 496
497 should 'notify plugins of comments being marked as spam' do 497 should 'notify plugins of comments being marked as spam' do
  498 + Noosfero::Plugin.stubs(:all).returns(['CommentTest::SpamNotification'])
498 Environment.default.enable_plugin(SpamNotification) 499 Environment.default.enable_plugin(SpamNotification)
499 500
500 c = create_comment 501 c = create_comment
@@ -506,6 +507,7 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -506,6 +507,7 @@ class CommentTest &lt; ActiveSupport::TestCase
506 end 507 end
507 508
508 should 'notify plugins of comments being marked as ham' do 509 should 'notify plugins of comments being marked as ham' do
  510 + Noosfero::Plugin.stubs(:all).returns(['CommentTest::SpamNotification'])
509 Environment.default.enable_plugin(SpamNotification) 511 Environment.default.enable_plugin(SpamNotification)
510 512
511 c = create_comment 513 c = create_comment
test/unit/community_test.rb
@@ -213,8 +213,8 @@ class CommunityTest &lt; ActiveSupport::TestCase @@ -213,8 +213,8 @@ class CommunityTest &lt; ActiveSupport::TestCase
213 community = fast_create(Community) 213 community = fast_create(Community)
214 community.closed = true 214 community.closed = true
215 community.save 215 community.save
216 -  
217 community.add_member(fast_create(Person)) 216 community.add_member(fast_create(Person))
  217 + community.reload
218 218
219 assert_difference AddMember, :count do 219 assert_difference AddMember, :count do
220 community.add_member(person) 220 community.add_member(person)
test/unit/contact_sender_test.rb
@@ -16,7 +16,7 @@ class ContactSenderTest &lt; ActiveSupport::TestCase @@ -16,7 +16,7 @@ class ContactSenderTest &lt; 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.deliver_mail(c) 18 response = Contact::Sender.deliver_mail(c)
19 - assert_equal Environment.default.contact_email, response.from.to_s 19 + assert_equal Environment.default.noreply_email.to_s, response.from.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 &lt; ActiveSupport::TestCase @@ -27,7 +27,7 @@ class ContactSenderTest &lt; ActiveSupport::TestCase
27 response = Contact::Sender.deliver_mail(c) 27 response = Contact::Sender.deliver_mail(c)
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 = Enterprise.create!(:name => 'my enterprise', :identifier => 'myent', :environment => Environment.default) 33 ent = Enterprise.create!(:name => 'my enterprise', :identifier => 'myent', :environment => Environment.default)
test/unit/contact_test.rb
@@ -44,11 +44,14 @@ class ContactTest &lt; ActiveSupport::TestCase @@ -44,11 +44,14 @@ class ContactTest &lt; 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 &lt; ActiveSupport::TestCase @@ -89,38 +89,6 @@ class ContentViewerHelperTest &lt; ActiveSupport::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 = model.new(:name => 'Some title', :body => 'Some text here.', :profile => profile)  
96 - assert_equal "http://www.facebook.com/sharer.php?s=100&p[title]=Some+title&p[summary]=Some+text+here.&p[url]=http%3A%2F%2Fnoosfero.org%2Fblog_helper_test%2Fsome-title&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 = TinyMceArticle.new(:name => 'Test', :body => nil, :profile => profile)  
103 - assert_equal "http://www.facebook.com/sharer.php?s=100&p[title]=Test&p[summary]=&p[url]=http%3A%2F%2Fnoosfero.org%2Fblog_helper_test%2Ftest&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 = TinyMceArticle.new(:name => 'Some title', :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]=Some+title&p[summary]=This+is+a+test&p[url]=http%3A%2F%2Fnoosfero.org%2Fblog_helper_test%2Fsome-title&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 = TinyMceArticle.new(:name => 'Some title', :body => 'test' * 76, :profile => profile)  
115 - assert_equal "http://www.facebook.com/sharer.php?s=100&p[title]=Some+title&p[summary]=#{'test' * 74}t...&p[url]=http%3A%2F%2Fnoosfero.org%2Fblog_helper_test%2Fsome-title&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 = TinyMceArticle.new(:name => 'Some title', :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]=Some+title&p[summary]=This+is+a+test&p[url]=http%3A%2F%2Fnoosfero.org%2Fblog_helper_test%2Fsome-title&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
@@ -99,6 +99,7 @@ class EnterpriseTest &lt; ActiveSupport::TestCase @@ -99,6 +99,7 @@ class EnterpriseTest &lt; ActiveSupport::TestCase
99 enterprise = fast_create(Enterprise) 99 enterprise = fast_create(Enterprise)
100 member = fast_create(Person) 100 member = fast_create(Person)
101 enterprise.add_member(member) 101 enterprise.add_member(member)
  102 + enterprise.reload
102 103
103 person = fast_create(Person) 104 person = fast_create(Person)
104 enterprise.add_member(person) 105 enterprise.add_member(person)
test/unit/environment_mailing_test.rb
@@ -46,7 +46,7 @@ class EnvironmentMailingTest &lt; ActiveSupport::TestCase @@ -46,7 +46,7 @@ class EnvironmentMailingTest &lt; ActiveSupport::TestCase
46 46
47 should 'display name and email on generate_from' do 47 should 'display name and email on generate_from' do
48 mailing = EnvironmentMailing.new(:source => environment, :person => person_1) 48 mailing = EnvironmentMailing.new(:source => environment, :person => person_1)
49 - assert_equal "#{environment.name} <#{environment.contact_email}>", mailing.generate_from 49 + assert_equal "#{environment.name} <#{environment.noreply_email}>", mailing.generate_from
50 end 50 end
51 51
52 should 'deliver mailing to each recipient after create' do 52 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 &lt; ActiveSupport::TestCase @@ -36,7 +39,7 @@ class EnvironmentStatisticsBlockTest &lt; 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
@@ -1220,6 +1220,27 @@ class EnvironmentTest &lt; ActiveSupport::TestCase @@ -1220,6 +1220,27 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
1220 end 1220 end
1221 end 1221 end
1222 1222
  1223 + should 'return a Hash on signup redirection options' do
  1224 + assert_kind_of Hash, Environment.signup_redirection_options
  1225 + end
  1226 +
  1227 + should 'respond to redirection after signup' do
  1228 + assert_respond_to Environment.new, :redirection_after_signup
  1229 + end
  1230 +
  1231 + should 'allow only environment signup redirection options' do
  1232 + environment = fast_create(Environment)
  1233 + environment.redirection_after_signup = 'invalid_option'
  1234 + environment.save
  1235 + assert environment.errors.invalid?(:redirection_after_signup)
  1236 +
  1237 + Environment.signup_redirection_options.keys.each do |redirection|
  1238 + environment.redirection_after_signup = redirection
  1239 + environment.save
  1240 + assert !environment.errors.invalid?(:redirection_after_signup)
  1241 + end
  1242 + end
  1243 +
1223 should 'respond to signup_welcome_text' do 1244 should 'respond to signup_welcome_text' do
1224 assert_respond_to Environment.new, :signup_welcome_text 1245 assert_respond_to Environment.new, :signup_welcome_text
1225 end 1246 end
test/unit/file_presenter_test.rb
@@ -58,4 +58,20 @@ class FilePresenterTest &lt; ActiveSupport::TestCase @@ -58,4 +58,20 @@ class FilePresenterTest &lt; 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 &lt; ActionView::TestCase @@ -22,6 +22,7 @@ class ForgotPasswordHelperTest &lt; ActionView::TestCase
22 {:field => 'f3', :name => 'F3', :model => 'person'}] 22 {:field => 'f3', :name => 'F3', :model => 'person'}]
23 end 23 end
24 end 24 end
  25 + Noosfero::Plugin.stubs(:all).returns(['ForgotPasswordHelperTest::Plugin1', 'ForgotPasswordHelperTest::Plugin2'])
25 26
26 environment.enable_plugin(Plugin1) 27 environment.enable_plugin(Plugin1)
27 environment.enable_plugin(Plugin2) 28 environment.enable_plugin(Plugin2)
@@ -43,6 +44,7 @@ class ForgotPasswordHelperTest &lt; ActionView::TestCase @@ -43,6 +44,7 @@ class ForgotPasswordHelperTest &lt; ActionView::TestCase
43 {:field => 'f3', :name => 'F3', :model => 'person'}] 44 {:field => 'f3', :name => 'F3', :model => 'person'}]
44 end 45 end
45 end 46 end
  47 + Noosfero::Plugin.stubs(:all).returns(['ForgotPasswordHelperTest::Plugin1', 'ForgotPasswordHelperTest::Plugin2'])
46 48
47 environment.enable_plugin(Plugin1) 49 environment.enable_plugin(Plugin1)
48 environment.enable_plugin(Plugin2) 50 environment.enable_plugin(Plugin2)
@@ -64,6 +66,7 @@ class ForgotPasswordHelperTest &lt; ActionView::TestCase @@ -64,6 +66,7 @@ class ForgotPasswordHelperTest &lt; ActionView::TestCase
64 {:field => 'f3', :name => 'F3', :model => 'user'}] 66 {:field => 'f3', :name => 'F3', :model => 'user'}]
65 end 67 end
66 end 68 end
  69 + Noosfero::Plugin.stubs(:all).returns(['ForgotPasswordHelperTest::Plugin1', 'ForgotPasswordHelperTest::Plugin2'])
67 70
68 environment.enable_plugin(Plugin1) 71 environment.enable_plugin(Plugin1)
69 environment.enable_plugin(Plugin2) 72 environment.enable_plugin(Plugin2)
@@ -85,6 +88,7 @@ class ForgotPasswordHelperTest &lt; ActionView::TestCase @@ -85,6 +88,7 @@ class ForgotPasswordHelperTest &lt; ActionView::TestCase
85 {:field => 'f3', :name => 'F3', :model => 'user'}] 88 {:field => 'f3', :name => 'F3', :model => 'user'}]
86 end 89 end
87 end 90 end
  91 + Noosfero::Plugin.stubs(:all).returns(['ForgotPasswordHelperTest::Plugin1', 'ForgotPasswordHelperTest::Plugin2'])
88 92
89 environment.enable_plugin(Plugin1) 93 environment.enable_plugin(Plugin1)
90 environment.enable_plugin(Plugin2) 94 environment.enable_plugin(Plugin2)
test/unit/link_list_block_test.rb
@@ -39,6 +39,32 @@ class LinkListBlockTest &lt; ActiveSupport::TestCase @@ -39,6 +39,32 @@ class LinkListBlockTest &lt; ActiveSupport::TestCase
39 assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/test_profile/address'} 39 assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/test_profile/address'}
40 end 40 end
41 41
  42 + should 'replace {portal} with environment portal identifier' do
  43 + env = Environment.default
  44 + env.enable('use_portal_community')
  45 + portal = fast_create(Community, :identifier => 'portal-community', :environment_id => env.id)
  46 + env.portal_community = portal
  47 + env.save
  48 +
  49 + stubs(:environment).returns(env)
  50 + l = LinkListBlock.new(:links => [{:name => 'categ', :address => '/{portal}/address'}])
  51 + l.stubs(:owner).returns(env)
  52 + assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/portal-community/address'}
  53 + end
  54 +
  55 + should 'not change address if no {portal} there' do
  56 + env = Environment.default
  57 + env.enable('use_portal_community')
  58 + portal = fast_create(Community, :identifier => 'portal-community', :environment_id => env.id)
  59 + env.portal_community = portal
  60 + env.save
  61 +
  62 + stubs(:environment).returns(env)
  63 + l = LinkListBlock.new(:links => [{:name => 'categ', :address => '/address'}])
  64 + l.stubs(:owner).returns(env)
  65 + assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/address'}
  66 + end
  67 +
42 should 'display options for icons' do 68 should 'display options for icons' do
43 l = LinkListBlock.new 69 l = LinkListBlock.new
44 l.icons_options.each do |option| 70 l.icons_options.each do |option|
test/unit/macros_helper_test.rb
@@ -28,6 +28,7 @@ class MacrosHelperTest &lt; ActiveSupport::TestCase @@ -28,6 +28,7 @@ class MacrosHelperTest &lt; ActiveSupport::TestCase
28 end 28 end
29 29
30 def setup 30 def setup
  31 + Noosfero::Plugin.stubs(:all).returns(['MacrosHelperTest::Plugin1'])
31 @environment = Environment.default 32 @environment = Environment.default
32 @environment.enable_plugin(Plugin1) 33 @environment.enable_plugin(Plugin1)
33 @plugins = Noosfero::Plugin::Manager.new(@environment, self) 34 @plugins = Noosfero::Plugin::Manager.new(@environment, self)
@@ -129,4 +130,27 @@ class MacrosHelperTest &lt; ActiveSupport::TestCase @@ -129,4 +130,27 @@ class MacrosHelperTest &lt; ActiveSupport::TestCase
129 assert_equal 'macro_generator', macro_generator(Plugin1::Macro) 130 assert_equal 'macro_generator', macro_generator(Plugin1::Macro)
130 end 131 end
131 132
  133 + should 'get macro default generator' do
  134 + class Plugin1::Macro < Noosfero::Plugin::Macro
  135 + def self.configuration
  136 + { :params => [] }
  137 + end
  138 + end
  139 + assert_nothing_raised NoMethodError do
  140 + assert macro_generator(Plugin1::Macro)
  141 + end
  142 + end
  143 +
  144 + should 'can use a code reference as macro generator' do
  145 + class Plugin1::Macro < Noosfero::Plugin::Macro
  146 + def self.configuration
  147 + { :params => [], :generator => method(:macro_generator_method) }
  148 + end
  149 + def self.macro_generator_method(macro)
  150 + "macro generator method return"
  151 + end
  152 + end
  153 + assert_equal "macro generator method return", macro_generator(Plugin1::Macro)
  154 + end
  155 +
132 end 156 end
test/unit/mailing_test.rb
@@ -74,7 +74,7 @@ class MailingTest &lt; ActiveSupport::TestCase @@ -74,7 +74,7 @@ class MailingTest &lt; 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 = Mailing.new(:source => environment, :person => person) 76 mailing = Mailing.new(: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 &lt; ActiveSupport::TestCase @@ -35,4 +35,28 @@ class MembersBlockTest &lt; 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 &lt; ActiveSupport::TestCase @@ -42,7 +42,7 @@ class OrganizationMailingTest &lt; 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 = OrganizationMailing.new(:source => community, :person => person) 44 mailing = OrganizationMailing.new(: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
@@ -62,18 +62,21 @@ class OrganizationMailingTest &lt; ActiveSupport::TestCase @@ -62,18 +62,21 @@ class OrganizationMailingTest &lt; ActiveSupport::TestCase
62 62
63 should 'deliver mailing to each member after create' do 63 should 'deliver mailing to each member after create' do
64 mailing = OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person) 64 mailing = OrganizationMailing.create(: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 2, 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 { OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person) } 71 50.times { OrganizationMailing.create(: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_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 = OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person) 78 mailing = OrganizationMailing.create(: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 &lt; ActiveSupport::TestCase @@ -302,18 +302,17 @@ class OrganizationTest &lt; 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 &lt; ActiveSupport::TestCase @@ -331,6 +330,7 @@ class OrganizationTest &lt; 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 &lt; ActiveSupport::TestCase @@ -342,47 +342,30 @@ class OrganizationTest &lt; 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 &lt; ActiveSupport::TestCase @@ -422,4 +405,24 @@ class OrganizationTest &lt; 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
test/unit/person_notifier_helper_test.rb 0 → 100644
@@ -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
test/unit/person_notifier_test.rb 0 → 100644
@@ -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
@@ -404,15 +404,14 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -404,15 +404,14 @@ class PersonTest &lt; ActiveSupport::TestCase
404 404
405 should 'not allow simple member to view group pending tasks' do 405 should 'not allow simple member to view group pending tasks' do
406 community = fast_create(Community) 406 community = fast_create(Community)
  407 + admin = fast_create(Person)
  408 + community.add_member(admin)
407 member = fast_create(Person) 409 member = fast_create(Person)
  410 + community.reload
408 community.add_member(member) 411 community.add_member(member)
409 -  
410 community.tasks << Task.new 412 community.tasks << Task.new
411 413
412 - person = fast_create(Person)  
413 - community.add_member(person)  
414 -  
415 - assert_not_includes Person.with_pending_tasks, person 414 + assert_not_includes Person.with_pending_tasks, member
416 end 415 end
417 416
418 should 'person has organization pending tasks' do 417 should 'person has organization pending tasks' do
@@ -642,16 +641,18 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -642,16 +641,18 @@ class PersonTest &lt; ActiveSupport::TestCase
642 end 641 end
643 642
644 should 'find more popular people' do 643 should 'find more popular people' do
  644 + extend CacheCounterHelper
  645 +
645 Person.delete_all 646 Person.delete_all
646 p1 = fast_create(Person) 647 p1 = fast_create(Person)
647 p2 = fast_create(Person) 648 p2 = fast_create(Person)
648 p3 = fast_create(Person) 649 p3 = fast_create(Person)
649 650
650 - p1.add_friend(p2)  
651 - p2.add_friend(p1)  
652 - p2.add_friend(p3)  
653 - assert_equal p2, Person.more_popular[0]  
654 - assert_equal p1, Person.more_popular[1] 651 + update_cache_counter(:friends_count, p1, 1)
  652 + update_cache_counter(:friends_count, p2, 2)
  653 + update_cache_counter(:friends_count, p3, 3)
  654 +
  655 + assert_order [p3, p2, p1], Person.more_popular
655 end 656 end
656 657
657 should 'list people that have no friends in more popular list' do 658 should 'list people that have no friends in more popular list' do
@@ -891,6 +892,7 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -891,6 +892,7 @@ class PersonTest &lt; ActiveSupport::TestCase
891 p1 = fast_create(Person) 892 p1 = fast_create(Person)
892 p2 = fast_create(Person) 893 p2 = fast_create(Person)
893 p3 = fast_create(Person) 894 p3 = fast_create(Person)
  895 + p4 = fast_create(Person)
894 896
895 community.add_member(p1) 897 community.add_member(p1)
896 assert p1.is_member_of?(community) 898 assert p1.is_member_of?(community)
@@ -901,14 +903,15 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -901,14 +903,15 @@ class PersonTest &lt; ActiveSupport::TestCase
901 903
902 action_tracker = fast_create(ActionTracker::Record, :verb => 'create_article') 904 action_tracker = fast_create(ActionTracker::Record, :verb => 'create_article')
903 action_tracker.target = community 905 action_tracker.target = community
  906 + action_tracker.user = p4
904 action_tracker.save! 907 action_tracker.save!
905 ActionTrackerNotification.delete_all 908 ActionTrackerNotification.delete_all
906 - assert_difference(ActionTrackerNotification, :count, 3) do 909 + assert_difference(ActionTrackerNotification, :count, 4) do
907 Person.notify_activity(action_tracker) 910 Person.notify_activity(action_tracker)
908 process_delayed_job_queue 911 process_delayed_job_queue
909 end 912 end
910 ActionTrackerNotification.all.map{|a|a.profile}.map do |profile| 913 ActionTrackerNotification.all.map{|a|a.profile}.map do |profile|
911 - assert [community,p1,p3].include?(profile) 914 + assert [community,p1,p3,p4].include?(profile)
912 end 915 end
913 end 916 end
914 917
@@ -1011,9 +1014,9 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1011,9 +1014,9 @@ class PersonTest &lt; ActiveSupport::TestCase
1011 1014
1012 should 'the community specific notification created when a member joins community could not be propagated to members' do 1015 should 'the community specific notification created when a member joins community could not be propagated to members' do
1013 ActionTracker::Record.delete_all 1016 ActionTracker::Record.delete_all
1014 - p1 = create_user('test_user').person  
1015 - p2 = create_user('test_user').person  
1016 - p3 = create_user('test_user').person 1017 + p1 = create_user('p1').person
  1018 + p2 = create_user('p2').person
  1019 + p3 = create_user('p3').person
1017 c = fast_create(Community, :name => "Foo") 1020 c = fast_create(Community, :name => "Foo")
1018 c.add_member(p1) 1021 c.add_member(p1)
1019 process_delayed_job_queue 1022 process_delayed_job_queue
@@ -1133,30 +1136,14 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1133,30 +1136,14 @@ class PersonTest &lt; ActiveSupport::TestCase
1133 p3 = fast_create(Person) 1136 p3 = fast_create(Person)
1134 1137
1135 ActionTracker::Record.destroy_all 1138 ActionTracker::Record.destroy_all
1136 - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p1, :created_at => Time.now)  
1137 - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p2, :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 => p3, :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) 1139 + ActionTracker::Record.create!(:user => p1, :verb => 'leave_scrap')
  1140 + ActionTracker::Record.create!(:user => p2, :verb => 'leave_scrap')
  1141 + ActionTracker::Record.create!(:user => p2, :verb => 'leave_scrap')
  1142 + ActionTracker::Record.create!(:user => p3, :verb => 'leave_scrap')
  1143 + ActionTracker::Record.create!(:user => p3, :verb => 'leave_scrap')
  1144 + ActionTracker::Record.create!(:user => p3, :verb => 'leave_scrap')
1142 1145
1143 - assert_equal [p3,p2,p1] , Person.more_active  
1144 - end  
1145 -  
1146 - should 'more active profile take in consideration only actions created only in the recent delay interval' do  
1147 - Person.delete_all  
1148 - ActionTracker::Record.destroy_all  
1149 - recent_delay = ActionTracker::Record::RECENT_DELAY.days.ago  
1150 -  
1151 - p1 = fast_create(Person)  
1152 - p2 = fast_create(Person)  
1153 -  
1154 - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p1, :created_at => recent_delay)  
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 => p2, :created_at => recent_delay)  
1157 - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p2, :created_at => recent_delay - 1.day)  
1158 -  
1159 - assert_equal [p1,p2], Person.more_active 1146 + assert_order [p3,p2,p1] , Person.more_active
1160 end 1147 end
1161 1148
1162 should 'list profiles that have no actions in more active list' do 1149 should 'list profiles that have no actions in more active list' do
@@ -1268,6 +1255,7 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1268,6 +1255,7 @@ class PersonTest &lt; ActiveSupport::TestCase
1268 false 1255 false
1269 end 1256 end
1270 end 1257 end
  1258 + Noosfero::Plugin.stubs(:all).returns(['PersonTest::Plugin1', 'PersonTest::Plugin2'])
1271 1259
1272 e = Environment.default 1260 e = Environment.default
1273 e.enable_plugin(Plugin1.name) 1261 e.enable_plugin(Plugin1.name)
@@ -1363,7 +1351,7 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1363,7 +1351,7 @@ class PersonTest &lt; ActiveSupport::TestCase
1363 u = create_user('user'+i.to_s) 1351 u = create_user('user'+i.to_s)
1364 u.deactivate 1352 u.deactivate
1365 } 1353 }
1366 - assert_equal activated, Person.activated 1354 + assert_equivalent activated, Person.activated
1367 end 1355 end
1368 1356
1369 should 'deactivated named_scope return persons who are deactivated users' do 1357 should 'deactivated named_scope return persons who are deactivated users' do
@@ -1379,7 +1367,7 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1379,7 +1367,7 @@ class PersonTest &lt; ActiveSupport::TestCase
1379 u = create_user('user'+i.to_s) 1367 u = create_user('user'+i.to_s)
1380 u.activate 1368 u.activate
1381 } 1369 }
1382 - assert_equal deactivated, Person.deactivated 1370 + assert_equivalent deactivated, Person.deactivated
1383 end 1371 end
1384 1372
1385 should 'be able to retrieve memberships by role person has' do 1373 should 'be able to retrieve memberships by role person has' do
@@ -1414,6 +1402,17 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1414,6 +1402,17 @@ class PersonTest &lt; ActiveSupport::TestCase
1414 assert_equal person.activities, [] 1402 assert_equal person.activities, []
1415 end 1403 end
1416 1404
  1405 + should 'person notifier be PersonNotifier class' do
  1406 + p = Person.new
  1407 + assert p.notifier.kind_of?(PersonNotifier)
  1408 + end
  1409 +
  1410 + should 'reschedule next notification after update' do
  1411 + p = fast_create(Person, :user_id => fast_create(User).id)
  1412 + PersonNotifier.any_instance.expects(:reschedule_next_notification_mail).once
  1413 + assert p.update_attribute(:name, 'Person name changed')
  1414 + end
  1415 +
1417 should 'merge memberships of plugins to original memberships' do 1416 should 'merge memberships of plugins to original memberships' do
1418 class Plugin1 < Noosfero::Plugin 1417 class Plugin1 < Noosfero::Plugin
1419 def person_memberships(person) 1418 def person_memberships(person)
@@ -1426,6 +1425,7 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1426,6 +1425,7 @@ class PersonTest &lt; ActiveSupport::TestCase
1426 Profile.memberships_of(Person.find_by_identifier('person2')) 1425 Profile.memberships_of(Person.find_by_identifier('person2'))
1427 end 1426 end
1428 end 1427 end
  1428 + Noosfero::Plugin.stubs(:all).returns(['PersonTest::Plugin1', 'PersonTest::Plugin2'])
1429 1429
1430 Environment.default.enable_plugin(Plugin1) 1430 Environment.default.enable_plugin(Plugin1)
1431 Environment.default.enable_plugin(Plugin2) 1431 Environment.default.enable_plugin(Plugin2)
@@ -1446,4 +1446,30 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1446,4 +1446,30 @@ class PersonTest &lt; ActiveSupport::TestCase
1446 assert 3, original_person.memberships.count 1446 assert 3, original_person.memberships.count
1447 end 1447 end
1448 1448
  1449 + should 'increase friends_count on new friendship' do
  1450 + person = create_user('person').person
  1451 + friend = create_user('friend').person
  1452 + assert_difference person, :friends_count, 1 do
  1453 + assert_difference friend, :friends_count, 1 do
  1454 + person.add_friend(friend)
  1455 + friend.reload
  1456 + end
  1457 + person.reload
  1458 + end
  1459 + end
  1460 +
  1461 + should 'decrease friends_count on friendship removal' do
  1462 + person = create_user('person').person
  1463 + friend = create_user('friend').person
  1464 + person.add_friend(friend)
  1465 + friend.reload
  1466 + person.reload
  1467 + assert_difference person, :friends_count, -1 do
  1468 + assert_difference friend, :friends_count, -1 do
  1469 + person.remove_friend(friend)
  1470 + friend.reload
  1471 + end
  1472 + person.reload
  1473 + end
  1474 + end
1449 end 1475 end
test/unit/plugin_manager_test.rb
@@ -26,6 +26,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -26,6 +26,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
26 class Plugin2 < Noosfero::Plugin; end; 26 class Plugin2 < Noosfero::Plugin; end;
27 class Plugin3 < Noosfero::Plugin; end; 27 class Plugin3 < Noosfero::Plugin; end;
28 class Plugin4 < Noosfero::Plugin; end; 28 class Plugin4 < Noosfero::Plugin; end;
  29 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3', 'PluginManagerTest::Plugin4'])
29 environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s, Plugin4.to_s]) 30 environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s, Plugin4.to_s])
30 Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin3.to_s, Plugin4.to_s]) 31 Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin3.to_s, Plugin4.to_s])
31 results = plugins.enabled_plugins.map { |instance| instance.class.to_s } 32 results = plugins.enabled_plugins.map { |instance| instance.class.to_s }
@@ -51,6 +52,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -51,6 +52,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
51 'Plugin 2 action.' 52 'Plugin 2 action.'
52 end 53 end
53 end 54 end
  55 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2'])
54 56
55 environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s]) 57 environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s])
56 58
@@ -83,6 +85,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -83,6 +85,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
83 'Plugin 3 action.' 85 'Plugin 3 action.'
84 end 86 end
85 end 87 end
  88 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3'])
86 89
87 environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s, Plugin3.to_s]) 90 environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s, Plugin3.to_s])
88 p1 = Plugin1.new 91 p1 = Plugin1.new
@@ -107,6 +110,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -107,6 +110,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
107 'Plugin3' 110 'Plugin3'
108 end 111 end
109 end 112 end
  113 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3'])
110 114
111 environment.enable_plugin(Plugin1.name) 115 environment.enable_plugin(Plugin1.name)
112 environment.enable_plugin(Plugin2.name) 116 environment.enable_plugin(Plugin2.name)
@@ -134,6 +138,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -134,6 +138,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
134 true 138 true
135 end 139 end
136 end 140 end
  141 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3'])
137 142
138 environment.enable_plugin(Plugin1.name) 143 environment.enable_plugin(Plugin1.name)
139 environment.enable_plugin(Plugin2.name) 144 environment.enable_plugin(Plugin2.name)
@@ -162,6 +167,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -162,6 +167,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
162 true 167 true
163 end 168 end
164 end 169 end
  170 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3'])
165 171
166 environment.enable_plugin(Plugin1.name) 172 environment.enable_plugin(Plugin1.name)
167 environment.enable_plugin(Plugin2.name) 173 environment.enable_plugin(Plugin2.name)
@@ -178,6 +184,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -178,6 +184,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
178 [Macro1, Macro2] 184 [Macro1, Macro2]
179 end 185 end
180 end 186 end
  187 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1'])
181 188
182 class Plugin1::Macro1 < Noosfero::Plugin::Macro 189 class Plugin1::Macro1 < Noosfero::Plugin::Macro
183 def convert(macro, source) 190 def convert(macro, source)
@@ -212,6 +219,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -212,6 +219,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
212 [v1 * v, v2 * v] 219 [v1 * v, v2 * v]
213 end 220 end
214 end 221 end
  222 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2'])
215 223
216 environment.enable_plugin(Plugin1) 224 environment.enable_plugin(Plugin1)
217 environment.enable_plugin(Plugin2) 225 environment.enable_plugin(Plugin2)
@@ -231,6 +239,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -231,6 +239,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
231 value * 5 239 value * 5
232 end 240 end
233 end 241 end
  242 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2'])
234 243
235 environment.enable_plugin(Plugin1) 244 environment.enable_plugin(Plugin1)
236 environment.enable_plugin(Plugin2) 245 environment.enable_plugin(Plugin2)
@@ -252,6 +261,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -252,6 +261,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
252 [v1 * v, v2 * v, 666] 261 [v1 * v, v2 * v, 666]
253 end 262 end
254 end 263 end
  264 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2'])
255 265
256 environment.enable_plugin(Plugin1) 266 environment.enable_plugin(Plugin1)
257 environment.enable_plugin(Plugin2) 267 environment.enable_plugin(Plugin2)
@@ -273,6 +283,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -273,6 +283,7 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
273 numbers.reject {|n| n<=5} 283 numbers.reject {|n| n<=5}
274 end 284 end
275 end 285 end
  286 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2'])
276 287
277 environment.enable_plugin(Plugin1) 288 environment.enable_plugin(Plugin1)
278 environment.enable_plugin(Plugin2) 289 environment.enable_plugin(Plugin2)
test/unit/plugin_test.rb
@@ -9,15 +9,9 @@ class PluginTest &lt; ActiveSupport::TestCase @@ -9,15 +9,9 @@ class PluginTest &lt; ActiveSupport::TestCase
9 9
10 include Noosfero::Plugin::HotSpot 10 include Noosfero::Plugin::HotSpot
11 11
12 - should 'keep the list of all loaded subclasses' do  
13 - class Plugin1 < Noosfero::Plugin  
14 - end  
15 -  
16 - class Plugin2 < Noosfero::Plugin  
17 - end  
18 -  
19 - assert_includes Noosfero::Plugin.all, Plugin1.to_s  
20 - assert_includes Noosfero::Plugin.all, Plugin2.to_s 12 + should 'keep the list of all available plugins' do
  13 + assert File.directory?(File.join(Rails.root, 'plugins', 'foo'))
  14 + assert_includes Noosfero::Plugin.all, 'FooPlugin'
21 end 15 end
22 16
23 should 'returns url to plugin management if plugin has admin_controller' do 17 should 'returns url to plugin management if plugin has admin_controller' do
@@ -496,4 +490,29 @@ class PluginTest &lt; ActiveSupport::TestCase @@ -496,4 +490,29 @@ class PluginTest &lt; 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
@@ -1688,6 +1688,7 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -1688,6 +1688,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1688 person = fast_create(Person) 1688 person = fast_create(Person)
1689 community = fast_create(Community) 1689 community = fast_create(Community)
1690 community.add_member(person) 1690 community.add_member(person)
  1691 + community.reload
1691 1692
1692 assert_equal 1, community.members_count 1693 assert_equal 1, community.members_count
1693 end 1694 end
@@ -1811,6 +1812,7 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -1811,6 +1812,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1811 Person.members_of(Community.find_by_identifier('community2')) 1812 Person.members_of(Community.find_by_identifier('community2'))
1812 end 1813 end
1813 end 1814 end
  1815 + Noosfero::Plugin.stubs(:all).returns(['ProfileTest::Plugin1', 'ProfileTest::Plugin2'])
1814 Environment.default.enable_plugin(Plugin1) 1816 Environment.default.enable_plugin(Plugin1)
1815 Environment.default.enable_plugin(Plugin2) 1817 Environment.default.enable_plugin(Plugin2)
1816 1818
@@ -1823,11 +1825,12 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -1823,11 +1825,12 @@ class ProfileTest &lt; ActiveSupport::TestCase
1823 original_community.add_member(original_member) 1825 original_community.add_member(original_member)
1824 community1.add_member(plugin1_member) 1826 community1.add_member(plugin1_member)
1825 community2.add_member(plugin2_member) 1827 community2.add_member(plugin2_member)
  1828 + original_community.reload
1826 1829
1827 assert_includes original_community.members, original_member 1830 assert_includes original_community.members, original_member
1828 assert_includes original_community.members, plugin1_member 1831 assert_includes original_community.members, plugin1_member
1829 assert_includes original_community.members, plugin2_member 1832 assert_includes original_community.members, plugin2_member
1830 - assert 3, original_community.members.count 1833 + assert 3, original_community.members_count
1831 end 1834 end
1832 1835
1833 private 1836 private
@@ -1967,6 +1970,7 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -1967,6 +1970,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1967 end 1970 end
1968 1971
1969 environment = Environment.default 1972 environment = Environment.default
  1973 + Noosfero::Plugin.stubs(:all).returns(['ProfileTest::Plugin1'])
1970 environment.enable_plugin(Plugin1) 1974 environment.enable_plugin(Plugin1)
1971 plugins = Noosfero::Plugin::Manager.new(environment, self) 1975 plugins = Noosfero::Plugin::Manager.new(environment, self)
1972 p = fast_create(Profile) 1976 p = fast_create(Profile)
test/unit/role_assignment_ext_test.rb 0 → 100644
@@ -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 &lt; ActiveSupport::TestCase @@ -7,6 +7,7 @@ class SuggestArticleTest &lt; ActiveSupport::TestCase
7 ActionMailer::Base.perform_deliveries = true 7 ActionMailer::Base.perform_deliveries = true
8 ActionMailer::Base.deliveries = [] 8 ActionMailer::Base.deliveries = []
9 @profile = create_user('test_user').person 9 @profile = create_user('test_user').person
  10 + Noosfero::Plugin.stubs(:all).returns(['SuggestArticleTest::EverythingIsSpam', 'SuggestArticleTest::SpamNotification'])
10 end 11 end
11 attr_reader :profile 12 attr_reader :profile
12 13
test/unit/task_mailer_test.rb
@@ -24,7 +24,7 @@ class TaskMailerTest &lt; ActiveSupport::TestCase @@ -24,7 +24,7 @@ class TaskMailerTest &lt; ActiveSupport::TestCase
24 requestor.expects(:name).returns('my name') 24 requestor.expects(:name).returns('my name')
25 25
26 environment = mock() 26 environment = mock()
27 - environment.expects(:contact_email).returns('sender@example.com') 27 + environment.expects(:noreply_email).returns('sender@example.com')
28 environment.expects(:default_hostname).returns('example.com') 28 environment.expects(:default_hostname).returns('example.com')
29 environment.expects(:name).returns('example').at_least_once 29 environment.expects(:name).returns('example').at_least_once
30 30
@@ -47,7 +47,7 @@ class TaskMailerTest &lt; ActiveSupport::TestCase @@ -47,7 +47,7 @@ class TaskMailerTest &lt; ActiveSupport::TestCase
47 requestor.expects(:name).returns('my name') 47 requestor.expects(:name).returns('my name')
48 48
49 environment = mock() 49 environment = mock()
50 - environment.expects(:contact_email).returns('sender@example.com') 50 + environment.expects(:noreply_email).returns('sender@example.com')
51 environment.expects(:default_hostname).returns('example.com') 51 environment.expects(:default_hostname).returns('example.com')
52 environment.expects(:name).returns('example').at_least_once 52 environment.expects(:name).returns('example').at_least_once
53 53
@@ -71,7 +71,7 @@ class TaskMailerTest &lt; ActiveSupport::TestCase @@ -71,7 +71,7 @@ class TaskMailerTest &lt; ActiveSupport::TestCase
71 requestor.expects(:name).returns('my name') 71 requestor.expects(:name).returns('my name')
72 72
73 environment = mock() 73 environment = mock()
74 - environment.expects(:contact_email).returns('sender@example.com') 74 + environment.expects(:noreply_email).returns('sender@example.com')
75 environment.expects(:default_hostname).returns('example.com') 75 environment.expects(:default_hostname).returns('example.com')
76 environment.expects(:name).returns('example').at_least_once 76 environment.expects(:name).returns('example').at_least_once
77 77
@@ -105,7 +105,7 @@ class TaskMailerTest &lt; ActiveSupport::TestCase @@ -105,7 +105,7 @@ class TaskMailerTest &lt; 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 &lt; ActiveSupport::TestCase @@ -124,11 +124,11 @@ class TaskMailerTest &lt; 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/theme_test.rb
@@ -191,4 +191,22 @@ class ThemeTest &lt; ActiveSupport::TestCase @@ -191,4 +191,22 @@ class ThemeTest &lt; 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 &lt; ActiveSupport::TestCase @@ -31,6 +31,13 @@ class UploadedFileTest &lt; 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')
@@ -119,24 +126,13 @@ class UploadedFileTest &lt; ActiveSupport::TestCase @@ -119,24 +126,13 @@ class UploadedFileTest &lt; ActiveSupport::TestCase
119 assert_equal 'my title', UploadedFile.new(:title => 'my title').title 126 assert_equal 'my title', UploadedFile.new(:title => 'my title').title
120 end 127 end
121 128
122 - should 'limit title to 140 characters' do  
123 - upload = UploadedFile.new  
124 -  
125 - upload.title = '+' * 61; upload.valid?  
126 - assert upload.errors[:title]  
127 -  
128 - upload.title = '+' * 60; upload.valid?  
129 - assert !upload.errors[:title]  
130 -  
131 - end  
132 -  
133 should 'always provide a display title' do 129 should 'always provide a display title' do
134 upload = UploadedFile.new(:uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain')) 130 upload = UploadedFile.new(:uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain'))
135 - assert_equal 'test.txt', upload.display_title 131 + assert_equal 'test.txt', upload.title
136 upload.title = 'My text file' 132 upload.title = 'My text file'
137 - assert_equal 'My text file', upload.display_title 133 + assert_equal 'My text file', upload.title
138 upload.title = '' 134 upload.title = ''
139 - assert_equal 'test.txt', upload.display_title 135 + assert_equal 'test.txt', upload.title
140 end 136 end
141 137
142 should 'use name as title by default' do 138 should 'use name as title by default' do
@@ -326,13 +322,15 @@ class UploadedFileTest &lt; ActiveSupport::TestCase @@ -326,13 +322,15 @@ class UploadedFileTest &lt; ActiveSupport::TestCase
326 end 322 end
327 323
328 should 'group trackers activity of image\'s upload' do 324 should 'group trackers activity of image\'s upload' do
  325 + ActionTracker::Record.delete_all
329 gallery = fast_create(Gallery, :profile_id => profile.id) 326 gallery = fast_create(Gallery, :profile_id => profile.id)
330 - 327 + count = ActionTracker::Record.find_all_by_verb('upload_image').count
331 image1 = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => gallery, :profile => profile) 328 image1 = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => gallery, :profile => profile)
332 - assert_equal 1, ActionTracker::Record.find_all_by_verb('upload_image').count 329 + count += 1
  330 + assert_equal count, ActionTracker::Record.find_all_by_verb('upload_image').count
333 331
334 image2 = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg'), :parent => gallery, :profile => profile) 332 image2 = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg'), :parent => gallery, :profile => profile)
335 - assert_equal 1, ActionTracker::Record.find_all_by_verb('upload_image').count 333 + assert_equal count, ActionTracker::Record.find_all_by_verb('upload_image').count
336 end 334 end
337 335
338 { 336 {
vendor/plugins/action_tracker/lib/action_tracker_model.rb
1 module ActionTracker 1 module ActionTracker
2 class Record < ActiveRecord::Base 2 class Record < ActiveRecord::Base
3 -  
4 set_table_name 'action_tracker' 3 set_table_name 'action_tracker'
5 4
6 belongs_to :user, :polymorphic => true 5 belongs_to :user, :polymorphic => true
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: