Browse Source

Merge pull request #13483 from DBnR1/enhancement-test-unlocked-fields-13071

Allow testing action with unlocked fields
Mark Story 6 years ago
parent
commit
eca9904115

+ 24 - 2
src/TestSuite/IntegrationTestTrait.php

@@ -195,6 +195,13 @@ trait IntegrationTestTrait
     protected $_cookieEncryptionKey;
 
     /**
+     * List of fields that are excluded from field validation.
+     *
+     * @var string[]
+     */
+    protected $_unlockedFields = [];
+
+    /**
      * Auto-detect if the HTTP middleware stack should be used.
      *
      * @before
@@ -271,6 +278,17 @@ trait IntegrationTestTrait
     }
 
     /**
+     * Set list of fields that are excluded from field validation.
+     *
+     * @param string[] $unlockedFields List of fields that are excluded from field validation.
+     * @return void
+     */
+    public function setUnlockedFields(array $unlockedFields = [])
+    {
+        $this->_unlockedFields = $unlockedFields;
+    }
+
+    /**
      * Calling this method will add a CSRF token to the request.
      *
      * Both the POST data and cookie will be populated when this option
@@ -671,10 +689,14 @@ trait IntegrationTestTrait
     protected function _addTokens($url, $data)
     {
         if ($this->_securityToken === true) {
+            $fields = array_diff_key($data, array_flip($this->_unlockedFields));
+
             $keys = array_map(function ($field) {
                 return preg_replace('/(\.\d+)+$/', '', $field);
-            }, array_keys(Hash::flatten($data)));
-            $tokenData = $this->_buildFieldToken($url, array_unique($keys));
+            }, array_keys(Hash::flatten($fields)));
+
+            $tokenData = $this->_buildFieldToken($url, array_unique($keys), $this->_unlockedFields);
+
             $data['_Token'] = $tokenData;
             $data['_Token']['debug'] = 'SecurityComponent debug data would be added here';
         }

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

@@ -864,6 +864,49 @@ class IntegrationTestTraitTest extends IntegrationTestCase
     }
 
     /**
+     * Test posting to a secured form action with unlocked fields
+     *
+     * @return void
+     */
+    public function testPostSecuredFormUnlockedFieldsFails()
+    {
+        $this->enableSecurityToken();
+        $data = [
+            'title' => 'New post',
+            'comments' => [
+                ['comment' => 'A new comment']
+            ],
+            'tags' => ['_ids' => [1, 2, 3, 4]],
+            'some_unlocked_field' => 'Unlocked data'
+        ];
+        $this->post('/posts/securePost', $data);
+        $this->assertResponseCode(400);
+        $this->assertResponseContains('Invalid security debug token.');
+    }
+
+    /**
+     * Test posting to a secured form action with unlocked fields
+     *
+     * @return void
+     */
+    public function testPostSecuredFormUnlockedFieldsWithSet()
+    {
+        $this->enableSecurityToken();
+        $data = [
+            'title' => 'New post',
+            'comments' => [
+                ['comment' => 'A new comment']
+            ],
+            'tags' => ['_ids' => [1, 2, 3, 4]],
+            'some_unlocked_field' => 'Unlocked data'
+        ];
+        $this->setUnlockedFields(['some_unlocked_field']);
+        $this->post('/posts/securePost', $data);
+        $this->assertResponseOk();
+        $this->assertResponseContains('Request was accepted');
+    }
+
+    /**
      * Test posting to a secured form action.
      *
      * @return void

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

@@ -45,6 +45,8 @@ class PostsController extends AppController
         if ($this->request->getParam('action') !== 'securePost') {
             $this->getEventManager()->off($this->Security);
         }
+
+        $this->Security->setConfig('unlockedFields', ['some_unlocked_field']);
     }
 
     /**