Fixtures for your Redis Database

Another week, another gem!

This time, you’ll be able to test your code that interacts with Redis much more easily and consistently, by resetting your Test Redis DB to a known state at the start of each test.

RedisFixtures is, as its name says, Fixtures for your Redis DB. If you are using Redis as more than a cache (and if you’re not, you absolutely should, Redis is awesome!), you’ll want to have a consistent initial database state for your tests.

RedisFixtures will run at the start of each of your tests, flush your test Redis DB, and load the data from the Fixture into it.

As for generating this fixture, if you’re using FixtureBuilder, then it couldn’t be easier. Simply call RedisFixtures.save_fixtures and the end of your factory block, and you’re in business!

If you’re using any other gems to generate your fixtures, basically do the equivalent thing for them.

RedisFixtures is compatible with Minitest, and I’ll be adding support for RSpec soon. If you’re using RSpec and would like to have fixtures for Redis, get in touch!

Happy testing!

SmsSafe – MailSafe for SMS – Send SMS safely in your apps!

So, after a very long blogging hiatus, I’m coming back, with a completely different approach. Ruby Gems!!

Over the last few years I’ve been working on some very very interesting projects, and as part of those I developed a lot of functionality that is quite general purpose, and that I’ve been extracting into gems, for my own future self, of course, but I’m also blogging about them in the hopes that they will help you.

On today’s installment: SmsSafe!

If you’ve every sent emails with Rails, you’ve probably encountered MailSafe, that beautiful gem that allows you to test your app safely, knowing you will never email actual customers with crap, test data, or worse. Both Watu and Msty had this need to send SMS, and being used to MailSafe, I felt very unhappy without having a similar safety net, especially on Msty, where accidentally sending out SMS during a load test of the system could easily mean a few thousand dollars in carrier fees.

Seeing this, I cut my Gem-making teeth by blatantly stealing stemps’s idea, and building what is essentially MailSafe for SMS.

The idea is quite simple. You add the gem to your Gemfile, and then add this to your config:

    SmsSafe.configure do |config|
      config.internal_phone_numbers = ['+12223334444', '+447111222222']
      config.intercept_mechanism = :redirect
      config.redirect_target = '+12223334444'
    SmsSafe.hook!(:action_texter) # or :twilio or :nexmo

The way this works, just like MailSafe, is you set a whitelist criteria, to which SMS can go, and for everything else, a redirection strategy and address. Anything that isn’t going to the whitelist, you can choose to ignore (simply drop it), redirect to a different number (probably your own), or redirect to e-mail instead, for a less annoying debugging alternative.

The usual cases:

  • For development, you’ll whitelist nothing and then redirect everything to your phone / email. That way, when you are testing workflows that send SMS, you do get them.
  • For staging, you can whitelist the numbers of everyone in the dev team… Or you can have a testing phone in the office that receives all SMS…
  • The whitelist can be either a string, an array of strings, a regex, and most interestly a Proc, which lets you do custom logic. For example, on our “beta testing” environment, we wanted our testers to be able to sign up (for which they needed a verification SMS), but not be able to SMS other people. This simple Proc solved that, using the “reference” field to filter based on the message “type”. You can also use a Proc for the redirection address, so you can vary who ends up receiving the SMS / email using any logic you may need.
        SmsSafe.configure do |config|
          config.internal_phone_numbers = do |message| # Return true if it can go out, false if it needs to be intercepted
          config.intercept_mechanism = :discard
  • For load / stress testing, you’ll turn off SMS sending completely. However, this will throw off your timings, since SMS sending is most certainly not instantaneous. To compensate for this, you can set a :discard_delay property to be the average response time of your SMS provider, which will give you a more realistic benchmark.

SmsSafe works by hooking into either the ActionTexter, Twilio or Nexmo gems. However, only ActionTexter has hooks that allow for interception (that I suggested via Pull Request for this very gem, and they graciously accepted). ActionTexter also provides functionality for switching to a “test” SMS provider in your test environment, allowing you to inspect the messages that would’ve been sent, so I strongly recommend you use it in your project.

Twilio and Nexmo are hooked via monkeypatching, unfortunately. If you use any other SMS gem or provider, and you’d like to use SmsSafe, please either submit a PR, or just let me know and I’ll try to add it, I’d love to see adoption for SmsSafe!