Commit 1df725331d211595ef75706b28a9a6d6bc2fdb68

Authored by Antonio Terceiro
1 parent 9129ba2c

First stab at HTTP caching

Implemented cache policy:

  * the homepage is cached for 5 minutes by default. This time can be
    configured with the =home_cache_in_minutes= attribute in the environment.
  * non-profile pages are cached for 15 minutes by default. This time can be
    configured with the =general_cache_in_minutes= attribute in the
    environment.
  * profile pages are cached for 15 minutes by default. This time can be
    configured in the =profile_cache_in_minutes= attribute in the environment.
  * The account controller (/account/*) is not cached at all.
  * The environment administration area (/admin/*) is not cached at all.
  * The profile administration area (/myprofile/*) is not cached at all.
  * Since Varnish will not cache any request that involves cookies:
    * Authenticated users will not benefit from the cache.
    * Cookies are not allowed for unauthenticated users. So, when a response is
      being prepared for an unauthenticated user, all cookies are wiped out.

The contents of the login block and the login/logout part of the header is now
loaded via an AJAX call to /account/user_data. This way we can cache almost all
pages without caching user-specific data.

We are also changing substantially how the flash[:notice] messages work. From
now on, instead of setting flash[:notice], we must set session[:flash]. It will
work more or less like before, except that session[:notice] will be consumed by
the AJAX call to /account/user_data that is done during all page loads instead
of being consumed automatically by Rails. The only exception to this is the
media_panel, because it uses a different layout.

(ActionItem1608)
Showing 56 changed files with 458 additions and 179 deletions   Show diff stats
app/controllers/admin/admin_panel_controller.rb
... ... @@ -40,7 +40,7 @@ class AdminPanelController < AdminController
40 40 end
41 41 redirect_to :action => 'set_portal_folders'
42 42 else
43   - flash[:notice] = __('Community not found. You must insert the identifier of a community from this environment')
  43 + session[:notice] = __('Community not found. You must insert the identifier of a community from this environment')
44 44 end
45 45 end
46 46 end
... ... @@ -54,7 +54,7 @@ class AdminPanelController < AdminController
54 54 folders = params[:folders].map{|fid| Folder.find(:first, :conditions => {:profile_id => env.portal_community, :id => fid})} if params[:folders]
55 55 env.portal_folders = folders
56 56 if env.save
57   - flash[:notice] = _('Saved the portal folders')
  57 + session[:notice] = _('Saved the portal folders')
58 58 redirect_to :action => 'set_portal_news_amount'
59 59 end
60 60 end
... ... @@ -63,7 +63,7 @@ class AdminPanelController < AdminController
63 63 def set_portal_news_amount
64 64 if request.post?
65 65 if @environment.update_attributes(params[:environment])
66   - flash[:notice] = _('Saved the number of news on folders')
  66 + session[:notice] = _('Saved the number of news on folders')
67 67 redirect_to :action => 'index'
68 68 end
69 69 end
... ...
app/controllers/admin/environment_role_manager_controller.rb
... ... @@ -14,9 +14,9 @@ class EnvironmentRoleManagerController < AdminController
14 14 @roles = params[:roles] ? Role.find(params[:roles]) : []
15 15 @person = Person.find(params[:person])
16 16 if @person.define_roles(@roles, environment)
17   - flash[:notice] = _('Roles successfuly updated')
  17 + session[:notice] = _('Roles successfuly updated')
18 18 else
19   - flash[:notice] = _('Couldnt change the roles')
  19 + session[:notice] = _('Couldnt change the roles')
20 20 end
21 21 redirect_to :action => :index
22 22 end
... ... @@ -42,9 +42,9 @@ class EnvironmentRoleManagerController < AdminController
42 42 def remove_role
43 43 @association = RoleAssignment.find(params[:id])
44 44 if @association.destroy
45   - flash[:notice] = _('Member succefully unassociated')
  45 + session[:notice] = _('Member succefully unassociated')
46 46 else
47   - flash[:notice] = _('Failed to unassociate member')
  47 + session[:notice] = _('Failed to unassociate member')
48 48 end
49 49 redirect_to :aciton => 'index'
50 50 end
... ... @@ -52,9 +52,9 @@ class EnvironmentRoleManagerController < AdminController
52 52 def unassociate
53 53 @association = RoleAssignment.find(params[:id])
54 54 if @association.destroy
55   - flash[:notice] = _('Member succefully unassociated')
  55 + session[:notice] = _('Member succefully unassociated')
56 56 else
57   - flash[:notice] = _('Failed to unassociate member')
  57 + session[:notice] = _('Failed to unassociate member')
58 58 end
59 59 redirect_to :aciton => 'index'
60 60 end
... ...
app/controllers/admin/features_controller.rb
... ... @@ -8,7 +8,7 @@ class FeaturesController < AdminController
8 8 post_only :update
9 9 def update
10 10 if @environment.update_attributes(params[:environment])
11   - flash[:notice] = _('Features updated successfully.')
  11 + session[:notice] = _('Features updated successfully.')
12 12 redirect_to :action => 'index'
13 13 else
14 14 render :action => 'index'
... ... @@ -24,7 +24,7 @@ class FeaturesController < AdminController
24 24 def manage_person_fields
25 25 environment.custom_person_fields = params[:person_fields]
26 26 if environment.save!
27   - flash[:notice] = _('Person fields updated successfully.')
  27 + session[:notice] = _('Person fields updated successfully.')
28 28 else
29 29 flash[:error] = _('Person fields not updated successfully.')
30 30 end
... ... @@ -34,7 +34,7 @@ class FeaturesController < AdminController
34 34 def manage_enterprise_fields
35 35 environment.custom_enterprise_fields = params[:enterprise_fields]
36 36 if environment.save!
37   - flash[:notice] = __('Enterprise fields updated successfully.')
  37 + session[:notice] = __('Enterprise fields updated successfully.')
38 38 else
39 39 flash[:error] = __('Enterprise fields not updated successfully.')
40 40 end
... ... @@ -44,7 +44,7 @@ class FeaturesController < AdminController
44 44 def manage_community_fields
45 45 environment.custom_community_fields = params[:community_fields]
46 46 if environment.save!
47   - flash[:notice] = _('Community fields updated successfully.')
  47 + session[:notice] = _('Community fields updated successfully.')
48 48 else
49 49 flash[:error] = _('Community fields not updated successfully.')
50 50 end
... ...
app/controllers/admin/role_controller.rb
... ... @@ -19,7 +19,7 @@ class RoleController < AdminController
19 19 if @role.save
20 20 redirect_to :action => 'show', :id => @role
21 21 else
22   - flash[:notice] = _('Failed to create role')
  22 + session[:notice] = _('Failed to create role')
23 23 render :action => 'new'
24 24 end
25 25 end
... ... @@ -33,7 +33,7 @@ class RoleController < AdminController
33 33 if @role.update_attributes(params[:role])
34 34 redirect_to :action => 'show', :id => @role
35 35 else
36   - flash[:notice] = _('Failed to edit role')
  36 + session[:notice] = _('Failed to edit role')
37 37 render :action => 'edit'
38 38 end
39 39 end
... ... @@ -43,7 +43,7 @@ class RoleController < AdminController
43 43 if @role.destroy
44 44 redirect_to :action => 'index'
45 45 else
46   - flash[:notice] = _('Failed to edit role')
  46 + session[:notice] = _('Failed to edit role')
47 47 redirect_to :action => 'index'
48 48 end
49 49 end
... ...
app/controllers/box_organizer_controller.rb
... ... @@ -96,7 +96,7 @@ class BoxOrganizerController < ApplicationController
96 96 expire_timeout_fragment(@block.cache_keys)
97 97 redirect_to :action => 'index'
98 98 else
99   - flash[:notice] = _('Failed to remove block')
  99 + session[:notice] = _('Failed to remove block')
100 100 end
101 101 end
102 102  
... ...
app/controllers/my_profile/cms_controller.rb
... ... @@ -143,7 +143,7 @@ class CmsController < MyProfileController
143 143 @article = profile.articles.find(params[:id])
144 144 profile.home_page = @article
145 145 profile.save(false)
146   - flash[:notice] = _('"%s" configured as home page.') % @article.name
  146 + session[:notice] = _('"%s" configured as home page.') % @article.name
147 147 redirect_to :action => 'view', :id => @article.id
148 148 end
149 149  
... ... @@ -232,7 +232,7 @@ class CmsController < MyProfileController
232 232 end
233 233 end
234 234 if @failed.blank?
235   - flash[:notice] = _("Your publish request was sent successfully")
  235 + session[:notice] = _("Your publish request was sent successfully")
236 236 if @back_to
237 237 redirect_to @back_to
238 238 else
... ...
app/controllers/my_profile/friends_controller.rb
... ... @@ -14,7 +14,7 @@ class FriendsController < MyProfileController
14 14 # FIXME this shouldn't be in Person model?
15 15 AddFriend.create!(:person => profile, :friend => @friend, :group_for_person => params[:group])
16 16  
17   - flash[:notice] = _('%s still needs to accept being your friend.') % @friend.name
  17 + session[:notice] = _('%s still needs to accept being your friend.') % @friend.name
18 18 # FIXME shouldn't redirect to the friend's page?
19 19 redirect_to :action => 'index'
20 20 end
... ...
app/controllers/my_profile/mailconf_controller.rb
... ... @@ -20,20 +20,20 @@ class MailconfController < MyProfileController
20 20 @task = EmailActivation.new(:target => environment, :requestor => profile)
21 21 begin
22 22 @task.save!
23   - flash[:notice] = _('Please fill your personal information below in order to get your mailbox approved by one of the administrators')
  23 + session[:notice] = _('Please fill your personal information below in order to get your mailbox approved by one of the administrators')
24 24 redirect_to :controller => 'profile_editor', :action => 'edit'
25 25 rescue Exception => ex
26   - flash[:notice] = _('e-Mail was not enabled successfully.')
  26 + session[:notice] = _('e-Mail was not enabled successfully.')
27 27 render :action => 'index'
28 28 end
29 29 end
30 30 post_only :disable
31 31 def disable
32 32 if profile.user.disable_email!
33   - flash[:notice] = _('e-Mail disabled successfully.')
  33 + session[:notice] = _('e-Mail disabled successfully.')
34 34 redirect_to :controller => 'profile_editor'
35 35 else
36   - flash[:notice] = _('e-Mail was not disabled successfully.')
  36 + session[:notice] = _('e-Mail was not disabled successfully.')
37 37 redirect_to :action => 'index'
38 38 end
39 39 end
... ...
app/controllers/my_profile/manage_products_controller.rb
... ... @@ -43,7 +43,7 @@ class ManageProductsController < ApplicationController
43 43 @level = 0
44 44 if request.post?
45 45 if @product.save
46   - flash[:notice] = _('Product succesfully created')
  46 + session[:notice] = _('Product succesfully created')
47 47 render :partial => 'shared/redirect_via_javascript',
48 48 :locals => { :url => url_for(:controller => 'manage_products', :action => 'show', :id => @product) }
49 49 else
... ... @@ -101,10 +101,10 @@ class ManageProductsController < ApplicationController
101 101 def destroy
102 102 @product = @profile.products.find(params[:id])
103 103 if @product.destroy
104   - flash[:notice] = _('Product succesfully removed')
  104 + session[:notice] = _('Product succesfully removed')
105 105 redirect_back_or_default :action => 'index'
106 106 else
107   - flash[:notice] = _('Could not remove the product')
  107 + session[:notice] = _('Could not remove the product')
108 108 redirect_back_or_default :action => 'show', :id => @product
109 109 end
110 110 end
... ...
app/controllers/my_profile/maps_controller.rb
... ... @@ -8,7 +8,7 @@ class MapsController < MyProfileController
8 8 begin
9 9 Profile.transaction do
10 10 if profile.update_attributes!(params[:profile_data])
11   - flash[:notice] = _('Address was updated successfully!')
  11 + session[:notice] = _('Address was updated successfully!')
12 12 redirect_to :action => 'edit_location'
13 13 end
14 14 end
... ...
app/controllers/my_profile/memberships_controller.rb
... ... @@ -29,7 +29,7 @@ class MembershipsController < MyProfileController
29 29 @community = Community.find(params[:id])
30 30 if request.post?
31 31 if @community.destroy
32   - flash[:notice] = _('%s was removed.') % @community.short_name
  32 + session[:notice] = _('%s was removed.') % @community.short_name
33 33 redirect_to :action => 'index'
34 34 end
35 35 end
... ...
app/controllers/my_profile/profile_editor_controller.rb
... ... @@ -25,7 +25,7 @@ class ProfileEditorController < MyProfileController
25 25 if profile.identifier.blank?
26 26 profile.identifier = params[:profile]
27 27 end
28   - flash[:notice] = _('Cannot update profile')
  28 + session[:notice] = _('Cannot update profile')
29 29 end
30 30 end
31 31 end
... ... @@ -34,7 +34,7 @@ class ProfileEditorController < MyProfileController
34 34 @to_enable = profile
35 35 if request.post? && params[:confirmation]
36 36 unless @to_enable.update_attribute('enabled', true)
37   - flash[:notice] = _('%s was not enabled.') % @to_enable.name
  37 + session[:notice] = _('%s was not enabled.') % @to_enable.name
38 38 end
39 39 redirect_to :action => 'index'
40 40 end
... ... @@ -44,7 +44,7 @@ class ProfileEditorController < MyProfileController
44 44 @to_disable = profile
45 45 if request.post? && params[:confirmation]
46 46 unless @to_disable.update_attribute('enabled', false)
47   - flash[:notice] = _('%s was not disabled.') % @to_disable.name
  47 + session[:notice] = _('%s was not disabled.') % @to_disable.name
48 48 end
49 49 redirect_to :action => 'index'
50 50 end
... ...
app/controllers/my_profile/profile_members_controller.rb
... ... @@ -12,9 +12,9 @@ class ProfileMembersController < MyProfileController
12 12 @roles = @roles.select{|r| r.has_kind?('Profile') }
13 13 @person = profile.members.find { |m| m.id == params[:person].to_i }
14 14 if @person && @person.define_roles(@roles, profile)
15   - flash[:notice] = _('Roles successfuly updated')
  15 + session[:notice] = _('Roles successfuly updated')
16 16 else
17   - flash[:notice] = _('Couldnt change the roles')
  17 + session[:notice] = _('Couldnt change the roles')
18 18 end
19 19 redirect_to :action => :index
20 20 end
... ... @@ -44,9 +44,9 @@ class ProfileMembersController < MyProfileController
44 44 def remove_role
45 45 @association = RoleAssignment.find(:all, :conditions => {:id => params[:id], :target_id => profile.id})
46 46 if @association.destroy
47   - flash[:notice] = 'Member succefully unassociated'
  47 + session[:notice] = 'Member succefully unassociated'
48 48 else
49   - flash[:notice] = 'Failed to unassociate member'
  49 + session[:notice] = 'Failed to unassociate member'
50 50 end
51 51 render :layout => false
52 52 end
... ... @@ -56,9 +56,9 @@ class ProfileMembersController < MyProfileController
56 56 associations = member.find_roles(profile)
57 57 RoleAssignment.transaction do
58 58 if associations.map(&:destroy)
59   - flash[:notice] = 'Member succefully unassociated'
  59 + session[:notice] = 'Member succefully unassociated'
60 60 else
61   - flash[:notice] = 'Failed to unassociate member'
  61 + session[:notice] = 'Failed to unassociate member'
62 62 end
63 63 end
64 64 render :layout => false
... ...
app/controllers/my_profile/tasks_controller.rb
... ... @@ -20,7 +20,7 @@ class TasksController < MyProfileController
20 20 begin
21 21 task.send(decision)
22 22 rescue Exception => ex
23   - flash[:notice] = ex.clean_message
  23 + session[:notice] = ex.clean_message
24 24 end
25 25 end
26 26 redirect_to :action => 'index'
... ...
app/controllers/public/account_controller.rb
... ... @@ -30,10 +30,10 @@ class AccountController < ApplicationController
30 30 end
31 31 if redirect?
32 32 go_to_initial_page
33   - flash[:notice] = _("Logged in successfully")
  33 + session[:notice] = _("Logged in successfully")
34 34 end
35 35 else
36   - flash[:notice] = _('Incorrect username or password') if redirect?
  36 + session[:notice] = _('Incorrect username or password') if redirect?
37 37 redirect_to :back if redirect?
38 38 end
39 39 end
... ... @@ -70,7 +70,7 @@ class AccountController < ApplicationController
70 70 invitation.update_attributes!({:friend => @user.person})
71 71 invitation.finish
72 72 end
73   - flash[:notice] = _("Thanks for signing up!")
  73 + session[:notice] = _("Thanks for signing up!")
74 74 if @wizard
75 75 redirect_to :controller => 'search', :action => 'assets', :asset => 'communities', :wizard => true
76 76 return
... ... @@ -109,7 +109,7 @@ class AccountController < ApplicationController
109 109 end
110 110 cookies.delete :auth_token
111 111 reset_session
112   - flash[:notice] = _("You have been logged out.")
  112 + session[:notice] = _("You have been logged out.")
113 113 redirect_to :controller => 'home', :action => 'index'
114 114 end
115 115  
... ... @@ -120,10 +120,10 @@ class AccountController < ApplicationController
120 120 @user.change_password!(params[:current_password],
121 121 params[:new_password],
122 122 params[:new_password_confirmation])
123   - flash[:notice] = _('Your password has been changed successfully!')
  123 + session[:notice] = _('Your password has been changed successfully!')
124 124 redirect_to :action => 'index'
125 125 rescue User::IncorrectPassword => e
126   - flash[:notice] = _('The supplied current password is incorrect.')
  126 + session[:notice] = _('The supplied current password is incorrect.')
127 127 render :action => 'change_password'
128 128 end
129 129 else
... ... @@ -235,6 +235,21 @@ class AccountController < ApplicationController
235 235 render :partial => 'identifier_status'
236 236 end
237 237  
  238 + def user_data
  239 + user_data =
  240 + if logged_in?
  241 + { "login" => current_user.login, "is_admin" => user.is_admin?(environment), 'since_month' => user.created_at.month, 'since_year' => user.created_at.year }
  242 + else
  243 + { }
  244 + end
  245 + if session[:notice]
  246 + user_data['notice'] = session[:notice]
  247 + session[:notice] = nil # consume the notice
  248 + end
  249 +
  250 + render :text => user_data.to_json, :layout => false, :content_type => "application/javascript"
  251 + end
  252 +
238 253 protected
239 254  
240 255 def redirect?
... ...
app/controllers/public/contact_controller.rb
... ... @@ -12,10 +12,10 @@ class ContactController < PublicController
12 12 @contact.city = (!params[:city].blank? && City.exists?(params[:city])) ? City.find(params[:city]).name : nil
13 13 @contact.state = (!params[:state].blank? && State.exists?(params[:state])) ? State.find(params[:state]).name : nil
14 14 if @contact.deliver
15   - flash[:notice] = _('Contact successfully sent')
  15 + session[:notice] = _('Contact successfully sent')
16 16 redirect_to :action => 'new'
17 17 else
18   - flash[:notice] = _('Contact not sent')
  18 + session[:notice] = _('Contact not sent')
19 19 end
20 20 else
21 21 @contact = user.build_contact(profile)
... ...
app/controllers/public/content_viewer_controller.rb
... ... @@ -110,7 +110,7 @@ class ContentViewerController < ApplicationController
110 110 @comment = @page.comments.find(params[:remove_comment])
111 111 if (user == @comment.author || user == @page.profile || user.has_permission?(:moderate_comments, @page.profile))
112 112 @comment.destroy
113   - flash[:notice] = _('Comment succesfully deleted')
  113 + session[:notice] = _('Comment succesfully deleted')
114 114 end
115 115 redirect_to :action => 'view_page', :profile => params[:profile], :page => @page.explode_path, :view => params[:view]
116 116 end
... ...
app/controllers/public/invite_controller.rb
... ... @@ -22,7 +22,7 @@ class InviteController < PublicController
22 22 flash.now[:notice] = _('<url> is needed in invitation mail.')
23 23 elsif !contacts_to_invite.empty?
24 24 Invitation.invite(current_user.person, contacts_to_invite, params[:mail_template], profile)
25   - flash[:notice] = _('Your invitations have been sent.')
  25 + session[:notice] = _('Your invitations have been sent.')
26 26 if profile.person?
27 27 redirect_to :controller => 'friends'
28 28 else
... ...
app/controllers/public/profile_controller.rb
... ... @@ -76,7 +76,7 @@ class ProfileController < PublicController
76 76 @wizard = params[:wizard]
77 77 if request.post? && params[:confirmation]
78 78 profile.add_member(current_user.person)
79   - flash[:notice] = _('%s administrator still needs to accept you as member.') % profile.name if profile.closed?
  79 + session[:notice] = _('%s administrator still needs to accept you as member.') % profile.name if profile.closed?
80 80 if @wizard
81 81 redirect_to :controller => 'search', :action => 'assets', :asset => 'communities', :wizard => true
82 82 else
... ... @@ -84,7 +84,7 @@ class ProfileController < PublicController
84 84 end
85 85 else
86 86 if current_user.person.memberships.include?(profile)
87   - flash[:notice] = _('You are already a member of "%s"') % profile.name
  87 + session[:notice] = _('You are already a member of "%s"') % profile.name
88 88 redirect_to profile.url
89 89 return
90 90 end
... ... @@ -129,7 +129,7 @@ class ProfileController < PublicController
129 129 def unblock
130 130 if current_user.person.is_admin?(profile.environment)
131 131 profile.unblock
132   - flash[:notice] = _("You have unblocked %s successfully. ") % profile.name
  132 + session[:notice] = _("You have unblocked %s successfully. ") % profile.name
133 133 redirect_to :controller => 'profile', :action => 'index'
134 134 else
135 135 message = __('You are not allowed to unblock enterprises in this environment.')
... ...
app/models/environment.rb
... ... @@ -643,5 +643,9 @@ class Environment < ActiveRecord::Base
643 643 Product.find(:all, {:conditions => {:highlighted => true, :enterprise_id => self.enterprises.find(:all, :select => :id) }, :joins => :image}.merge(options))
644 644 end
645 645  
  646 + settings_items :home_cache_in_minutes, :type => :integer, :default => 5
  647 + settings_items :general_cache_in_minutes, :type => :integer, :default => 15
  648 + settings_items :profile_cache_in_minutes, :type => :integer, :default => 15
  649 +
646 650 end
647 651  
... ...
app/models/login_block.rb
... ... @@ -10,11 +10,7 @@ class LoginBlock < Block
10 10  
11 11 def content
12 12 lambda do
13   - if logged_in?
14   - render :file => 'account/user_info'
15   - else
16   - render :file => 'account/login_block'
17   - end
  13 + render :file => 'blocks/login_block'
18 14 end
19 15 end
20 16  
... ...
app/views/account/login_block.rhtml
... ... @@ -6,7 +6,7 @@
6 6 <div class="login-box-content">
7 7  
8 8 <%
9   - @user = User.new if ! @user
  9 + @user ||= User.new
10 10 %>
11 11  
12 12 <% labelled_form_for :user, @user,
... ...
app/views/account/user_info.rhtml
... ... @@ -1,16 +0,0 @@
1   -<div class="logged-user-info">
2   -
3   -<h2><%= _('Logged in as %s') % user.identifier %></h2>
4   -
5   -<ul>
6   - <li><%= _('User since %{year}/%{month}') % { :year => user.created_at.year, :month => user.created_at.month } %></li>
7   - <li><%= link_to_homepage _('Homepage') %></li>
8   -</ul>
9   -
10   -<div class="user-actions">
11   -<%= lightbox_link_to content_tag('span', _('Logout')),
12   - { :controller => 'account', :action => 'logout_popup' },
13   - :class => 'button with-text icon-menu-logout' %>
14   -</div>
15   -
16   -</div>
app/views/blocks/login_block.rhtml 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +<div class="logged-user-info" style='display: none;'>
  2 + <h2><%= _('Logged in as %s') % '%{login}' %></h2>
  3 + <ul>
  4 + <li><%= _('User since %{year}/%{month}') %></li>
  5 + <li><%= link_to _('Homepage'), '/%{login}' %></li>
  6 + </ul>
  7 + <div class="user-actions">
  8 + <%= link_to content_tag('span', _('Logout')), { :controller => 'account', :action => 'logout' }, :class => 'button with-text icon-menu-logout' %>
  9 + </div>
  10 +</div>
  11 +<div class='not-logged-user' style='display: none;'>
  12 + <%= render :file => 'account/login_block' %>
  13 +</div>
... ...
app/views/cms/media_listing.rhtml
... ... @@ -33,7 +33,7 @@
33 33  
34 34 <div id="notice" onclick="Element.hide('notice');" style="display:none">
35 35 <% unless flash[:notice].nil? %>
36   - <%= flash[:notice] unless flash[:notice].nil? %>
  36 + <%= flash[:notice] %>
37 37 <%= javascript_tag(visual_effect( :appear, 'notice')) %>
38 38 <% end %>
39 39 </div>
... ...
app/views/layouts/application-ng.rhtml
... ... @@ -41,24 +41,18 @@
41 41 </div>
42 42 <div id="wrap-2">
43 43 <div id="user">
44   - <% if logged_in? %>
45   - <%= _('Welcome, %s.') % link_to('<i></i><strong>' + user.identifier + '</strong>', user.url, :id => "homepage-link", :title => _('Go to your homepage')) %>
46   - <% if user.is_admin?(environment) %>
47   - <%= link_to('<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>', { :controller => 'admin_panel', :action => 'index' }, :id => "controlpanel", :title => _("Configure the environment")) %>
48   - <% end %>
49   - <% if (user.environment == environment) %>
50   - <%= link_to('<i class="icon-menu-ctrl-panel"></i><strong>' + _('Control panel') + '</strong>', user.admin_url, :id => "controlpanel", :title => _("Configure your personal account and content")) %>
51   - <% end %>
  44 + <span class='logged-in' style='display: none;'>
  45 + <%= _('Welcome, %s.') % link_to('<i></i><strong>%{login}</strong>', '/%{login}', :id => "homepage-link", :title => _('Go to your homepage')) %>
  46 + <%= link_to('<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>', { :controller => 'admin_panel', :action => 'index' }, :id => "controlpanel", :title => _("Configure the environment"), :class => 'admin-link') %>
  47 + <%= link_to('<i class="icon-menu-ctrl-panel"></i><strong>' + _('Control panel') + '</strong>', '/myprofile/%{login}', :id => "controlpanel", :title => _("Configure your personal account and content")) %>
52 48 <%= link_to('<i class="icon-menu-logout"></i><strong>' + _('Logout') + '</strong>', { :controller => 'account', :action => 'logout'} , :id => "logout", :title => _("Leave the system")) %>
53   - <% else %>
54   - <% if params[:controller] != 'account' || params[:action] != 'signup' %>
  49 + </span>
  50 + <span class='not-logged-in' style='display: none'>
55 51 <%= _('%s or %s') % [thickbox_inline_popup_link('<i class="icon-menu-login"></i><strong>' + _('Login') + '</strong>', login_url, 'inlineLoginBox', :id => 'link_login'), link_to('<strong>' + _('Register') + '</strong>', :controller => 'account', :action => 'signup') ] %>
56 52 <div id='inlineLoginBox' style='display: none;'>
57 53 <%= render :file => 'account/login', :locals => { :is_thickbox => true } %>
58 54 </div>
59   - <% end %>
60   - <% end %>
61   -
  55 + </span>
62 56 <form action="/search" class="search_form" method="get" class="clean">
63 57 <input name="query" size="15" value="<%=_('Search...')%>"
64 58 onfocus="this.form.className='focused';
... ...
app/views/shared/noosfero_layout_features.rhtml
1   - <% unless flash[:notice].nil? %>
2   - <div id="notice" onclick="Element.hide('notice');" style="display:none">
3   - <%= flash[:notice] %>
4   - <%= javascript_tag(
5   - visual_effect( :appear, 'notice', :duration => 1.5, :to => 0.8, :queue => :end ) +
6   - 'setTimeout(function() { %s }, 5000)' % visual_effect( :fade, 'notice', :duration => 1.0, :from => 0.8, :queue => :end )
7   - ) %>
8   - </div>
9   - <% end %>
10   -
11 1 <% if is_testing_theme %>
12 2 <%= render :file => 'shared/theme_test_panel' %>
13 3 <% end %>
... ...
db/schema.rb
... ... @@ -9,7 +9,7 @@
9 9 #
10 10 # It's strongly recommended to check this file into your version control system.
11 11  
12   -ActiveRecord::Schema.define(:version => 20100730141134) do
  12 +ActiveRecord::Schema.define(:version => 20100811211216) do
13 13  
14 14 create_table "article_versions", :force => true do |t|
15 15 t.integer "article_id"
... ...
features/blog.feature
... ... @@ -10,7 +10,7 @@ Feature: blog
10 10 And I am logged in as "joaosilva"
11 11  
12 12 Scenario: create a blog
13   - Given I follow "Control panel"
  13 + Given I go to the Control panel
14 14 And I follow "Create blog"
15 15 Then I should see "My Blog"
16 16 When I fill in "Title" with "My Blog"
... ... @@ -19,7 +19,7 @@ Feature: blog
19 19 Then I should see "Configure blog"
20 20  
21 21 Scenario: redirect to blog after create blog from control panel
22   - Given I follow "Control panel"
  22 + Given I go to the Control panel
23 23 And I follow "Create blog"
24 24 Then I should see "My Blog"
25 25 When I fill in "Title" with "My Blog"
... ... @@ -27,7 +27,7 @@ Feature: blog
27 27 Then I should be on /joaosilva/my-blog
28 28  
29 29 Scenario: redirect to blog after create blog from cms
30   - Given I follow "Control panel"
  30 + Given I go to the Control panel
31 31 And I follow "Manage Content"
32 32 When I follow "New Blog"
33 33 And I fill in "Title" with "Blog from cms"
... ... @@ -35,12 +35,12 @@ Feature: blog
35 35 Then I should be on /joaosilva/blog-from-cms
36 36  
37 37 Scenario: create multiple blogs
38   - Given I follow "Control panel"
  38 + Given I go to the Control panel
39 39 And I follow "Manage Content"
40 40 And I follow "New Blog"
41 41 And I fill in "Title" with "Blog One"
42 42 And I press "Save"
43   - Then I follow "Control panel"
  43 + Then I go to the Control panel
44 44 And I follow "Manage Content"
45 45 And I follow "New Blog"
46 46 And I fill in "Title" with "Blog Two"
... ... @@ -49,16 +49,16 @@ Feature: blog
49 49 And I should be on /joaosilva/blog-two
50 50  
51 51 Scenario: cancel button back to cms
52   - Given I follow "Control panel"
  52 + Given I go to the Control panel
53 53 And I follow "Manage Content"
54 54 And I follow "New Blog"
55   - When I follow "Cancel"
  55 + When I follow "Cancel" within ".main-block"
56 56 Then I should be on /myprofile/joaosilva/cms
57 57  
58 58 Scenario: cancel button back to myprofile
59   - Given I follow "Control panel"
  59 + Given I go to the Control panel
60 60 And I follow "Create blog"
61   - When I follow "Cancel"
  61 + When I follow "Cancel" within ".main-block"
62 62 Then I should be on /myprofile/joaosilva
63 63  
64 64 Scenario: configure blog link to cms
... ... @@ -66,7 +66,7 @@ Feature: blog
66 66 | owner | name |
67 67 | joaosilva | Blog One |
68 68 | joaosilva | Blog Two |
69   - And I follow "Control panel"
  69 + And I go to the Control panel
70 70 When I follow "Configure blog"
71 71 Then I should be on /myprofile/joaosilva/cms
72 72  
... ... @@ -74,7 +74,7 @@ Feature: blog
74 74 Given the following blogs
75 75 | owner | name |
76 76 | joaosilva | Blog One |
77   - And I follow "Control panel"
  77 + And I go to the Control panel
78 78 When I follow "Configure blog"
79 79 Then I should be on edit "Blog One" by joaosilva
80 80  
... ... @@ -82,7 +82,7 @@ Feature: blog
82 82 Given the following blogs
83 83 | owner | name |
84 84 | joaosilva | Blog One |
85   - And I follow "Control panel"
  85 + And I go to the Control panel
86 86 And I follow "Configure blog"
87 87 And I fill in "Address" with "blog-two"
88 88 And I press "Save"
... ... @@ -90,7 +90,7 @@ Feature: blog
90 90 Then I should see "Blog One"
91 91  
92 92 Scenario: display tag list field when creating new blog
93   - Given I follow "Control panel"
  93 + Given I go to the Control panel
94 94 And I follow "Manage Content"
95 95 When I follow "New blog"
96 96 Then I should see "Tag list"
... ...
features/create_community.feature
... ... @@ -11,7 +11,7 @@ Feature: create community
11 11 Scenario: a user creates a community
12 12 Given I am logged in as "joaosilva"
13 13 And feature "admin_must_approve_new_communities" is disabled on environment
14   - And I follow "Control panel"
  14 + And I go to the Control panel
15 15 And I follow "Manage my groups"
16 16 When I follow "Create a new community"
17 17 And I fill in "Name" with "Fancy community"
... ... @@ -21,7 +21,7 @@ Feature: create community
21 21 Scenario: a user creates a community when environment moderates it
22 22 Given I am logged in as "joaosilva"
23 23 And feature "admin_must_approve_new_communities" is enabled on environment
24   - When I follow "Control panel"
  24 + When I go to the Control panel
25 25 And I follow "Manage my groups"
26 26 And I follow "Create a new community"
27 27 And I fill in "Name" with "Community for moderation"
... ... @@ -31,7 +31,7 @@ Feature: create community
31 31 Scenario: a user tries to create a community without a name
32 32 Given I am logged in as "joaosilva"
33 33 And feature "admin_must_approve_new_communities" is disabled on environment
34   - And I follow "Control panel"
  34 + And I go to the Control panel
35 35 And I follow "Manage my groups"
36 36 When I follow "Create a new community"
37 37 And I press "Create"
... ... @@ -41,20 +41,20 @@ Feature: create community
41 41 Given I am logged in as admin
42 42 And feature "admin_must_approve_new_communities" is enabled on environment
43 43 When I create community "Community for approval"
44   - And I follow "Control Panel"
  44 + And I go to the Control panel
45 45 Then I should see "admin_user wants to create community Community for approval"
46 46  
47 47 Scenario: environment admin accepts new community task
48 48 Given I am logged in as admin
49 49 And feature "admin_must_approve_new_communities" is enabled on environment
50 50 When I create community "Community for approval"
51   - And I follow "Control Panel"
  51 + And I go to the Control panel
52 52 And I follow "Process requests"
53 53 And I should see "admin_user wants to create community Community for approval"
54 54 And I choose "Approve"
55 55 When I press "Ok!"
56 56 Then I should not see "admin_user wants to create community Community for approval"
57   - When I follow "Control panel"
  57 + When I go to the Control panel
58 58 And I follow "Manage my groups"
59 59 Then I should see "Community for approval"
60 60  
... ... @@ -62,13 +62,13 @@ Feature: create community
62 62 Given I am logged in as admin
63 63 And feature "admin_must_approve_new_communities" is enabled on environment
64 64 When I create community "Community for approval"
65   - And I follow "Control Panel"
  65 + And I go to the Control panel
66 66 And I follow "Process requests"
67 67 And I should see "admin_user wants to create community Community for approval"
68 68 And I choose "Reject"
69 69 When I press "Ok!"
70 70 Then I should not see "admin_user wants to create community Community for approval"
71   - When I follow "Control panel"
  71 + When I go to the Control panel
72 72 And I follow "Manage my groups"
73 73 Then I should not see "Community for approval"
74 74  
... ... @@ -77,7 +77,7 @@ Feature: create community
77 77 And feature "admin_must_approve_new_communities" is enabled on environment
78 78 When I create community "Community for approval"
79 79 And I approve community "Community for approval"
80   - When I follow "Control panel"
  80 + When I go to the Control panel
81 81 And I follow "Manage my groups"
82 82 Then I should see "Community for approval"
83 83  
... ... @@ -86,7 +86,7 @@ Feature: create community
86 86 And feature "admin_must_approve_new_communities" is enabled on environment
87 87 When I create community "Community for approval"
88 88 And I reject community "Community for approval"
89   - When I follow "Control panel"
  89 + When I go to the Control panel
90 90 And I follow "Manage my groups"
91 91 Then I should not see "Community for approval"
92 92  
... ...
features/edit_article.feature
... ... @@ -31,27 +31,27 @@ Feature: edit article
31 31 And I should be on /joaosilva/my-folder
32 32  
33 33 Scenario: cancel button back to cms
34   - Given I follow "Control panel"
  34 + Given I go to the Control panel
35 35 And I follow "Manage Content"
36 36 And I follow "New Folder"
37   - When I follow "Cancel"
  37 + When I follow "Cancel" within ".main-block"
38 38 Then I should be on Joao Silva's cms
39 39  
40 40 Scenario: display tag list field when creating event
41   - Given I follow "Control panel"
  41 + Given I go to the Control panel
42 42 And I follow "Manage Content"
43 43 And I follow "New article"
44 44 When I follow "Event"
45 45 Then I should see "Tag list"
46 46  
47 47 Scenario: display tag list field when creating folder
48   - Given I follow "Control panel"
  48 + Given I go to the Control panel
49 49 And I follow "Manage Content"
50 50 When I follow "New folder"
51 51 Then I should see "Tag list"
52 52  
53 53 Scenario: create new article with tags
54   - Given I follow "Control panel"
  54 + Given I go to the Control panel
55 55 And I follow "Manage Content"
56 56 And I follow "New article"
57 57 When I follow "Text article with Textile markup language"
... ... @@ -85,7 +85,7 @@ Feature: edit article
85 85 Given I am on Joao Silva's sitemap
86 86 And I follow "Save the whales"
87 87 And I follow "Edit"
88   - When I follow "Cancel"
  88 + When I follow "Cancel" within ".main-block"
89 89 Then I should be on /joaosilva/save-the-whales
90 90  
91 91 Scenario: create an article inside a folder
... ... @@ -111,6 +111,6 @@ Feature: edit article
111 111 Then I should be on /joaosilva/my-folder
112 112 When I follow "New article"
113 113 And I follow "Text article with visual editor"
114   - When I follow "Cancel"
  114 + When I follow "Cancel" within ".no-boxes"
115 115 And I should be on /joaosilva/my-folder
116 116  
... ...
features/http_caching.feature 0 → 100644
... ... @@ -0,0 +1,60 @@
  1 +Feature: HTTP caching
  2 +
  3 + As a sysdamin
  4 + I want Noosfero to provide appropriate cache headers
  5 + So that Varnish can serve content from the cache, everything works faster and everyone is happy
  6 +
  7 + Background:
  8 + Given the following user
  9 + | login | name |
  10 + | joao | João Silva |
  11 +
  12 + Scenario: home page, default configuration
  13 + When I go to the homepage
  14 + Then the response should be valid for 5 minutes
  15 + And the cache should be public
  16 +
  17 + Scenario: home page, custom configuration
  18 + Given the following environment configuration
  19 + | home_cache_in_minutes | 10 |
  20 + When I go to the homepage
  21 + Then the response should be valid for 10 minutes
  22 +
  23 + Scenario: search results, default configuration
  24 + Given I am on the search page
  25 + When I fill in "query" with "anything"
  26 + And I press "Search"
  27 + Then the response should be valid for 15 minutes
  28 +
  29 + Scenario: search results, custom configuration
  30 + Given the following environment configuration
  31 + | general_cache_in_minutes | 90 |
  32 + When I go to the search page
  33 + And I fill in "query" with "anything"
  34 + And I press "Search"
  35 + Then the response should be valid for 90 minutes
  36 +
  37 + Scenario: profile pages, default configuaration
  38 + When I go to João Silva's homepage
  39 + Then the response should be valid for 15 minutes
  40 +
  41 + Scenario: profile pages, custom configuration
  42 + Given the following environment configuration
  43 + | profile_cache_in_minutes | 90 |
  44 + When I go to João Silva's homepage
  45 + Then the response should be valid for 90 minutes
  46 +
  47 + Scenario: account controller should not be cached at all
  48 + When I go to /account/login
  49 + Then there must be no cache at all
  50 +
  51 + Scenario: profile administration
  52 + Given I am logged in as "joao"
  53 + When I go to João Silva's control panel
  54 + Then there must be no cache at all
  55 +
  56 + Scenario: environment administration
  57 + Given I am logged in as admin
  58 + When I go to /admin
  59 + Then there must be no cache at all
  60 +
... ...
features/invitation.feature
... ... @@ -92,32 +92,32 @@ Feature: invitation
92 92 And I fill in "mail_template" with "Follow this link <url>"
93 93 And I press "Invite my friends!"
94 94 When I am logged in as "josesantos"
95   - And I follow "Control Panel"
  95 + And I go to the Control panel
96 96 And I should see "josesilva invites you to join the community 26 Bsslines."
97 97  
98 98 Scenario: noosfero user accepts to join community
99 99 Given I invite email "santos@invalid.br" to join community "26 Bsslines"
100 100 When I am logged in as "josesantos"
101   - And I follow "Control panel"
  101 + And I go to the Control panel
102 102 And I follow "Process requests"
103 103 And I should see "josesilva invites you to join the community 26 Bsslines."
104 104 And I choose "Accept"
105 105 When I press "Ok!"
106 106 Then I should not see "josesilva invites you to join the community 26 Bsslines."
107   - When I follow "Control panel"
  107 + When I go to the Control panel
108 108 And I follow "Manage my groups"
109 109 Then I should see "26 Bsslines"
110 110  
111 111 Scenario: noosfero user rejects to join community
112 112 Given I invite email "santos@invalid.br" to join community "26 Bsslines"
113 113 When I am logged in as "josesantos"
114   - And I follow "Control panel"
  114 + And I go to the Control panel
115 115 And I follow "Process requests"
116 116 And I should see "josesilva invites you to join the community 26 Bsslines."
117 117 And I choose "Reject"
118 118 When I press "Ok!"
119 119 Then I should not see "josesilva invites you to join the community 26 Bsslines."
120   - When I follow "Control panel"
  120 + When I go to the Control panel
121 121 And I follow "Manage my groups"
122 122 Then I should not see "26 Bsslines"
123 123  
... ... @@ -130,31 +130,31 @@ Feature: invitation
130 130 And I fill in "mail_template" with "Follow this link <url>"
131 131 And I press "Invite my friends!"
132 132 When I am logged in as "josesantos"
133   - And I follow "Control Panel"
  133 + And I go to the Control panel
134 134 And I should see "josesilva wants to be your friend."
135 135  
136 136 Scenario: noosfero user accepts to be friend
137 137 Given I invite email "santos@invalid.br" to be my friend
138 138 When I am logged in as "josesantos"
139   - And I follow "Control panel"
  139 + And I go to the Control panel
140 140 And I follow "Process requests"
141 141 And I should see "josesilva wants to be your friend."
142 142 And I choose "Accept"
143 143 When I press "Ok!"
144 144 And I should not see "josesilva wants to be your friend."
145   - When I follow "Control panel"
  145 + When I go to the Control panel
146 146 And I follow "Manage friends"
147 147 Then I should see "josesilva"
148 148  
149 149 Scenario: noosfero user rejects to be friend
150 150 Given I invite email "santos@invalid.br" to be my friend
151 151 When I am logged in as "josesantos"
152   - And I follow "Control panel"
  152 + And I go to the Control panel
153 153 And I follow "Process requests"
154 154 And I should see "josesilva wants to be your friend."
155 155 And I choose "Ignore"
156 156 When I press "Ok!"
157 157 And I should not see "josesilva wants to be your friend."
158   - When I follow "Control panel"
  158 + When I go to the Control panel
159 159 And I follow "Manage friends"
160 160 Then I should not see "josesilva"
... ...
features/join_community.feature
... ... @@ -48,7 +48,7 @@ Feature: join a community
48 48 And I go to Sample Community's homepage
49 49 And I press "Yes"
50 50 And I follow "New user"
51   - And I fill in the following:
  51 + And I fill in the following within ".no-boxes":
52 52 | e-mail | jose@domain.br |
53 53 | Username | joseoliveira |
54 54 | Password | 123456 |
... ...
features/location.feature
... ... @@ -16,7 +16,7 @@ Feature: Location
16 16 | state |
17 17 | city |
18 18 | zip_code |
19   - And I follow "Control panel"
  19 + And I go to the Control panel
20 20 And I follow "Location"
21 21 When I fill in "Address" with "Rua Marechal Floriano, 28"
22 22 And I select "Brazil" from "Country"
... ...
features/organization_custom_fields.feature
... ... @@ -9,7 +9,7 @@ Feature: organization custom fields
9 9 | joaosilva | Joao Silva |
10 10 And I am logged in as "joaosilva"
11 11 And feature "enterprise_registration" is enabled on environment
12   - And I follow "Control panel"
  12 + And I go to the Control panel
13 13  
14 14 Scenario Outline: organization active fields are not displayed on creation
15 15 Given the following <organization> fields are active fields
... ...
features/publish_article.feature
... ... @@ -110,9 +110,11 @@ Feature: publish article
110 110 And I am on Sample Community's control panel
111 111 And I follow "Tasks"
112 112 And I press "Ok!"
113   - And I should not see "The title (article name) is already being used by another article, please use another title."
114   - When I press "Ok!"
115   - Then I should see "The title (article name) is already being used by another article, please use another title."
  113 + And I press "Ok!"
  114 + Then I should see "wants to publish"
  115 + When I fill in "Name for publishing" with "other title"
  116 + And I press "Ok!"
  117 + Then I should not see "wants to publish"
116 118  
117 119 Scenario: ask to publish an article that was deleted before approval
118 120 Given I am logged in as "joaosilva"
... ...
features/register_enterprise.feature
... ... @@ -92,7 +92,7 @@ Feature: register enterprise
92 92 And I press "Next"
93 93 Then I should see "Enterprise registration completed"
94 94 And I am logged in as admin
95   - And I follow "Control panel"
  95 + And I go to the Control panel
96 96 When I follow "Tasks"
97 97 Then I should see /Processing task: Enterprise registration: "My Enterprise"/
98 98 And the first mail is to admin_user@example.com
... ... @@ -118,7 +118,7 @@ Feature: register enterprise
118 118 And I press "Next"
119 119 Then I should see "Enterprise registration completed"
120 120 And I am logged in as admin
121   - And I follow "Control panel"
  121 + And I go to the Control panel
122 122 When I follow "Tasks"
123 123 Then I should see /Processing task: Enterprise registration: "My Enterprise"/
124 124 And the first mail is to admin_user@example.com
... ...
features/session_and_cookies_handling.feature 0 → 100644
... ... @@ -0,0 +1,22 @@
  1 +Feature: session and cookies handling
  2 +
  3 + As a Noosfero system administrator
  4 + I want Noosfero to manage well it usage of sessions and cookies
  5 + So that we can use HTTP caching effectively
  6 +
  7 + Scenario: home page, logged in
  8 + Given the following users
  9 + | login |
  10 + | joaosilva |
  11 + When I am logged in as "joaosilva"
  12 + And I go to the homepage
  13 + Then there must be a cookie "_noosfero_session"
  14 +
  15 + Scenario: home page, not logged in
  16 + When I go to the homepage
  17 + Then there must be no cookies
  18 +
  19 + Scenario: logout
  20 + Given I am logged in as "joao"
  21 + When I go to /logout
  22 + Then there must be a cookie "auth_token"
... ...
features/signup.feature
... ... @@ -7,13 +7,14 @@ Feature: signup
7 7 Given I am on the homepage
8 8 When I follow "Login"
9 9 And I follow "New user"
10   - And I fill in "e-Mail" with "josesilva@example.com"
11   - And I fill in "Username" with "josesilva"
12   - And I fill in "Password" with "secret"
13   - And I fill in "Password confirmation" with "secret"
14   - And I fill in "Name" with "José da Silva"
  10 + And I fill in the following within ".no-boxes":
  11 + | e-Mail | josesilva@example.com |
  12 + | Username | josesilva |
  13 + | Password | secret |
  14 + | Password confirmation | secret |
  15 + | Name | José da Silva |
15 16 And I press "Sign up"
16   - Then I should see "Thanks for signing up!"
  17 + Then I should be logged in as "josesilva"
17 18  
18 19 Scenario: be redirected if user goes to signup page and is logged
19 20 Given the following users
... ...
features/step_definitions/create_community_steps.rb
1 1 Given /^I create community "(.+)"$/ do |community|
2   - click_link('Control panel')
  2 + Given 'I go to the Control panel'
3 3 click_link('Manage my groups')
4 4 click_link('Create a new community')
5 5 fill_in("Name", :with => community)
... ... @@ -8,7 +8,7 @@ end
8 8  
9 9 Given /^I approve community "(.+)"$/ do |community|
10 10 task = CreateCommunity.all.select {|c| c.name == community}.first
11   - click_link('Control Panel')
  11 + Given 'I go to the Control panel'
12 12 click_link('Process requests')
13 13 choose("decision-finish-#{task.id}")
14 14 click_button('OK!')
... ... @@ -16,7 +16,7 @@ end
16 16  
17 17 Given /^I reject community "(.+)"$/ do |community|
18 18 task = CreateCommunity.all.select {|c| c.name == community}.first
19   - click_link('Control Panel')
  19 + Given 'I go to the Control panel'
20 20 click_link('Process requests')
21 21 choose("decision-cancel-#{task.id}")
22 22 click_button('OK!')
... ...
features/step_definitions/custom_webrat_steps.rb
... ... @@ -18,3 +18,15 @@ When /^I select &quot;([^\&quot;]*)&quot;$/ do |value|
18 18 selenium.wait_for_ajax
19 19 end
20 20 end
  21 +
  22 +When /^I fill in the following within "([^\"]*)":$/ do |parent, fields|
  23 + fields.rows_hash.each do |name, value|
  24 + When %{I fill in "#{name}" with "#{value}" within "#{parent}"}
  25 + end
  26 +end
  27 +
  28 +When /^I fill in "([^\"]*)" with "([^\"]*)" within "([^\"]*)"$/ do |field, value, parent|
  29 + within(parent) do |content|
  30 + content.fill_in(field, :with => value)
  31 + end
  32 +end
... ...
features/step_definitions/http_caching_steps.rb 0 → 100644
... ... @@ -0,0 +1,21 @@
  1 +Then /^the response should be valid for (.+) minutes$/ do |n|
  2 + response.headers['Cache-Control'].split(/,\s*/).should include("max-age=#{n.to_i * 60}")
  3 +end
  4 +
  5 +Then /^the cache should be public/ do
  6 + response.headers['Cache-Control'].split(/,\s*/).should include("public")
  7 +end
  8 +
  9 +Then /^there must be no cache at all$/ do
  10 + parts = response.headers['Cache-Control'].split(/,\s*/)
  11 + parts.should include('must-revalidate')
  12 + parts.should include('max-age=0')
  13 +end
  14 +
  15 +Then 'there must be no cookies' do
  16 + cookies.should == {}
  17 +end
  18 +
  19 +Then /^there must be a cookie "(.+)"$/ do |cookie_name|
  20 + cookies.keys.should include(cookie_name)
  21 +end
