Skip to content

Instantly share code, notes, and snippets.

View pat's full-sized avatar
🇵🇸
free Palestine 🇵🇸

Pat Allan pat

🇵🇸
free Palestine 🇵🇸
View GitHub Profile

I've written this code to test what happens once a Stripe card token has been passed through to the server. This code does not do any browser testing (because JS-friendly headless testing is painful at best, and impossible if you want VCR in the mix). VCR is being used here to capture interactions with a test Stripe account, to ensure the tests are fast on future runs. That said, it's structured so that nothing is expected to be present in the Stripe account. If you delete all the stored VCR cassettes, the specs will safely re-record them.

Instead of using VCR.use_cassette directly, instead you use stripe_cassette in your specs, passing in the current spec example object. This will automatically generate a cassette name based on the spec's file name and the example's description (limitations of this are noted in the code comments). Within the cassette's recording block, Stripe data is cleared out before yielding back to the spec, with a context object. The context object provides access to helper methods

The problem:

We want to run headless browser tests (in this case, using Poltergeist & PhantomJS) that call our Ruby code which then makes requests out to Stripe's API.

However, we don't want those API requests happening every time. In our non-headless-browser tests (ie: using vanilla Capybara), we have VCR recording those requests, so subsequent runs of the specs are kept quick. VCR is only recording in the RSpec process, though, not the Poltergeist server process - so in our headless-browser tests, Stripe calls don't get recorded by VCR (different process, different context).

What I'm thinking is:

  • A HTTP/S proxy running in a separate thread/process, which is also where VCR operates.
  • Requests made in the RSpec process are proxied through to the VCR process.
@pat
pat / README.markdown
Last active April 16, 2021 00:55
Custom CSS for Safari (likely every browser) to avoid the who-to-follow and trends components.

EDIT These rules do not work with the current desktop-browser design for Twitter (mid-2019). Try uBlock Origin with these rules instead.

But if you're somehow using an old Twitter design…

In Safari's preferences, the ability to choose a custom CSS file is under the Advanced tab. As far as I can tell, you must quit and re-open Safari when you make changes to the file to see those changes take place on the sites you're browsing.

bundle --local
Resolving dependencies...
Using rake 10.4.2
Using i18n 0.7.0
Using json 1.8.3
Using minitest 5.7.0
Using thread_safe 0.3.5
Using tzinfo 1.2.2
Using activesupport 4.1.5
Using builder 3.2.2

MICF Acts on the $20 list that I've seen before and enjoyed:

  • Alan Brough & Casey Bennetto
  • Celia Pacquola
  • Dave Thornton
  • Hannah Gadsby
  • Josh Earl
  • Justin Hamilton
  • Mark Watson
  • Max & Ivan
@pat
pat / index_set.rb
Created January 21, 2015 08:43
Mixing Apartment with Thinking Sphinx
# app/lib/index_set.rb
class IndexSet < ThinkingSphinx::IndexSet
private
def indices
# respect index names if they're provided
return super if index_names.any?
# filter indices by current tenant.
suffix = "#{Apartment::Tenant.current_tenant}_core"
@pat
pat / gist:1c5c6e7dcab49a20e6ea
Last active April 26, 2017 11:43
Looking for Rubyists in Melbourne?

Looking for Rubyists in Melbourne?

I get asked whether I know anyone who is available for Ruby gigs quite regularly - and the answer is almost always 'not at the moment' - but I'm not a definitive source! The recommendations I always have for potential Rubyist employers/clients are:

Go to Ruby events!

Attend a Melbourne Ruby presentations night - they're always on the last Wednesday of the month, excluding December. These are the most social events (hack nights and InstallFests are a bit more studious), so they're the best opportunity to meet Rubyists face to face. There's also the opportunity to give a short (10-30 seconds) pitch for anyone who's hiring early in the evening (but stick around after that, so people can find you and chat further!).

There are also always a few recruiters at these events - perhaps it's worth having a chat with them too? The fact that they attend events is a good sign that they're engaged with the community.

# Within a Reform::Form subclass, for attribute type detection with Formtastic
def column_for_attribute(attribute)
type = options_for(attribute)[:coercion_type]
Column.new type.name.demodulize.downcase.to_sym
end
Column = Struct.new :type

We've got a model User, and we're adding in the ability for a user to share their actions on Facebook (and likely other social mediums later on). Obviously, not every user wants to do this, so we want to track their preferences on a per-action-type basis.

I figure there's four ways of handling this:

  • Add a boolean column for every setting to the users table.
  • Add a JSON hash column to the users table to store all preferences.
  • Create a new model (UserPreference) and store each setting as a separate boolean column.
  • Create a new model (UserPreference) and perhaps have separate JSON hash columns per social medium (one for Facebook, one for Twitter, etc).

Whichever approach, it'd be really nice to have form objects for just preferences (and ones that handle situations where not all attributes/settings will be available - some users may only have Twitter connected, others only Facebook, etc).

@pat
pat / migration.rb
Created December 20, 2014 02:03
Slugging logic out of the model.
# For when you're adding the slug column to a model with existing records:
SlugGenerator.slug User, :slug