Why am I getting this 'no implicit conversion of Hash into String' when mocking Stripe with WebMock - ruby

I'm trying to mock Stripe like this:
stub_request(:post, "https://api.stripe.com/v1/tokens").with(
:body => {"card" => {"number" => "4242424242424242", "exp_month"=> "12", "exp_year" => "2018", "cvc" => "123"}}
).
to_return(:status => 200, :headers => {}, :body => {
"id" => "tok_14CgP22eZvKYlo2CkgJ6ymLE",
"livemode" => false,
"created" => 1404517660,
"used" => false,
"object" => "token",
"type" => "card",
"card" => {
"id" => "card_14CgP22eZvKYlo2CcdUNvicW",
"object" => "card",
"last4" => "4242",
"brand" => "Visa",
"funding" => "credit",
"exp_month" => 12,
"exp_year" => 2018,
"fingerprint" => "Xt5EWLLDS7FJjR1c",
"country" => "US"
}
})
I am getting a no implicit conversion of Hash into String error when I call:
token = Stripe::Token.create(:card => {
:number => params["number"],
:exp_month => params["expiry_month"],
:exp_year => params["expiry_year"],
:cvc => params["cvc"]})
It's because of the hash in body in to_return, but I don't know how to avoid the error.
If I add .to_s to the hash, I get:
Invalid response object from API: "{\"id\"=>\"tok_14CgP22eZvKYlo2CkgJ6ymLE\", \"livemode\"=>false, \"created\"=>1404517660, \"used\"=>false, \"object\"=>\"token\", \"type\"=>\"card\", \"card\"=>{\"id\"=>\"card_14CgP22eZvKYlo2CcdUNvicW\", \"object\"=>\"card\", \"last4\"=>\"4242\", \"brand\"=>\"Visa\", \"funding\"=>\"credit\", \"exp_month\"=>12, \"exp_year\"=>2018, \"fingerprint\"=>\"Xt5EWLLDS7FJjR1c\", \"country\"=>\"US\"}}" (HTTP response code was 200)
If I add a .to_json to the end, Stripe::Token passes but I get a stack error too deep error when I try to use the resulting token in any way.
What do you recommend?

It could be that your stubbing is not returning correctly. It may help to make your stubbing a little less specific. For example:
body = {
"id" => "tok_14CgP22eZvKYlo2CkgJ6ymLE",
"livemode" => false
# snip...
}
stub_request(:post, "https://api.stripe.com/v1/tokens")
.to_return(:status => 200, :body => body.to_json)
However, it's difficult to know exactly what errors are being thrown, so I can only give vague ideas which may help. What error does calling token give you?

Related

jira-ruby: issue.save returning false

I am trying to create an issue with jira-ruby in the terminal. So far I have done the following (where username, password, site and project have been replaced with the proper values). I have been able to fetch issues, but not to create them. Jira-ruby return false when i try and save an issue
options = {
:username => "username",
:password => "password",
:site => 'site',
:context_path => '',
:auth_type => :basic
}
client = JIRA::Client.new(options)
issue = client.Issue.build
issue.save({
"fields" => {
"summary" => "blarg from in example.rb",
"project" => {"key" => "mykey"},
"issuetype" => {"id" => "1"}
}
})
=> false
issue.attrs
=> {"errorMessages"=>[], "errors"=>{"issuetype"=>"issue type is required"}, "summary"=>"blarg from in example.rb", "key"=>"somekey", "id"=>"someid", "self"=>"site", "exception"=>{"class"=>"Net::HTTPBadRequest", "code"=>"400", "message"=>"Bad Request"}}
What is the problem?

Savon: Wrong Element Name Prefix. How can I change it?

So here is the code that I have:
resp = client.call(
:producer_query,
message: {
'cmn:Carrier' => '',
'cmn:ProducerCriteria' => { 'cmn:EntityType' => 'Individual',
'cmn:CustomerId' => 5555,
:attributes! => {'CustomerId' => {'type' => 'AGENTCD'}}},
'cmn:SectionConfiguration' => { 'cmn:SectionType' => 'Associations', :attributes! => {'cmn:SectionType' => {'activeOnly' => 'false'}}},
:attributes! => { 'cmn:Carrier' => { "id" => 55555 }}
}
) do
wsse_auth ENV['ID'], ENV['PASSWORD'], :digest
end
And it produces something that looks like:
<soapenv:Body>
<cmn:ProducerQuery>
<cmn:Carrier id="5555"/>
<cmn:ProducerCriteria>
<cmn:EntityType>Individual</cmn:EntityType>
<cmn:CustomerId>55555</cmn:CustomerId>
</cmn:ProducerCriteria>
<cmn:SectionConfiguration>
<cmn:SectionType activeOnly="false">Associations</cmn:SectionType>
</cmn:SectionConfiguration>
</cmn:ProducerQuery>
</soapenv:Body>
I've added in the 'cmn' to everything, but the ProducerQuery to make it match what I think it should be. However, I think it really should read 'tran' instead. I can control the 'cmn' for everything but the part that reads <cmn:ProducerQuery>. How can I make it read <cmn:ProducerQuery>?

Upload Captions YouTube Data API ruby

