CakeTestCaseでtestActionを実行すると別のページにリダイレクトされちゃう問題

ControllerのテストをCakeTestCase#testActionで書こうと思ったのですが、
テストするactionの中でredirectのところを通ると本当にリダイレクトされてしまいます。

Google先生に聞いたところ、下記の記事が。

cakephp1.2でControllerをテストする際のredirectとcakeErrorアクションの取扱い

この記事ではrunkitという仕組みを使って、動的に定義を書き換えているようだけど、
今回は下記な感じで app ディレクトリ内だけで対応が済む感じにしてみました。

(1) app/webroot/test.php の 98行目付近に追記

require_once CAKE_TESTS_LIB . 'test_manager.php';

の後ろ辺りに

Configure::write('CAKE_ENV', 'test');

と定義。

(2) app/app_controller.php に下記を追記。

function redirect($url, $status = null, $exit = true) {
  // 「テスト実行時に本当にリダイレクトしちゃう」問題への対処
  if(Configure::read('CAKE_ENV') == 'test') {
    $this->set('function', 'redirect');
    $this->set('url', $url);
    $this->set('status', $status);
    $this->set('exit', $exit);
    $this->render(null, null, TESTS . DS . 'views' . DS . 'redirect.ctp');
  } else {
    parent::redirect($url, $status, $exit);
  }
}


(3) app/tests/views/redirect.ctp というファイルを下記の内容で作成。

<h2>redirect</h2>
<div>session flash : <?php $session->flash(); ?>
<?php if (isset($url) &&is_array($url)) : ?>
<?php foreach ($url as $k => $v) : ?>
<div>url : <?php echo '[', $k, '] : ', $v; ?></div>
<?php endforeach; ?>
<?php else: ?>
<div>url : <?php echo $url ? $url : ''; ?></div>
<?php endif; ?>
<div>status : <?php echo $status ? $status : ''; ?></div>
<div>exit : <?php echo $exit ? $exit : ''; ?></div>

以上の設定で、テスト実行中だけredirectの挙動を変えることができます。

テスト環境は別のDBを使う、という設定

テスト実行時はそれまで作ってたデータが消えてしまったりするのが嫌ですよね。

App::import('Model', 'User');
class UserTest extends User {
  $this->useDbConfig = 'test';
}  

とか定義して、このUserTestクラスをつかってUnitテストを書いたりしてみたんですが、
Userクラス内のhasManyとかbelongsToなどの関連データがtestじゃなくてdefaultの環境から
selectされちゃって行き詰まってしまいました。。。

runkitというやつで動的に定義をオーバーライドすることも考えましたが、
そこまですることでもないな、ということで対応は以下になりました。

app/webroot/test.php の 98行目付近

require_once CAKE_TESTS_LIB . 'test_manager.php';

の後ろ辺りに

Configure::write('CAKE_ENV', 'test');

と定義。

加えて app/app_models.php に下記のコンストラクタ定義を追加。

function __construct($id = false, $table = null, $ds = null) {
  if(Configure::read('CAKE_ENV')) $this->useDbConfig = Configure::read('CAKE_ENV');
  parent::__construct($id, $table, $ds);
}

Railsに比べ、サーバの構成とか、フォルダの構成とかが柔軟に変えられるのがCakePHPのいいところですね。

参考にした記事:
CakePHP 環境に応じてDBの設定を変える http://www.1x1.jp/blog/2006/09/cakephp_db_config.html
テスト環境でのDBの切り替え方 http://cakephp.blog16.jp/index.php/2008/07/02/p28

Xdebugを入れてCode Coverageを計算したらSegmentation fault発生

MacPortsでPHP5を入れた環境でXdebugを有効にしてCode Coverageを計算しようとしたら、真っ白い画面が表示されてしまった。ログをみても「Segmentation fault」としか出力されていない。。。
PHPはこういうのがあるんだよなー、とため息をつきながら調査開始。


