6

I'm trying to mock a api call in which I upload a file, I'm using Wistia Upload API and because I don't want to hit the server with every test, I'm trying VCR for the first time.

I have the following test in my spec/controllers folder:

let(:file) { Rack::Test::UploadedFile.new("video_path", 'video/mp4') }

describe "GET #index" do
  it "assigns all videos as @videos" do
    VCR.use_cassette "wistia/upload" do 
      video = Video.create! valid_attributes

      get :index, {}
      expect(assigns(:videos)).to eq([video])
    end
  end
end

end

The API call is triggered inside a model callback that looks like this:

class Video < ActiveRecord::Base
  after_save :move_video
  def move_video
    uri = URI('https://upload.wistia.com/')

    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true

    # Construct the request.
    request = Net::HTTP::Post::Multipart.new uri.request_uri, {
    'api_password' => '',
    'project_id'   => ''
    'file' => my_video_file
    }
    # Make it so!
    response = http.request(request)
    return response
  end
end

I've debugged the call to this method, and it's being called properly, but when I run my test I'm getting the following error:

1) VideosController GET #index assigns all videos as @videos
     Failure/Error: video = Video.create! valid_attributes
     VCR::Errors::UnhandledHTTPRequestError:


       ================================================================================
       An HTTP request has been made that VCR does not know how to handle:
         POST https://upload.wistia.com/

       VCR is currently using the following cassette:
         - /Users/urielhernandez/Documents/pf/spec/vcr/wistia/upload.yml
         - :record => :once
         - :match_requests_on => [:method, :uri]

       Under the current configuration VCR can not find a suitable HTTP interaction
       to replay and is prevented from recording new requests. There are a few ways
       you can deal with this:

         * 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].
         * You can use the :new_episodes record mode to allow VCR to
           record this new request to the existing cassette [2].
         * If you want VCR to ignore this request (and others like it), you can
           set an `ignore_request` callback [3].
         * The current record mode (:once) does not allow new requests to be recorded
           to a previously recorded cassette. You can delete the cassette file and re-run
           your tests to allow the cassette to be recorded with this request [4].
         * The cassette contains an HTTP interaction that matches this request,
           but it has already been played back. If you wish to allow a single HTTP
           interaction to be played back multiple times, set the `:allow_playback_repeats`
           cassette option [5].

       [1] https://www.relishapp.com/vcr/vcr/v/2-9-3/docs/configuration/debug-logging
       [2] https://www.relishapp.com/vcr/vcr/v/2-9-3/docs/record-modes/new-episodes
       [3] https://www.relishapp.com/vcr/vcr/v/2-9-3/docs/configuration/ignore-request
       [4] https://www.relishapp.com/vcr/vcr/v/2-9-3/docs/record-modes/once
       [5] https://www.relishapp.com/vcr/vcr/v/2-9-3/docs/request-matching/playback-repeats
       ================================================================================

The cassette was created but I was receiving the mentioned error. After I deleted the cassette to see if it was being generated, it was no re generated, and VCR is not handling the request.

Uriel Hernández
  • 731
  • 3
  • 9
  • 23
  • The `VCR.use_cassette "wistia/upload" do ` block does not have an `end`; so I am guessing this should have thrown a syntax error. Try `VCR.use_cassette "wistia_upload" do ... end` ; the `/` in the cassette name might also be throwing VCR off. – Prakash Murthy Mar 17 '15 at 14:30
  • Sorry, I'm editing my question, it was a typo copying my code to the question. In my code I do have the end block for the VCR.use_cassete method. – Uriel Hernández Mar 17 '15 at 14:32
  • Changing `wistia/upload` to `wistia_upload` didn't change anything. – Uriel Hernández Mar 17 '15 at 14:33
  • 1
    The `/` in the cassette name is fine. The cassette is created at `/Users/urielhernandez/Documents/pf/spec/vcr/wistia/upload.yml` as described in the error message. Try `VCR.use_cassette("wistia/upload", :record => :new_episodes) do` ; that will record this as a new request in the same cassette. – Prakash Murthy Mar 17 '15 at 14:41
  • Is working now, the only thing I added was the new_episode option you said. How could I mark your question as the correct? I don't understand yet what was the problem. And also, my cassette was never regenerated, I've to recovered from the trash and it worked. – Uriel Hernández Mar 17 '15 at 14:54
  • Perfect. I will add that in the answer with more details. – Prakash Murthy Mar 17 '15 at 14:55
  • I stopped using VCR, and just using rspec mocks to mock my objects. It is much more flexible then using VCR – Fabrizio Bertoglio Aug 06 '19 at 03:42

1 Answers1

10

The cassette is being created at /Users/urielhernandez/Documents/pf/spec/vcr/wistia/upload.yml as described in the error message.

Try VCR.use_cassette("wistia/upload", :record => :new_episodes) do ; that will record this as a new request in the same cassette.

See more about vcr record modes at https://www.relishapp.com/vcr/vcr/v/1-3-2/docs/record-modes

Prakash Murthy
  • 12,923
  • 3
  • 46
  • 74