AngularJSとRuby on Railsで作るCRUDアプリ – (6)X-CSRF-Tokenについて、Jasmineによるユニットテストを考慮する

2014.04.13

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

以前の記事で、X-CSRFトークンをAjax送信することについて言及しました。
それについての説明の追加と、Jasmineによるユニットテストを実行した場合に
エラーにならない方法について記述します。

X-CSRFトークンについてと、Jasmineによるユニットテストの実行について

1.X-CSRFトークンについて

RailsでPOST送信を行う場合、CSRFトークンが必要になります。
デフォルトでは、application.html.erbに以下のタグがある場合、metaタグ内に
CSRFトークンが付与されるようです。

application.html.erb
<%= csrf_meta_tags %>

このため、以前の記事ではCSRFトークンを付与するため
AngularJSに以下のように記述し、metaタグからCSRFトークンを取得し
$httpProviderのheaderに設定していました。

controllers.js
whiskiesListApp.config(
    ["$httpProvider", 
        function($httpProvider) {
            $httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content');
        }
    ]
);

2.問題点

この方法はmetaタグ内よりCSRFトークンを取得しています。
その為、Jasmineによるユニットテストを実行すると、CSRFトークンが取得できないことにより
エラーとなっていました。(つまりテストが実行できない)

3.解決策

上記の問題点を解決するため、metaタグ内からCSRFトークンを検索し
取得できる場合はhttpProviderのheaderに設定するようにしました。

controllers.js
whiskiesListApp.config(
    ["$httpProvider", 
        function($httpProvider) {
            var meta = document.getElementsByTagName('meta');
            for (var item in meta) {
                if (meta[item].name == 'csrf-token') {
                    $httpProvider.defaults.headers.common['X-CSRF-Token'] = meta[item].content;
                    break;
                }
            }
        }
    ]
);

まとめ

以上により
・Jasmineによるユニットテスト実行時にはCSRFトークンは設定されず
・ブラウザより実行時にはCSRFトークンが設定されるようになり
テスト、ブラウザ処理とも稼動するようになりました。

尚、このソースはGitHubの以下に入れてあります。ソースを見たい方は参考にしてください。
AngularjsWhiskyList

参考記事
http://qiita.com/kt_Biz/items/21051cd586e057302559
http://penguinlab.jp/blog/post/2167