|
78 | 78 | context "with AA's default logout_link_method (:get)" do |
79 | 79 | before { sign_in admin_user } |
80 | 80 |
|
81 | | - it "accepts GET /admin/logout" do |
| 81 | + it "accepts GET /admin/logout", skip: (ActiveAdmin::Oidc.aa_v4? && "AA 4 dropped logout_link_method; layout uses button_to + Turbo") do |
82 | 82 | get "/admin/logout" |
83 | 83 |
|
84 | 84 | expect(response).to be_redirect |
|
87 | 87 | expect(response).to redirect_to("/admin/login") |
88 | 88 | end |
89 | 89 | end |
| 90 | + |
| 91 | + # Route-table introspection so a future regression in the mount-time |
| 92 | + # method-resolution logic is caught even if no request spec happens |
| 93 | + # to exercise the affected verb. Reads the verbs actually advertised |
| 94 | + # by the destroy route and compares them against what AA and Devise |
| 95 | + # configured. |
| 96 | + describe "destroy_admin_user_session route verbs" do |
| 97 | + subject(:route) do |
| 98 | + Rails.application.routes.routes.find { |r| r.name == "destroy_admin_user_session" } |
| 99 | + end |
| 100 | + |
| 101 | + it "exists" do |
| 102 | + expect(route).not_to be_nil |
| 103 | + end |
| 104 | + |
| 105 | + it "includes Devise.sign_out_via" do |
| 106 | + Array(::Devise.sign_out_via).each do |method| |
| 107 | + expect(route.verb).to match(/#{method.to_s.upcase}/), |
| 108 | + "destroy_admin_user_session does not accept #{method.to_s.upcase} (verb: #{route.verb.inspect})" |
| 109 | + end |
| 110 | + end |
| 111 | + |
| 112 | + it "includes ActiveAdmin.application.logout_link_method when AA exposes it" do |
| 113 | + aa_app = ::ActiveAdmin.application |
| 114 | + skip "AA 4 dropped logout_link_method" unless aa_app.respond_to?(:logout_link_method) |
| 115 | + |
| 116 | + expected = aa_app.logout_link_method&.to_s&.upcase |
| 117 | + skip "logout_link_method not set" if expected.nil? |
| 118 | + |
| 119 | + expect(route.verb).to match(/#{expected}/), |
| 120 | + "destroy_admin_user_session does not accept #{expected} (verb: #{route.verb.inspect})" |
| 121 | + end |
| 122 | + |
| 123 | + # End-to-end proof that the gem follows host overrides: change |
| 124 | + # AA's setting, reload routes, then drive an actual request |
| 125 | + # through the freshly-drawn route. Catches regressions where |
| 126 | + # logout_link_method gets read once at boot and frozen into the |
| 127 | + # closure (route introspection alone wouldn't catch a frozen |
| 128 | + # `via:` array if Rails resolved it before the stub took effect). |
| 129 | + it "logs the user out via the method host configured on logout_link_method" do |
| 130 | + aa_app = ::ActiveAdmin.application |
| 131 | + skip "AA 4 dropped logout_link_method" unless aa_app.respond_to?(:logout_link_method) |
| 132 | + |
| 133 | + original = aa_app.logout_link_method |
| 134 | + begin |
| 135 | + allow(aa_app).to receive(:logout_link_method).and_return(:put) |
| 136 | + Rails.application.reload_routes! |
| 137 | + |
| 138 | + sign_in admin_user |
| 139 | + put "/admin/logout" |
| 140 | + expect(response).to be_redirect |
| 141 | + |
| 142 | + # Session is really cleared — subsequent admin request is |
| 143 | + # bounced back to the login page. |
| 144 | + get "/admin" |
| 145 | + expect(response).to redirect_to("/admin/login") |
| 146 | + ensure |
| 147 | + allow(aa_app).to receive(:logout_link_method).and_return(original) |
| 148 | + Rails.application.reload_routes! |
| 149 | + end |
| 150 | + end |
| 151 | + end |
90 | 152 | end |
0 commit comments