Sinatra fails to answer to a very basic GET request - ruby

I have the following Gemfile:
source "http://rubygems.org"
gem 'sinatra', '1.3.2'
gem 'json', '1.6.4'
And the following Sinatra application:
require 'sinatra'
require 'json'
get '/ze/api/session.json' do
content_type :json
{ :name => 'name' }
end
And when I make a basic request like this one:
curl localhost:4567/ze/api/session.json
I get this:
[2012-01-13 17:30:36] ERROR TypeError: can't convert Array into String
/Users/mauricio/.rvm/gems/ruby-1.9.2-p290#office-drop-sync/gems/rack-1.4.0/lib/rack/handler/webrick.rb:72:in `block in service'
/Users/mauricio/.rvm/gems/ruby-1.9.2-p290#office-drop-sync/gems/rack-1.4.0/lib/rack/handler/webrick.rb:71:in `each'
/Users/mauricio/.rvm/gems/ruby-1.9.2-p290#office-drop-sync/gems/rack-1.4.0/lib/rack/handler/webrick.rb:71:in `service'
/Users/mauricio/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/httpserver.rb:111:in `service'
/Users/mauricio/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/httpserver.rb:70:in `run'
/Users/mauricio/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'
localhost - - [13/Jan/2012:17:30:36 BRT] "GET /ze/api/session.json HTTP/1.1" 500 311
I am using Ruby 1.9.2 with RVM in a Lion Mac.

You're trying to return a hash from the route, but a hash isn't something you can return here.
Simply use .to_json to turn the hash into a json string which you can then return (you've required json, but aren't using it yet):
get '/ze/api/session.json' do
content_type :json
{ :name => 'name' }.to_json
end

Related

How to simulate a POST request in Ruby with the webmock gem?

I am trying to simulate a POST request with rspec. I thought about using the webmock gem, after searching how it worked, my code looks like this:
Gist_Request_spec.rb:
require_relative '../Gist_Request.rb'
require 'spec_helper'
require 'webmock'
include WebMock::API
WebMock.enable!
RSpec.describe GistRequest do
describe "#post" do
it "crear gist" do
stub_request(:post, "https://api.github.com/gists").
with(
body: {"description" => "description","public" => true,"files" => { "file.txt" => { "content" => "content" }}},
headers: {
'Accept'=>'*/*',
'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
'Authorization'=>'Basic Sm9lbEFsYXlvbjEyMzo0NzVmYjI1ZWU0MGQyNGQzZGM1NWQ0MzQ5YjI4MTU3MjM1ZjdmZDBk',
'Host'=>'api.github.com',
'User-Agent'=>'Ruby'}).to_return(status: 201, body: "", headers: {})
expect(WebMock).to have_requested(:post, "https://api.github.com/gists").with { |req| req.status == 201 }
end
end
end
I added code to my file spec_helper.rb and now it looks like this:
The first lines spec_helper.rb:
require 'webmock/rspec'
WebMock.disable_net_connect!(allow_localhost: true)
But when I run rspec spec/Gist_Request_spec.rb, it returns the following error:
GistRequest
#post
crear gist (FAILED - 1)
Failures:
1) GistRequest#post crear gist
Failure/Error: expect(WebMock).to have_requested(:post, "https://api.github.com/gists").with { |req| req.status == 201 }
The request POST https://api.github.com/gists with given block was expected to execute 1 time but it executed 0 times
The following requests were made:
No requests were made.
============================================================
# ./spec/Gist_Request_spec.rb:21:in `block (3 levels) in <top (required)>'

Faraday::Error: :hashie is not registered on Faraday::Middleware

