From a52afb7a2b848bc0954df503be83d3ae89197f0f Mon Sep 17 00:00:00 2001 From: Eric Davis Date: Tue, 20 Jan 2009 11:05:19 -0800 Subject: [PATCH] Protect locked rates from being updated. * Locked rates will fail to save * Attempting to save a Locked rates will display an error and reload the Rate from the database so the update parameters are thrown away #1919 --- app/controllers/rates_controller.rb | 5 +++ spec/controllers/rates_controller_spec.rb | 44 ++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/app/controllers/rates_controller.rb b/app/controllers/rates_controller.rb index fb8bc43..6a9c3bc 100644 --- a/app/controllers/rates_controller.rb +++ b/app/controllers/rates_controller.rb @@ -79,6 +79,7 @@ class RatesController < ApplicationController @rate = Rate.find(params[:id]) respond_to do |format| + # Locked rates will fail saving here. if @rate.update_attributes(params[:rate]) flash[:notice] = 'Rate was successfully updated.' format.html { @@ -90,6 +91,10 @@ class RatesController < ApplicationController } format.xml { head :ok } else + if @rate.locked? + flash[:error] = "Rate is locked and cannot be edited" + @rate.reload # Removes attribute changes + end format.html { render :action => "edit" } format.xml { render :xml => @rate.errors, :status => :unprocessable_entity } end diff --git a/spec/controllers/rates_controller_spec.rb b/spec/controllers/rates_controller_spec.rb index efe6a61..289d75d 100644 --- a/spec/controllers/rates_controller_spec.rb +++ b/spec/controllers/rates_controller_spec.rb @@ -123,7 +123,8 @@ describe RatesController, "as an administrator" do :amount => 100.0, :user => @user, :user_id => @user.id, - :unlocked? => true + :unlocked? => true, + :locked? => false }.merge(stubs) @mock_rate ||= mock_model(Rate, stubs) end @@ -353,6 +354,47 @@ describe RatesController, "as an administrator" do end end + + describe "on a locked rate" do + def mock_locked_rate(stubs = { }) + mock_rate(stubs.merge(:locked? => true, + :unlocked? => false, + :update_attributes => false, + :reload => nil + )) + end + + it "should try to update the requested rate" do + Rate.should_receive(:find).with("37").and_return(mock_locked_rate) + mock_locked_rate.should_receive(:update_attributes).with({'these' => 'params'}) + put :update, :id => "37", :rate => {:these => 'params'} + end + + it "should not save the rate" do + Rate.should_receive(:find).with("37").and_return(mock_locked_rate) + mock_locked_rate.should_receive(:update_attributes).and_return(false) + put :update, :id => "37", :rate => {:these => 'params'} + end + + it "should reload the locked rate as @rate" do + Rate.stub!(:find).and_return(mock_locked_rate(:id => 37)) + mock_locked_rate.should_receive(:reload).and_return(mock_locked_rate(:id => 37)) + put :update, :id => "37", :rate => { :amount => 200.0 } + assigns(:rate).should equal(mock_locked_rate) + end + + it "should re-render the 'edit' template" do + Rate.stub!(:find).and_return(mock_locked_rate) + put :update, :id => "1" + response.should render_template('edit') + end + + it "should render an error message" do + Rate.stub!(:find).and_return(mock_locked_rate) + put :update, :id => "1" + flash[:error].should match(/locked/) + end + end end