In Rspec how does one download content - ruby-on-rails

I want to download from a website during my rspec test
I do not want to stub the API usage for this specific function.
I don't plan on doing a heap of test against an API. For that I hope shall trust the stubbing.
But I think it's a good idea to do at least one test against an API.
Here is some sample code that replicates the issue I'm having:
require 'vcr'
context 'test vcr off' do
it 'should work' do
VCR.turn_off!
res = Net::HTTP.get_response(URI('http://www.google.com.au/?q=tester'))
print res.body
end
end
Here's the error I'm getting:
Failure/Error: res = Net::HTTP.get_response(URI('http://www.google.com.au/?q=tester'))
WebMock::NetConnectNotAllowedError:
Real HTTP connections are disabled. Unregistered request: GET http://www.google.com.au/?q=tester with headers
{'Accept'=>'*/*',
'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
'Host'=>'www.google.com.au', 'User-Agent'=>'Ruby'}
You can stub this request with the following snippet:
stub_request(:get, "http://www.google.com.au/?q=tester").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Host'=>'www.google.com.au', 'User-Agent'=>'Ruby'}).
to_return(:status => 200, :body => "", :headers => {})
The Doc's I've read on VCR indicate that the above code should work.

I really hate when this happens..
I search and search for an answer and then I post a question.
Then minutes later I find the answer..
1 require 'vcr'
2 context 'test vcr off' do
3 it 'should work' do
4 VCR.turn_off!
5 WebMock.disable_net_connect!(:allow => "www.google.com.au")
6 res = Net::HTTP.get_response(URI('http://www.google.com.au/?q=tester'))
7 print res.body
8 end
9 end
The answer was on line 5.. this let me make the call.. I mean I get a pile of junk on the screen, but it doesn't fail... no exception.

Related

response.body is "" even though webmock .to_return(:body => "return") is set

