Commit 7793e38498e271c0265832aeff9dc5391da32b36

Authored by Daniela Feitosa
2 parents 2be7f5f4 488335e5

Merge commit 'refs/merge-requests/172' of git://gitorious.org/noosfero/noosfero …

…into merge-requests/172
Showing 43 changed files with 1079 additions and 238 deletions   Show diff stats
app/controllers/public/account_controller.rb
@@ -216,10 +216,10 @@ class AccountController < ApplicationController @@ -216,10 +216,10 @@ class AccountController < ApplicationController
216 valid = Person.is_available?(@identifier, environment) 216 valid = Person.is_available?(@identifier, environment)
217 if valid 217 if valid
218 @status = _('This login name is available') 218 @status = _('This login name is available')
219 - @status_class = 'available' 219 + @status_class = 'validated'
220 else 220 else
221 @status = _('This login name is unavailable') 221 @status = _('This login name is unavailable')
222 - @status_class = 'unavailable' 222 + @status_class = 'invalid'
223 end 223 end
224 render :partial => 'identifier_status' 224 render :partial => 'identifier_status'
225 end 225 end
@@ -227,10 +227,10 @@ class AccountController < ApplicationController @@ -227,10 +227,10 @@ class AccountController < ApplicationController
227 def check_email 227 def check_email
228 if User.find_by_email_and_environment_id(params[:address], environment.id).nil? 228 if User.find_by_email_and_environment_id(params[:address], environment.id).nil?
229 @status = _('This e-mail address is available') 229 @status = _('This e-mail address is available')
230 - @status_class = 'available' 230 + @status_class = 'validated'
231 else 231 else
232 @status = _('This e-mail address is taken') 232 @status = _('This e-mail address is taken')
233 - @status_class = 'unavailable' 233 + @status_class = 'invalid'
234 end 234 end
235 render :partial => 'email_status' 235 render :partial => 'email_status'
236 end 236 end
app/helpers/account_helper.rb
1 module AccountHelper 1 module AccountHelper
2 2
3 def validation_classes 3 def validation_classes
4 - 'available unavailable valid invalid checking' 4 + 'available unavailable valid validated invalid checking'
5 end 5 end
6 6
7 def checking_message(key) 7 def checking_message(key)
app/models/environment.rb
@@ -258,7 +258,7 @@ class Environment < ActiveRecord::Base @@ -258,7 +258,7 @@ class Environment < ActiveRecord::Base
258 end 258 end
259 259
260 def enable_plugin(plugin) 260 def enable_plugin(plugin)
261 - self.enabled_plugins += [plugin] 261 + self.enabled_plugins += [plugin.to_s]
262 self.enabled_plugins.uniq! 262 self.enabled_plugins.uniq!
263 self.save! 263 self.save!
264 end 264 end
@@ -269,7 +269,7 @@ class Environment < ActiveRecord::Base @@ -269,7 +269,7 @@ class Environment < ActiveRecord::Base
269 end 269 end
270 270
271 def disable_plugin(plugin) 271 def disable_plugin(plugin)
272 - self.enabled_plugins.delete(plugin) 272 + self.enabled_plugins.delete(plugin.to_s)
273 self.save! 273 self.save!
274 end 274 end
275 275
@@ -278,6 +278,10 @@ class Environment < ActiveRecord::Base @@ -278,6 +278,10 @@ class Environment < ActiveRecord::Base
278 self.settings["#{feature}_enabled".to_sym] == true 278 self.settings["#{feature}_enabled".to_sym] == true
279 end 279 end
280 280
  281 + def plugin_enabled?(plugin)
  282 + enabled_plugins.include?(plugin.to_s)
  283 + end
  284 +
281 # enables the features identified by <tt>features</tt>, which is expected to 285 # enables the features identified by <tt>features</tt>, which is expected to
282 # be an Enumarable object containing the identifiers of the desired features. 286 # be an Enumarable object containing the identifiers of the desired features.
283 # Passing <tt>nil</tt> is the same as passing an empty Array. 287 # Passing <tt>nil</tt> is the same as passing an empty Array.
app/models/person.rb
@@ -4,6 +4,20 @@ class Person &lt; Profile @@ -4,6 +4,20 @@ class Person &lt; Profile
4 acts_as_trackable :after_add => Proc.new {|p,t| notify_activity(t)} 4 acts_as_trackable :after_add => Proc.new {|p,t| notify_activity(t)}
5 acts_as_accessor 5 acts_as_accessor
6 6
  7 + @@human_names = {}
  8 +
  9 + def self.human_names
  10 + @@human_names
  11 + end
  12 +
  13 + # FIXME ugly workaround
  14 + def self.human_attribute_name(attrib)
  15 + human_names.each do |key, human_text|
  16 + return human_text if attrib.to_sym == key.to_sym
  17 + end
  18 + super
  19 + end
  20 +
7 named_scope :members_of, lambda { |resource| { :select => 'DISTINCT profiles.*', :joins => :role_assignments, :conditions => ['role_assignments.resource_type = ? AND role_assignments.resource_id = ?', resource.class.base_class.name, resource.id ] } } 21 named_scope :members_of, lambda { |resource| { :select => 'DISTINCT profiles.*', :joins => :role_assignments, :conditions => ['role_assignments.resource_type = ? AND role_assignments.resource_id = ?', resource.class.base_class.name, resource.id ] } }
8 22
9 def memberships 23 def memberships
app/views/account/_signup_form.rhtml
@@ -49,9 +49,15 @@ @@ -49,9 +49,15 @@
49 :loading => "jQuery('#user_email').removeClass('#{validation_classes}').addClass('checking'); 49 :loading => "jQuery('#user_email').removeClass('#{validation_classes}').addClass('checking');
50 jQuery('#email-check').html('<p><span class=\"checking\">#{checking_message(:email)}</span></p>');", 50 jQuery('#email-check').html('<p><span class=\"checking\">#{checking_message(:email)}</span></p>');",
51 :complete => "jQuery('#user_email').removeClass('checking')", 51 :complete => "jQuery('#user_email').removeClass('checking')",
52 - :before => "if (!( jQuery('#user_email').valid() )) {  
53 - jQuery('#user_email').removeClass('#{validation_classes}').addClass('unavailable');  
54 - jQuery('#email-check').html('<p><span class=\"unavailable\">#{_('This e-mail address is not valid')}</span></p>'); 52 + :before => "var field = jQuery('#user_email');
  53 + if (field.val()=='') {
  54 + field.removeClass('#{validation_classes}');
  55 + jQuery('#email-check').html('<p>&nbsp;</p>');
  56 + return false;
  57 + }
  58 + if (!( field.valid() )) {
  59 + field.removeClass('#{validation_classes}').addClass('invalid');
  60 + jQuery('#email-check').html('<p><span class=\"invalid\">#{_('This e-mail address is not valid')}</span></p>');
55 return false; 61 return false;
56 }" 62 }"
57 %> 63 %>
@@ -67,6 +73,10 @@ @@ -67,6 +73,10 @@
67 <%= render :partial => 'profile_editor/person_form', :locals => {:f => f} %> 73 <%= render :partial => 'profile_editor/person_form', :locals => {:f => f} %>
68 <% end %> 74 <% end %>
69 75
  76 +
  77 +
  78 + <%= @plugins.dispatch(:signup_extra_contents).collect { |content| instance_eval(&content) }.join("") %>
  79 +
70 <% unless @terms_of_use.blank? %> 80 <% unless @terms_of_use.blank? %>
71 <div id='terms-of-use-box' class='formfieldline'> 81 <div id='terms-of-use-box' class='formfieldline'>
72 <%= labelled_check_box(_('I accept the %s') % link_to(_('terms of use'), {:controller => 'home', :action => 'terms'}, :target => '_blank'), 'user[terms_accepted]') %> 82 <%= labelled_check_box(_('I accept the %s') % link_to(_('terms of use'), {:controller => 'home', :action => 'terms'}, :target => '_blank'), 'user[terms_accepted]') %>
@@ -139,13 +149,13 @@ jQuery(function($) { @@ -139,13 +149,13 @@ jQuery(function($) {
139 $('#user_password_confirmation_clear').show(); 149 $('#user_password_confirmation_clear').show();
140 $('#user_password_confirmation').hide(); 150 $('#user_password_confirmation').hide();
141 } else if ($('#user_password_confirmation').val() == $('#user_pw').val()) { 151 } else if ($('#user_password_confirmation').val() == $('#user_pw').val()) {
142 - $('#user_password_confirmation').addClass('passwords_match').removeClass('passwords_differ'); 152 + $('#user_password_confirmation').addClass('validated').removeClass('invalid');
143 $('#user_pw').removeClass('invalid_input').addClass('valid_input'); 153 $('#user_pw').removeClass('invalid_input').addClass('valid_input');
144 $('#password-check').html("<p>&nbsp;</p>"); 154 $('#password-check').html("<p>&nbsp;</p>");
145 } else if ($('#user_password_confirmation').val() != $('#user_pw').val()) { 155 } else if ($('#user_password_confirmation').val() != $('#user_pw').val()) {
146 - $('#user_password_confirmation').removeClass('passwords_match').addClass('passwords_differ'); 156 + $('#user_password_confirmation').removeClass('validated').addClass('invalid');
147 $('#user_pw').addClass('invalid_input').removeClass('valid_input'); 157 $('#user_pw').addClass('invalid_input').removeClass('valid_input');
148 - $('#password-check').html("<p><span class='unavailable'><%= _('Passwords dont match') %></span></p>"); 158 + $('#password-check').html("<p><span class='invalid'><%= _('Passwords dont match') %></span></p>");
149 } 159 }
150 $('#password-balloon').fadeOut('slow'); 160 $('#password-balloon').fadeOut('slow');
151 }); 161 });
app/views/friends/index.rhtml
@@ -14,7 +14,9 @@ @@ -14,7 +14,9 @@
14 <% button_bar do %> 14 <% button_bar do %>
15 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %> 15 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
16 <%= button(:search, _('Find people'), :controller => 'search', :action => 'assets', :asset => 'people') %> 16 <%= button(:search, _('Find people'), :controller => 'search', :action => 'assets', :asset => 'people') %>
17 - <%= button(:search, _('Invite people from my e-mail contacts'), :controller => 'invite', :action => 'select_address_book') %> 17 + <% if !@plugins.dispatch(:remove_invite_friends_button).include?(true) %>
  18 + <%= button(:search, _('Invite people from my e-mail contacts'), :controller => 'invite', :action => 'select_address_book') %>
  19 + <% end %>
