Commit 36360403cd4b0b3398eca8066d945263683a2af3

Authored by Joenio Costa
2 parents 5d77e0b5 647ca1a5

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

app/controllers/public/account_controller.rb
@@ -16,6 +16,17 @@ class AccountController < ApplicationController @@ -16,6 +16,17 @@ class AccountController < ApplicationController
16 end 16 end
17 end 17 end
18 18
  19 + def activate
  20 + @user = User.find_by_activation_code(params[:activation_code]) if params[:activation_code]
  21 + if @user and @user.activate
  22 + @message = _("Your account has been activated, now you can log in!")
  23 + render :action => 'login', :userlogin => @user.login
  24 + else
  25 + session[:notice] = _("It looks like you're trying to activate an account. Perhaps have already activated this account?")
  26 + redirect_to :controller => :home
  27 + end
  28 + end
  29 +
19 # action to perform login to the application 30 # action to perform login to the application
20 def login 31 def login
21 @user = User.new 32 @user = User.new
@@ -60,7 +71,6 @@ class AccountController < ApplicationController @@ -60,7 +71,6 @@ class AccountController < ApplicationController
60 @person.environment = @user.environment 71 @person.environment = @user.environment
61 if request.post? && params[self.icaptcha_field].blank? 72 if request.post? && params[self.icaptcha_field].blank?
62 @user.signup! 73 @user.signup!
63 - self.current_user = @user  
64 owner_role = Role.find_by_name('owner') 74 owner_role = Role.find_by_name('owner')
65 @user.person.affiliate(@user.person, [owner_role]) if owner_role 75 @user.person.affiliate(@user.person, [owner_role]) if owner_role
66 invitation = Task.find_by_code(@invitation_code) 76 invitation = Task.find_by_code(@invitation_code)
@@ -68,8 +78,7 @@ class AccountController < ApplicationController @@ -68,8 +78,7 @@ class AccountController < ApplicationController
68 invitation.update_attributes!({:friend => @user.person}) 78 invitation.update_attributes!({:friend => @user.person})
69 invitation.finish 79 invitation.finish
70 end 80 end
71 - session[:notice] = _("Thanks for signing up!")  
72 - go_to_initial_page if redirect? 81 + @register_pending = true
73 end 82 end
74 rescue ActiveRecord::RecordInvalid 83 rescue ActiveRecord::RecordInvalid
75 @person.valid? 84 @person.valid?
app/models/user.rb
@@ -21,6 +21,8 @@ class User < ActiveRecord::Base @@ -21,6 +21,8 @@ class User < ActiveRecord::Base
21 end 21 end
22 end 22 end
23 23
  24 + before_create :make_activation_code
  25 +
24 before_create do |user| 26 before_create do |user|
25 if user.environment.nil? 27 if user.environment.nil?
26 user.environment = Environment.default 28 user.environment = Environment.default
@@ -31,8 +33,11 @@ class User < ActiveRecord::Base @@ -31,8 +33,11 @@ class User < ActiveRecord::Base
31 user.person ||= Person.new 33 user.person ||= Person.new
32 user.person.attributes = user.person_data.merge(:identifier => user.login, :user_id => user.id, :environment_id => user.environment_id) 34 user.person.attributes = user.person_data.merge(:identifier => user.login, :user_id => user.id, :environment_id => user.environment_id)
33 user.person.name ||= user.login 35 user.person.name ||= user.login
  36 + user.person.visible = false unless user.activated?
34 user.person.save! 37 user.person.save!
35 end 38 end
  39 + after_create :deliver_activation_code
  40 + after_create :delay_activation_check
36 41
37 attr_writer :person_data 42 attr_writer :person_data
38 def person_data 43 def person_data
@@ -55,6 +60,17 @@ class User < ActiveRecord::Base @@ -55,6 +60,17 @@ class User < ActiveRecord::Base
55 :environment => user.environment.name, 60 :environment => user.environment.name,
56 :url => url_for(:host => user.environment.default_hostname, :controller => 'home') 61 :url => url_for(:host => user.environment.default_hostname, :controller => 'home')
57 end 62 end
  63 +
  64 + def activation_code(user)
  65 + recipients user.email
  66 +
  67 + from "#{user.environment.name} <#{user.environment.contact_email}>"
  68 + subject _("[%s] Activate your account") % [user.environment.name]
  69 + body :recipient => user.name,
  70 + :activation_code => user.activation_code,
  71 + :environment => user.environment.name,
  72 + :url => user.environment.top_url
  73 + end
58 end 74 end
59 75
60 def signup! 76 def signup!
@@ -67,6 +83,8 @@ class User &lt; ActiveRecord::Base @@ -67,6 +83,8 @@ class User &lt; ActiveRecord::Base
67 has_one :person, :dependent => :destroy 83 has_one :person, :dependent => :destroy
68 belongs_to :environment 84 belongs_to :environment
69 85
  86 + attr_protected :activated_at
  87 +
