Reputation: 738
I have a JSON Rails 4 API that I'm testing with Rspec. I'm having trouble passing to two parameters in the post :create request.
Here is the current test:
require 'spec_helper'
module Api
module V1
describe Api::V1::ProductsController, type: :controller do
before do
@api_app = FactoryGirl.create(:api_app, request_origin: "0.0.0.0")
@store = FactoryGirl.create(:store)
end
after(:all) do
Product.all.each {|l| l.destroy}
ApiApp.all.each {|a| a.destroy}
end
describe "POST 'create' " do
context "Creates a product with the correct parameters" do
it "returns a successful response string with success message" do
json = { :format => 'json', product:{first_name:"Hello", last_name:"You", email:"[email protected]",street1:"103 ABC Street", city:"Pittsburgh", phone:"4125361111", store_id:@store.id, state:"CA", country:"United States", organization:"ABC", organization_type: "Org"}}
post :create, json, access_token: @api_app.access_token
expect(response).to be_success
expect(response.body).to include("Product created")
end
end
context "Incorrect parameters to create a product" do
it "returns a failure response when a parameter is missing" do
json = { :format => 'json', product:{first_name:"Hello", last_name:"You", email:"[email protected]",street1:"103 ABC Street", city:"Pittsburgh", phone:"4125361111", store_id:@store.id, state:"CA", country:"United States", organization:"ABC"}}
post :create, json, access_token: @api_app.access_token
expect(response).to be_success
expect(response.body).to include("Product failed to create")
end
end
end
end
end
end
I need both json and access_token on the line:
post :create, json, access_token: @api_app.access_token
but the request ignores the second parameter (I can switch their placement to confirm). How do I word the post so that both parameters are read in?
Upvotes: 0
Views: 1634
Reputation: 102036
What you are looking for is Hash.merge(other_hash)
. You might want to do some reading on the Hash class since about 50% of Ruby programming is about hash manipulation (IMHO).
This is how you would use it in your spec:
require 'spec_helper'
# You don't need to put the spec inside your module!
# It just makes it harder to read!
describe Api::V1::ProductsController, type: :controller do
before do
@api_app = FactoryGirl.create(:api_app, request_origin: "0.0.0.0")
@store = FactoryGirl.create(:store)
end
after(:all) do
Product.all.each {|l| l.destroy}
ApiApp.all.each {|a| a.destroy}
end
describe "POST 'create' " do
# DRY up the parameters
let(:params){
access_token: @api_app.access_token
format: 'json'
}
# Even better is to use fixures or factories for this.
let(:product_params) {
first_name:"Hello",
last_name:"You",
email:"[email protected]",
street1:"103 ABC Street",
city:"Pittsburgh",
phone:"4125361111",
store_id:@store.id,
state:"CA",
country:"United States",
organization:"ABC"
}
context "Creates a product with the correct parameters" do
it "returns a successful response string with success message" do
product = product_params.merge(organization_type: "Org")
post :create, params.merge(product: product)
expect(response).to be_success
expect(response.body).to include("Product created")
end
end
context "Incorrect parameters to create a product" do
it "returns a failure response when a parameter is missing" do
product = product_params.merge(organization_type: "ABC")
post :create, params.merge(product: product)
expect(response).to be_success
expect(response.body).to include("Product failed to create")
end
end
end
end
However your spec contains an misstake:
context "Incorrect parameters to create a product" do
it "returns a failure response when a parameter is missing" do
product = product_params.merge(organization_type: "ABC")
post :create, params.merge(product: product)
expect(response).to be_success #! it should not be a success!
end
end
expect(response).to be_success
actually means that the response should have the 200 OK HTTP response code - but you should be returning a 400 Bad Request if there is missing parameter. The correct expectation is:
expect(response).to have_http_status :bad_request
Upvotes: 2
Reputation: 10769
I think you should send a single hash in your post. Try the following:
post :create, json.merge!(access_token: @api_app.access_token)
Upvotes: 1