18 <% end %> 20 <% end %>
19 <% end %> 21 <% end %>
20 22
@@ -43,7 +45,9 @@ @@ -43,7 +45,9 @@
43 <% button_bar do %> 45 <% button_bar do %>
44 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %> 46 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
45 <%= button(:search, _('Find people'), :controller => 'search', :action => 'assets', :asset => 'people') %> 47 <%= button(:search, _('Find people'), :controller => 'search', :action => 'assets', :asset => 'people') %>
46 - <%= button(:search, _('Invite people from my e-mail contacts'), :controller => 'invite', :action => 'select_address_book') %> 48 + <% if !@plugins.dispatch(:remove_invite_friends_button).include?(true) %>
  49 + <%= button(:search, _('Invite people from my e-mail contacts'), :controller => 'invite', :action => 'select_address_book') %>
  50 + <% end %>
47 <% end %> 51 <% end %>
48 <% end %> 52 <% end %>
49 53
app/views/profile_editor/_organization.rhtml
@@ -4,6 +4,8 @@ @@ -4,6 +4,8 @@
4 4
5 <%= required f.text_field(:name) %> 5 <%= required f.text_field(:name) %>
6 6
  7 + <%= @plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_eval(&content) }.join("") %>
  8 +
7 <% if @environment.enabled?('enable_organization_url_change') %> 9 <% if @environment.enabled?('enable_organization_url_change') %>
8 <script type="text/javascript"> 10 <script type="text/javascript">
9 function updateUrlField(name_field, id) { 11 function updateUrlField(name_field, id) {
app/views/profile_editor/_person.rhtml
@@ -6,4 +6,6 @@ @@ -6,4 +6,6 @@
6 6
7 <%= required f.text_field(:email) %> 7 <%= required f.text_field(:email) %>
8 8
  9 + <%= @plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_eval(&content) }.join("") %>
  10 +
9 <%= render :partial => 'person_form', :locals => {:f => f} %> 11 <%= render :partial => 'person_form', :locals => {:f => f} %>
lib/noosfero/plugin.rb
@@ -238,4 +238,22 @@ class Noosfero::Plugin @@ -238,4 +238,22 @@ class Noosfero::Plugin
238 def comment_saved(comment) 238 def comment_saved(comment)
239 end 239 end
240 240
  241 + # -> Adds fields to the signup form
  242 + # returns = lambda block that creates a html code
  243 + def signup_extra_contents
  244 + nil
  245 + end
  246 +
  247 + # -> Adds adicional content to profile info
  248 + # returns = lambda block that creates a html code
  249 + def profile_info_extra_contents
  250 + nil
  251 + end
  252 +
  253 + # -> Removes the invite friend button from the friends controller
  254 + # returns = boolean
  255 + def remove_invite_friends_button
  256 + nil
  257 + end
  258 +
241 end 259 end
lib/noosfero/plugin/routes.rb
1 Dir.glob(File.join(Rails.root, 'config', 'plugins', '*', 'controllers')) do |dir| 1 Dir.glob(File.join(Rails.root, 'config', 'plugins', '*', 'controllers')) do |dir|
2 plugin_name = File.basename(File.dirname(dir)) 2 plugin_name = File.basename(File.dirname(dir))
3 - map.connect 'plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_environment' 3 + map.connect 'plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin'
4 map.connect 'profile/:profile/plugins/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_profile' 4 map.connect 'profile/:profile/plugins/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_profile'
5 map.connect 'myprofile/:profile/plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_myprofile' 5 map.connect 'myprofile/:profile/plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_myprofile'
6 map.connect 'admin/plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_admin' 6 map.connect 'admin/plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_admin'
plugins/bsc/controllers/bsc_plugin_admin_controller.rb 0 → 100644
@@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
  1 +class BscPluginAdminController < AdminController
  2 +
  3 + include BscPlugin::BscHelper
  4 +
  5 + def new
  6 + @bsc = BscPlugin::Bsc.new(params[:profile_data])
  7 + if request.post? && @bsc.valid?
  8 + @bsc.user = current_user
  9 + @bsc.save!
  10 + @bsc.add_admin(user)
  11 + session[:notice] = _('Your Bsc was created.')
  12 + redirect_to :controller => 'profile_editor', :profile => @bsc.identifier
  13 + end
  14 + end
  15 +
  16 + def save_validations
  17 + enterprises = [Enterprise.find(params[:q].split(','))].flatten
  18 +
  19 + begin
  20 + enterprises.each { |enterprise| enterprise.validated = true ; enterprise.save! }
  21 + session[:notice] = _('Enterprises validated.')
  22 + redirect_to :controller => 'admin_panel'
  23 + rescue Exception => ex
  24 + session[:notice] = _('Enterprise validations couldn\'t be saved.')
  25 + logger.info ex
  26 + redirect_to :action => 'validate_enterprises'
  27 + end
  28 + end
  29 +
  30 + def search_enterprise
  31 + render :text => Enterprise.not_validated.find(:all, :conditions => ["type <> 'BscPlugin::Bsc' AND (name LIKE ? OR identifier LIKE ?)", "%#{params[:q]}%", "%#{params[:q]}%"]).
  32 + map {|enterprise| {:id => enterprise.id, :name => enterprise.name} }.
  33 + to_json
  34 + end
  35 +
  36 +end
  37 +
plugins/bsc/controllers/bsc_plugin_environment_controller.rb
@@ -1,37 +0,0 @@ @@ -1,37 +0,0 @@
1 -class BscPluginEnvironmentController < AdminController  
2 -  
3 - include BscPlugin::BscHelper  
4 -  
5 - def new  
6 - @bsc = BscPlugin::Bsc.new(params[:profile_data])  
7 - if request.post? && @bsc.valid?  
8 - @bsc.user = current_user  
9 - @bsc.save!  
10 - @bsc.add_admin(user)  
11 - session[:notice] = _('Your Bsc was created.')  
12 - redirect_to :controller => 'profile_editor', :profile => @bsc.identifier  
13 - end  
14 - end  
15 -  
16 - def save_validations  
17 - enterprises = [Enterprise.find(params[:q].split(','))].flatten  
18 -  
19 - begin  
20 - enterprises.each { |enterprise| enterprise.validated = true ; enterprise.save! }  
21 - session[:notice] = _('Enterprises validated.')  
22 - redirect_to :controller => 'admin_panel'  
23 - rescue Exception => ex  
24 - session[:notice] = _('Enterprise validations couldn\'t be saved.')  
25 - logger.info ex  
26 - redirect_to :action => 'validate_enterprises'  
27 - end  
28 - end  
29 -  
30 - def search_enterprise  
31 - render :text => Enterprise.not_validated.find(:all, :conditions => ["type <> 'BscPlugin::Bsc' AND (name LIKE ? OR identifier LIKE ?)", "%#{params[:q]}%", "%#{params[:q]}%"]).  
32 - map {|enterprise| {:id => enterprise.id, :name => enterprise.name} }.  
33 - to_json  
34 - end  
35 -  
36 -end  
37 -  
plugins/bsc/lib/bsc_plugin.rb
@@ -14,8 +14,8 @@ class BscPlugin &lt; Noosfero::Plugin @@ -14,8 +14,8 @@ class BscPlugin &lt; Noosfero::Plugin
14 end 14 end
15 15
16 def admin_panel_links 16 def admin_panel_links
17 - [{:title => _('Create Bsc'), :url => {:controller => 'bsc_plugin_environment', :action => 'new'}},  
18 - {:title => _('Validate Enterprises'), :url => {:controller => 'bsc_plugin_environment', :action => 'validate_enterprises'}} ] 17 + [{:title => _('Create Bsc'), :url => {:controller => 'bsc_plugin_admin', :action => 'new'}},
  18 + {:title => _('Validate Enterprises'), :url => {:controller => 'bsc_plugin_admin', :action => 'validate_enterprises'}} ]
19 end 19 end
20 20
21 def control_panel_buttons 21 def control_panel_buttons
plugins/bsc/test/functional/bsc_plugin_admin_controller_test.rb 0 → 100644
@@ -0,0 +1,82 @@ @@ -0,0 +1,82 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +require File.dirname(__FILE__) + '/../../controllers/bsc_plugin_admin_controller'
  3 +require File.dirname(__FILE__) + '/../../../../app/models/uploaded_file'
  4 +
  5 +# Re-raise errors caught by the controller.
  6 +class BscPluginAdminController; def rescue_action(e) raise e end; end
  7 +
  8 +class BscPluginAdminControllerTest < ActionController::TestCase
  9 +
  10 + VALID_CNPJ = '94.132.024/0001-48'
  11 +
  12 + def setup
  13 + @controller = BscPluginAdminController.new
  14 + @request = ActionController::TestRequest.new
  15 + @response = ActionController::TestResponse.new
  16 + user_login = create_admin_user(Environment.default)
  17 + login_as(user_login)
  18 + @admin = User[user_login].person
  19 + e = Environment.default
  20 + e.enabled_plugins = ['BscPlugin']
  21 + e.save!
  22 + end
  23 +
  24 + attr_accessor :admin
  25 +
  26 + should 'create a new bsc' do
  27 + assert_difference BscPlugin::Bsc, :count, 1 do
  28 + post :new, :profile_data => {:business_name => 'Sample Bsc', :identifier => 'sample-bsc', :company_name => 'Sample Bsc Ltda.', :cnpj => VALID_CNPJ}
  29 + end
  30 +
  31 + assert_redirected_to :controller => 'profile_editor', :profile => 'sample-bsc'
  32 + end
  33 +
  34 + should 'not create an invalid bsc' do
  35 + assert_difference BscPlugin::Bsc, :count, 0 do
  36 + post :new, :profile_data => {:business_name => 'Sample Bsc', :identifier => 'sample-bsc', :company_name => 'Sample Bsc Ltda.', :cnpj => '29837492304'}
  37 + end
  38 +
  39 + assert_response 200
  40 + end
  41 +
  42 + should 'set the current user as the bsc admin' do
  43 + name = 'Sample Bsc'
  44 + post :new, :profile_data => {:business_name => name, :identifier => 'sample-bsc', :company_name => 'Sample Bsc Ltda.', :cnpj => VALID_CNPJ}
  45 + bsc = BscPlugin::Bsc.find_by_name(name)
  46 + assert_includes bsc.admins, admin
  47 + end
  48 +
  49 + should 'list correct enterprises on search' do
  50 + # Should list if: not validated AND (name matches OR identifier matches) AND not bsc
  51 + e1 = Enterprise.create!(:name => 'Sample Enterprise 1', :identifier => 'bli', :validated => false)
  52 + e2 = Enterprise.create!(:name => 'Bla', :identifier => 'sample-enterprise-6', :validated => false)
  53 + e3 = Enterprise.create!(:name => 'Blo', :identifier => 'blo', :validated => false)
  54 + e4 = BscPlugin::Bsc.create!(:business_name => "Sample Bsc", :identifier => 'sample-bsc', :company_name => 'Sample Bsc Ltda.', :cnpj => VALID_CNPJ, :validated => false)
  55 + e5 = Enterprise.create!(:name => 'Sample Enterprise 5', :identifier => 'sample-enterprise-5')
  56 + e5.validated = true
  57 + e5.save!
  58 +
  59 + get :search_enterprise, :q => 'sampl'
  60 +
  61 + assert_match /#{e1.name}/, @response.body
  62 + assert_match /#{e2.name}/, @response.body
  63 + assert_no_match /#{e3.name}/, @response.body
  64 + assert_no_match /#{e4.name}/, @response.body
  65 + assert_no_match /#{e5.name}/, @response.body
  66 + end
  67 +
  68 + should 'save validations' do
  69 + e1 = fast_create(Enterprise, :validated => false)
  70 + e2 = fast_create(Enterprise, :validated => false)
  71 + e3 = fast_create(Enterprise, :validated => false)
  72 +
  73 + post :save_validations, :q => "#{e1.id},#{e2.id}"
  74 + e1.reload
  75 + e2.reload
  76 + e3.reload
  77 +
  78 + assert e1.validated
  79 + assert e2.validated
  80 + assert !e3.validated
  81 + end
  82 +end
plugins/bsc/test/functional/bsc_plugin_environment_controller_test.rb
@@ -1,82 +0,0 @@ @@ -1,82 +0,0 @@
1 -require File.dirname(__FILE__) + '/../../../../test/test_helper'  
2 -require File.dirname(__FILE__) + '/../../controllers/bsc_plugin_environment_controller'  
3 -require File.dirname(__FILE__) + '/../../../../app/models/uploaded_file'  
4 -  
5 -# Re-raise errors caught by the controller.  
6 -class BscPluginEnvironmentController; def rescue_action(e) raise e end; end  
7 -  
8 -class BscPluginEnvironmentControllerTest < ActionController::TestCase  
9 -  
10 - VALID_CNPJ = '94.132.024/0001-48'  
11 -  
12 - def setup  
13 - @controller = BscPluginEnvironmentController.new  
14 - @request = ActionController::TestRequest.new  
15 - @response = ActionController::TestResponse.new  
16 - user_login = create_admin_user(Environment.default)  
17 - login_as(user_login)  
18 - @admin = User[user_login].person  
19 - e = Environment.default  
20 - e.enabled_plugins = ['BscPlugin']  
21 - e.save!  
22 - end  
23 -  
24 - attr_accessor :admin  
25 -  
26 - should 'create a new bsc' do  
27 - assert_difference BscPlugin::Bsc, :count, 1 do  
28 - post :new, :profile_data => {:business_name => 'Sample Bsc', :identifier => 'sample-bsc', :company_name => 'Sample Bsc Ltda.', :cnpj => VALID_CNPJ}  
29 - end  
30 -  
31 - assert_redirected_to :controller => 'profile_editor', :profile => 'sample-bsc'  
32 - end  
33 -  
34 - should 'not create an invalid bsc' do  
35 - assert_difference BscPlugin::Bsc, :count, 0 do  
36 - post :new, :profile_data => {:business_name => 'Sample Bsc', :identifier => 'sample-bsc', :company_name => 'Sample Bsc Ltda.', :cnpj => '29837492304'}  
37 - end  
38 -  
39 - assert_response 200  
40 - end  
41 -  
42 - should 'set the current user as the bsc admin' do  
43 - name = 'Sample Bsc'  
44 - post :new, :profile_data => {:business_name => name, :identifier => 'sample-bsc', :company_name => 'Sample Bsc Ltda.', :cnpj => VALID_CNPJ}  
45 - bsc = BscPlugin::Bsc.find_by_name(name)  
46 - assert_includes bsc.admins, admin  
47 - end  
48 -  
49 - should 'list correct enterprises on search' do  
50 - # Should list if: not validated AND (name matches OR identifier matches) AND not bsc  
51 - e1 = Enterprise.create!(:name => 'Sample Enterprise 1', :identifier => 'bli', :validated => false)  
52 - e2 = Enterprise.create!(:name => 'Bla', :identifier => 'sample-enterprise-6', :validated => false)  
53 - e3 = Enterprise.create!(:name => 'Blo', :identifier => 'blo', :validated => false)  
54 - e4 = BscPlugin::Bsc.create!(:business_name => "Sample Bsc", :identifier => 'sample-bsc', :company_name => 'Sample Bsc Ltda.', :cnpj => VALID_CNPJ, :validated => false)  
55 - e5 = Enterprise.create!(:name => 'Sample Enterprise 5', :identifier => 'sample-enterprise-5')  
56 - e5.validated = true  
57 - e5.save!  
58 -  
59 - get :search_enterprise, :q => 'sampl'  
60 -  
61 - assert_match /#{e1.name}/, @response.body  
62 - assert_match /#{e2.name}/, @response.body  
63 - assert_no_match /#{e3.name}/, @response.body  
64 - assert_no_match /#{e4.name}/, @response.body  
65 - assert_no_match /#{e5.name}/, @response.body  
66 - end  
67 -  
68 - should 'save validations' do  
69 - e1 = fast_create(Enterprise, :validated => false)  
70 - e2 = fast_create(Enterprise, :validated => false)  
71 - e3 = fast_create(Enterprise, :validated => false)  
72 -  
73 - post :save_validations, :q => "#{e1.id},#{e2.id}"  
74 - e1.reload  
75 - e2.reload  
76 - e3.reload  
77 -  
78 - assert e1.validated  
79 - assert e2.validated  
80 - assert !e3.validated  
81 - end  
82 -end  
plugins/bsc/views/bsc_plugin_admin/new.html.erb 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +<%= error_messages_for :bsc %>
  2 +<h1><%= _('BSC registration') %></h1>
  3 +
  4 +<% labelled_form_for :profile_data, @bsc do |f| %>
  5 + <%= render :partial => 'shared/fields', :locals => {:f => f, :profile => @bsc} %>
  6 +
  7 + <% button_bar do %>
  8 + <%= submit_button('save', _('Save')) %>
  9 + <%= button('cancel', _('Cancel'), {:controller => 'admin_panel'}) %>
  10 + <% end %>
  11 +<% end %>
plugins/bsc/views/bsc_plugin_admin/validate_enterprises.html.erb 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +<h1><%= _('Validate enterprises') %></h1>
  2 +
  3 +<% form_tag :action => 'save_validations' do %>
  4 + <%= token_input_field_tag(:q, 'search-enterprises', {:action => 'search_enterprise'},
  5 + { :hint_text => _('Type in a search term for enterprise'),
  6 + :focus => true }) %>
  7 +
  8 + <% button_bar do %>
  9 + <%= submit_button('save', _('Save'))%>
  10 + <%= button('cancel', _('Cancel'), {:controller => 'admin_panel'})%>
  11 + <% end %>
  12 +<% end %>
plugins/bsc/views/bsc_plugin_environment/new.html.erb
@@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
1 -<%= error_messages_for :bsc %>  
2 -<h1><%= _('BSC registration') %></h1>  
3 -  
4 -<% labelled_form_for :profile_data, @bsc do |f| %>  
5 - <%= render :partial => 'shared/fields', :locals => {:f => f, :profile => @bsc} %>  
6 -  
7 - <% button_bar do %>  
8 - <%= submit_button('save', _('Save')) %>  
9 - <%= button('cancel', _('Cancel'), {:controller => 'admin_panel'}) %>  
10 - <% end %>  
11 -<% end %>  
plugins/bsc/views/bsc_plugin_environment/validate_enterprises.html.erb
@@ -1,12 +0,0 @@ @@ -1,12 +0,0 @@
1 -<h1><%= _('Validate enterprises') %></h1>  
2 -  
3 -<% form_tag :action => 'save_validations' do %>  
4 - <%= token_input_field_tag(:q, 'search-enterprises', {:action => 'search_enterprise'},  
5 - { :hint_text => _('Type in a search term for enterprise'),  
6 - :focus => true }) %>  
7 -  
8 - <% button_bar do %>  
9 - <%= submit_button('save', _('Save'))%>  
10 - <%= button('cancel', _('Cancel'), {:controller => 'admin_panel'})%>  
11 - <% end %>  
12 -<% end %>  
plugins/stoa/README 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +Banco de Dados
  2 +==============
  3 +
  4 +É preciso adicionar uma seção definindo a conexão com o banco de usuários da USP, no arquivo config/database.yml com identificador stoa.
  5 +``
  6 +stoa:
  7 + adapter: mysql
  8 + host: db2.stoa.usp.br
  9 + database: usp
  10 + username: <usuario>
  11 + password: <senha>
  12 +``
plugins/stoa/controllers/stoa_plugin_controller.rb 0 → 100644
@@ -0,0 +1,43 @@ @@ -0,0 +1,43 @@
  1 +class StoaPluginController < PublicController
  2 + append_view_path File.join(File.dirname(__FILE__) + '/../views')
  3 +
  4 + def authenticate
  5 + if request.ssl? && request.post?
  6 + user = User.authenticate(params[:login], params[:password], environment)
  7 + if user
  8 + result = {
  9 + :username => user.login,
  10 + :email => user.email,
  11 + :name => user.name,
  12 + :nusp => user.person.usp_id,
  13 + :first_name => user.name.split(' ').first,
  14 + :surname => user.name.split(' ',2).last,
  15 + :address => user.person.address,
  16 + :homepage => url_for(user.person.url),
  17 + }
  18 + else
  19 + result = { :error => _('Incorrect user/password pair.') }
  20 + end
  21 + render :text => result.to_json
  22 + else
  23 + render :text => { :error => _('Conection requires SSL certificate and post method.') }.to_json
  24 + end
  25 + end
  26 +
  27 + def check_usp_id
  28 + begin
  29 + render :text => { :exists => StoaPlugin::UspUser.exists?(params[:usp_id]) && Person.find_by_usp_id(params[:usp_id]).nil? }.to_json
  30 + rescue Exception => exception
  31 + render :text => { :exists => false, :error => {:message => exception.to_s, :backtrace => exception.backtrace} }.to_json
  32 + end
  33 + end
  34 +
  35 + def check_cpf
  36 + begin
  37 + render :text => { :exists => !StoaPlugin::UspUser.find_by_codpes(params[:usp_id]).cpf.blank? }.to_json
  38 + rescue Exception => exception
  39 + render :text => { :exists => false, :error => {:message => exception.to_s, :backtrace => exception.backtrace} }.to_json
  40 + end
  41 + end
  42 +
  43 +end
plugins/stoa/db/migrate/20120301212702_add_usp_id_to_profile.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +class AddUspIdToProfile < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :profiles, :usp_id, :string
  4 + end
  5 +
  6 + def self.down
  7 + remove_column :profiles, :usp_id
  8 + end
  9 +end
plugins/stoa/lib/ext/person.rb 0 → 100644
@@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
  1 +require_dependency 'person'
  2 +
  3 +class Person
  4 + validates_uniqueness_of :usp_id, :allow_nil => true
  5 + settings_items :invitation_code
  6 + validate :usp_id_or_invitation, :if => lambda { |person| person.environment && person.environment.plugin_enabled?(StoaPlugin)}
  7 +
  8 + def usp_id_or_invitation
  9 + if usp_id.blank? && (invitation_code.blank? || !invitation_task)
  10 + errors.add(:usp_id, "can't register without usp_id or invitation")
  11 + end
  12 + end
  13 +
  14 + def invitation_task
  15 + Task.pending.find(:first, :conditions => {:code => invitation_code}) ||
  16 + Task.finished.find(:first, :conditions => {:code => invitation_code, :target_id => id})
  17 + end
  18 +end
plugins/stoa/lib/stoa_plugin.rb 0 → 100644
@@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
  1 +require_dependency 'person'
  2 +require_dependency 'ext/person'
  3 +
  4 +class StoaPlugin < Noosfero::Plugin
  5 +
  6 + Person.human_names[:usp_id] = _('USP number')
  7 +
  8 + def self.plugin_name
  9 + "Stoa"
  10 + end
  11 +
  12 + def self.plugin_description
  13 + _("Add Stoa features")
  14 + end
  15 +
  16 + def stylesheet?
  17 + true
  18 + end
  19 +
  20 + def signup_extra_contents
  21 + lambda {
  22 + labelled_form_field(_('USP number'), text_field_tag('profile_data[usp_id]', '', :id => 'usp_id_field')) +
  23 + content_tag(:small, _('The usp id grants you special powers in the network. Don\'t forget to fill it if you have one.'), :id => 'usp-id-balloon') +
  24 + content_tag('div', required(labelled_form_field(_('Birth date (yyyy-mm-dd)'), text_field_tag('birth_date', ''))), :id => 'signup-birth-date', :style => 'display: none') +
  25 + content_tag('div', required(labelled_form_field(_('CPF'), text_field_tag('cpf', ''))), :id => 'signup-cpf', :style => 'display:none') +
  26 + javascript_include_tag('../plugins/stoa/javascripts/jquery.observe_field', '../plugins/stoa/javascripts/signup_complement')
  27 + }
  28 + end
  29 +
  30 + def profile_info_extra_contents
  31 + lambda {
  32 + labelled_form_field(_('USP number'), text_field_tag('profile_data[usp_id]', '', :id => 'usp_id_field')) +
  33 + content_tag(:small, _('The usp id grants you special powers in the network. Don\'t forget to fill it if you have one.')) +
  34 + content_tag('div', required(labelled_form_field(_('Birth date (yyyy-mm-dd)'), text_field_tag('birth_date', ''))), :id => 'signup-birth-date', :style => 'display: none') +
  35 + content_tag('div', required(labelled_form_field(_('CPF'), text_field_tag('cpf', ''))), :id => 'signup-cpf', :style => 'display:none') +
  36 + javascript_include_tag('../plugins/stoa/javascripts/jquery.observe_field', '../plugins/stoa/javascripts/signup_complement')
  37 + } if context.profile.person? && context.profile.usp_id.blank?
  38 + end
  39 +
  40 + def account_controller_filters
  41 + block = lambda do
  42 + params[:profile_data] ||= {}
  43 + params[:profile_data][:invitation_code] = params[:invitation_code]
  44 + if request.post?
  45 + if !params[:invitation_code] && !StoaPlugin::UspUser.matches?(params[:profile_data][:usp_id], params[:confirmation_field], params[params[:confirmation_field]])
  46 + @person = Person.new
  47 + @person.errors.add(:usp_id, _(' validation failed'))
  48 + render :action => :signup
  49 + end
  50 + end
  51 + end
  52 +
  53 + [{ :type => 'before_filter',
  54 + :method_name => 'validate_usp_id',
  55 + :options => {:only => 'signup'},
  56 + :block => block }]
  57 + end
  58 +
  59 + def profile_editor_controller_filters
  60 + block = lambda do
  61 + if request.post?
  62 + if !params[:profile_data][:usp_id].blank? && !StoaPlugin::UspUser.matches?(params[:profile_data][:usp_id], params[:confirmation_field], params[params[:confirmation_field]])
  63 + @profile_data = profile
  64 + @profile_data.attributes = params[:profile_data]
  65 + @profile_data.valid?
  66 + @profile_data.errors.add(:usp_id, _(' validation failed'))
  67 + @profile_data.usp_id = nil
  68 + @possible_domains = profile.possible_domains
  69 + render :action => :edit
  70 + end
  71 + end
  72 + end
  73 +
  74 + [{ :type => 'before_filter',
  75 + :method_name => 'validate_usp_id',
  76 + :options => {:only => 'edit'},
  77 + :block => block }]
  78 + end
  79 +
  80 + def invite_controller_filters
  81 + [{ :type => 'before_filter',
  82 + :method_name => 'check_usp_id_existence',
  83 + :block => lambda {render_access_denied if profile.usp_id.blank?} }]
  84 + end
  85 +
  86 + def control_panel_buttons
  87 + { :title => _('Invite friends'),
  88 + :icon => 'invite-friends',
  89 + :url => {:controller => 'invite',
  90 + :action => 'select_address_book'} } if !context.profile.usp_id.blank?
  91 + end
  92 +
  93 + def remove_invite_friends_button
  94 + true
  95 + end
  96 +
  97 +end
plugins/stoa/lib/stoa_plugin/usp_user.rb 0 → 100644
@@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
  1 +class StoaPlugin::UspUser < ActiveRecord::Base
  2 +
  3 + establish_connection(:stoa)
  4 + set_table_name('pessoa')
  5 +
  6 + SALT=YAML::load(File.open(StoaPlugin.root_path + '/config.yml'))['salt']
  7 +
  8 + alias_attribute :cpf, :numcpf
  9 + alias_attribute :birth_date, :dtanas
  10 +
  11 + def self.exists?(usp_id)
  12 + !StoaPlugin::UspUser.find(:first, :conditions => {:codpes => usp_id.to_i}).nil?
  13 + end
  14 +
  15 + def self.matches?(usp_id, field, value)
  16 + user = StoaPlugin::UspUser.find(:first, :conditions => {:codpes => usp_id.to_i})
  17 + return false if user.nil? || !user.respond_to?(field) || value.blank?
  18 + case field.to_sym
  19 + when :cpf
  20 + user.cpf == Digest::MD5.hexdigest(SALT+value.to_i.to_s)
  21 + when :birth_date
  22 + user.birth_date.to_s == value
  23 + end
  24 + end
  25 +
  26 +end
plugins/stoa/public/images/control-panel/invite-friends.gif 0 → 100644

1.97 KB

plugins/stoa/public/images/control-panel/invite-friends.png 0 → 100644

3.66 KB

plugins/stoa/public/images/grey-bg.png 0 → 100644

187 Bytes

plugins/stoa/public/javascripts/jquery.observe_field.js 0 → 100644
@@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
  1 +// jquery.observe_field.js
  2 +
  3 +
  4 +(function( $ ){
  5 +
  6 + jQuery.fn.observe_field = function(frequency, callback) {
  7 +
  8 + frequency = frequency * 1000; // translate to milliseconds
  9 +
  10 + return this.each(function(){
  11 + var $this = $(this);
  12 + var prev = $this.val();
  13 +
  14 + var check = function() {
  15 + var val = $this.val();
  16 + if(prev != val){
  17 + prev = val;
  18 + $this.map(callback); // invokes the callback on $this
  19 + }
  20 + };
  21 +
  22 + var reset = function() {
  23 + if(ti){
  24 + clearInterval(ti);
  25 + ti = setInterval(check, frequency);
  26 + }
  27 + };
  28 +
  29 + check();
  30 + var ti = setInterval(check, frequency); // invoke check periodically
  31 +
  32 + // reset counter after user interaction
  33 + $this.bind('keyup click mousemove', reset); //mousemove is for selects
  34 + });
  35 +
  36 + };
  37 +
  38 +})( jQuery );
  39 +
plugins/stoa/public/javascripts/signup_complement.js 0 → 100644
@@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
  1 +jQuery("#usp_id_field").observe_field(1, function(){
  2 + var me=this;
  3 + jQuery(this).addClass('checking').removeClass('validated');
  4 + jQuery(this.parentNode).addClass('checking')
  5 + jQuery.getJSON('/plugin/stoa/check_usp_id?usp_id='+me.value,
  6 + function(data){
  7 + if(data.exists) {
  8 + jQuery.getJSON('/plugin/stoa/check_cpf?usp_id='+me.value,
  9 + function(data){
  10 + if(data.exists){
  11 + jQuery('#signup-birth-date').hide();
  12 + jQuery('#signup-cpf').show();
  13 + jQuery('#confirmation_field').remove();
  14 + jQuery('#signup-form').append('<input id="confirmation_field" type="hidden" value="cpf" name="confirmation_field">')
  15 + }
  16 + else {
  17 + jQuery('#signup-cpf').hide();
  18 + jQuery('#signup-birth-date').show();
  19 + jQuery('#confirmation_field').remove();
  20 + jQuery('#signup-form').append('<input id="confirmation_field" type="hidden" value="birth_date" name="confirmation_field">')
  21 + }
  22 + jQuery('#signup-form .submit').attr('disabled', false);
  23 + jQuery(me).removeClass('checking').addClass('validated');
  24 + jQuery(me.parentNode).removeClass('checking')
  25 + });
  26 + }
  27 + else {
  28 + jQuery(me).removeClass('checking');
  29 + jQuery(me.parentNode).removeClass('checking')
  30 + if(me.value) {
  31 + jQuery('#signup-form .submit').attr('disabled', true);
  32 + jQuery(me).addClass('invalid');
  33 + }
  34 + else {
  35 + jQuery('#signup-form .submit').attr('disabled', false);
  36 + jQuery(me).removeClass('invalid');
  37 + jQuery(me).removeClass('validated');
  38 + }
  39 + jQuery('#signup-birth-date').hide();
  40 + jQuery('#signup-cpf').hide();
  41 + }
  42 + if(data.error) displayValidationUspIdError(data.error);
  43 + }
  44 + );
  45 +});
  46 +
  47 +function displayValidationUspIdError(error){
  48 + jQuery.colorbox({html: '<h2>'+error.message+'</h2>'+error.backtrace.join("<br />"),
  49 + height: "80%",
  50 + width: "70%" });
  51 +}
  52 +
  53 +jQuery('#usp_id_field').focus(function() {
  54 + jQuery('#usp-id-balloon').fadeIn('slow');
  55 +});
  56 +
  57 +jQuery('#usp_id_field').blur(function() { jQuery('#usp-id-balloon').fadeOut('slow'); });
plugins/stoa/public/style.css 0 → 100644
@@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
  1 +#signup-form label[for="usp_id_field"],
  2 +#signup-form label[for="cpf"],
  3 +#signup-form label[for="birth_date"] {
  4 + display: block;
  5 +}
  6 +
  7 +#content #signup-form input.submit[disabled=""] {
  8 + background-image: url(/plugins/stoa/images/grey-bg.png);
  9 + text-shadow: 0 -1px 0 #686156;
  10 + cursor: default;
  11 +}
  12 +
  13 +.controller-profile_editor a.control-panel-invite-friends {background-image: url(../../plugins/stoa/images/control-panel/invite-friends.png)}
  14 +.controller-profile_editor .msie6 a.control-panel-invite-friends {background-image: url(../../plugins/stoa/images/control-panel/invite-friends.gif)}
  15 +
  16 +#signup-form small#usp-id-balloon {
  17 + display: none;
  18 + width: 142px;
  19 + height: 69px;
  20 + color: #FFFFFF;
  21 + font-weight: bold;
  22 + font-size: 11px;
  23 + padding: 5px 10px 45px 10px;
  24 + margin: 0;
  25 + line-height: 1.5em;
  26 + background: transparent url(/images/orange-balloon.png) bottom center no-repeat;
  27 + position: absolute;
  28 + z-index: 2;
  29 + right: 20px;
  30 + bottom: 110px;
  31 +}
  32 +
  33 +.controller-profile_editor input.checking {
  34 + cursor: progress;
  35 +}
  36 +
  37 +.controller-profile_editor div.checking {
  38 + background: transparent url(/images/loading-small.gif) 153px center no-repeat;
  39 +}
