19d544b3c407fac62988258452764b4a5822d3a5
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Database / PreparedStatementTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Database;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 /**
18 * Test case
19 */
20 class PreparedStatementTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
21 {
22 /**
23 * @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Database\DatabaseConnection
24 */
25 protected $databaseStub;
26
27 /**
28 * Create a new database mock object for every test
29 * and backup the original global database object.
30 *
31 * @return void
32 */
33 protected function setUp()
34 {
35 $this->databaseStub = $this->setUpAndReturnDatabaseStub();
36 }
37
38 //////////////////////
39 // Utility functions
40 //////////////////////
41 /**
42 * Set up the stub to be able to get the result of the prepared statement.
43 *
44 * @return \PHPUnit_Framework_MockObject_MockObject
45 */
46 private function setUpAndReturnDatabaseStub()
47 {
48 $GLOBALS['TYPO3_DB'] = $this->getAccessibleMock(
49 \TYPO3\CMS\Core\Database\DatabaseConnection::class,
50 array('prepare_PREPAREDquery'),
51 array(),
52 '',
53 false,
54 false
55 );
56
57 return $GLOBALS['TYPO3_DB'];
58 }
59
60 /**
61 * Create an object fo the subject to be tested.
62 *
63 * @param string $query
64 * @return \TYPO3\CMS\Core\Database\PreparedStatement
65 */
66 private function createPreparedStatement($query)
67 {
68 return new \TYPO3\CMS\Core\Database\PreparedStatement($query, 'pages');
69 }
70
71 ////////////////////////////////////
72 // Tests for the utility functions
73 ////////////////////////////////////
74
75 /**
76 * @test
77 * @return void
78 */
79 public function setUpAndReturnDatabaseStubReturnsMockObjectOfDatabaseConnection()
80 {
81 $this->assertTrue($this->setUpAndReturnDatabaseStub() instanceof \TYPO3\CMS\Core\Database\DatabaseConnection);
82 }
83
84 /**
85 * @test
86 * @return void
87 */
88 public function createPreparedStatementReturnsInstanceOfPreparedStatementClass()
89 {
90 $this->assertTrue($this->createPreparedStatement('dummy') instanceof \TYPO3\CMS\Core\Database\PreparedStatement);
91 }
92
93 ///////////////////////////////////////
94 // Tests for \TYPO3\CMS\Core\Database\PreparedStatement
95 ///////////////////////////////////////
96 /**
97 * Data Provider for two tests, providing sample queries, parameters and expected result queries.
98 *
99 * @see parametersAreReplacedInQueryByCallingExecute
100 * @see parametersAreReplacedInQueryWhenBoundWithBindValues
101 * @return array
102 */
103 public function parametersAndQueriesDataProvider()
104 {
105 return array(
106 'one named integer parameter' => array('SELECT * FROM pages WHERE pid=:pid', array(':pid' => 1), 'SELECT * FROM pages WHERE pid=?'),
107 'one unnamed integer parameter' => array('SELECT * FROM pages WHERE pid=?', array(1), 'SELECT * FROM pages WHERE pid=?'),
108 'one named integer parameter is replaced multiple times' => array('SELECT * FROM pages WHERE pid=:pid OR uid=:pid', array(':pid' => 1), 'SELECT * FROM pages WHERE pid=? OR uid=?'),
109 'two named integer parameters are replaced' => array('SELECT * FROM pages WHERE pid=:pid OR uid=:uid', array(':pid' => 1, ':uid' => 10), 'SELECT * FROM pages WHERE pid=? OR uid=?'),
110 'two unnamed integer parameters are replaced' => array('SELECT * FROM pages WHERE pid=? OR uid=?', array(1, 1), 'SELECT * FROM pages WHERE pid=? OR uid=?'),
111 );
112 }
113
114 /**
115 * Checking if calling execute() with parameters, they are
116 * properly replaced in the query.
117 *
118 * @test
119 * @dataProvider parametersAndQueriesDataProvider
120 * @param string $query Query with unreplaced markers
121 * @param array $parameters Array of parameters to be replaced in the query
122 * @param string $expectedResult Query with all markers replaced
123 * @return void
124 */
125 public function parametersAreReplacedByQuestionMarkInQueryByCallingExecute($query, $parameters, $expectedResult)
126 {
127 $statement = $this->createPreparedStatement($query);
128 $this->databaseStub->expects($this->any())->method('prepare_PREPAREDquery')->with($this->equalTo($expectedResult));
129 $statement->execute($parameters);
130 }
131
132 /**
133 * Checking if parameters bound to the statement by bindValues()
134 * are properly replaced in the query.
135 *
136 * @test
137 * @dataProvider parametersAndQueriesDataProvider
138 * @param string $query Query with unreplaced markers
139 * @param array $parameters Array of parameters to be replaced in the query
140 * @param string $expectedResult Query with all markers replaced
141 * @return void
142 */
143 public function parametersAreReplacedInQueryWhenBoundWithBindValues($query, $parameters, $expectedResult)
144 {
145 $statement = $this->createPreparedStatement($query);
146 $this->databaseStub->expects($this->any())->method('prepare_PREPAREDquery')->with($this->equalTo($expectedResult));
147 $statement->bindValues($parameters);
148 $statement->execute();
149 }
150
151 /**
152 * Data Provider with invalid parameters.
153 *
154 * @see invalidParameterTypesPassedToBindValueThrowsException
155 * @return array
156 */
157 public function invalidParameterTypesPassedToBindValueThrowsExceptionDataProvider()
158 {
159 return array(
160 'integer passed with param type NULL' => array(1, \TYPO3\CMS\Core\Database\PreparedStatement::PARAM_NULL),
161 'string passed with param type NULL' => array('1', \TYPO3\CMS\Core\Database\PreparedStatement::PARAM_NULL),
162 'bool passed with param type NULL' => array(true, \TYPO3\CMS\Core\Database\PreparedStatement::PARAM_NULL),
163 'NULL passed with param type INT' => array(null, \TYPO3\CMS\Core\Database\PreparedStatement::PARAM_INT),
164 'string passed with param type INT' => array('1', \TYPO3\CMS\Core\Database\PreparedStatement::PARAM_INT),
165 'bool passed with param type INT' => array(true, \TYPO3\CMS\Core\Database\PreparedStatement::PARAM_INT),
166 'NULL passed with param type BOOL' => array(null, \TYPO3\CMS\Core\Database\PreparedStatement::PARAM_BOOL),
167 'string passed with param type BOOL' => array('1', \TYPO3\CMS\Core\Database\PreparedStatement::PARAM_BOOL),
168 'integer passed with param type BOOL' => array(1, \TYPO3\CMS\Core\Database\PreparedStatement::PARAM_BOOL)
169 );
170 }
171
172 /**
173 * Checking if an exception is thrown if invalid parameters are
174 * provided vor bindValue().
175 *
176 * @test
177 * @expectedException \InvalidArgumentException
178 * @dataProvider invalidParameterTypesPassedToBindValueThrowsExceptionDataProvider
179 * @param mixed $parameter Parameter to be replaced in the query
180 * @param int $type Type of the parameter value
181 * @return void
182 */
183 public function invalidParameterTypesPassedToBindValueThrowsException($parameter, $type)
184 {
185 $statement = $this->createPreparedStatement('');
186 $statement->bindValue(1, $parameter, $type);
187 }
188
189 /**
190 * Data Provider for invalid marker names.
191 *
192 * @see passingInvalidMarkersThrowsExeption
193 * @return array
194 */
195 public function passingInvalidMarkersThrowsExceptionDataProvider()
196 {
197 return array(
198 'using other prefix than colon' => array('SELECT * FROM pages WHERE pid=#pid', array('#pid' => 1)),
199 'using non alphanumerical character' => array('SELECT * FROM pages WHERE title=:stra≠e', array(':stra≠e' => 1)),
200 'no colon used' => array('SELECT * FROM pages WHERE pid=pid', array('pid' => 1)),
201 'colon at the end' => array('SELECT * FROM pages WHERE pid=pid:', array('pid:' => 1)),
202 'colon without alphanumerical character' => array('SELECT * FROM pages WHERE pid=:', array(':' => 1))
203 );
204 }
205
206 /**
207 * Checks if an exception is thrown, if parameter have invalid marker named.
208 *
209 * @test
210 * @expectedException \InvalidArgumentException
211 * @dataProvider passingInvalidMarkersThrowsExceptionDataProvider
212 * @param string $query Query with unreplaced markers
213 * @param array $parameters Array of parameters to be replaced in the query
214 * @return void
215 */
216 public function passingInvalidMarkersThrowsException($query, $parameters)
217 {
218 $statement = $this->createPreparedStatement($query);
219 $statement->bindValues($parameters);
220 }
221 }