Joey bookmarked James Patterson Inc.


Koi in Chengdu

Golden

China - 2009 to 2010 | Chengdu, Sichuan, China | taken January 23, 2010 | Previous - Next


Giant Panda in Chengdu

Golden

China - 2009 to 2010 | Chengdu, Sichuan, China | taken January 23, 2010 | Previous - Next


Statue at Wuhou Temple, Chengdu

Golden

China - 2009 to 2010 | Chengdu, Sichuan, China | taken January 22, 2010 | Previous - Next


Terracotta Army

Golden

China - 2009 to 2010 | Xi'an, Shaanxi, China | taken January 21, 2010 | Previous - Next


Terracotta Army

Golden

China - 2009 to 2010 | Xi'an, Shaanxi, China | taken January 21, 2010 | Previous - Next


Joey bookmarked Craftsmanship


Xi'an's Ancient City Wall

Golden

China - 2009 to 2010 | Xi'an, Shaanxi, China | taken January 19, 2010 | Previous - Next

Yes, the air is really bad in Xi'an.


Inside the Forbidden CIty

Golden

China - 2009 to 2010 | Beijing, China | taken January 17, 2010 | Previous - Next


Bronze Lion in the Forbidden City

Golden

China - 2009 to 2010 | Beijing, China | taken January 17, 2010 | Previous - Next


Ancient Tree in the Forbidden City

Golden

China - 2009 to 2010 | Beijing, China | taken January 17, 2010 | Previous - Next


Roof Detail - Forbidden City

Golden

China - 2009 to 2010 | Beijing, China | taken January 17, 2010 | Previous - Next


Guard Tower in the Forbidden City

Golden

China - 2009 to 2010 | Beijing, China | taken January 17, 2010 | Previous - Next


Scorpions on a Stick in Beijing

Golden

China - 2009 to 2010 | Beijing, China | taken January 16, 2010 | Previous - Next


Tiananmen

Golden

China - 2009 to 2010 | Beijing, China | taken January 16, 2010 | Previous - Next

The placards read: "Long live the People's Republic of China. Long live the great unity of the world's peoples."


View Over The Forbidden City

Golden

China - 2009 to 2010 | Beijing, China | taken January 15, 2010 | Previous - Next


Joey bookmarked 2010: The Year of the Products + A New Way of Working


Joey bookmarked Official Google Blog: A New Approach to China


Joey bookmarked Kickstarter - A New Way To Fund Ideas and Endeavors


Shoulda Macros for Testing (Not) Logged-In Filters

In any Rails app with a user system, certain actions are likely to have a before_filter to ensure that a user is either logged in or not logged in before accessing those actions. For instance, the edit profile page should only be accessible if a user is logged in. The registration page, conversely, should only be accessible if a user is NOT logged in.

With Shoulda, we can easily create a few macros which make testing this behavior as simple as adding a single line to the test context for each action that uses one of these filters.

# test_helper.rb

# ...

class ActiveSupport::TestCase

  include RR::Adapters::TestUnit

  def self.should_require_user(opts = {})
    simulate_no_user = lambda do
      stub(@controller).current_user { nil }
      @preserve_login = true
    end
    
    should "require user", :before => simulate_no_user do
      assert_contains flash.values, (opts[:flash] || /Please log in/)
      assert_redirected_to login_path
    end
  end

  def self.should_require_no_user(opts = {})
    simulate_user = lambda do
      stub(@controller).current_user { opts[:user] || Factory(:user) }
      @preserve_login = true
    end
    
    should "require no user", :before => simulate_user do
      assert_contains flash.values, (opts[:flash] || /Please log out/)
      assert_redirected_to root_path
    end
  end
  
  # ...

end

def login(user)
  stub(@controller).current_user { user } unless @preserve_login
end

By adding one of these macros to a Shoulda context it will, before that context's setup block, simulate a user being logged in (or out), execute the setup block (preserving the state of @controller.current_user), and then ensure that the appropriate redirect occurs and flash message is set.

So, with these macros defined, our users_controller test looks like this:

# users_controller_test.rb

require 'test_helper'

class UsersControllerTest < ActionController::TestCase
  
  context 'get new' do
    
    setup { get :new }
    
    should_require_no_user
    # ...
    
  end
  
  context 'get edit' do
    
    setup do
      login Factory(:user)
      get :edit
    end
    
    should_require_user
    # ...
    
  end
  
  # ...
  
end

The resulting tests are succinct, explicit and easy-to-type.

You can recycle this pattern for other before_filters in your app too. For instance, if you have admin-only controllers / actions, just add macros that simulate an admin instead of a regular user and you're ready to test.