plugins/stoa/test/functional/account_controller_test.rb 0 → 100644
@@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +require File.dirname(__FILE__) + '/../../../../app/controllers/public/account_controller'
  3 +
  4 +# Re-raise errors caught by the controller.
  5 +class AccountController; def rescue_action(e) raise e end; end
  6 +
  7 +class AccountControllerTest < ActionController::TestCase
  8 +
  9 + SALT=YAML::load(File.open(StoaPlugin.root_path + '/config.yml'))['salt']
  10 +
  11 + def setup
  12 + @controller = AccountController.new
  13 + @request = ActionController::TestRequest.new
  14 + @response = ActionController::TestResponse.new
  15 + @db = Tempfile.new('stoa-test')
  16 + configs = ActiveRecord::Base.configurations['stoa'] = {:adapter => 'sqlite3', :database => @db.path}
  17 + ActiveRecord::Base.establish_connection(:stoa)
  18 + ActiveRecord::Schema.verbose = false
  19 + ActiveRecord::Schema.create_table "pessoa" do |t|
  20 + t.integer "codpes"
  21 + t.text "numcpf"
  22 + t.date "dtanas"
  23 + end
  24 + ActiveRecord::Base.establish_connection(:test)
  25 + StoaPlugin::UspUser.create!(:codpes => 12345678, :cpf => Digest::MD5.hexdigest(SALT+'12345678'), :birth_date => '1970-01-30')
  26 + Environment.default.enable_plugin(StoaPlugin.name)
  27 + end
  28 +
  29 + def teardown
  30 + @db.unlink
  31 + end
  32 +
  33 + should 'fail if confirmation value doesn\'t match' do
  34 + #StoaPlugin::UspUser.stubs(:matches?).returns(false)
  35 + post :signup, :profile_data => {:usp_id => '12345678'}, :confirmation_field => 'cpf', :cpf => '00000000'
  36 + assert_not_nil assigns(:person).errors[:usp_id]
  37 + end
  38 +
  39 + should 'pass if confirmation value matches' do
  40 + #StoaPlugin::UspUser.stubs(:matches?).returns(true)
  41 + post :signup, :profile_data => {:usp_id => '12345678'}, :confirmation_field => 'cpf', :cpf => '12345678'
  42 + assert_nil assigns(:person).errors[:usp_id]
  43 + end
  44 +
  45 + should 'inlude invitation_code param in the person\'s attributes' do
  46 + get :signup, :invitation_code => 12345678
  47 + assert assigns(:person).invitation_code == '12345678'
  48 + end
  49 +
  50 +end
