I have a request and in the response i use this:
def get_request
...
return response.code == "200"
end
but when i set in the spec:
stub_request(:get, 'https:domain.com/stock').to_return(status: 200)
I get this error: undefined method `code' for false:FalseClass
The solution is add a body with data like the response in production.
stub_request(:get, 'https:domain.com/stock')
.to_return(status: 200, body: JSON.generate(available: []))
Related
I have created a function that makes a HTTParty get request. It raises a custom error message that i need to test. I tried to stub the request using Webmock in the test but it is raising a <Net::OpenTimeout>. How can i stub the get request if the url is dynamically constructed?
def function(a , b)
# some logic , dynamic url constructed
response = HTTParty.get(url, headers: {"Content-Type" =>
"application/json"})
if response.code != 200
raise CustomError.new <<~EOF
Error while fetching job details.
Response code: #{response.code}
Response body: #{response.body}
EOF
end
JSON.parse(response.body)
for the test
def test_function
WebMock.stub_request(:get, url).with(:headers => {'Content-
Type'=>'application/json'}).to_return(:status => 500)
# HTTParty.stub(get: fake_response)
err = assert_raises CustumError do
c.function(a , b)
end
WebMock allows you to use "wildcard matching" so you can stub requests matching a regular expression:
WebMock.stub_request(:get, /example/).to_return(status: 500)
I have a module called token wrapper, in which there is a method getToken:
def Tokenwrapper.getToken
uri = URI.parse("[URL REDACTED]/api/authenticate")
request = Net::HTTP::Post.new(uri)
request.basic_auth("email#domain.com", "pass")
request.content_type = "application/json"
request["Accept"] = "application/json"
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
response
end
When I attempt to test it with the following assertion:
assert_equal("#<Net::HTTPOK:",Tokenwrapper.getToken[0..13])
I get this error:
NoMethodError: undefined method 'downcase' for 0..13:Range
I don't manually invoke the downcase method, and I don't see any reason that ruby should be doing so automatically. Why is this happening and how do I make my test run?
I'll be honest I don't know a lot about HTTP API responses and how this area of networking operates, so I'd appreciate any resources as well as answers to this question.
The response object has a [] method that provides access to a header from the response. When you're trying to do getToken[0..13] this is the method that's actually being called.
This [] is expecting a call like response['Content-Type'] and uses downcase on the value passed in in order to handle header names case insensitively.
If you want to check the first few characters from the string representation of the response you can convert the response to a string and compare it, like this:
assert_equal("#<Net::HTTPOK:",Tokenwrapper.getToken.to_s[0..13])
Alternatively, can you use an assertion on the HTTP status code, e.g.
assert_equal(200, Tokenwrapper.getToken.code)
I am writing a Sinatra-based API, and want to protect certain endpoints with an API key, validating the key before the route is processed.
I understand why throwing an error in the before block doesn't work, because the begin/rescue statements haven't been called yet, however I want a JSON response to be sent back to the client with the error message as a JSON object.
How would I do this?
namespace '/v1/sponser/:key' do
before do
if APIHelper.valid_key?(params[:key]) == false
throw 'Error, invalid API key'
# is it possible to return a JSON response from the before statement here?
end
end
get '/test' do
begin
json status: 200, body: 'just a test'
rescue => error
json status: 404, error: error
end
end
end
I would consider using halt:
before do
unless APIHelper.valid_key?(params[:key])
halt 404, { 'Content-Type' => 'application/json' },
{ error: 'Error, invalid API key' }.to_json
end
end
get '/test' do
json status: 200, body: 'just a test'
end
You can use halt method to return response with specific code, body and headers. So it looks like this:
before do
halt 401, {'Content-Type' => 'application/json'}, '{"Message": "..."}'
end
It looks sloppy so you can just redirect to another url, that provide some service
What is wrong with the following request?
request = Typhoeus::Request.new("http://fluidsurveys.com/api/v2/groups",
method: :get,
userpwd: "test_user:test_password",
headers: { 'ContentType' => "application/json"})
response = request.body
puts response
This returns undefined method body for #<Typhoeus::Request:0x007f8e50d3b1d0> (NoMethodError)
The following request works fine with httparty:
call= "/api/v2/groups/"
auth = {:username => "test_user", :password => "test_password"}
url = HTTParty.get("http://fluidsurveys.com/api/v2/groups",
:basic_auth => auth,
:headers => { 'ContentType' => 'application/json' } )
response = url.body
puts response
EDIT:
I tried this:
response = request.response
puts response.body
with no luck. I receive this : undefined method body for nil:NilClass (NoMethodError)
From https://github.com/typhoeus/typhoeus
You need to do the get before the response body is available.
EDIT: Here is an operable solution. It doesn't use your website, which I couldn't access even manually. But, this returns response code 200 and the response_body. Running this in my debugger showed the complete response, which you could see using "puts response.inspect".
class TyphoeusTry
require 'typhoeus'
request = Typhoeus::Request.new("http://www.google.com",
method: :get,
userpwd: "test_user:test_password",
headers: { ContentType: "application/json"})
response = request.run
puts response.response_body
end
The problem is that you didn't actually execute your request. The following code should work.
request = Typhoeus::Request.new("http://fluidsurveys.com/api/v2/groups",
method: :get,
userpwd: "test_user:test_password",
headers: { 'ContentType' => "application/json"})
request.run
response = request.response
response_code = response.code
response_body = response.body
I have the following Method:
http_client=Net::HTTP.new(#uri.host,#uri.port)
request=Net::HTTP::Post.new(#uri.request_uri)
request.set_form_data(params)
request.basic_auth(#user,#pass)
result = http_client.request(request)
#
# !!! .content_type does not exist !!!
#
result=case result.content_type
when "application/json" JSON.parse(result,{:symbolize_names => true})
when "application/xml" XMLHELPER.parse(result)
end
result
So how to determine the content-type that was sent by the server?
You're getting a NoMethodError from calling result.content_type because you've assigned result to the response body, which is a string.
[...]
response = client.request(request)
result = case response.content_type
when "application/json" JSON.parse(response.body, {:symbolize_names => true})
when "application/xml" XMLHELPER.parse(response.body)
end