Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VCR says "no cassette in use" even after specifying cassette

I have an api-only RoR app with a user model. Users are authenticated via Twilio/Authy (using this gem). Each user has_one authy_user model for storing authy info, with dependent: :destroy.

The authy_user model has a before_destroy hook that connects to the authy api via the authy gem and deletes the user there.

The authy_user specs run just fine, and I've recorded cassettes for both registering and deleting users with the authy api.

A piece of the authy_user spec:

describe "delete user" do
 before do
  @user = create(:user_with_authy_user)
 end

 context "user is registered" do
  it "deletes user in authy and locally" do
    VCR.use_cassette("authy_delete_user") do
      expect {
        @user.authy_user.destroy
      }.to change { AuthyUser.count }.by(-1)
     end
   end
 end
end

(this fails with the same error as below if i change it from @user.authy_user.destroy to @user.destroy)

My problem is the user request spec, specifically the one that deletes the user.

Here's the spec that fails:

describe "DELETE /user" do
  context "user exists" do
    before do
      @user = create(:user_with_authy_user)
      @token = JWTService.issue_access_token user: @user, provider: "authy"
    end

    it "deletes the user" do
      expect {
        VCR.use_cassette("authy_delete_user") do
          delete(user_path, headers: { "X-Auth-Token": @token })
        end
      }.to change { User.count }.by(-1)
      expect(status).to eq(204)
      expect(body).to be_blank
    end
  end
end

Here's the failure:

  1) Users DELETE /user user exists deletes the user
 Failure/Error: Authy::API.delete_user id: authy_id

 VCR::Errors::UnhandledHTTPRequestError:


   ================================================================================
   An HTTP request has been made that VCR does not know how to handle:
     POST https://api.authy.com/protected/json/users/delete/92962960

   There is currently no cassette in use. There are a few ways
   you can configure VCR to handle this request:

     * If you're surprised VCR is raising this error
       and want insight about how VCR attempted to handle the request,
       you can use the debug_logger configuration option to log more details [1].
     * If you want VCR to record this request and play it back during future test
       runs, you should wrap your test (or this portion of your test) in a
       `VCR.use_cassette` block [2].
     * If you only want VCR to handle requests made while a cassette is in use,
       configure `allow_http_connections_when_no_cassette = true`. VCR will
       ignore this request since it is made when there is no cassette [3].
     * If you want VCR to ignore this request (and others like it), you can
       set an `ignore_request` callback [4].

   [1] https://www.relishapp.com/vcr/vcr/v/4-0-0/docs/configuration/debug-logging
   [2] https://www.relishapp.com/vcr/vcr/v/4-0-0/docs/getting-started
   [3] https://www.relishapp.com/vcr/vcr/v/4-0-0/docs/configuration/allow-http-connections-when-no-cassette
   [4] https://www.relishapp.com/vcr/vcr/v/4-0-0/docs/configuration/ignore-request
   ================================================================================
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr/request_handler.rb:97:in `on_unhandled_request'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr/library_hooks/webmock.rb:129:in `on_unhandled_request'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr/request_handler.rb:24:in `handle'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr/library_hooks/webmock.rb:144:in `block in <module:WebMock>'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:28:in `block in register_global_stub'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/request_pattern.rb:40:in `matches?'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:58:in `block in request_stub_for'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:57:in `each'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:57:in `detect'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:57:in `request_stub_for'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:50:in `response_for_request'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/http_lib_adapters/httpclient_adapter.rb:187:in `block in webmock_responses'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/http_lib_adapters/httpclient_adapter.rb:59:in `do_get'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/http_lib_adapters/httpclient_adapter.rb:47:in `do_get_block'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/httpclient-2.8.3/lib/httpclient.rb:1019:in `block in do_request'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/httpclient-2.8.3/lib/httpclient.rb:1133:in `protect_keep_alive_disconnected'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/httpclient-2.8.3/lib/httpclient.rb:1014:in `do_request'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/httpclient-2.8.3/lib/httpclient.rb:856:in `request'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/httpclient-2.8.3/lib/httpclient.rb:765:in `post'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/authy-2.7.4/lib/authy/api.rb:119:in `post_request'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/authy-2.7.4/lib/authy/api.rb:100:in `delete_user'
 # ./app/services/authy_service.rb:20:in `delete'
 # ./app/models/authy_user.rb:74:in `remove_from_authy'
 # ./app/controllers/users_controller.rb:31:in `destroy'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-2.0.5/lib/rack/etag.rb:25:in `call'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-2.0.5/lib/rack/conditional_get.rb:38:in `call'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-2.0.5/lib/rack/head.rb:12:in `call'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/railties-5.2.0/lib/rails/rack/logger.rb:38:in `call_app'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/railties-5.2.0/lib/rails/rack/logger.rb:26:in `block in call'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/railties-5.2.0/lib/rails/rack/logger.rb:26:in `call'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-2.0.5/lib/rack/runtime.rb:22:in `call'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-2.0.5/lib/rack/sendfile.rb:111:in `call'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/railties-5.2.0/lib/rails/engine.rb:524:in `call'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-test-1.0.0/lib/rack/mock_session.rb:29:in `request'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-test-1.0.0/lib/rack/test.rb:259:in `process_request'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-test-1.0.0/lib/rack/test.rb:119:in `request'
 # ./spec/requests/users_request_spec.rb:137:in `block (5 levels) in <main>'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr/util/variable_args_block_caller.rb:9:in `call_block'
 # /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr.rb:188:in `use_cassette'
 # ./spec/requests/users_request_spec.rb:136:in `block (4 levels) in <main>'

It looks like use_cassette is called, but maybe it gets unset somewhere along the road? Does it have something to do with the dependent: :destroy relationship between user and authy_user?

Any help is appreciated, and let me know if you need more info.

like image 423
Raymond Gulbrandsen Avatar asked Jul 31 '18 11:07

Raymond Gulbrandsen


1 Answers

Maybe, something in the request is changing each time you do, like an HTTP header, a timestamp, and since you didn't specified VCR to record new transactions, it will fail.

I would debug it, using

VCR.use_cassette("authy_delete_user", record: :new_episodes)

and see if records a new cassette and compare both, to see the output, see what is changing.

By default, if anything in the request changes, a new cassette is written or an error is thrown (your case). You can, in this case, specify how the cassette data and request is matched, for example, using match_requests_on, see here

like image 87
Luiz E. Avatar answered Nov 02 '22 17:11

Luiz E.