Stubbing Devise helpers to get RSpec to pass

I have literally been bashing my head into the wall this past week trying to figure out how to get RSpec view tests to pass when using Devise. I finally figured it out after a lot of trial and error because there is a particular combination of things you have to have in place to make things work.

First, the what: I added some navigation to a menu bar that only shows up if the user is logged in. It was just:

<nav>
  <% if user_logged_in? %>
    <%= link_to ...blah... %>
  <% end %>
</nav>

The trouble is, I kept getting this error:

Failure/Error: render
ActionView::Template::Error:
  undefined method `authenticate' for nil:NilClass

The first problem was figuring out why Devise’s helpers weren’t being loaded. According to the Devise documentation you should create a spec/support/devise.rb file like:

RSpec.configure do |config|
  config.include Devise::TestHelpers, :type => :controller
end

But what about running view tests? The missing line is:

RSpec.configure do |config|
  config.include Devise::TestHelpers, :type => :controller
  config.include Devise::TestHelpers, :type => :view
end

Great! But that only solves the missing helpers. What about getting current_user to actually return a user? I tried all sorts of things and spent days searching for the answer and it comes down to stubbing out the helpers … but which object? The answer is on the view itself:

module ApplicationRspecHelpers
  def stub_user
    @user = double('user')
    @user.stub(:id => 100)
    view.stub(:user_signed_in? => true)
    view.stub(:current_user => @user)
  end
end

That works exactly as I want it. So now I can write my view tests like:

require 'spec_helper'

describe 'layouts/application' do
  include ApplicationRspecHelpers

  describe 'authentication nav' do
    context 'when authenticated' do
      it 'should have Log Out' do
        stub_user
        render
        rendered.should have_selector('nav a', text: 'Log Out')
      end
    end
  end
end

Hide the iPhone address bar (navigation bar) without appearing to move the page

The popular trick most people apparently do to remove that iPhone address bar in mobile Safari is to scroll the window up by 1 pixel:

window.scrollTo(0, 1);

My problem with this is it shifts the canvas up thereby losing 1 pixel. It turns out you can specify a fraction of a pixel and the trick works just fine still:

Note: I added a 100ms delay to it because it made it work better. I tried listening to the window “load” event it just wasn’t as reliable.

Setup Rails gem Devise to work with Amazon’s Simple Email Service (SES)

This post is mostly for me to remember how to do this. :)

It turns out that getting Devise (or the built-in mailer for that matter) to send email through Amazon Web Services’ (AWS) Simple Email Service (SES) is stupid easy. Most of the work is just getting SES set up properly. After that:

1. Verify some email addresses

  • If you just set up SES you are probably still in sandbox mode. You need to add new recipients on the Verified Senders dashboard first.

2. Generate your SES SMTP Credentials

  • You must generate a new SMTP User and SMTP Password to connect ActionMailer to AWS SES. These are NOT your AWS login credentials!
  • Go to the SMTP Settings dashboard.
  • Click the button “Create My SMTP Credentials”.
  • Copy the information out—it will not be displayed again!

3. Edit your ActionMailer settings in the production.rb file

That should do it! Send yourself a test message.

Remember: you can only send to verified email addresses while in Sandbox Mode. You must request Production Mode access to send to any unverified email address. Otherwise you will probably see the Rails log error: Net::SMTPFatalError (554 Message rejected: Email address is not verified.)

Setup Amazon’s (AWS) Simple Email Service (SES) + DKIM with DreamHost’s DNS

This is mostly a note to myself on how to do this. :)

Amazon’s Simple Email Service (SES) seems pretty easy to use but working with the DreamHost DNS management proved slightly tricky because of the large amount of steps and the order of them. Getting the DNS values right was also not completely obvious. Here’s my recipe:

1. Register a Domain

  • Log into your DreamHost Panel
  • Add a domain (Domains -> Registrations)

2. Change the Domain to DNS-only

  • Click the Edit link for your domain (Domains -> Manage Domains -> Edit)
  • Scroll all the way down to the DNS Only section
  • Choose that

3. Turn on Amazon SES

  • Create your Amazon Web Services (AWS) account
  • Go to the console page
  • Click SES to get to your SES dashboard
  • Click Verify New Sender
  • Click Verify a New Email Address
  • Wait until your new email address shows up in the Email Addresses list (or hit Refresh)
  • Click on the new email address to get its Details, you should see Status: pending verification

4. Verify Your Email Address

  • You should have gotten an email with the verification link in it: click it
  • Go back to the SES dashboard and click on the new email

5. Update DNS custom records on DreamHost

  • Return to your DreamHost Panel
  • Click Domains -> Manage Domains
  • Click the DNS link under your domain
  • Scroll down to the “Add a custom DNS record to YOURDOMAIN.com” section
  • Add a TXT record with the full value:
    • Notice: SES might recommend a text record of _amazonses.YOURDOMAIN.com. Do not paste this full value in! You must remove the “.YOURDOMAIN.com” part. That’s right, just enter: _amazonses
  • You might also want to add DKIM to your domain as well.
    • Click the “copy record” link to see the full name and value.
    • Notice: Again, SES might recommend a CNAME record that looks like abcdefghijklmnop1234567890._domainkey.YOURDOMAIN.comYou need to remove “.YOURDOMAIN.com” for DreamHost.

6. Wait…!

  • It takes a while for the DNS records to propagate. You will also get an email notification that says the sender is verified and the DKIM verification is complete.

 

Mac OS X Mail uses “Sent Messages” folder, not “Sent”

Oh, Mac OS X…

It is pretty. But it has so many quirks. I suppose if you’ve been a long-time Mac fan these things don’t feel that weird to you, but I have to say that I’ve just come across the most non-obvious way of changing an application’s settings.

A few months back I took the plunge and made Mac OS X Mail my primary mail app. I figured all I had to do was hook up the accounts like I did on my iPhone and iPad: pick an account type, enter some credentials, and that was it. Generally-speaking, that is true. But I started running into this problem: sent messages from OS X Mail weren’t showing up in my Sent mail folders on my iPhone and iPad.

I still have lots of IMAP mail accounts. When you add those IMAP accounts to an iPhone or iPad you can go to the advanced server settings and choose where you want the Sent messages to go: on the phone/tablet or to a folder on the server. And when you pick the folder on the server you normally would pick “Sent”. Not so for OS X Mail!

OS X Mail creates a folder called “Sent Messages” and there is no indication anywhere that’s the case. If you look at the Mailboxes bar there is a Sent category which expands to show you all the sent-mail folders for all accounts you’ve connected. And if you open up your IMAP account folders you might see a Sent folder but no Sent Messages folder. As you send messages out your Sent Messages folder gets all those new sent messages.

(And, no, there is no indication in the Preferences for Mail that Sent Messages is the destination sent mail folder.)

How do you fix this? A post back in 2004 has the answer:

  • Open Mail
  • Navigate to the Sent folder of an IMAP account
  • Click the name to highlight it
  • From the Mailbox menu choose Use This Mailbox For, then choose Sent

If you look at your IMAP folders now you will see the Sent Messages folder listed.

How horrible.

Grepping with more context

I wanted to get some more context while grepping some code. Turns out there are options -A and -B that give you n number of lines after/before the matched pattern. But that can still leave you a little lost, so why not add some color?

% grep some_pattern -B 3 -A 3 --color some_file
blah blah blah
blah blah blah
blah blah blah
blah some_pattern blah
blah blah blah
blah blah blah
blah blah blah

Video editing on a 2012 MacBook Pro Retina

I’m no stranger to taxing computers’ CPUs by rendering video. I’ve been doing it off and on pretty much since I figured out how to work Microsoft’s Movie Maker software—I couldn’t really afford Vegas or Premiere as a student.

These days I use Final Cut Pro X and the projects I work on are long and complex, though not nearly at the professional level. Some of the larger projects use about 80 GB of video and audio from multiple sources and the final rendered projects are approaching 40 minutes. The machine is decently beefy: 2.7 GHz Core i7, 16 GB RAM, 512 GB SSD. That’s pretty much the top spec w/out splurging for the larger SSD.

I’ve found that the best way to edit the video is to load all the sources onto the MacBook Pro. It has a 512GB hard drive but a good portion of that is already used up by work and other projects. That leaves about 200 GB available, which is apparently bare minimum. During the process of editing the intermediary files that get generated quickly swallow up the remainder of the space. To get around this I’ve often been taking project segments and “bouncing” them down (an audio editor term; I don’t know the equivalent video editor term) to high-resolution rendered movies. Then I piece them back together to make the whole.

All in all, the MacBook Pro’s CPU capacity is pushed to its limits but it still crunches video like no other computer I’ve used—including desktops. Plus the added portability lets me work on segments while commuting on the train. The one thing it lacks is storage space. A Thunderbolt SSD would be perfect; spinning disks are too slow for all of this random access work.

“Why do YouTube views freeze at 301?”

Interesting interview with Ted Hamilton at YouTube by numberphile (Brady Haran):

<iframe width=”560″ height=”315″ src=”http://www.youtube.com/embed/oIkhgagvrjI” frameborder=”0″ allowfullscreen></iframe>

“The number 300 was chosen. … When the code was written … what was actually written was … less than or equal to 300.” (If view_count <= 300 then views += 1.)