plugins/stoa/test/functional/invite_controller_test.rb 0 → 100644
@@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +require File.dirname(__FILE__) + '/../../../../app/controllers/public/invite_controller'
  3 +
  4 +# Re-raise errors caught by the controller.
  5 +class InviteController; def rescue_action(e) raise e end; end
  6 +
  7 +class InviteControllerTest < ActionController::TestCase
  8 +
  9 + def setup
  10 + @controller = InviteController.new
  11 + @request = ActionController::TestRequest.new
  12 + @response = ActionController::TestResponse.new
  13 + environment = Environment.default
  14 + environment.enabled_plugins = ['StoaPlugin']
  15 + environment.save!
  16 + end
  17 +
  18 + should 'not enable access to invitation if the user has not an usp_id' do
  19 + Task.create!(:code => 12345678)
  20 + person_without_usp_id = User.create!(:login => 'user-without', :email => 'user-without@example.com', :password => 'test', :password_confirmation => 'test', :person_data => {:invitation_code => 12345678}).person
  21 +
  22 + login_as(person_without_usp_id.identifier)
  23 + get :select_address_book, :profile => person_without_usp_id.identifier
  24 + assert_response 403
  25 + get :select_friends, :profile => person_without_usp_id.identifier
  26 + assert_response 403
  27 + end
  28 +
  29 + should 'enable access to invitation if the user has an usp_id' do
  30 + person_with_usp_id = User.create!(:login => 'user-with', :email => 'user-with@example.com', :password => 'test', :password_confirmation => 'test', :person_data => {:usp_id => 12345678}).person
  31 +
  32 + login_as(person_with_usp_id.identifier)
  33 + get :select_address_book, :profile => person_with_usp_id.identifier
  34 + assert_response 200
  35 + get :select_friends, :profile => person_with_usp_id.identifier, :contact_list => ContactList.create.id
  36 + assert_response 200
  37 + end
  38 +
  39 +end
  40 +