... ...
features/step_definitions/invitation_steps.rb
... ... @@ -9,7 +9,7 @@ Given /^I invite email &quot;(.+)&quot; to join community &quot;(.+)&quot;$/ do |email, community|
9 9 end
10 10  
11 11 Given /^I invite email "(.+)" to be my friend$/ do |email|
12   - click_link('Control panel')
  12 + Given "I go to the Control panel"
13 13 click_link('Manage friends')
14 14 click_link('Invite people from my e-mail contacts')
15 15 click_button('Next')
... ...
features/step_definitions/noosfero_steps.rb
... ... @@ -231,3 +231,15 @@ Given /^the (.+) mail (.+) is like (.+)$/ do |position, field, regexp|
231 231 re =~ ActionMailer::Base.deliveries.send(position)[field.to_sym]
232 232 end
233 233 end
  234 +
  235 +Given /^the following environment configuration$/ do |table|
  236 + env = Environment.default
  237 + table.raw.each do |item|
  238 + env.send("#{item[0]}=", item[1])
  239 + end
  240 + env.save
  241 +end
  242 +
  243 +Then /^I should be logged in as "(.+)"$/ do |login|
  244 + User.find(session[:user]).login.should == login
  245 +end
... ...
features/support/paths.rb
... ... @@ -42,6 +42,9 @@ module NavigationHelpers
42 42 when /^(.*)'s control panel$/
43 43 '/myprofile/%s' % Profile.find_by_name($1).identifier
44 44  
  45 + when /^the Control panel$/
  46 + '/myprofile/%s' % User.find_by_id(session[:user]).login
  47 +
