Commit 4d09c0fd4189dd964cdbabb9a9d4f104668ee063

Authored by Leandro Santos
2 parents 24ead125 1af9c045
Exists in staging and in 1 other branch production

Merge branch 'master' into staging

Showing 35 changed files with 584 additions and 464 deletions   Show diff stats
app/api/v1/profiles.rb
@@ -22,6 +22,15 @@ module Api @@ -22,6 +22,15 @@ module Api
22 not_found! 22 not_found!
23 end 23 end
24 end 24 end
  25 +
  26 + desc "Update profile information"
  27 + post ':id' do
  28 + authenticate!
  29 + profile = environment.profiles.find_by(id: params[:id])
  30 + return forbidden! unless current_person.has_permission?(:edit_profile, profile)
  31 + profile.update_attributes!(params[:profile])
  32 + present profile, :with => Entities::Profile, :current_person => current_person
  33 + end
25 34
26 delete ':id' do 35 delete ':id' do
27 authenticate! 36 authenticate!
app/concerns/authenticated_system.rb 0 → 100644
@@ -0,0 +1,160 @@ @@ -0,0 +1,160 @@
  1 +module AuthenticatedSystem
  2 +
  3 + protected
  4 +
  5 + def self.included base
  6 + if base < ActionController::Base
  7 + base.around_filter :user_set_current
  8 + base.before_filter :login_from_cookie
  9 + end
  10 +
  11 + # Inclusion hook to make #current_user and #logged_in?
  12 + # available as ActionView helper methods.
  13 + base.helper_method :current_user, :logged_in?
  14 + end
  15 +
  16 + # Returns true or false if the user is logged in.
  17 + # Preloads @current_user with the user model if they're logged in.
  18 + def logged_in?
  19 + current_user != nil
  20 + end
  21 +
  22 + # Accesses the current user from the session.
  23 + def current_user
  24 + @current_user ||= begin
  25 + id = session[:user]
  26 + user = User.where(id: id).first if id
  27 + user.session = session if user
  28 + User.current = user
  29 + user
  30 + end
  31 + end
  32 +
  33 + # Store the given user in the session.
  34 + def current_user=(new_user)
  35 + if new_user.nil?
  36 + session.delete(:user)
  37 + else
  38 + session[:user] = new_user.id
  39 + new_user.session = session
  40 + new_user.register_login
  41 + end
  42 + @current_user = User.current = new_user
  43 + end
  44 +
  45 + # See impl. from http://stackoverflow.com/a/2513456/670229
  46 + def user_set_current
  47 + User.current = current_user
  48 + yield
  49 + ensure
  50 + # to address the thread variable leak issues in Puma/Thin webserver
  51 + User.current = nil
  52 + end
  53 +
  54 + # Check if the user is authorized.
  55 + #
  56 + # Override this method in your controllers if you want to restrict access
  57 + # to only a few actions or if you want to check if the user
  58 + # has the correct rights.
  59 + #
  60 + # Example:
  61 + #
  62 + # # only allow nonbobs
  63 + # def authorize?
  64 + # current_user.login != "bob"
  65 + # end
  66 + def authorized?
  67 + true
  68 + end
  69 +
  70 + # Filter method to enforce a login requirement.
  71 + #
  72 + # To require logins for all actions, use this in your controllers:
  73 + #
  74 + # before_filter :login_required
  75 + #
  76 + # To require logins for specific actions, use this in your controllers:
  77 + #
  78 + # before_filter :login_required, :only => [ :edit, :update ]
  79 + #
  80 + # To skip this in a subclassed controller:
  81 + #
  82 + # skip_before_filter :login_required
  83 + #
  84 + def login_required
  85 + username, passwd = get_auth_data
  86 + if username && passwd
  87 + self.current_user ||= User.authenticate(username, passwd) || nil
  88 + end
  89 + if logged_in? && authorized?
  90 + true
  91 + else
  92 + if params[:require_login_popup]
  93 + render :json => { :require_login_popup => true }
  94 + else
  95 + access_denied
  96 + end
  97 + end
  98 + end
  99 +
  100 + # Redirect as appropriate when an access request fails.
  101 + #
  102 + # The default action is to redirect to the login screen.
  103 + #
  104 + # Override this method in your controllers if you want to have special
  105 + # behavior in case the user is not authorized
  106 + # to access the requested action. For example, a popup window might
  107 + # simply close itself.
  108 + def access_denied
  109 + respond_to do |accepts|
  110 + accepts.html do
  111 + if request.xhr?
  112 + render :text => _('Access denied'), :status => 401
  113 + else
  114 + store_location
  115 + redirect_to :controller => '/account', :action => 'login'
  116 + end
  117 + end
  118 + accepts.xml do
  119 + headers["Status"] = "Unauthorized"
  120 + headers["WWW-Authenticate"] = %(Basic realm="Web Password")
  121 + render :text => "Could't authenticate you", :status => '401 Unauthorized'
  122 + end
  123 + end
  124 + false
  125 + end
  126 +
  127 + # Store the URI of the current request in the session.
  128 + #
  129 + # We can return to this location by calling #redirect_back_or_default.
  130 + def store_location(location = request.url)
  131 + session[:return_to] = location
  132 + end
  133 +
  134 + # Redirect to the URI stored by the most recent store_location call or
  135 + # to the passed default.
  136 + def redirect_back_or_default(default)
  137 + if session[:return_to]
  138 + redirect_to(session.delete(:return_to))
  139 + else
  140 + redirect_to(default)
  141 + end
  142 + end
  143 +
  144 + # When called with before_filter :login_from_cookie will check for an :auth_token
  145 + # cookie and log the user back in if apropriate
  146 + def login_from_cookie
  147 + return if cookies[:auth_token].blank? or logged_in?
  148 + user = User.where(remember_token: cookies[:auth_token]).first
  149 + self.current_user = user if user and user.remember_token?
  150 + end
  151 +
  152 + private
  153 + @@http_auth_headers = %w(X-HTTP_AUTHORIZATION HTTP_AUTHORIZATION Authorization)
  154 + # gets BASIC auth info
  155 + def get_auth_data
  156 + auth_key = @@http_auth_headers.detect { |h| request.env.has_key?(h) }
  157 + auth_data = request.env[auth_key].to_s.split unless auth_key.blank?
  158 + return auth_data && auth_data[0] == 'Basic' ? Base64.decode64(auth_data[1]).split(':')[0..1] : [nil, nil]
  159 + end
  160 +end
app/controllers/application_controller.rb
@@ -18,6 +18,13 @@ class ApplicationController &lt; ActionController::Base @@ -18,6 +18,13 @@ class ApplicationController &lt; ActionController::Base
18 end 18 end
19 before_filter :redirect_to_current_user 19 before_filter :redirect_to_current_user
20 20
  21 + before_filter :set_session_theme
  22 + def set_session_theme
  23 + if params[:theme]
  24 + session[:theme] = environment.theme_ids.include?(params[:theme]) ? params[:theme] : nil
  25 + end
  26 + end
  27 +
21 def require_login_for_environment 28 def require_login_for_environment
22 login_required 29 login_required
23 end 30 end
app/controllers/my_profile/profile_themes_controller.rb
@@ -63,12 +63,12 @@ class ProfileThemesController &lt; ThemesController @@ -63,12 +63,12 @@ class ProfileThemesController &lt; ThemesController
63 end 63 end
64 64
65 def start_test 65 def start_test
66 - session[:theme] = params[:id] 66 + session[:user_theme] = params[:id]
67 redirect_to :controller => 'content_viewer', :profile => profile.identifier, :action => 'view_page' 67 redirect_to :controller => 'content_viewer', :profile => profile.identifier, :action => 'view_page'
68 end 68 end
69 69
70 def stop_test 70 def stop_test
71 - session[:theme] = nil 71 + session[:user_theme] = nil
72 redirect_to :action => 'index' 72 redirect_to :action => 'index'
73 end 73 end
74 74
app/helpers/application_helper.rb
@@ -346,7 +346,7 @@ module ApplicationHelper @@ -346,7 +346,7 @@ module ApplicationHelper
346 end 346 end
347 347
348 def is_testing_theme 348 def is_testing_theme
349 - !controller.session[:theme].nil? 349 + !controller.session[:user_theme].nil?
350 end 350 end
351 351
352 def theme_owner 352 def theme_owner
@@ -595,8 +595,8 @@ module ApplicationHelper @@ -595,8 +595,8 @@ module ApplicationHelper
595 end 595 end
596 596
597 if block 597 if block
598 - field_html ||= ''  
599 - field_html += capture(&block) 598 + field_html ||= ''.html_safe
  599 + field_html = [field_html, capture(&block)].safe_join
600 end 600 end
601 601
602 if controller.action_name == 'signup' || controller.action_name == 'new_community' || (controller.controller_name == "enterprise_registration" && controller.action_name == 'index') || (controller.controller_name == 'home' && controller.action_name == 'index' && user.nil?) 602 if controller.action_name == 'signup' || controller.action_name == 'new_community' || (controller.controller_name == "enterprise_registration" && controller.action_name == 'index') || (controller.controller_name == 'home' && controller.action_name == 'index' && user.nil?)
@@ -605,7 +605,9 @@ module ApplicationHelper @@ -605,7 +605,9 @@ module ApplicationHelper
605 end 605 end
606 else 606 else
607 if profile.active_fields.include?(name) 607 if profile.active_fields.include?(name)
608 - result = content_tag('div', field_html + profile_field_privacy_selector(profile, name), :class => 'field-with-privacy-selector') 608 + result = content_tag :div, class: 'field-with-privacy-selector' do
  609 + [field_html, profile_field_privacy_selector(profile, name)].safe_join
  610 + end