plugins/stoa/test/functional/profile_editor_controller.rb 0 → 100644
@@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +require File.dirname(__FILE__) + '/../../../../app/controllers/my_profile/profile_editor_controller'
  3 +
  4 +# Re-raise errors caught by the controller.
  5 +class ProfileEditorController; def rescue_action(e) raise e end; end
  6 +
  7 +class ProfileEditorTest < ActionController::TestCase
  8 +
  9 + SALT=YAML::load(File.open(StoaPlugin.root_path + '/config.yml'))['salt']
  10 +
  11 + def setup
  12 + @controller = ProfileEditorController.new
  13 + @request = ActionController::TestRequest.new
  14 + @response = ActionController::TestResponse.new
  15 + @person = User.create(:login => 'test_user', :email => 'test_user@example.com', :password => 'test', :password_confirmation => 'test').person
  16 + login_as(@person.identifier)
  17 + Environment.default.enable_plugin(StoaPlugin.name)
  18 + db = Tempfile.new('stoa-test')
  19 + ActiveRecord::Base.configurations['stoa'] = {:adapter => 'sqlite3', :database => db.path}
  20 + end
  21 +
  22 + attr_accessor :person
  23 +
  24 + should 'show usp_id field if person did not filled it' do
  25 + get :edit, :profile => person.identifier
  26 + assert_match /USP number/, @response.body
  27 + end
  28 +
  29 + should 'not show usp_id field if person already filled it' do
  30 + person.usp_id = 12345
  31 + person.save
  32 + get :edit, :profile => person.identifier
  33 + assert_no_match /USP number/, @response.body
  34 + end
  35 +
  36 + should 'not display field if profile is an organization' do
  37 + organization = fast_create(Organization)
  38 + get :edit, :profile => organization.identifier
  39 + assert_no_match /USP number/, @response.body
  40 + end
  41 +
  42 + should 'display error if usp_id does not match with supplied confirmation' do
  43 + StoaPlugin::UspUser.stubs(:matches?).returns(false)
  44 + post :edit, :profile => person.identifier, :profile_data => {:usp_id => 12345678}, :confirmation_field => 'cpf', :cpf => 99999999
  45 + assert assigns(:profile_data).errors.invalid?(:usp_id)
  46 + end
  47 +
  48 + should 'save usp_id if everyhtings is ok' do
  49 + StoaPlugin::UspUser.stubs(:matches?).returns(true)
  50 + post :edit, :profile => person.identifier, :profile_data => {:usp_id => 12345678}, :confirmation_field => 'cpf', :cpf => 99999999
  51 + person.reload
  52 + assert_equal '12345678', person.usp_id
  53 + end
  54 +
  55 +end