45 48 when /^the search page$/
46 49 '/search'
47 50  
... ...
features/tags.feature
... ... @@ -22,7 +22,7 @@ Feature: tags
22 22  
23 23 Scenario: viewing a single tag
24 24 When I go to /tag
25   - And I follow "environment"
  25 + And I follow "environment" within ".no-boxes"
26 26 Then I should see "save the whales"
27 27 And I should see "the Amazon is being destroyed"
28 28  
... ...
public/javascripts/application.js
... ... @@ -263,3 +263,27 @@ jQuery(document).ready(function() {
263 263 jQuery('body').click(function() { hideAllSubmenus(); });
264 264 jQuery('.menu-submenu-trigger').click(function(e) { e.stopPropagation(); });
265 265 });
  266 +
  267 +// controls the display of the login/logout stuff
  268 +jQuery(function($) {
  269 + $.getJSON('/account/user_data', function(data) {
  270 + if (data.login) {
  271 + // logged in
  272 + $('#user .logged-in, .login-block .logged-user-info').each(function() {
  273 + $(this).find('a[href]').each(function() {
  274 + $(this).attr('href', $(this).attr('href').replace('%{login}', data.login))
  275 + });
  276 + var html = $(this).html().replace('%{login}', data.login).replace('%{month}', data.since_month).replace('%{year}', data.since_year);
  277 + $(this).html(html).fadeIn();
  278 + });
  279 + } else {
  280 + // not logged in
  281 + $('#user .not-logged-in, .login-block .not-logged-user').fadeIn();
  282 + }
  283 + if (data.notice) {
  284 + var $noticeBox = $('<div id="notice"></div>').html(data.notice).appendTo('body').fadeTo('fast', 0.8);
  285 + $noticeBox.click(function() { $(this).hide(); });
  286 + setTimeout(function() { $noticeBox.fadeOut('fast'); }, 5000);
  287 + }
  288 + });
  289 +});
