Specifying Content Type in rspec - ruby

I'm trying to build an rspec test that sends JSON (or XML) via POST. However, I can't seem to actually get it working:
json = {.... data ....}.to_json
post '/model1.json',json,{'CONTENT_TYPE'=>'application/json'}
and this
json = {.... data ....}.to_json
post '/model1.json',json,{'Content-Type'=>'application/json'}
any ideas? THANKS!

In Rails 3, you can skip the header and #request.env stuff and just add a format parameter to your post call, e.g.:
post :create, format: :json, param: 'Value of Param'

There's a way to do this described in this thread -- it's a hack, but it seems to work:
#request.env["HTTP_ACCEPT"] = "application/json"
json = { ... data ... }.to_json
post :create, :some_param => json

A lot of frustration and variations and that's what worked for me.
Rails 3.2.12 Rspec 2.10
#request.env["HTTP_ACCEPT"] = "application/json"
#request.env["CONTENT_TYPE"] = "application/json"
put :update, :id => 1, "email" => "bing#test.com"

First of all, you don't want to test the built-in conversion of json to hash. Same applies to xml.
You test controller with data as hashes, not bothering wether it's json, xml or from a html form.
But if you would like to do that as an exercise, this is a standalone ruby script to do play with :)
require 'json'
url = URI.parse('http://localhost:3030/mymodels.json')
request = Net::HTTP::Post.new(url.path)
request.content_type="application/json"
request.basic_auth('username', 'password') #if used, else comment out
hash = {:mymodel => {:name => "Test Name 1", :description => "some data for testing description"}}
request.body = hash.to_json
response = Net::HTTP.start(url.host, url.port) {|http| http.request(request)}
puts response
to switch to xml, use content_type="text/xml" and
request.body = "<?xml version='1.0' encoding='UTF-8'?><somedata><name>Test Name 1</name><description>Some data for testing</description></somedata>"

A slightly more elegant test is to use the header helper:
header "HTTP_ACCEPT", "application/json"
json = {.... data ....}.to_json
post '/model1.json', json
Now this does exactly the same thing as setting #env; it's just a bit prettier.

The best way that I have found to test these things is with request tests. Request tests go through the full param parsing and routing stages of Rails. So I can write a test like this:
request_params = {:id => 1, :some_attribute => "some value"}
headers = {'Accept' => 'application/json', 'Content-Type' => 'application/json'}
put "/url/path", request_params.to_json, headers
expect(response).to be_success

I think that you can specify the headers with headers param:
post '/model1.json', headers: {'Content-type': 'application/json'}
Following the Rspec documentation of how provide JSON data.

#request.env["CONTENT_TYPE"] = "application/json"
OR pass in request
"CONTENT_TYPE" => "application/json"

Related

HTTParty post method doesn't return status code when adding follow_redirects = false along with other headers and cookies?

The HTTParty methods are like HTTParty.XXX(urlGoesHere, and Args Here)
I'm doing the following:
params = {:UserName => "uname", :Password => "pwd"}
cookie_hash = HTTParty::CookieHash.new
cookie_hash.add_cookies("key1=val1")
cookie_hash.add_cookies("key2=val2")
options = {
:body=>params,
:headers => { 'Cookie' => cookie_hash.to_cookie_string,
'Accept' => something },
:follow_redirects => false
}
URLUserNamePwd = HTTParty.post(myURL, options) # Is this the right way to do?
When I check the http status code, body I get nothing. When I check in the browser development console, I see 302 redirect, and in response headers I see lot of header pairs returned.
What is the URL you're attempting to hit? 302 Found will be paired with a Location header containing the URL where the resource can be found.

In ruby with sinatra, How to get I response with get method on rest client?

I use ruby with sinatra and I used rest-client on import for payment.
I got token that string typed through post method on specific url: '... /users/getToken'.
Using this token, I wanna get payments information with get method on this url:
get_url = 'https://api/iamport.kr/payments/'+imp_uid
the detail codes are below,
def get_paymentsdetails(token, imp_uid)
get_url = 'https://api.iamport.kr/payments/'+imp_uid
response = RestClient.get get_url, :data => {}.to_json, :accept => :json, :headers => {'Authorization' => token}
json = JSON.parse(response, :symbolize_names => true)
# json = JSON.parse(response.to_json, {:symbolize_names => true})
return json
end
However, I got 401 unauthorized error on this part of code.
response = RestClient.get get_url, :data => {}.to_json, :accept => :json, :headers => {'Authorization' => token}
After I access get_url with specific imp_uid, I got this page,{"code":-1,"message":"Unauthorized","response":null}
I checked parameter token and imp_uid of get_paymentsdetails function have valid string values,, so How can I access response parameter??
I think that there are some problems on response = RestClient.get get_url.... code.
Thanks.
Method 'get' from the 'RestClient' class return some object with attributes. So response have few values. Which of them do you need? Access to them you can get by their names, its described here.
In your case, after response = RestClient.get get_url... you should have variable response and ability to call response.headers, response.code or response.body.
But im afraid that you have some problems with autorization, which means that imp_uid or token is not correct. Thats why remote server sended to you responce with http-code 401 (Unauthorized). If it is so you should try to check your imp_uid and token. If everything is correct try to reach support of iamport.kr .

