fugafugaにrestful_authenticationをセットアップ。(5) ~ Userモデルの初期値の設定

※「APP_CONFIG~」は、config/config.ymlで定数として定義しています。

とりあえず、定数は、config/config.yml作って、config/environment.rbで、restful_authentication_tutorialを参考に。

 require File.join(File.dirname(__FILE__), 'boot')
 
+ #Load application and environment specific constants
+ raw_config = File.read(RAILS_ROOT + "/config/config.yml")
+ APP_CONFIG = YAML.load(raw_config)[RAILS_ENV]
 
 Rails::Initializer.run do |config|

なんて書いて、RAILS_ENVによって切り替わるように。
た・だ・し、productiionをベースにして、developmentとかtestとかでは、それをマージする。
なんで?


だって、本来有るべき完成されたものは、製品版であって、開発版だとかテスト版だとかは、あくまで、その状況に合わせて作った、特別なものでしかないから。


実際には、

defaults: &defaults
  settings: &settings
  name: fugafuga
(略)
development:
  <<: *defaults
  settings:
    <<: *settings
    name: fugafuga_development
(略)
test:
  <<: *defaults
  settings:
    <<: *settings
    name: fugafuga_test
(略)
production:
  <<: *defaults

みたいに書いてるんだけど。
結果、developmentとtestとで、同じ値を代入することになること、多々なんだけど(管理者のメール・アドレスとか、ね)、でも、敢えて、そうしてる。


同じことをやる≠同じコードを書く、だから、ねぇ。


で、ここに、

  owner: &owner
    email:                  info@fugafuga.com
    password:               password
    crypted_password:       280856ca36237a0bdcd009fc5d667e39a263068c
    salt:                   441dc46651c37d3a4c9ed617a63a49ca2a3276b3
    name:                   fugafuga Inc. Customer Center

みたいな感じで、Userモデルの初期データ、この場合は、サイト・オーナーなんだけど、を書く。
crypted_passwordとsaltは、アプリ上で実際にユーザ作って、DBから抜いてきた。
泥クサっwww


で、テスト用のフィクスチャと、初期データを同一内容にしたいな、ということで、developmentのマイグレーションでは、テスト用フィクスチャを読み込むようにする。


とりあえず、テスト用のフィクスチャの修正。
基本は、「restful_authenticationの生成したフィクスャ、users.ymlを動的なものにする。」でやったのと同じなんだけど。
元からあったquentin、aaron、old_password_holderのIDは、+10してやった;-)

# spec/fixtures/users.yml	(revision 8)

+<%
+  ## this code must match that in templates/model.rb
+  require 'digest/sha1'
 
+  def secure_digest(*args)
+    Digest::SHA1.hexdigest(args.flatten.join('--'))
+  end
+
+  def password_digest(password, salt)
+    digest = REST_AUTH_SITE_KEY
+    REST_AUTH_DIGEST_STRETCHES.times do
+      digest = secure_digest(digest, salt, password, REST_AUTH_SITE_KEY)
+    end
+    digest
+  end      
+
+  def make_fake_token
+    @fake_token_counter ||= 0
+    @fake_token_counter +=  1
+    Digest::SHA1.hexdigest(@fake_token_counter.to_s)
+  end
+
+  salts   = (1..20).map{ make_fake_token }
+  passwds = salts.map{ |salt| password_digest('monkey', salt) }
+%>
+
+owner:
+  id:                         1
+  email:                      <%= APP_CONFIG["owner"]["email"] %>
+  name:                       <%= APP_CONFIG["owner"]["name"] %>
+  salt:                       <%= APP_CONFIG["owner"]["salt"] %>
+  crypted_password:           <%= APP_CONFIG["owner"]["crypted_password"] %>
+  created_at:                 <%= 5.days.ago.to_s :db  %>
+  remember_token_expires_at:  
+  remember_token:             
+  activation_code:            
+  activated_at:               <%= 5.days.ago.to_s :db %>
+  state:                      active
+
 quentin:
-  id:                        1
+  id:                        11
 #  login:                     quentin
   email:                     quentin@example.com
-  salt:                      356a192b7913b04c54574d18c28d46e6395428ab # SHA1('0')
-  crypted_password:          d75386ba63f62bcab088361332a4a8d02c853074 # 'monkey'
+  name:                      quentin
+  salt:                      <%= salts[10]   %> # SHA1('10')
+  crypted_password:          <%= passwds[10] %> # 'monkey'
   created_at:                <%= 5.days.ago.to_s :db  %>
   remember_token_expires_at: <%= 1.days.from_now.to_s %>
   remember_token:            77de68daecd823babbb58edb1c8e14d7106e83bb
