DriverTest.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  5. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  6. *
  7. * Licensed under The MIT License
  8. * For full copyright and license information, please see the LICENSE.txt
  9. * Redistributions of files must retain the above copyright notice.
  10. *
  11. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  12. * @link https://cakephp.org CakePHP(tm) Project
  13. * @since 3.2.12
  14. * @license https://opensource.org/licenses/mit-license.php MIT License
  15. */
  16. namespace Cake\Test\TestCase\Database;
  17. use Cake\Database\Driver;
  18. use Cake\Database\Driver\Mysql;
  19. use Cake\Database\DriverInterface;
  20. use Cake\Database\Exception\MissingConnectionException;
  21. use Cake\Database\Query;
  22. use Cake\Database\QueryCompiler;
  23. use Cake\Database\Schema\TableSchema;
  24. use Cake\Database\ValueBinder;
  25. use Cake\TestSuite\TestCase;
  26. use Exception;
  27. use PDO;
  28. use PDOStatement;
  29. /**
  30. * Tests Driver class
  31. */
  32. class DriverTest extends TestCase
  33. {
  34. /**
  35. * @var \Cake\Database\Driver|\PHPUnit\Framework\MockObject\MockObject
  36. */
  37. protected $driver;
  38. /**
  39. * Setup.
  40. */
  41. public function setUp(): void
  42. {
  43. parent::setUp();
  44. $this->driver = $this->getMockForAbstractClass(Driver::class);
  45. }
  46. /**
  47. * Test if building the object throws an exception if we're not passing
  48. * required config data.
  49. */
  50. public function testConstructorException(): void
  51. {
  52. $arg = ['login' => 'Bear'];
  53. try {
  54. $this->getMockForAbstractClass(Driver::class, [$arg]);
  55. } catch (Exception $e) {
  56. $this->assertStringContainsString(
  57. 'Please pass "username" instead of "login" for connecting to the database',
  58. $e->getMessage()
  59. );
  60. }
  61. }
  62. /**
  63. * Test the constructor.
  64. */
  65. public function testConstructor(): void
  66. {
  67. $arg = ['quoteIdentifiers' => true];
  68. $driver = $this->getMockForAbstractClass(Driver::class, [$arg]);
  69. $this->assertTrue($driver->isAutoQuotingEnabled());
  70. $arg = ['username' => 'GummyBear'];
  71. $driver = $this->getMockForAbstractClass(Driver::class, [$arg]);
  72. $this->assertFalse($driver->isAutoQuotingEnabled());
  73. }
  74. /**
  75. * Tests default implementation of feature support check.
  76. */
  77. public function testSupports(): void
  78. {
  79. $this->assertTrue($this->driver->supports(DriverInterface::FEATURE_SAVEPOINT));
  80. $this->assertTrue($this->driver->supports(DriverInterface::FEATURE_QUOTE));
  81. $this->assertFalse($this->driver->supports(DriverInterface::FEATURE_CTE));
  82. $this->assertFalse($this->driver->supports(DriverInterface::FEATURE_JSON));
  83. $this->assertFalse($this->driver->supports(DriverInterface::FEATURE_WINDOW));
  84. $this->assertFalse($this->driver->supports('this-is-fake'));
  85. }
  86. /**
  87. * Tests deprecated supports checks.
  88. */
  89. public function testDeprecatedSupports(): void
  90. {
  91. $this->deprecated(function () {
  92. $this->assertSame($this->driver->supportsCTEs(), $this->driver->supports(DriverInterface::FEATURE_CTE));
  93. $this->assertSame($this->driver->supportsSavePoints(), $this->driver->supports(DriverInterface::FEATURE_SAVEPOINT));
  94. $this->assertSame($this->driver->supportsQuoting(), $this->driver->supports(DriverInterface::FEATURE_QUOTE));
  95. });
  96. }
  97. /**
  98. * Test schemaValue().
  99. * Uses a provider for all the different values we can pass to the method.
  100. *
  101. * @dataProvider schemaValueProvider
  102. * @param mixed $input
  103. */
  104. public function testSchemaValue($input, string $expected): void
  105. {
  106. $result = $this->driver->schemaValue($input);
  107. $this->assertSame($expected, $result);
  108. }
  109. /**
  110. * Test schemaValue().
  111. * Asserting that quote() is being called because none of the conditions were met before.
  112. */
  113. public function testSchemaValueConnectionQuoting(): void
  114. {
  115. $value = 'string';
  116. $connection = $this->getMockBuilder(PDO::class)
  117. ->disableOriginalConstructor()
  118. ->onlyMethods(['quote'])
  119. ->getMock();
  120. $connection
  121. ->expects($this->once())
  122. ->method('quote')
  123. ->with($value, PDO::PARAM_STR)
  124. ->will($this->returnValue('string'));
  125. $this->driver->setConnection($connection);
  126. $this->driver->schemaValue($value);
  127. }
  128. /**
  129. * Test lastInsertId().
  130. */
  131. public function testLastInsertId(): void
  132. {
  133. $connection = $this->getMockBuilder(Mysql::class)
  134. ->disableOriginalConstructor()
  135. ->onlyMethods(['lastInsertId'])
  136. ->getMock();
  137. $connection
  138. ->expects($this->once())
  139. ->method('lastInsertId')
  140. ->willReturn('all-the-bears');
  141. $this->driver->setConnection($connection);
  142. $this->assertSame('all-the-bears', $this->driver->lastInsertId());
  143. }
  144. /**
  145. * Test isConnected().
  146. */
  147. public function testIsConnected(): void
  148. {
  149. $this->assertFalse($this->driver->isConnected());
  150. $connection = $this->getMockBuilder(PDO::class)
  151. ->disableOriginalConstructor()
  152. ->onlyMethods(['query'])
  153. ->getMock();
  154. $connection
  155. ->expects($this->once())
  156. ->method('query')
  157. ->willReturn(new PDOStatement());
  158. $this->driver->setConnection($connection);
  159. $this->assertTrue($this->driver->isConnected());
  160. }
  161. /**
  162. * test autoQuoting().
  163. */
  164. public function testAutoQuoting(): void
  165. {
  166. $this->assertFalse($this->driver->isAutoQuotingEnabled());
  167. $this->assertSame($this->driver, $this->driver->enableAutoQuoting(true));
  168. $this->assertTrue($this->driver->isAutoQuotingEnabled());
  169. $this->driver->disableAutoQuoting();
  170. $this->assertFalse($this->driver->isAutoQuotingEnabled());
  171. }
  172. /**
  173. * Test compileQuery().
  174. */
  175. public function testCompileQuery(): void
  176. {
  177. $compiler = $this->getMockBuilder(QueryCompiler::class)
  178. ->onlyMethods(['compile'])
  179. ->getMock();
  180. $compiler
  181. ->expects($this->once())
  182. ->method('compile')
  183. ->willReturn('1');
  184. $driver = $this->getMockBuilder(Driver::class)
  185. ->onlyMethods(['newCompiler', 'queryTranslator'])
  186. ->getMockForAbstractClass();
  187. $driver
  188. ->expects($this->once())
  189. ->method('newCompiler')
  190. ->willReturn($compiler);
  191. $driver
  192. ->expects($this->once())
  193. ->method('queryTranslator')
  194. ->willReturn(function ($query) {
  195. return $query;
  196. });
  197. $query = $this->getMockBuilder(Query::class)
  198. ->disableOriginalConstructor()
  199. ->getMock();
  200. $query->method('type')->will($this->returnValue('select'));
  201. $result = $driver->compileQuery($query, new ValueBinder());
  202. $this->assertIsArray($result);
  203. $this->assertSame($query, $result[0]);
  204. $this->assertSame('1', $result[1]);
  205. }
  206. /**
  207. * Test newCompiler().
  208. */
  209. public function testNewCompiler(): void
  210. {
  211. $this->assertInstanceOf(QueryCompiler::class, $this->driver->newCompiler());
  212. }
  213. /**
  214. * Test newTableSchema().
  215. */
  216. public function testNewTableSchema(): void
  217. {
  218. $tableName = 'articles';
  219. $actual = $this->driver->newTableSchema($tableName);
  220. $this->assertInstanceOf(TableSchema::class, $actual);
  221. $this->assertSame($tableName, $actual->name());
  222. }
  223. /**
  224. * Test __destruct().
  225. */
  226. public function testDestructor(): void
  227. {
  228. $this->driver->setConnection(true);
  229. $this->driver->__destruct();
  230. $this->expectException(MissingConnectionException::class);
  231. $this->driver->getConnection();
  232. }
  233. /**
  234. * Data provider for testSchemaValue().
  235. *
  236. * @return array
  237. */
  238. public function schemaValueProvider(): array
  239. {
  240. return [
  241. [null, 'NULL'],
  242. [false, 'FALSE'],
  243. [true, 'TRUE'],
  244. [1, '1'],
  245. ['0', '0'],
  246. ['42', '42'],
  247. ];
  248. }
  249. }