結局Xdebugの不具合でした。
http://bugs.xdebug.org/view.php?id=422


MacPortsでインストールしたxdebug2.0.4を捨てて

sudo pecl install xdebug

でxdebug2.0.5を入れ直したところ正常に動くようになりましたとさ。めでたし、めでたし。

Rails2.2.2でアプリを日本語化(i18n_generators, i18n_label)

Rails2.2.2で作ったアプリのエラーメッセージやlabelメソッドの出力を日本語化したかったので下記の手順で実行してみた。

(1)翻訳ファイル(config/locales/*)を自動生成してくれるgeneratorをインストール

sudo gem install amatsuda-i18n_generators
cd RAILS_ROOT
ruby script/generate i18n ja

(2)labelメソッドに翻訳機能をもたせてくれるpluginをインストール

cd ~/Downloads
wget http://d.hatena.ne.jp/babydaemons/files/i18n_label.zip
cd RAILS_ROOT
unzip ~/Downloads/i18n_label.zip

大部分が自動で日本語化された。
あとはコツコツとconfig/locales以下のymlファイルで翻訳活動をしていこう。

Rails2系アプリの管理機能を10分で作る方法

Rails 2.2.2で作ったWEBアプリの管理サイトを/admin/で始まるURLで作る手順をまとめました。
例えば「カテゴリー」(Category name:string position:integer)というモデルがあって、
そのマスターデータを管理したいという前提で。


(1)scaffoldをgenerateする

ruby script/generate rspec_scaffold Admin::Category name:string position:integer

って感じのコマンドでスケルトンを作ります。

  • nameとかpositionとかは編集対象となるフィールドを列挙。
  • rspecを使っていない場合は「rspec_scaffold」じゃなくて「scaffold」


(2)不要なファイルの削除
前の手順で「Admin::Category」を対象とした migration やら model やらが生成されます。
これは既存の「Category」を対象にしたいのでmodel関連の余計なファイルは削除します。

ruby script/destroy rspec_model Admin::Category


(3)変数名の置換

  • 「Admin::Category.」を「Category.」に
  • 「Admin::Category,」を「Category,」に
  • 「Admin::Category 」を「Category 」に
  • 「@admin_categories」を「@categories」に

します。コマンドで実行すると以下。
(grep の l オプションはファイル名のみ出力。v オプションは該当するファイルを除外。の意)。

grep -lr "Admin::Category." * | grep -v svn | grep -v back | grep -v log \
 | xargs sed -i.back "s/Admin::Category\./Category\./g"
grep -lr "Admin::Category," * | grep -v svn | grep -v back | grep -v log \
 | xargs sed -i.back "s/Admin::Category,/Category,/g"
grep -lr "Admin::Category " * | grep -v svn | grep -v back | grep -v log \
 | xargs sed -i.back "s/Admin::Category /Category /g"
grep -lr @admin_categories * | grep -v svn | grep -v back | grep -v log \
 | xargs sed -i.back "s/@admin_categories/@categories/g"


(4)URL関連のヘルパー名を置換

  • 「category_path」を「admin_category_path」に
  • 「categories_path」を「admin_categories_path」に
  • 「category_url」を「admin_category_url」に
  • 「categories_url」を「admin_categories_url」に

します。コマンドは以下。

grep -lr category_path * | grep -v svn | grep -v back | grep -v log \
 | xargs sed -i.back 's/category_path/admin_category_path/g'
grep -lr categories_path * | grep -v svn | grep -v back | grep -v log \
 | xargs sed -i.back 's/categories_path/admin_categories_path/g'
grep -lr category_url * | grep -v svn | grep -v back | grep -v log \
 | xargs sed -i.back 's/category_url/admin_category_url/g'
grep -lr categories_url * | grep -v svn | grep -v back | grep -v log \
 | xargs sed -i.back 's/categories_url/admin_categories_url/g'


(5)link_toの引数を書き換え

  • 「link_to 'Show', category」を「link_to 'Show', admin_category_path(category)」に
  • 「link_to 'Show', @category」を「link_to 'Show', admin_category_path(@category)」に
  • 「link_to 'Destroy', category」を「link_to 'Destroy', admin_category_path(category)」に
  • 「link_to 'Destroy', @category」を「link_to 'Destroy', admin_category_path(@category)」に

それぞれ置換。コマンドは以下。

grep -lr link_to * | grep -v svn | grep -v back | grep -v log \
 | xargs sed -i.back "s/link_to 'Show', category/link_to 'Show', admin_category_path(category)/g"
grep -lr link_to * | grep -v svn | grep -v back | grep -v log \
 | xargs sed -i.back "s/link_to 'Show', @category/link_to 'Show', admin_category_path(@category)/g"
grep -lr link_to * | grep -v svn | grep -v back | grep -v log \
 | xargs sed -i.back "s/link_to 'Destroy', category/link_to 'Destroy', admin_category_path(category)/g"
grep -lr link_to * | grep -v svn | grep -v back | grep -v log \
 | xargs sed -i.back "s/link_to 'Destroy', @category/link_to 'Destroy', admin_category_path(@category)/g"


(6)その他の置換

  • 「/admin_categories」を「/admin/categories」に
  • 「:controller => "admin_categories"」を「:controller => "admin/categories"」に
  • 「redirect_to(@category)」を「redirect_to(admin_category_url(@category))」に
  • 「assigns[:admin_categories]」を「assigns[:categories]」に

します。コマンドは以下。

grep -lr /admin_categories * | grep -v svn | grep -v back | grep -v log \
 | xargs sed -i.back "s/\/admin_categories/\/admin\/categories/g"
grep -lr ':controller => "admin_categories"' * | grep -v svn | grep -v back | grep -v log \
 | xargs sed -i.back "s/:controller => \"admin_categories\"/:controller => \"admin\/categories\"/g"
grep -lr "redirect_to(@category)" * | grep -v svn | grep -v back | grep -v log \
 | xargs sed -i.back "s/redirect_to(@category)/redirect_to(admin_category_url(@category))/g"
grep -lr ":admin_categories" * | grep -v svn | grep -v back | grep -v log \
 | xargs sed -i.back "s/assigns\[:admin_categories\]/assigns\[:categories\]/g"


(7)form_forの引数を書き換え

  • new.html.erb の「form_for(@category)」を「form_for(@category, :url=>admin_categories_path)」に
  • edit.html.erb の「form_for(@category)」を「form_for(@category, :url=>admin_category_path(@category))」に

それぞれ書き換えます。


(8)routes.rbの編集

  map.resources :categories

  map.namespace :admin do |admin|
    admin.resources :categories
  end

にします。

RedHat EL4にRedmineをインストール

RedHat EL4にRedmineをインストールする、というお仕事をしたので、作業ログを公開。
各種ライブラリはrpmで入れて、rubyやらgemやらはソースからビルドした。

(1)Railsの実行で必要になるライブラリを入れる

su
wget ftp://mirror.switch.ch/pool/3/mirror/centos/4.8/os/i386/CentOS/RPMS/libtermcap-devel-2.0.8-39.i386.rpm
rpm -ivh libtermcap-devel-2.0.8-39.i386.rpm
wget ftp://ftp.pbone.net/mirror/atrpms.net/el4-i386/atrpms/testing/readline-devel-4.3-11.99_2.0.1.el4.i386.rpm
rpm -ivh readline-devel-4.3-11.99_2.0.1.el4.i386.rpm 

(2)rubyを入れる

cd /usr/local/src/
wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p174.tar.gz
gtar -zxvf ruby-1.8.7-p174.tar.gz 
cd ruby-1.8.7-p174
./configure --with-install-readline
make
make install

(3)rubygemsを入れる

cd /usr/local/src
wget http://rubyforge.org/frs/download.php/60718/rubygems-1.3.5.tgz
gtar -zxvf rubygems-1.3.5.tgz
cd rubygems-1.3.5
ruby setup.rb

(4)railsを入れる

gem install rails -v=2.1.2

(5)redmineをダウンロード&初期設定

cd /usr/local/src
wget http://rubyforge.org/frs/download.php/63583/redmine-0.8.5.tar.gz
cd /var/www
gtar -zxvf /usr/local/src/redmine-0.8.5.tar.gz
cd /var/www/redmine-0.8.5
cp config/database.yml.sample config/database.yml
rake db:create RAILS_ENV=production
rake db:migrate RAILS_ENV=production

(6)apache連携モジュール mod_rails(passenger) を入れる

gem install passenger
passenger-install-apache2-module

(7)apacheのDigest認証の準備

cd /var/www/redmine-0.8.5/conf
htdigest -c digest RELM_NAME USER_NAME
※ パスワードを登録

(8)apacheの設定ファイルに以下を記述

LoadModule passenger_module /usr/local/lib/ruby/gems/1.8/gems/passenger-2.2.5/ext/apache2/mod_passenger.so
PassengerRoot /usr/local/lib/ruby/gems/1.8/gems/passenger-2.2.5
PassengerRuby /usr/local/bin/ruby

RailsAllowModRewrite on
RailsMaxPoolSize 4
RailsPoolIdleTime 30
PassengerEnabled off


  ServerName ドメイン名
  DocumentRoot /var/www/redmine-0.8.5/public
  AddDefaultCharset UTF-8
  RailsEnv production
  RailsBaseURI /
  RailsAllowModRewrite off
  PassengerEnabled on
  
   Options FollowSymLinks
   AllowOverride All
   Order allow,deny
   Allow from all
  
  
   AuthType Digest
   AuthName RELM_NAME
   AuthDigestProvider file
   AuthUserFile	/var/www/redmine-0.8.5/config/digest
   Require valid-user
  

(9)apache再起動

/etc/rc.d/init.d/httpd restart

(10)動作確認
ドメイン名」にブラウザでアクセスする。
redmineの初期アカウントはid, passwordどちらも「admin」

RedHat EL4にrpmでSVNをインストール

yumで管理した方がいいのでは?という疑問はおいといて。
RedHat EL4 にrpmSVNをインストールする、という作業をしたので手順を公開。

su
cd /usr/local/src
wget ftp://mirror.switch.ch/pool/3/mirror/centos/4.7/os/x86_64/CentOS/RPMS/apr-0.9.4-24.9.i386.rpm
rpm -ivh apr-0.9.4-24.9.i386.rpm 
wget ftp://mirror.switch.ch/pool/3/mirror/centos/4.8/os/i386/CentOS/RPMS/apr-util-0.9.4-22.el4.i386.rpm
rpm -ivh apr-util-0.9.4-22.el4.i386.rpm 
wget ftp://ftp.pbone.net/mirror/atrpms.net/el4-i386/atrpms/stable/neon-0.24.7-5.99_3.el4.at.i386.rpm
rpm -ivh neon-0.24.7-5.99_3.el4.at.i386.rpm 
wget ftp://ftp.pbone.net/mirror/ftp.pramberger.at/systems/linux/contrib/rhel4/noarch/perl-URI-1.35-2.el4.pp.noarch.rpm
rpm -ivh perl-URI-1.35-2.el4.pp.noarch.rpm 
wget ftp://ftp.univie.ac.at/systems/linux/dag/redhat/el4/en/i386/RPMS.dag/subversion-1.4.4-0.1.el4.rf.i386.rpm
rpm -ivh subversion-1.4.4-0.1.el4.rf.i386.rpm 

※ 役に立ったサイト
RPM Search superkaramba
http://rpm.pbone.net/index.php3?stat=3&search=superkaramba&srodzaj=3