plugins/stoa/test/functional/stoa_plugin_controller_test.rb 0 → 100644
@@ -0,0 +1,100 @@ @@ -0,0 +1,100 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +require File.dirname(__FILE__) + '/../../controllers/stoa_plugin_controller'
  3 +
  4 +# Re-raise errors caught by the controller.
  5 +class StoaPluginController; def rescue_action(e) raise e end; end
  6 +
  7 +class StoaPluginControllerTest < ActionController::TestCase
  8 +
  9 + SALT=YAML::load(File.open(StoaPlugin.root_path + '/config.yml'))['salt']
  10 +
  11 + def setup
  12 + @controller = StoaPluginController.new
  13 + @request = ActionController::TestRequest.new
  14 + @response = ActionController::TestResponse.new
  15 + @db = Tempfile.new('stoa-test')
  16 + configs = ActiveRecord::Base.configurations['stoa'] = {:adapter => 'sqlite3', :database => @db.path}
  17 + ActiveRecord::Base.establish_connection(:stoa)
  18 + ActiveRecord::Schema.verbose = false
  19 + ActiveRecord::Schema.create_table "pessoa" do |t|
  20 + t.integer "codpes"
  21 + t.text "numcpf"
  22 + t.date "dtanas"
  23 + end
  24 + ActiveRecord::Base.establish_connection(:test)
  25 + env = Environment.default
  26 + env.enable_plugin(StoaPlugin.name)
  27 + env.enable('skip_new_user_email_confirmation')
  28 + env.save!
  29 + @user = create_user_full('real_user', {:password => '123456', :password_confirmation => '123456'}, {:usp_id => 9999999})
  30 + StoaPlugin::UspUser.create!(:codpes => 12345678, :cpf => Digest::MD5.hexdigest(SALT+'12345678'), :birth_date => '1970-01-30')
  31 + end
  32 +
  33 + def teardown
  34 + @db.unlink
  35 + @user.destroy
  36 + end
  37 +
  38 + attr_accessor :user
  39 +
  40 + should 'not authenticate if method not post' do
  41 + @request.stubs(:ssl?).returns(true)
  42 + get :authenticate, :login => user.login, :password => '123456'
  43 +
  44 + assert_not_nil json_response['error']
  45 + assert_match /post method/,json_response['error']
  46 + end
  47 +
  48 + should 'not authenticate if request is not using ssl' do
  49 + @request.stubs(:ssl?).returns(false)
  50 + post :authenticate, :login => user.login, :password => '123456'
  51 +
  52 + assert_not_nil json_response['error']
  53 + assert_match /SSL/,json_response['error']
  54 + end
  55 +
  56 + should 'not authenticate if method password is wrong' do
  57 + @request.stubs(:ssl?).returns(true)
  58 + post :authenticate, :login => user.login, :password => 'wrong_password'
  59 +
  60 + assert_not_nil json_response['error']
  61 + assert_match /password/,json_response['error']
  62 + end
  63 +
  64 + should 'authenticate if everything is right' do
  65 + @request.stubs(:ssl?).returns(true)
  66 + post :authenticate, :login => user.login, :password => '123456'
  67 +
  68 + assert_nil json_response['error']
  69 + assert_equal user.login, json_response['username']
  70 + end
  71 +
  72 + should 'check valid usp id' do
  73 + get :check_usp_id, :usp_id => '12345678'
  74 + assert json_response['exists']
  75 + end
  76 +
  77 + should 'check invalid usp id' do
  78 + get :check_usp_id, :usp_id => '87654321'
  79 + assert !json_response['exists']
  80 + end
  81 +
  82 + should 'check existent cpf' do
  83 + get :check_cpf, :usp_id => '12345678'
  84 + assert json_response['exists']
  85 + end
  86 +
  87 + should 'check not existent cpf' do
  88 + StoaPlugin::UspUser.create(:codpes => 87654321, :birth_date => '1970-01-30')
  89 + get :check_cpf, :usp_id => '87654321'
  90 + assert !json_response['exists']
  91 + end
  92 +
  93 + private
  94 +
  95 + def json_response
  96 + ActiveSupport::JSON.decode @response.body
  97 + end
  98 +
  99 +end
  100 +
plugins/stoa/test/unit/person_test.rb 0 → 100644
@@ -0,0 +1,65 @@ @@ -0,0 +1,65 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +
  3 +class StoaPlugin::Person < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @environment = Environment.default
  7 + @environment.enable_plugin(StoaPlugin)
  8 + end
  9 +
  10 + attr_reader :environment
  11 +
  12 + should 'validates uniqueness of usp_id' do
  13 + usp_id = 87654321
  14 + fast_create(Person, :usp_id => usp_id)
  15 + another_person = Person.new(:usp_id => usp_id)
  16 + another_person.valid?
  17 +
  18 + assert another_person.errors.invalid?(:usp_id)
  19 + end
  20 +
  21 + should 'allow nil usp_id only if person has an invitation_code' do
  22 + person = Person.new(:environment => environment)
  23 + person.valid?
  24 + assert person.errors.invalid?(:usp_id)
  25 +
  26 + Task.create!(:code => 12345678)
  27 + person.invitation_code = 12345678
  28 + person.valid?
  29 +
  30 + assert !person.errors.invalid?(:usp_id)
  31 + end
  32 +
  33 + should 'allow multiple nil usp_id' do
  34 + fast_create(Person)
  35 + Task.create!(:code => 87654321)
  36 + person = Person.new(:invitation_code => 87654321)
  37 + person.valid?
  38 +
  39 + assert !person.errors.invalid?(:usp_id)
  40 + end
  41 +
  42 + should 'not allow person to be saved with a finished invitation that is not his own' do
  43 + t = Task.create!(:code => 87654321, :target_id => 1)
  44 + t.finish
  45 + person = Person.new(:environment => environment, :invitation_code => 87654321)
  46 + person.valid?
  47 +
  48 + assert person.errors.invalid?(:usp_id)
  49 + end
  50 +
  51 + should 'allow person to be saved with a finished invitation if it is his own' do
  52 + t = Task.create!(:code => 87654321)
  53 + user = User.new(:login => 'some-person', :email => 'some-person@example.com', :password => 'test', :password_confirmation => 'test', :person_data => {:environment => environment, :invitation_code => 87654321})
  54 + user.save!
  55 + person = user.person
  56 + t.target_id = person.id
  57 + t.finish
  58 +
  59 + person.valid?
  60 + assert !person.errors.invalid?(:usp_id)
  61 + end
  62 +
  63 +
  64 +end
  65 +
plugins/stoa/test/unit/usp_user_test.rb 0 → 100644
@@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +
  3 +class StoaPlugin::UspUserTest < ActiveSupport::TestCase
  4 +
  5 + SALT=YAML::load(File.open(StoaPlugin.root_path + '/config.yml'))['salt']
  6 +
  7 + def setup
  8 + @db = Tempfile.new('stoa-test')
  9 + configs = ActiveRecord::Base.configurations['stoa'] = {:adapter => 'sqlite3', :database => @db.path}
  10 + ActiveRecord::Base.establish_connection(:stoa)
  11 + ActiveRecord::Schema.verbose = false
  12 + ActiveRecord::Schema.create_table "pessoa" do |t|
  13 + t.integer "codpes"
  14 + t.text "numcpf"
  15 + t.date "dtanas"
  16 + end
  17 + ActiveRecord::Base.establish_connection(:test)
  18 + StoaPlugin::UspUser.create!(:codpes => 123456, :cpf => Digest::MD5.hexdigest(SALT+'12345678'), :birth_date => '1970-01-30')
  19 + end
  20 +
  21 + def teardown
  22 + @db.unlink
  23 + end
  24 +
  25 + should 'check existence of usp_id' do
  26 + assert StoaPlugin::UspUser.exists?(123456)
  27 + assert !StoaPlugin::UspUser.exists?(654321)
  28 + end
  29 +
  30 + should 'check if usp_id matches with a cpf' do
  31 + assert StoaPlugin::UspUser.matches?(123456, :cpf, 12345678)
  32 + assert !StoaPlugin::UspUser.matches?(123456, :cpf, 87654321)
  33 + assert !StoaPlugin::UspUser.matches?(654321, :cpf, 12345678)
  34 + end
  35 +
  36 + should 'check if usp_id matches with a birth_date' do
  37 + assert StoaPlugin::UspUser.matches?(123456, :birth_date, '1970-01-30')
  38 + assert !StoaPlugin::UspUser.matches?(123456, :birth_date, '1999-01-30')
  39 + assert !StoaPlugin::UspUser.matches?(654321, :birth_date, '1970-01-30')
  40 + end
  41 +
  42 + should 'filter leading zeroes of id codes on exists and matches' do
  43 + assert StoaPlugin::UspUser.exists?('0000123456')
  44 + assert StoaPlugin::UspUser.matches?(123456, :cpf, '00012345678')
  45 + end
  46 +end
  47 +
public/stylesheets/application.css
@@ -6500,14 +6500,14 @@ h1#agenda-title { @@ -6500,14 +6500,14 @@ h1#agenda-title {
6500 margin-left: 12px; 6500 margin-left: 12px;
6501 } 6501 }
6502 6502
6503 -.action-account-signup #wrap-1 label,  
6504 -.action-account-signup #wrap-1 small,  
6505 -.action-account-signup #wrap-1 #user_password,  
6506 -.action-account-signup #wrap-1 #user_password_confirmation { 6503 +#signup-form label,
  6504 +#signup-form small,
  6505 +#signup-form #user_password,
  6506 +#signup-form #user_password_confirmation {
6507 display: none; 6507 display: none;
6508 } 6508 }
6509 6509
6510 -.action-account-signup #wrap-1 #signup-form-header { 6510 +#signup-form #signup-form-header {
6511 background: #E3E3E3; 6511 background: #E3E3E3;
6512 padding: 22px 0; 6512 padding: 22px 0;
6513 -moz-border-radius: 8px; 6513 -moz-border-radius: 8px;
@@ -6518,24 +6518,24 @@ h1#agenda-title { @@ -6518,24 +6518,24 @@ h1#agenda-title {
6518 width: 563px; 6518 width: 563px;
6519 } 6519 }
6520 6520
6521 -.action-account-signup #wrap-1 .formfield input.invalid_input { 6521 +#signup-form input.invalid_input {
6522 border: 2px solid #FFA000; 6522 border: 2px solid #FFA000;
6523 background: #FFF; 6523 background: #FFF;
6524 padding: 5px 30px 8px 5px; 6524 padding: 5px 30px 8px 5px;
6525 } 6525 }
6526 6526
6527 -.action-account-signup #wrap-1 .formfield input.valid_input { 6527 +#signup-form input.valid_input {
6528 border: 2px solid #88BD00; 6528 border: 2px solid #88BD00;
6529 background: #FFF; 6529 background: #FFF;
6530 padding: 5px 30px 8px 5px; 6530 padding: 5px 30px 8px 5px;
6531 } 6531 }
6532 6532
6533 -.action-account-signup #wrap-1 .formfield select,  
6534 -.action-account-signup #wrap-1 .formfield textarea,  
6535 -.action-account-signup #wrap-1 #profile_data_name,  
6536 -.action-account-signup #wrap-1 .formfield input { 6533 +#signup-form select,
  6534 +#signup-form textarea,
  6535 +#signup-form #profile_data_name,
  6536 +#signup-form input {
