Browse Source

Keep CSRF tokens consistent across all requests in a test case.

Keep the CSRF token consistent across all the requests in a single test
case method. This saves regenerating the token and even lets people
pre-configure the token if they really want to.

Refs #7828
Mark Story 10 years ago
parent
commit
cf833c7843

+ 4 - 5
src/TestSuite/IntegrationTestCase.php

@@ -430,12 +430,11 @@ abstract class IntegrationTestCase extends TestCase
         }
 
         if ($this->_csrfToken === true) {
-            $csrfToken = Text::uuid();
-            if (!isset($data['_csrfToken'])) {
-                $data['_csrfToken'] = $csrfToken;
-            }
             if (!isset($this->_cookie['csrfToken'])) {
-                $this->_cookie['csrfToken'] = $csrfToken;
+                $this->_cookie['csrfToken'] = Text::uuid();
+            }
+            if (!isset($data['_csrfToken'])) {
+                $data['_csrfToken'] = $this->_cookie['csrfToken'];
             }
         }
         return $data;

+ 33 - 0
tests/TestCase/TestSuite/IntegrationTestCaseTest.php

@@ -98,6 +98,39 @@ class IntegrationTestCaseTest extends IntegrationTestCase
     }
 
     /**
+     * Test multiple actions using CSRF tokens don't fail
+     *
+     * @return void
+     */
+    public function testEnableCsrfMultipleRequests()
+    {
+        $this->enableCsrfToken();
+        $first = $this->_buildRequest('/tasks/add', 'POST', ['title' => 'First post']);
+        $second = $this->_buildRequest('/tasks/add', 'POST', ['title' => 'Second post']);
+        $this->assertSame($first->cookies['csrfToken'], $second->data['_csrfToken'], 'Csrf token should match cookie');
+        $this->assertSame(
+            $first->data['_csrfToken'],
+            $second->data['_csrfToken'],
+            'Tokens should be consistent per test method'
+        );
+    }
+
+    /**
+     * Test pre-determined CSRF tokens.
+     *
+     * @return void
+     */
+    public function testEnableCsrfPredeterminedCookie()
+    {
+        $this->enableCsrfToken();
+        $value = 'I am a teapot';
+        $this->cookie('csrfToken', $value);
+        $request = $this->_buildRequest('/tasks/add', 'POST', ['title' => 'First post']);
+        $this->assertSame($value, $request->cookies['csrfToken'], 'Csrf token should match cookie');
+        $this->assertSame($value, $request->data['_csrfToken'], 'Tokens should match');
+    }
+
+    /**
      * Test building a request, with query parameters
      *
      * @return void