Skip to content

Commit

Permalink
Warden::Test::Helpers unlogin method
Browse files Browse the repository at this point in the history
- Add an unlogin helper method, for testing custom serializers and fetch
  hooks in the context of your app.
- Made the existing helper tests more specific about what happens
  by logging the events as they go.
- Made the logout helper tests actually test the logout helper.
  • Loading branch information
BrianHawley committed Jun 24, 2022
1 parent 8b44aa4 commit c535234
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 15 deletions.
18 changes: 18 additions & 0 deletions lib/warden/test/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,24 @@ def logout(*scopes)
proxy.logout(*scopes)
end
end

# Removes the user(s) from the list of logged-in users, but doesn't log
# them out of the session. The user will then be fetched from the session
# and deserialized when requested by Warden::Proxy#user. This lets you
# test cookie deserialization and after_fetch hooks in your app context.
# Without arguments, all scopes will have their users cleared.
# Provide a list of scopes to only clear users with those scopes.
# @api public
def unlogin(*scopes)
Warden.on_next_request do |proxy|
users = proxy.instance_variable_get(:@users)
if scopes.empty?
users.clear
else
scopes.each { |scope| users.delete(scope) }
end
end
end
end
end
end
179 changes: 164 additions & 15 deletions spec/warden/test/helpers_spec.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
# encoding: utf-8
# frozen_string_literal: true
RSpec.describe Warden::Test::Helpers do
before{ $captures = [] }
after{ Warden.test_reset! }
before do
$captures = []
Warden::Manager._after_set_user.clear
Warden::Manager._before_logout.clear
Warden::Manager.after_set_user do |user, _auth, opts|
$captures << { :action => :set_user, :user => user }.merge(opts)
end
Warden::Manager.before_logout do |user, _auth, opts|
$captures << { :action => :logout, :user => user }.merge(opts)
end
end

it "should log me in as a user" do
after do
Warden.test_reset!
Warden::Manager._after_set_user.clear
Warden::Manager._before_logout.clear
end

it "#login_as should log me in as a user" do
user = "A User"
login_as user
app = lambda{|e|
Expand All @@ -14,10 +29,13 @@
valid_response
}
setup_rack(app).call(env_with_params)
expect($captures).to eq([:run])
expect($captures).to eq([
{ :action => :set_user, :event => :authentication, :scope => :default, :user => user },
:run
])
end

it "should log me in as a user of a given scope" do
it "#login_as with a scope should log me in as a user in that scope" do
user = {:some => "user"}
login_as user, :scope => :foo_scope
app = lambda{|e|
Expand All @@ -27,10 +45,13 @@
expect(w.user(:foo_scope)).to eq(some: "user")
}
setup_rack(app).call(env_with_params)
expect($captures).to eq([:run])
expect($captures).to eq([
{ :action => :set_user, :event => :authentication, :scope => :foo_scope, :user => user },
:run
])
end

it "should login multiple users with different scopes" do
it "#login_as should login multiple users with different scopes" do
user = "A user"
foo_user = "A foo user"
login_as user
Expand All @@ -44,43 +65,171 @@
expect(w).to be_authenticated(:foo)
}
setup_rack(app).call(env_with_params)
expect($captures).to eq([:run])
expect($captures).to eq([
{ :action => :set_user, :event => :authentication, :scope => :default, :user => user },
{ :action => :set_user, :event => :authentication, :scope => :foo, :user => foo_user },
:run
])
end

it "should log out all users" do
it "#logout should log out all users" do
user = "A user"
foo = "Foo"
login_as user
login_as foo, :scope => :foo
logout
app = lambda{|e|
$captures << :run
w = e['warden']
expect(w.user).to eq("A user")
expect(w.user(:foo)).to eq("Foo")
w.logout
expect(w.user).to be_nil
expect(w.user(:foo)).to be_nil
expect(w).not_to be_authenticated
expect(w).not_to be_authenticated(:foo)
}
setup_rack(app).call(env_with_params)
expect($captures).to eq([:run])
expect($captures).to eq([
{ :action => :set_user, :event => :authentication, :scope => :default, :user => user },
{ :action => :set_user, :event => :authentication, :scope => :foo, :user => foo },
{ :action => :logout, :scope => :default, :user => user },
{ :action => :logout, :scope => :foo, :user => foo },
:run
])
end

