Agile Web Development with Rails, Edition 4

Agile Web Development with Rails, Edition 4

13.1 Iteration H1: Adding Users 12.7 Iteration J2: Email Notifications

12.8 Iteration J3: Integration Tests

edit app/controllers/orders_controller.rb
  def create
    @order = Order.new(params[:order])
    @order.add_line_items_from_cart(find_or_create_cart)
 
    respond_to do |format|
      if @order.save
        Cart.destroy(session[:cart_id])
        session[:cart_id] = nil
        Notifier.order_received(@order).deliver
        format.html { redirect_to(store_url, :notice => 
          'Thank you for your order.') }
        format.xml  { render :xml => @order, :status => :created,
          :location => @order }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @order.errors,
          :status => :unprocessable_entity }
      end
    end
  end
rails generate integration_test user_stories
DEPRECATION WARNING: railtie_name is deprecated and has no effect. (called from /home/rubys/.rvm/gems/ruby-1.8.8-r28169/gems/will_paginate-3.0.pre/lib/will_paginate/railtie.rb:6)
      invoke  test_unit
      create    test/integration/user_stories_test.rb
edit test/integration/user_stories_test.rb
require 'test_helper'
 
class UserStoriesTest < ActionController::IntegrationTest
  fixtures :products
 
  # A user goes to the index page. They select a product, adding it to their
  # cart, and check out, filling in their details on the checkout form. When
  # they submit, an order is created containing their information, along with a
  # single line item corresponding to the product they added to their cart.
  
  test "buying a product" do
    LineItem.delete_all
    Order.delete_all
    ruby_book = products(:ruby)
 
    get "/"
    assert_response :success
    assert_template "index"
    
    xml_http_request :post, '/line_items', :product_id => ruby_book.id
    assert_response :success 
    
    cart = Cart.find(session[:cart_id])
    assert_equal 1, cart.line_items.size
    assert_equal ruby_book, cart.line_items[0].product
    
    get "/orders/new"
    assert_response :success
    assert_template "new"
    
    post_via_redirect "/orders",
                      :order => { :name     => "Dave Thomas",
                                 :address  => "123 The Street",
                                 :email    => "dave@example.com",
                                 :pay_type => "Check" }
    assert_response :success
    assert_template "index"
    cart = Cart.find(session[:cart_id])
    assert_equal 0, cart.line_items.size
    
    orders = Order.find(:all)
    assert_equal 1, orders.size
    order = orders[0]
    
    assert_equal "Dave Thomas",       order.name
    assert_equal "123 The Street",    order.address
    assert_equal "dave@example.com", order.email
    assert_equal "Check",             order.pay_type
    
    assert_equal 1, order.line_items.size
    line_item = order.line_items[0]
    assert_equal ruby_book, line_item.product
 
    mail = ActionMailer::Base.deliveries.last
    assert_equal ["dave@example.com"], mail.to
    assert_equal 'Sam Ruby <depot@example.com>', mail[:from].value
    assert_equal "Pragmatic Store Order Confirmation", mail.subject
  end
end
rake test:integration
DEPRECATION WARNING: railtie_name is deprecated and has no effect. (called from /home/rubys/.rvm/gems/ruby-1.8.8-r28169/gems/will_paginate-3.0.pre/lib/will_paginate/railtie.rb:6)
(in /home/rubys/svn/rails4/Book/util/work-188/depot)
DEPRECATION WARNING: railtie_name is deprecated and has no effect. (called from /home/rubys/.rvm/gems/ruby-1.8.8-r28169/gems/will_paginate-3.0.pre/lib/will_paginate/railtie.rb:6)
Loaded suite /home/rubys/.rvm/gems/ruby-1.8.8-r28169%global/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.
Finished in 0.370191 seconds.
 
1 tests, 20 assertions, 0 failures, 0 errors
edit test/integration/dsl_user_stories_test.rb
require 'test_helper'
 
