Skip to content

Commit 1c2870e

Browse files
committed
TDD step 8: Logout request spec
Verifies that DELETE /admin/logout clears the session via Devise's stock flow, that subsequent admin requests bounce back to the login page, that it's idempotent when already signed out, and crucially that WebMock sees no outbound HTTP to the IdP — the gem deliberately keeps logout local.
1 parent 02788a9 commit 1c2870e

3 files changed

Lines changed: 67 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
//= link active_admin.css
2+
//= link active_admin.js
23

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// stub for specs — ActiveAdmin layout references this file

spec/requests/logout_spec.rb

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# frozen_string_literal: true
2+
3+
require "rails_helper"
4+
5+
# Verifies that signing out goes through Devise's stock session destroy
6+
# and does NOT hit the IdP's end_session_endpoint. The gem intentionally
7+
# keeps logout local — hosts that want RP-initiated single-logout can
8+
# override the destroy action themselves.
9+
RSpec.describe "Logout", type: :request do
10+
include Devise::Test::IntegrationHelpers
11+
12+
before do
13+
ActiveAdmin::Oidc.configure do |c|
14+
c.issuer = "https://idp.example.com"
15+
c.client_id = "client-abc"
16+
c.on_login = ->(*) { true }
17+
end
18+
19+
AdminUser.delete_all
20+
end
21+
22+
let!(:admin_user) do
23+
AdminUser.create!(
24+
email: "alice@example.com",
25+
provider: "oidc",
26+
uid: "sub-123"
27+
)
28+
end
29+
30+
context "with a signed-in admin user" do
31+
before { sign_in admin_user }
32+
33+
it "clears the session and redirects to the login page" do
34+
# sanity: we can reach /admin while signed in
35+
get "/admin"
36+
expect(response).to have_http_status(:ok).or have_http_status(:redirect)
37+
38+
delete "/admin/logout"
39+
expect(response).to be_redirect
40+
41+
# Subsequent admin request is bounced back to the login page.
42+
get "/admin"
43+
expect(response).to redirect_to("/admin/login")
44+
end
45+
46+
it "does not hit the IdP end_session endpoint" do
47+
WebMock.reset!
48+
stub_any = WebMock.stub_request(:any, /idp\.example\.com/)
49+
50+
delete "/admin/logout"
51+
52+
expect(stub_any).not_to have_been_requested
53+
end
54+
end
55+
56+
context "when already signed out" do
57+
it "is idempotent and still redirects to login" do
58+
delete "/admin/logout"
59+
expect(response).to be_redirect
60+
61+
get "/admin"
62+
expect(response).to redirect_to("/admin/login")
63+
end
64+
end
65+
end

0 commit comments

Comments
 (0)