From ba4ccdbddd1ec2d6995ac50a75113e9981b825a5 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Sat, 10 Sep 2016 15:01:50 +0100 Subject: [PATCH] Fix race condition in sponsors controller Similar to #506, there's a race condition in the sponsors controller that can be triggered by a double submit. We can fix it in a similar fashion as well by redirecting to the thank you url as the email will have already been sent by the first submit. --- app/controllers/sponsors_controller.rb | 2 ++ spec/controllers/signatures_controller_spec.rb | 1 + spec/controllers/sponsors_controller_spec.rb | 14 ++++++++++++++ 3 files changed, 17 insertions(+) diff --git a/app/controllers/sponsors_controller.rb b/app/controllers/sponsors_controller.rb index 712fbddc0..8cacaf332 100644 --- a/app/controllers/sponsors_controller.rb +++ b/app/controllers/sponsors_controller.rb @@ -31,6 +31,8 @@ def update format.html { render :show } end end + rescue ActiveRecord::RecordNotUnique => e + redirect_to thank_you_petition_sponsor_url(@petition, token: @petition.sponsor_token) end def thank_you diff --git a/spec/controllers/signatures_controller_spec.rb b/spec/controllers/signatures_controller_spec.rb index 2467fde5d..38bf8aee1 100644 --- a/spec/controllers/signatures_controller_spec.rb +++ b/spec/controllers/signatures_controller_spec.rb @@ -477,6 +477,7 @@ def do_post(options = {}) context "when a race condition occurs" do let(:exception) { ActiveRecord::RecordNotUnique.new("PG::UniqueViolation") } + before do FactoryGirl.create(:validated_signature, signature_params.merge(petition_id: petition.id)) allow_any_instance_of(Signature).to receive(:save).and_raise(exception) diff --git a/spec/controllers/sponsors_controller_spec.rb b/spec/controllers/sponsors_controller_spec.rb index e2f529d66..cf4263226 100644 --- a/spec/controllers/sponsors_controller_spec.rb +++ b/spec/controllers/sponsors_controller_spec.rb @@ -284,6 +284,20 @@ def do_patch(options = {}) expect(assigns[:stage_manager].stage).to eq 'signer' end end + + context "when a race condition occurs" do + let(:exception) { ActiveRecord::RecordNotUnique.new("PG::UniqueViolation") } + + before do + FactoryGirl.create(:sponsor, :validated, petition: petition) + allow_any_instance_of(Signature).to receive(:save).and_raise(exception) + end + + it "redirects to the thank you page" do + do_patch + expect(response).to redirect_to("https://petition.parliament.uk/petitions/#{petition.id}/sponsors/#{petition.sponsor_token}/thank-you") + end + end end context 'GET thank-you' do