I am creating a wrapper gem for a RESTful API. I am getting following error when I try to add hashie middleware as per the documentation:
Magpress::Login::#call#test_0001_should return valid JWT token:
Faraday::Error: :hashie is not registered on Faraday::Middleware
/home/amit/.rvm/gems/ruby-2.2.2#magpress/gems/faraday-0.10.0/lib/faraday.rb:184:in `lookup_middleware'
/home/amit/.rvm/gems/ruby-2.2.2#magpress/gems/faraday-0.10.0/lib/faraday/rack_builder.rb:204:in `use_symbol'
/home/amit/.rvm/gems/ruby-2.2.2#magpress/gems/faraday-0.10.0/lib/faraday/rack_builder.rb:84:in `use'
/home/amit/projects/bt/magpress/lib/magpress/client.rb:24:in `block in connection'
/home/amit/.rvm/gems/ruby-2.2.2#magpress/gems/faraday-0.10.0/lib/faraday/connection.rb:91:in `initialize'
/home/amit/.rvm/gems/ruby-2.2.2#magpress/gems/faraday-0.10.0/lib/faraday.rb:70:in `new'
/home/amit/.rvm/gems/ruby-2.2.2#magpress/gems/faraday-0.10.0/lib/faraday.rb:70:in `new'
/home/amit/projects/bt/magpress/lib/magpress/client.rb:18:in `connection'
/home/amit/projects/bt/magpress/lib/magpress/base.rb:7:in `initialize'
/home/amit/projects/bt/magpress/test/login_spec.rb:13:in `new'
/home/amit/projects/bt/magpress/test/login_spec.rb:13:in `block (3 levels) in <top (required)>'
Here is how I delcared dependencies in .gemspec.
...
spec.add_dependency "faraday"
spec.add_dependency "faraday_middleware"
spec.add_dependency "hashie"
....
and the class that uses faraday and it's middleware
require 'faraday'
require 'faraday_middleware'
require 'hashie'
module Magpress
class Client
def connection(url)
conn = ::Faraday.new(url) do |faraday|
faraday.request :json
faraday.response :json, :content_type => /\bjson$/
# faraday.use :instrumentation
faraday.use :hashie # FaradayMiddleware::Mashify
faraday.adapter Faraday.default_adapter
end
conn
end
end
end
farady and middlware gem versions
amit#amit:~/projects/bt/magpress$ gem list | grep faraday
faraday (0.10.0)
faraday_middleware (0.10.1)
What could be wrong here?
If I replace :hashie with FaradayMiddleware::Mashify, the errors goes away but the response.body returns instance of vanilla Hash instead of
Hashie::Mash
Voila! It is fixed.
Current
faraday.response :json, :content_type !=> /\bjson$/
faraday.use :hashie # FaradayMiddleware::Mashify
After Fix
faraday.response :mashify
faraday.response :json, :content_type => /\bjson$/
I could fix by reading the code!

Ruby: How to access an api using HTTParty

