diff --git a/app/controllers/waiting_lists_controller.rb b/app/controllers/waiting_lists_controller.rb index 471def73d..a27f0c759 100644 --- a/app/controllers/waiting_lists_controller.rb +++ b/app/controllers/waiting_lists_controller.rb @@ -26,7 +26,13 @@ def create # rubocop:disable Metrics/MethodLength end def destroy - WaitingList.find_by(invitation_id: @invitation.id).destroy + entry = WaitingList.find_by(invitation_id: @invitation.id) + unless entry + return redirect_to(invitation_path(@invitation), + notice: 'You are not on the waiting list') + end + + entry.destroy MemberActivityRecorder.record(actor: @invitation.member, key: 'waiting_list.left', trackable: @invitation) diff --git a/spec/controllers/waiting_lists_controller_spec.rb b/spec/controllers/waiting_lists_controller_spec.rb index cf09b26c4..047d1fc6f 100644 --- a/spec/controllers/waiting_lists_controller_spec.rb +++ b/spec/controllers/waiting_lists_controller_spec.rb @@ -48,6 +48,21 @@ end describe 'DELETE #destroy' do + context 'when the waiting-list entry is already gone' do + it 'redirects with a notice instead of raising' do + delete :destroy, params: { invitation_id: invitation.token } + + expect(response).to redirect_to(invitation_path(invitation)) + expect(flash[:notice]).to eq('You are not on the waiting list') + end + + it 'does not record a "waiting_list.left" activity' do + delete :destroy, params: { invitation_id: invitation.token } + + expect(PublicActivity::Activity.where(key: 'waiting_list.left')).to be_empty + end + end + context 'without a CSRF token (browser did not send session cookie)' do include_context 'with forgery protection enforced'