I am trying to upload captions to YouTube using the Data API. However I can't find in the reference or in the forum any example in Ruby. In specific how to send the actual caption file (xml).
body = {
:snippet => {
:videoId => videoId,
:language => "English",
:name => "English"
}
}
captions_insert_response = client.execute(
:api_method => youtube.captions.insert,
:parameters => {
:part => body.keys.join(',')
},
:body_object => body
)
where and how do I add the caption file? I tried doing it like uploading a video, but it didn't seem to work. This line was added after ":body_object"
:media => Google::APIClient::UploadIO.new(captions_file, 'text/xml')
Thanks
I solved the issue changing the language in the snippet to "en".
This is the complete request if someone needs it.
body = {
:snippet => {
:videoId => videoId,
:language => "en",
:name => "English"
}
}
captions_insert_response = client.execute(
:api_method => youtube.captions.insert,
:body_object => body,
:media => Google::APIClient::UploadIO.new(captions_file, 'text/xml'),
:parameters => {
'uploadType' => 'multipart',
:part => body.keys.join(',')
}
)

How can I implement this POST request using HTTParty?

I am having difficulty making a POST request to an API endpoint using Ruby's HTTParty library. The API I'm interacting with is the Gittip API and their endpoint requires authentication. I have been able to successfully make an authenticated GET request using HTTParty.
You can see in the example code:
user = "gratitude_test"
api_key = "5962b93a-5bf7-4cb6-ae6f-aa4114c5e4f2"
# I have included real credentials since the above is merely a test account.
HTTParty.get("https://www.gittip.com/#{user}/tips.json",
{ :basic_auth => { :username => api_key } })
That request works and returns the following as expected:
[
{
"amount" => "1.00",
"platform" => "gittip",
"username" => "whit537"
},
{
"amount" => "0.25",
"platform" => "gittip",
"username" => "JohnKellyFerguson"
}
]
However, I have been unable to make a successful POST request using HTTParty. The Gittip API describes making a POST request using curl as follows:
curl https://www.gittip.com/foobar/tips.json \
-u API_KEY: \
-X POST \
-d'[{"username":"bazbuz", "platform":"gittip", "amount": "1.00"}]' \
-H"Content-Type: application/json"
I have tried (unsuccessfully) structuring my code using HTTParty as follows:
user = "gratitude_test"
api_key = "5962b93a-5bf7-4cb6-ae6f-aa4114c5e4f2"
HTTParty.post("https://www.gittip.com/#{user}/tips.json",
{
:body => [ { "amount" => "0.25", "platform" => "gittip", "username" => "whit537" } ],
:basic_auth => { :username => api_key },
:headers => { 'Content-Type' => 'application/json' }
})
The first argument is the url and the second argument is an options hash. When I run the code above, I get the following error:
NoMethodError: undefined method `bytesize' for [{"amount"=>"0.25", "platform"=>"gittip", "username"=>"whit537"}]:Array
from /Users/John/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http/generic_request.rb:179:in `send_request_with_body'
I have tried various other combinations of structuring the API call, but can't figure out how to get it to work. Here's another such example, where I do not user an array as part of the body and convert the contents to_json.
user = "gratitude_test"
api_key = "5962b93a-5bf7-4cb6-ae6f-aa4114c5e4f2"
HTTParty.post("https://www.gittip.com/#{user}/tips.json",
{
:body => { "amount" => "0.25", "platform" => "gittip", "username" => "whit537" }.to_json,
:basic_auth => { :username => api_key },
:headers => { 'Content-Type' => 'application/json' }
})
Which returns the following (a 500 error):
<html>
<head>
<title>500 Internal Server Error</title>
</head>
<body>\n Internal server error, program!\n <pre></pre>
</body>
</html>
I'm not really familiar with curl, so I'm not sure if I am incorrectly translating things to HTTParty.
Any help would be appreciated. Thanks.
Just a guess, but it looks like you're passing a hash in the body when JSON is expected.
Try replacing the :body declaration with:
:body => [{ "amount" => "0.25",
"platform" => "gittip",
"username" => "whit537" }].to_json
Edit:
I suggested the to_json serializer, but misplaced it by putting it after the hash instead of the array and removing the array altogether. The example uses multiple records, so the array is necessary.
After looking at this thread, it looks like Gittip is picky about the accept header.
:headers => { 'Content-Type' => 'application/json', 'Accept' => 'application/json'}
So, the full suggestion is:
HTTParty.post("https://www.gittip.com/#{user}/tips.json",
{
:body => [ { "amount" => "0.25", "platform" => "gittip", "username" => "whit537" } ].to_json,
:basic_auth => { :username => api_key },
:headers => { 'Content-Type' => 'application/json', 'Accept' => 'application/json'}
})

Google Calendar Ruby API

I'm working on an app that needs to update a google calendar.
By following the Google Calendar Developer Guide at:
http://code.google.com/apis/calendar/v3/using.html#creating_events
event = {
'summary' => 'Appointment',
'location' => 'Somewhere',
'start' => {
'dateTime' => '2011-06-03T10:00:00.000-07:00'
},
'end' => {
'dateTime' => '2011-06-03T10:25:00.000-07:00'
}
}
result = client.execute(:api_method => service.events.insert,
:parameters => {'calendarId' => 'primary'},
:body => JSON.dump(event),
:headers => {'Content-Type' => 'application/json'})
I get the following error:
TypeError (Expected body to respond to :each.):
I have tried to do event.to_json as well.
Just a couple of suggestions from the top of my head which may help. Please try them and inform us if these help.
Wrap :body into array:
result = client.execute(:api_method => service.events.insert,
:parameters => {'calendarId' => 'primary'},
:body => [JSON.dump(event)],
:headers => {'Content-Type' => 'application/json'})
Or use:body_object instead of body, and don't jsonify the event hash:
result = client.execute(:api_method => service.events.insert,
:parameters => {'calendarId' => 'primary'},
:body_object => event,
:headers => {'Content-Type' => 'application/json'})
Take a look at http://code.google.com/p/google-api-ruby-client/source/browse/lib/google/api_client/reference.rb, and you'll understand how I came up with these suggestions.

Resources