Thank you to anyone who has already donated - your generous donations helped make three months of treatment possible.

My brother Nate continues to fight stage IV Hodgkin's lymphoma. He's just 31, with a wife and baby girl. They have no active income (since he's been unable to return to work), no insurance, and cannot afford the treatment he needs. Nate and his family need your help. Please consider a donation, every dollar helps. Thanks.



			
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe AccountsController do

  # having this here removes interesting details from other examples
  # i'd probably try to inline it
  def mock_account(stubs={})
    stubs = {
      :save => true,
      :update_attributes => true,
      :destroy => true,
      :to_xml => ''
    }.merge(stubs)
    @mock_account ||= mock_model(Account, stubs)
  end

  describe "responding to GET /accounts" do

    # using TDD I would not write this example
    it "should succeed" do
      Account.stub!(:find)
      get :index
      response.should be_success
    end

    # using TDD I would not write this example
    it "should render the 'index' template" do
      Account.stub!(:find)
      get :index
      response.should render_template('index')
    end

    # using TDD I would not write this example
    # the simpliest code that makes the example pass is:
    #   def index
    #     Account.find(:all)
    #   end
    # Which clearly isn't what you want. The next example is
    # what you want, and it removes the need for this example.
    it "should find all accounts" do
      Account.should_receive(:find).with(:all)
      get :index
    end

    # i like it
    it "should assign the found accounts for the view" do
      Account.should_receive(:find).and_return([mock_account])
      get :index
      assigns[:accounts].should == [mock_account]
    end

  end

  describe "responding to GET /accounts.xml" do

    before(:each) do
      request.env["HTTP_ACCEPT"] = "application/xml" 
    end

    # using TDD I would not write this example
    it "should succeed" do
      Account.stub!(:find).and_return([])
      get :index
      response.should be_success
    end

    # same comment as the example undder GET /accounts
    it "should find all accounts" do
      Account.should_receive(:find).with(:all).and_return([])
      get :index
    end

    # i like it
    it "should render the found accounts as xml" do
      Account.should_receive(:find).and_return(accounts = mock("Array of Accounts"))
      accounts.should_receive(:to_xml).and_return("generated XML")
      get :index
      response.body.should == "generated XML" 
    end

  end

  describe "responding to GET /accounts/1" do

    # using TDD I would not write this example
    it "should succeed" do
      Account.stub!(:find)
      get :show, :id => "1" 
      response.should be_success
    end

    # using TDD I would not write this example
    it "should render the 'show' template" do
      Account.stub!(:find)
      get :show, :id => "1" 
      response.should render_template('show')
    end

    # same comment as:
    #  "responding to GET /accounts" it "should find all accounts"
    it "should find the requested account" do
      Account.should_receive(:find).with("37")
      get :show, :id => "37" 
    end

    # i like it
    it "should assign the found account for the view" do
      Account.should_receive(:find).and_return(mock_account)
      get :show, :id => "1" 
      assigns[:account].should equal(mock_account)
    end

  end

  describe "responding to GET /accounts/1.xml" do

    before(:each) do
      request.env["HTTP_ACCEPT"] = "application/xml" 
    end

    # using TDD I would not write this example
    it "should succeed" do
      Account.stub!(:find).and_return(mock_account)
      get :show, :id => "1" 
      response.should be_success
    end

    # using TDD I would not write this example
    it "should find the account requested" do
      Account.should_receive(:find).with("37").and_return(mock_account)
      get :show, :id => "37" 
    end

    # i like it
    it "should render the found account as xml" do
      Account.should_receive(:find).and_return(mock_account)
      mock_account.should_receive(:to_xml).and_return("generated XML")
      get :show, :id => "1" 
      response.body.should == "generated XML" 
    end

  end

  describe "responding to GET /accounts/new" do

    # using TDD I would not write this example
    it "should succeed" do
      get :new
      response.should be_success
    end

    # using TDD I would not write this example
    it "should render the 'new' template" do
      get :new
      response.should render_template('new')
    end

    # same comment as:
    #  "responding to GET /accounts" it "should find all accounts"
    it "should create a new account" do
      Account.should_receive(:new)
      get :new
    end

    # i like it
    it "should assign the new account for the view" do
      Account.should_receive(:new).and_return(mock_account)
      get :new
      assigns[:account].should equal(mock_account)
    end

  end

  describe "responding to GET /accounts/1/edit" do

    # using TDD I would not write this example
    it "should succeed" do
      Account.stub!(:find)
      get :edit, :id => "1" 
      response.should be_success
    end

    # using TDD I would not write this example
    it "should render the 'edit' template" do
      Account.stub!(:find)
      get :edit, :id => "1" 
      response.should render_template('edit')
    end

    # same comment as:
    #  "responding to GET /accounts" it "should find all accounts"
    it "should find the requested account" do
      Account.should_receive(:find).with("37")
      get :edit, :id => "37" 
    end

    # i like it
    it "should assign the found Account for the view" do
      Account.should_receive(:find).and_return(mock_account)
      get :edit, :id => "1" 
      assigns[:account].should equal(mock_account)
    end

  end

  describe "responding to POST /accounts" do

    describe "with successful save" do

      it "should create a new account" do
        Account.should_receive(:new).with({'these' => 'params'}).and_return(mock_account)
        post :create, :account => {:these => 'params'}
      end

      # what view? it redirects. :)
      it "should assign the created account for the view" do
        Account.stub!(:new).and_return(mock_account)
        post :create, :account => {}
        assigns(:account).should equal(mock_account)
      end

      it "should redirect to the created account" do
        Account.stub!(:new).and_return(mock_account)
        post :create, :account => {}
        response.should redirect_to(account_url(mock_account))
      end

    end

    describe "with failed save" do

      it "should create a new account" do
        Account.should_receive(:new).with({'these' => 'params'}).and_return(mock_account(:save => false))
        post :create, :account => {:these => 'params'}
      end

      it "should assign the invalid account for the view" do
        Account.stub!(:new).and_return(mock_account(:save => false))
        post :create, :account => {}
        assigns(:account).should equal(mock_account)
      end

      it "should re-render the 'new' template" do
        Account.stub!(:new).and_return(mock_account(:save => false))
        post :create, :account => {}
        response.should render_template('new')
      end

    end

  end

  describe "responding to PUT /accounts/1" do

    describe "with successful update" do

      it "should find the requested account" do
        Account.should_receive(:find).with("37").and_return(mock_account)
        put :update, :id => "37" 
      end

      it "should update the found account" do
        Account.stub!(:find).and_return(mock_account)
        mock_account.should_receive(:update_attributes).with({'these' => 'params'})
        put :update, :id => "1", :account => {:these => 'params'}
      end

      # what view? it redirects
      it "should assign the found account for the view" do
        Account.stub!(:find).and_return(mock_account)
        put :update, :id => "1" 
        assigns(:account).should equal(mock_account)
      end

      it "should redirect to the account" do
        Account.stub!(:find).and_return(mock_account)
        put :update, :id => "1" 
        response.should redirect_to(account_url(mock_account))
      end

    end

    describe "with failed update" do

      it "should find the requested account" do
        Account.should_receive(:find).with("37").and_return(mock_account(:update_attributes => false))
        put :update, :id => "37" 
      end

      it "should update the found account" do
        Account.stub!(:find).and_return(mock_account)
        mock_account.should_receive(:update_attributes).with({'these' => 'params'})
        put :update, :id => "1", :account => {:these => 'params'}
      end

      it "should assign the found account for the view" do
        Account.stub!(:find).and_return(mock_account(:update_attributes => false))
        put :update, :id => "1" 
        assigns(:account).should equal(mock_account)
      end

      it "should re-render the 'edit' template" do
        Account.stub!(:find).and_return(mock_account(:update_attributes => false))
        put :update, :id => "1" 
        response.should render_template('edit')
      end

    end

  end

  describe "responding to DELETE /accounts/1" do

    # i think i would just combine this with the next spec
    it "should find the account requested" do
      Account.should_receive(:find).with("37").and_return(mock_account)
      delete :destroy, :id => "37" 
    end

    it "should call destroy on the found account" do
      Account.stub!(:find).and_return(mock_account)
      mock_account.should_receive(:destroy)
      delete :destroy, :id => "1" 
    end

    it "should redirect to the accounts list" do
      Account.stub!(:find).and_return(mock_account)
      delete :destroy, :id => "1" 
      response.should redirect_to(accounts_url)
    end

  end

end