5

Hi I am trying to test google auth with cucumber using vcr with a tag.

Everything goes fine till token expires. I think when it expires this happens

enter image description here

But I have a file with this content

http_interactions:
- request:
  method: post
  uri: https://accounts.google.com/o/oauth2/token
  body:

If I allow vcr to record new requests the content of this cassette changes. I don't understand why, if the method and uri do not change POST to https://accounts.google.com/o/oauth2/token.

I changed tag to record new episodes and now test is passing... I am clueless.

I run the test again and now I am having this when POST to token url is being done:

Completed 500 Internal Server Error in 449ms

Psych::BadAlias (Unknown alias: 70317249293120):
sites
  • 21,417
  • 17
  • 87
  • 146
  • 1
    Something similar is happening to me... I think it has to do with refreshing the token. When using oauth you have a token, which may be expired (or not). If you run the test and the token is fresh, that request isn't called. But if the token has expired it has to refresh it, and thus vcr throws an error... I'm not sure how to solve this yet. I'll keep investigating. Did you solve this? – iwiznia Mar 12 '14 at 19:42

4 Answers4

3

Maybe you have some parameters inside the post, which are different for every request? If so, you can tell VCR to ignore this parameters by adding match_requests_on: [:method, VCR.request_matchers.uri_without_params("your_param")] to your VCR configuration.

In depth analyse your request, and find out which parameters are changing. You can tell VCR also to match on other criterias, have a look here https://www.relishapp.com/vcr/vcr/v/2-4-0/docs/request-matching

23tux
  • 14,104
  • 15
  • 88
  • 187
  • I had `match_requests_on [:method, :url]`, as far as I remember. NO params there. Thanks – sites Apr 30 '13 at 14:33
3

Ok, here's a solution... The problem comes, as I said in the comment, from refreshing the token. When using oauth you have a token, which may be expired (or not). If you run the test and the token is fresh, that request isn't called. But if the token has expired it has to refresh it, and thus vcr throws an error. To solve that, what I did is add the refresh token url to the ignored requests of vcr:

VCR.configure do |c|
  c.cassette_library_dir = 'fixtures/vcr_cassettes'
  c.hook_into :webmock # or :fakeweb
  c.ignore_request {|request| request.uri == 'https://accounts.google.com/o/oauth2/token' }
end

It's not the best solution, since sometimes the token gets refreshed in the tests... but it's the best solution I could find...

iwiznia
  • 1,669
  • 14
  • 21
2

I was getting the same issue with the same URL. For me, the problem was that my code was attempting to make the same call to https://accounts.google.com/o/oauth2/token more than once.

One of the potential solutions given in the VCR error message tells you the solution:

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

In my case, adding this option fixed the problem, as it tells VCR to revert back to its 1.x functionality of not re-recording duplicate requests, but simply playing back the result of a previously recorded duplicate request.

I am using Cucumber, so my solution was to add the following to my features/support/vcr.rb:

VCR.cucumber_tags do |t|
  t.tag  '@vcr', use_scenario_name: true
  t.tag  '@new_episodes', record: :new_episodes
  t.tag  '@allow_playback_repeats', use_scenario_name: true, allow_playback_repeats: true, record: :new_episodes
end

Notice the @allow_playback_repeats tag. I simply tagged my scenario with this tag, and everything worked properly thereafter:

@allow_playback_repeats
Scenario: Uploading a video initiates an upload to YouTube

Note that it doesn't work if you specify both @vcr and @allow_playback_repeats.

If you're using RSpec, you'll need to adapt the solution accordingly, but, it should be as simple as:

it "does something", :vcr => { allow_playback_repeats: true } do
   ...
end
ctc
  • 2,640
  • 1
  • 16
  • 18
0

I met the same problem, and finally found the there is a parameter changed every time.

you my solution is: copy and paste the mock parameter and real parameter together, and compare with them , and also make sure your next unit test would generate new parameter.

Siwei
  • 19,858
  • 7
  • 75
  • 95