70 # Virtual attribute for the unencrypted password 88 # Virtual attribute for the unencrypted password
71 attr_accessor :password 89 attr_accessor :password
72 90
@@ -87,10 +105,22 @@ class User &lt; ActiveRecord::Base @@ -87,10 +105,22 @@ class User &lt; ActiveRecord::Base
87 # Authenticates a user by their login name and unencrypted password. Returns the user or nil. 105 # Authenticates a user by their login name and unencrypted password. Returns the user or nil.
88 def self.authenticate(login, password, environment = nil) 106 def self.authenticate(login, password, environment = nil)
89 environment ||= Environment.default 107 environment ||= Environment.default
90 - u = find_by_login_and_environment_id(login, environment.id) # need to get the salt 108 + u = first :conditions => ['login = ? AND environment_id = ? AND activated_at IS NOT NULL', login, environment.id] # need to get the salt
91 u && u.authenticated?(password) ? u : nil 109 u && u.authenticated?(password) ? u : nil
92 end 110 end
93 111
  112 + # Activates the user in the database.
  113 + def activate
  114 + self.activated_at = Time.now.utc
  115 + self.activation_code = nil
  116 + self.person.visible = true
  117 + self.person.save && self.save
  118 + end
  119 +
  120 + def activated?
  121 + self.activation_code.nil? && !self.activated_at.nil?
  122 + end
  123 +
