0

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?

2 Answers 2

2

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 
Sign up to request clarification or add additional context in comments.

3 Comments

50% of Ruby programming is about hash manipulation - I'd argue that only 10% is hash manipulation, another 10% is figuring out how to write your method on one line, and 80% is bragging about how great Ruby is. :)
Thanks, maxcal. I ended up needing the one liner from another answer. I'm using FactoryGirl already but the point of the test is whether the API creates the record. I'll second that 80%, zetetic!
Then you can do FactoryGirl.attributes_for(:product, organization_type: "ABC")
1

I think you should send a single hash in your post. Try the following:

post :create, json.merge!(access_token: @api_app.access_token) 

1 Comment

The simplest answer wins! Thank you, gabrielhilal.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.