Fix Display\ResultsTest test on Windows
[phpmyadmin.git] / test / classes / ImportTest.php
blob968714986032104c800e22a7f982fe83844d63f2
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Test for PhpMyAdmin\Import
6 * @package PhpMyAdmin-test
7 */
8 declare(strict_types=1);
10 namespace PhpMyAdmin\Tests;
12 use PhpMyAdmin\Import;
13 use PhpMyAdmin\SqlParser\Parser;
14 use PhpMyAdmin\Url;
15 use PhpMyAdmin\Util;
16 use PHPUnit\Framework\TestCase;
18 /**
19 * Tests for import functions
21 * @package PhpMyAdmin-test
23 class ImportTest extends TestCase
25 /**
26 * @var Import $import
28 private $import;
30 /**
31 * Prepares environment for the test.
33 * @return void
35 protected function setUp(): void
37 $GLOBALS['server'] = 0;
38 $GLOBALS['cfg']['ServerDefault'] = '';
39 $this->import = new Import();
42 /**
43 * Test for checkTimeout
45 * @return void
47 public function testCheckTimeout()
49 global $timestamp, $maximum_time, $timeout_passed;
51 //Reinit values.
52 $timestamp = time();
53 $maximum_time = 0;
54 $timeout_passed = false;
56 $this->assertFalse($this->import->checkTimeout());
58 //Reinit values.
59 $timestamp = time();
60 $maximum_time = 0;
61 $timeout_passed = true;
63 $this->assertFalse($this->import->checkTimeout());
65 //Reinit values.
66 $timestamp = time();
67 $maximum_time = 30;
68 $timeout_passed = true;
70 $this->assertTrue($this->import->checkTimeout());
72 //Reinit values.
73 $timestamp = time() - 15;
74 $maximum_time = 30;
75 $timeout_passed = false;
77 $this->assertFalse($this->import->checkTimeout());
79 //Reinit values.
80 $timestamp = time() - 60;
81 $maximum_time = 30;
82 $timeout_passed = false;
84 $this->assertTrue($this->import->checkTimeout());
87 /**
88 * Test for lookForUse
90 * @return void
92 public function testLookForUse()
94 $this->assertEquals(
96 null,
97 null,
99 $this->import->lookForUse(null, null, null)
102 $this->assertEquals(
104 'myDb',
105 null,
107 $this->import->lookForUse(null, 'myDb', null)
110 $this->assertEquals(
112 'myDb',
113 true,
115 $this->import->lookForUse(null, 'myDb', true)
118 $this->assertEquals(
120 'myDb',
121 true,
123 $this->import->lookForUse('select 1 from myTable', 'myDb', true)
126 $this->assertEquals(
128 'anotherDb',
129 true,
131 $this->import->lookForUse('use anotherDb', 'myDb', false)
134 $this->assertEquals(
136 'anotherDb',
137 true,
139 $this->import->lookForUse('use anotherDb', 'myDb', true)
142 $this->assertEquals(
144 'anotherDb',
145 true,
147 $this->import->lookForUse('use `anotherDb`;', 'myDb', true)
152 * Test for getColumnAlphaName
154 * @param string $expected Expected result of the function
155 * @param int $num The column number
157 * @return void
159 * @dataProvider provGetColumnAlphaName
161 public function testGetColumnAlphaName($expected, $num): void
163 $this->assertEquals($expected, $this->import->getColumnAlphaName($num));
167 * Data provider for testGetColumnAlphaName
169 * @return array
171 public function provGetColumnAlphaName()
173 return [
175 'A',
179 'Z',
183 'AA',
187 'AZ',
191 'BA',
195 'BB',
202 * Test for getColumnNumberFromName
204 * @param int $expected Expected result of the function
205 * @param string|null $name column name(i.e. "A", or "BC", etc.)
207 * @return void
209 * @dataProvider provGetColumnNumberFromName
211 public function testGetColumnNumberFromName($expected, $name): void
213 $this->assertEquals($expected, $this->import->getColumnNumberFromName($name));
217 * Data provider for testGetColumnNumberFromName
219 * @return array
221 public function provGetColumnNumberFromName()
223 return [
226 'A',
230 'Z',
234 'AA',
238 'AZ',
242 'BA',
246 'BB',
252 * Test for getDecimalPrecision
254 * @param int $expected Expected result of the function
255 * @param string|null $size Size of field
257 * @return void
259 * @dataProvider provGetDecimalPrecision
261 public function testGetDecimalPrecision($expected, $size): void
263 $this->assertEquals($expected, $this->import->getDecimalPrecision($size));
267 * Data provider for testGetDecimalPrecision
269 * @return array
271 public function provGetDecimalPrecision()
273 return [
276 '2,1',
280 '6,2',
284 '6,0',
288 '16,2',
294 * Test for getDecimalScale
296 * @param int $expected Expected result of the function
297 * @param string|null $size Size of field
299 * @return void
301 * @dataProvider provGetDecimalScale
303 public function testGetDecimalScale($expected, $size): void
305 $this->assertEquals($expected, $this->import->getDecimalScale($size));
309 * Data provider for testGetDecimalScale
311 * @return array
313 public function provGetDecimalScale()
315 return [
318 '2,1',
322 '6,2',
326 '6,0',
330 '30,20',
336 * Test for getDecimalSize
338 * @param array $expected Expected result of the function
339 * @param string|null $cell Cell content
341 * @return void
343 * @dataProvider provGetDecimalSize
345 public function testGetDecimalSize($expected, $cell): void
347 $this->assertEquals($expected, $this->import->getDecimalSize($cell));
351 * Data provider for testGetDecimalSize
353 * @return array
355 public function provGetDecimalSize()
357 return [
362 '2,1',
363 ], '2.1',
369 '2,1',
370 ], '6.2',
376 '3,1',
377 ], '10.0',
383 '4,2',
384 ], '30.20',
390 * Test for detectType
392 * @param int $expected Expected result of the function
393 * @param int|null $type Last cumulative column type (VARCHAR or INT or
394 * BIGINT or DECIMAL or NONE)
395 * @param string|null $cell String representation of the cell for which a
396 * best-fit type is to be determined
398 * @return void
400 * @dataProvider provDetectType
402 public function testDetectType($expected, $type, $cell): void
404 $this->assertEquals($expected, $this->import->detectType($type, $cell));
408 * Data provider for testDetectType
410 * @return array
412 public function provDetectType()
414 $data = [
416 Import::NONE,
417 null,
418 'NULL',
421 Import::NONE,
422 Import::NONE,
423 'NULL',
426 Import::INT,
427 Import::INT,
428 'NULL',
431 Import::VARCHAR,
432 Import::VARCHAR,
433 'NULL',
436 Import::VARCHAR,
437 null,
438 null,
441 Import::VARCHAR,
442 Import::INT,
443 null,
446 Import::INT,
447 Import::INT,
448 '10',
451 Import::DECIMAL,
452 Import::DECIMAL,
453 '10.2',
456 Import::DECIMAL,
457 Import::INT,
458 '10.2',
461 Import::VARCHAR,
462 Import::VARCHAR,
463 'test',
466 Import::VARCHAR,
467 Import::INT,
468 'test',
472 if (PHP_INT_MAX > 2147483647) {
473 $data[] = [
474 Import::BIGINT,
475 Import::BIGINT,
476 '2147483648',
478 $data[] = [
479 Import::BIGINT,
480 Import::INT,
481 '2147483648',
483 } else {
484 // To be fixed ?
485 // Can not detect a BIGINT since the value is over PHP_INT_MAX
486 $data[] = [
487 Import::VARCHAR,
488 Import::BIGINT,
489 '2147483648',
491 $data[] = [
492 Import::VARCHAR,
493 Import::INT,
494 '2147483648',
498 return $data;
502 * Test for getMatchedRows.
504 * @return void
506 public function testPMAGetMatchedRows()
508 $GLOBALS['db'] = 'PMA';
509 //mock DBI
510 $dbi = $this->getMockBuilder('PhpMyAdmin\DatabaseInterface')
511 ->disableOriginalConstructor()
512 ->getMock();
514 $update_query = 'UPDATE `table_1` '
515 . 'SET `id` = 20 '
516 . 'WHERE `id` > 10';
517 $simulated_update_query = 'SELECT `id` FROM `table_1` WHERE `id` > 10 AND (`id` <> 20)';
519 $delete_query = 'DELETE FROM `table_1` '
520 . 'WHERE `id` > 10';
521 $simulated_delete_query = 'SELECT * FROM `table_1` WHERE `id` > 10';
523 $dbi->expects($this->any())
524 ->method('numRows')
525 ->with([])
526 ->will($this->returnValue(2));
528 $dbi->expects($this->any())
529 ->method('selectDb')
530 ->with('PMA')
531 ->will($this->returnValue(true));
533 $dbi->expects($this->at(1))
534 ->method('tryQuery')
535 ->with($simulated_update_query)
536 ->will($this->returnValue([]));
538 $dbi->expects($this->at(4))
539 ->method('tryQuery')
540 ->with($simulated_delete_query)
541 ->will($this->returnValue([]));
543 $GLOBALS['dbi'] = $dbi;
545 $this->simulatedQueryTest($update_query, $simulated_update_query);
546 $this->simulatedQueryTest($delete_query, $simulated_delete_query);
550 * Tests simulated UPDATE/DELETE query.
552 * @param string $sql_query SQL query
553 * @param string $simulated_query Simulated query
555 * @return void
557 public function simulatedQueryTest($sql_query, $simulated_query)
559 $parser = new Parser($sql_query);
560 $analyzed_sql_results = [
561 'query' => $sql_query,
562 'parser' => $parser,
563 'statement' => $parser->statements[0],
566 $simulated_data = $this->import->getMatchedRows($analyzed_sql_results);
568 // URL to matched rows.
569 $_url_params = [
570 'db' => 'PMA',
571 'sql_query' => $simulated_query,
573 $matched_rows_url = 'sql.php' . Url::getCommon($_url_params);
575 $this->assertEquals(
577 'sql_query' => Util::formatSql(
578 $analyzed_sql_results['query']
580 'matched_rows' => 2,
581 'matched_rows_url' => $matched_rows_url,
583 $simulated_data
588 * Test for checkIfRollbackPossible
590 * @return void
592 public function testPMACheckIfRollbackPossible()
594 $GLOBALS['db'] = 'PMA';
595 //mock DBI
596 $dbi = $this->getMockBuilder('PhpMyAdmin\DatabaseInterface')
597 ->disableOriginalConstructor()
598 ->getMock();
600 // List of Transactional Engines.
601 $transactional_engines = [
602 'INNODB',
603 'FALCON',
604 'NDB',
605 'INFINIDB',
606 'TOKUDB',
607 'XTRADB',
608 'SEQUENCE',
609 'BDB',
612 $check_query = 'SELECT `ENGINE` FROM `information_schema`.`tables` '
613 . 'WHERE `table_name` = "%s" '
614 . 'AND `table_schema` = "%s" '
615 . 'AND UPPER(`engine`) IN ("'
616 . implode('", "', $transactional_engines)
617 . '")';
619 $check_table_query = 'SELECT * FROM `%s`.`%s` '
620 . 'LIMIT 1';
622 $dbi->expects($this->at(0))
623 ->method('tryQuery')
624 ->with(sprintf($check_table_query, 'PMA', 'table_1'))
625 ->will($this->returnValue(['table']));
627 $dbi->expects($this->at(1))
628 ->method('tryQuery')
629 ->with(sprintf($check_query, 'table_1', 'PMA'))
630 ->will($this->returnValue(true));
632 $dbi->expects($this->at(2))
633 ->method('numRows')
634 ->will($this->returnValue(1));
636 $dbi->expects($this->at(3))
637 ->method('tryQuery')
638 ->with(sprintf($check_table_query, 'PMA', 'table_2'))
639 ->will($this->returnValue(['table']));
641 $dbi->expects($this->at(4))
642 ->method('tryQuery')
643 ->with(sprintf($check_query, 'table_2', 'PMA'))
644 ->will($this->returnValue(true));
646 $dbi->expects($this->at(5))
647 ->method('numRows')
648 ->will($this->returnValue(1));
650 $GLOBALS['dbi'] = $dbi;
652 $sql_query = 'UPDATE `table_1` AS t1, `table_2` t2 '
653 . 'SET `table_1`.`id` = `table_2`.`id` '
654 . 'WHERE 1';
656 $this->assertEquals(true, $this->import->checkIfRollbackPossible($sql_query));