diff --git a/apps/web/config/routes.rb b/apps/web/config/routes.rb index d2fbbe3..546661c 100644 --- a/apps/web/config/routes.rb +++ b/apps/web/config/routes.rb @@ -4,3 +4,5 @@ resources :users, only: %i[new create] resources :sessions, only: %i[new create] + +delete 'sessions', as: 'logout' diff --git a/apps/web/controllers/sessions/destroy.rb b/apps/web/controllers/sessions/destroy.rb new file mode 100644 index 0000000..e8b1047 --- /dev/null +++ b/apps/web/controllers/sessions/destroy.rb @@ -0,0 +1,23 @@ +module Web + module Controllers + module Sessions + class Destroy + include Web::Action + + prepend_before :skip_authentication! + + def call(_params) + process + end + + private + + def process + warden.logout + flash[:notice] = 'Successfully logged out' + redirect_to routes.root_path + end + end + end + end +end diff --git a/spec/web/config/routes_spec.rb b/spec/web/config/routes_spec.rb new file mode 100644 index 0000000..1ba8c27 --- /dev/null +++ b/spec/web/config/routes_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +RSpec.describe Web.routes do + describe 'DELETE session' do + let(:generated_path) { described_class.path(:logout) } + let(:env) { Rack::MockRequest.env_for('/sessions', method: 'DELETE') } + let(:route) { described_class.recognize(env) } + + it 'has a generated path' do + expect(generated_path).to eq('/sessions') + end + + it 'is a recognisable route' do + expect(route).to be_routable + expect(route.path).to eq('/sessions') + expect(route.verb).to eq('DELETE') + end + end +end diff --git a/spec/web/controllers/sessions/destroy_spec.rb b/spec/web/controllers/sessions/destroy_spec.rb new file mode 100644 index 0000000..7b36706 --- /dev/null +++ b/spec/web/controllers/sessions/destroy_spec.rb @@ -0,0 +1,21 @@ +RSpec.describe Web::Controllers::Sessions::Destroy, type: :action do + let(:action) { described_class.new } + let(:response) { action.call(params) } + let(:params) { Hash[] } + let(:warden) { instance_double Warden::Proxy } + + before do + allow(action).to receive(:warden).and_return(warden) + allow(warden).to receive(:logout) + allow(warden).to receive(:user) + response + end + + it 'calls the `logout` method on warden' do + expect(warden).to have_received(:logout) + end + + it 'returns the correct response code' do + expect(response[0]).to eq 302 + end +end