How to stub external javascript libraries when writing Rails integration tests/specs? - ruby-on-rails

My app interfaces with Google Maps for geocoding and Stripe for payments. Using VCR I've mocked all requests to these services, which works great. But the libraries for both are still being loaded in javascript_include_tags. What's the best way to deal with this so that integration tests can run completely disconnected from the internet?

If you want to stub the javascript, then why record the interactions in the first place? Am I missing something?
I'm pretty sure geocoding from a test is a violation of the google maps ToS. I think what you want to do is stub the geocoding itself.
Have never used Stripe, but I might take this approach: add a method in a spec helper to cache the Stripe javascript locally, i.e., when a connection is available, download the Stripe javascript. Then in your view load the javascript locally if Rails.env.test?.

For anyone looking for a solution these days, there is a nice gem called Puffing Billy.
Similarly to how VCR allows you to record and replay external requests made by your server code, this library allows you to do the same for external requests made by your client code.

Related

Rails External API Testing

I'm writing tests for my Rails app. My app communicates with an external API that processes customer payments, specifically BrainTree. Now, I want to make sure my app's class that communicates with BrainTree works properly e.g. that it submits user information and other parameters to BrainTree correctly. Making the goal to only test that BrainTree and my App are communicating properly.
One thing to note, is that BrainTree has a sandbox account. To test my class, should I:
Write a feature test using something like Capybara and Rspec and test it from a user's perspective e.g. user logs in, fills out form, submits payment etc.
Write a request spec that just submits the required information and examines the return values. This is what I would prefer but is tricky since BrainTree requires js, and I am not sure I can do have js in a request spec without monkey patching Rspec, which I'd rather not do since I am still fairly new to Rspec and testing in general.
Write both feature and request specs
Write a completely different type of test
I have a feature test in place, but it seems cumbersome to use to just test an external API since it needs to open a browser, fill out forms, etc. in my feature spec I'd rather stub the external API and test the API as a unit test. A request spec seems more efficient but the js requirement seems like a roadblock.
Is there a Best Practice to what I should do in my scenario above?
In general, you don't typically want to write tests only for an external service, but instead for your own code that tests against the responses you receive.
The best way I've found to stub a response from an external API is the VCR gem. This will get a legitimate response and save it for use in future runs. You can erase the stored response occasionally to ensure continued functionality.
Another approach to testing this is to use a fake service that mimics the API. Fake Braintree Gem provides such functionality and I've used this with a mix of VCR for other tests to ensure correct functionality. There's many other approaches but you can test to see which one fits your needs

In Rails, how can I stub a websocket message for a test?

The application is using Minitest on Rails 4 with Capybara.
I'd like to write an integration or feature test that stubs a websocket connection (the application uses Faye as a client) to return a specific message (like I'm used to doing with Webmock).
Is this possible? If so, can you provide an example? My research has not turned up any examples.
Your research hasn't shown up any examples because it's not really what you're supposed to be doing in feature tests. Feature tests are supposed to be end-to-end black box tests where you configure the data as required for the app to generate the desired results and then all interaction is done via the browser (no mocking/stubbing which technically alter your apps code). Additionally when connections between the browser and a 3rd party service are involved there is nowhere in your app where you can mock it.
It may be possible to stub a websocket connection from the browser with a programmable proxy like puffing-billy, however it's generally cleaner to produce a small fake version of the 3rd party service for testing purposes (sinatra app, etc) and point the browser at that rather than the original service when you need to craft custom responses. Additionally, there are a lot of fakes already out there, depending on what service you are using (fake-stripe, fake-s3, etc), which may provide the functionality you're looking for.

How to reduce external API calls in rails

I have integrated facebook, twitter API's in my rails application for getting hashtag records. Everything is working fine but API calls are taking too long too execute which is really very frustrating. I googled around to get rid of this. There are curl_multi functions available in PHP. Is there something available in rails too?
Not sure about the PHP thing, but if you want to asynchronously process API calls use a queue. Rails provides us with the ActiveJob facade that allows us to use a variety of queues on the back-end. A good tutorial on how to do this can be found here.

How do I test this third party API integration in rspec?

My project is a rails app that extends some third party API. A lot of the requests rely on third party API calls. How should I test these cases in rspec? Should I use VCR and actually just hit the third party (then mock future requests)? Or should I just download the payload into a fixture manually and stub requests with webmock and find a way to bypass the oauth process? Are the better solutions?
Note that it uses OAuth, but I don't use omniauth.
Sometimes the API limits me to fetching N records at a time, so I have to paginate them. There could be instances where I'm making 25 requests just to get the data I need, but this is mostly for the sync rake tasks.
There is no need to download a payload manually, as this is exactly what VCR does for you. VCR creates a yaml fixture, that it uses for all future requests.

What is the first step to using a REST API in Rails?

I have just completed Hartl's book on rails. Following the examples have been helpful and I have been able to build some very basic functionality for my app. However, there is this API I would like to use, and have been granted a key for the API. I have absolutely no idea how to start implementing the API. The other stuff surrounding API's have been helpful, but I literally am stuck on what the very first step should be to begin implementing the API.
I need for a user to be able to sign up and authenticate, then supply data that will be tracked through the external API. I've got the user sign up and authenticate stuff down pat, just need to know what the very first baby step to using this API should be.
The logic behind the answer would be equally helpful.
You can use ActiveResource for your model and point it to the external API. This is useful if your model uses an external data source.
http://api.rubyonrails.org/classes/ActiveResource/Base.html
If the external API you want to use is a well known, there is a good chance that there is already a gem for interaction with that API.
If you only need to send some data to the external API but your model does not use it as its source, you can use an HTTP client like Faraday https://github.com/technoweenie/faraday

Resources