ITの隊長のブログ

ITの隊長のブログです。Rubyを使って仕事しています。最近も色々やっているお(^ω^ = ^ω^)

【CakePHP3.x】AuthがかかったController::Actionをテストしようとしたらハマった

スポンサードリンク

ログ残し。

qiita.com

ここを参考にテストを実行する。

<?php
//...
    private function setAuthSession()
    {
        $this->session([
            'Auth' => [
                'id' => 1,
                'email' => 'xxx@gmail.com',
                'password' => 'Lorem ipsum dolor sit amet',
                'created' => '2017-01-31 14:43:15',
                'modified' => '2017-01-31 14:43:15'
            ]
        ]);
    }

    public function testLoginRequiredPageNotAccess()
    {
        $this->get('/contact/login-required');
        $this->assertRedirect(['controller' => 'users', 'action' => 'login']);
    }

    /**
     * Test contact pre register
     *
     * @return void
     */
    public function testLoginRequiredPageAccess()
    {
        $this->setAuthSession();
        $postData = ['test'];
        $this->post('/contact/login-required', $postData);
        $response = json_decode($this->_response->body(), true);
    }
// ...

よーし、これを実行すれば。。。と思ったら失敗。testLoginReequiredPageNotAccess()は失敗してもいいけど、その下のメソッドは失敗しちゃ困る。なぁーぜぇー?

これだけで1時間程潰してしまったが、AuthComponentを読んでみたらわかった。

<?php
// ...
class AuthComponent extends Component

    //...
    public function authCheck(Event $event)
    {
        if ($this->_config['checkAuthIn'] !== $event->name()) {
            return null;
        }

        /* @var \Cake\Controller\Controller $controller */
        $controller = $event->subject();

        // ...

        $isLoginAction = $this->_isLoginAction($controller); // ここがfalse

        if (!$this->_getUser()) { // ここがfalse
            if ($isLoginAction) { // ここもfalse
                return null; // 未ログインで返り値
            }
            $result = $this->_unauthenticated($controller);
            if ($result instanceof Response) {
                $event->stopPropagation();
            }

            return $result;
        }
        // ...
    }
// ...

省略しているが、$isLoginActionは「ログインページへのアクセスなら~」をチェックしているので、今回は関係ない(ログインページのテストではないので)。

ということは、$this->_getUser()でfalseが返ってくるのが困るってことだ。こいつの中を覗く。

<?php
// ...
class AuthComponent extends Component
{
    // ...
    public function user($key = null)
    {
        $user = $this->storage()->read();
        if (!$user) {
            return null;
        }

        if ($key === null) {
            return $user;
        }

        return Hash::get($user, $key);
    }
    // ...

this->storage()->read()のところで、セッションから値を取得しているようだ。要するにログインしているとAuthの名前をkeyとしてセッションに保存しているはずなので、それが取れていないということである。

うーん? 何故?

(°ω°・・・・( ゚д゚)ハッ!

思い出しました。

このプロジェクトではログインフォームを2つ用意していて、それぞれ管理者用とユーザー用で分けていました。

そのとき、セッションのkeyの値が被るとおかしくなるとCakePHP2.xから知っていたので、Auth keyをそれぞれAuth.AdminAuth.Userとしていました。

ということは

<?php
    // ...
    private function setAuthSession()
    {
        $this->session([
            'Auth.User' => [ // ここを変更
                'id' => 1,
                'email' => 'xxx@gmail.com',
                'password' => 'Lorem ipsum dolor sit amet',
                'created' => '2017-01-31 14:43:15',
                'modified' => '2017-01-31 14:43:15'
            ]
        ]);
    }
    // ...

セッションのkeyを変更してみて、テストを実行してみると。

うまくいきましたぁー!ヾ(´∀`)ノキャッキャ

はぁ...先週の1時間。