class DslUserStoriesTest < ActionController::IntegrationTest
  fixtures :products
 
 
  DAVES_DETAILS = {
      :name     => "Dave Thomas",
      :address  => "123 The Street",
      :email    => "dave@example.com",
      :pay_type => "Check"
  }
 
  MIKES_DETAILS = {
      :name     => "Mike Clark",
      :address  => "345 The Avenue",
      :email    => "mike@pragmaticstudio.com",
      :pay_type => "Credit card"
  }
  
  
    
  def setup
    LineItem.delete_all
    Order.delete_all
    @ruby_book = products(:ruby)
    @rails_book = products(:two)
  end 
  
  # A user goes to the store index page. They select a product,
  # adding it to their cart. They then check out, filling in
  # their details on the checkout form. When they submit,
  # an order is created in the database containing
  # their information, along with a single line item
  # corresponding to the product they added to their cart.
  
  def test_buying_a_product
    dave = regular_user
    dave.get "/"
    dave.is_viewing "index"
    dave.buys_a @ruby_book
    dave.has_a_cart_containing @ruby_book
    dave.checks_out DAVES_DETAILS
    dave.is_viewing "index"
    check_for_order DAVES_DETAILS, @ruby_book
  end
 
  def test_two_people_buying
    dave = regular_user
        mike = regular_user
    dave.buys_a @ruby_book
        mike.buys_a @rails_book
    dave.has_a_cart_containing @ruby_book
    dave.checks_out DAVES_DETAILS
        mike.has_a_cart_containing @rails_book
    check_for_order DAVES_DETAILS, @ruby_book
        mike.checks_out MIKES_DETAILS
        check_for_order MIKES_DETAILS, @rails_book
  end
  
  def regular_user
    open_session do |user|
      def user.is_viewing(page)
        assert_response :success
        assert_template page
      end
    
      def user.buys_a(product)
        xml_http_request :post, '/line_items', :product_id => product.id
        assert_response :success 
      end
    
      def user.has_a_cart_containing(*products)
        cart = Cart.find(session[:cart_id])
        assert_equal products.size, cart.line_items.size
        for item in cart.line_items
          assert products.include?(item.product)
        end
      end
    
      def user.checks_out(details)
        get "/orders/new"
        assert_response :success
        assert_template "new"
 
       post_via_redirect "/orders",
                          :order => { :name     => details[:name],
                                     :address  => details[:address],
                                     :email    => details[:email],
                                     :pay_type => details[:pay_type]
                                    }
        assert_response :success
        assert_template "index"
        cart = Cart.find(session[:cart_id])
        assert_equal 0, cart.line_items.size
      end
    end  
  end
  
  def check_for_order(details, *products)
    order = Order.find_by_name(details[:name])
    assert_not_nil order
    
    assert_equal details[:name],     order.name
    assert_equal details[:address],  order.address
    assert_equal details[:email],    order.email
    assert_equal details[:pay_type], order.pay_type
    
    assert_equal products.size, order.line_items.size
    for line_item in order.line_items
      assert products.include?(line_item.product)
    end
 
    mail = ActionMailer::Base.deliveries.last
    assert_equal order.email,           mail[:to].value
    for line_item in order.line_items
      assert_operator mail.body.to_s, :include?, line_item.product.title
    end
  end
end
rake test:integration
DEPRECATION WARNING: railtie_name is deprecated and has no effect. (called from /home/rubys/.rvm/gems/ruby-1.8.8-r28169/gems/will_paginate-3.0.pre/lib/will_paginate/railtie.rb:6)
(in /home/rubys/svn/rails4/Book/util/work-188/depot)
DEPRECATION WARNING: railtie_name is deprecated and has no effect. (called from /home/rubys/.rvm/gems/ruby-1.8.8-r28169/gems/will_paginate-3.0.pre/lib/will_paginate/railtie.rb:6)
Loaded suite /home/rubys/.rvm/gems/ruby-1.8.8-r28169%global/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
...
Finished in 0.991327 seconds.
 
3 tests, 75 assertions, 0 failures, 0 errors
git commit -a -m "Admin"
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	app/controllers/carts_controller.rb
#	app/controllers/line_items_controller.rb
#	app/controllers/orders_controller.rb
#	app/controllers/store_controller.rb
#	app/helpers/carts_helper.rb
#	app/helpers/line_items_helper.rb
#	app/helpers/orders_helper.rb
#	app/helpers/store_helper.rb
#	app/mailers/
#	app/models/cart.rb
#	app/models/line_item.rb
#	app/models/order.rb
#	app/views/carts/
#	app/views/line_items/
#	app/views/notifier/
#	app/views/orders/
#	app/views/products/who_bought.atom.builder
#	app/views/products/who_bought.html.erb
#	app/views/products/who_bought.xml.builder
#	app/views/store/
#	db/migrate/20100301000002_create_carts.rb
#	db/migrate/20100301000003_create_line_items.rb
#	db/migrate/20100301000004_add_quantity_to_line_item.rb
#	db/migrate/20100301000005_combine_items_in_cart.rb
#	db/migrate/20100301000006_create_orders.rb
#	db/migrate/20100301000007_add_order_id_to_line_item.rb
#	script/load_orders.rb
#	test/fixtures/carts.yml
#	test/fixtures/line_items.yml
#	test/fixtures/orders.yml
#	test/functional/carts_controller_test.rb
#	test/functional/line_items_controller_test.rb
#	test/functional/notifier_test.rb
#	test/functional/orders_controller_test.rb
#	test/functional/store_controller_test.rb
#	test/integration/
#	test/unit/cart_test.rb
#	test/unit/helpers/carts_helper_test.rb
#	test/unit/helpers/line_items_helper_test.rb
#	test/unit/helpers/orders_helper_test.rb
#	test/unit/helpers/store_helper_test.rb
#	test/unit/line_item_test.rb
#	test/unit/order_test.rb
nothing added to commit but untracked files present (use "git add" to track)
git tag iteration-j
pub depot_q

13.1 Iteration H1: Adding Users 12.7 Iteration J2: Email Notifications