I'm new to Ruby, and to using HTTParty, and was trying to follow the HTTParty examples from their github page to execute a basic POST. When I run the code below I get an error:
require 'pp'
require 'HTTParty'
require 'pry'
class Partay
include HTTParty
base_uri "http://<myapidomain>/search/semanticsearch/query/"
end
options= {
query: {
version: "0.4",
query: "lawyer"
}}
response = Partay.post(options)
puts response
The error I get is:
rbenv/versions/2.2.0/lib/ruby/2.2.0/uri/common.rb:715:in `URI': bad argument (expected URI object or URI string) (ArgumentError)
from ~/.ruby/2.2.0/gems/httparty-0.13.3/lib/httparty/request.rb:47:in `path='
from ~/.ruby/2.2.0/gems/httparty-0.13.3/lib/httparty/request.rb:34:in `initialize'
from ~/.ruby/2.2.0/gems/httparty-0.13.3/lib/HTTParty.rb:539:in `new'
from ~/.ruby/2.2.0/gems/httparty-0.13.3/lib/HTTParty.rb:539:in `perform_request'
from ~/.ruby/2.2.0/gems/httparty-0.13.3/lib/HTTParty.rb:491:in `post'
from json-to-csv.rb:16:in `<main>'
What I am looking for is calling a post that receives JSON in the same way that calling this URL works:
http://somedomain.com/search/semanticsearch/query/?version=0.4&query=lawyer
Noting a solution with the suggested gem - unirest:
require 'unirest'
url = "http://somedomain.com/search/semanticsearch/query"
response = Unirest.post url,
headers:{ "Accept" => "application/json" },
parameters:{ :version => 0.4, :query => "lawyer" }

Obtaining a render Argument Error: What is the correct syntax or usage?

I am new to Ruby, Sinatra and Pusher so this is a basic question. I am attempting to authenticate a Pusher Client (using iOS demo code https://github.com/lukeredpath/libPusher). The server code below fails with error when the iOS client attempts to join a presence channel:
ArgumentError - wrong number of arguments (1 for 2):
/Users/waveocean/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:665:in `render'
web.rb:13:in `auth'
web.rb:26:in `block in <main>'
/Users/waveocean/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:1265:in `call'
... snipped for brevity ...
Here is the code:
require 'sinatra'
require 'pusher'
require 'thin'
Thin::HTTP_STATUS_CODES[403] = "FORBIDDEN"
Pusher.app_id = 'MY-APP-ID'
Pusher.key = 'MY-KEY'
Pusher.secret = 'MY-SECRET'
def auth
response = Pusher[params[:channel_name]].authenticate(params[:socket_id], {:user_id => 101})
render :json => response
end
use Rack::Auth::Basic, "Protected Area" do |username, password|
username == 'foo' && password == 'bar'
end
post '/presence/auth' do
if params[:channel_name] == 'presence-demo'
auth
else
# render :text => "Forbidden", :status => '403'
response.status = 403
end
end
Can someone provide a suggestion or correct usage of render?
Here's is what I discovered. render is associated with Rails, and not strictly Ruby. To respond to the Sinatra route, use the following in the auth method:
def auth
response = Pusher[params[:channel_name]].authenticate(params[:socket_id], {:user_id => 101})
[200, {"Content-Type" => "application/json"}, response.to_json]
end
As it turns out, the Pusher iOS project demo provides a Scripts/auth_server.rb file with the required implementation. It is documented with the installation instructions here: https://github.com/lukeredpath/libPusher/wiki/Adding-libPusher-to-your-project .

Can't use facebook to authenticate: undefined method 'web_server' for OAuth2?

Trying to let users sign in / sign up with Twitter and Facebook. Twitter works no problem but the strategy is different for Facebook.
undefined method `web_server' for #<OAuth2::Client:0x00000005211d58>
Trace shows
oa-oauth (0.0.1) lib/omniauth/strategies/oauth2.rb:18:in `request_phase'
oa-oauth (0.0.1) lib/omniauth/strategies/facebook.rb:28:in `request_phase'
oa-core (0.0.5) lib/omniauth/strategy.rb:25:in `call!'
oa-core (0.0.5) lib/omniauth/strategy.rb:19:in `call'
oa-core (0.0.5) lib/omniauth/builder.rb:22:in `call'
warden (1.0.5) lib/warden/manager.rb:35:in `block in call'
warden (1.0.5) lib/warden/manager.rb:34:in `catch'
warden (1.0.5) lib/warden/manager.rb:34:in `call'
Anybody else experienced this?
ps. I'm using the following gems:
gem 'oa-oauth', :require => 'omniauth/oauth'
gem 'oauth2'
I'm not using the full omniauth gem as its addressable dependencies conflict with other gems.
I ran into the same problem when trying to use facebook_oauth (https://github.com/moomerman/facebook_oauth) on my rails app. After spending an hour or so trying to change its code, i realized it might be easier just to use oauth2 directly. I solved the problem and now there's no need for that intermediate library. Here's how:
In Gemfile add
gem 'oauth2'
Then run
bundle update
Then, in your login_via_facebook method you either construct the dialog uri manually or use the oauth client something along these lines:
oauth_client = OAuth2::Client.new(APPLICATION_ID, APPLICATION_SECRET, {
:authorize_url => 'https://www.facebook.com/dialog/oauth'
})
redirect_to oauth_client.authorize_url({
:client_id => APPLICATION_ID,
:redirect_uri => YOUR_REDIRECT_URL
})
If you need to request additional permissions, specify scope param in the authorize_url call:
redirect_to oauth_client.authorize_url({
:client_id => APPLICATION_ID,
:redirect_uri => YOUR_REDIRECT_URL,
:scope => 'offline_access,email'
})
Then, in the method that handles YOUR_REDIRECT_URL (i call mine login_via_facebook_callback), do something like this:
oauth_client = OAuth2::Client.new(APPLICATION_ID, APPLICATION_SECRET, {
:site => 'https://graph.facebook.com',
:token_url => '/oauth/access_token'
})
begin
access_token = oauth_client.get_token({
:client_id => APPLICATION_ID,
:client_secret => APPLICATION_SECRET,
:redirect_uri => YOUR_REDIRECT_URL,
:code => params[:code],
:parse => :query
})
access_token.options[:mode] = :query
access_token.options[:param_name] = :access_token
facebook_user_info = access_token.get('/me', {:parse => :json}).parsed
rescue Error => e
# You will need this error during development to make progress :)
#logger.error(e)
end
Now facebook_user_info has the basic user info!
I had a similar issue, you should try two things:
I also had conflicting gem issues/dependencies issues and resolved them by adding this in my gemfile:
gem 'omniauth', :git => 'git://github.com/intridea/omniauth.git'
Try using a rails application template which works remarkably well for starting a Twitter/Facebook app in no time, run this command in your terminal:
rails new APP_NAME -m https://github.com/RailsApps/rails3-application-templates/raw/master/rails3-mongoid-omniauth-template.rb -T
You can read more about it here:
https://github.com/RailsApps/rails3-mongoid-omniauth/wiki/Tutorial
here i came across an example app that demonstrates the use of omniauth along with authlogic
https://github.com/madhums/omniauth-authlogic-demo
hope it helps

Resources