94 class UnsupportedEncryptionType < Exception; end 124 class UnsupportedEncryptionType < Exception; end
95 125
96 def self.system_encryption_method 126 def self.system_encryption_method
@@ -253,4 +283,16 @@ class User &lt; ActiveRecord::Base @@ -253,4 +283,16 @@ class User &lt; ActiveRecord::Base
253 def password_required? 283 def password_required?
254 crypted_password.blank? || !password.blank? 284 crypted_password.blank? || !password.blank?
255 end 285 end
  286 +
  287 + def make_activation_code
  288 + self.activation_code = Digest::SHA1.hexdigest(Time.now.to_s.split(//).sort_by{rand}.join)
  289 + end
  290 +
  291 + def deliver_activation_code
  292 + User::Mailer.deliver_activation_code(self) unless self.activation_code.blank?
  293 + end
  294 +
  295 + def delay_activation_check
  296 + Delayed::Job.enqueue(UserActivationJob.new(self.id), 0, 72.hours.from_now)
  297 + end
256 end 298 end
app/views/account/login.rhtml
@@ -5,9 +5,11 @@ @@ -5,9 +5,11 @@
5 <% @user ||= User.new %> 5 <% @user ||= User.new %>
6 <% is_thickbox ||= false %> 6 <% is_thickbox ||= false %>
7 7
  8 +<%= @message %>
  9 +
8 <% labelled_form_for :user, @user, :url => login_url do |f| %> 10 <% labelled_form_for :user, @user, :url => login_url do |f| %>
9 11
10 - <%= f.text_field :login, :id => 'main_user_login', :onchange => 'this.value = convToValidLogin( this.value )' %> 12 + <%= f.text_field :login, :id => 'main_user_login', :onchange => 'this.value = convToValidLogin( this.value )', :value => params[:userlogin] %>
11 13
12 <%= f.password_field :password %> 14 <%= f.password_field :password %>
13 15
app/views/account/signup.rhtml
1 <h1><%= _('Signup') %></h1> 1 <h1><%= _('Signup') %></h1>
2 -<%= render :partial => 'signup_form' %> 2 +<% if @register_pending %>
  3 + <%= _('Thanks for signing up! Now check your e-mail to activate your account!') %>
  4 + <p style="text-align: center"><%= link_to(_('Go to the homepage'), '/') %></p>
  5 +<% else %>
  6 + <%= render :partial => 'signup_form' %>
  7 +<% end %>
app/views/user/mailer/activation_code.rhtml 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +<%= _('Hi, %{recipient}!') % { :recipient => @recipient } %>
  2 +
  3 +<%= word_wrap(_('Welcome to %{environment}! To activate your account, follow the link: %{activation_url}') % { :environment => @environment, :activation_url => @url + url_for(:controller => :account, :action => :activate, :activation_code => @activation_code) }) %>
  4 +
  5 +<%= _("Greetings,") %>
  6 +
  7 +--
  8 +<%= _('%s team.') % @environment %>
  9 +<%= url_for @url %>
db/migrate/20110824192153_add_activated_at_to_users.rb 0 → 100644
@@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
  1 +class AddActivatedAtToUsers < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :users, :activation_code, :string, :limit => 40
  4 + add_column :users, :activated_at, :datetime
  5 + if ActiveRecord::Base.connection.adapter_name == 'SQLite'
  6 + execute "update users set activated_at = datetime();"
  7 + else
  8 + execute "update users set activated_at = now();"
  9 + end
  10 + end
  11 +
  12 + def self.down
  13 + remove_column :users, :activation_code
  14 + remove_column :users, :activated_at
  15 + end
  16 +end
features/my_network_block.feature
@@ -56,9 +56,10 @@ Feature: my_network_block @@ -56,9 +56,10 @@ Feature: my_network_block
56 56
57 Scenario: not display how many invisible friends I have 57 Scenario: not display how many invisible friends I have
58 Given the following users 58 Given the following users
59 - | login | name | visible |  
60 - | mariasilva | Maria Silva | true |  
61 - | josesilva | Jose Silva | false | 59 + | login | name |
  60 + | mariasilva | Maria Silva |
  61 + | josesilva | Jose Silva |
  62 + And "josesilva" is invisible
62 And "joaosilva" is friend of "mariasilva" 63 And "joaosilva" is friend of "mariasilva"
63 And I am logged in as "joaosilva" 64 And I am logged in as "joaosilva"
64 When I go to Joao Silva's homepage 65 When I go to Joao Silva's homepage
features/signup.feature
@@ -14,6 +14,18 @@ Feature: signup @@ -14,6 +14,18 @@ Feature: signup
14 | Password confirmation | secret | 14 | Password confirmation | secret |
15 | Name | José da Silva | 15 | Name | José da Silva |
16 And I press "Sign up" 16 And I press "Sign up"
  17 + Then I should not be logged in
  18 + And I should receive an e-mail on josesilva@example.com
  19 + When I go to login page
  20 + And I fill in "Username" with "josesilva"
  21 + And I fill in "Password" with "secret"
  22 + And I press "Log in"
  23 + Then I should not be logged in
  24 + When José da Silva's account is activated
  25 + And I go to login page
  26 + And I fill in "Username" with "josesilva"
  27 + And I fill in "Password" with "secret"
  28 + And I press "Log in"
17 Then I should be logged in as "josesilva" 29 Then I should be logged in as "josesilva"
18 30
19 Scenario: be redirected if user goes to signup page and is logged 31 Scenario: be redirected if user goes to signup page and is logged
features/step_definitions/noosfero_steps.rb
@@ -7,10 +7,14 @@ Given /^the following users?$/ do |table| @@ -7,10 +7,14 @@ Given /^the following users?$/ do |table|
7 table.hashes.each do |item| 7 table.hashes.each do |item|
8 person_data = item.dup 8 person_data = item.dup
9 person_data.delete("login") 9 person_data.delete("login")
10 - User.create!(:login => item[:login], :password => '123456', :password_confirmation => '123456', :email => item[:login] + "@example.com", :person_data => person_data) 10 + User.create!(:login => item[:login], :password => '123456', :password_confirmation => '123456', :email => item[:login] + "@example.com", :person_data => person_data).activate
11 end 11 end
12 end 12 end
13 13
  14 +Given /^"(.+)" is (invisible|visible)$/ do |user, visibility|
  15 + User.find_by_login(user).person.update_attributes(:visible => (visibility == 'visible'))
  16 +end
  17 +
14 Given /^"(.+)" is (online|offline|busy) in chat$/ do |user, status| 18 Given /^"(.+)" is (online|offline|busy) in chat$/ do |user, status|
15 status = {'online' => 'chat', 'offline' => '', 'busy' => 'dnd'}[status] 19 status = {'online' => 'chat', 'offline' => '', 'busy' => 'dnd'}[status]
16 User.find_by_login(user).update_attributes(:chat_status => status, :chat_status_at => DateTime.now) 20 User.find_by_login(user).update_attributes(:chat_status => status, :chat_status_at => DateTime.now)
@@ -195,6 +199,7 @@ end @@ -195,6 +199,7 @@ end
195 Given /^I am logged in as admin$/ do 199 Given /^I am logged in as admin$/ do
196 visit('/account/logout') 200 visit('/account/logout')
197 user = User.create!(:login => 'admin_user', :password => '123456', :password_confirmation => '123456', :email => 'admin_user@example.com') 201 user = User.create!(:login => 'admin_user', :password => '123456', :password_confirmation => '123456', :email => 'admin_user@example.com')
  202 + user.activate
198 e = Environment.default 203 e = Environment.default
199 e.add_admin(user.person) 204 e.add_admin(user.person)
200 visit('/account/login') 205 visit('/account/login')
@@ -345,6 +350,10 @@ Then /^I should be logged in as &quot;(.+)&quot;$/ do |login| @@ -345,6 +350,10 @@ Then /^I should be logged in as &quot;(.+)&quot;$/ do |login|
345 User.find(session[:user]).login.should == login 350 User.find(session[:user]).login.should == login
346 end 351 end
347 352
  353 +Then /^I should not be logged in$/ do
  354 + session[:user].nil?
  355 +end
  356 +
348 Given /^the profile "(.+)" has no blocks$/ do |profile| 357 Given /^the profile "(.+)" has no blocks$/ do |profile|
349 profile = Profile[profile] 358 profile = Profile[profile]
350 profile.boxes.map do |box| 359 profile.boxes.map do |box|
@@ -416,3 +425,12 @@ end @@ -416,3 +425,12 @@ end
416 Given /^skip comments captcha$/ do 425 Given /^skip comments captcha$/ do
417 Comment.any_instance.stubs(:skip_captcha?).returns(true) 426 Comment.any_instance.stubs(:skip_captcha?).returns(true)
418 end 427 end
  428 +
  429 +When /^([^\']*)'s account is activated$/ do |person|
  430 + Person.find_by_name(person).user.activate
  431 +end
  432 +
  433 +Then /^I should receive an e-mail on (.*)$/ do |address|
  434 + last_mail = ActionMailer::Base.deliveries.last
  435 + last_mail['to'].to_s.should == address
  436 +end
lib/user_activation_job.rb 0 → 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 +class UserActivationJob < Struct.new(:user_id)
  2 + def perform
  3 + user = User.find(user_id)
  4 + user.destroy unless user.activated?
  5 + end
  6 +end
test/fixtures/users.yml
@@ -6,7 +6,7 @@ johndoe: @@ -6,7 +6,7 @@ johndoe:
6 crypted_password: 00742970dc9e6319f8019fd54864d3ea740f04b1 # test 6 crypted_password: 00742970dc9e6319f8019fd54864d3ea740f04b1 # test
7 #crypted_password: "ce2/iFrNtQ8=\n" # johndoe, use only if you're using 2-way encryption 7 #crypted_password: "ce2/iFrNtQ8=\n" # johndoe, use only if you're using 2-way encryption
8 created_at: <%= 5.days.ago.to_s :db %> 8 created_at: <%= 5.days.ago.to_s :db %>
9 - # activated_at: <%= 5.days.ago.to_s :db %> # only if you're activating new signups 9 + activated_at: <%= 5.days.ago.to_s :db %> # only if you're activating new signups
10 environment_id: 1 10 environment_id: 1
11 joerandomhacker: 11 joerandomhacker:
12 id: 2 12 id: 2
@@ -14,7 +14,7 @@ joerandomhacker: @@ -14,7 +14,7 @@ joerandomhacker:
14 email: joerandomhacker@localhost.localdomain 14 email: joerandomhacker@localhost.localdomain
15 salt: 7e3041ebc2fc05a40c60028e2c4901a81035d3cd 15 salt: 7e3041ebc2fc05a40c60028e2c4901a81035d3cd
16 crypted_password: 00742970dc9e6319f8019fd54864d3ea740f04b1 # test 16 crypted_password: 00742970dc9e6319f8019fd54864d3ea740f04b1 # test
17 - # activation_code: aaronscode # only if you're activating new signups 17 + activated_at: <%= 5.days.ago.to_s :db %> # only if you're activating new signups
18 created_at: <%= 1.days.ago.to_s :db %> 18 created_at: <%= 1.days.ago.to_s :db %>
19 environment_id: 1 19 environment_id: 1
20 ze: 20 ze:
@@ -23,7 +23,7 @@ ze: @@ -23,7 +23,7 @@ ze:
23 email: ze@localhost.localdomain 23 email: ze@localhost.localdomain
24 salt: 7e3041ebc2fc05a40c60028e2c4901a81035d3cd 24 salt: 7e3041ebc2fc05a40c60028e2c4901a81035d3cd
25 crypted_password: 00742970dc9e6319f8019fd54864d3ea740f04b1 # test 25 crypted_password: 00742970dc9e6319f8019fd54864d3ea740f04b1 # test
26 - # activation_code: aaronscode # only if you're activating new signups 26 + activated_at: <%= 5.days.ago.to_s :db %> # only if you're activating new signups
27 created_at: <%= 1.days.ago.to_s :db %> 27 created_at: <%= 1.days.ago.to_s :db %>
28 environment_id: 1 28 environment_id: 1
29 other_ze: 29 other_ze:
@@ -32,6 +32,6 @@ other_ze: @@ -32,6 +32,6 @@ other_ze:
32 email: ze@localhost.localdomain 32 email: ze@localhost.localdomain
33 salt: 7e3041ebc2fc05a40c60028e2c4901a81035d3cd 33 salt: 7e3041ebc2fc05a40c60028e2c4901a81035d3cd
34 crypted_password: 00742970dc9e6319f8019fd54864d3ea740f04b1 # test 34 crypted_password: 00742970dc9e6319f8019fd54864d3ea740f04b1 # test
35 - # activation_code: aaronscode # only if you're activating new signups 35 + activated_at: <%= 5.days.ago.to_s :db %> # only if you're activating new signups
36 created_at: <%= 1.days.ago.to_s :db %> 36 created_at: <%= 1.days.ago.to_s :db %>
37 environment_id: 2 37 environment_id: 2
test/functional/account_controller_test.rb
@@ -70,7 +70,8 @@ class AccountControllerTest &lt; Test::Unit::TestCase @@ -70,7 +70,8 @@ class AccountControllerTest &lt; Test::Unit::TestCase
70 def test_should_allow_signup 70 def test_should_allow_signup
71 assert_difference User, :count do 71 assert_difference User, :count do
72 new_user 72 new_user
73 - assert_response :redirect 73 + assert_response :success
  74 + assert_not_nil assigns(:register_pending)
74 end 75 end
75 end 76 end
76 77
@@ -79,6 +80,7 @@ class AccountControllerTest &lt; Test::Unit::TestCase @@ -79,6 +80,7 @@ class AccountControllerTest &lt; Test::Unit::TestCase
79 new_user(:login => nil) 80 new_user(:login => nil)
80 assert assigns(:user).errors.on(:login) 81 assert assigns(:user).errors.on(:login)
81 assert_response :success 82 assert_response :success
  83 + assert_nil assigns(:register_pending)
82 end 84 end
83 end 85 end
84 86
@@ -87,6 +89,7 @@ class AccountControllerTest &lt; Test::Unit::TestCase @@ -87,6 +89,7 @@ class AccountControllerTest &lt; Test::Unit::TestCase
87 new_user(:password => nil) 89 new_user(:password => nil)
88 assert assigns(:user).errors.on(:password) 90 assert assigns(:user).errors.on(:password)
89 assert_response :success 91 assert_response :success
  92 + assert_nil assigns(:register_pending)
90 end 93 end
91 end 94 end
92 95
@@ -95,6 +98,7 @@ class AccountControllerTest &lt; Test::Unit::TestCase @@ -95,6 +98,7 @@ class AccountControllerTest &lt; Test::Unit::TestCase
95 new_user(:password_confirmation => nil) 98 new_user(:password_confirmation => nil)
96 assert assigns(:user).errors.on(:password_confirmation) 99 assert assigns(:user).errors.on(:password_confirmation)
97 assert_response :success 100 assert_response :success
  101 + assert_nil assigns(:register_pending)
98 end 102 end
99 end 103 end
100 104
@@ -103,6 +107,7 @@ class AccountControllerTest &lt; Test::Unit::TestCase @@ -103,6 +107,7 @@ class AccountControllerTest &lt; Test::Unit::TestCase
103 new_user(:email => nil) 107 new_user(:email => nil)
104 assert assigns(:user).errors.on(:email) 108 assert assigns(:user).errors.on(:email)
105 assert_response :success 109 assert_response :success
  110 + assert_nil assigns(:register_pending)
106 end 111 end
107 end 112 end
108 113
@@ -111,6 +116,7 @@ class AccountControllerTest &lt; Test::Unit::TestCase @@ -111,6 +116,7 @@ class AccountControllerTest &lt; Test::Unit::TestCase
111 Environment.default.update_attributes(:terms_of_use => 'some terms ...') 116 Environment.default.update_attributes(:terms_of_use => 'some terms ...')
112 new_user 117 new_user
113 assert_response :success 118 assert_response :success
  119 + assert_nil assigns(:register_pending)
114 end 120 end
115 end 121 end
116 122
@@ -118,7 +124,8 @@ class AccountControllerTest &lt; Test::Unit::TestCase @@ -118,7 +124,8 @@ class AccountControllerTest &lt; Test::Unit::TestCase
118 assert_difference User, :count do 124 assert_difference User, :count do
119 Environment.default.update_attributes(:terms_of_use => 'some terms ...') 125 Environment.default.update_attributes(:terms_of_use => 'some terms ...')
120 new_user(:terms_accepted => '1') 126 new_user(:terms_accepted => '1')
121 - assert_response :redirect 127 + assert_response :success
  128 + assert_not_nil assigns(:register_pending)
122 end 129 end
123 end 130 end
124 131
@@ -643,7 +650,7 @@ class AccountControllerTest &lt; Test::Unit::TestCase @@ -643,7 +650,7 @@ class AccountControllerTest &lt; Test::Unit::TestCase
643 Person.any_instance.stubs(:required_fields).returns(['organization']) 650 Person.any_instance.stubs(:required_fields).returns(['organization'])
644 assert_difference User, :count do 651 assert_difference User, :count do
645 post :signup, :user => { :login => 'testuser', :password => '123456', :password_confirmation => '123456', :email => 'testuser@example.com' }, :profile_data => { :organization => 'example.com' } 652 post :signup, :user => { :login => 'testuser', :password => '123456', :password_confirmation => '123456', :email => 'testuser@example.com' }, :profile_data => { :organization => 'example.com' }
646 - assert_redirected_to :controller => 'profile_editor', :profile => 'testuser' 653 + assert_response :success
647 end 654 end
648 assert_equal 'example.com', Person['testuser'].organization 655 assert_equal 'example.com', Person['testuser'].organization
649 end 656 end
@@ -689,6 +696,36 @@ class AccountControllerTest &lt; Test::Unit::TestCase @@ -689,6 +696,36 @@ class AccountControllerTest &lt; Test::Unit::TestCase
689 assert_equal User.find_by_login('ze').data_hash.merge({ 'foo' => 'bar', 'test' => 5 }), ActiveSupport::JSON.decode(@response.body) 696 assert_equal User.find_by_login('ze').data_hash.merge({ 'foo' => 'bar', 'test' => 5 }), ActiveSupport::JSON.decode(@response.body)
690 end 697 end
691 698
  699 + should 'activate user when activation code is present and correct' do
  700 + user = User.create! :login => 'testuser', :password => 'test123', :password_confirmation => 'test123', :email => 'test@test.org'
  701 + get :activate, :activation_code => user.activation_code
  702 + assert_not_nil assigns(:message)
  703 + assert_response :success
  704 + post :login, :user => {:login => 'testuser', :password => 'test123'}
  705 + assert_not_nil session[:user]
  706 + assert_redirected_to :controller => 'profile_editor', :profile => 'testuser'
  707 + end
  708 +
  709 + should 'not activate user when activation code is missing' do
  710 + @request.env["HTTP_REFERER"] = '/bli'
  711 + user = User.create! :login => 'testuser', :password => 'test123', :password_confirmation => 'test123', :email => 'test@test.org'
  712 + get :activate
  713 + assert_nil assigns(:message)
  714 + post :login, :user => {:login => 'testuser', :password => 'test123'}
  715 + assert_nil session[:user]
  716 + assert_redirected_to '/bli'
  717 + end
  718 +
  719 + should 'not activate user when activation code is incorrect' do
  720 + @request.env["HTTP_REFERER"] = '/bli'
  721 + user = User.create! :login => 'testuser', :password => 'test123', :password_confirmation => 'test123', :email => 'test@test.org'
  722 + get :activate, :activation_code => 'wrongcode'
  723 + assert_nil assigns(:message)
  724 + post :login, :user => {:login => 'testuser', :password => 'test123'}
  725 + assert_nil session[:user]
  726 + assert_redirected_to '/bli'
  727 + end
  728 +
692 protected 729 protected
693 def new_user(options = {}, extra_options ={}) 730 def new_user(options = {}, extra_options ={})
694 data = {:profile_data => person_data} 731 data = {:profile_data => person_data}
test/functional/profile_controller_test.rb
@@ -189,8 +189,10 @@ class ProfileControllerTest &lt; Test::Unit::TestCase @@ -189,8 +189,10 @@ class ProfileControllerTest &lt; Test::Unit::TestCase
189 end 189 end
190 190
191 should 'display add friend button' do 191 should 'display add friend button' do
  192 + @profile.user.activate
192 login_as(@profile.identifier) 193 login_as(@profile.identifier)
193 friend = create_user_full('friendtestuser').person 194 friend = create_user_full('friendtestuser').person
  195 + friend.user.activate
194 friend.boxes.first.blocks << block = ProfileInfoBlock.create! 196 friend.boxes.first.blocks << block = ProfileInfoBlock.create!
195 get :profile_info, :profile => friend.identifier, :block_id => block.id 197 get :profile_info, :profile => friend.identifier, :block_id => block.id
196 assert_match /Add friend/, @response.body 198 assert_match /Add friend/, @response.body
@@ -318,6 +320,7 @@ class ProfileControllerTest &lt; Test::Unit::TestCase @@ -318,6 +320,7 @@ class ProfileControllerTest &lt; Test::Unit::TestCase
318 320
319 should 'display contact button only if friends' do 321 should 'display contact button only if friends' do
320 friend = create_user_full('friend_user').person 322 friend = create_user_full('friend_user').person
  323 + friend.user.activate
321 friend.boxes.first.blocks << block = ProfileInfoBlock.create! 324 friend.boxes.first.blocks << block = ProfileInfoBlock.create!
322 @profile.add_friend(friend) 325 @profile.add_friend(friend)
323 env = Environment.default 326 env = Environment.default
@@ -338,6 +341,7 @@ class ProfileControllerTest &lt; Test::Unit::TestCase @@ -338,6 +341,7 @@ class ProfileControllerTest &lt; Test::Unit::TestCase
338 341
339 should 'display contact button only if friends and its enable in environment' do 342 should 'display contact button only if friends and its enable in environment' do
340 friend = create_user_full('friend_user').person 343 friend = create_user_full('friend_user').person
  344 + friend.user.activate
341 friend.boxes.first.blocks << block = ProfileInfoBlock.create! 345 friend.boxes.first.blocks << block = ProfileInfoBlock.create!
342 env = Environment.default 346 env = Environment.default
343 env.disable('disable_contact_person') 347 env.disable('disable_contact_person')
test/integration/editing_person_info_test.rb
@@ -8,6 +8,8 @@ class EditingPersonInfoTest &lt; ActionController::IntegrationTest @@ -8,6 +8,8 @@ class EditingPersonInfoTest &lt; ActionController::IntegrationTest
8 8
9 profile = create_user('user_ze', :password => 'test', :password_confirmation => 'test').person 9 profile = create_user('user_ze', :password => 'test', :password_confirmation => 'test').person
10 10
  11 + profile.user.activate
  12 +
11 login(profile.identifier, 'test') 13 login(profile.identifier, 'test')
12 14
13 get "/myprofile/#{profile.identifier}" 15 get "/myprofile/#{profile.identifier}"
test/integration/enterprise_registration_test.rb
@@ -50,6 +50,7 @@ class EnterpriseRegistrationTest &lt; ActionController::IntegrationTest @@ -50,6 +50,7 @@ class EnterpriseRegistrationTest &lt; ActionController::IntegrationTest
50 50
51 # steps done by the validator 51 # steps done by the validator
52 validator = create_user_with_permission('validator', 'validate_enterprise', org) 52 validator = create_user_with_permission('validator', 'validate_enterprise', org)
  53 + validator.user.activate
53 login 'validator', 'validator' 54 login 'validator', 'validator'
54 55
55 get "/myprofile/myorg/enterprise_validation" 56 get "/myprofile/myorg/enterprise_validation"
test/integration/forgot_password_test.rb
@@ -12,7 +12,7 @@ class ForgotPasswordTest &lt; ActionController::IntegrationTest @@ -12,7 +12,7 @@ class ForgotPasswordTest &lt; ActionController::IntegrationTest
12 Profile.destroy_all 12 Profile.destroy_all
13 ChangePassword.destroy_all 13 ChangePassword.destroy_all
14 14
15 - create_user('forgotten', :password => 'test', :password_confirmation => 'test', :email => 'forgotten@localhost.localdomain') 15 + create_user('forgotten', :password => 'test', :password_confirmation => 'test', :email => 'forgotten@localhost.localdomain').activate
16 16
17 get '/account/forgot_password' 17 get '/account/forgot_password'
18 18
test/integration/manage_documents_test.rb
@@ -6,6 +6,7 @@ class ManageDocumentsTest &lt; ActionController::IntegrationTest @@ -6,6 +6,7 @@ class ManageDocumentsTest &lt; ActionController::IntegrationTest
6 6
7 def test_creation_of_a_new_article 7 def test_creation_of_a_new_article
8 user = create_user('myuser') 8 user = create_user('myuser')
  9 + user.activate
9 10
10 login('myuser', 'myuser') 11 login('myuser', 'myuser')
11 assert_tag :tag => 'a', :attributes => { :href => "#{user.environment.top_url}/myprofile\/{login}" } 12 assert_tag :tag => 'a', :attributes => { :href => "#{user.environment.top_url}/myprofile\/{login}" }
@@ -34,6 +35,7 @@ class ManageDocumentsTest &lt; ActionController::IntegrationTest @@ -34,6 +35,7 @@ class ManageDocumentsTest &lt; ActionController::IntegrationTest
34 35
35 def test_update_of_an_existing_article 36 def test_update_of_an_existing_article
36 profile = create_user('myuser').person 37 profile = create_user('myuser').person
  38 + profile.user.activate
37 article = create_article(profile, :name => 'my-article') 39 article = create_article(profile, :name => 'my-article')
38 article.save! 40 article.save!
39 41
@@ -67,6 +69,7 @@ class ManageDocumentsTest &lt; ActionController::IntegrationTest @@ -67,6 +69,7 @@ class ManageDocumentsTest &lt; ActionController::IntegrationTest
67 69
68 def test_removing_an_article 70 def test_removing_an_article
69 profile = create_user('myuser').person 71 profile = create_user('myuser').person
  72 + profile.user.activate
70 article = create_article(profile, :name => 'my-article') 73 article = create_article(profile, :name => 'my-article')
71 article.save! 74 article.save!
72 75
test/integration/signup_test.rb
@@ -11,6 +11,7 @@ class SignupTest &lt; ActionController::IntegrationTest @@ -11,6 +11,7 @@ class SignupTest &lt; ActionController::IntegrationTest
11 Environment.default.update_attributes(:terms_of_use => 'You agree to not be annoying.') 11 Environment.default.update_attributes(:terms_of_use => 'You agree to not be annoying.')
12 12
13 count = User.count 13 count = User.count
  14 + mail_count = ActionMailer::Base.deliveries.count
14 15
15 get '/account/signup' 16 get '/account/signup'
16 assert_response :success 17 assert_response :success
@@ -20,13 +21,13 @@ class SignupTest &lt; ActionController::IntegrationTest @@ -20,13 +21,13 @@ class SignupTest &lt; ActionController::IntegrationTest
20 assert_response :success 21 assert_response :success
21 assert_template 'signup' 22 assert_template 'signup'
22 assert_equal count, User.count 23 assert_equal count, User.count
  24 + assert_equal mail_count, ActionMailer::Base.deliveries.count
23 25
24 post '/account/signup', :user => { :login => 'shouldaccepterms', :password => 'test', :password_confirmation => 'test', :email => 'shouldaccepterms@example.com', :terms_accepted => '1' }, :profile_data => person_data 26 post '/account/signup', :user => { :login => 'shouldaccepterms', :password => 'test', :password_confirmation => 'test', :email => 'shouldaccepterms@example.com', :terms_accepted => '1' }, :profile_data => person_data
25 - assert_response :redirect  
26 -  
27 - follow_redirect!  
28 assert_response :success 27 assert_response :success
  28 +
29 assert_equal count + 1, User.count 29 assert_equal count + 1, User.count
  30 + assert_equal mail_count + 1, ActionMailer::Base.deliveries.count
30 31
31 end 32 end
32 33
test/integration/user_registers_at_the_application_test.rb
@@ -13,13 +13,9 @@ class UserRegistersAtTheApplicationTest &lt; ActionController::IntegrationTest @@ -13,13 +13,9 @@ class UserRegistersAtTheApplicationTest &lt; ActionController::IntegrationTest
13 assert_response :success 13 assert_response :success
14 14
15 post '/account/signup', :user => { :login => 'mylogin', :password => 'mypassword', :password_confirmation => 'mypassword', :email => 'mylogin@example.com' } 15 post '/account/signup', :user => { :login => 'mylogin', :password => 'mypassword', :password_confirmation => 'mypassword', :email => 'mylogin@example.com' }
16 - assert_response :redirect  
17 - assert_redirected_to '/myprofile/mylogin' 16 + assert_response :success
18 17
19 - # user is logged in right after the registration  
20 - follow_redirect!  
21 - assert_no_tag :tag => 'a', :attributes => { :href => '/account/login_popup' }  
22 - assert_tag :tag => 'a', :attributes => { :href => '/account/logout' } 18 + assert_tag :tag => 'a', :attributes => { :href => /^\/account\/login/ }
23 end 19 end
24 20
25 def test_trying_an_existing_login_name 21 def test_trying_an_existing_login_name
test/unit/user_activation_job_test.rb 0 → 100644
@@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class NotifyActivityToProfilesJobTest < ActiveSupport::TestCase
  4 +
  5 + should 'create job on user creation' do
  6 + assert_difference Delayed::Job, :count, 1 do
  7 + user = new_user :login => 'test1'
  8 + assert_equal user.id, YAML.load(Delayed::Job.last.handler).user_id
  9 + end
  10 + process_delayed_job_queue
  11 + end
  12 +
  13 + should 'destroy user if not activated' do
  14 + user = new_user :login => 'test2'
  15 + job = UserActivationJob.new(user.id)
  16 + assert_difference User, :count, -1 do
  17 + job.perform
  18 + process_delayed_job_queue
  19 + end
  20 + end
  21 +
  22 + should 'not destroy user if activated' do
  23 + user = new_user :login => 'test3'
  24 + user.activate
  25 + job = UserActivationJob.new(user.id)
  26 + assert_no_difference User, :count do
  27 + job.perform
  28 + process_delayed_job_queue
  29 + end
  30 + end
  31 +
  32 + protected
  33 + def new_user(options = {})
  34 + user = User.new({ :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' }.merge(options))
  35 + user.save
  36 + user
  37 + end
  38 +
  39 +end
test/unit/user_test.rb
@@ -346,7 +346,7 @@ class UserTest &lt; Test::Unit::TestCase @@ -346,7 +346,7 @@ class UserTest &lt; Test::Unit::TestCase
346 Person.any_instance.stubs(:profile_custom_icon).returns('/custom_icon') 346 Person.any_instance.stubs(:profile_custom_icon).returns('/custom_icon')
347 expected_hash = { 347 expected_hash = {
348 'coldplayfriend' => { 348 'coldplayfriend' => {
349 - 'avatar' => '/custom_icon', 'name' => 'coldplayfriend', 'jid' => 'coldplayfriend@colivre.net/coldplayfriend', 'status' => 'chat' 349 + 'avatar' => '/custom_icon', 'name' => 'coldplayfriend', 'jid' => 'coldplayfriend@' + Environment.default.default_hostname + '/coldplayfriend', 'status' => 'chat'
350 } 350 }
351 } 351 }
352 assert_equal expected_hash, person.user.data_hash['friends_list'] 352 assert_equal expected_hash, person.user.data_hash['friends_list']
@@ -409,6 +409,75 @@ class UserTest &lt; Test::Unit::TestCase @@ -409,6 +409,75 @@ class UserTest &lt; Test::Unit::TestCase
409 assert_equal 'testuser', user.name 409 assert_equal 'testuser', user.name
410 end 410 end
411 411
  412 + should 'have activation code' do
  413 + user = create_user('testuser')
  414 + assert_respond_to user, :activation_code
  415 + end
  416 +
  417 + should 'have activated at' do
  418 + user = create_user('testuser')
  419 + assert_respond_to user, :activated_at
  420 + end
  421 +
  422 + should 'make activation code before creation' do
  423 + assert_not_nil new_user.activation_code
  424 + end
  425 +
  426 + should 'deliver e-mail with activation code after creation' do
  427 + assert_difference(ActionMailer::Base.deliveries, :size, 1) do
  428 + new_user :email => 'pending@activation.com'
  429 + end
  430 + assert_equal 'pending@activation.com', ActionMailer::Base.deliveries.last['to'].to_s
  431 + end
  432 +
  433 + should 'not mass assign activated at' do
  434 + user = User.new :activated_at => 5.days.ago
  435 + assert_nil user.activated_at
  436 + user.attributes = { :activated_at => 5.days.ago }
  437 + assert_nil user.activated_at
  438 + user.activated_at = 5.days.ago
  439 + assert_not_nil user.activated_at
  440 + end
  441 +
  442 + should 'authenticate an activated user' do
  443 + user = new_user :login => 'testuser', :password => 'test123', :password_confirmation => 'test123'
  444 + user.activate
  445 + assert_equal user, User.authenticate('testuser', 'test123')
  446 + end
  447 +
  448 + should 'not authenticate a not activated user' do
  449 + user = new_user :login => 'testuser', :password => 'test123', :password_confirmation => 'test123'
  450 + assert_nil User.authenticate('testuser', 'test123')
  451 + end
  452 +
  453 + should 'have activation code but no activated at when created' do
  454 + user = new_user
  455 + assert_not_nil user.activation_code
  456 + assert_nil user.activated_at
  457 + assert !user.person.visible
  458 + end
  459 +
  460 + should 'activate an user' do
  461 + user = new_user
  462 + assert user.activate
  463 + assert_nil user.activation_code
  464 + assert_not_nil user.activated_at
  465 + assert user.person.visible
  466 + end
  467 +
  468 + should 'return if the user is activated' do
  469 + user = new_user
  470 + assert !user.activated?
  471 + user.activate
  472 + assert user.activated?
  473 + end
  474 +
  475 + should 'delay activation check' do
  476 + assert_difference Delayed::Job, :count, 1 do
  477 + user = new_user
  478 + end
  479 + end
  480 +
412 protected 481 protected
413 def new_user(options = {}) 482 def new_user(options = {})
414 user = User.new({ :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' }.merge(options)) 483 user = User.new({ :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' }.merge(options))