... ...
public/stylesheets/application.css
... ... @@ -2342,6 +2342,10 @@ div#activation_enterprise div {
2342 2342 margin: auto;
2343 2343 }
2344 2344  
  2345 +.login-block {
  2346 + min-height: 100px;
  2347 +}
  2348 +
2345 2349 .login-block .login-box {
2346 2350 }
2347 2351  
... ...
test/functional/features_controller_test.rb
... ... @@ -36,7 +36,7 @@ class FeaturesControllerTest &lt; Test::Unit::TestCase
36 36 uses_host 'anhetegua.net'
37 37 post :update, :environment => { :enabled_features => [ 'feature1', 'feature2' ] }
38 38 assert_redirected_to :action => 'index'
39   - assert_kind_of String, flash[:notice]
  39 + assert_kind_of String, session[:notice]
40 40 v = Environment.find(environments(:anhetegua_net).id)
41 41 assert v.enabled?('feature2')
42 42 assert v.enabled?('feature2')
... ... @@ -47,7 +47,7 @@ class FeaturesControllerTest &lt; Test::Unit::TestCase
47 47 uses_host 'anhetegua.net'
48 48 post :update # no features
49 49 assert_redirected_to :action => 'index'
50   - assert_kind_of String, flash[:notice]
  50 + assert_kind_of String, session[:notice]