6537 background: transparent url(/images/field-bg.png) left top no-repeat; 6537 background: transparent url(/images/field-bg.png) left top no-repeat;
6538 - padding: 7px 3px 10px 7px; 6538 + padding: 7px 30px 10px 7px;
6539 height: 24px; 6539 height: 24px;
6540 width: 335px; 6540 width: 335px;
6541 color: #6d786e; 6541 color: #6d786e;
@@ -6543,71 +6543,62 @@ h1#agenda-title { @@ -6543,71 +6543,62 @@ h1#agenda-title {
6543 font-family: droidserif, serif; 6543 font-family: droidserif, serif;
6544 margin: 9px 14px 0; 6544 margin: 9px 14px 0;
6545 border: 0; 6545 border: 0;
6546 - padding-right: 30px;  
6547 } 6546 }
6548 6547
6549 -.action-account-signup #wrap-1 #user_login.checking,  
6550 -.action-account-signup #wrap-1 #user_login.available,  
6551 -.action-account-signup #wrap-1 #user_login.unavailable,  
6552 -.action-account-signup #wrap-1 #user_email.checking,  
6553 -.action-account-signup #wrap-1 #user_email.available,  
6554 -.action-account-signup #wrap-1 #user_email.unavailable,  
6555 -.action-account-signup #wrap-1 .formfield input.passwords_differ,  
6556 -.action-account-signup #wrap-1 .formfield input.passwords_match { 6548 +#signup-form #user_password,
  6549 +#signup-form #user_password_confirmation,
  6550 +#signup-form .filled-in,
  6551 +#signup-form .passwords_match,
  6552 +#signup-form .invalid,
  6553 +#signup-form .checking {
6557 border-width: 2px; 6554 border-width: 2px;
6558 border-style: solid; 6555 border-style: solid;
6559 background-color: #fff; 6556 background-color: #fff;
6560 background-position: right center; 6557 background-position: right center;
6561 background-repeat: no-repeat; 6558 background-repeat: no-repeat;
6562 padding: 5px 30px 8px 5px; 6559 padding: 5px 30px 8px 5px;
  6560 + color: #4A4A4A;
6563 } 6561 }
6564 6562
6565 -.action-account-signup #wrap-1 .formfield select.filled-in,  
6566 -.action-account-signup #wrap-1 .formfield textarea.filled-in,  
6567 -.action-account-signup #wrap-1 #profile_data_name.filled-in,  
6568 -.action-account-signup #wrap-1 .formfield input.filled-in {  
6569 - color: #4A4A4A;  
6570 -}  
6571 -  
6572 -.action-account-signup #wrap-1 .formfield select { 6563 +#signup-form select {
6573 height: auto; 6564 height: auto;
6574 padding-right: 3px; 6565 padding-right: 3px;
6575 width: 365px; 6566 width: 365px;
6576 } 6567 }
6577 6568
6578 -.action-account-signup #wrap-1 .formfield .select-birth-date select { 6569 +#signup-form .select-birth-date select {
6579 width: 93px; 6570 width: 93px;
6580 margin-right: 2px; 6571 margin-right: 2px;
6581 margin-left: 0; 6572 margin-left: 0;
6582 } 6573 }
6583 6574
6584 -.webkit.action-account-signup #wrap-1 .formfield select { 6575 +.webkit #signup-form select {
6585 background: #fff; 6576 background: #fff;
6586 } 6577 }
6587 6578
6588 -.action-account-signup #wrap-1 .formfield textarea { 6579 +#signup-form textarea {
6589 background: #fff; 6580 background: #fff;
6590 height: 100px; 6581 height: 100px;
6591 padding-right: 3px; 6582 padding-right: 3px;
6592 width: 365px; 6583 width: 365px;
6593 } 6584 }
6594 6585
6595 -.action-account-signup #wrap-1 .formfield input[type=file] { 6586 +#signup-form input[type=file] {
6596 font-size: 12px; 6587 font-size: 12px;
6597 } 6588 }
6598 6589
6599 -.action-account-signup #wrap-1 input[type=radio] { 6590 +#signup-form input[type=radio] {
6600 height: auto; 6591 height: auto;
6601 margin: 0; 6592 margin: 0;
6602 margin-left: 3px; 6593 margin-left: 3px;
6603 } 6594 }
6604 6595
6605 -.action-account-signup #wrap-1 .fieldgroup { 6596 +#signup-form .fieldgroup {
6606 margin: 5px 10px; 6597 margin: 5px 10px;
6607 } 6598 }
6608 6599
6609 -.action-account-signup #wrap-1 label[for=profile_data_sex_female],  
6610 -.action-account-signup #wrap-1 label[for=profile_data_sex_male] { 6600 +#signup-form label[for=profile_data_sex_female],
  6601 +#signup-form label[for=profile_data_sex_male] {
6611 color: #6d786e; 6602 color: #6d786e;
6612 font-size: 20px; 6603 font-size: 20px;
6613 font-family: droidserif; 6604 font-family: droidserif;
@@ -6616,41 +6607,55 @@ h1#agenda-title { @@ -6616,41 +6607,55 @@ h1#agenda-title {
6616 margin-left: 8px; 6607 margin-left: 8px;
6617 } 6608 }
6618 6609
6619 -.action-account-signup #wrap-1 label[for=profile_data_country],  
6620 -.action-account-signup #wrap-1 label[for=profile_data_preferred_domain_id],  
6621 -.action-account-signup #wrap-1 label[for=profile_data_birth_date_2i],  
6622 -.action-account-signup #wrap-1 label[for=profile_data_birth_date_3i],  
6623 -.action-account-signup #wrap-1 label[for=profile_data_schooling],  
6624 -.action-account-signup #wrap-1 label[for=profile_data_formation],  
6625 -.action-account-signup #wrap-1 label[for=profile_data_area_of_study],  
6626 -.action-account-signup #wrap-1 label[for=profile_data_image_builder_uploaded_data] { 6610 +#signup-form label[for=profile_data_country],
  6611 +#signup-form label[for=profile_data_preferred_domain_id],
  6612 +#signup-form label[for=profile_data_birth_date_2i],
  6613 +#signup-form label[for=profile_data_birth_date_3i],
  6614 +#signup-form label[for=profile_data_schooling],
  6615 +#signup-form label[for=profile_data_formation],
  6616 +#signup-form label[for=profile_data_area_of_study],
  6617 +#signup-form label[for=profile_data_image_builder_uploaded_data] {
6627 display: block; 6618 display: block;
6628 } 6619 }
6629 6620
6630 -.action-account-signup #wrap-1 #profile_data_name { 6621 +#signup-form #profile_data_name {
6631 padding-left: 10px; 6622 padding-left: 10px;
6632 } 6623 }
6633 6624
6634 -.action-account-signup #wrap-1 #user_login.unavailable,  
6635 -.action-account-signup #wrap-1 #user_email.unavailable,  
6636 -.action-account-signup #wrap-1 .formfield input.passwords_differ { 6625 +#signup-form .invalid {
6637 border-color: #FFA000; 6626 border-color: #FFA000;
6638 background-image: url(/images/passwords_nomatch.png); 6627 background-image: url(/images/passwords_nomatch.png);
6639 } 6628 }
6640 6629
6641 -.action-account-signup #wrap-1 #user_email.checking,  
6642 -.action-account-signup #wrap-1 #user_login.checking { 6630 +#signup-form span.invalid {
  6631 + border: none;
  6632 + padding: 0px;
  6633 + background: transparent;
  6634 + color: #FFA000;
  6635 +}
  6636 +
  6637 +#signup-form .checking {
6643 border-color: #4A4A4A; 6638 border-color: #4A4A4A;
6644 background-image: url(/images/login_checking.png); 6639 background-image: url(/images/login_checking.png);
6645 } 6640 }
6646 6641
6647 -.action-account-signup #wrap-1 #user_login.available,  
6648 -.action-account-signup #wrap-1 #user_email.available,  
6649 -.action-account-signup #wrap-1 .formfield input.passwords_match { 6642 +#signup-form span.checking {
  6643 + border: none;
  6644 + padding: 0px;
  6645 + background: transparent;
  6646 + color: #4A4A4A;
  6647 +}
  6648 +
  6649 +#signup-form .validated {
6650 border-color: #88BD00; 6650 border-color: #88BD00;
6651 background-image: url(/images/passwords_match.png); 6651 background-image: url(/images/passwords_match.png);
6652 } 6652 }
6653 6653
  6654 +#signup-form span.validated {
  6655 + background: transparent;
  6656 + color: #88BD00;
  6657 +}
  6658 +
6654 #signup-domain { 6659 #signup-domain {
6655 float: left; 6660 float: left;
6656 display: inline-block; 6661 display: inline-block;
@@ -6669,7 +6674,7 @@ h1#agenda-title { @@ -6669,7 +6674,7 @@ h1#agenda-title {
6669 margin-left: 14px; 6674 margin-left: 14px;
6670 } 6675 }
6671 6676
6672 -.action-account-signup #wrap-1 #signup-form-header #user_login { 6677 +#signup-form #signup-form-header #user_login {
6673 margin: 0; 6678 margin: 0;
6674 width: 200px; 6679 width: 200px;
6675 padding-right: 30px; 6680 padding-right: 30px;
@@ -6683,14 +6688,14 @@ h1#agenda-title { @@ -6683,14 +6688,14 @@ h1#agenda-title {
6683 float: left; 6688 float: left;
6684 } 6689 }
6685 6690
6686 -.action-account-signup #wrap-1 #signup-password,  
6687 -.action-account-signup #wrap-1 #signup-password-confirmation,  
6688 -.action-account-signup #wrap-1 #signup-login { 6691 +#signup-form #signup-password,
  6692 +#signup-form #signup-password-confirmation,
  6693 +#signup-form #signup-login {
6689 position: relative; 6694 position: relative;
6690 } 6695 }
6691 6696
6692 -.action-account-signup #wrap-1 small#signup-balloon,  
6693 -.action-account-signup #wrap-1 small#password-balloon { 6697 +#signup-form small#signup-balloon,
  6698 +#signup-form small#password-balloon {
6694 display: none; 6699 display: none;
6695 width: 142px; 6700 width: 142px;
6696 height: 69px; 6701 height: 69px;
@@ -6707,8 +6712,8 @@ h1#agenda-title { @@ -6707,8 +6712,8 @@ h1#agenda-title {
6707 top: -100px; 6712 top: -100px;
6708 } 6713 }
6709 6714
6710 -.action-account-signup #wrap-1 .required-field label,  
6711 -.action-account-signup #wrap-1 .formlabel { 6715 +#signup-form .required-field label,
  6716 +#signup-form .formlabel {