(略)       
 aaron:
-  id:                        2
+  id:                        12
 #  login:                     aaron
   email:                     aaron@example.com
-  salt:                      da4b9237bacccdf19c0760cab7aec4a8359010b0 # SHA1('1')
-  crypted_password:          c10cf1a334ae31f972ca0c23ff16175aecb00ea7 # 'monkey'
+  name:                      aaron
+  salt:                      <%= salts[11]   %> # SHA1('11')
+  crypted_password:          <%= passwds[11] %> # 'monkey'
   created_at:                <%= 1.days.ago.to_s :db %>
   remember_token_expires_at: 
   remember_token:            
(略)       
 old_password_holder:
-  id:                        3
+  id:                        13
 #  login:                     old_password_holder
   email:                     salty_dog@example.com
+  name:                      old_password_holder
   salt:                      7e3041ebc2fc05a40c60028e2c4901a81035d3cd
   crypted_password:          00742970dc9e6319f8019fd54864d3ea740f04b1 # test
   created_at:                <%= 1.days.ago.to_s :db %>
(略)       


で、rake spec回すと、failure帰ってきます。
spec/controllers/authenticated_system_spec.rbで、User.idに依存しているテストがあるから。
なんで、そこを修正。

#spec/controllers/authenticated_system_spec.rb

(略)       
     it 'forgets me' do    
       current_user.remember_me
       current_user.remember_token.should_not be_nil; current_user.remember_token_expires_at.should_not be_nil
-      User.find(1).remember_token.should_not be_nil; User.find(1).remember_token_expires_at.should_not be_nil
+      User.find(:first, :conditions => ["email like ?", "quentin@%"]).remember_token.should_not be_nil; User.find(:first, :conditions => ["email like ?", "quentin@%"]).remember_token_expires_at.should_not be_nil
       logout_killing_session!
-      User.find(1).remember_token.should     be_nil; User.find(1).remember_token_expires_at.should     be_nil
+      User.find(:first, :conditions => ["email like ?", "quentin@%"]).remember_token.should     be_nil; User.find(:first, :conditions => ["email like ?", "quentin@%"]).remember_token_expires_at.should     be_nil
     end
(略)       
     it 'forgets me' do    
       current_user.remember_me
       current_user.remember_token.should_not be_nil; current_user.remember_token_expires_at.should_not be_nil
-      User.find(1).remember_token.should_not be_nil; User.find(1).remember_token_expires_at.should_not be_nil
+      User.find(:first, :conditions => ["email like ?", "quentin@%"]).remember_token.should_not be_nil; User.find(:first, :conditions => ["email like ?", "quentin@%"]).remember_token_expires_at.should_not be_nil
       logout_keeping_session!
-      User.find(1).remember_token.should     be_nil; User.find(1).remember_token_expires_at.should     be_nil
+      User.find(:first, :conditions => ["email like ?", "quentin@%"]).remember_token.should     be_nil; User.find(:first, :conditions => ["email like ?", "quentin@%"]).remember_token_expires_at.should     be_nil
     end
(略)       

あまり、テストでショートハンドは使いたくない(ちょっとコダワリさんw)んで、find_by_emailではなく、:conditionsで積んでます。
まあ、結果コードが汚い気がしないでもないがwww


あと、お慰み程度に、初期ユーザが正常にテスト用フィクスチャに反映されているかをspec/models/user_spec.rbでテスト。

# spec/models/user_spec.rb

(略)
   it 'authenticates user' do
     User.authenticate('quentin@example.com', 'monkey').should == users(:quentin)
+    User.authenticate(APP_CONFIG["owner"]["email"], APP_CONFIG["owner"]["password"]).should == users(:owner)
   end
(略)


おk。
じゃあ、このフィクスチャを元に、初期データ用のマイグレーション、書きましょうか。

$ script/generate migration AddInisialDataToUser

で、マイグレーション・ファイルの修正。

# *数字*_add_initial_data_to_user.rb

require "active_record/fixtures"

class AddInisialDataToUser < ActiveRecord::Migration
  def self.up
    down

    directory = "spec/fixtures"
    Fixtures.create_fixtures(directory, "users")
  end

  def self.down
    User.delete_all
  end
end


...アレ?
でも、これ、なんか、危険因子を含んでいるような気がしてきたwww
う〜ん...なんて云うのか、な? 野生の勘?
本番環境に移行して、運用して、んで、更新しようとした時に、不具合が出そうな気がしてきた...


このやり方、マズいかも知れないwww


...まあ、いいやw
とりあえず、これで進めよう。