Browse Source

Merge pull request #12213 from jeremyharris/stringdata

Casting all integration test data to string
Mark Sch 7 years ago
parent
commit
f130611505

+ 31 - 1
src/TestSuite/IntegrationTestCase.php

@@ -605,7 +605,8 @@ abstract class IntegrationTestCase extends TestCase
             $props['input'] = $data;
         }
         if (!isset($props['input'])) {
-            $props['post'] = $this->_addTokens($tokenUrl, $data);
+            $data = $this->_addTokens($tokenUrl, $data);
+            $props['post'] = $this->_castToString($data);
         }
         $props['cookies'] = $this->_cookie;
 
@@ -661,6 +662,35 @@ abstract class IntegrationTestCase extends TestCase
     }
 
     /**
+     * Recursively casts all data to string as that is how data would be POSTed in
+     * the real world
+     *
+     * @param array $data POST data
+     * @return array
+     */
+    protected function _castToString($data)
+    {
+        foreach ($data as $key => $value) {
+            if (is_scalar($value)) {
+                $data[$key] = $value === false ? '0' : (string)$value;
+
+                continue;
+            }
+
+            if (is_array($value)) {
+                $looksLikeFile = isset($value['error']) && isset($value['tmp_name']) && isset($value['size']);
+                if ($looksLikeFile) {
+                    continue;
+                }
+
+                $data[$key] = $this->_castToString($value);
+            }
+        }
+
+        return $data;
+    }
+
+    /**
      * Creates a valid request url and parameter array more like Request::_url()
      *
      * @param string $url The URL

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

@@ -23,6 +23,7 @@ use Cake\Routing\Route\InflectedRoute;
 use Cake\TestSuite\IntegrationTestCase;
 use Cake\Test\Fixture\AssertIntegrationTestCase;
 use Cake\Utility\Security;
+use Zend\Diactoros\UploadedFile;
 
 /**
  * Self test of the IntegrationTestCase
@@ -68,6 +69,69 @@ class IntegrationTestCaseTest extends IntegrationTestCase
     }
 
     /**
+     * Tests that all data that used by the request is cast to strings
+     *
+     * @return void
+     */
+    public function testDataCastToString()
+    {
+        $data = [
+            'title' => 'Blog Post',
+            'status' => 1,
+            'published' => true,
+            'not_published' => false,
+            'comments' => [
+                [
+                    'body' => 'Comment',
+                    'status' => 1,
+                ]
+            ],
+            'file' => [
+                'tmp_name' => __FILE__,
+                'size' => 42,
+                'error' => 0,
+                'type' => 'text/plain',
+                'name' => 'Uploaded file'
+            ],
+            'pictures' => [
+                'name' => [
+                    ['file' => 'a-file.png'],
+                    ['file' => 'a-moose.png']
+                ],
+                'type' => [
+                    ['file' => 'image/png'],
+                    ['file' => 'image/jpg']
+                ],
+                'tmp_name' => [
+                    ['file' => __FILE__],
+                    ['file' => __FILE__]
+                ],
+                'error' => [
+                    ['file' => 0],
+                    ['file' => 0]
+                ],
+                'size' => [
+                    ['file' => 17188],
+                    ['file' => 2010]
+                ],
+            ],
+            'upload' => new UploadedFile(__FILE__, 42, 0)
+        ];
+        $request = $this->_buildRequest('/posts/add', 'POST', $data);
+        $this->assertInternalType('string', $request['post']['status']);
+        $this->assertInternalType('string', $request['post']['published']);
+        $this->assertSame('0', $request['post']['not_published']);
+        $this->assertInternalType('string', $request['post']['comments'][0]['status']);
+        $this->assertInternalType('integer', $request['post']['file']['error']);
+        $this->assertInternalType('integer', $request['post']['file']['size']);
+        $this->assertInternalType('integer', $request['post']['pictures']['error'][0]['file']);
+        $this->assertInternalType('integer', $request['post']['pictures']['error'][1]['file']);
+        $this->assertInternalType('integer', $request['post']['pictures']['size'][0]['file']);
+        $this->assertInternalType('integer', $request['post']['pictures']['size'][1]['file']);
+        $this->assertInstanceOf(UploadedFile::class, $request['post']['upload']);
+    }
+
+    /**
      * Test building a request.
      *
      * @return void