51 51 v = Environment.find(environments(:anhetegua_net).id)
52 52 assert !v.enabled?('feature1')
53 53 assert !v.enabled?('feature2')
... ... @@ -64,7 +64,7 @@ class FeaturesControllerTest &lt; Test::Unit::TestCase
64 64 uses_host 'anhetegua.net'
65 65 post :update, :environment => { :organization_approval_method => 'region' }
66 66 assert_redirected_to :action => 'index'
67   - assert_kind_of String, flash[:notice]
  67 + assert_kind_of String, session[:notice]
68 68 v = Environment.find(environments(:anhetegua_net).id)
69 69 assert_equal :region, v.organization_approval_method
70 70 end
... ...
test/functional/mailconf_controller_test.rb
... ... @@ -112,7 +112,7 @@ class MailconfControllerTest &lt; Test::Unit::TestCase
112 112 should 'display notice after saving' do
113 113 login_as('ze')
114 114 post :enable, :profile => 'ze'
115   - assert_kind_of String, flash[:notice]
  115 + assert_kind_of String, session[:notice]
116 116 end
117 117  
118 118 should 'link back to control panel' do
... ...
test/functional/profile_controller_test.rb
... ... @@ -183,7 +183,7 @@ class ProfileControllerTest &lt; Test::Unit::TestCase
183 183 community = Community.create!(:name => 'my test community')
184 184 community.add_admin(@profile)
185 185 get :index, :profile => community.identifier
186   - assert_tag :tag => 'a', :attributes => { :href => /\/myprofile\/#{@profile.identifier}/ }, :content => 'Control panel'
  186 + assert_tag :tag => 'a', :attributes => { :href => /\/myprofile\/%\{login\}/ }, :content => 'Control panel'
187 187 end
188 188  
189 189 should 'show create community in own profile' do
... ...
test/functional/role_controller_test.rb
... ... @@ -42,7 +42,7 @@ class RoleControllerTest &lt; Test::Unit::TestCase
42 42 Role.any_instance.stubs(:valid?).returns(true)
43 43 post 'create'
44 44 assert !assigns(:role).new_record?
45   - assert_nil flash[:notice]
  45 + assert_nil session[:notice]
46 46 assert_response :redirect
47 47 end
48 48  
... ... @@ -50,7 +50,7 @@ class RoleControllerTest &lt; Test::Unit::TestCase
50 50 Role.any_instance.stubs(:valid?).returns(false)
51 51 post 'create'
52 52 assert assigns(:role).new_record?
53   - assert_not_nil flash[:notice]
  53 + assert_not_nil session[:notice]
54 54 assert_response :success
55 55 end
56 56  
... ... @@ -65,7 +65,7 @@ class RoleControllerTest &lt; Test::Unit::TestCase
65 65 post 'update', :id => @role.id
66 66 assert_response :redirect
67 67 assert_not_nil assigns(:role)
68   - assert_nil flash[:notice]
  68 + assert_nil session[:notice]
69 69 end
70 70  
71 71 def test_should_not_update_to_invalid_paramters
... ... @@ -73,7 +73,7 @@ class RoleControllerTest &lt; Test::Unit::TestCase
73 73 post 'update', :id => @role.id
74 74 assert_response :success
75 75 assert_not_nil assigns(:role)
76   - assert_not_nil flash[:notice]
  76 + assert_not_nil session[:notice]
77 77 end
78 78  
79 79 def test_should_destroy
... ...
test/unit/environment_test.rb
... ... @@ -1005,4 +1005,73 @@ class EnvironmentTest &lt; Test::Unit::TestCase
1005 1005 assert_not_includes env.users, user_from_other_environment
1006 1006 end
1007 1007  
  1008 + should 'provide cache time for home page' do
  1009 + env = Environment.new
  1010 + assert env.respond_to?(:home_cache_in_minutes)
  1011 + end
  1012 +
  1013 + should 'store cache time for home page' do
  1014 + env = Environment.new(:home_cache_in_minutes => 99)
  1015 + assert_equal 99, env.home_cache_in_minutes
  1016 + end
  1017 +
  1018 + should 'retrieve cache time for home page' do
  1019 + env = fast_create(Environment)
  1020 + env.home_cache_in_minutes = 33
  1021 + env.save!
  1022 +
  1023 + assert_equal 33, Environment.find(env.id).home_cache_in_minutes
  1024 + end
  1025 +
  1026 + should 'cache home page for 5 minutes by default' do
  1027 + env = Environment.new
  1028 + assert_equal 5, env.home_cache_in_minutes
  1029 + end
  1030 +
  1031 + should 'provide cache time for general content' do
  1032 + env = Environment.new
  1033 + assert env.respond_to?(:general_cache_in_minutes)
  1034 + end
  1035 +
  1036 + should 'store cache time for general content' do
  1037 + env = Environment.new(:general_cache_in_minutes => 99)
  1038 + assert_equal 99, env.general_cache_in_minutes
  1039 + end
  1040 +
  1041 + should 'retrieve cache time for general content' do
  1042 + env = fast_create(Environment)
  1043 + env.general_cache_in_minutes = 33
  1044 + env.save!
  1045 +
  1046 + assert_equal 33, Environment.find(env.id).general_cache_in_minutes
  1047 + end
  1048 +
  1049 + should 'cache general content for 15 minutes by default' do
  1050 + env = Environment.new
  1051 + assert_equal 15, env.general_cache_in_minutes
  1052 + end
  1053 +
  1054 + should 'provide cache time for profile content' do
  1055 + env = Environment.new
  1056 + assert env.respond_to?(:profile_cache_in_minutes)
  1057 + end
  1058 +
  1059 + should 'store cache time for profile content' do
  1060 + env = Environment.new(:profile_cache_in_minutes => 99)
  1061 + assert_equal 99, env.profile_cache_in_minutes
  1062 + end
  1063 +
  1064 + should 'retrieve cache time for profile content' do
  1065 + env = fast_create(Environment)
  1066 + env.profile_cache_in_minutes = 33
  1067 + env.save!
  1068 +
  1069 + assert_equal 33, Environment.find(env.id).profile_cache_in_minutes
  1070 + end
  1071 +
  1072 + should 'cache profile content for 15 minutes by default' do
  1073 + env = Environment.new
  1074 + assert_equal 15, env.profile_cache_in_minutes
  1075 + end
  1076 +
1008 1077 end
... ...
test/unit/login_block_test.rb
... ... @@ -11,16 +11,4 @@ class LoginBlockTest &lt; Test::Unit::TestCase
11 11 assert_not_equal Block.description, LoginBlock.description
12 12 end
13 13  
14   - should 'point to account/login_block' do
15   - self.expects(:logged_in?).returns(false)
16   - self.expects(:render).with(:file => 'account/login_block')
17   - self.instance_eval(& block.content)
18   - end
19   -
20   - should 'display user_info if not logged' do
21   - self.expects(:logged_in?).returns(true)
22   - self.expects(:render).with(:file => 'account/user_info')
23   - self.instance_eval(& block.content)
24   - end
25   -
26 14 end
... ...
vendor/plugins/noosfero_caching/init.rb 0 → 100644
... ... @@ -0,0 +1,65 @@
  1 +module NoosferoHttpCaching
  2 +
  3 + def self.included(c)
  4 + c.send(:after_filter, :noosfero_set_cache)
  5 + c.send(:before_filter, :noosfero_session_check_before)
  6 + c.send(:after_filter, :noosfero_session_check_after)
  7 + end
  8 +
  9 + def noosfero_set_cache
  10 + n = nil
  11 + if profile
  12 + unless request.path =~ /^\/myprofile/
  13 + n = environment.profile_cache_in_minutes
  14 + end
  15 + else
  16 + if request.path == '/'
  17 + n = environment.home_cache_in_minutes
  18 + else
  19 + if params[:controller] != 'account' && request.path !~ /^\/admin/
  20 + n = environment.general_cache_in_minutes
  21 + end
  22 + end
  23 + end
  24 + if n
  25 + expires_in n.minutes, :private => false, :public => true
  26 + end
  27 + end
  28 +
  29 + def noosfero_session_check_before
  30 + return if params[:controller] == 'account'
  31 + headers["X-Noosfero-Auth"] = (session[:user] != nil).to_s
  32 + end
  33 +
  34 + def noosfero_session_check_after
  35 + if headers['X-Noosfero-Auth'] == 'true'
  36 + # special case: logout
  37 + if !session[:user]
  38 + session.delete
  39 + end
  40 + else
  41 + # special case: login
  42 + if session[:user]
  43 + headers['X-Noosfero-Auth'] = 'true'
  44 + end
  45 + end
  46 + end
  47 +
  48 +end
  49 +
  50 +class ActionController::CgiResponse
  51 +
  52 + def out_with_noosfero_session_check(output = $stdout)
  53 + if headers['X-Noosfero-Auth'] == 'false'
  54 + @cgi.send(:instance_variable_set, '@output_cookies', nil)
  55 + end
  56 + headers.delete('X-Noosfero-Auth')
  57 + out_without_noosfero_session_check(output)
  58 + end
  59 + alias_method_chain :out, :noosfero_session_check
  60 +
  61 +end
  62 +
  63 +if Rails.env != 'development'
  64 + ActionController::Base.send(:include, NoosferoHttpCaching)
  65 +end
... ...