609 end 611 end
610 end 612 end
611 613
@@ -613,10 +615,6 @@ module ApplicationHelper @@ -613,10 +615,6 @@ module ApplicationHelper
613 result = required(result) 615 result = required(result)
614 end 616 end
615 617
616 - if block  
617 - concat(result)  
618 - end  
619 -  
620 result 618 result
621 end 619 end
622 620
@@ -983,6 +981,7 @@ module ApplicationHelper @@ -983,6 +981,7 @@ module ApplicationHelper
983 values = {} 981 values = {}
984 values.merge!(task.information[:variables]) if task.information[:variables] 982 values.merge!(task.information[:variables]) if task.information[:variables]
985 values.merge!({:requestor => link_to(task.requestor.name, task.requestor.url)}) if task.requestor 983 values.merge!({:requestor => link_to(task.requestor.name, task.requestor.url)}) if task.requestor
  984 + values.merge!({:target => link_to(task.target.name, task.target.url)}) if (task.target && task.target.respond_to?(:url))
986 values.merge!({:subject => content_tag('span', task.subject, :class=>'task_target')}) if task.subject 985 values.merge!({:subject => content_tag('span', task.subject, :class=>'task_target')}) if task.subject
987 values.merge!({:linked_subject => link_to(content_tag('span', task.linked_subject[:text], :class => 'task_target'), task.linked_subject[:url])}) if task.linked_subject 986 values.merge!({:linked_subject => link_to(content_tag('span', task.linked_subject[:text], :class => 'task_target'), task.linked_subject[:url])}) if task.linked_subject
988 (task.information[:message] % values).html_safe 987 (task.information[:message] % values).html_safe
app/helpers/article_helper.rb
@@ -188,9 +188,9 @@ module ArticleHelper @@ -188,9 +188,9 @@ module ArticleHelper
188 def following_button(page, user) 188 def following_button(page, user)
189 if !user.blank? and user != page.author 189 if !user.blank? and user != page.author
190 if page.is_followed_by? user 190 if page.is_followed_by? user
191 - button :cancel, unfollow_button_text(page), {:controller => 'profile', :profile => page.profile.identifier, :action => 'unfollow_article', :article_id => page.id, :profile => page.profile.identifier} 191 + button :cancel, unfollow_button_text(page), {controller: :profile, profile: page.profile.identifier, action: :unfollow_article, article_id: page.id}
192 else 192 else
193 - button :add, follow_button_text(page), {:controller => 'profile', :profile => page.profile.identifier, :action => 'follow_article', :article_id => page.id, :profile => page.profile.identifier} 193 + button :add, follow_button_text(page), {controller: :profile, profile: page.profile.identifier, action: :follow_article, article_id: page.id}
194 end 194 end
195 end 195 end
196 end 196 end
app/helpers/theme_loader_helper.rb
@@ -2,8 +2,8 @@ module ThemeLoaderHelper @@ -2,8 +2,8 @@ module ThemeLoaderHelper
2 def current_theme 2 def current_theme
3 @current_theme ||= 3 @current_theme ||=
4 begin 4 begin
5 - if session[:theme]  
6 - session[:theme] 5 + if session[:user_theme]
  6 + session[:user_theme]
7 else 7 else
8 # utility for developers: set the theme to 'random' in development mode and 8 # utility for developers: set the theme to 'random' in development mode and
9 # you will get a different theme every request. This is interesting for 9 # you will get a different theme every request. This is interesting for
@@ -11,8 +11,8 @@ module ThemeLoaderHelper @@ -11,8 +11,8 @@ module ThemeLoaderHelper
11 if Rails.env.development? && environment.theme == 'random' 11 if Rails.env.development? && environment.theme == 'random'
12 @random_theme ||= Dir.glob('public/designs/themes/*').map { |f| File.basename(f) }.rand 12 @random_theme ||= Dir.glob('public/designs/themes/*').map { |f| File.basename(f) }.rand
13 @random_theme 13 @random_theme
14 - elsif Rails.env.development? && respond_to?(:params) && params[:theme] && File.exists?(Rails.root.join('public/designs/themes', params[:theme]))  
15 - params[:theme] 14 + elsif Rails.env.development? && respond_to?(:params) && params[:user_theme] && File.exists?(Rails.root.join('public/designs/themes', params[:user_theme]))
  15 + params[:user_theme]
16 else 16 else
17 if profile && !profile.theme.nil? 17 if profile && !profile.theme.nil?
18 profile.theme 18 profile.theme
@@ -34,8 +34,10 @@ module ThemeLoaderHelper @@ -34,8 +34,10 @@ module ThemeLoaderHelper
34 end 34 end
35 35
36 def theme_path 36 def theme_path
37 - if session[:theme] 37 + if session[:user_theme]
38 '/user_themes/' + current_theme 38 '/user_themes/' + current_theme
  39 + elsif session[:theme]
  40 + '/designs/themes/' + session[:theme]
39 else 41 else
40 '/designs/themes/' + current_theme 42 '/designs/themes/' + current_theme
41 end 43 end
app/models/add_member.rb
@@ -37,6 +37,10 @@ class AddMember &lt; Task @@ -37,6 +37,10 @@ class AddMember &lt; Task
37 true 37 true
38 end 38 end
39 39
  40 + def reject_details
  41 + true
  42 + end
  43 +
40 def footer 44 def footer
41 true 45 true
42 end 46 end
@@ -72,8 +76,9 @@ class AddMember &lt; Task @@ -72,8 +76,9 @@ class AddMember &lt; Task
72 end 76 end
73 77
74 def task_cancelled_message 78 def task_cancelled_message
75 - _("Your request to enter community \"%{target} with the profile \"%{requestor}\" was not accepted. Please contact any profile admin from %{url} for more information.") %  
76 - {:target => self.target.name, :url => self.target.url,  
77 - :requestor => self.requestor.name} 79 + _("Your request to enter community \"%{target}\" with the profile \"%{requestor}\" was not accepted. Please contact any profile admin from %{target} for more information. The following explanation was given: \n\n\"%{explanation}\"") %
  80 + {:target => self.target.name,
  81 + :requestor => self.requestor.name,
  82 + :explanation => self.reject_explanation}
78 end 83 end
79 end 84 end
app/models/environment.rb
@@ -750,6 +750,10 @@ class Environment &lt; ApplicationRecord @@ -750,6 +750,10 @@ class Environment &lt; ApplicationRecord
750 end 750 end
751 end 751 end
752 752
  753 + def theme_ids
  754 + settings[:themes] || []
  755 + end
  756 +
