Thursday, June 11, 2009

Outside the Homepage

‹prev | My Chain | next›

I finished off the navigation between meals Cucumber scenario last night. Before moving on, I have to ask myself, "did I create a navigation between recipes scenario?" Sadly, the answer to that is "no", so I do so now:
    Scenario: Navigating to other recipes

Given a "Spaghetti" recipe from May 30, 2009
And a "Pizza" recipe from June 1, 2009
And a "Peanut Butter and Jelly" recipe from June 11, 2009
When I view the "Peanut Butter and Jelly" recipe
Then I should see the "Peanut Butter and Jelly" title
When I click "Pizza"
Then I should see the "Pizza" title
When I click "Spaghetti"
Then I should see the "Spaghetti" title
When I click "Pizza"
Then I should see the "Pizza" title
When I click "Peanut Butter and Jelly"
Then I should see the "Peanut Butter and Jelly" title
That's very nearly a cut-n-paste of the navigation between meals scenario. Hopefully the work already done to implement the latter will make this new scenario easy to implement.

I will not be implementing that today. Even with the new scenario, I have 170 out of 220 scenario steps complete. Most of the remaining scenarios deal with the homepage and site-wide navigation. If I can get those complete, I can deploy—if only in beta. I can live without between-recipe navigation for a beta deployment. Heck, I can live without it in live code for a little while.

So it's on to the "Site" feature. To put myself in the right frame of mind, I revisit the Cucumber preamble that I wrote for this feature:
  So that I may explore many wonderful recipes and see the meals in which they were served
As someone interested in cooking
I want to be able to easily explore this awesome site
Ah, effusive language really inspires. I must do well by these users!

The first scenario in there is "Quickly scanning meals and recipes accessible from the home page". The "given" preconditions are:
    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 creating the 25 meals, I inject the IDs into an instance variable for use in later steps:
Given /^(\d+) yummy meals$/ do |count|
start_date =, 6, 11)

@meal_ids = (0...count.to_i).inject([]) do |memo, i|
date = start_date - (i * 10)

meal = {
:title => "Meal #{i}",
:date => date.to_s,
:serves => 4,
:summary => "meal summary",
:description => "meal description",
:type => "Meal",
:menu => []

RestClient.put "#{@@db}/#{date.to_s}",
:content_type => 'application/json'

memo + [date.to_s]
I do something similar when creating a recipe for each meal. The only difference is that I need to update the meal with the recipe included on the menu:
Given /^1 delicious recipe for each meal$/ do
@recipe_ids = @meal_ids.inject([]) do |memo, meal_id|
data = RestClient.get "#{@@db}/#{meal_id}"
meal = JSON.parse(data)

permalink = meal['date'] + "-recipe"

recipe = {
:title => "Recipe for #{meal['title']}",
:date => meal['date'],
:preparations => [
{ 'ingredient' => { 'name' => 'ingredient' } }

RestClient.put "#{@@db}/#{permalink}",
:content_type => 'application/json'

# Update the meal to include the recipe in the menu
meal['menu'] << "[recipe:#{permalink.gsub(/-/, '/')}"
RestClient.put "#{@@db}/#{meal['_id']}",
:content_type => 'application/json'

memo + [permalink]
Per the CouchDB API I can PUT the meal there because it includes the rev attribute when it is looked up at the beginning of this step. Had I simply remembered the JSON from the meal creation step, I would have gotten a 409 error from CouchDB telling me that the PUT operation failed. By retrieving the meals via the IDs, I retrieve the current revision number, allowing this step to pass without error.

I need to call it a night at this point. I will pick up the next pending step tomorrow and then start working my way into the homepage code.

No comments:

Post a Comment