Adding mail delivery to an existing code base: Part One — webmocks

Amber Wilkie
Nomads Of Code
Published in
4 min readJan 18, 2017

This post is part of the Agile Ventures initiative to develop a Visualizer for Google Analytics. Supported in part by Craft Academy staff (including myself), we will document the journey from building the application to bringing it to market. Onward!

First things first: it’s my very first “real” Open Source project. I’ve never written a single line of code that wasn’t freely available on Github, but I’ve not had the chance to build something with others that was destined for anything but code reviews by my coaches at bootcamp. Now I’m working on a real project with people I’ve never met! Here we go…

Step One: Understand what the hell these people want

My feature: Add email distribution Here’s the user story:

As a user
In order to have my report delivered to my inbox
I would like to be able to submit my email address.

Cool, I think, and head into the code base but when I run rails db:migrate nothing at all happens. Funny… there are no users at all. How can we set up a service to email them if we can’t remember who they are after they click away from the page?

I post my confusion to the Slack channel, and get the response: we need to mail them after they have authorized the app to access their Google Analytics. Only once, while they are looking at the page that made the API call. I assume we’ll have to build users and all that, but someone else will handle that and integrate my feature later. Ok now I know what this user story is about and I’m on it.

Step Two: Research

  • As always, I start with the excellent Rails Guides.
  • Oh crap, this might require Sidekiq or Resque in production (job handlers). I’ll get it working in test and development first before I pull those guys in.
  • I might want to use email-spec for testing in Cucumber
  • To actually send the emails, we are going to need to pull in a gem. I spoke with the unofficial project lead and was advised to use SendGrid.

Step Three: Write some tests

This code base is almost 100% untested, but I want to try and give my piece at least some unit tests so we can make sure it’s performing as it should. Unfortunately the Google Analytics API calls aren’t stubbed, so I can’t really test the actual functionality, but maybe I can get it sending some other emails. Here’s my test:

Scenario: I send an email
Given I am on the "Get Data" page
When I fill in "Email" with "example@example.com"
And I click on "Send"
Then "example@example.com" should receive an email

Now we’re getting hit with that non-stub problem:

Failing test because API calls are not being stubbed in test.

Step 3a: let’s try getting those stubs in place after all.

So we install Webmock. We put gem 'webmock' in our :test group and throw these lines into a support file. My response body is coming from the logs when I actually clicked through with my Google account. This is what the app expects Google to send, more or less, so it seems like the right thing to mock with.

require 'webmock/cucumber'

Before '@webmock' do
stub_request(:get, "https://www.googleapis.com/analytics/v3/management/accounts//webproperties/").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip,deflate', 'Date'=>Time.now.utc.strftime('%a, %d %b %Y %R:%S GMT'), 'User-Agent'=>'unknown/0.0.0 google-api-ruby-client/0.9.20 Mac OS X/10.10.5
(gzip)'}).
to_return(:status => 200, :body => "<Google::Apis::AnalyticsV3::AccountSummary:
... a bunch of stuff I've omitted in case it's sensitive info - I honestly don't know.
>", :headers => {})
end

I’m particularly proud of the date formatting there — that was such a pain. I did find strftime while I was trying to figure it out, which I am definitely going to keep in mind for the future!

Of course, I didn’t get to this until days of rerunning my Cucumber test. Until — finally, I was getting a new webmock dialog! The app was finally trying to make the second API call. Nice.

And this one was totally awesome (not). Spot the difference? I didn’t.

Until I came upon text-compare.com, which shows you where there are differences between two different strings. Guess the difference? One space between the (gzip) and the text before it. Painful.

Then another stub to register. This app makes a lot of API calls.

Finally, finally, finally, I had stubbed all the API calls. Next up, this bad boy:

My copy-pasted response clearly wasn’t formatted correctly… but it is 5pm and I have to meet a friend so this needs to be handled on some other day!

--

--

Amber Wilkie
Nomads Of Code

Software developer, mostly Ruby and Javascript. Yogi, Traveler, Enthusiast. All photographs mine. I don’t read the comments — try me on Twitter.