753 def themes=(values) 757 def themes=(values)
754 settings[:themes] = values 758 settings[:themes] = values
755 end 759 end
app/models/person_notifier.rb
@@ -82,7 +82,7 @@ class PersonNotifier @@ -82,7 +82,7 @@ class PersonNotifier
82 helper ActionTrackerHelper 82 helper ActionTrackerHelper
83 83
84 def session 84 def session
85 - {:theme => nil} 85 + {:user_theme => nil}
86 end 86 end
87 87
88 def content_summary(person, notifications, tasks) 88 def content_summary(person, notifications, tasks)
config/application.rb
@@ -40,7 +40,6 @@ module Noosfero @@ -40,7 +40,6 @@ module Noosfero
40 # Custom directories with classes and modules you want to be autoloadable. 40 # Custom directories with classes and modules you want to be autoloadable.
41 config.autoload_paths << config.root.join('lib') 41 config.autoload_paths << config.root.join('lib')
42 config.autoload_paths << config.root.join('app') 42 config.autoload_paths << config.root.join('app')
43 - config.autoload_paths << config.root.join('app/jobs')  
44 config.autoload_paths << config.root.join('app/sweepers') 43 config.autoload_paths << config.root.join('app/sweepers')
45 config.autoload_paths.concat Dir["#{config.root}/app/controllers/**/"] 44 config.autoload_paths.concat Dir["#{config.root}/app/controllers/**/"]
46 config.autoload_paths << config.root.join('test', 'mocks', Rails.env) 45 config.autoload_paths << config.root.join('test', 'mocks', Rails.env)
lib/authenticated_system.rb
@@ -1,160 +0,0 @@ @@ -1,160 +0,0 @@
1 -module AuthenticatedSystem  
2 -  
3 - protected  
4 -  
5 - def self.included base  
6 - if base < ActionController::Base  
7 - base.around_filter :user_set_current  
8 - base.before_filter :login_from_cookie  
9 - end  
10 -  
11 - # Inclusion hook to make #current_user and #logged_in?  
12 - # available as ActionView helper methods.  
13 - base.helper_method :current_user, :logged_in?  
14 - end  
15 -  
16 - # Returns true or false if the user is logged in.  
17 - # Preloads @current_user with the user model if they're logged in.  
18 - def logged_in?  
19 - current_user != nil  
20 - end  
21 -  
22 - # Accesses the current user from the session.  
23 - def current_user  
24 - @current_user ||= begin  
25 - id = session[:user]  
26 - user = User.where(id: id).first if id  
27 - user.session = session if user  
28 - User.current = user  
29 - user  
30 - end  
31 - end  
32 -  
33 - # Store the given user in the session.  
34 - def current_user=(new_user)  
35 - if new_user.nil?  
36 - session.delete(:user)  
37 - else  
38 - session[:user] = new_user.id  
39 - new_user.session = session  
40 - new_user.register_login  
41 - end  
42 - @current_user = User.current = new_user  
43 - end  
44 -  
45 - # See impl. from http://stackoverflow.com/a/2513456/670229  
46 - def user_set_current  
47 - User.current = current_user  
48 - yield  
49 - ensure  
50 - # to address the thread variable leak issues in Puma/Thin webserver  
51 - User.current = nil  
52 - end  
53 -  
54 - # Check if the user is authorized.  
55 - #  
56 - # Override this method in your controllers if you want to restrict access  
57 - # to only a few actions or if you want to check if the user  
58 - # has the correct rights.  
59 - #  
60 - # Example:  
61 - #  
62 - # # only allow nonbobs  
63 - # def authorize?  
64 - # current_user.login != "bob"  
65 - # end  
66 - def authorized?  
67 - true  
68 - end  
69 -  
70 - # Filter method to enforce a login requirement.  
71 - #  
72 - # To require logins for all actions, use this in your controllers:  
73 - #  
74 - # before_filter :login_required  
75 - #  
76 - # To require logins for specific actions, use this in your controllers:  
77 - #  
78 - # before_filter :login_required, :only => [ :edit, :update ]  
79 - #  
80 - # To skip this in a subclassed controller:  
81 - #  
82 - # skip_before_filter :login_required  
83 - #  
84 - def login_required  
85 - username, passwd = get_auth_data  
86 - if username && passwd  
87 - self.current_user ||= User.authenticate(username, passwd) || nil  
88 - end  
89 - if logged_in? && authorized?  
90 - true  
91 - else  
92 - if params[:require_login_popup]  
93 - render :json => { :require_login_popup => true }  
94 - else  
95 - access_denied  
96 - end  
97 - end  
98 - end  
99 -  
100 - # Redirect as appropriate when an access request fails.  
101 - #  
102 - # The default action is to redirect to the login screen.  
103 - #  
104 - # Override this method in your controllers if you want to have special  
105 - # behavior in case the user is not authorized  
106 - # to access the requested action. For example, a popup window might  
107 - # simply close itself.  
108 - def access_denied  
109 - respond_to do |accepts|  
110 - accepts.html do  
111 - if request.xhr?  
112 - render :text => _('Access denied'), :status => 401  
113 - else  
114 - store_location  
115 - redirect_to :controller => '/account', :action => 'login'  
116 - end  
117 - end  
118 - accepts.xml do  
119 - headers["Status"] = "Unauthorized"  
120 - headers["WWW-Authenticate"] = %(Basic realm="Web Password")  
121 - render :text => "Could't authenticate you", :status => '401 Unauthorized'  
122 - end  
123 - end  
124 - false  
125 - end  
126 -  
127 - # Store the URI of the current request in the session.  
128 - #  
129 - # We can return to this location by calling #redirect_back_or_default.  
130 - def store_location(location = request.url)  
131 - session[:return_to] = location  
132 - end  
133 -  
134 - # Redirect to the URI stored by the most recent store_location call or  
135 - # to the passed default.  
136 - def redirect_back_or_default(default)  
137 - if session[:return_to]  
138 - redirect_to(session.delete(:return_to))  
139 - else  
140 - redirect_to(default)  
141 - end  
142 - end  
143 -  
144 - # When called with before_filter :login_from_cookie will check for an :auth_token  
145 - # cookie and log the user back in if apropriate  
146 - def login_from_cookie  
147 - return if cookies[:auth_token].blank? or logged_in?  
148 - user = User.where(remember_token: cookies[:auth_token]).first  
149 - self.current_user = user if user and user.remember_token?  
150 - end  
151 -  
152 - private  
153 - @@http_auth_headers = %w(X-HTTP_AUTHORIZATION HTTP_AUTHORIZATION Authorization)  
154 - # gets BASIC auth info  
155 - def get_auth_data  
156 - auth_key = @@http_auth_headers.detect { |h| request.env.has_key?(h) }  
157 - auth_data = request.env[auth_key].to_s.split unless auth_key.blank?  
158 - return auth_data && auth_data[0] == 'Basic' ? Base64.decode64(auth_data[1]).split(':')[0..1] : [nil, nil]  
159 - end  
160 -end  
plugins/analytics/views/analytics_plugin/_body_ending.html.slim
1 javascript: 1 javascript:
2 - analytics.timeOnPage.baseUrl = #{url_for(controller: 'analytics_plugin/time_on_page').to_json} 2 + analytics.timeOnPage.baseUrl = #{url_for(profile: profile.identifier, controller: 'analytics_plugin/time_on_page').to_json}
3 analytics.timeOnPage.updateInterval = #{AnalyticsPlugin::TimeOnPageUpdateIntervalMs.to_json} 3 analytics.timeOnPage.updateInterval = #{AnalyticsPlugin::TimeOnPageUpdateIntervalMs.to_json}
4 analytics.requestId = #{request.env['action_dispatch.request_id'].to_json} 4 analytics.requestId = #{request.env['action_dispatch.request_id'].to_json}
5 analytics.init() 5 analytics.init()
plugins/metadata/lib/metadata_plugin/base.rb
1 -  
2 class MetadataPlugin::Base < Noosfero::Plugin 1 class MetadataPlugin::Base < Noosfero::Plugin
3 2
4 def self.plugin_name 3 def self.plugin_name
@@ -71,6 +70,6 @@ end @@ -71,6 +70,6 @@ end
71 70
72 ActiveSupport.run_load_hooks :metadata_plugin, MetadataPlugin 71 ActiveSupport.run_load_hooks :metadata_plugin, MetadataPlugin
73 ActiveSupport.on_load :active_record do 72 ActiveSupport.on_load :active_record do
74 - ApplicationRecord.extend MetadataPlugin::Specs::ClassMethods 73 + ActiveRecord::Base.extend MetadataPlugin::Specs::ClassMethods
75 end 74 end
76 75
plugins/products/test/unit/profile_test.rb
@@ -22,9 +22,8 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -22,9 +22,8 @@ class ProfileTest &lt; ActiveSupport::TestCase
22 end 22 end
23 23
24 should 'collect the highlighted products with image' do 24 should 'collect the highlighted products with image' do
25 - env = Environment.default  
26 e1 = fast_create(Enterprise) 25 e1 = fast_create(Enterprise)
27 - p1 = create(Product, name: 'test_prod1', product_category_id: @product_category.id, enterprise: e1) 26 + create(Product, name: 'test_prod1', product_category_id: @product_category.id, enterprise: e1)
28 products = [] 27 products = []
29 3.times {|n| 28 3.times {|n|
30 products.push(create(Product, name: "product #{n}", profile_id: e1.id, 29 products.push(create(Product, name: "product #{n}", profile_id: e1.id,
@@ -36,7 +35,8 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -36,7 +35,8 @@ class ProfileTest &lt; ActiveSupport::TestCase
36 create(Product, name: "product 5", profile_id: e1.id, product_category_id: @product_category.id, image_builder: { 35 create(Product, name: "product 5", profile_id: e1.id, product_category_id: @product_category.id, image_builder: {
37 uploaded_data: fixture_file_upload('/files/rails.png', 'image/png') 36 uploaded_data: fixture_file_upload('/files/rails.png', 'image/png')
38 }) 37 })
39 - assert_equal products, e1.highlighted_products_with_image 38 +
  39 + assert_equivalent products, e1.highlighted_products_with_image
40 end 40 end
41 41
42 should 'have many inputs through products' do 42 should 'have many inputs through products' do
plugins/products/views/profile_editor/_products_profile_info_contents.html.slim 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +- if profile.enterprise?
  2 + h2= _('Products/Services catalog')
  3 + = labelled_form_field(_('Number of products/services displayed per page on catalog'), text_field(:profile_data, :products_per_catalog_page, size: 3))
plugins/products/views/profile_editor/products_profile_info_contents.html.slim
@@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
1 -- if profile.enterprise?  
2 - h2= _('Products/Services catalog')  
3 - = labelled_form_field(_('Number of products/services displayed per page on catalog'), text_field(:profile_data, :products_per_catalog_page, size: 3))  
plugins/responsive/lib/ext/application_helper.rb
@@ -5,7 +5,7 @@ module ApplicationHelper @@ -5,7 +5,7 @@ module ApplicationHelper
5 protected 5 protected
6 6
7 module ResponsiveMethods 7 module ResponsiveMethods
8 - FORM_CONTROL_CLASS = "form-control" 8 + FORM_CONTROL_CLASS = 'form-control'
9 9
10 def button(type, label, url, html_options = {}) 10 def button(type, label, url, html_options = {})
11 return super unless theme_responsive? 11 return super unless theme_responsive?
@@ -13,15 +13,14 @@ module ApplicationHelper @@ -13,15 +13,14 @@ module ApplicationHelper
13 option = html_options.delete(:option) || 'default' 13 option = html_options.delete(:option) || 'default'
14 size = html_options.delete(:size) || 'xs' 14 size = html_options.delete(:size) || 'xs'
15 the_class = "with-text btn btn-#{size} btn-#{option} icon-#{type}" 15 the_class = "with-text btn btn-#{size} btn-#{option} icon-#{type}"
16 - if html_options.has_key?(:class)  
17 - the_class << ' ' << html_options[:class]  
18 - end  
19 - #button_without_text type, label, url, html_options.merge(:class => the_class) 16 + the_class << ' ' << html_options[:class] if html_options.has_key?(:class)
  17 +
  18 + #button_without_text type, label, url, html_options.merge(class: the_class)
20 the_title = html_options[:title] || label 19 the_title = html_options[:title] || label
21 if html_options[:disabled] 20 if html_options[:disabled]
22 - content_tag('a', content_tag('span', label), html_options.merge(class: the_class, title: the_title)) 21 + content_tag(:a, content_tag(:span, label), html_options.merge(class: the_class, title: the_title))
23 else 22 else
24 - link_to(content_tag('span', label), url, html_options.merge(class: the_class, title: the_title)) 23 + link_to(content_tag(:span, label), url, html_options.merge(class: the_class, title: the_title))
25 end 24 end
26 end 25 end
27 26
@@ -36,7 +35,7 @@ module ApplicationHelper @@ -36,7 +35,7 @@ module ApplicationHelper
36 end 35 end
37 the_title = html_options[:title] || label 36 the_title = html_options[:title] || label
38 if html_options[:disabled] 37 if html_options[:disabled]
39 - content_tag('a', '', html_options.merge(class: the_class, title: the_title)) 38 + content_tag(:a, '', html_options.merge(class: the_class, title: the_title))
40 else 39 else
41 link_to('', url, html_options.merge(class: the_class, title: the_title)) 40 link_to('', url, html_options.merge(class: the_class, title: the_title))
42 end 41 end
@@ -91,7 +90,7 @@ module ApplicationHelper @@ -91,7 +90,7 @@ module ApplicationHelper
91 if html_options.has_key?(:class) 90 if html_options.has_key?(:class)
92 the_class << ' ' << html_options[:class] 91 the_class << ' ' << html_options[:class]
93 end 92 end
94 - content_tag('div', '', html_options.merge(class: the_class)) 93 + content_tag(:div, '', html_options.merge(class: the_class))
95 end 94 end
96 95
97 def icon_button(type, text, url, html_options = {}) 96 def icon_button(type, text, url, html_options = {})
@@ -104,16 +103,21 @@ module ApplicationHelper @@ -104,16 +103,21 @@ module ApplicationHelper
104 the_class << ' ' << html_options[:class] 103 the_class << ' ' << html_options[:class]
105 end 104 end
106 105
107 - link_to(content_tag('span', text), url, html_options.merge(class: the_class, title: text)) 106 + link_to(content_tag(:span, text), url, html_options.merge(class: the_class, title: text))
108 end 107 end
109 108
110 - def button_bar(options = {}, &block) 109 + def button_bar options = {}, &block
111 return super unless theme_responsive? 110 return super unless theme_responsive?
112 111
113 - options[:class].nil? ?  
114 - options[:class]='button-bar' :  
115 - options[:class]+=' button-bar'  
116 - concat(content_tag('div', capture(&block).to_s + tag('br', style: 'clear: left;'), options)) 112 + options[:class] ||= ''
  113 + options[:class] << 'button-bar'
  114 +
  115 + content_tag :div, options do
  116 + [
  117 + capture(&block).to_s,
  118 + tag('br', style: 'clear: left;'),
  119 + ].safe_join
  120 + end
117 end 121 end
118 122
119 def expirable_button(content, action, text, url, html_options = {}) 123 def expirable_button(content, action, text, url, html_options = {})
@@ -128,143 +132,93 @@ module ApplicationHelper @@ -128,143 +132,93 @@ module ApplicationHelper
128 def search_contents_menu 132 def search_contents_menu
129 return super unless theme_responsive? 133 return super unless theme_responsive?
130 134
131 - host = environment.default_hostname  
132 -  
133 - output = '<li class="dropdown">'  
134 - output += link_to(_('Contents'), '#', :class=>"dropdown-toggle icon-menu-articles", title: _('Contents'), :'data-toggle'=>"dropdown", :'data-hover'=>"dropdown")  
135 - output += '<ul class="dropdown-menu" role="menu">'  
136 -  
137 - output += '<li>' + link_to(_('All contents'), {host: host, controller: "search", action: 'contents', category_path: ''}) + '</li>'  
138 - 135 + host = environment.default_hostname
139 links = [ 136 links = [
140 - {s_('contents|More recent') => {:href => url_for({host: host, :controller => 'search', :action => 'contents', :filter => 'more_recent'})}},  
141 - {s_('contents|More viewed') => {:href => url_for({host: host, :controller => 'search', :action => 'contents', :filter => 'more_popular'})}},  
142 - {s_('contents|Most commented') => {:href => url_for({host: host, :controller => 'search', :action => 'contents', :filter => 'more_comments'})}} 137 + [_('All contents'), {host: host, controller: :search, action: :contents, category_path: ''}],
  138 + [s_('contents|More recent'), {host: host, controller: :search, action: :contents, filter: 'more_recent'}],
  139 + [s_('contents|More viewed'), {host: host, controller: :search, action: :contents, filter: 'more_popular'}],
  140 + [s_('contents|Most commented'), {host: host, controller: :search, action: :contents, filter: 'more_comments'}],
143 ] 141 ]
144 if logged_in? 142 if logged_in?
145 - links.push(_('New content') => modal_options({href: url_for({controller: 'cms', action: 'new', profile: current_user.login, cms: true})})) 143 + links.push [_('New content'), '', modal_options({href: url_for({controller: 'cms', action: 'new', profile: current_user.login, cms: true})})]
146 end 144 end
147 145
148 - links.each do |link|  
149 - link.each do |name, options|  
150 - output += content_tag(:li,content_tag(:a,name,options))  
151 - end 146 + content_tag :li, class: 'dropdown' do
  147 + [
  148 + link_to('#', class: 'dropdown-toggle icon-menu-articles', title: _('Contents'), data: {toggle: 'dropdown', hover: 'dropdown'}) do
  149 + content_tag :span, _('Contents')
  150 + end,
  151 + content_tag(:ul, class: 'dropdown-menu', role: 'menu') do
  152 + links.map do |(name, url)|
  153 + content_tag :li do
  154 + link_to name, url
  155 + end
  156 + end.safe_join
  157 + end,
  158 + ].safe_join
152 end 159 end
153 -  
154 - output += '</ul>'  
155 - output += '</li>'  
156 - output  
157 end 160 end
158 161
159 def search_people_menu 162 def search_people_menu
160 return super unless theme_responsive? 163 return super unless theme_responsive?
161 164
162 - host = environment.default_hostname  
163 -  
164 - output = '<li class="dropdown">'  
165 - output += link_to(_('People'), '#', :class=>"dropdown-toggle icon-menu-people", title: _('People'), :'data-toggle'=>"dropdown", :'data-hover'=>"dropdown")  
166 - output += '<ul class="dropdown-menu" role="menu">'  
167 -  
168 - output += '<li>' + link_to(_('All people'), {host: host, controller: "search", action: 'people', category_path: ''}) + '</li>'  
169 - 165 + host = environment.default_hostname
170 links = [ 166 links = [
171 - {s_('people|More recent') => {:href => url_for({host: host, :controller => 'search', :action => 'people', :filter => 'more_recent'})}},  
172 - {s_('people|More active') => {:href => url_for({host: host, :controller => 'search', :action => 'people', :filter => 'more_active'})}},  
173 - {s_('people|More popular') => {:href => url_for({host: host, :controller => 'search', :action => 'people', :filter => 'more_popular'})}} 167 + [_('All people'), {host: host, controller: :search, action: :people, category_path: ''}],
  168 + [s_('people|More recent'), {host: host, controller: :search, action: :people, filter: 'more_recent'}],
  169 + [s_('people|More active'), {host: host, controller: :search, action: :people, filter: 'more_active'}],
  170 + [s_('people|More popular'), {host: host, controller: :search, action: :people, filter: 'more_popular'}],
174 ] 171 ]
175 if logged_in? 172 if logged_in?
176 - links.push(_('My friends') => {href: url_for({profile: current_user.login, controller: 'friends'})})  
177 - links.push(_('Invite friends') => {href: url_for({profile: current_user.login, controller: 'invite', action: 'friends'})}) 173 + links.push [_('My friends'), {profile: current_user.login, controller: 'friends'}]
  174 + links.push [_('Invite friends'), {profile: current_user.login, controller: 'invite', action: 'friends'}]
178 end 175 end
179 176
180 - links.each do |link|  
181 - link.each do |name, url|  
182 - output += '<li><a href="'+url[:href]+'">' + name + '</a></li>'  
183 - end 177 + content_tag :li, class: 'dropdown' do
  178 + [
  179 + link_to('#', class: "dropdown-toggle icon-menu-people", title: _('People'), data: {toggle: 'dropdown', hover: 'dropdown'}) do
  180 + content_tag :span, _('People')
  181 + end,
  182 + content_tag(:ul, class: 'dropdown-menu', role: 'menu') do
  183 + links.map do |params|
  184 + content_tag :li do
  185 + link_to *params
  186 + end
  187 + end.safe_join
  188 + end
  189 + ].safe_join
184 end 190 end
185 -  
186 - output += '</ul>'  
187 - output += '</li>'  
188 - output  
189 end 191 end
190 192
191 def search_communities_menu 193 def search_communities_menu
192 return super unless theme_responsive? 194 return super unless theme_responsive?
193 195
194 - host = environment.default_hostname  
195 -  
196 - output = '<li class="dropdown">'  
197 - output += link_to(_('Communities'), '#', :class=>"dropdown-toggle icon-menu-community", title: _('Communities'), :'data-toggle'=>"dropdown", :'data-hover'=>"dropdown")  
198 - output += '<ul class="dropdown-menu" role="menu">'  
199 -  
200 - output += '<li>' + link_to(_('All communities'), {host: host, controller: "search", action: 'communities', category_path: ''}) + '</li>'  
201 - 196 + host = environment.default_hostname
202 links = [ 197 links = [
203 - {s_('communities|More recent') => {:href => url_for({host: host, :controller => 'search', :action => 'communities', :filter => 'more_recent'})}},  
204 - {s_('communities|More active') => {:href => url_for({host: host, :controller => 'search', :action => 'communities', :filter => 'more_active'})}},  
205 - {s_('communities|More popular') => {:href => url_for({host: host, :controller => 'search', :action => 'communities', :filter => 'more_popular'})}} 198 + [_('All communities'), {host: host, controller: :search, action: :communities, category_path: ''}],
  199 + [s_('communities|More recent'), {host: host, controller: :search, action: :communities, filter: 'more_recent'}],
  200 + [s_('communities|More active'), {host: host, controller: :search, action: :communities, filter: 'more_active'}],
  201 + [s_('communities|More popular'), {host: host, controller: :search, action: :communities, filter: 'more_popular'}],
206 ] 202 ]
207 if logged_in? 203 if logged_in?
208 - links.push(_('My communities') => {href: url_for({profile: current_user.login, controller: 'memberships'})})  
209 - links.push(_('New community') => {href: url_for({profile: current_user.login, controller: 'memberships', action: 'new_community'})}) 204 + links.push [_('My communities'), {profile: current_user.login, controller: 'memberships'}]
  205 + links.push [_('New community'), {profile: current_user.login, controller: 'memberships', action: 'new_community'}]
210 end 206 end
211 207
212 - links.each do |link|  
213 - link.each do |name, url|  
214 - output += '<li><a href="'+url[:href]+'">' + name + '</a></li>'  
215 - end  
216 - end  
217 -  
218 - output += '</ul>'  
219 - output += '</li>'  
220 - output  
221 - end  
222 -  
223 - def usermenu_logged_in  
224 - return super unless theme_responsive?  
225 -  
226 - output = '<li class="dropdown">'  
227 -  
228 - pending_tasks_count = ''  
229 - count = user ? Task.to(user).pending.count : -1  
230 - if count > 0  
231 - pending_tasks_count = "<span class=\"badge\" onclick=\"document.location='#{url_for(user.tasks_url)}'\" title=\"#{_("Manage your pending tasks")}\">" + count.to_s + '</span>' 208 + content_tag :li, class: 'dropdown' do
  209 + [
  210 + link_to('#', class: 'dropdown-toggle icon-menu-community', title: _('Communities'), data: {toggle: 'dropdown', hover: 'dropdown'}) do
  211 + content_tag :span, _('Communities')
  212 + end,
  213 + content_tag(:ul, class: 'dropdown-menu', role: 'menu') do
  214 + links.map do |params|
  215 + content_tag :li do
  216 + link_to *params
  217 + end
  218 + end.safe_join
  219 + end
  220 + ].safe_join
232 end 221 end
233 -  
234 - output += link_to("<img class=\"menu-user-gravatar\" src=\"#{user.profile_custom_icon(gravatar_default)}\"><strong>#{user.identifier}</strong> #{pending_tasks_count}", '#', id: "homepage-link", title: _('Go to your homepage'), :class=>"dropdown-toggle", :'data-toggle'=>"dropdown", :'data-target'=>"", :'data-hover'=>"dropdown")  
235 -  
236 -  
237 - output += '<ul class="dropdown-menu" role="menu">'  
238 - output += '<li>' + link_to('<span class="icon-person">'+_('Profile')+'</span>', user.public_profile_url, id: "homepage-link", title: _('Go to your homepage')) + '</li>'  
239 -  
240 - output += '<li class="divider"></li>'  
241 -  
242 - #TODO  
243 - #render_environment_features(:usermenu) +  
244 -  
245 - #admin_link  
246 - admin_link_str = admin_link  
247 - output += admin_link_str.present? ? '<li>' + admin_link_str + '</li>' : ''  
248 -  
249 - #control_panel link  
250 - output += '<li>' + link_to('<i class="icon-menu-ctrl-panel"></i><strong>' + _('Control panel') + '</strong>', user.admin_url, class: 'ctrl-panel', title: _("Configure your personal account and content")) + '</li>'  
251 -  
252 - output += chat_user_status_menu('icon-menu-offline', _('Offline'))  
253 -  
254 - #manage_enterprises  
255 - manage_enterprises_str = manage_enterprises  
256 - output += manage_enterprises_str.present? ? '<li>' + manage_enterprises_str + '</li>' : ''  
257 -  
258 - #manage_communities  
259 - manage_communities_str = manage_communities  
260 - output += manage_communities_str.present? ? '<li>' + manage_communities_str + '</li>' : ''  
261 -  
262 - output += '<li class="divider"></li>'  
263 -  
264 - output += '<li>' + link_to('<i class="icon-menu-logout"></i><strong>' + _('Logout') + '</strong>', { controller: 'account', action: 'logout'} , id: "logout", title: _("Leave the system")) + '</li>'  
265 -  
266 - output += '</ul>'  
267 - output  
268 end 222 end
269 223
270 def manage_link(list, kind, title) 224 def manage_link(list, kind, title)
@@ -274,17 +228,22 @@ module ApplicationHelper @@ -274,17 +228,22 @@ module ApplicationHelper
274 link_to_all = nil 228 link_to_all = nil
275 if list.count > 5 229 if list.count > 5
276 list = list.first(5) 230 list = list.first(5)
277 - link_to_all = link_to(content_tag('strong', _('See all')), :controller => 'memberships', :profile => user.identifier) 231 + link_to_all = link_to(content_tag(:strong, _('See all')), controller: 'memberships', profile: user.identifier)
278 end 232 end
279 link = list.map do |element| 233 link = list.map do |element|
280 - link_to(content_tag('strong', element.short_name(25)), element.admin_url, :class => "icon-menu-"+element.class.identification.underscore, :title => _('Manage %s') % element.short_name) 234 + link_to(content_tag(:strong, element.short_name(25)), element.admin_url, class: "icon-menu-"+element.class.identification.underscore, title: _('Manage %s') % element.short_name)
281 end 235 end
282 if link_to_all 236 if link_to_all
283 link << link_to_all 237 link << link_to_all
284 end 238 end
285 - content_tag('li', nil, class: 'divider') +  
286 - content_tag('li', title, class: 'dropdown-header') +  
287 - link.map{ |l| content_tag 'li', l }.join 239 +
  240 + [
  241 + content_tag(:li, nil, class: 'divider'),
  242 + content_tag(:li, title, class: 'dropdown-header'),
  243 + link.map do |l|
  244 + content_tag :li, l
  245 + end.safe_join
  246 + ].safe_join
288 end 247 end
289 end 248 end
290 249
@@ -301,15 +260,24 @@ module ApplicationHelper @@ -301,15 +260,24 @@ module ApplicationHelper
301 unless html_options[:style].present? and html_options[:style] =~ /display *: *none/ 260 unless html_options[:style].present? and html_options[:style] =~ /display *: *none/
302 menu_content << '<br/>' unless first 261 menu_content << '<br/>' unless first
303 first = false 262 first = false
304 - menu_content << content_tag(:a,link_label,html_options) 263 + menu_content << content_tag(:a, link_label,html_options)
305 end 264 end
306 end 265 end
307 end 266 end
308 end 267 end
309 268
310 option = html_options.delete(:option) || 'default' 269 option = html_options.delete(:option) || 'default'
311 - size = html_options.delete(:size) || 'xs'  
312 - "<button class='btn btn-#{size} btn-#{option} btn-popover-menu icon-parent-folder' data-toggle='popover' data-html='true' data-placement='top' data-trigger='focus' data-content=\""+CGI::escapeHTML(menu_content)+'" data-title="'+menu_title+'"></button>' 270 + size = html_options.delete(:size) || 'xs'
  271 + button_tag '',
  272 + class: "btn btn-#{size} btn-#{option} btn-popover-menu icon-parent-folder",
  273 + data: {
  274 + html: 'true',
  275 + toggle: 'popover',
  276 + placement: 'top',
  277 + trigger: 'focus',
  278 + content: menu_content,
  279 + title: menu_title,
  280 + }
313 end 281 end
314 282
315 283
@@ -406,12 +374,7 @@ module ApplicationHelper @@ -406,12 +374,7 @@ module ApplicationHelper
406 end 374 end
407 375
408 include ResponsiveChecks 376 include ResponsiveChecks
409 - if RUBY_VERSION >= '2.0.0'  
410 - prepend ResponsiveMethods  
411 - else  
412 - extend ActiveSupport::Concern  
413 - included { include ResponsiveMethods }  
414 - end 377 + prepend ResponsiveMethods
415 378
416 # TODO: apply theme_responsive? condition 379 # TODO: apply theme_responsive? condition
417 class NoosferoFormBuilder 380 class NoosferoFormBuilder
@@ -440,13 +403,16 @@ module ApplicationHelper @@ -440,13 +403,16 @@ module ApplicationHelper
440 403
441 if options[:horizontal] 404 if options[:horizontal]
442 label_html = content_tag :label, gettext(text), class: 'control-label col-sm-3 col-md-2 col-lg-2', for: field_id 405 label_html = content_tag :label, gettext(text), class: 'control-label col-sm-3 col-md-2 col-lg-2', for: field_id
443 - result = content_tag :div, label_html + content_tag('div',field_html, class: 'col-sm-9 col-md-6 col-lg-6'), class: 'form-group' 406 + content = [
  407 + label_html,
  408 + content_tag(:div, field_html.html_safe, class: 'col-sm-9 col-md-6 col-lg-6'),
  409 + ].safe_join
  410 + content_tag :div, content, class: 'form-group'
444 else 411 else
445 label_html = content_tag :label, gettext(text), class: 'control-label', for: field_id 412 label_html = content_tag :label, gettext(text), class: 'control-label', for: field_id
446 - result = content_tag :div, label_html + field_html, class: 'form-group' 413 + content = [label_html, field_html.html_safe].safe_join
  414 + content_tag :div, content, class: 'form-group'
447 end 415 end
448 -  
449 - result  
450 end 416 end
451 end 417 end
452 418
plugins/responsive/lib/ext/boxes_helper.rb
@@ -62,12 +62,7 @@ module BoxesHelper @@ -62,12 +62,7 @@ module BoxesHelper
62 end 62 end
63 63
64 include ResponsiveChecks 64 include ResponsiveChecks
65 - if RUBY_VERSION >= '2.0.0'  
66 - prepend ResponsiveMethods  
67 - else  
68 - extend ActiveSupport::Concern  
69 - included { include ResponsiveMethods }  
70 - end 65 + prepend ResponsiveMethods
71 66
72 end 67 end
73 68
plugins/responsive/lib/ext/chat_helper.rb
@@ -23,12 +23,7 @@ module ChatHelper @@ -23,12 +23,7 @@ module ChatHelper
23 end 23 end
24 24
25 include ResponsiveChecks 25 include ResponsiveChecks
26 - if RUBY_VERSION >= '2.0.0'  
27 - prepend ResponsiveMethods  
28 - else  
29 - extend ActiveSupport::Concern  
30 - included { include ResponsiveMethods }  
31 - end 26 + prepend ResponsiveMethods
32 27
33 end 28 end
34 29
plugins/responsive/lib/ext/forms_helper.rb
@@ -11,8 +11,15 @@ module FormsHelper @@ -11,8 +11,15 @@ module FormsHelper
11 return super unless theme_responsive? 11 return super unless theme_responsive?
12 12
13 options[:id] ||= 'radio-' + FormsHelper.next_id_number 13 options[:id] ||= 'radio-' + FormsHelper.next_id_number
14 - content_tag( 'label', radio_button_tag( name, value, checked, options ) + ' ' +  
15 - human_name, for: options[:id], class: 'radio-inline' ) 14 + content_tag :div, class:'radio-inline' do
  15 + content_tag :label, for: options[:id] do
  16 + [
  17 + radio_button_tag(name, value, checked, options),
  18 + ' ',
  19 + human_name,
  20 + ].safe_join
  21 + end
  22 + end
16 end 23 end
17 24
18 # add -inline class 25 # add -inline class
@@ -20,8 +27,18 @@ module FormsHelper @@ -20,8 +27,18 @@ module FormsHelper
20 return super unless theme_responsive? 27 return super unless theme_responsive?
21 28
22 options[:id] ||= 'checkbox-' + FormsHelper.next_id_number 29 options[:id] ||= 'checkbox-' + FormsHelper.next_id_number
23 - hidden_field_tag(name, '0') +  
24 - content_tag( 'label', check_box_tag( name, value, checked, options ) + ' ' + human_name, for: options[:id], class: 'checkbox-inline') 30 + [
  31 + hidden_field_tag(name, '0'),
  32 + content_tag(:div, class:'checkbox-inline') do
  33 + content_tag :label, for: options[:id] do
  34 + [
  35 + check_box_tag(name, value, checked, options),
  36 + ' ',
  37 + human_name,
  38 + ].safe_join
  39 + end
  40 + end
  41 + ].safe_join
25 end 42 end
26 43
27 def submit_button(type, label, html_options = {}) 44 def submit_button(type, label, html_options = {})
@@ -43,42 +60,34 @@ module FormsHelper @@ -43,42 +60,34 @@ module FormsHelper
43 html_options.delete(:cancel) 60 html_options.delete(:cancel)
44 bt_submit = button_tag(label, html_options.merge(class: the_class)) 61 bt_submit = button_tag(label, html_options.merge(class: the_class))
45 62
46 - bt_submit + bt_cancel 63 + [bt_submit + bt_cancel].safe_join
47 end 64 end
48 65
49 - %w[select select_tag text_field_tag number_field_tag password_field_tag].each do |method|  
50 - define_method method do |*args, &block|  
51 - #return super(*args, &block) unless theme_responsive? 66 + bt_submit + bt_cancel
  67 + end
52 68
53 - options = args.extract_options!  
54 - if options['class']  
55 - options['class'] = "#{options['class']} form-control"  
56 - else  
57 - options[:class] = "#{options[:class]} form-control"  
58 - end  
59 - super(*(args << options), &block) 69 + %w[
  70 + select_tag
  71 + text_field_tag text_area_tag
  72 + number_field_tag password_field_tag url_field_tag email_field_tag
  73 + month_field_tag date_field_tag
  74 + ].each do |method|
  75 + define_method method do |name, value=nil, options={}, &block|
  76 + responsive_add_field_class! options
  77 + super(name, value, options, &block).html_safe
60 end 78 end
61 end 79 end
62 %w[select_month select_year].each do |method| 80 %w[select_month select_year].each do |method|
63 define_method method do |date, options={}, html_options={}| 81 define_method method do |date, options={}, html_options={}|
64 - if html_options['class']  
65 - html_options['class'] = "#{html_options['class']} form-control"  
66 - else  
67 - html_options[:class] = "#{html_options[:class]} form-control"  
68 - end  
69 - super date, options, html_options 82 + responsive_add_field_class! html_options
  83 + super(date, options, html_options).html_safe
70 end 84 end
71 end 85 end
72 86
73 end 87 end
74 88
75 include ResponsiveChecks 89 include ResponsiveChecks
76 - if RUBY_VERSION >= '2.0.0'  
77 - prepend ResponsiveMethods  
78 - else  
79 - extend ActiveSupport::Concern  
80 - included { include ResponsiveMethods }  
81 - end 90 + prepend ResponsiveMethods
82 91
83 end 92 end
84 93
plugins/responsive/lib/ext/input_helper.rb
@@ -4,16 +4,15 @@ module InputHelper @@ -4,16 +4,15 @@ module InputHelper
4 protected 4 protected
5 5
6 def input_group_addon addon, options = {}, &block 6 def input_group_addon addon, options = {}, &block
7 - content_tag :div,  
8 - content_tag(:span, addon, class: 'input-group-addon') + yield,  
9 - class: 'input-group' 7 + content_tag :div, class: 'input-group' do
  8 + [
  9 + content_tag(:span, addon, class: 'input-group-addon'),
  10 + capture(&block),
  11 + ].safe_join
  12 + end
10 end 13 end
11 14
12 end 15 end
13 16
14 -module ApplicationHelper  
15 -  
16 - include InputHelper  
17 -  
18 -end 17 +ApplicationHelper.include InputHelper
19 18
plugins/responsive/lib/responsive_plugin.rb
@@ -13,7 +13,7 @@ class ResponsivePlugin &lt; Noosfero::Plugin @@ -13,7 +13,7 @@ class ResponsivePlugin &lt; Noosfero::Plugin
13 end 13 end
14 14
15 def head_ending 15 def head_ending
16 - '<meta name="viewport" content="width=device-width, initial-scale=1">' 16 + '<meta name="viewport" content="width=device-width, initial-scale=1">'.html_safe
17 end 17 end
18 18
19 def body_ending 19 def body_ending
plugins/responsive/views/layouts/_menu_responsive.html.erb
@@ -1,71 +0,0 @@ @@ -1,71 +0,0 @@
1 -<div>  
2 -<nav id="top-bar" class="navbar navbar-default" role="navigation">  
3 - <div class="container">  
4 - <!-- Brand and toggle get grouped for better mobile display -->  
5 - <div class="navbar-header">  
6 - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-user-collapse">  
7 - <span class="sr-only"><%= _('User menu') %></span>  
8 - <span class="fa fa-user navbar-toggle-icon"></span>  
9 - </button>  
10 - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-search-collapse">  
11 - <span class="sr-only"><%= _('Search') %></span>  
12 - <span class="fa fa-search navbar-toggle-icon"></span>  
13 - </button>  
14 - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-navigation-collapse">  
15 - <span class="sr-only"><%= _('Navigation') %></span>  
16 - <span class="icon-bar"></span>  
17 - <span class="icon-bar"></span>  
18 - <span class="icon-bar"></span>  
19 - </button>  
20 -  
21 - </div>  
22 -  
23 - <!-- Collect the nav links, forms, and other content for toggling -->  
24 - <div class="collapse navbar-collapse" id="navbar-navigation-collapse">  
25 - <ul class="nav navbar-nav menu-navigation">  
26 - <%= theme_extra_navigation %>  
27 - <li class="dropdown" id="search-dropdown-menu">  
28 - <a href="#" class="dropdown-toggle icon-search" data-hover="dropdown" data-toggle="dropdown" title="<%= _('Search') %>"><span><%= _('Search') %></span></a>  
29 - <ul class="dropdown-menu" role="menu">  
30 - <li>  
31 - <form action="/search" id="top-search" method="get" role="search">  
32 - <div class="form-group col-lg-12 col-md-12 col-sm-12">  
33 - <input name="query" title="<%=_('Search...')%>" placeholder="<%=_('Search...')%>" type="text" class="form-control input-sm"/>  
34 - </div>  
35 - </form>  
36 - </li>  
37 - </ul>  
38 - </li>  
39 - </ul>  
40 - </div>  
41 - <div class="collapse navbar-collapse" id="navbar-search-collapse">  
42 - <form action="/search" id="top-search" class="navbar-form navbar-left" method="get" role="search">  
43 - <div class="form-group">  
44 - <input name="query" title="<%=_('Search...')%>" placeholder="<%=_('Search...')%>" type="text" class="form-control"/>  
45 - </div>  
46 - </form>  
47 - </div>  
48 - <div class="collapse navbar-collapse" id="navbar-user-collapse">  
49 - <ul class="nav navbar-nav pull-right">  
50 - <% if user.present? %>  
51 - <%= usermenu_logged_in %>  
52 - <% else %>  
53 - <li>  
54 - <%= modal_inline_link_to('<i class="icon-menu-login"></i><strong>' + _('Login') + '</strong>', login_url, '#inlineLoginBox', :id => 'link_login') %>  
55 - <%= @plugins.dispatch(:alternative_authentication_link).collect { |content| instance_exec(&content) }.join("") #TODO review this  
56 - %>  
57 - </li>  
58 - <% unless @plugins.dispatch(:allow_user_registration).include?(false) %>  
59 - <li>  
60 - <%= link_to('<strong>' + _('Sign up') + '</strong>', :controller => 'account', :action => 'signup')%>  
61 - </li>  
62 - <% end %>  
63 - <% end %>  
64 - </ul>  
65 - </div><!-- /.navbar-collapse -->  
66 - </div><!-- /.container-fluid -->  
67 -</nav>  
68 -</div>  
69 -<div id='inlineLoginBox' style='display: none;'>  
70 - <%= render :file => 'account/login', :locals => { :is_thickbox => true } %>  
71 -</div>  
plugins/responsive/views/layouts/_menu_responsive.html.slim 0 → 100644
@@ -0,0 +1,54 @@ @@ -0,0 +1,54 @@
  1 +div
  2 + nav#top-bar.navbar.navbar-default.navbar-static-top role="navigation"
  3 + .container
  4 + /! Brand and toggle get grouped for better mobile display
  5 + .navbar-header
  6 + button.navbar-toggle data-target="#navbar-user-collapse" data-toggle="collapse" type="button"
  7 + span.sr-only= _('User menu')
  8 + span.fa.fa-user.navbar-toggle-icon
  9 +
  10 + button.navbar-toggle data-target="#navbar-search-collapse" data-toggle="collapse" type="button"
  11 + span.sr-only= _('Search')
  12 + span.fa.fa-search.navbar-toggle-icon
  13 +
  14 + button.navbar-toggle data-target="#navbar-navigation-collapse" data-toggle="collapse" type="button"
  15 + span.sr-only= _('Navigation')
  16 + span.icon-bar
  17 + span.icon-bar
  18 + span.icon-bar
  19 + a.navbar-brand href="#{environment.top_url}"
  20 + = theme_site_title
  21 + span#navbar-brand-site-title
  22 + = h @environment.name
  23 +
  24 + /! Collect the nav links, forms, and other content for toggling
  25 + #navbar-navigation-collapse.collapse.navbar-collapse
  26 + ul.nav.navbar-nav.menu-navigation
  27 + = theme_extra_navigation
  28 + li#search-dropdown-menu.dropdown
  29 + a.dropdown-toggle.icon-search data-hover="dropdown" data-toggle="dropdown" href="#" title="#{_('Search')}"
  30 + span= _('Search')
  31 + ul.dropdown-menu role="menu"
  32 + li
  33 + form#top-search action="/search" method="get" role="search"
  34 + .form-group.col-lg-12.col-md-12.col-sm-12
  35 + input.form-control.input-sm name="query" placeholder="#{_('Search...')}" title="#{_('Search...')}" type="text" /
  36 +
  37 + #navbar-search-collapse.collapse.navbar-collapse
  38 + form#top-search.navbar-form.navbar-left action="/search" method="get" role="search"
  39 + .form-group
  40 + input.form-control name="query" placeholder="#{_('Search...')}" title="#{_('Search...')}" type="text" /
  41 +
  42 + #navbar-user-collapse.collapse.navbar-collapse
  43 + ul.nav.navbar-nav.pull-right
  44 + - if user.present?
  45 + = render 'layouts/usermenu_logged_in'
  46 + - else
  47 + li
  48 + = modal_inline_link_to "<i class='icon-menu-login'></i><strong>#{_('Login')}</strong>".html_safe, login_url, '#inlineLoginBox', id: 'link_login'
  49 + = @plugins.dispatch(:alternative_authentication_link).collect{ |content| instance_exec(&content) }.safe_join
  50 + - unless @plugins.dispatch(:allow_user_registration).include? false
  51 + li= link_to content_tag(:strong, _('Sign up')), controller: :account, action: :signup
  52 +
  53 +#inlineLoginBox style="display: none;"
  54 + = render file: 'account/login', locals: {is_thickbox: true}
plugins/responsive/views/layouts/_usermenu_logged_in.html.slim 0 → 100644
@@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
  1 +- pending_tasks_count = Task.to(user).pending.count if user
  2 +
  3 +li.dropdown
  4 + = link_to '#', id: "homepage-link", title: _('Go to your homepage'), class: 'dropdown-toggle', data: {toggle: 'dropdown', hover: 'dropdown'}
  5 + = image_tag user.profile_custom_icon(gravatar_default), class: 'menu-user-gravatar'
  6 + = content_tag :strong, user.identifier
  7 + - if pending_tasks_count
  8 + span class='badge' onclick="document.location='#{url_for(user.tasks_url)}'" title="#{_("Manage your pending tasks")}"
  9 + count
  10 +
  11 + ul class='dropdown-menu' role='menu'
  12 + li
  13 + = link_to user.public_profile_url, id: "homepage-link", title: _('Go to your homepage')
  14 + span class='icon-person' = _('Profile')
  15 + li.divider
  16 +
  17 + /TODO
  18 + /= render_environment_features(:usermenu)
  19 +
  20 + li = admin_link
  21 +
  22 + li
  23 + = link_to user.admin_url, class: 'ctrl-panel', title: _("Configure your personal account and content")
  24 + i class='icon-menu-ctrl-panel'
  25 + strong = _('Control panel')
  26 +
  27 + - if environment.enabled? 'xmpp_chat'
  28 + = responsive_chat_user_status_menu 'icon-menu-offline', _('Offline')
  29 +
  30 + li = manage_enterprises
  31 + li = manage_communities
  32 +
  33 + li.divider
  34 +
  35 + li
  36 + = link_to({controller: 'account', action: 'logout'}, id: "logout", title: _("Leave the system"))
  37 + i class='icon-menu-logout'
  38 + strong = _('Logout')
  39 +
plugins/responsive/views/layouts/application-responsive.html.erb
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%= html_language %>" lang="<%= html_language %>" class="<%= h html_tag_classes %>"> 2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%= html_language %>" lang="<%= html_language %>" class="<%= h html_tag_classes %>">
3 <head> 3 <head>
4 - <title><%= h page_title %></title> 4 + <title><%= h page_title.html_safe %></title>
5 <%= yield(:feeds) %> 5 <%= yield(:feeds) %>
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"/>
@@ -22,7 +22,7 @@ @@ -22,7 +22,7 @@
22 <%= 22 <%=
23 @plugins.dispatch(:head_ending).map do |content| 23 @plugins.dispatch(:head_ending).map do |content|
24 if content.respond_to?(:call) then instance_exec(&content).to_s.html_safe else content.to_s.html_safe end 24 if content.respond_to?(:call) then instance_exec(&content).to_s.html_safe else content.to_s.html_safe end
25 - end.join("\n") 25 + end.safe_join
26 %> 26 %>
27 27
28 <script type="text/javascript"> 28 <script type="text/javascript">
@@ -68,7 +68,7 @@ @@ -68,7 +68,7 @@
68 <%= 68 <%=
69 @plugins.dispatch(:body_ending).map do |content| 69 @plugins.dispatch(:body_ending).map do |content|
70 if content.respond_to?(:call) then instance_exec(&content).html_safe else content.html_safe end 70 if content.respond_to?(:call) then instance_exec(&content).html_safe else content.html_safe end
71 - end.join("\n") 71 + end.safe_join
72 %> 72 %>
73 </body> 73 </body>
74 </html> 74 </html>
test/api/profiles_test.rb
@@ -146,4 +146,49 @@ class ProfilesTest &lt; ActiveSupport::TestCase @@ -146,4 +146,49 @@ class ProfilesTest &lt; ActiveSupport::TestCase
146 refute json.has_key?('Rating') 146 refute json.has_key?('Rating')
147 end 147 end
148 148
  149 + [Community, Enterprise].each do |klass|
  150 + should "update #{klass.name}" do
  151 + login_api
  152 + profile = fast_create(klass)
  153 + profile.add_admin(person)
  154 + params[:profile] = {}
  155 + params[:profile][:custom_header] = "Another Header"
  156 + post "/api/v1/profiles/#{profile.id}?#{params.to_query}"
  157 + assert_equal "Another Header", profile.reload.custom_header
  158 + end
  159 +
  160 + should "not update a #{klass.name} if user does not have permission" do
  161 + login_api
  162 + profile = fast_create(klass)
  163 + params[:profile] = {}
  164 + params[:profile][:custom_header] = "Another Header"
  165 + post "/api/v1/profiles/#{profile.id}?#{params.to_query}"
  166 + assert_equal 403, last_response.status
  167 + end
  168 +
  169 + should "not update a #{klass.name} if user is not logged in" do
  170 + profile = fast_create(klass)
  171 + params[:profile] = {}
  172 + params[:profile][:custom_header] = "Another Header"
  173 + post "/api/v1/profiles/#{profile.id}?#{params.to_query}"
  174 + assert_equal 401, last_response.status
  175 + end
  176 + end
  177 +
  178 + should 'update person' do
  179 + login_api
  180 + params[:profile] = {}
  181 + params[:profile][:custom_header] = "Another Header"
  182 + post "/api/v1/profiles/#{person.id}?#{params.to_query}"
  183 + assert_equal "Another Header", person.reload.custom_header
  184 + end
  185 +
  186 + should 'not update person information if user does not have permission' do
  187 + login_api
  188 + profile = fast_create(Person)
  189 + params[:profile] = {}
  190 + params[:profile][:custom_header] = "Another Header"
  191 + post "/api/v1/profiles/#{profile.id}?#{params.to_query}"
  192 + assert_equal 403, last_response.status
  193 + end
149 end 194 end
test/functional/application_controller_test.rb
@@ -224,7 +224,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -224,7 +224,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase
224 end 224 end
225 225
226 should 'display theme test panel when testing theme' do 226 should 'display theme test panel when testing theme' do
227 - @request.session[:theme] = 'my-test-theme' 227 + @request.session[:user_theme] = 'my-test-theme'
228 theme = mock 228 theme = mock
229 profile = mock 229 profile = mock
230 theme.expects(:owner).returns(profile).at_least_once 230 theme.expects(:owner).returns(profile).at_least_once
@@ -576,4 +576,36 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -576,4 +576,36 @@ class ApplicationControllerTest &lt; ActionController::TestCase
576 assert_redirected_to :controller => 'test', :action => 'index', :profile => profile.identifier 576 assert_redirected_to :controller => 'test', :action => 'index', :profile => profile.identifier
577 end 577 end
578 578
  579 + should 'set session theme if a params theme is passed as parameter' do
  580 + current_theme = 'my-test-theme'
  581 + environment = Environment.default
  582 + Theme.stubs(:system_themes).returns([Theme.new(current_theme)])
  583 + environment.themes = [current_theme]
  584 + environment.save!
  585 + assert_nil @request.session[:theme]
  586 + get :index, :theme => current_theme
  587 + assert_equal current_theme, @request.session[:theme]
  588 + end
  589 +
  590 + should 'set session theme only in environment available themes' do
  591 + environment = Environment.default
  592 + assert_nil @request.session[:theme]
  593 + environment.stubs(:theme_ids).returns(['another_theme'])
  594 + get :index, :theme => 'my-test-theme'
  595 + assert_nil @request.session[:theme]
  596 + end
  597 +
  598 + should 'unset session theme if not environment available themes is defined' do
  599 + environment = Environment.default
  600 + current_theme = 'my-test-theme'
  601 + Theme.stubs(:system_themes).returns([Theme.new(current_theme)])
  602 + environment.themes = [current_theme]
  603 + environment.save!
  604 + get :index, :theme => current_theme
  605 + assert_equal current_theme, @request.session[:theme]
  606 +
  607 + get :index, :theme => 'another_theme'
  608 + assert_nil @request.session[:theme]
  609 + end
  610 +
579 end 611 end
test/functional/profile_themes_controller_test.rb
@@ -231,7 +231,7 @@ class ProfileThemesControllerTest &lt; ActionController::TestCase @@ -231,7 +231,7 @@ class ProfileThemesControllerTest &lt; ActionController::TestCase
231 theme = Theme.create('theme-under-test', :owner => profile) 231 theme = Theme.create('theme-under-test', :owner => profile)
232 post :start_test, :profile => 'testinguser', :id => 'theme-under-test' 232 post :start_test, :profile => 'testinguser', :id => 'theme-under-test'
233 233
234 - assert_equal 'theme-under-test', session[:theme] 234 + assert_equal 'theme-under-test', session[:user_theme]
235 assert_redirected_to :controller => 'content_viewer', :profile => 'testinguser', :action => 'view_page' 235 assert_redirected_to :controller => 'content_viewer', :profile => 'testinguser', :action => 'view_page'
236 end 236 end
237 237
@@ -239,7 +239,7 @@ class ProfileThemesControllerTest &lt; ActionController::TestCase @@ -239,7 +239,7 @@ class ProfileThemesControllerTest &lt; ActionController::TestCase
239 theme = Theme.create('theme-under-test', :owner => profile) 239 theme = Theme.create('theme-under-test', :owner => profile)
240 post :stop_test, :profile => 'testinguser', :id => 'theme-under-test' 240 post :stop_test, :profile => 'testinguser', :id => 'theme-under-test'
241 241
242 - assert_nil session[:theme] 242 + assert_nil session[:user_theme]
243 assert_redirected_to :action => 'index' 243 assert_redirected_to :action => 'index'
244 end 244 end
245 245
test/unit/add_member_test.rb
@@ -149,4 +149,11 @@ class AddMemberTest &lt; ActiveSupport::TestCase @@ -149,4 +149,11 @@ class AddMemberTest &lt; ActiveSupport::TestCase
149 149
150 assert_no_match(/\(#{task.requestor.email}\)/, task.target_notification_description) 150 assert_no_match(/\(#{task.requestor.email}\)/, task.target_notification_description)
151 end 151 end
  152 +
  153 + should 'have cancel notification message with explanation' do
  154 + explanation_message = 'some explanation'
  155 + task = AddMember.new(:person => person, :organization => community,
  156 + :reject_explanation => explanation_message)
  157 + assert_match(/#{explanation_message}/, task.task_cancelled_message)
  158 + end
152 end 159 end
test/unit/application_helper_test.rb
@@ -466,7 +466,7 @@ class ApplicationHelperTest &lt; ActionView::TestCase @@ -466,7 +466,7 @@ class ApplicationHelperTest &lt; ActionView::TestCase
466 should 'use theme passed via param when in development mode' do 466 should 'use theme passed via param when in development mode' do
467 stubs(:environment).returns(build(Environment, :theme => 'environment-theme')) 467 stubs(:environment).returns(build(Environment, :theme => 'environment-theme'))
468 Rails.env.stubs(:development?).returns(true) 468 Rails.env.stubs(:development?).returns(true)
469 - self.stubs(:params).returns({:theme => 'skyblue'}) 469 + self.stubs(:params).returns({:user_theme => 'skyblue'})
470 assert_equal 'skyblue', current_theme 470 assert_equal 'skyblue', current_theme
471 end 471 end
472 472
test/unit/content_viewer_helper_test.rb
@@ -101,14 +101,14 @@ class ContentViewerHelperTest &lt; ActionView::TestCase @@ -101,14 +101,14 @@ class ContentViewerHelperTest &lt; ActionView::TestCase
101 end 101 end
102 102
103 should 'theme provides addthis custom icon' do 103 should 'theme provides addthis custom icon' do
104 - stubs(:session).returns({:theme => 'base'}) 104 + stubs(:session).returns({:user_theme => 'base'})
105 File.expects(:exists?).with(anything).returns(true) 105 File.expects(:exists?).with(anything).returns(true)
106 Environment.any_instance.stubs(:default_hostname).returns('noosfero.org') 106 Environment.any_instance.stubs(:default_hostname).returns('noosfero.org')
107 assert_match 'addthis.gif', addthis_image_tag 107 assert_match 'addthis.gif', addthis_image_tag
108 end 108 end
109 109
110 should 'use default addthis icon if theme has no addthis.gif image' do 110 should 'use default addthis icon if theme has no addthis.gif image' do
111 - stubs(:session).returns({:theme => 'base'}) 111 + stubs(:session).returns({:user_theme => 'base'})
112 File.expects(:exists?).with(anything).returns(false) 112 File.expects(:exists?).with(anything).returns(false)
113 Environment.any_instance.stubs(:default_hostname).returns('noosfero.org') 113 Environment.any_instance.stubs(:default_hostname).returns('noosfero.org')
114 assert_match 'bt-bookmark.gif', addthis_image_tag 114 assert_match 'bt-bookmark.gif', addthis_image_tag
test/unit/environment_test.rb
@@ -457,6 +457,22 @@ class EnvironmentTest &lt; ActiveSupport::TestCase @@ -457,6 +457,22 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
457 assert_equal ['new-theme', 'other-theme'], Environment.default.themes.map(&:id) 457 assert_equal ['new-theme', 'other-theme'], Environment.default.themes.map(&:id)
458 end 458 end
459 459
  460 + should 'return the theme ids' do
  461 + env = Environment.default
  462 + t1 = 'theme_1'
  463 + t2 = 'theme_2'
  464 + Theme.stubs(:system_themes).returns([Theme.new(t1), Theme.new(t2)])
  465 + env.themes = [t1, t2]
  466 + env.save!
  467 + assert_equivalent [t1, t2], Environment.default.theme_ids
  468 + end
  469 + should 'theme_ids be an empty array if there is no settings themes defined' do
  470 + env = Environment.default
  471 + env.settings[:themes] = nil
  472 + env.save!
  473 + assert Environment.default.theme_ids.empty?
  474 + end
  475 +
460 should 'create templates' do 476 should 'create templates' do
461 e = create(Environment, :name => 'test_env') 477 e = create(Environment, :name => 'test_env')
462 e.reload 478 e.reload
test/unit/theme_loader_helper_test.rb
@@ -20,7 +20,7 @@ class ThemeLoaderHelperTest &lt; ActionView::TestCase @@ -20,7 +20,7 @@ class ThemeLoaderHelperTest &lt; ActionView::TestCase
20 end 20 end
21 21
22 should 'override theme with testing theme from session' do 22 should 'override theme with testing theme from session' do
23 - stubs(:session).returns(:theme => 'theme-under-test') 23 + stubs(:session).returns(:user_theme => 'theme-under-test')
24 assert_equal 'theme-under-test', current_theme 24 assert_equal 'theme-under-test', current_theme
25 end 25 end
26 26
@@ -30,7 +30,17 @@ class ThemeLoaderHelperTest &lt; ActionView::TestCase @@ -30,7 +30,17 @@ class ThemeLoaderHelperTest &lt; ActionView::TestCase
30 end 30 end
31 31
32 should 'point to user theme path when testing theme' do 32 should 'point to user theme path when testing theme' do
33 - stubs(:session).returns({:theme => 'theme-under-test'}) 33 + stubs(:session).returns({:user_theme => 'theme-under-test'})
34 assert_equal '/user_themes/theme-under-test', theme_path 34 assert_equal '/user_themes/theme-under-test', theme_path
35 end 35 end
36 -end  
37 \ No newline at end of file 36 \ No newline at end of file
  37 +
  38 + should 'point to session theme is defined' do
  39 + session = mock
  40 + stubs(:session).returns(session)
  41 + my_session_theme = 'session_theme'
  42 + session.stubs(:[]).with(:user_theme).returns(nil)
  43 + session.stubs(:[]).with(:theme).returns(my_session_theme)
  44 + assert_equal '/designs/themes/' + my_session_theme, theme_path
  45 + end
  46 +
  47 +end