Exercises

編寫一個測試,確定友善導向只會在第一次登入時導向指定的位址,以後的登入都會導向預設位址,例如個人資料頁面。提示:把這個測試加進 test/integration/users_edit_test.rb 裡面,檢查 session[:forwarding_url] 的值是否正確。


編寫一個整合測試,檢查佈局中的所有連結,包括登入和未登入會看到的連結。提示:把這個測試加進 test/integration/site_layout_test.rb 裡面,使用 log_in_as 輔助方法。


參考以下程式碼,直接向 update action 發送 PATCH 請求,確認無法修改 admin 屬性。為了確保測試寫得正確,首先應該先把 admin 加進允許修改的 user_params 參數列表中,所以在此之前的測試會無法通過。

test/controllers/users_controller_test.rb

require 'test_helper'

class UsersControllerTest < ActionController::TestCase

  def setup
    @user       = users(:michael)
    @other_user = users(:archer)
  end
  .
  .
  .
  test "should redirect update when logged in as wrong user" do
    log_in_as(@other_user)
    patch :update, id: @user, user: { name: @user.name, email: @user.email }
    assert_redirected_to root_url
  end

  test "should not allow the admin attribute to be edited via the web" do
    log_in_as(@other_user)
    assert_not @other_user.admin?
    patch :update, id: @other_user, user: { password:              FILL_IN,
                                            password_confirmation: FILL_IN,
                                            admin: FILL_IN }
    assert_not @other_user.FILL_IN.admin?
  end
  .
  .
  .
end

重構 new.html.erbedit.html.erb,把重複的表單程式碼移除,使用下列的 app/views/users/_form.html.erb partial。注意,這裡使用 provide 方法,用來避免重複佈局:

app/views/users/_form.html.erb

<%= form_for(@user) do |f| %>
  <%= render 'shared/error_messages', object: @user %>

  <%= f.label :name %>
  <%= f.text_field :name, class: 'form-control' %>

  <%= f.label :email %>
  <%= f.email_field :email, class: 'form-control' %>

  <%= f.label :password %>
  <%= f.password_field :password, class: 'form-control' %>

  <%= f.label :password_confirmation %>
  <%= f.password_field :password_confirmation, class: 'form-control' %>

  <%= f.submit yield(:button_text), class: "btn btn-primary" %>
<% end %>

app/views/users/new.html.erb

<% provide(:title, 'Sign up') %>
<% provide(:button_text, 'Create my account') %>
<h1>Sign up</h1>
<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= render 'form' %>
  </div>
</div>

app/views/users/edit.html.erb

<% provide(:title, 'Edit user') %>
<% provide(:button_text, 'Save changes') %>
<h1>Update your profile</h1>
<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= render 'form' %>
    <div class="gravatar_edit">
      <%= gravatar_for @user %>
      <a href="http://gravatar.com/emails" target="_blank">Change</a>
    </div>
  </div>
</div>