I'm writing unit tests for a Rails service using minitest. A snippet of my test looks like this:
stub_request(:get, #service_url)
.with(:headers => #authheader)
.to_return(:body => "ABC", :status => 200)
get :index
After the get :index, response.code is 200 as expected (and I've changed it to 201 in the .to_return and seen that code be correct after get :index, but every time response.body is "". I'm sure I'm just doing something unimaginably dumb here and welcome being told what a dummy I am. :)
Thanks in advance
minitest 5.8.2
webmock 3.0.1
rails 4

How to stub HTTP request on Mechanize in Rails?

I have some codebase like this, and I wanna use rspec test favicon_href, but as you like, the favicon_href will call the page function, I know I can mock page function, but for this stage I wanna mock the HTTP request from the given url, so I use WebMock gem's syntax to stub HTTP request, but it seems WebMock is not compatibility with Mechanize, it always show the error in the below despite I relleay have done the stub, anyone know how can solve it or any gem can stub HTTP request on Mechanize?
Code
def favicon_href
#favicon_href ||=
begin
page.at(FAVICON_DOM).attributes['href'].value # finding <link> elements
rescue Exception
'/favicon.ico' # there are some situation the favicon's not <link>'
end
end
def page
#page ||= mechanize.get(url)
end
def mechanize
#mechanize ||= Mechanize.new
end
Error
Failure/Error: #page ||= mechanize.get(valid_url(url))
WebMock::NetConnectNotAllowedError:
Real HTTP connections are disabled. Unregistered request: GET https://tsaohucn.wordpress.com/ with headers {'Accept'=>'*/*', 'Accept-Charset'=>'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'Accept-Encoding'=>'gzip,deflate,identity', 'Accept-Language'=>'en-us,en;q=0.5', 'Connection'=>'keep-alive', 'Host'=>'tsaohucn.wordpress.com', 'Keep-Alive'=>'300', 'User-Agent'=>'Mechanize/2.7.5 Ruby/2.3.1p112 (http://github.com/sparklemotion/mechanize/)'}
You can stub this request with the following snippet:
stub_request(:get, "https://tsaohucn.wordpress.com/").
with(headers: {'Accept'=>'*/*', 'Accept-Charset'=>'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'Accept-Encoding'=>'gzip,deflate,identity', 'Accept-Language'=>'en-us,en;q=0.5', 'Connection'=>'keep-alive', 'Host'=>'tsaohucn.wordpress.com', 'Keep-Alive'=>'300', 'User-Agent'=>'Mechanize/2.7.5 Ruby/2.3.1p112 (http://github.com/sparklemotion/mechanize/)'}).
to_return(status: 200, body: "", headers: {})
registered request stubs:
stub_request(:get, "https://tsaohucn.wordpress.com/").
with(headers: {'Accept'=>'*/*', 'User-Agent'=>'Ruby'})
stub_request(:any, "http://api.stripe.com/")
stub_request(:any, "/api.stripe.com/")
============================================================
There exists an incompatibility between WebMock and net-http-persistent.
See
https://github.com/bblimke/webmock#connecting-on-nethttpstart
Add
WebMock.allow_net_connect!(:net_http_connect_on_start => true)
to your test set up.

WebMock stub_request not working

In my rails project, one of the initialisers requests and fetches certain data from S3.
S3.buckets[CONFIG['aws']['cdn_bucket']].objects['object_name'].read
This breaks the rspec test suite which uses webmock gem
WebMock.allow_net_connect!(:net_http_connect_on_start => true)
I get the following error when I try to run the test suite
WebMock::NetConnectNotAllowedError
You can stub this request with the following snippet:
stub_request(:get, "https://bucket.s3.amazonaws.com/object_name").with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'', 'Authorization'=>'AWS AKxxxxxx:Hyxxxxxxxxxx', 'Content-Type'=>'', 'Date'=>'Thu, 14 Apr 2016 15:10:18 GMT', 'User-Agent'=>'aws-sdk-ruby/1.60.2 ruby/1.8.7 i686-darwin15.3.0'}).to_return(:status => 200, :body => "", :headers => {})
Adding this stub does not fix the error. Infact, adding any of the following does not seem to make any change:
WebMock.stub_request(:any, /.*amazonaws.*/).with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'', 'Authorization'=>'AWS AKIxxxxxxxxxx:MSxxxxxxxx'}).to_return(:status => 200, :body => "stubbed response", :headers => {})
WebMock.stub_request(:any, /.*amazonaws.*/).to_return(:status => 200, :body => "stubbed response", :headers => {})
What is it that I am missing here? The detailed header in the error message does not seem to make sense here to allow all kinds of requests to S3
EDIT:
I just noticed that adding WebMock.disable! to the spec_helper also results in no change. Am I not adding the stub to the right place? Where should it be added if not in the spec_helper?
After sleeping over it, it was clear that the stub_request was being added to the wrong place. Adding it directly to the initialiser could have fixed this but that would have broken all other environments as the gem webmock is included for test env only.
Hence adding the following code snippet to the script fixed this
begin
require 'webmock'
WebMock.stub_request(:any, /testimonial/).to_return(:body => '')
rescue LoadError
end
S3.buckets[CONFIG['aws']['cdn_bucket']].objects['object_name'].read
This makes a stub_request if the gem is included else simply goes on as nothing happened.

Webmock and VCR, allow Http Connections if there is no cassette

I have a problem, I can run a test that uses vcr on its own and it works, it creates the cassette and it uses that on the next test. Great.
The problem is when I run all my tests together this particular test fails, because webmock disables http connections, I have seen this example on the Github repo page that explains how to expect real and not stubbed requests
My question is how Do I say: Allow Http connections for requests UNLESS there is a cassette. It should also CREATE the cassette when HTTP connections are allowed.
The VCR Settings
require 'vcr'
VCR.configure do | c |
if !ARGV.first.nil?
c.default_cassette_options = { :record => :new_episodes, :erb => true }
c.filter_sensitive_data('<BLACKBIRD_API_KEY>') {YAML.load(File.read('config/application.yml'))['BLACKBIRD_API_KEY'].to_s}
c.filter_sensitive_data('<BLACKBIRD_API_URL>') {YAML.load(File.read('config/application.yml'))['BLACKBIRD_API_URL'].to_s}
c.debug_logger = File.open(ARGV.first, 'w')
c.cassette_library_dir = 'spec/vcr'
c.hook_into :webmock
end
end
the above if statement exists because not EVERY test creates a cassette. So we want them to run when a cassette isn't needed.
The Test
require 'spec_helper'
describe Xaaron::Publishers::Users do
context "publish created users" do
before(:each) do
Xaaron.configuration.reset
no_user_member_roles_relation
Xaaron.configuration.publish_to_black_bird = true
Xaaron.configuration.black_bird_api_url = YAML.load(File.read('config/application.yml'))['BLACKBIRD_API_URL']
Xaaron.configuration.black_bird_api_key =YAML.load(File.read('config/application.yml'))['BLACKBIRD_API_KEY']
end
it "should publish to blackbird" do
VCR.use_cassette 'publisher/create_user_response' do
expect(
Xaaron::Publishers::Users.publish_new_user({user: {
first_name: 'adsadsad', user_name: 'sasdasdasdsa' ,
email: 'asdassad#sample.com', auth_token: 'asdsadasdasdsa'
}}).code
).to eql 200
end
end
end
end
Runs fine on its own, creates the cassette, fails when run with all other tests due to webmock.
The Failure
Failure/Error: Xaaron::Publishers::Users.publish_new_user({user: {
WebMock::NetConnectNotAllowedError:
Real HTTP connections are disabled. Unregistered request: GET some_site_url_here with headers {'Http-Authorization'=>'api_key_here', 'User-Agent'=>'Typhoeus - https://github.com/typhoeus/typhoeus'}
You can stub this request with the following snippet:
stub_request(:get, "some site url here").
with(:headers => {'Http-Authorization'=>'some api key here', 'User-Agent'=>'Typhoeus - https://github.com/typhoeus/typhoeus'}).
to_return(:status => 200, :body => "", :headers => {})

Webmock caching responses? Or: How to respond to repeated requests with randomized content

I've tried using a lambda in my custom response:
stub_request(
:post,
'http://blah.blah/token'
).to_return(
status: 200,
body: lambda { |a| '{"token":"' + SecureRandom.hex(20) + '","expires_in":"259200"}' }
)
Maybe this isn't the correct way to handle dynamic responses, but anyway, webmock seems to execute the lambda exactly once. The request is identical each time, so either:
My asumption that using a lambda would allow me to generate dynamic content on a per-response basis was wrong.
Because the repeated requests are identical, webmock just uses the last response it generated.
Since this question was written, I strongly suspect that something in Webmock has changed, because the following test passes:
require 'webmock/rspec'
require 'securerandom'
require 'uri'
describe "something" do
it "happens" do
s = stub_request(:get, 'example.com/blah').
to_return(status: 200, body: lambda { |x| SecureRandom.hex(20) })
expect(Net::HTTP.get(URI('http://example.com/blah')))
.to_not eq(Net::HTTP.get(URI('http://example.com/blah')))
expect(s).to have_been_requested.at_least_once
end
end
Tested with Ruby 2.1.5p273, RSpec 3.3.1, and WebMock 1.21.0.

Resources