Zend certified PHP/Magento developer

RubySource: Rails Deep Dive: Loccasions, Home Page

In the last post, we ended with our application structure. In this post, we’ll start with our first user story As an unregistered user, I want to see the home/landing page. There are a few things to point out in this short user story. First, we have identified a role of the application in the form of an unregistered user. Also, the story tells us that we need to have a home page that is not protected by authorization.

Mocking Up the Home Page

This page is the front door of our application, and anyone can knock on it. At this point, it’d be nice to have a talented web designer on the team who could crank out a simple, elegant page. Unfortunately, we just have me, and my design skills are, um, raw. coughs
I like to sketch out wireframes when someone can’t afford a real designer, er, I mean, when I am designing a page. There are a plethora of mockup tools on the interwebs (and there is paper and pencil virtually everywhere) and I’ve settled on MockupBuilder because my usual tool (Pencil) is on sabbatical or something. I have cranked out a quick mockup here:

Our blueprint

It’s a simple, if criminally familiar, home page. There are links to sign in and register, a largish image to promote the site, and a divided area below to put information about the awesome of Loccasions. The layout feeds into a grid system nicely, which is no mistake.

Prepare the Test Environment

Before we take that mockup through the looking glass, we need to setup our test environment and write a test (or two) to validate our page. I mentioned Daniel Kehoe’s (@rails_apps) excellent tutorials in the last post, and I am relying heavily on them to setup the test environment for Loccasions.

Setup RSpec

RSpec comes with generators to setup the environment, so open up a terminal, cd into the loccasions directory and type:

rails g rspec:install

The output to this command complained that the Mongoid config didn’t exist (ugh, first mistake), so we need to generate it.

rails g mongoid:config

That gives us a config/mongoid.yml that will drive the creation of our databases in MongoDB. Re-running rails g rspec:install and rspec is happy (unless, MongoDB is not running) again.

We aren’t going to use ActiveRecord in Loccasions, so we have to comment out a couple of lines in the spec/spec_helper.rb file. Comment out these lines:

# config.fixture_path = "#{::Rails.root}/spec/fixtures"
# config.use_transactional_fixtures = true

In between test suites, we want RSpec to clean up the database. The database_cleaner gem performs this task for us. Add the following to the spec/spec_helper.rb file.

# Clean up the database
require 'database_cleaner'
config.before(:suite) do
  DatabaseCleaner.strategy = :truncation
  DatabaseCleaner.orm = "mongoid"
end
config.before(:each) do
  DatabaseCleaner.clean
end

Also in the spec_helper.rb file, add

require 'capybara/rspec'/code

to get the capybara RSpec matchers.

The mongoid-rspec gem gives us some nice RSpec matchers to help our tests communicate their purpose more effectively. These matchers are added to RSpec by creating a spec/support/mongoid.rb (you’ll have to create the support directory too) file with the following:

RSpec.configure do |config|
  config.include Mongoid::Matchers
end

That gets our test environment into a state that we can get going. There are still a couple of things to set up, but we’ll do that when it’s more pressing. Just to make sure that we haven’t broken anything, run rake -T at the command prompt and make sure you see the RSpec tasks. If all is well, run rake spec and RSpec should tell you that it has nothing to do, which is a good thing.

Our First Test

Looking at our current user story, an unregistered user needs to see our home page. How do we measure that we’ve met this story? What will the home page have that we can confirm and know we’re OK? My first thoughts on what to measure are:

  • The page has a ‘Sign In’ link
  • The page title is ‘Loccasions: Home’
  • The page has ‘What is Loccasions?’ somewhere on it. (We want to explain ourselves…)

We’ll start by using Capybara’s new feature syntax in our first acceptence test. Create a file called spec/acceptance/home_page_spec.rb (you’ll have to create the acceptance directory as well) with the following content:
require ‘spec_helper’

feature 'Home Page', %q{
  As an unregistered user
  I want to see the home/landing page
} do
  background do
    # Nothing to do here
  end
  scenario "Home page" do
    visit "/"
    page.should have_link('Sign In')
    page.should have_selector('title', :content = "Loccasions")
    page.should have_content('What is Loccasions?')
  end
end

This spec is very easy to read and looks for the items we are using to measure success. By starting with an acceptance test, we are driving the design from the user’s perspective. Running rake spec results in:

Awww…our first spec…

As expected, the spec fails trying to find a “Sign In” link. Right now, we are still using the default index.html in the public directory, so let’s delete it. Running the spec again, we now see a “Routing error” which, again, makes sense as we have no root route. Based on previous Rails apps and convention, let’s make a “Home” controller with an “index” action.

rails g controller Home index

ERB? Que pasa??

Hmmm…something is not right. The generator created an ERB template instead of a Haml template. I swear I’ve read that, at 3.1, including Haml in your Gemfile will automatically make it the default template_engine. Seems I am incorrect. Oh well, the quick solution is to add gem "haml-rails", "~ 0.3.4" to our Gemfile and bundle install. Now, rerun the rails g controller Home index and voila!, we have a Haml template. (Oh, and go ahead and remove the app/views/home/index.html.erb file)

Next, we need to point our root path to the index method on our new controller. Open up config/routes.rb, remove the get "home#index" line and replace it with root :to = "home#index". Running the spec again brings the return of the no “Sign-In” link error.
In the interest of time and effort, I am going to jump ahead a bit and create the layout for our home page. I am using Skeleton, and have modified the app/views/layouts/application.html.haml (I migrated the ERB layout file to Haml) and the app/views/home/index.html.haml files accordingly. Here is what you need to do to catch up:

  • Download and uncompress Skeleton.
  • Copy the files from the javascript and stylesheets directories to those same directories in app/assets/
  • Replace the contents of your app/views/layouts/application.html.haml file with the content here
  • Replace the contents of your app/views/home/index.html.haml file with the content here
  • Replace the contents of your app/assets/stylesheets/home.css.sass file with the content here
  • Copy to your app/assets/images directory

If you rerun the spec, it passes.

Pass me on the lefthand side

Just like that, our first user story is complete. It’s Miller Time!

Feel free to look over the layout and index Haml files and see how I met our spec. Once you are comfortable with Haml’s syntax, the details of our layout is much less interesting.

git add .
git commit -am "Added home page and layout"
git push origin master

Next time, we’ll start with another user story and see where that takes Loccasions. As always, I am interested in your opinions and comments about how the series is playing out.

BTW, the font used for the Loccasions header is Eight One by glue.