Friday, June 12, 2009

Finally, a Homepage

‹prev | My Chain | next›

Continuing the homepage-and-beyond Cucumber scenario, next up is adding some categories to the recipes:
  Scenario: Quickly scanning meals and recipes accessible from the home page
Given 25 yummy meals
And 1 delicious recipe for each meal
And the first 5 recipes are Italian
And the second 10 recipes are Vegetarian

When I view the site's homepage
In the "1 delicious recipe for each meal" step (implemented last night), the recipe IDs are stored away in an instance variable (@recipe_ids) for later use. I make use of it when adding the first five recipes to the "Italian" category:
Given /^the first 5 recipes are Italian$/ do
@recipe_ids[0...5].each do |recipe_id|
data = RestClient.get "#{@@db}/#{recipe_id}"
recipe = JSON.parse(data)

recipe['tag_names'] = ['italian']

RestClient.put "#{@@db}/#{recipe['_id']}",
:content_type => 'application/json'
That step operates on each of the first five recipes (0...5 includes 0, 1, 2, 3, and 4 and not 5—two dots instead of three would include 5). For each recipe created in the previous Cucumber step, the recipe's tag names are set to 'italian'. The recipe is then PUT back onto the CouchDB database. As with the meal updates from yesterday, this CouchDB PUT is only possible because the lookup pulls back the most recent revision ID.

I implement a similar step for the next 10 vegetarian recipes, then it is time to visit homepage:
When /^I view the site's homepage$/ do
response.should be_ok
This step fails, of course, because I have not created the homepage. So let's move into the code to create it.

I drive the initial development of the homepage with these examples:
    describe "GET /" do
it "should respond OK" do
get "/"
last_response.should be_ok

it "should request the most recent 13 meals from CouchDB" do
and_return('{"rows": [] }')

get "/"
Those two examples ensure that the homepage will respond OK and that it will load 13 meals from CouchDB (10 for pretty display, 3 extra for links only). The code that makes these two examples pass is:
get '/' do
url = "#{@@db}/_design/meals/_view/by_date?limit=13"
data = RestClient.get url
@meals = JSON.parse(data)['rows']

Next, I remove the empty string from the end of the get "/" block, replacing it with a Haml template call:
  haml :index
So now, it is time to move down into the Haml template. I carry the instance variable @meals down to the Haml template to drive the presentation:
describe "index.haml" do
before(:each) do
assigns[:meals] = [{ "key" => "2009-05-15",
"value" => ['2009-05-15', "Foo"] },
{ "key" => "2009-05-31",
"value" => ["2009-05-31", "Bar"] }]

it "should link to the meal titles" do
response.should have_selector("h2", :content => "Bar")
Finally, I implement this in a Haml template:
%h1 Meals
- @meals.each do |meal|
%h2= meal["value"][1]
That is decent progress for a day. Before quitting, I double-check that the Cucumber step describing accessing the homepage is now passing, which it is:

I could make the first "then" step pass. The h2 headers in the Haml template could be construed as "prominently displayed" meals. I still need to display the meal summary, so I will pick up with that tomorrow, before marking that step as complete.

No comments:

Post a Comment