I have a Rails RESTful web service application that accepts a value from a client to increment the value in the database. The database value is an integer, but when using rspec to test the code, the value being passed in is interpreted as a string.
I'm using Rails 3.1 and Ruby 1.9.2.
Here's the rspec snippet:
...
it "should find Points and return object" do
put :update, :username => "tester", :newpoints => [10, 15, 0], :format => :xml
end
...
Here's the controller code:
...
respond_to do |format|
if points.update_attributes([xp + :newpoints[0]][sp + :newpoints[1]][cash + :newpoints[2]])
format.json { head :ok }
format.xml { head :ok }
...
xp, sp and cash are values from the database and have been validated as Fixnum datatype. The error I am getting is:
TypeError: String can't be coerced into Fixnum
How do I write my test to ensure that the parameters being passed are passed as the proper datatype?
I can include more of the code if needed. Thanks in advance!
It took me a bit of head banging, but I found out that I was passing everything in wrong. The solution I've come up with is definitely not the best solution and could probably be re-written, but it works and for now, that's sufficient.
The change to the rspec snippet was to create hash represented by symbol :newpoints
it "should find Points and return object" do
put :update, :username => "tester", :newpoints => {"experience_points" => 10, "shame_points" => 15, "gold" => 0}, :format => :xml
end
The handling of this request in the controller required a bit of tweaking, but here's the pertinent pieces:
class PointsController < ApplicationController
#before_filter :authenticate, :only => :update
before_filter :must_specify_user
before_filter :fix_params
before_filter :clean_up
respond_to :html, :xml, :json
def fix_params
if params[:points]
params[:points][:user_id] = @user.id if @user
end
end
def clean_up
@newpoints = params[:newpoints]
@experience = @newpoints["experience_points"]
@shame = @newpoints["shame_points"]
@gold = @newpoints["gold"]
@xp = @experience.to_i
@sp = @shame.to_i
@cash = @gold.to_i
end
def update
points = Points.find_by_user_id(@user.id, params[:id])
xp = points.experience_points
sp = points.shame_points
cash = points.gold
final_experience = xp += @xp
final_shame = sp += @sp
final_gold = cash += @cash
final_points = {:experience_points => final_experience, :shame_points => final_shame, :gold => final_gold}
if_found points do
respond_to do |format|
if points.update_attributes!(params[final_points])
format.json { head :ok }
format.xml { head :ok }
else
format.json { render :nothing => true, :status => "401 Not Authorized"}
format.xml { render :nothing => true, :status => "401 Not Authorized"}
end
end
end
end
end
Obviously, much can be done to make this follow DRY and what not, so any suggestions are still welcome. Thanks in advance!