heroku / heroku.rb

DEPRECATED! Official Heroku Ruby Legacy API wrapper
161 stars 41 forks source link

mock: true, works in console but failing in the Test environment #75

Open abibullah opened 10 years ago

abibullah commented 10 years ago

When I use the following command on the console, it creates the Heroku::Api object

heroku = Heroku::API.new username: ENV['HEROKU_USER'], password: ENV['HEROKU_PASSWORD'], mock: !Rails.env.prod?

But this same command fails in the rspec tests and it generates

Heroku::API::Errors::NotFound: Expected(200) <=> Actual(404 Not Found)

When I investigated further I found that

In console, the excon connection object that getting generated in development(console) is different from the test environment

In console:

#<Excon::Connection:7f9a71607530 @data={:chunk_size=>1048576, :connect_timeout=>60, :debug_request=>false, 
:debug_response=>false, :headers=>{"Accept"=>"application/json", "Accept-Encoding"=>"gzip", "User-Agent"=>"heroku-rb/0.3.15", "X-Ruby-Version"=>"2.0.0", "X-Ruby-Platform"=>"x86_64-darwin11.4.2"}, :idempotent=>false, 
:instrumentor_name=>"excon", :middlewares=>[Excon::Middleware::ResponseParser, Excon::Middleware::Expects, 
Excon::Middleware::Idempotent, Excon::Middleware::Instrumentor, Excon::Middleware::Mock], :mock=>true, 
:nonblock=>false, :omit_default_port=>false, :read_timeout=>60, :retry_limit=>4, :ssl_verify_peer=>true, 
:tcp_nodelay=>false, :uri_parser=>URI, :write_timeout=>60, :host=>"api.heroku.com", :path=>"", :port=>"443", 
:query=>nil, :scheme=>"https", :user=>nil, :password=>nil} @socket_key="https://api.heroku.com:443">

In Tests

#<Excon::Connection:7ff5dd0c3ac0 @data={:chunk_size=>1048576, :connect_timeout=>60, :debug_request=>false, 
:debug_response=>false, :headers=>{"Accept"=>"application/json", "Accept-Encoding"=>"gzip", "User-Agent"=>
"heroku-rb/0.3.15", "X-Ruby-Version"=>"2.0.0", "X-Ruby-Platform"=>"x86_64-darwin11.4.2"}, :idempotent=>false, 
:instrumentor_name=>"excon", :middlewares=>[Excon::Middleware::ResponseParser, Excon::Middleware::Expects, 
Excon::Middleware::Idempotent, Excon::Middleware::Instrumentor, Excon::Middleware::Mock], :mock=>true, 
:nonblock=>false, :omit_default_port=>false, :read_timeout=>60, :retry_limit=>4, :ssl_verify_peer=>true, 
:tcp_nodelay=>false, :uri_parser=>URI, :write_timeout=>60, :host=>"api.heroku.com", :path=>"", :port=>"443", 
:query=>nil, :scheme=>"https", :user=>nil, :password=>nil, :__construction_args=>{:host=>"api.heroku.com", 
:path=>"", :port=>"443", :query=>nil, :scheme=>"https", :user=>nil, :password=>nil, :headers=>{"Accept"=>
"application/json", "Accept-Encoding"=>"gzip", "User-Agent"=>"heroku-rb/0.3.15", "X-Ruby-Version"=>"2.0.0", "X-
Ruby-Platform"=>"x86_64-darwin11.4.2"}, :nonblock=>false, :mock=>true}} @socket_key="https://api.heroku.com:443">

I see that the second object has an additional key value :__construction_args

I am not sure weather this key value is creating an issue.

geemus commented 10 years ago

I wouldn't expect the API constructor itself to throw this error in really any situation. Are you sure the constructor is causing the problem, rather than other/subsequent usage of the API object? The error you mention looks more like what you might see when trying to call subsequent operations on the connection. Does that make sense? Happy to discuss further and try to help, I don't think the :__construction_args should cause an issue though.

abibullah commented 10 years ago

Its creating the problem at the constructor itself when I tried to initialize the object with .new method

    def initialize(options={})
      options = OPTIONS.merge(options)

      @api_key = options.delete(:api_key) || ENV['HEROKU_API_KEY']
      if !@api_key && options.has_key?(:username) && options.has_key?(:password)
        username = options.delete(:username)
        password = options.delete(:password)
        @connection = Excon.new("#{options[:scheme]}://#{options[:host]}", options.merge(:headers => HEADERS))
        @api_key = self.post_login(username, password).body["api_key"]
      end
      puts "#{@api_key}" # it never comes here in test mode
      user_pass = ":#{@api_key}"
      options[:headers] = HEADERS.merge({
        'Authorization' => "Basic #{Base64.encode64(user_pass).gsub("\n", '')}",
      }).merge(options[:headers])

      @connection = Excon.new("#{options[:scheme]}://#{options[:host]}", options)
    end

@api_key = self.post_login(username, password).body["api_key"] This snippet is making an call which actually throws the error that I pasted above, but in dev mode it doesn't throw an error, I have updated the snippet with a puts. In test environment the execution breaks before the puts with error

geemus commented 10 years ago

@abibullah - Are you calling Excon.stubs.clear or anything similar to that in tests? The error you are getting seems to indicate the tests might be removing stubs in some way/shape/form. Maybe check the setup/teardown related stuff to see if that could be in there somewhere? Certainly happy to continue discussing/working through this, but that seems a likely culprit to start with.