Ruby RestClient post request with cookies

I've been trying for over a week now with no joy to post an api request setting the cookies with values from a previous request. First request is fine:
response = RestClient.post ('http://api-qa1:8180/api/rest/GB/session'),'{"email":""}',:content_type => 'application/json'
obj = JSON.parse(response)
id = obj['id']
profileId = obj['profile_id']
#cookies = response.cookies
dyn = obj['verification_id']
jsessionid = #cookies['JSESSIONID']
puts jsessionid,dyn,profileID
I get a response and the values i need, I now want to use the values returned 'profile_id'(URi), jsessionid(cookie), and dyn(cookie) values to form my second request.
res = RestClient.post ("http://api-qa1:8180/api/rest/GB/profile/#{profileId}/cart/item"),
'{
"sku_id":"1234"
"product_id":"1234"
"quantity":"2"
"recommended":"false"
}',
headers = {
:content_type => 'application/json',
:userPrefLanguage => 'en-GB'
}
cookies = {'JSESSIONID' => jsessionid},{'DYN_USER_CONFIRM' => dyn }
I've tried many combinations all to no avail, this is as far as i've got which gives me a 403, im also aware that post request should have a maximum of 3 arguments I just cant get it to work. The cookies properties i need to set are
DYN_USER_CONFIRM and JSESSION.
Just looking at the documentation for RestClient:
response.cookies
# => {"_applicatioN_session_id" => "1234"}
response2 = RestClient.post(
'http://localhost:3000/',
{:param1 => "foo"},
{:cookies => {:session_id => "1234"}}
)
It looks like you need to set cookies and headers as a hash inside of the request. The code you've posted has cookies = .... and it's not inside of the request. You need to set headers in a hash as well I believe.

Rspec Controller testing with Javascript

How do you test a controller in Rspec if the controller only responds with javascript? For example this would be my actual code:
some view.html.erb
link_to 'More Chips', add_chips_path, :remote => true
chips_controller
def add_chips
Chips.create(:color => :red)
#chips = Chips.all
end
add_chips.js.erb
$('#chip_count').html('<%=j render("chips/list", :chips => #chips) %>');
Rspec Test
spec/controllers/chips_controller_spec
it "should add chips" do
post :add_chips, :format => 'js'
end
When I try to post to this using RSpec I get a Missing Template error because it is sending an HTML request but there isn't an HTML view. I've tried passing in a format but that doesn't seem to work. I know I can put in a "dummy" html view to make it pass but that seems like a hack.
Thanks
If you're trying to perform an Ajax request from a controller spec, instead of doing post :add_chips and passing the format as a parameter, you should do:
xhr :post, :add_chips, #params
...without format in params. That will do a JavaScript request and respond with the .js template.
Update:
In recent versions of Rails/RSpec, you should instead do:
post :add_chips, params: #params, xhr: true
Ok, I figured out what I was doing wrong. I was passing a parameters hash in with my test and the format needs to be included in the same hash. so instead of this:
#params = {:chip_color => 'red'}
...
post :add_chips, #params, :format => 'js'
It needs to look like this
#params = {:chip_color => 'red', :format => 'js'}
...
post :add_chips, #params

Setting Request Headers in Ruby

I have the rest client gem and I am defining a request like this:
url = 'http://someurl'
request = {"data" => data}.to_json
response = RestClient.post(url,request,:content_type => :json, :accept => :json)
However I need to set the HTTP header to something. For example an API key. Which could be done in curl as:
curl -XHEAD -H x-auth-user: myusername -H x-auth-key: mykey "url"
Whats the best way to do this in ruby? Using this gem? Or can I do it manually to have more control.
The third parameter is the headers hash.
You can do what you want by:
response = RestClient.post(
url,
request,
:content_type => :json, :accept => :json, :'x-auth-key' => "mykey")
You can also do this
RestClient::Request.execute(
:method => :get or :post,
:url => your_url,
:headers => {key => value}
)
I had the same problem with Rest-Client (1.7.2) I need to put both params and HTTP headers.
I solved with this syntax:
params = {id: id, device: device, status: status}
headers = {myheader: "giorgio"}
RestClient.put url, params, headers
I hate RestClient :-)
If PUT isn't allowed we can pass it in the header of POST. Headers in bold. This worked for me:
act_resp = RestClient.post url, req_param, **:content_type => :json, :method => :put**

Resources