6712 color: #b4b9b5; 6717 color: #b4b9b5;
6713 font-size: 20px; 6718 font-size: 20px;
6714 text-transform: lowercase; 6719 text-transform: lowercase;
@@ -6717,7 +6722,7 @@ h1#agenda-title { @@ -6717,7 +6722,7 @@ h1#agenda-title {
6717 font-family: droidserif; 6722 font-family: droidserif;
6718 } 6723 }
6719 6724
6720 -.action-account-signup #wrap-1 .required-field label::after { 6725 +#signup-form .required-field label::after {
6721 content: ''; 6726 content: '';
6722 } 6727 }
6723 6728
@@ -6741,16 +6746,16 @@ h1#agenda-title { @@ -6741,16 +6746,16 @@ h1#agenda-title {
6741 background: #FFF; 6746 background: #FFF;
6742 } 6747 }
6743 6748
6744 -.action-account-signup #terms-of-use-box label { 6749 +#signup-form #terms-of-use-box label {
6745 display: inline; 6750 display: inline;
6746 font-size: 16px; 6751 font-size: 16px;
6747 } 6752 }
6748 6753
6749 -.action-account-signup #terms-of-use-box label a { 6754 +#signup-form #terms-of-use-box label a {
6750 color: #FF7F2A; 6755 color: #FF7F2A;
6751 } 6756 }
6752 6757
6753 -.action-account-signup #content form input.button.submit { 6758 +#content #signup-form .submit {
6754 border: 0; 6759 border: 0;
6755 padding: 8px 36px 12px; 6760 padding: 8px 36px 12px;
6756 background: transparent url(/images/orange-bg.png) left center repeat-x; 6761 background: transparent url(/images/orange-bg.png) left center repeat-x;
@@ -6784,7 +6789,7 @@ h1#agenda-title { @@ -6784,7 +6789,7 @@ h1#agenda-title {
6784 text-align: center; 6789 text-align: center;
6785 } 6790 }
6786 6791
6787 -.action-account-signup .formfieldline { 6792 +#signup-form .formfieldline {
6788 padding: 0; 6793 padding: 0;
6789 } 6794 }
6790 6795
test/factories.rb
@@ -80,8 +80,8 @@ module Noosfero::Factory @@ -80,8 +80,8 @@ module Noosfero::Factory
80 :password_confirmation => name.underscore 80 :password_confirmation => name.underscore
81 }.merge(options) 81 }.merge(options)
82 user = User.new(data) 82 user = User.new(data)
  83 + user.person = Person.new(person_options)
83 user.save! 84 user.save!
84 - user.person.update_attributes!(person_data.merge(person_options))  
85 user 85 user
86 end 86 end
87 87
test/functional/account_controller_test.rb
@@ -622,14 +622,14 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -622,14 +622,14 @@ class AccountControllerTest &lt; ActionController::TestCase
622 @controller.expects(:environment).returns(env).at_least_once 622 @controller.expects(:environment).returns(env).at_least_once
623 profile = create_user('mylogin').person 623 profile = create_user('mylogin').person
624 get :check_url, :identifier => 'mylogin' 624 get :check_url, :identifier => 'mylogin'
625 - assert_equal 'available', assigns(:status_class) 625 + assert_equal 'validated', assigns(:status_class)
626 end 626 end
627 627
628 should 'check if url is not available on environment' do 628 should 'check if url is not available on environment' do
629 @controller.expects(:environment).returns(Environment.default).at_least_once 629 @controller.expects(:environment).returns(Environment.default).at_least_once
630 profile = create_user('mylogin').person 630 profile = create_user('mylogin').person
631 get :check_url, :identifier => 'mylogin' 631 get :check_url, :identifier => 'mylogin'
632 - assert_equal 'unavailable', assigns(:status_class) 632 + assert_equal 'invalid', assigns(:status_class)
633 end 633 end
634 634
635 should 'check if e-mail is available on environment' do 635 should 'check if e-mail is available on environment' do
@@ -637,7 +637,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -637,7 +637,7 @@ class AccountControllerTest &lt; ActionController::TestCase
637 @controller.expects(:environment).returns(env).at_least_once 637 @controller.expects(:environment).returns(env).at_least_once
638 profile = create_user('mylogin', :email => 'mylogin@noosfero.org', :environment_id => fast_create(Environment).id) 638 profile = create_user('mylogin', :email => 'mylogin@noosfero.org', :environment_id => fast_create(Environment).id)
639 get :check_email, :address => 'mylogin@noosfero.org' 639 get :check_email, :address => 'mylogin@noosfero.org'
640 - assert_equal 'available', assigns(:status_class) 640 + assert_equal 'validated', assigns(:status_class)
641 end 641 end
642 642
643 should 'check if e-mail is not available on environment' do 643 should 'check if e-mail is not available on environment' do
@@ -645,7 +645,7 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -645,7 +645,7 @@ class AccountControllerTest &lt; ActionController::TestCase
645 @controller.expects(:environment).returns(env).at_least_once 645 @controller.expects(:environment).returns(env).at_least_once
646 profile = create_user('mylogin', :email => 'mylogin@noosfero.org', :environment_id => env) 646 profile = create_user('mylogin', :email => 'mylogin@noosfero.org', :environment_id => env)
647 get :check_email, :address => 'mylogin@noosfero.org' 647 get :check_email, :address => 'mylogin@noosfero.org'
648 - assert_equal 'unavailable', assigns(:status_class) 648 + assert_equal 'invalid', assigns(:status_class)
649 end 649 end
650 650
651 should 'merge user data with extra stuff from plugins' do 651 should 'merge user data with extra stuff from plugins' do
@@ -747,6 +747,27 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -747,6 +747,27 @@ class AccountControllerTest &lt; ActionController::TestCase
747 assert_not_nil assigns(:current_user) 747 assert_not_nil assigns(:current_user)
748 end 748 end
749 749
  750 + should 'add extra content on signup forms from plugins' do
  751 + class Plugin1 < Noosfero::Plugin
  752 + def signup_extra_contents
  753 + lambda {"<strong>Plugin1 text</strong>"}
  754 + end
  755 + end
  756 + class Plugin2 < Noosfero::Plugin
  757 + def signup_extra_contents
  758 + lambda {"<strong>Plugin2 text</strong>"}
  759 + end
  760 + end
  761 +
  762 + Environment.default.enable_plugin(Plugin1.name)
  763 + Environment.default.enable_plugin(Plugin2.name)
  764 +
  765 + get :signup
  766 +
  767 + assert_tag :tag => 'strong', :content => 'Plugin1 text'
  768 + assert_tag :tag => 'strong', :content => 'Plugin2 text'
  769 + end
  770 +
750 protected 771 protected
751 def new_user(options = {}, extra_options ={}) 772 def new_user(options = {}, extra_options ={})
752 data = {:profile_data => person_data} 773 data = {:profile_data => person_data}
test/functional/friends_controller_test.rb
@@ -57,4 +57,24 @@ class FriendsControllerTest &lt; ActionController::TestCase @@ -57,4 +57,24 @@ class FriendsControllerTest &lt; ActionController::TestCase
57 assert_tag :tag => 'a', :content => 'Find people', :attributes => { :href => '/assets/people' } 57 assert_tag :tag => 'a', :content => 'Find people', :attributes => { :href => '/assets/people' }
58 end 58 end
59 59
  60 + should 'not display invite friends button if any plugin tells not to' do
  61 + class Plugin1 < Noosfero::Plugin
  62 + def remove_invite_friends_button
  63 + true
  64 + end
  65 + end
  66 + class Plugin2 < Noosfero::Plugin
  67 + def remove_invite_friends_button
  68 + false
  69 + end
  70 + end
  71 +
  72 + e = profile.environment
  73 + e.enable_plugin(Plugin1.name)
  74 + e.enable_plugin(Plugin2.name)
  75 +
  76 + get :index, :profile => 'testuser'
  77 + assert_no_tag :tag => 'a', :attributes => { :href => "/profile/testuser/invite/friends" }
  78 + end
  79 +
60 end 80 end
test/functional/profile_editor_controller_test.rb
@@ -907,4 +907,47 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase @@ -907,4 +907,47 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
907 assert_tag :tag => 'div', :attributes => { :id => 'profile_change_picture' } 907 assert_tag :tag => 'div', :attributes => { :id => 'profile_change_picture' }
908 end 908 end
909 909
  910 + should 'add extra content on person info from plugins' do
  911 + class Plugin1 < Noosfero::Plugin
  912 + def profile_info_extra_contents
  913 + lambda {"<strong>Plugin1 text</strong>"}
  914 + end
  915 + end
  916 + class Plugin2 < Noosfero::Plugin
  917 + def profile_info_extra_contents
  918 + lambda {"<strong>Plugin2 text</strong>"}
  919 + end
  920 + end
  921 +
  922 + Environment.default.enable_plugin(Plugin1)
  923 + Environment.default.enable_plugin(Plugin2)
  924 +
  925 + get :edit, :profile => profile.identifier
  926 +
  927 + assert_tag :tag => 'strong', :content => 'Plugin1 text'
  928 + assert_tag :tag => 'strong', :content => 'Plugin2 text'
  929 + end
  930 +
  931 + should 'add extra content on organization info from plugins' do
  932 + class Plugin1 < Noosfero::Plugin
  933 + def profile_info_extra_contents
  934 + lambda {"<strong>Plugin1 text</strong>"}
  935 + end
  936 + end
  937 + class Plugin2 < Noosfero::Plugin
  938 + def profile_info_extra_contents
  939 + lambda {"<strong>Plugin2 text</strong>"}
  940 + end
  941 + end
  942 +
  943 + Environment.default.enable_plugin(Plugin1)
  944 + Environment.default.enable_plugin(Plugin2)
  945 + organization = fast_create(Community)
  946 +
  947 + get :edit, :profile => organization.identifier
  948 +
  949 + assert_tag :tag => 'strong', :content => 'Plugin1 text'
  950 + assert_tag :tag => 'strong', :content => 'Plugin2 text'
  951 + end
  952 +
910 end 953 end
test/unit/environment_test.rb
@@ -1187,17 +1187,18 @@ class EnvironmentTest &lt; ActiveSupport::TestCase @@ -1187,17 +1187,18 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
1187 assert !environment.errors.invalid?(:reports_lower_bound) 1187 assert !environment.errors.invalid?(:reports_lower_bound)
1188 end 1188 end
1189 1189
1190 - should 'be able to enable or disable a plugin' do 1190 + should 'be able to enable or disable a plugin with the class or class name' do
  1191 + class Plugin
  1192 + end
1191 environment = Environment.default 1193 environment = Environment.default
1192 - plugin = 'Plugin'  
1193 1194
1194 - environment.enable_plugin(plugin) 1195 + environment.enable_plugin(Plugin)
1195 environment.reload 1196 environment.reload
1196 - assert_includes environment.enabled_plugins, plugin 1197 + assert environment.plugin_enabled?(Plugin.to_s)
1197 1198
1198 - environment.disable_plugin(plugin) 1199 + environment.disable_plugin(Plugin.to_s)
1199 environment.reload 1200 environment.reload
1200 - assert_not_includes environment.enabled_plugins, plugin 1201 + assert !environment.plugin_enabled?(Plugin)
1201 end 1202 end
1202 1203
1203 should 'have production costs' do 1204 should 'have production costs' do