it "should logout a specific user" do
it "#logout of a scope should logout that scope's specific user" do
user = "A User"
foo = "Foo"
login_as user
login_as foo, :scope => :foo
logout :foo
app = lambda{|e|
$captures << :run
w = e['warden']
w.logout :foo
expect(w.user).to eq("A User")
expect(w.user(:foo)).to be_nil
expect(w).not_to be_authenticated(:foo)
}
setup_rack(app).call(env_with_params)
expect($captures).to eq([
{ :action => :set_user, :event => :authentication, :scope => :default, :user => user },
{ :action => :set_user, :event => :authentication, :scope => :foo, :user => foo },
{ :action => :logout, :scope => :foo, :user => foo },
:run
])
end

it "#logout can log out of multiple scopes, in the order specified" do
user = "A user"
foo = "Foo"
login_as user
login_as foo, :scope => :foo
logout :foo, :default
app = lambda{|e|
$captures << :run
w = e['warden']
expect(w.user).to be_nil
expect(w.user(:foo)).to be_nil
expect(w).not_to be_authenticated
expect(w).not_to be_authenticated(:foo)
}
setup_rack(app).call(env_with_params)
expect($captures).to eq([
{ :action => :set_user, :event => :authentication, :scope => :default, :user => user },
{ :action => :set_user, :event => :authentication, :scope => :foo, :user => foo },
{ :action => :logout, :scope => :foo, :user => foo },
{ :action => :logout, :scope => :default, :user => user },
:run
])
end

it "#logout with no users logged in should be a noop" do
logout
app = lambda{|e|
$captures << :run
w = e['warden']
expect(w.user).to be_nil
expect(w.user(:foo)).to be_nil
expect(w).not_to be_authenticated
expect(w).not_to be_authenticated(:foo)
}
setup_rack(app).call(env_with_params)
expect($captures).to eq([:run])
end

it "#unlogin should cause the user to be fetched from the session, but not log out" do
user = "A User"
login_as user
unlogin
app = lambda{|e|
$captures << :run
expect(e['warden']).to be_authenticated
expect(e['warden'].user).to eq("A User")
valid_response
}
setup_rack(app).call(env_with_params)
expect($captures).to eq([
{ :action => :set_user, :event => :authentication, :scope => :default, :user => user },
:run,
{ :action => :set_user, :event => :fetch, :scope => :default, :user => user }
])
end

it "#unlogin of a scope should cause that scope's specific user to be fetched from the session, but not log out" do
user = "A User"
foo = "A foo user"
login_as user
login_as foo, :scope => :foo
unlogin :foo
app = lambda{|e|
$captures << :run
w = e['warden']
expect(w.user).to eq("A User")
expect(w.user(:foo)).to eq("A foo user")
expect(w).to be_authenticated(:foo)
}
setup_rack(app).call(env_with_params)
expect($captures).to eq([
{ :action => :set_user, :event => :authentication, :scope => :default, :user => user },
{ :action => :set_user, :event => :authentication, :scope => :foo, :user => foo },
:run,
{ :action => :set_user, :event => :fetch, :scope => :foo, :user => foo }
])
end

it "#unlogin can handle multiple scopes, without affecting fetch order" do
user = "A User"
foo = "A foo user"
login_as user
login_as foo, :scope => :foo
unlogin :foo, :default
app = lambda{|e|
$captures << :run
w = e['warden']
expect(w.user).to eq("A User")
expect(w.user(:foo)).to eq("A foo user")
expect(w).to be_authenticated(:foo)
}
setup_rack(app).call(env_with_params)
expect($captures).to eq([
{ :action => :set_user, :event => :authentication, :scope => :default, :user => user },
{ :action => :set_user, :event => :authentication, :scope => :foo, :user => foo },
:run,
{ :action => :set_user, :event => :fetch, :scope => :default, :user => user },
{ :action => :set_user, :event => :fetch, :scope => :foo, :user => foo }
])
end

it "#unlogin with no users logged in should be a noop" do
unlogin
app = lambda{|e|
$captures << :run
w = e['warden']
expect(w.user).to be_nil
expect(w.user(:foo)).to be_nil
expect(w).not_to be_authenticated
expect(w).not_to be_authenticated(:foo)
}
setup_rack(app).call(env_with_params)
expect($captures).to eq([:run])
end

Expand Down

0 comments on commit c535234

Please sign in to comment.