10

I have a spec file with an expectation that a controller action will return success.

The POST api/v1/users/:id/features/block action in the controller calls two HTTP calls on an external API, the only difference being in the body.

I've put the two requests and responses in the same VCR cassette, but when the cassette is being used, only the first request ever gets compared against and fails when it should be matching the second, causing the tests to fail.

What I'm looking for is a way of having the multiple requests match so the controller action completes and returns successfully.

The error I'm getting is at the end.

describe "POST /api/v1/users/:id/features/block" do
  before(:each) do
    @user = FactoryGirl.create(:user)
    post :block, user_id: @user.id, block: "0"
  end

  it "should return 200 OK" do
    expect(response).to be_success
  end
end

Simplified versions of my VCR configuration and RSpec configuration follow:

VCR.configure do |c|
  c.hook_into :webmock
  c.default_cassette_options = {
    match_requests_on: [:method, :uri, :body_regex]
  }
  c.register_request_matcher :body_regex do |request_1, request_2|
    # Match body against regex if cassette body is "--ruby_regex /regexhere/"
    if request_2.body[/^--ruby_regex\s*\//]
      regex = request_2.body.gsub(/^--ruby_regex\s*\//, '').gsub(/\/$/, '')
      request_1.body[/#{regex}/] ? true : false
    else
      true # No regex defined, continue processing
    end
  end
end

RSpec.configure do |c|
  c.around(:each) do |example|
    options = example.metadata[:vcr] || {} 
      name = example.metadata[:full_description].split(/\s+/, 2).join("/").underscore.gsub(/[^\w\/]+/, "_")
      VCR.use_cassette(name, options, &example)
    end
  end
end

A summarized version of the cassette being used in this comparison that I'm having trouble with is:

---
http_interactions:
- request:
    method: post
    uri: https://upstream/api
    body:
      string: --ruby_regex /query1.+block/
  response:
    status:
      code: 200
    body:
      string: { "response": "SUCCESS" }
- request:
    method: post
    uri: https://upstream/api
    body:
      string: --ruby_regex /query2.+block/
  response:
    status:
      code: 200
    body:
      string: { "response": "SUCCESS" }
  recorded_at: Fri, 05 Sep 2014 08:26:12 GMT
recorded_with: VCR 2.8.0

Error during tests:

An HTTP request has been made that VCR does not know how to handle
...
VCR is using the current cassette: (Correct cassette file path)
...
Under the current configuration VCR can not find a suitable HTTP interaction to replay and is prevented from recording new requests.

I don't want to record new requests because then the second one overwrites the first instead of adding the second request to the end of the cassette.

bdx
  • 3,316
  • 4
  • 32
  • 65

1 Answers1

-1

Maybe new_episodes will work for you. See docs.

General Grievance
  • 4,555
  • 31
  • 31
  • 45