responds_to_parentをassertするassert_select_parent

responds_to_parentAjax風のファイルアップロードを実現するためのRailsプラグインです。responds_to_parentによって生成されるレスポンスは特異なJavaScriptを含むため(後述)、専用のselector assertionを書いてパッチを送ったところ採用されましたので、ここでも使い方を説明します。

responds_to_parentの仕組み

まずresponds_to_parentの仕組みを簡単に説明します。ファイルはXMLHttpRequestでは送れないので必ずformでsubmitする必要があるのですが、普通にsubmitすると画面が遷移してしまいます。そこでformのtargetを隠されたiframeにすることで画面遷移を抑制します(レスポンスはiframe内にレンダリングされます)。そしてiframe内で、”親ウィンドウのコンテキストでeval()を実行するスクリプト”を実行します(親ウィンドウというのはファイルをアップロードするformのあるウィンドウ)。こうすることによって親ウィンドウを画面遷移させずファイルをアップロードし、任意のJavaScriptを実行することが可能になります。

詳しくは『ずっと君のターン - 雨。雷が鳴ってますな』などを参照してください。

assert_select_parent

このようにresponds_to_parentの吐くレスポンスは特別なので、正確にテストを書くにはresponds_to_parentの実装を知っている必要があります。その手間を省き、assert_select_rjsなどの一般的なassertionを利用可能にするのがassert_select_parentです。

assert_select_parentはiframe向けのレスポンスを、普通に親ウィンドウ向けに生成されたレスポンスに見えるように変換します。使い方はassert_select_rjsに似ています。
例:

assert_select_parent do
  assert_select_rjs :replace, "foo" do
    assert_select "li", bar
  end
end

assert_select_rjsの代わりに、RJSのassertionコレクションのARTSを使ってもいいですね。

assert_select_parentはresponds_to_parentのsvnリポジトリにチェックインされましたので、普通にresponds_to_parentをインストールして使ってください。