auth-slice 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,157 @@
1
+ body {
2
+ font-family: Arial, Verdana, sans-serif;
3
+ font-size: 14px;
4
+ background-color: #fff;
5
+ color: #000;
6
+ background-color: #fff;
7
+ }
8
+
9
+ html {
10
+ height: 100%;
11
+ }
12
+
13
+ hr {
14
+ border: 0px;
15
+ color: #ccc;
16
+ background-color: #cdcdcd;
17
+ height: 1px;
18
+ width: 100%;
19
+ text-align: left;
20
+ }
21
+
22
+ h1, h2, h3 {
23
+ color: #003399;
24
+ color: #09579A;
25
+ background-color: #fff;
26
+ font-family: Arial, Verdana, sans-serif;
27
+ font-weight: 300;
28
+ }
29
+
30
+ h1 {
31
+ font-size: 20px;
32
+ }
33
+ h2 {
34
+ font-size: 15px;
35
+ }
36
+ h3 {
37
+ font-size: 15px;
38
+ }
39
+
40
+ p {
41
+ line-height: 20px;
42
+ padding: 5px;
43
+ }
44
+
45
+ a, a:hover {
46
+ color: #0033CC;
47
+ background-color: #fff;
48
+ text-decoration: underline;
49
+ }
50
+
51
+ #container {
52
+ width: 95%;
53
+ text-align: left;
54
+ background-color: #fff;
55
+ margin-right: auto;
56
+ margin-left: auto;
57
+ }
58
+
59
+ #header-container {
60
+ width: 100%;
61
+ padding-top: 15px;
62
+ }
63
+
64
+ #header-container h1, #header-container h2 {
65
+ margin-left: 6px;
66
+ margin-bottom: 6px;
67
+ }
68
+
69
+ #main-container {
70
+ padding: 15px;
71
+ min-height: 400px;
72
+ }
73
+
74
+ #footer-container {
75
+ clear: both;
76
+ font-size: 12px;
77
+ font-family: Verdana, Arial, sans-serif;
78
+ }
79
+
80
+ #main-container ul {
81
+ margin-left: 3.0em;
82
+ }
83
+
84
+ .right {
85
+ float: right;
86
+ font-size: 100%;
87
+ margin-top: 5px;
88
+ color: #999;
89
+ background-color: #fff;
90
+ }
91
+ .left {
92
+ float: left;
93
+ font-size: 100%;
94
+ margin-top: 5px;
95
+ color: #999;
96
+ background-color: #fff;
97
+ }
98
+
99
+ a#google_signup {
100
+ background:transparent url(/images/btn-google-signup.png) no-repeat scroll 0% 0%;
101
+ color:#FFFFFF;
102
+ display:block;
103
+ font-size:14px;
104
+ height:67px;
105
+ line-height:22px;
106
+ margin:0pt;
107
+ padding:0px;
108
+ text-align:center;
109
+ text-decoration:none;
110
+ width:151px;
111
+ }
112
+
113
+ a#google_signup div {
114
+ padding-top:8px;
115
+ }
116
+
117
+ #openid_url, .openid_link {
118
+ background:#FFFFFF url(/images/openid-login.gif) no-repeat scroll 2px 50%;
119
+ padding-left:25px;
120
+ width:14.25em;
121
+ }
122
+
123
+ /** Form inputs **/
124
+ label {
125
+ font-weight: bold;
126
+ display: block;
127
+ }
128
+
129
+ #remember_me {
130
+ margin: 2px 5px 0px 0px;
131
+ float: left;
132
+ }
133
+
134
+ div.error {
135
+ background-color:#FCECEC;
136
+ }
137
+
138
+ div.error ul {
139
+ padding-bottom:20px;
140
+ }
141
+
142
+ .error {
143
+ background-color:#FCECEC;
144
+ }
145
+
146
+ .error h2 {
147
+ background: #CC0000 no-repeat scroll left center;
148
+ border-color: #CC9999;
149
+ color:#FFFFFF;
150
+ border:1px solid #CCCCCC;
151
+ font-size:14px;
152
+ padding:5px 5px 5px 10px;
153
+ }
154
+
155
+ .error li {
156
+ color: #CC0000;
157
+ }
@@ -0,0 +1,52 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "AuthSlice (module)" do
4
+
5
+ it "should be registered in Merb::Slices.slices" do
6
+ Merb::Slices.slices.should include(AuthSlice)
7
+ end
8
+
9
+ it "should have an :identifier property" do
10
+ AuthSlice.identifier.should == "auth-slice"
11
+ end
12
+
13
+ it "should have a :root property" do
14
+ AuthSlice.root.should == current_slice_root
15
+ AuthSlice.root_path('app').should == current_slice_root / 'app'
16
+ end
17
+
18
+ it "should have a dir_for method" do
19
+ app_path = AuthSlice.dir_for(:application)
20
+ app_path.should == current_slice_root / 'app'
21
+ [:view, :model, :controller, :helper, :mailer, :part].each do |type|
22
+ AuthSlice.dir_for(type).should == app_path / "#{type}s"
23
+ end
24
+ public_path = AuthSlice.dir_for(:public)
25
+ public_path.should == current_slice_root / 'public'
26
+ [:stylesheet, :javascript, :image].each do |type|
27
+ AuthSlice.dir_for(type).should == public_path / "#{type}s"
28
+ end
29
+ end
30
+
31
+ it "should have a app_dir_for method" do
32
+ app_path = AuthSlice.app_dir_for(:application)
33
+ app_path.should == Merb.root / 'slices' / 'auth-slice' / 'app'
34
+ [:view, :model, :controller, :helper, :mailer, :part].each do |type|
35
+ AuthSlice.app_dir_for(type).should == app_path / "#{type}s"
36
+ end
37
+ public_path = AuthSlice.app_dir_for(:public)
38
+ public_path.should == Merb.dir_for(:public) / 'slices' / 'auth-slice'
39
+ [:stylesheet, :javascript, :image].each do |type|
40
+ AuthSlice.app_dir_for(type).should == public_path / "#{type}s"
41
+ end
42
+ end
43
+
44
+ it "should have a public_dir_for method" do
45
+ public_path = AuthSlice.public_dir_for(:public)
46
+ public_path.should == '/slices' / 'auth-slice'
47
+ [:stylesheet, :javascript, :image].each do |type|
48
+ AuthSlice.public_dir_for(type).should == public_path / "#{type}s"
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,29 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
2
+
3
+ prefix = 'auth-slice'
4
+
5
+ describe "Router.add_slice(:AuthSlice)" do
6
+ include Merb::Test::Rspec::RouteMatchers
7
+
8
+ before(:all) do
9
+ Merb::Router.prepare { |r| r.add_slice(:AuthSlice) } if standalone?
10
+ end
11
+
12
+ it "should have named routes for :login, :logout and :signup" do
13
+ [:login, :logout, :signup].each do |name|
14
+ url(name).should == "/#{prefix}/#{name}"
15
+ end
16
+ end
17
+
18
+ it "should route /#{prefix}/login to Session#new" do
19
+ request_to("/#{prefix}/login", :get).should route_to(AuthSlice::Users, :login)
20
+ end
21
+
22
+ it "should route /#{prefix}/login via post to Session#create" do
23
+ request_to("/#{prefix}/login", :post).should route_to(AuthSlice::Users, :login)
24
+ end
25
+
26
+ it "should route /#{prefix}/logout via delete to Session#destroy" do
27
+ request_to("/#{prefix}/logout", :delete).should route_to(AuthSlice::Users, :logout)
28
+ end
29
+ end
@@ -0,0 +1,87 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
2
+
3
+ describe "Session Controller", "index action" do
4
+ before(:all) do
5
+ Merb::Router.prepare { |r| r.add_slice(:AuthSlice) } if standalone?
6
+ end
7
+
8
+ def login_with(params = {}, &blk)
9
+ dispatch_to(AuthSlice::Users, :login, params, {:request_method => 'post'}, &blk)
10
+ end
11
+
12
+ def logout(&blk)
13
+ dispatch_to(AuthSlice::Users, :logout, {}, {}, &blk)
14
+ end
15
+
16
+ it 'logins and redirects' do
17
+ controller = login_with(:username => 'quentin', :password => 'test') {|c|
18
+ c.should_receive(:verify_login).with('quentin', 'test').and_return(mock("User", :id => 1, :name => 'quentin'))
19
+ }
20
+
21
+ controller.session[:user].should_not be_nil
22
+ controller.session[:user].should == 1
23
+ controller.should redirect_to("/")
24
+ end
25
+
26
+ it 'fails login and does not redirect' do
27
+ controller = login_with(:username => 'quentin', :password => 'bad password') {|c|
28
+ c.should_receive(:verify_login).with('quentin', 'bad password').and_return(nil)
29
+ }
30
+ controller.session[:user].should be_nil
31
+ controller.should be_successful
32
+ end
33
+
34
+ it 'logs out' do
35
+ controller = logout {|c|
36
+ c.stub!(:current_user).and_return(mock("User", :forget_me => true))
37
+ }
38
+ controller.session[:user].should be_nil
39
+ controller.should redirect
40
+ end
41
+
42
+ it 'remembers me' do
43
+ controller = login_with(:username => 'quentin', :password => 'test', :remember_me => "1") {|c|
44
+ user = mock("User", :id => 1)
45
+ c.should_receive(:verify_login).with('quentin', 'test').and_return(user)
46
+ user.should_receive(:remember_me)
47
+ user.should_receive(:remember_token).and_return("abc123")
48
+ user.should_receive(:remember_token_expires_at).and_return(Date.today)
49
+ }
50
+ controller.cookies["auth_token"].should_not be_nil
51
+ end
52
+
53
+ it 'does not remember me' do
54
+ controller = login_with(:username => 'quentin', :password => 'test', :remember_me => "0") {|c|
55
+ user = mock("User", :id => 1)
56
+ c.should_receive(:verify_login).with('quentin', 'test').and_return(user)
57
+ }
58
+ controller.cookies["auth_token"].should be_nil
59
+ end
60
+
61
+ it 'deletes token on logout' do
62
+ controller = logout {|c| controller.stub!(:current_user).and_return(@quentin) }
63
+ controller.cookies["auth_token"].should == nil
64
+ end
65
+
66
+
67
+ it 'logs in with cookie' do
68
+ controller = login_with do |c|
69
+ c.request.env[Merb::Const::HTTP_COOKIE] = "auth_token=abc123"
70
+ c.should_receive(:verify_login).and_return(nil)
71
+ user = mock("User", :id => 1, :remember_token? => true)
72
+ c.should_receive(:find_user_by_remember_token).with('abc123').and_return(user)
73
+ user.should_receive(:remember_me)
74
+ user.should_receive(:remember_token).and_return("abc123")
75
+ user.should_receive(:remember_token_expires_at).and_return(Date.today)
76
+ end
77
+ controller.should be_logged_in
78
+ end
79
+
80
+ def auth_token(token)
81
+ CGI::Cookie.new('name' => 'auth_token', 'value' => token)
82
+ end
83
+
84
+ def cookie_for(user)
85
+ auth_token user.remember_token
86
+ end
87
+ end
@@ -0,0 +1,37 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
2
+
3
+ def user_hash(options = {})
4
+ { 'name' => 'ctran',
5
+ 'username' => "ctran",
6
+ 'email' => "ctran@example.com",
7
+ 'password' => "sekret",
8
+ 'password_confirmation' => "sekret"}.merge(options)
9
+ end
10
+
11
+ describe AuthSlice::Users do
12
+ before(:all) do
13
+ Merb::Router.prepare { |r| r.add_slice(:AuthSlice) } if standalone?
14
+ end
15
+
16
+ before(:each) do
17
+ @user = mock("User", user_hash)
18
+ AuthSlice::User.should_receive(:new).with(user_hash).and_return(@user)
19
+ end
20
+
21
+ it 'allows signup and redirect to /' do
22
+ @user.should_receive(:save).and_return(true)
23
+
24
+ controller = dispatch_to(AuthSlice::Users, :signup, {'auth_slice::user' => user_hash }, {:request_method => 'post'})
25
+ controller.assigns(:user).should == @user
26
+ controller.should redirect_to('/')
27
+ end
28
+
29
+ it 'reject signup and render errors in template' do
30
+ @user.should_receive(:save).and_return(false)
31
+ controller = dispatch_to(AuthSlice::Users, :signup, {'auth_slice::user' => user_hash}, {:request_method => 'post'}) {|c|
32
+ c.should_receive(:render)
33
+ }
34
+ controller.assigns(:user).should == @user
35
+ controller.should respond_successfully
36
+ end
37
+ end
@@ -0,0 +1,27 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ module AuthSlice
4
+ class Main < Application
5
+ def index
6
+ 'index'
7
+ end
8
+ end
9
+ end
10
+
11
+ describe "AuthSlice::Main (controller)" do
12
+ before :all do
13
+ Merb::Router.prepare { |r| r.add_slice(:AuthSlice) } if standalone?
14
+ end
15
+
16
+ it "should have helper methods for dealing with public paths" do
17
+ controller = dispatch_to(AuthSlice::Main, :index)
18
+ controller.public_path_for(:image).should == "/slices/auth-slice/images"
19
+ controller.public_path_for(:javascript).should == "/slices/auth-slice/javascripts"
20
+ controller.public_path_for(:stylesheet).should == "/slices/auth-slice/stylesheets"
21
+ end
22
+
23
+ it "should have a slice-specific _template_root" do
24
+ AuthSlice::Main._template_root.should == AuthSlice.dir_for(:view)
25
+ AuthSlice::Main._template_root.should == AuthSlice::Application._template_root
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ require File.join( File.dirname(__FILE__), "shared_user_spec")
2
+
3
+ require 'activerecord'
4
+ use_orm :activerecord
5
+
6
+ describe "User with Activerecord adapter" do
7
+ before(:all) do
8
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
9
+ AuthSlice.use_adapter(:activerecord)
10
+ end
11
+
12
+ before(:each) do
13
+ AuthSlice::User.create_db_table
14
+ end
15
+
16
+ after(:each) do
17
+ AuthSlice::User.drop_db_table
18
+ end
19
+
20
+ it_should_behave_like "AuthSlice::User"
21
+ end
@@ -0,0 +1,20 @@
1
+ require File.join( File.dirname(__FILE__), "shared_user_spec")
2
+
3
+ use_orm :datamapper
4
+
5
+ describe "User with Datamapper adapter" do
6
+ before(:all) do
7
+ DataMapper.setup(:default, 'sqlite3::memory:')
8
+ AuthSlice.use_adapter(:datamapper)
9
+ end
10
+
11
+ before(:each) do
12
+ AuthSlice::User.create_db_table
13
+ end
14
+
15
+ after(:each) do
16
+ AuthSlice::User.drop_db_table
17
+ end
18
+
19
+ it_should_behave_like "AuthSlice::User"
20
+ end
@@ -0,0 +1,251 @@
1
+ require File.join( File.dirname(__FILE__), "..", "spec_helper" )
2
+
3
+ def valid_user_hash(options = {})
4
+ { :name => 'ctran',
5
+ :username => "ctran",
6
+ :email => "ctran@example.com",
7
+ :password => "sekret",
8
+ :password_confirmation => "sekret"}.merge(options)
9
+ end
10
+
11
+ describe "AuthSlice::User", :shared => true do
12
+ describe "username" do
13
+ it "should require username field" do
14
+ user = AuthSlice::User.new
15
+ user.should respond_to(:username)
16
+ user.should_not be_valid
17
+ user.errors.on(:username).should_not be_nil
18
+ end
19
+
20
+ it "should fail validation with username less than 3 chars" do
21
+ user = AuthSlice::User.new
22
+ user.username = "AB"
23
+ user.should_not be_valid
24
+ user.errors.on(:username).should_not be_nil
25
+ end
26
+
27
+ it "should require username with between 3 and 40 chars" do
28
+ user = AuthSlice::User.new(valid_user_hash(:username => nil))
29
+ [3,40].each do |num|
30
+ user.username = "a" * num
31
+ user.should be_valid
32
+ user.errors.on(:username).should be_nil
33
+ end
34
+ end
35
+
36
+ it "should fail validation with username over 90 chars" do
37
+ user = AuthSlice::User.new
38
+ user.username = "A" * 41
39
+ user.valid?
40
+ user.errors.on(:username).should_not be_nil
41
+ end
42
+
43
+ it "should make a valid user with all required fields set" do
44
+ user = AuthSlice::User.new(valid_user_hash)
45
+ user.save.should be_true
46
+ user.errors.should be_empty
47
+ end
48
+
49
+ it "should set timestamps after save" do
50
+ user = AuthSlice::User.new(valid_user_hash)
51
+ user.save.should be_true
52
+ user.created_at.should_not be_nil
53
+ user.updated_at.should_not be_nil
54
+ end
55
+
56
+ it "should make sure username is unique" do
57
+ user = AuthSlice::User.new( valid_user_hash(:username => "Daniel") )
58
+ user2 = AuthSlice::User.new( valid_user_hash(:username => "Daniel"))
59
+ user.save.should be_true
60
+ user.username.should == "daniel"
61
+ user2.save.should be_false
62
+ user2.errors.on(:username).should_not be_nil
63
+ end
64
+
65
+ it "should make sure username is unique regardless of case" do
66
+ user = AuthSlice::User.new( valid_user_hash(:username => "Daniel") )
67
+ user2 = AuthSlice::User.new( valid_user_hash(:username => "daniel"))
68
+ user.save.should be_true
69
+ user.username = "Daniel"
70
+ user2.save.should be_false
71
+ user2.errors.on(:username).should_not be_nil
72
+ end
73
+
74
+ it "should downcase username" do
75
+ user = AuthSlice::User.new( valid_user_hash(:username => "DaNieL"))
76
+ user.username.should == "daniel"
77
+ end
78
+
79
+ it "should authenticate a user using a class method" do
80
+ user = AuthSlice::User.new(valid_user_hash)
81
+ user.save.should be_true
82
+ AuthSlice::User.authenticate(valid_user_hash[:username], valid_user_hash[:password]).should_not be_nil
83
+ end
84
+
85
+ it "should not authenticate a user using the wrong password" do
86
+ user = AuthSlice::User.new(valid_user_hash)
87
+ user.save.should be_true
88
+ AuthSlice::User.authenticate(valid_user_hash[:username], "not_the_password").should be_nil
89
+ end
90
+
91
+ it "should not authenticate a user using the wrong username" do
92
+ user = AuthSlice::User.create(valid_user_hash)
93
+ AuthSlice::User.authenticate("not_the_username", valid_user_hash[:password]).should be_nil
94
+ end
95
+
96
+ it "should not authenticate a user that does not exist" do
97
+ AuthSlice::User.authenticate("i_dont_exist", "password").should be_nil
98
+ end
99
+ end
100
+
101
+ describe "the password fields for User" do
102
+ before(:each) do
103
+ @user = AuthSlice::User.new( valid_user_hash )
104
+ end
105
+
106
+ it "should respond to password" do
107
+ @user.should respond_to(:password)
108
+ end
109
+
110
+ it "should respond to password_confirmation" do
111
+ @user.should respond_to(:password_confirmation)
112
+ end
113
+
114
+ it "should have a protected password_required method" do
115
+ @user.protected_methods.should include("password_required?")
116
+ end
117
+
118
+ it "should respond to crypted_password" do
119
+ @user.should respond_to(:crypted_password)
120
+ end
121
+
122
+ it "should require password if password is required" do
123
+ user = AuthSlice::User.new( valid_user_hash(:password => nil))
124
+ user.stub!(:password_required?).and_return(true)
125
+ user.should_not be_valid
126
+ user.errors.on(:password).should_not be_nil
127
+ user.errors.on(:password).should_not be_empty
128
+ end
129
+
130
+ it "should set the salt" do
131
+ user = AuthSlice::User.new(valid_user_hash)
132
+ user.salt.should be_nil
133
+ user.send(:encrypt_password)
134
+ user.salt.should_not be_nil
135
+ end
136
+
137
+ it "should require the password on create" do
138
+ user = AuthSlice::User.new(valid_user_hash(:password => nil))
139
+ user.save.should_not be_true
140
+ user.errors.on(:password).should_not be_nil
141
+ user.errors.on(:password).should_not be_empty
142
+ end
143
+
144
+ it "should require password_confirmation if the password_required?" do
145
+ user = AuthSlice::User.new(valid_user_hash(:password_confirmation => nil))
146
+ user.save.should_not be_true
147
+ (user.errors.on(:password) || user.errors.on(:password_confirmation)).should_not be_nil
148
+ end
149
+
150
+ it "should fail when password is outside 4 and 40 chars" do
151
+ [3,41].each do |num|
152
+ user = AuthSlice::User.new(valid_user_hash(:password => ("a" * num)))
153
+ user.should_not be_valid
154
+ user.errors.on(:password).should_not be_nil
155
+ end
156
+ end
157
+
158
+ it "should pass when password is within 4 and 40 chars" do
159
+ [4,30,40].each do |num|
160
+ user = AuthSlice::User.new(valid_user_hash(:password => ("a" * num), :password_confirmation => ("a" * num)))
161
+ user.should be_valid
162
+ user.errors.on(:password).should be_nil
163
+ end
164
+ end
165
+
166
+ it "should autenticate against a password" do
167
+ user = AuthSlice::User.new(valid_user_hash)
168
+ user.save.should be_true
169
+ user.should be_authenticated(valid_user_hash[:password])
170
+ end
171
+
172
+ it "should not require a password when saving an existing user" do
173
+ user = AuthSlice::User.create(valid_user_hash)
174
+ user = AuthSlice::User.find_by_username(valid_user_hash[:username])
175
+ user.password.should be_nil
176
+ user.password_confirmation.should be_nil
177
+ user.username = "some_different_username_to_allow_saving"
178
+ user.save.should be_true
179
+ end
180
+ end
181
+
182
+ describe "remember_me" do
183
+ predicate_matchers[:remember_token] = :remember_token?
184
+
185
+ before do
186
+ @user = AuthSlice::User.new(valid_user_hash)
187
+
188
+ t = Date.today
189
+ Date.stub!(:today).and_return(t)
190
+ end
191
+
192
+ it "should have a remember_token_expires_at attribute" do
193
+ @user.attributes.keys.any?{|a| a.to_s == "remember_token_expires_at"}.should_not be_nil
194
+ end
195
+
196
+ it "should return true if remember_token_expires_at is set and is in the future" do
197
+ @user.remember_token_expires_at = Date.today + 7
198
+ @user.should remember_token
199
+ end
200
+
201
+ it "should set remember_token_expires_at to a specific date" do
202
+ time = Date.new(2009,12,25)
203
+ @user.remember_me_until(time)
204
+ @user.remember_token_expires_at.should == time
205
+ end
206
+
207
+ it "should set the remember_me token when remembering" do
208
+ time = Date.new(2009,12,25)
209
+ @user.remember_me_until(time)
210
+ @user.remember_token.should_not be_nil
211
+ @user.save
212
+ @user = AuthSlice::User.find_by_username(valid_user_hash[:username])
213
+ @user.remember_token.should_not be_nil
214
+ @user.remember_token_expires_at.should == time
215
+ end
216
+
217
+ it "should set remember_me token for" do
218
+ remember_until = Date.today + 7
219
+ @user.remember_me_for(7)
220
+ @user.remember_token_expires_at.should == (remember_until)
221
+ end
222
+
223
+ it "should remember_me token for two weeks" do
224
+ @user.remember_me
225
+ @user.remember_token_expires_at.should == (Date.today + 14)
226
+ end
227
+
228
+ it "should forget me" do
229
+ @user.remember_me
230
+ @user.save
231
+ @user.forget_me
232
+ @user.remember_token.should be_nil
233
+ @user.remember_token_expires_at.should be_nil
234
+ end
235
+
236
+ it "should persist the remember_me token to the database" do
237
+ @user.remember_me
238
+ @user.save
239
+
240
+ @user = AuthSlice::User.find_by_username(valid_user_hash[:username])
241
+ @user.remember_token.should_not be_nil
242
+ @user.remember_token_expires_at == (Date.today + 14)
243
+
244
+ @user.forget_me
245
+
246
+ @user = AuthSlice::User.find_by_username(valid_user_hash[:username])
247
+ @user.remember_token.should be_nil
248
+ @user.remember_token_expires_at.should be_nil
249
+ end
250
+ end
251
+ end