Test the JSON response using rspec rails - ruby-on-rails

I get all the responses from JSON in rails(API). How should I test the responses from JSON using rspec gem(CRUD operations)

Couple of ways.
You could validated it as a string.
You could parse JSON.parse(response) the response string, validate specific elements of the response.
Are something I can recommend.

Related

How to get POST request from API with rails

I got POST request from API. I checked content-type, it's x-www-form-urlencoded, but body request also contains JSON. How can I parse from JSON in hash?
Parameters of request in console: Screenshot || Parameters: {"vpbx_api_key"=>"etxojfklr6nue6tl627pn5sdi0koov7t", "sign"=>"ad0c49034c8d83a7d7f1b433afc2ed5a9aa08d933dba3724062aed0c3d1a79bb", "json"=>"{\"entry_id\":\"MjYyNjQ2NzM1Njo0Mg==\",\"call_id\":\"MToxMDAxNDAzOTo0Mjo4Mjc2NzEzMzk=\",\"timestamp\":1485939839,\"seq\":2,\"call_state\":\"Disconnected\",\"location\":\"abonent\",\"from\":{\"number\":\"79268220697\",\"taken_from_call_id\":\"MToxMDAxNDAzOTo0Mjo4Mjc2NzEwOTA6MQ==\"},\"to\":{\"extension\":\"2\",\"number\":\"79154612023\",\"line_number\":\"74953749768\"},\"disconnect_reason\":1100}"}
If you want to keep the form encoded that way, you will have the parameters in the params collection. That means you could be parsing that JSON doing something as:
def my_method_to_process_the_post
parsed = JSON.parse params[:json]
end
'json' is the key for the json that you are receiving in the payload.
For historical evolution of JSON parsing you may want to check this thread.

Interpolation with httparty request in rails

I want to make a http request (using httparty gem) to facebook graph to check if a token which comes form the client is valid or not, but I suppose that interpolation doesn't work with httparty
response = HTTParty.get("https://graph.facebook.com/me?access_token=#{params[:access_token]}")
render json: response
but this gives me the response
{"error":{"message":"Bad signature","type":"OAuthException","code":1}}
Am I missing something?
I suppose that interpolation doesn't work with httparty
Interpolation is a Ruby syntax feature; your string gets interpolated before it's ever passed to HTTParty.
You could have debugged this by inspecting the URL:
uri = "https://graph.facebook.com/me?access_token=#{params[:access_token]}"
Rails.logger.info(uri)
response = HTTParty.get(uri)
Regardless, when using query parameters with HTTParty, you shouldn't use interpolation anyway. You should pass them with the :query option, which will ensure that the parameters are encoded correctly:
response = HTTParty.get( "https://graph.facebook.com/me",
query: { access_token: params[:access_token] })
However, I'm not certain this will actually fix your problem. There's a good chance the problem is really somewhere else in your OAuth flow--there's a lot of room for error when working with OAuth.

How to indicate empty array in HTTP request query params?

This is the way Rails accepts arrays in query parameters:
PUT /resource.json?sport_ids[]=133&sport_ids[]=64&sport_ids[]=71 ...
I tried to google this question but didn't find any explicit docs on it:
How to tell Rails that we want sport_ids to become empty (pass empty array of sport_ids via query parameters) ?
HTTP requests can have only variables on the url itself. That's a limitation feature of HTTP, not Rails.
Take a look at How Does Rack Parse Query Params? With Parse_nested_query to figure out how rails collects the variables into an array, it won't run out of the box in case of an empty array.
You can avoiding sending the params["sport_ids"] and patch your controller with:
params["sport_ids"] ||= []
The best practice to use put/post requests, is passing such data in the request body (json/xml) like:
{
"sport_ids": []
}
Or with data as:
//...
{
"sport_ids": [133, 64, 71]
}
//...
For more info about HTTP request steps, check Running a HTTP request with rails.
While #mohameddiaa27's answer has good advice on how to achieve that by passing such data in the request body as JSON I found that I cannot rely on it within my application: I found that it is not easy to combine such passing of JSON into request body within multipart forms where I want to pass user record (with user[sport_ids] in it) and user's avatar image (user[avatar]) field.
So I continued to investigate how to achieve that using default "query parameters in a request body of POST/PUT request" approach and found the reason why I was not able to reset my sport_ids on server-side: it was the lack of permission for that specific sport_ids field. Now I have the following permits (pseudocode):
current_user.update!(user_params)
where user_params is
user_attributes_to_permit = [
...
:sport_ids, # this is what was needed for just `user[sport_ids]` to work.
{ :sport_ids => [] } # this is needed for sport_ids non-empty arrays to work
...
]
params.require(:user).permit(user_attributes_to_permit)
so now I am able to reset the sport_ids array of my user by passing just user[sport_ids] (without '=' and value! i.e. ...&user[sport_ids]&...) within my query parameters.

How do you use paths in "json_spec" gem if you have no arrays?

I'm using the "json_spec" gem in a Rails app and I'm trying to create some Cucumber steps to document/test my API code.
I have the following scenario:
Scenario: Create new authorization
Given an existing user and merchant
When I post to "/api/v1/authorizations.json" with:
"""
{"email":"user#email.com", "code": "43434", "merchant_account_id":1, "amount": 45.00}
"""
And I keep the JSON response at "authorization/id" as "AUTH_ID"
Then the JSON response should be:
"""
{"authorization":{"id":1,"email":"user#email.com","amount":45.0}}
"""
I expected "authorization/id" to give me the value of the "id" key in the "authorizations" hash. All the examples in the json_spec documentation contain arrays, but in this case the response only involves one entity--it would not make sense to have an array in the JSON. Is there a way to use paths when there is no array present?
Sure, and the syntax you used is correct. The scenarios in the documentation examples work with a response to a post, and then a check whether that post is part of the collection - hence the array. But if you were to check e.g., that your post now is the last post (for which you retrieve just one value) you'd use the hash syntax:
Scenario: Create new authorization
Given an existing user and merchant
And I post to "/api/v1/authorizations.json" with:
"""
{"email":"user#email.com", "code": "43434", "merchant_account_id":1, "amount": 45.00}
"""
And I keep the JSON response at "authorization/id" as "AUTH_ID"
When I get from "/api/v1/authorizations/last.json"
Then the JSON response at "authorization/id" should be %{AUTH_ID}

Parsing JSON feed with Ruby on Rails

I know this has been covered over and over but I just can't understand how to get started. Am too much of a JSON virgin to know what's going on.
I'm trying to get some data from a json feed on a remote server into a rails3 application.
I understand I need the json gem but I have no idea how to pull the data.
If the url is something like this:
http://my-feed.com/json?res=service&s=table&table=User&start=0&max=5&sort=id&desc=true
How do I go about getting that from my application?
Any help, walk-throughs, tutorials appreciated
You are going to need to make an HTTP request for the resource, grab the response, and (potentially) parse it yourself - although I think HTTParty will do the JSON parsing for you. HTTParty would be my suggestion for making requests, though.
If you read the README, it links to examples of how to use HTTParty which you should find helpful. The basic example includes how to make a get request, inspect the headers and body, etc. I believe you can also use response.parsed_response to get the parsed response of whatever HTTParty's default parser is. There is also an example of using your own custom parsers (if you prefer another to HTTParty's).
I don't really know the json gem - does it only handle the parsing?
If yes, and you only need to pull in the information, try this:
require 'open-uri'
begin
json = open 'http://my-feed.com/json?res=service&s=table&table=User&start=0&max=5&sort=id&desc=true'
rescue
# a multitude of HTTP-related errors can occur
end
json_string = json.read
# parse

Resources