Browse Source

Added assertions for flash messages

Jeremy Harris 7 years ago
parent
commit
88417f86c2

+ 107 - 0
src/TestSuite/Constraint/Session/FlashParamEquals.php

@@ -0,0 +1,107 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @since         3.7.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\TestSuite\Constraint\Session;
+
+use PHPUnit\Framework\AssertionFailedError;
+use PHPUnit\Framework\Constraint\Constraint;
+
+/**
+ * FlashParamEquals
+ *
+ * @internal
+ */
+class FlashParamEquals extends Constraint
+{
+
+    /**
+     * @var \Cake\Http\Session
+     */
+    protected $session;
+
+    /**
+     * @var string
+     */
+    protected $key;
+
+    /**
+     * @var string
+     */
+    protected $param;
+
+    /**
+     * @var int|null
+     */
+    protected $at;
+
+    /**
+     * Constructor
+     *
+     * @param \Cake\Http\Session $session Session
+     * @param string $key Flash key
+     * @param string $param Param to check
+     * @param int $at Expected index
+     */
+    public function __construct($session, $key, $param, $at = null)
+    {
+        parent::__construct();
+
+        if (!$session) {
+            throw new AssertionFailedError('There is no stored session data. Perhaps you need to run a request?');
+        }
+
+        $this->session = $session;
+        $this->key = $key;
+        $this->param = $param;
+        $this->at = $at;
+    }
+
+    /**
+     * Compare to flash message(s)
+     *
+     * @param mixed $other Value to compare with
+     * @return bool
+     */
+    public function matches($other)
+    {
+        $messages = (array)$this->session->read('Flash.' . $this->key);
+        if ($this->at) {
+            $messages = [$this->session->read('Flash.' . $this->key . '.' . $this->at)];
+        }
+
+        foreach ($messages as $message) {
+            if (!isset($message[$this->param])) {
+                continue;
+            }
+            if ($message[$this->param] === $other) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Assertion message string
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        if ($this->at !== null) {
+            return sprintf('was in \'%s\' %s #%d', $this->key, $this->param, $this->at);
+        }
+
+        return sprintf('was in \'%s\' %s', $this->key, $this->param);
+    }
+}

+ 55 - 0
src/TestSuite/IntegrationTestTrait.php

@@ -42,6 +42,7 @@ use Cake\TestSuite\Constraint\Response\StatusError;
 use Cake\TestSuite\Constraint\Response\StatusFailure;
 use Cake\TestSuite\Constraint\Response\StatusOk;
 use Cake\TestSuite\Constraint\Response\StatusSuccess;
+use Cake\TestSuite\Constraint\Session\FlashParamEquals;
 use Cake\TestSuite\Constraint\Session\SessionEquals;
 use Cake\TestSuite\Constraint\View\LayoutFileEquals;
 use Cake\TestSuite\Constraint\View\TemplateFileEquals;
@@ -1008,6 +1009,60 @@ trait IntegrationTestTrait
     }
 
     /**
+     * Asserts a flash message was set
+     *
+     * @param string $expected Expected message
+     * @param string $key Flash key
+     * @param string $message Assertion failure message
+     * @return void
+     */
+    public function assertFlashMessage($expected, $key = 'flash', $message = '')
+    {
+        $this->assertThat($expected, new FlashParamEquals($this->_requestSession, $key, 'message'), $message);
+    }
+
+    /**
+     * Asserts a flash message was set at a certain index
+     *
+     * @param int $at Flash index
+     * @param string $expected Expected message
+     * @param string $key Flash key
+     * @param string $message Assertion failure message
+     * @return void
+     */
+    public function assertFlashMessageAt($at, $expected, $key = 'flash', $message = '')
+    {
+        $this->assertThat($expected, new FlashParamEquals($this->_requestSession, $key, 'message', $at), $message);
+    }
+
+    /**
+     * Asserts a flash element was set
+     *
+     * @param string $expected Expected element name
+     * @param string $key Flash key
+     * @param string $message Assertion failure message
+     * @return void
+     */
+    public function assertFlashElement($expected, $key = 'flash', $message = '')
+    {
+        $this->assertThat($expected, new FlashParamEquals($this->_requestSession, $key, 'element'), $message);
+    }
+
+    /**
+     * Asserts a flash element was set at a certain index
+     *
+     * @param int $at Flash index
+     * @param string $expected Expected element name
+     * @param string $key Flash key
+     * @param string $message Assertion failure message
+     * @return void
+     */
+    public function assertFlashElementAt($at, $expected, $key = 'flash', $message = '')
+    {
+        $this->assertThat($expected, new FlashParamEquals($this->_requestSession, $key, 'element', $at), $message);
+    }
+
+    /**
      * Asserts cookie values
      *
      * @param string $expected The expected contents.

+ 38 - 0
tests/TestCase/TestSuite/IntegrationTestTraitTest.php

@@ -1155,6 +1155,36 @@ class IntegrationTestTraitTest extends IntegrationTestCase
     }
 
     /**
+     * Tests flash assertions
+     *
+     * @return void
+     * @throws \PHPUnit\Exception
+     */
+    public function testAssertFlashMessage()
+    {
+        $this->get('/posts/stacked_flash');
+
+        $this->assertFlashElement('Flash/error');
+        $this->assertFlashElement('Flash/success', 'custom');
+
+        $this->assertFlashMessage('Error 1');
+        $this->assertFlashMessageAt(0, 'Error 1');
+        $this->assertFlashElementAt(0, 'Flash/error');
+
+        $this->assertFlashMessage('Error 2');
+        $this->assertFlashMessageAt(1, 'Error 2');
+        $this->assertFlashElementAt(1, 'Flash/error');
+
+        $this->assertFlashMessage('Success 1', 'custom');
+        $this->assertFlashMessageAt(0, 'Success 1', 'custom');
+        $this->assertFlashElementAt(0, 'Flash/success', 'custom');
+
+        $this->assertFlashMessage('Success 2', 'custom');
+        $this->assertFlashMessageAt(1, 'Success 2', 'custom');
+        $this->assertFlashElementAt(1, 'Flash/success', 'custom');
+    }
+
+    /**
      * tests failure messages for assertions
      *
      * @param string $assertion Assertion method
@@ -1210,6 +1240,14 @@ class IntegrationTestTraitTest extends IntegrationTestCase
             'assertResponseSuccess' => ['assertResponseSuccess', 'Failed asserting that 404 is between 200 and 308.', '/posts/missing'],
             'assertSession' => ['assertSession', 'Failed asserting that \'test\' is in session path \'Missing.path\'.', '/posts/index', 'test', 'Missing.path'],
             'assertTemplate' => ['assertTemplate', 'Failed asserting that \'custom_template\' equals template file ' . $templateDir . 'Posts' . DS . 'index.ctp.', '/posts/index', 'custom_template'],
+            'assertFlashMessage' => ['assertFlashMessage', 'Failed asserting that \'missing\' was in \'flash\' message.', '/posts/index', 'missing'],
+            'assertFlashMessageWithKey' => ['assertFlashMessage', 'Failed asserting that \'missing\' was in \'auth\' message.', '/posts/index', 'missing', 'auth'],
+            'assertFlashMessageAt' => ['assertFlashMessageAt', 'Failed asserting that \'missing\' was in \'flash\' message #0.', '/posts/index', 0, 'missing'],
+            'assertFlashMessageAtWithKey' => ['assertFlashMessageAt', 'Failed asserting that \'missing\' was in \'auth\' message #0.', '/posts/index', 0, 'missing', 'auth'],
+            'assertFlashElement' => ['assertFlashElement', 'Failed asserting that \'missing\' was in \'flash\' element.', '/posts/index', 'missing'],
+            'assertFlashElementWithKey' => ['assertFlashElement', 'Failed asserting that \'missing\' was in \'auth\' element.', '/posts/index', 'missing', 'auth'],
+            'assertFlashElementAt' => ['assertFlashElementAt', 'Failed asserting that \'missing\' was in \'flash\' element #0.', '/posts/index', 0, 'missing'],
+            'assertFlashElementAtWithKey' => ['assertFlashElementAt', 'Failed asserting that \'missing\' was in \'auth\' element #0.', '/posts/index', 0, 'missing', 'auth'],
         ];
     }
 

+ 10 - 0
tests/test_app/TestApp/Controller/PostsController.php

@@ -106,4 +106,14 @@ class PostsController extends AppController
     {
         return $this->getResponse()->withStringBody('');
     }
+
+    public function stacked_flash()
+    {
+        $this->Flash->error('Error 1');
+        $this->Flash->error('Error 2');
+        $this->Flash->success('Success 1', ['key' => 'custom']);
+        $this->Flash->success('Success 2', ['key' => 'custom']);
+
+        return $this->getResponse()->withStringBody('');
+    }
 }