diff options
Diffstat (limited to 'test')
281 files changed, 8507 insertions, 2520 deletions
diff --git a/test/ci-phplint b/test/ci-phplint index 5e23620edb..5f8a47cf42 100755 --- a/test/ci-phplint +++ b/test/ci-phplint @@ -1,9 +1,16 @@ #!/bin/sh -FILES=`find . -name '*.php' -not -path './vendor/*'` +FILES=$(find . -name '*.php' -not -path './vendor/*' -not -path './tmp/*' -not -path './node_modules/*') +result=0 for FILE in $FILES ; do - if [ -f $FILE ] ; then - php -l $FILE + if [ -f "$FILE" ] ; then + php -l "$FILE" + ret=$? + if [ $ret != 0 ] ; then + result=$ret + fi fi done + +exit $result diff --git a/test/classes/AbstractNetworkTestCase.php b/test/classes/AbstractNetworkTestCase.php index db7838b464..c7894ff2e0 100644 --- a/test/classes/AbstractNetworkTestCase.php +++ b/test/classes/AbstractNetworkTestCase.php @@ -30,10 +30,8 @@ abstract class AbstractNetworkTestCase extends AbstractTestCase */ public static function setUpBeforeClass(): void { - global $cfg; - $settings = new Settings([]); - $cfg = $settings->toArray(); + $GLOBALS['cfg'] = $settings->toArray(); } /** @@ -53,7 +51,7 @@ abstract class AbstractNetworkTestCase extends AbstractTestCase 'setRequestStatus', 'addJSON', 'addHTML', - 'getFooter', + 'setMinimalFooter', 'getHeader', 'httpResponseCode', ]) diff --git a/test/classes/AbstractTestCase.php b/test/classes/AbstractTestCase.php index 45fdc9850a..c880cc28d9 100644 --- a/test/classes/AbstractTestCase.php +++ b/test/classes/AbstractTestCase.php @@ -8,6 +8,7 @@ use PhpMyAdmin\Cache; use PhpMyAdmin\Config; use PhpMyAdmin\Core; use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Dbal\DbiExtension; use PhpMyAdmin\LanguageManager; use PhpMyAdmin\SqlParser\Translator; use PhpMyAdmin\Tests\Stubs\DbiDummy; @@ -44,20 +45,6 @@ abstract class AbstractTestCase extends TestCase ]; /** - * The DatabaseInterface loaded by setGlobalDbi - * - * @var DatabaseInterface - */ - protected $dbi; - - /** - * The DbiDummy loaded by setGlobalDbi - * - * @var DbiDummy - */ - protected $dummyDbi; - - /** * Prepares environment for the test. * Clean all variables */ @@ -85,134 +72,100 @@ abstract class AbstractTestCase extends TestCase $_COOKIE = []; $_FILES = []; $_REQUEST = []; + + $GLOBALS['server'] = 1; + $GLOBALS['db'] = ''; + $GLOBALS['table'] = ''; + $GLOBALS['sql_query'] = ''; + $GLOBALS['text_dir'] = 'ltr'; + $GLOBALS['PMA_PHP_SELF'] = 'index.php'; + // Config before DBI $this->setGlobalConfig(); $this->loadContainerBuilder(); - $this->setGlobalDbi(); - $this->loadDbiIntoContainerBuilder(); + $this->setTheme(); Cache::purge(); } - protected function assertAllQueriesConsumed(): void - { - $unUsedQueries = $this->dummyDbi->getUnUsedQueries(); - $this->assertSame([], $unUsedQueries, 'Some queries where not used !'); - } - - protected function assertAllSelectsConsumed(): void - { - $unUsedSelects = $this->dummyDbi->getUnUsedDatabaseSelects(); - $this->assertSame( - [], - $unUsedSelects, - 'Some database selects where not used !' - ); - } - - protected function assertAllErrorCodesConsumed(): void - { - if ($this->dummyDbi->hasUnUsedErrors() === false) { - $this->assertTrue(true);// increment the assertion count - - return; - } - - $this->fail('Some error codes where not used !'); - } - protected function loadContainerBuilder(): void { - global $containerBuilder; - - $containerBuilder = Core::getContainerBuilder(); + $GLOBALS['containerBuilder'] = Core::getContainerBuilder(); } protected function loadDbiIntoContainerBuilder(): void { - global $containerBuilder, $dbi; - - $containerBuilder->set(DatabaseInterface::class, $dbi); - $containerBuilder->setAlias('dbi', DatabaseInterface::class); + $GLOBALS['containerBuilder']->set(DatabaseInterface::class, $GLOBALS['dbi']); + $GLOBALS['containerBuilder']->setAlias('dbi', DatabaseInterface::class); } protected function loadResponseIntoContainerBuilder(): void { - global $containerBuilder; - $response = new ResponseRenderer(); - $containerBuilder->set(ResponseRenderer::class, $response); - $containerBuilder->setAlias('response', ResponseRenderer::class); + $GLOBALS['containerBuilder']->set(ResponseRenderer::class, $response); + $GLOBALS['containerBuilder']->setAlias('response', ResponseRenderer::class); } protected function setResponseIsAjax(): void { - global $containerBuilder; - /** @var ResponseRenderer $response */ - $response = $containerBuilder->get(ResponseRenderer::class); + $response = $GLOBALS['containerBuilder']->get(ResponseRenderer::class); $response->setAjax(true); } protected function getResponseHtmlResult(): string { - global $containerBuilder; - /** @var ResponseRenderer $response */ - $response = $containerBuilder->get(ResponseRenderer::class); + $response = $GLOBALS['containerBuilder']->get(ResponseRenderer::class); return $response->getHTMLResult(); } protected function getResponseJsonResult(): array { - global $containerBuilder; - /** @var ResponseRenderer $response */ - $response = $containerBuilder->get(ResponseRenderer::class); + $response = $GLOBALS['containerBuilder']->get(ResponseRenderer::class); return $response->getJSONResult(); } protected function assertResponseWasNotSuccessfull(): void { - global $containerBuilder; /** @var ResponseRenderer $response */ - $response = $containerBuilder->get(ResponseRenderer::class); + $response = $GLOBALS['containerBuilder']->get(ResponseRenderer::class); $this->assertFalse($response->hasSuccessState(), 'expected the request to fail'); } protected function assertResponseWasSuccessfull(): void { - global $containerBuilder; /** @var ResponseRenderer $response */ - $response = $containerBuilder->get(ResponseRenderer::class); + $response = $GLOBALS['containerBuilder']->get(ResponseRenderer::class); $this->assertTrue($response->hasSuccessState(), 'expected the request not to fail'); } - protected function setGlobalDbi(): void + protected function createDatabaseInterface(?DbiExtension $extension = null): DatabaseInterface { - global $dbi; - $this->dummyDbi = new DbiDummy(); - $this->dbi = DatabaseInterface::load($this->dummyDbi); - $dbi = $this->dbi; + return new DatabaseInterface($extension ?? $this->createDbiDummy()); + } + + protected function createDbiDummy(): DbiDummy + { + return new DbiDummy(); } protected function setGlobalConfig(): void { - global $config, $cfg; - $config = new Config(); - $config->checkServers(); - $config->set('environment', 'development'); - $cfg = $config->settings; + $GLOBALS['config'] = new Config(); + $GLOBALS['config']->checkServers(); + $GLOBALS['config']->set('environment', 'development'); + $GLOBALS['cfg'] = $GLOBALS['config']->settings; } protected function setTheme(): void { - global $theme; - $theme = Theme::load( + $GLOBALS['theme'] = Theme::load( ThemeManager::getThemesDir() . 'pmahomme', ThemeManager::getThemesFsDir() . 'pmahomme' . DIRECTORY_SEPARATOR, 'pmahomme' @@ -221,9 +174,7 @@ abstract class AbstractTestCase extends TestCase protected function setLanguage(string $code = 'en'): void { - global $lang; - - $lang = $code; + $GLOBALS['lang'] = $code; /* Ensure default language is active */ $languageEn = LanguageManager::getInstance()->getLanguage($code); if ($languageEn === false) { diff --git a/test/classes/AdvisorTest.php b/test/classes/Advisory/AdvisorTest.php index 81c245933c..25f849be6a 100644 --- a/test/classes/AdvisorTest.php +++ b/test/classes/Advisory/AdvisorTest.php @@ -2,13 +2,14 @@ declare(strict_types=1); -namespace PhpMyAdmin\Tests; +namespace PhpMyAdmin\Tests\Advisory; -use PhpMyAdmin\Advisor; +use PhpMyAdmin\Advisory\Advisor; +use PhpMyAdmin\Tests\AbstractTestCase; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; /** - * @covers \PhpMyAdmin\Advisor + * @covers \PhpMyAdmin\Advisory\Advisor */ class AdvisorTest extends AbstractTestCase { @@ -16,6 +17,7 @@ class AdvisorTest extends AbstractTestCase { parent::setUp(); parent::setGlobalConfig(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 1; } @@ -72,10 +74,6 @@ class AdvisorTest extends AbstractTestCase { parent::setLanguage(); $advisor = new Advisor($GLOBALS['dbi'], new ExpressionLanguage()); - $parseResult = include ROOT_PATH . 'libraries/advisory_rules_generic.php'; - $this->assertIsArray($parseResult); - $this->assertArrayHasKey(0, $parseResult); - $this->assertIsArray($parseResult[0]); $advisor->setVariable('value', 0); $advisor->addRule('fired', $rule); $runResult = $advisor->getRunResult(); @@ -229,7 +227,7 @@ class AdvisorTest extends AbstractTestCase 'justification_formula' => 'value', 'name' => 'Distribution', 'issue' => 'official MySQL binaries.', - 'recommendation' => 'See <a href="./url.php?url=https%3A%2F%2F' . + 'recommendation' => 'See <a href="index.php?route=/url&url=https%3A%2F%2F' . 'example.com%2F" target="_blank" rel="noopener noreferrer">web</a>', 'id' => 'Distribution', ], @@ -249,7 +247,7 @@ class AdvisorTest extends AbstractTestCase 'justification_formula' => 'ADVISOR_timespanFormat(1377027)', 'name' => 'Distribution', 'issue' => 'official MySQL binaries.', - 'recommendation' => 'See <a href="./url.php?url=https%3A%2F%2F' . + 'recommendation' => 'See <a href="index.php?route=/url&url=https%3A%2F%2F' . 'example.com%2F" target="_blank" rel="noopener noreferrer">web</a>', 'id' => 'Distribution', ], @@ -270,9 +268,9 @@ class AdvisorTest extends AbstractTestCase 'justification_formula' => 'ADVISOR_formatByteDown(1000000, 2, 2)', 'name' => 'Distribution', 'issue' => 'official MySQL binaries.', - 'recommendation' => 'See <a href="./url.php?url=https%3A%2F%2F' + 'recommendation' => 'See <a href="index.php?route=/url&url=https%3A%2F%2F' . 'example.com%2F" target="_blank" rel="noopener noreferrer">web</a>' - . ' and <a href="./url.php?url=https%3A%2F%2Fexample.com%2F" target="_blank"' + . ' and <a href="index.php?route=/url&url=https%3A%2F%2Fexample.com%2F" target="_blank"' . ' rel="noopener noreferrer">web2</a>', 'id' => 'Distribution', ], @@ -294,9 +292,9 @@ class AdvisorTest extends AbstractTestCase 'name' => 'Distribution', 'issue' => '<a href="index.php?route=/server/variables&filter=long_query_time&lang=en">' . 'long_query_time</a> is set to 10 seconds or more', - 'recommendation' => 'See <a href="./url.php?url=https%3A%2F%2F' + 'recommendation' => 'See <a href="index.php?route=/url&url=https%3A%2F%2F' . 'example.com%2F" target="_blank" rel="noopener noreferrer">web</a>' - . ' and <a href="./url.php?url=https%3A%2F%2Fexample.com%2F" target="_blank"' + . ' and <a href="index.php?route=/url&url=https%3A%2F%2Fexample.com%2F" target="_blank"' . ' rel="noopener noreferrer">web2</a>', 'id' => 'Distribution', ], diff --git a/test/classes/Advisory/RulesTest.php b/test/classes/Advisory/RulesTest.php new file mode 100644 index 0000000000..b85511598f --- /dev/null +++ b/test/classes/Advisory/RulesTest.php @@ -0,0 +1,56 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Advisory; + +use PhpMyAdmin\Advisory\Rules; +use PHPUnit\Framework\TestCase; + +/** + * @covers \PhpMyAdmin\Advisory\Rules + * @psalm-import-type RuleType from Rules + */ +class RulesTest extends TestCase +{ + /** + * @psalm-param callable(): list<RuleType> $rulesFactory + * + * @dataProvider providerForTestRules + */ + public function testRules(callable $rulesFactory): void + { + $rules = $rulesFactory(); + $this->assertNotEmpty($rules); + foreach ($rules as $rule) { + $this->assertArrayHasKey('id', $rule); + $this->assertArrayHasKey('name', $rule); + $this->assertArrayHasKey('formula', $rule); + $this->assertArrayHasKey('test', $rule); + $this->assertArrayHasKey('issue', $rule); + $this->assertArrayHasKey('recommendation', $rule); + $this->assertArrayHasKey('justification', $rule); + $this->assertContainsOnly('string', $rule); + } + } + + /** + * @return array<string, callable[]> + * @psalm-return array<string, array{callable(): list<RuleType>}> + */ + public function providerForTestRules(): iterable + { + return [ + 'generic rules' => [ + static function (): array { + return Rules::getGeneric(); + }, + ], + 'rules before MySQL 8.0.3' => [ + static function (): array { + return Rules::getBeforeMySql80003(); + }, + ], + ]; + } +} diff --git a/test/classes/BookmarkTest.php b/test/classes/BookmarkTest.php index 588c77c956..39006160d3 100644 --- a/test/classes/BookmarkTest.php +++ b/test/classes/BookmarkTest.php @@ -6,14 +6,22 @@ namespace PhpMyAdmin\Tests; use PhpMyAdmin\Bookmark; use PhpMyAdmin\ConfigStorage\Features\BookmarkFeature; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Dbal\DatabaseName; use PhpMyAdmin\Dbal\TableName; +use PhpMyAdmin\Tests\Stubs\DbiDummy; /** * @covers \PhpMyAdmin\Bookmark */ class BookmarkTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** * Sets up the fixture, for example, opens a network connection. * This method is called before a test is executed. @@ -21,6 +29,9 @@ class BookmarkTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['cfg']['Server']['user'] = 'root'; $GLOBALS['cfg']['Server']['pmadb'] = 'phpmyadmin'; $GLOBALS['cfg']['Server']['bookmarktable'] = 'pma_bookmark'; @@ -47,7 +58,7 @@ class BookmarkTest extends AbstractTestCase 'sakila' ); $this->assertContainsOnlyInstancesOf(Bookmark::class, $actual); - $this->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllSelectsConsumed(); } /** @@ -64,7 +75,7 @@ class BookmarkTest extends AbstractTestCase '1' ) ); - $this->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllSelectsConsumed(); } /** @@ -83,6 +94,6 @@ class BookmarkTest extends AbstractTestCase $this->assertNotFalse($bookmark); $this->dummyDbi->addSelectDb('phpmyadmin'); $this->assertFalse($bookmark->save()); - $this->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllSelectsConsumed(); } } diff --git a/test/classes/CharsetsTest.php b/test/classes/CharsetsTest.php index ef46c2e99a..32f28d188e 100644 --- a/test/classes/CharsetsTest.php +++ b/test/classes/CharsetsTest.php @@ -8,83 +8,119 @@ use PhpMyAdmin\Charsets; /** * @covers \PhpMyAdmin\Charsets + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled */ class CharsetsTest extends AbstractTestCase { - protected function setUp(): void - { - parent::setUp(); - parent::setGlobalDbi(); - $GLOBALS['server'] = 0; - $GLOBALS['cfg']['DBG']['sql'] = false; - $GLOBALS['cfg']['Server']['DisableIS'] = false; - } - public function testGetServerCharset(): void { - $this->dummyDbi->addResult( + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + $dummyDbi->addResult( 'SHOW SESSION VARIABLES LIKE \'character_set_server\';', - [ - [ - 'character_set_server', - 'utf8mb3', - ], - ], - [ - 'Variable_name', - 'Value', - ] + [['character_set_server', 'utf8mb3']], + ['Variable_name', 'Value'] ); - $this->dummyDbi->addResult('SHOW SESSION VARIABLES LIKE \'character_set_server\';', false); - $this->dummyDbi->addResult('SELECT @@character_set_server;', false); - $this->dummyDbi->addResult('SHOW SESSION VARIABLES LIKE \'character_set_server\';', false); - $this->dummyDbi->addResult( - 'SELECT @@character_set_server;', - [ - ['utf8mb3'], - ] + $dummyDbi->addResult('SHOW SESSION VARIABLES LIKE \'character_set_server\';', false); + $dummyDbi->addResult('SELECT @@character_set_server;', false); + $dummyDbi->addResult('SHOW SESSION VARIABLES LIKE \'character_set_server\';', false); + $dummyDbi->addResult('SELECT @@character_set_server;', [['utf8mb3']]); + $dummyDbi->addResult( + 'SHOW SESSION VARIABLES LIKE \'character_set_server\';', + [['character_set_server', 'utf8mb4']], + ['Variable_name', 'Value'] ); - $charset = Charsets::getServerCharset($GLOBALS['dbi'], $GLOBALS['cfg']['Server']['DisableIS']); + $charset = Charsets::getServerCharset($dbi, false); $this->assertSame('utf8', $charset->getName()); - $charset = Charsets::getServerCharset($GLOBALS['dbi'], $GLOBALS['cfg']['Server']['DisableIS']); + $charset = Charsets::getServerCharset($dbi, false); $this->assertSame('Unknown', $charset->getName()); - $charset = Charsets::getServerCharset($GLOBALS['dbi'], $GLOBALS['cfg']['Server']['DisableIS']); + $charset = Charsets::getServerCharset($dbi, false); $this->assertSame('utf8', $charset->getName()); - $this->assertAllQueriesConsumed(); + $charset = Charsets::getServerCharset($dbi, false); + $this->assertSame('utf8mb4', $charset->getName()); + + $charset = Charsets::getServerCharset($dbi, false); + $this->assertSame('utf8mb4', $charset->getName()); + + $dummyDbi->assertAllQueriesConsumed(); } public function testFindCollationByName(): void { - $this->assertNull(Charsets::findCollationByName( - $GLOBALS['dbi'], - $GLOBALS['cfg']['Server']['DisableIS'], - null - )); - - $this->assertNull(Charsets::findCollationByName( - $GLOBALS['dbi'], - $GLOBALS['cfg']['Server']['DisableIS'], - '' - )); - - $this->assertNull(Charsets::findCollationByName( - $GLOBALS['dbi'], - $GLOBALS['cfg']['Server']['DisableIS'], - 'invalid' - )); - - $actual = Charsets::findCollationByName( - $GLOBALS['dbi'], - $GLOBALS['cfg']['Server']['DisableIS'], - 'utf8_general_ci' + $dbi = $this->createDatabaseInterface(); + $this->assertNull(Charsets::findCollationByName($dbi, false, null)); + $this->assertNull(Charsets::findCollationByName($dbi, false, '')); + $this->assertNull(Charsets::findCollationByName($dbi, false, 'invalid')); + $actual = Charsets::findCollationByName($dbi, false, 'utf8_general_ci'); + $this->assertInstanceOf(Charsets\Collation::class, $actual); + $this->assertSame('utf8_general_ci', $actual->getName()); + } + + public function testGetCharsetsWithIS(): void + { + $dbi = $this->createDatabaseInterface(); + $charsets = Charsets::getCharsets($dbi, false); + $this->assertCount(4, $charsets); + $this->assertContainsOnlyInstancesOf(Charsets\Charset::class, $charsets); + } + + public function testGetCharsetsWithoutIS(): void + { + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + $dummyDbi->addResult( + 'SHOW CHARACTER SET', + [ + ['armscii8', 'ARMSCII-8 Armenian', 'armscii8_general_ci', '1'], + ['utf8', 'utf8_general_ci', 'UTF-8 Unicode', '3'], + ['utf8mb4', 'UTF-8 Unicode', 'utf8mb4_0900_ai_ci', '4'], + ['latin1', 'latin1_swedish_ci', 'cp1252 West European', '1'], + ], + ['Charset', 'Default collation', 'Description', 'Maxlen'] ); - $this->assertInstanceOf(Charsets\Collation::class, $actual); + $charsets = Charsets::getCharsets($dbi, true); + $this->assertCount(4, $charsets); + $this->assertContainsOnlyInstancesOf(Charsets\Charset::class, $charsets); + } - $this->assertSame('utf8_general_ci', $actual->getName()); + public function testGetCollationsWithIS(): void + { + $dbi = $this->createDatabaseInterface(); + $collations = Charsets::getCollations($dbi, false); + $this->assertCount(4, $collations); + $this->assertContainsOnly('array', $collations); + foreach ($collations as $collation) { + $this->assertContainsOnlyInstancesOf(Charsets\Collation::class, $collation); + } + } + + public function testGetCollationsWithoutIS(): void + { + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + $dummyDbi->addResult( + 'SHOW COLLATION', + [ + ['utf8mb4_general_ci', 'utf8mb4', '45', 'Yes', 'Yes', '1'], + ['armscii8_general_ci', 'armscii8', '32', 'Yes', 'Yes', '1'], + ['utf8_general_ci', 'utf8', '33', 'Yes', 'Yes', '1'], + ['utf8_bin', 'utf8', '83', '', 'Yes', '1'], + ['latin1_swedish_ci', 'latin1', '8', 'Yes', 'Yes', '1'], + ], + ['Collation', 'Charset', 'Id', 'Default', 'Compiled', 'Sortlen'] + ); + + $collations = Charsets::getCollations($dbi, true); + $this->assertCount(4, $collations); + $this->assertContainsOnly('array', $collations); + foreach ($collations as $collation) { + $this->assertContainsOnlyInstancesOf(Charsets\Collation::class, $collation); + } } } diff --git a/test/classes/CheckUserPrivilegesTest.php b/test/classes/CheckUserPrivilegesTest.php index f258940905..813866e431 100644 --- a/test/classes/CheckUserPrivilegesTest.php +++ b/test/classes/CheckUserPrivilegesTest.php @@ -20,6 +20,7 @@ class CheckUserPrivilegesTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 1; $GLOBALS['cfg']['Server']['DisableIS'] = false; $GLOBALS['col_priv'] = false; diff --git a/test/classes/Command/TwigLintCommandTest.php b/test/classes/Command/TwigLintCommandTest.php index f56f9a089a..b97d2cd703 100644 --- a/test/classes/Command/TwigLintCommandTest.php +++ b/test/classes/Command/TwigLintCommandTest.php @@ -28,15 +28,13 @@ class TwigLintCommandTest extends AbstractTestCase public function setUp(): void { - global $cfg, $config; - if (! class_exists(Command::class)) { $this->markTestSkipped('The Symfony Console is missing'); } parent::setUp(); - $cfg['environment'] = 'development'; - $config = null; + $GLOBALS['cfg']['environment'] = 'development'; + $GLOBALS['config'] = null; $this->command = new TwigLintCommand(); } diff --git a/test/classes/CommonTest.php b/test/classes/CommonTest.php index 83c05cfae1..ca156c5238 100644 --- a/test/classes/CommonTest.php +++ b/test/classes/CommonTest.php @@ -84,18 +84,16 @@ class CommonTest extends AbstractTestCase public function testCheckTokenRequestParam(): void { - global $token_mismatch, $token_provided; - $_SERVER['REQUEST_METHOD'] = 'GET'; Common::checkTokenRequestParam(); - $this->assertTrue($token_mismatch); - $this->assertFalse($token_provided); + $this->assertTrue($GLOBALS['token_mismatch']); + $this->assertFalse($GLOBALS['token_provided']); $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST['test'] = 'test'; Common::checkTokenRequestParam(); - $this->assertTrue($token_mismatch); - $this->assertFalse($token_provided); + $this->assertTrue($GLOBALS['token_mismatch']); + $this->assertFalse($GLOBALS['token_provided']); $this->assertArrayNotHasKey('test', $_POST); $_SERVER['REQUEST_METHOD'] = 'POST'; @@ -103,8 +101,8 @@ class CommonTest extends AbstractTestCase $_POST['test'] = 'test'; $_SESSION[' PMA_token '] = 'mismatch'; Common::checkTokenRequestParam(); - $this->assertTrue($token_mismatch); - $this->assertTrue($token_provided); + $this->assertTrue($GLOBALS['token_mismatch']); + $this->assertTrue($GLOBALS['token_provided']); $this->assertArrayNotHasKey('test', $_POST); $_SERVER['REQUEST_METHOD'] = 'POST'; @@ -112,8 +110,8 @@ class CommonTest extends AbstractTestCase $_POST['test'] = 'test'; $_SESSION[' PMA_token '] = 'token'; Common::checkTokenRequestParam(); - $this->assertFalse($token_mismatch); - $this->assertTrue($token_provided); + $this->assertFalse($GLOBALS['token_mismatch']); + $this->assertTrue($GLOBALS['token_provided']); $this->assertArrayHasKey('test', $_POST); $this->assertEquals('test', $_POST['test']); } diff --git a/test/classes/Config/DescriptionTest.php b/test/classes/Config/DescriptionTest.php index b9e36c3abc..6943a1a4a4 100644 --- a/test/classes/Config/DescriptionTest.php +++ b/test/classes/Config/DescriptionTest.php @@ -13,12 +13,11 @@ use function in_array; /** * @covers \PhpMyAdmin\Config\Descriptions + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled */ class DescriptionTest extends AbstractTestCase { - /** - * Setup tests - */ protected function setUp(): void { parent::setUp(); @@ -38,26 +37,57 @@ class DescriptionTest extends AbstractTestCase } /** - * @return array + * @return array<string, string[]> + * @psalm-return array<string, array{non-empty-string, 'name'|'desc'|'cmt', string}> */ public function getValues(): array { return [ - [ + 'valid name' => [ 'AllowArbitraryServer', 'name', 'Allow login to any MySQL server', ], - [ + 'valid description' => [ + 'AllowArbitraryServer', + 'desc', + 'If enabled, user can enter any MySQL server in login form for cookie auth.', + ], + 'valid comment' => [ + 'MaxDbList', + 'cmt', + 'Users cannot set a higher value', + ], + 'invalid name' => [ 'UnknownSetting', 'name', 'UnknownSetting', ], - [ + 'invalid description' => [ 'UnknownSetting', 'desc', '', ], + 'invalid comment' => [ + 'UnknownSetting', + 'cmt', + '', + ], + 'server number' => [ + 'Servers/1/DisableIS', + 'name', + 'Disable use of INFORMATION_SCHEMA', + ], + 'composed name' => [ + 'Import/format', + 'name', + 'Format of imported file', + ], + 'bb code' => [ + 'NavigationLogoLinkWindow', + 'desc', + 'Open the linked page in the main window (<code>main</code>) or in a new one (<code>new</code>).', + ], ]; } diff --git a/test/classes/Config/FormDisplayTemplateTest.php b/test/classes/Config/FormDisplayTemplateTest.php index 542d309759..f80a6e998c 100644 --- a/test/classes/Config/FormDisplayTemplateTest.php +++ b/test/classes/Config/FormDisplayTemplateTest.php @@ -266,10 +266,10 @@ class FormDisplayTemplateTest extends AbstractTestCase $this->assertEquals( [ - 'registerFieldValidator(\'testID\', \'\\\';\', true, ' + 'window.Config.registerFieldValidator(\'testID\', \'\\\';\', true, ' . '[\'\\\\r\\\\n\\\\\\\'' . '<scrIpt></\\\' + \\\'script>\'])', - 'registerFieldValidator(\'testID\', \'\', true)', + 'window.Config.registerFieldValidator(\'testID\', \'\', true)', ], $js ); diff --git a/test/classes/Config/FormDisplayTest.php b/test/classes/Config/FormDisplayTest.php index 7c0e4b2442..e89974f994 100644 --- a/test/classes/Config/FormDisplayTest.php +++ b/test/classes/Config/FormDisplayTest.php @@ -312,7 +312,8 @@ class FormDisplayTest extends AbstractTestCase public function testGetDocLink(): void { $this->assertEquals( - './url.php?url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2Flatest%2Fconfig.html%23cfg_Servers_3_test_2_', + 'index.php?route=/url&url=' + . 'https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2Flatest%2Fconfig.html%23cfg_Servers_3_test_2_', $this->object->getDocLink('Servers/3/test/2/') ); diff --git a/test/classes/Config/PageSettingsTest.php b/test/classes/Config/PageSettingsTest.php index 93b28ee493..b68adc4ed6 100644 --- a/test/classes/Config/PageSettingsTest.php +++ b/test/classes/Config/PageSettingsTest.php @@ -21,6 +21,7 @@ class PageSettingsTest extends AbstractTestCase parent::setLanguage(); parent::setGlobalConfig(); parent::setTheme(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 1; $GLOBALS['db'] = 'db'; $GLOBALS['table'] = ''; @@ -53,7 +54,7 @@ class PageSettingsTest extends AbstractTestCase '<div id="page_settings_modal">' . '<div class="page_settings">' . '<form method="post" ' - . 'action="index.php?db=db&server=1&lang=en" ' + . 'action="index.php?route=%2F&db=db&server=1&lang=en" ' . 'class="config-form disableAjax">', $html ); @@ -61,9 +62,9 @@ class PageSettingsTest extends AbstractTestCase $this->assertStringContainsString('<input type="hidden" name="submit_save" value="Browse">', $html); $this->assertStringContainsString( - "registerFieldValidator('MaxRows', 'validatePositiveNumber', true);\n" - . "registerFieldValidator('RepeatCells', 'validateNonNegativeNumber', true);\n" - . "registerFieldValidator('LimitChars', 'validatePositiveNumber', true);\n", + "window.Config.registerFieldValidator('MaxRows', 'validatePositiveNumber', true);\n" + . "window.Config.registerFieldValidator('RepeatCells', 'validateNonNegativeNumber', true);\n" + . "window.Config.registerFieldValidator('LimitChars', 'validatePositiveNumber', true);\n", $html ); } diff --git a/test/classes/ConfigStorage/RelationCleanupTest.php b/test/classes/ConfigStorage/RelationCleanupTest.php index 1a795a2ffb..e98e6f4c83 100644 --- a/test/classes/ConfigStorage/RelationCleanupTest.php +++ b/test/classes/ConfigStorage/RelationCleanupTest.php @@ -9,55 +9,20 @@ use PhpMyAdmin\ConfigStorage\RelationCleanup; use PhpMyAdmin\ConfigStorage\RelationParameters; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Tests\AbstractTestCase; -use PHPUnit\Framework\MockObject\MockObject; /** * @covers \PhpMyAdmin\ConfigStorage\RelationCleanup */ class RelationCleanupTest extends AbstractTestCase { - /** @var Relation|MockObject */ - private $relation; - - /** @var RelationCleanup */ - private $relationCleanup; - - /** @var DatabaseInterface&MockObject */ - protected $dbi; - - /** - * Prepares environment for the test. - */ - protected function setUp(): void - { - parent::setUp(); - $GLOBALS['server'] = 1; - - $this->relation = $this->getMockBuilder(Relation::class) - ->disableOriginalConstructor() - ->onlyMethods([]) - ->getMock(); - $this->dbi = $this->getMockBuilder(DatabaseInterface::class) - ->disableOriginalConstructor() - ->onlyMethods(['queryAsControlUser']) - ->getMock(); - $this->relationCleanup = new RelationCleanup($this->dbi, $this->relation); - } - - /** - * Test for column method - */ public function testColumnWithoutRelations(): void { - $this->dbi->expects($this->never()) - ->method('queryAsControlUser'); + $dbi = $this->createMock(DatabaseInterface::class); + $dbi->expects($this->never())->method('queryAsControlUser'); - $this->relationCleanup->column('database', 'table', 'column'); + (new RelationCleanup($dbi, new Relation($dbi)))->column('database', 'table', 'column'); } - /** - * Test for column method - */ public function testColumnWithRelations(): void { $_SESSION['relation'] = []; @@ -72,7 +37,8 @@ class RelationCleanupTest extends AbstractTestCase 'column_info' => 'column_info', ])->toArray(); - $this->dbi->expects($this->exactly(4)) + $dbi = $this->createPartialMock(DatabaseInterface::class, ['queryAsControlUser']); + $dbi->expects($this->exactly(4)) ->method('queryAsControlUser') ->withConsecutive( [ @@ -101,23 +67,17 @@ class RelationCleanupTest extends AbstractTestCase ] ); - $this->relationCleanup->column('database', 'table', 'column'); + (new RelationCleanup($dbi, new Relation($dbi)))->column('database', 'table', 'column'); } - /** - * Test for table method - */ public function testTableWithoutRelations(): void { - $this->dbi->expects($this->never()) - ->method('queryAsControlUser'); + $dbi = $this->createMock(DatabaseInterface::class); + $dbi->expects($this->never())->method('queryAsControlUser'); - $this->relationCleanup->table('database', 'table'); + (new RelationCleanup($dbi, new Relation($dbi)))->table('database', 'table'); } - /** - * Test for table method - */ public function testTableWithRelations(): void { $_SESSION['relation'] = []; @@ -139,7 +99,8 @@ class RelationCleanupTest extends AbstractTestCase 'navigationhiding' => 'navigationhiding', ])->toArray(); - $this->dbi->expects($this->exactly(7)) + $dbi = $this->createPartialMock(DatabaseInterface::class, ['queryAsControlUser']); + $dbi->expects($this->exactly(7)) ->method('queryAsControlUser') ->withConsecutive( [ @@ -180,23 +141,17 @@ class RelationCleanupTest extends AbstractTestCase ] ); - $this->relationCleanup->table('database', 'table'); + (new RelationCleanup($dbi, new Relation($dbi)))->table('database', 'table'); } - /** - * Test for database method - */ public function testDatabaseWithoutRelations(): void { - $this->dbi->expects($this->never()) - ->method('queryAsControlUser'); + $dbi = $this->createMock(DatabaseInterface::class); + $dbi->expects($this->never())->method('queryAsControlUser'); - $this->relationCleanup->database('database'); + (new RelationCleanup($dbi, new Relation($dbi)))->database('database'); } - /** - * Test for database method - */ public function testDatabaseWithRelations(): void { $_SESSION['relation'] = []; @@ -224,7 +179,8 @@ class RelationCleanupTest extends AbstractTestCase 'central_columns' => 'central_columns', ])->toArray(); - $this->dbi->expects($this->exactly(11)) + $dbi = $this->createPartialMock(DatabaseInterface::class, ['queryAsControlUser']); + $dbi->expects($this->exactly(11)) ->method('queryAsControlUser') ->withConsecutive( [$this->equalTo("DELETE FROM `pmadb`.`column_info` WHERE db_name = 'database'")], @@ -240,23 +196,17 @@ class RelationCleanupTest extends AbstractTestCase [$this->equalTo("DELETE FROM `pmadb`.`central_columns` WHERE db_name = 'database'")] ); - $this->relationCleanup->database('database'); + (new RelationCleanup($dbi, new Relation($dbi)))->database('database'); } - /** - * Test for user method - */ public function testUserWithoutRelations(): void { - $this->dbi->expects($this->never()) - ->method('queryAsControlUser'); + $dbi = $this->createMock(DatabaseInterface::class); + $dbi->expects($this->never())->method('queryAsControlUser'); - $this->relationCleanup->user('user'); + (new RelationCleanup($dbi, new Relation($dbi)))->user('user'); } - /** - * Test for user method - */ public function testUserWithRelations(): void { $_SESSION['relation'] = []; @@ -286,7 +236,8 @@ class RelationCleanupTest extends AbstractTestCase 'designer_settings' => 'designer_settings', ])->toArray(); - $this->dbi->expects($this->exactly(10)) + $dbi = $this->createPartialMock(DatabaseInterface::class, ['queryAsControlUser']); + $dbi->expects($this->exactly(10)) ->method('queryAsControlUser') ->withConsecutive( [$this->equalTo("DELETE FROM `pmadb`.`bookmark` WHERE `user` = 'user'")], @@ -301,6 +252,6 @@ class RelationCleanupTest extends AbstractTestCase [$this->equalTo("DELETE FROM `pmadb`.`designer_settings` WHERE `username` = 'user'")] ); - $this->relationCleanup->user('user'); + (new RelationCleanup($dbi, new Relation($dbi)))->user('user'); } } diff --git a/test/classes/ConfigStorage/RelationTest.php b/test/classes/ConfigStorage/RelationTest.php index 678fcb752f..6553430915 100644 --- a/test/classes/ConfigStorage/RelationTest.php +++ b/test/classes/ConfigStorage/RelationTest.php @@ -18,54 +18,40 @@ use function implode; */ class RelationTest extends AbstractTestCase { - /** @var Relation */ - private $relation; - /** - * Sets up the fixture, for example, opens a network connection. - * This method is called before a test is executed. + * Test for getDisplayField */ - protected function setUp(): void + public function testPMAGetDisplayField(): void { - parent::setUp(); - parent::setTheme(); - $GLOBALS['server'] = 1; - $GLOBALS['db'] = 'db'; $GLOBALS['cfg']['Server']['user'] = 'root'; $GLOBALS['cfg']['Server']['pmadb'] = 'phpmyadmin'; $GLOBALS['cfg']['Server']['DisableIS'] = false; - $GLOBALS['cfg']['ZeroConf'] = true; - $GLOBALS['cfg']['ServerDefault'] = 0; - $_SESSION['relation'] = []; - $this->relation = new Relation($GLOBALS['dbi']); - } + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); - /** - * Test for getDisplayField - */ - public function testPMAGetDisplayField(): void - { - $this->dummyDbi->addSelectDb('phpmyadmin'); + $relation = new Relation($dbi); + + $dummyDbi->addSelectDb('phpmyadmin'); $db = 'information_schema'; $table = 'CHARACTER_SETS'; $this->assertEquals( 'DESCRIPTION', - $this->relation->getDisplayField($db, $table) + $relation->getDisplayField($db, $table) ); - $this->assertAllSelectsConsumed(); + $dummyDbi->assertAllSelectsConsumed(); $db = 'information_schema'; $table = 'TABLES'; $this->assertEquals( 'TABLE_COMMENT', - $this->relation->getDisplayField($db, $table) + $relation->getDisplayField($db, $table) ); $db = 'information_schema'; $table = 'PMA'; $this->assertFalse( - $this->relation->getDisplayField($db, $table) + $relation->getDisplayField($db, $table) ); } @@ -74,6 +60,7 @@ class RelationTest extends AbstractTestCase */ public function testPMAGetComments(): void { + $GLOBALS['cfg']['Server']['DisableIS'] = false; $GLOBALS['cfg']['ServerDefault'] = 0; $dbi = $this->getMockBuilder(DatabaseInterface::class) @@ -95,13 +82,14 @@ class RelationTest extends AbstractTestCase $dbi->expects($this->any())->method('getColumns') ->will($this->returnValue($getColumnsResult)); + $relation = new Relation($dbi); + $GLOBALS['dbi'] = $dbi; - $this->relation->dbi = $GLOBALS['dbi']; $db = 'information_schema'; $this->assertEquals( [''], - $this->relation->getComments($db) + $relation->getComments($db) ); $db = 'information_schema'; @@ -111,7 +99,7 @@ class RelationTest extends AbstractTestCase 'field1' => 'Comment1', 'field2' => 'Comment1', ], - $this->relation->getComments($db, $table) + $relation->getComments($db, $table) ); } @@ -135,23 +123,25 @@ class RelationTest extends AbstractTestCase ->method('getError') ->will($this->onConsecutiveCalls('Error', '')); $GLOBALS['dbi'] = $dbi; - $this->relation->dbi = $GLOBALS['dbi']; + + $relation = new Relation($dbi); $GLOBALS['cfg']['Server']['pmadb'] = 'pmadb'; $GLOBALS['cfg']['Server']['column_info'] = 'column_info'; // Case 1 - $actual = $this->relation->tryUpgradeTransformations(); + $actual = $relation->tryUpgradeTransformations(); $this->assertFalse($actual); // Case 2 - $actual = $this->relation->tryUpgradeTransformations(); + $actual = $relation->tryUpgradeTransformations(); $this->assertTrue($actual); } public function testSearchColumnInForeignersError(): void { - $this->assertFalse($this->relation->searchColumnInForeigners([], 'id')); + $relation = new Relation($this->createDatabaseInterface()); + $this->assertFalse($relation->searchColumnInForeigners([], 'id')); } /** @@ -185,7 +175,9 @@ class RelationTest extends AbstractTestCase ], ]; - $foreigner = $this->relation->searchColumnInForeigners($foreigners, 'id'); + $relation = new Relation($this->createDatabaseInterface()); + + $foreigner = $relation->searchColumnInForeigners($foreigners, 'id'); $expected = []; $expected['foreign_field'] = 'id'; $expected['foreign_db'] = 'GSoC14'; @@ -199,21 +191,20 @@ class RelationTest extends AbstractTestCase public function testFixPmaTablesNothingWorks(): void { - parent::setGlobalDbi(); + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); - $this->relation = new Relation($this->dbi); + $relation = new Relation($dbi); - $this->dummyDbi->removeDefaultResults(); - $this->dummyDbi->addResult('SHOW TABLES FROM `db_pma`;', false); + $dummyDbi->removeDefaultResults(); + $dummyDbi->addResult('SHOW TABLES FROM `db_pma`;', false); - $this->relation->fixPmaTables('db_pma', false); - $this->assertAllQueriesConsumed(); + $relation->fixPmaTables('db_pma', false); + $dummyDbi->assertAllQueriesConsumed(); } public function testFixPmaTablesNormal(): void { - parent::setGlobalDbi(); - $GLOBALS['db'] = ''; $GLOBALS['server'] = 1; $GLOBALS['cfg']['Server']['user'] = ''; @@ -238,10 +229,12 @@ class RelationTest extends AbstractTestCase $GLOBALS['cfg']['Server']['designer_settings'] = ''; $GLOBALS['cfg']['Server']['export_templates'] = ''; - $this->relation = new Relation($this->dbi); + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + $relation = new Relation($dbi); - $this->dummyDbi->removeDefaultResults(); - $this->dummyDbi->addResult( + $dummyDbi->removeDefaultResults(); + $dummyDbi->addResult( 'SHOW TABLES FROM `db_pma`;', [ ['pma__userconfig'], @@ -249,7 +242,7 @@ class RelationTest extends AbstractTestCase ['Tables_in_db_pma'] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SHOW TABLES FROM `db_pma`', [ ['pma__userconfig'], @@ -257,15 +250,15 @@ class RelationTest extends AbstractTestCase ['Tables_in_db_pma'] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SELECT NULL FROM `pma__userconfig` LIMIT 0', [['NULL']] ); - $this->dummyDbi->addSelectDb('db_pma'); + $dummyDbi->addSelectDb('db_pma'); $_SESSION['relation'] = []; - $this->relation->fixPmaTables('db_pma', false); + $relation->fixPmaTables('db_pma', false); $this->assertArrayHasKey($GLOBALS['server'], $_SESSION['relation'], 'The cache is expected to be filled'); /** @psalm-suppress EmptyArrayAccess */ @@ -278,14 +271,12 @@ class RelationTest extends AbstractTestCase ]); $this->assertSame($relationParameters->toArray(), $_SESSION['relation'][$GLOBALS['server']]); - $this->assertAllQueriesConsumed(); - $this->assertAllSelectsConsumed(); + $dummyDbi->assertAllQueriesConsumed(); + $dummyDbi->assertAllSelectsConsumed(); } public function testFixPmaTablesNormalFixTables(): void { - parent::setGlobalDbi(); - $GLOBALS['db'] = ''; $GLOBALS['server'] = 1; $GLOBALS['cfg']['Server']['user'] = ''; @@ -310,10 +301,13 @@ class RelationTest extends AbstractTestCase $GLOBALS['cfg']['Server']['designer_settings'] = ''; $GLOBALS['cfg']['Server']['export_templates'] = ''; - $this->relation = new Relation($this->dbi); + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $relation = new Relation($dbi); - $this->dummyDbi->removeDefaultResults(); - $this->dummyDbi->addResult( + $dummyDbi->removeDefaultResults(); + $dummyDbi->addResult( 'SHOW TABLES FROM `db_pma`;', [ ['pma__userconfig'], @@ -321,7 +315,7 @@ class RelationTest extends AbstractTestCase ['Tables_in_db_pma'] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SHOW TABLES FROM `db_pma`', [ ['pma__userconfig'], @@ -329,14 +323,14 @@ class RelationTest extends AbstractTestCase ['Tables_in_db_pma'] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SELECT NULL FROM `pma__userconfig` LIMIT 0', [['NULL']] ); - $this->dummyDbi->addSelectDb('db_pma'); - $this->dummyDbi->addSelectDb('db_pma'); + $dummyDbi->addSelectDb('db_pma'); + $dummyDbi->addSelectDb('db_pma'); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__bookmark` ' . '-- CREATE TABLE IF NOT EXISTS `pma__bookmark` ( ' @@ -348,7 +342,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'Bookmarks\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__relation` ' . '-- CREATE TABLE IF NOT EXISTS `pma__relation` ( ' @@ -361,7 +355,7 @@ class RelationTest extends AbstractTestCase . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__table_info`' . ' -- CREATE TABLE IF NOT EXISTS `pma__table_info` ( ' @@ -371,7 +365,7 @@ class RelationTest extends AbstractTestCase [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__table_coords`' . ' -- CREATE TABLE IF NOT EXISTS `pma__table_coords` ( ' @@ -383,7 +377,7 @@ class RelationTest extends AbstractTestCase . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__pdf_pages`' . ' -- CREATE TABLE IF NOT EXISTS `pma__pdf_pages` ( ' @@ -393,7 +387,7 @@ class RelationTest extends AbstractTestCase . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__column_info`' . ' -- CREATE TABLE IF NOT EXISTS `pma__column_info` ( ' @@ -409,7 +403,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'Column information for phpMyAdmin\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__history` ' . '-- CREATE TABLE IF NOT EXISTS `pma__history` ( ' @@ -420,7 +414,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'SQL history for phpMyAdmin\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__recent` ' . '-- CREATE TABLE IF NOT EXISTS `pma__recent` ( ' @@ -428,7 +422,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'Recently accessed tables\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__favorite` ' . '-- CREATE TABLE IF NOT EXISTS `pma__favorite` ( ' @@ -436,7 +430,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'Favorite tables\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__table_uiprefs`' . ' -- CREATE TABLE IF NOT EXISTS `pma__table_uiprefs` ( ' @@ -447,7 +441,7 @@ class RelationTest extends AbstractTestCase . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__tracking` ' . '-- CREATE TABLE IF NOT EXISTS `pma__tracking` ( ' @@ -466,7 +460,7 @@ class RelationTest extends AbstractTestCase . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__users` ' . '-- CREATE TABLE IF NOT EXISTS `pma__users` ( ' @@ -476,7 +470,7 @@ class RelationTest extends AbstractTestCase . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__usergroups`' . ' -- CREATE TABLE IF NOT EXISTS `pma__usergroups` ( ' @@ -487,7 +481,7 @@ class RelationTest extends AbstractTestCase . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__navigationhiding`' . ' -- CREATE TABLE IF NOT EXISTS `pma__navigationhiding` ( ' @@ -498,7 +492,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'Hidden items of navigation tree\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__savedsearches`' . ' -- CREATE TABLE IF NOT EXISTS `pma__savedsearches` ( ' @@ -509,7 +503,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'Saved searches\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__central_columns`' . ' -- CREATE TABLE IF NOT EXISTS `pma__central_columns` ( ' @@ -520,7 +514,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'Central list of columns\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__designer_settings`' . ' -- CREATE TABLE IF NOT EXISTS `pma__designer_settings` ( ' @@ -529,7 +523,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'Settings related to Designer\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__export_templates`' . ' -- CREATE TABLE IF NOT EXISTS `pma__export_templates` ( ' @@ -545,7 +539,7 @@ class RelationTest extends AbstractTestCase $_SESSION['relation'] = []; - $this->relation->fixPmaTables('db_pma', true); + $relation->fixPmaTables('db_pma', true); $this->assertArrayNotHasKey('message', $GLOBALS); $this->assertArrayHasKey($GLOBALS['server'], $_SESSION['relation'], 'The cache is expected to be filled'); /** @psalm-suppress EmptyArrayAccess */ @@ -559,14 +553,12 @@ class RelationTest extends AbstractTestCase ]); $this->assertSame($relationParameters->toArray(), $_SESSION['relation'][$GLOBALS['server']]); - $this->assertAllQueriesConsumed(); - $this->assertAllSelectsConsumed(); + $dummyDbi->assertAllQueriesConsumed(); + $dummyDbi->assertAllSelectsConsumed(); } public function testFixPmaTablesNormalFixTablesWithCustomOverride(): void { - parent::setGlobalDbi(); - $GLOBALS['db'] = ''; $GLOBALS['server'] = 1; $GLOBALS['cfg']['Server']['user'] = ''; @@ -591,10 +583,13 @@ class RelationTest extends AbstractTestCase $GLOBALS['cfg']['Server']['designer_settings'] = ''; $GLOBALS['cfg']['Server']['export_templates'] = ''; - $this->relation = new Relation($this->dbi); + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); - $this->dummyDbi->removeDefaultResults(); - $this->dummyDbi->addResult( + $relation = new Relation($dbi); + + $dummyDbi->removeDefaultResults(); + $dummyDbi->addResult( 'SHOW TABLES FROM `db_pma`;', [ ['pma__userconfig'], @@ -605,7 +600,7 @@ class RelationTest extends AbstractTestCase ['Tables_in_db_pma'] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SHOW TABLES FROM `db_pma`', [ ['pma__userconfig'], @@ -616,12 +611,12 @@ class RelationTest extends AbstractTestCase ['Tables_in_db_pma'] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SELECT NULL FROM `pma__userconfig` LIMIT 0', [['NULL']] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__bookmark` ' . '-- CREATE TABLE IF NOT EXISTS `pma__bookmark` ( ' @@ -633,7 +628,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'Bookmarks\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `custom_relation_pma` ' . '-- CREATE TABLE IF NOT EXISTS `custom_relation_pma` ( ' @@ -646,7 +641,7 @@ class RelationTest extends AbstractTestCase . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__table_info`' . ' -- CREATE TABLE IF NOT EXISTS `pma__table_info` ( ' @@ -656,7 +651,7 @@ class RelationTest extends AbstractTestCase [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__table_coords`' . ' -- CREATE TABLE IF NOT EXISTS `pma__table_coords` ( ' @@ -668,7 +663,7 @@ class RelationTest extends AbstractTestCase . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__pdf_pages`' . ' -- CREATE TABLE IF NOT EXISTS `pma__pdf_pages` ( ' @@ -678,7 +673,7 @@ class RelationTest extends AbstractTestCase . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__column_info`' . ' -- CREATE TABLE IF NOT EXISTS `pma__column_info` ( ' @@ -694,7 +689,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'Column information for phpMyAdmin\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__history` ' . '-- CREATE TABLE IF NOT EXISTS `pma__history` ( ' @@ -705,7 +700,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'SQL history for phpMyAdmin\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__recent` ' . '-- CREATE TABLE IF NOT EXISTS `pma__recent` ( ' @@ -713,7 +708,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'Recently accessed tables\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__favorite` ' . '-- CREATE TABLE IF NOT EXISTS `pma__favorite` ( ' @@ -721,7 +716,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'Favorite tables\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__table_uiprefs`' . ' -- CREATE TABLE IF NOT EXISTS `pma__table_uiprefs` ( ' @@ -732,7 +727,7 @@ class RelationTest extends AbstractTestCase . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__tracking` ' . '-- CREATE TABLE IF NOT EXISTS `pma__tracking` ( ' @@ -751,7 +746,7 @@ class RelationTest extends AbstractTestCase . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__users` ' . '-- CREATE TABLE IF NOT EXISTS `pma__users` ( ' @@ -761,7 +756,7 @@ class RelationTest extends AbstractTestCase . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__usergroups`' . ' -- CREATE TABLE IF NOT EXISTS `pma__usergroups` ( ' @@ -772,7 +767,7 @@ class RelationTest extends AbstractTestCase . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__navigationhiding`' . ' -- CREATE TABLE IF NOT EXISTS `pma__navigationhiding` ( ' @@ -783,7 +778,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'Hidden items of navigation tree\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__savedsearches`' . ' -- CREATE TABLE IF NOT EXISTS `pma__savedsearches` ( ' @@ -794,7 +789,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'Saved searches\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__central_columns`' . ' -- CREATE TABLE IF NOT EXISTS `pma__central_columns` ( ' @@ -805,7 +800,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'Central list of columns\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__designer_settings`' . ' -- CREATE TABLE IF NOT EXISTS `pma__designer_settings` ( ' @@ -814,7 +809,7 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'Settings related to Designer\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__export_templates`' . ' -- CREATE TABLE IF NOT EXISTS `pma__export_templates` ( ' @@ -830,9 +825,9 @@ class RelationTest extends AbstractTestCase $_SESSION['relation'] = []; - $this->dummyDbi->addSelectDb('db_pma'); - $this->dummyDbi->addSelectDb('db_pma'); - $this->relation->fixPmaTables('db_pma', true); + $dummyDbi->addSelectDb('db_pma'); + $dummyDbi->addSelectDb('db_pma'); + $relation->fixPmaTables('db_pma', true); $this->assertArrayNotHasKey('message', $GLOBALS); $this->assertArrayHasKey($GLOBALS['server'], $_SESSION['relation'], 'The cache is expected to be filled'); /** @psalm-suppress EmptyArrayAccess */ @@ -846,14 +841,12 @@ class RelationTest extends AbstractTestCase ]); $this->assertSame($relationParameters->toArray(), $_SESSION['relation'][$GLOBALS['server']]); - $this->assertAllQueriesConsumed(); - $this->assertAllSelectsConsumed(); + $dummyDbi->assertAllQueriesConsumed(); + $dummyDbi->assertAllSelectsConsumed(); } public function testFixPmaTablesNormalFixTablesFails(): void { - parent::setGlobalDbi(); - $GLOBALS['db'] = ''; $GLOBALS['server'] = 1; $GLOBALS['cfg']['Server']['user'] = ''; @@ -878,10 +871,13 @@ class RelationTest extends AbstractTestCase $GLOBALS['cfg']['Server']['designer_settings'] = ''; $GLOBALS['cfg']['Server']['export_templates'] = ''; - $this->relation = new Relation($this->dbi); + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); - $this->dummyDbi->removeDefaultResults(); - $this->dummyDbi->addResult( + $relation = new Relation($dbi); + + $dummyDbi->removeDefaultResults(); + $dummyDbi->addResult( 'SHOW TABLES FROM `db_pma`;', [ ['pma__userconfig'], @@ -890,8 +886,8 @@ class RelationTest extends AbstractTestCase ); // Fail the query - $this->dummyDbi->addErrorCode('MYSQL_ERROR'); - $this->dummyDbi->addResult( + $dummyDbi->addErrorCode('MYSQL_ERROR'); + $dummyDbi->addResult( '-- -------------------------------------------------------- -- --' . ' Table structure for table `pma__bookmark` ' . '-- CREATE TABLE IF NOT EXISTS `pma__bookmark` ( ' @@ -903,13 +899,13 @@ class RelationTest extends AbstractTestCase . ' COMMENT=\'Bookmarks\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', false ); - $this->dummyDbi->addSelectDb('db_pma'); + $dummyDbi->addSelectDb('db_pma'); $this->assertSame('', $GLOBALS['cfg']['Server']['pmadb']); $_SESSION['relation'] = []; - $this->relation->fixPmaTables('db_pma', true); + $relation->fixPmaTables('db_pma', true); $this->assertArrayHasKey('message', $GLOBALS); $this->assertSame('MYSQL_ERROR', $GLOBALS['message']); @@ -917,54 +913,61 @@ class RelationTest extends AbstractTestCase $this->assertSame([], $_SESSION['relation']); - $this->assertAllQueriesConsumed(); - $this->assertAllErrorCodesConsumed(); - $this->assertAllSelectsConsumed(); + $dummyDbi->assertAllQueriesConsumed(); + $dummyDbi->assertAllErrorCodesConsumed(); + $dummyDbi->assertAllSelectsConsumed(); } public function testCreatePmaDatabase(): void { - parent::setGlobalDbi(); - $this->relation = new Relation($this->dbi); + $GLOBALS['cfg']['Server']['user'] = 'root'; + $GLOBALS['cfg']['Server']['pmadb'] = 'phpmyadmin'; - $this->dummyDbi->removeDefaultResults(); - $this->dummyDbi->addResult( + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $relation = new Relation($dbi); + + $dummyDbi->removeDefaultResults(); + $dummyDbi->addResult( 'CREATE DATABASE IF NOT EXISTS `phpmyadmin`', [] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SHOW TABLES FROM `phpmyadmin`', [] ); - $this->dummyDbi->addSelectDb('phpmyadmin'); + $dummyDbi->addSelectDb('phpmyadmin'); $this->assertArrayNotHasKey('errno', $GLOBALS); $this->assertTrue( - $this->relation->createPmaDatabase('phpmyadmin') + $relation->createPmaDatabase('phpmyadmin') ); $this->assertArrayNotHasKey('message', $GLOBALS); - $this->assertAllQueriesConsumed(); - $this->assertAllErrorCodesConsumed(); - $this->assertAllSelectsConsumed(); + $dummyDbi->assertAllQueriesConsumed(); + $dummyDbi->assertAllErrorCodesConsumed(); + $dummyDbi->assertAllSelectsConsumed(); } public function testCreatePmaDatabaseFailsError1044(): void { - parent::setGlobalDbi(); - $this->relation = new Relation($this->dbi); + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $relation = new Relation($dbi); - $this->dummyDbi->removeDefaultResults(); - $this->dummyDbi->addErrorCode('MYSQL_ERROR'); - $this->dummyDbi->addResult('CREATE DATABASE IF NOT EXISTS `phpmyadmin`', false); + $dummyDbi->removeDefaultResults(); + $dummyDbi->addErrorCode('MYSQL_ERROR'); + $dummyDbi->addResult('CREATE DATABASE IF NOT EXISTS `phpmyadmin`', false); $GLOBALS['errno'] = 1044;// ER_DBACCESS_DENIED_ERROR $this->assertFalse( - $this->relation->createPmaDatabase('phpmyadmin') + $relation->createPmaDatabase('phpmyadmin') ); $this->assertArrayHasKey('message', $GLOBALS); @@ -975,35 +978,40 @@ class RelationTest extends AbstractTestCase $GLOBALS['message'] ); - $this->assertAllQueriesConsumed(); - $this->assertAllErrorCodesConsumed(); + $dummyDbi->assertAllQueriesConsumed(); + $dummyDbi->assertAllErrorCodesConsumed(); } public function testCreatePmaDatabaseFailsError1040(): void { - parent::setGlobalDbi(); - $this->relation = new Relation($this->dbi); + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); - $this->dummyDbi->removeDefaultResults(); - $this->dummyDbi->addErrorCode('Too many connections'); - $this->dummyDbi->addResult('CREATE DATABASE IF NOT EXISTS `pma_1040`', false); + $relation = new Relation($dbi); + + $dummyDbi->removeDefaultResults(); + $dummyDbi->addErrorCode('Too many connections'); + $dummyDbi->addResult('CREATE DATABASE IF NOT EXISTS `pma_1040`', false); $GLOBALS['errno'] = 1040; $this->assertFalse( - $this->relation->createPmaDatabase('pma_1040') + $relation->createPmaDatabase('pma_1040') ); $this->assertArrayHasKey('message', $GLOBALS); $this->assertSame('Too many connections', $GLOBALS['message']); - $this->assertAllQueriesConsumed(); - $this->assertAllErrorCodesConsumed(); + $dummyDbi->assertAllQueriesConsumed(); + $dummyDbi->assertAllErrorCodesConsumed(); } public function testGetDefaultPmaTableNames(): void { - $this->relation = new Relation($this->dbi); + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $relation = new Relation($dbi); $data = [ 'pma__bookmark' => implode("\n", [ @@ -1395,7 +1403,7 @@ class RelationTest extends AbstractTestCase $this->assertSame( $data, - $this->relation->getDefaultPmaTableNames([]) + $relation->getDefaultPmaTableNames([]) ); $data['pma__export_templates'] = implode("\n", [ @@ -1422,36 +1430,38 @@ class RelationTest extends AbstractTestCase $this->assertSame( $data, - $this->relation->getDefaultPmaTableNames(['pma__export_templates' => 'db_exporttemplates_pma']) + $relation->getDefaultPmaTableNames(['pma__export_templates' => 'db_exporttemplates_pma']) ); } public function testInitRelationParamsCacheDefaultDbNameDbDoesNotExist(): void { - parent::setGlobalDbi(); - $GLOBALS['db'] = ''; $GLOBALS['server'] = 0; - $this->dummyDbi->removeDefaultResults(); - $this->dummyDbi->addResult('SHOW TABLES FROM `phpmyadmin`;', false); + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); - $relation = new Relation($this->dbi); + $dummyDbi->removeDefaultResults(); + $dummyDbi->addResult('SHOW TABLES FROM `phpmyadmin`;', false); + + $relation = new Relation($dbi); $relation->initRelationParamsCache(); - $this->assertAllQueriesConsumed(); + $dummyDbi->assertAllQueriesConsumed(); } public function testInitRelationParamsCacheDefaultDbNameDbExistsServerZero(): void { - parent::setGlobalDbi(); - $GLOBALS['db'] = ''; $GLOBALS['server'] = 0; $GLOBALS['cfg']['Server'] = []; - $this->dummyDbi->removeDefaultResults(); - $this->dummyDbi->addResult( + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $dummyDbi->removeDefaultResults(); + $dummyDbi->addResult( 'SHOW TABLES FROM `phpmyadmin`;', [ ['pma__userconfig'], @@ -1461,7 +1471,7 @@ class RelationTest extends AbstractTestCase $_SESSION['relation'] = []; - $relation = new Relation($this->dbi); + $relation = new Relation($dbi); $relation->initRelationParamsCache(); $this->assertArrayHasKey($GLOBALS['server'], $_SESSION['relation'], 'The cache is expected to be filled'); @@ -1476,13 +1486,11 @@ class RelationTest extends AbstractTestCase 'userconfig' => 'pma__userconfig', 'pmadb' => false,// This is the expected value for server = 0 ], $GLOBALS['cfg']['Server']); - $this->assertAllQueriesConsumed(); + $dummyDbi->assertAllQueriesConsumed(); } public function testInitRelationParamsCacheDefaultDbNameDbExistsFirstServer(): void { - parent::setGlobalDbi(); - $GLOBALS['db'] = ''; $GLOBALS['server'] = 1; $GLOBALS['cfg']['Server'] = []; @@ -1508,8 +1516,11 @@ class RelationTest extends AbstractTestCase $GLOBALS['cfg']['Server']['designer_settings'] = ''; $GLOBALS['cfg']['Server']['export_templates'] = ''; - $this->dummyDbi->removeDefaultResults(); - $this->dummyDbi->addResult( + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $dummyDbi->removeDefaultResults(); + $dummyDbi->addResult( 'SHOW TABLES FROM `phpmyadmin`;', [ ['pma__userconfig'], @@ -1517,7 +1528,7 @@ class RelationTest extends AbstractTestCase ['Tables_in_phpmyadmin'] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SHOW TABLES FROM `phpmyadmin`', [ ['pma__userconfig'], @@ -1525,7 +1536,7 @@ class RelationTest extends AbstractTestCase ['Tables_in_phpmyadmin'] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SELECT NULL FROM `pma__userconfig` LIMIT 0', [ ['NULL'], @@ -1535,10 +1546,10 @@ class RelationTest extends AbstractTestCase $_SESSION['relation'] = []; - $this->dummyDbi->addSelectDb('phpmyadmin'); - $relation = new Relation($this->dbi); + $dummyDbi->addSelectDb('phpmyadmin'); + $relation = new Relation($dbi); $relation->initRelationParamsCache(); - $this->assertAllSelectsConsumed(); + $dummyDbi->assertAllSelectsConsumed(); $this->assertArrayHasKey($GLOBALS['server'], $_SESSION['relation'], 'The cache is expected to be filled'); /** @psalm-suppress EmptyArrayAccess */ @@ -1576,13 +1587,11 @@ class RelationTest extends AbstractTestCase 'export_templates' => '', ], $GLOBALS['cfg']['Server']); - $this->assertAllQueriesConsumed(); + $dummyDbi->assertAllQueriesConsumed(); } public function testInitRelationParamsCacheDefaultDbNameDbExistsFirstServerNotWorkingTable(): void { - parent::setGlobalDbi(); - $GLOBALS['db'] = ''; $GLOBALS['server'] = 1; $GLOBALS['cfg']['Server'] = []; @@ -1608,8 +1617,11 @@ class RelationTest extends AbstractTestCase $GLOBALS['cfg']['Server']['designer_settings'] = ''; $GLOBALS['cfg']['Server']['export_templates'] = ''; - $this->dummyDbi->removeDefaultResults(); - $this->dummyDbi->addResult( + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $dummyDbi->removeDefaultResults(); + $dummyDbi->addResult( 'SHOW TABLES FROM `phpmyadmin`;', [ ['pma__userconfig'], @@ -1617,7 +1629,7 @@ class RelationTest extends AbstractTestCase ['Tables_in_phpmyadmin'] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SHOW TABLES FROM `phpmyadmin`', [ ['pma__userconfig'], @@ -1625,14 +1637,14 @@ class RelationTest extends AbstractTestCase ['Tables_in_phpmyadmin'] ); - $this->dummyDbi->addResult('SELECT NULL FROM `pma__userconfig` LIMIT 0', false); + $dummyDbi->addResult('SELECT NULL FROM `pma__userconfig` LIMIT 0', false); $_SESSION['relation'] = []; - $this->dummyDbi->addSelectDb('phpmyadmin'); - $relation = new Relation($this->dbi); + $dummyDbi->addSelectDb('phpmyadmin'); + $relation = new Relation($dbi); $relation->initRelationParamsCache(); - $this->assertAllSelectsConsumed(); + $dummyDbi->assertAllSelectsConsumed(); $this->assertArrayHasKey($GLOBALS['server'], $_SESSION['relation'], 'The cache is expected to be filled'); /** @psalm-suppress EmptyArrayAccess */ @@ -1669,13 +1681,11 @@ class RelationTest extends AbstractTestCase 'export_templates' => '', ], $GLOBALS['cfg']['Server']); - $this->assertAllQueriesConsumed(); + $dummyDbi->assertAllQueriesConsumed(); } public function testInitRelationParamsCacheDefaultDbNameDbExistsFirstServerOverride(): void { - parent::setGlobalDbi(); - $GLOBALS['db'] = ''; $GLOBALS['server'] = 1; $GLOBALS['cfg']['Server'] = []; @@ -1701,8 +1711,11 @@ class RelationTest extends AbstractTestCase $GLOBALS['cfg']['Server']['designer_settings'] = ''; $GLOBALS['cfg']['Server']['export_templates'] = ''; - $this->dummyDbi->removeDefaultResults(); - $this->dummyDbi->addResult( + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $dummyDbi->removeDefaultResults(); + $dummyDbi->addResult( 'SHOW TABLES FROM `PMA-storage`;', [ [ @@ -1713,7 +1726,7 @@ class RelationTest extends AbstractTestCase ['Tables_in_PMA-storage'] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SHOW TABLES FROM `PMA-storage`', [ [ @@ -1724,7 +1737,7 @@ class RelationTest extends AbstractTestCase ['Tables_in_PMA-storage'] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SELECT NULL FROM `pma__userconfig_custom` LIMIT 0', [ ['NULL'], @@ -1732,11 +1745,11 @@ class RelationTest extends AbstractTestCase ['NULL'] ); - $this->dummyDbi->addSelectDb('PMA-storage'); + $dummyDbi->addSelectDb('PMA-storage'); $_SESSION['relation'] = []; - $relation = new Relation($this->dbi); + $relation = new Relation($dbi); $relation->initRelationParamsCache(); $this->assertArrayHasKey( @@ -1746,10 +1759,10 @@ class RelationTest extends AbstractTestCase . 'was undertood (pma__userconfig vs pma__userconfig_custom)' ); - $this->assertAllQueriesConsumed(); - $this->assertAllSelectsConsumed(); + $dummyDbi->assertAllQueriesConsumed(); + $dummyDbi->assertAllSelectsConsumed(); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SHOW TABLES FROM `PMA-storage`', [ [ @@ -1760,7 +1773,7 @@ class RelationTest extends AbstractTestCase ['Tables_in_PMA-storage'] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SELECT NULL FROM `pma__userconfig_custom` LIMIT 0', [ ['NULL'], @@ -1768,11 +1781,11 @@ class RelationTest extends AbstractTestCase ['NULL'] ); - $this->dummyDbi->addSelectDb('PMA-storage'); + $dummyDbi->addSelectDb('PMA-storage'); /** @psalm-suppress EmptyArrayAccess */ unset($_SESSION['relation'][$GLOBALS['server']]); $relationData = $relation->getRelationParameters(); - $this->assertAllSelectsConsumed(); + $dummyDbi->assertAllSelectsConsumed(); $relationParameters = RelationParameters::fromArray([ 'db' => 'PMA-storage', @@ -1805,7 +1818,7 @@ class RelationTest extends AbstractTestCase 'export_templates' => '', ], $GLOBALS['cfg']['Server']); - $this->assertAllQueriesConsumed(); + $dummyDbi->assertAllQueriesConsumed(); } /** @@ -1816,17 +1829,22 @@ class RelationTest extends AbstractTestCase */ public function testRenameTable(array $params, array $queries): void { + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $relation = new Relation($dbi); + $GLOBALS['server'] = 1; $_SESSION['relation'] = []; $_SESSION['relation'][$GLOBALS['server']] = RelationParameters::fromArray($params)->toArray(); foreach ($queries as $query) { - $this->dummyDbi->addResult($query, []); + $dummyDbi->addResult($query, []); } - $this->relation->renameTable('db_1', 'db_2', 'table_1', 'table_2'); + $relation->renameTable('db_1', 'db_2', 'table_1', 'table_2'); - $this->assertAllQueriesConsumed(); + $dummyDbi->assertAllQueriesConsumed(); } /** @@ -1873,6 +1891,11 @@ class RelationTest extends AbstractTestCase public function testRenameTableEscaping(): void { + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $relation = new Relation($dbi); + $GLOBALS['server'] = 1; $_SESSION['relation'] = []; $_SESSION['relation'][$GLOBALS['server']] = RelationParameters::fromArray([ @@ -1883,14 +1906,14 @@ class RelationTest extends AbstractTestCase 'table_coords' => 'table`coords', ])->toArray(); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'UPDATE `pma``db`.`table``coords` SET db_name = \'db\\\'1\', table_name = \'table\\\'2\'' . ' WHERE db_name = \'db\\\'1\' AND table_name = \'table\\\'1\'', [] ); - $this->relation->renameTable('db\'1', 'db\'1', 'table\'1', 'table\'2'); + $relation->renameTable('db\'1', 'db\'1', 'table\'1', 'table\'2'); - $this->assertAllQueriesConsumed(); + $dummyDbi->assertAllQueriesConsumed(); } } diff --git a/test/classes/ConfigStorage/UserGroupsTest.php b/test/classes/ConfigStorage/UserGroupsTest.php index 7f293c3683..1c958506bf 100644 --- a/test/classes/ConfigStorage/UserGroupsTest.php +++ b/test/classes/ConfigStorage/UserGroupsTest.php @@ -30,6 +30,7 @@ class UserGroupsTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['db'] = ''; $GLOBALS['table'] = ''; diff --git a/test/classes/ConfigTest.php b/test/classes/ConfigTest.php index 68864504b5..dca54db8db 100644 --- a/test/classes/ConfigTest.php +++ b/test/classes/ConfigTest.php @@ -54,6 +54,7 @@ class ConfigTest extends AbstractTestCase { parent::setUp(); parent::setTheme(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $_SERVER['HTTP_USER_AGENT'] = ''; $this->object = new Config(); $GLOBALS['server'] = 0; diff --git a/test/classes/ConsoleTest.php b/test/classes/ConsoleTest.php index 23ebd5ec3a..243f00846b 100644 --- a/test/classes/ConsoleTest.php +++ b/test/classes/ConsoleTest.php @@ -13,6 +13,7 @@ class ConsoleTest extends AbstractTestCase { public function testGetScripts(): void { + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $console = new Console(); $this->assertEquals(['console.js'], $console->getScripts()); } diff --git a/test/classes/Controllers/AbstractControllerTest.php b/test/classes/Controllers/AbstractControllerTest.php new file mode 100644 index 0000000000..1ac2d3eade --- /dev/null +++ b/test/classes/Controllers/AbstractControllerTest.php @@ -0,0 +1,141 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers; + +use PhpMyAdmin\Controllers\AbstractController; +use PhpMyAdmin\Html\MySQLDocumentation; +use PhpMyAdmin\Message; +use PhpMyAdmin\Sanitize; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\AbstractController + */ +class AbstractControllerTest extends AbstractTestCase +{ + protected function setUp(): void + { + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + } + + public function testCheckParametersWithMissingParameters(): void + { + $_REQUEST = []; + + $response = new ResponseRenderer(); + $template = new Template(); + $controller = new class ($response, $template) extends AbstractController { + /** + * @psalm-param non-empty-list<non-empty-string> $params + */ + public function testCheckParameters(array $params): void + { + parent::checkParameters($params); + } + }; + + \PhpMyAdmin\ResponseRenderer::getInstance()->setAjax(false); + + $GLOBALS['param1'] = 'param1'; + $GLOBALS['param2'] = null; + + $message = 'index.php: Missing parameter: param2'; + $message .= MySQLDocumentation::showDocumentation('faq', 'faqmissingparameters', true); + $message .= '[br]'; + $expected = $template->render('error/generic', [ + 'lang' => 'en', + 'dir' => 'ltr', + 'error_message' => Sanitize::sanitizeMessage($message), + ]); + + $this->expectOutputString($expected); + + $controller->testCheckParameters(['param1', 'param2']); + + $this->assertSame(400, $response->getHttpResponseCode()); + } + + public function testCheckParametersWithAllParameters(): void + { + $_REQUEST = []; + + $response = new ResponseRenderer(); + $controller = new class ($response, new Template()) extends AbstractController { + /** + * @psalm-param non-empty-list<non-empty-string> $params + */ + public function testCheckParameters(array $params): void + { + parent::checkParameters($params); + } + }; + + \PhpMyAdmin\ResponseRenderer::getInstance()->setAjax(false); + + $GLOBALS['param1'] = 'param1'; + $GLOBALS['param2'] = 'param2'; + + $this->expectOutputString(''); + + $controller->testCheckParameters(['param1', 'param2']); + + $this->assertSame(200, $response->getHttpResponseCode()); + } + + public function testSendErrorResponseWithJson(): void + { + $response = new ResponseRenderer(); + $response->setAjax(true); + + $controller = new class ($response, new Template()) extends AbstractController { + /** + * @psalm-param int<400,599> $statusCode + */ + public function testSendErrorResponse(string $message, int $statusCode = 400): void + { + parent::sendErrorResponse($message, $statusCode); + } + }; + + $controller->testSendErrorResponse('Error message.', 404); + + $this->assertSame(404, $response->getHttpResponseCode()); + $this->assertFalse($response->hasSuccessState()); + $this->assertSame('', $response->getHTMLResult()); + $this->assertSame([ + 'isErrorResponse' => true, + 'message' => 'Error message.', + ], $response->getJSONResult()); + } + + public function testSendErrorResponseWithHtml(): void + { + $response = new ResponseRenderer(); + $response->setAjax(false); + + $controller = new class ($response, new Template()) extends AbstractController { + /** + * @psalm-param int<400,599> $statusCode + */ + public function testSendErrorResponse(string $message, int $statusCode = 400): void + { + parent::sendErrorResponse($message, $statusCode); + } + }; + + $controller->testSendErrorResponse('Error message.', 404); + + $this->assertSame(404, $response->getHttpResponseCode()); + $this->assertFalse($response->hasSuccessState()); + $this->assertSame( + Message::error('Error message.')->getDisplay(), + $response->getHTMLResult() + ); + $this->assertSame([], $response->getJSONResult()); + } +} diff --git a/test/classes/Controllers/CheckRelationsControllerTest.php b/test/classes/Controllers/CheckRelationsControllerTest.php index 590d6ba3e6..46cd7ee3e6 100644 --- a/test/classes/Controllers/CheckRelationsControllerTest.php +++ b/test/classes/Controllers/CheckRelationsControllerTest.php @@ -6,9 +6,11 @@ namespace PhpMyAdmin\Tests\Controllers; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\Controllers\CheckRelationsController; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; /** @@ -16,9 +18,26 @@ use PhpMyAdmin\Tests\Stubs\ResponseRenderer; */ class CheckRelationsControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void + { + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + public function testCheckRelationsController(): void { $GLOBALS['server'] = 1; + $GLOBALS['db'] = ''; + $GLOBALS['table'] = ''; $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['PMA_PHP_SELF'] = 'index.php'; diff --git a/test/classes/Controllers/CollationConnectionControllerTest.php b/test/classes/Controllers/CollationConnectionControllerTest.php new file mode 100644 index 0000000000..1b581104fd --- /dev/null +++ b/test/classes/Controllers/CollationConnectionControllerTest.php @@ -0,0 +1,38 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers; + +use PhpMyAdmin\Config; +use PhpMyAdmin\Controllers\CollationConnectionController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\ResponseRenderer; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Url; + +/** + * @covers \PhpMyAdmin\Controllers\CollationConnectionController + */ +class CollationConnectionControllerTest extends AbstractTestCase +{ + public function testInvoke(): void + { + $_POST['collation_connection'] = 'utf8mb4_general_ci'; + + $response = $this->createMock(ResponseRenderer::class); + $response->expects($this->once())->method('header') + ->with('Location: index.php?route=/' . Url::getCommonRaw([], '&')); + + $config = $this->createMock(Config::class); + $config->expects($this->once())->method('setUserValue') + ->with(null, 'DefaultConnectionCollation', 'utf8mb4_general_ci', 'utf8mb4_unicode_ci'); + + (new CollationConnectionController( + $response, + new Template(), + $config + ))($this->createStub(ServerRequest::class)); + } +} diff --git a/test/classes/Controllers/Database/MultiTableQuery/TablesControllerTest.php b/test/classes/Controllers/Database/MultiTableQuery/TablesControllerTest.php index 0d74f7be9f..3ee720c6fe 100644 --- a/test/classes/Controllers/Database/MultiTableQuery/TablesControllerTest.php +++ b/test/classes/Controllers/Database/MultiTableQuery/TablesControllerTest.php @@ -5,18 +5,29 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Database\MultiTableQuery; use PhpMyAdmin\Controllers\Database\MultiTableQuery\TablesController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; /** * @covers \PhpMyAdmin\Controllers\Database\MultiTableQuery\TablesController */ class TablesControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + protected function setUp(): void { parent::setUp(); parent::setLanguage(); - parent::setGlobalDbi(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; parent::loadContainerBuilder(); parent::loadDbiIntoContainerBuilder(); $GLOBALS['server'] = 1; @@ -32,10 +43,9 @@ class TablesControllerTest extends AbstractTestCase ]; $_GET['db'] = 'test'; - global $containerBuilder; /** @var TablesController $multiTableQueryController */ - $multiTableQueryController = $containerBuilder->get(TablesController::class); - $multiTableQueryController(); + $multiTableQueryController = $GLOBALS['containerBuilder']->get(TablesController::class); + $multiTableQueryController($this->createStub(ServerRequest::class)); $this->assertSame( [ 'foreignKeyConstrains' => [ diff --git a/test/classes/Controllers/Database/PrivilegesControllerTest.php b/test/classes/Controllers/Database/PrivilegesControllerTest.php index c5cb8fe205..c3d1ae8171 100644 --- a/test/classes/Controllers/Database/PrivilegesControllerTest.php +++ b/test/classes/Controllers/Database/PrivilegesControllerTest.php @@ -5,10 +5,13 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Database; use PhpMyAdmin\Controllers\Database\PrivilegesController; -use PhpMyAdmin\ResponseRenderer; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Server\Privileges; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; use PhpMyAdmin\Url; use function __; @@ -19,24 +22,42 @@ use function _pgettext; */ class PrivilegesControllerTest extends AbstractTestCase { - /** - * Configures global environment. - */ + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + protected function setUp(): void { parent::setUp(); parent::setLanguage(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; } public function testIndex(): void { - global $dbi, $db, $server, $cfg, $PMA_PHP_SELF; + $GLOBALS['db'] = 'test_db'; + $GLOBALS['server'] = 0; + $GLOBALS['cfg']['Server']['DisableIS'] = false; + $GLOBALS['PMA_PHP_SELF'] = 'index.php'; + + $this->dummyDbi->addResult( + 'SHOW TABLES FROM `test_db`;', + [['test_table']], + ['Tables_in_test_db'] + ); - $db = 'db'; - $server = 0; - $cfg['Server']['DisableIS'] = false; - $PMA_PHP_SELF = 'index.php'; + // phpcs:disable Generic.Files.LineLength.TooLong + $this->dummyDbi->addResult( + 'SELECT *, `TABLE_SCHEMA` AS `Db`, `TABLE_NAME` AS `Name`, `TABLE_TYPE` AS `TABLE_TYPE`, `ENGINE` AS `Engine`, `ENGINE` AS `Type`, `VERSION` AS `Version`, `ROW_FORMAT` AS `Row_format`, `TABLE_ROWS` AS `Rows`, `AVG_ROW_LENGTH` AS `Avg_row_length`, `DATA_LENGTH` AS `Data_length`, `MAX_DATA_LENGTH` AS `Max_data_length`, `INDEX_LENGTH` AS `Index_length`, `DATA_FREE` AS `Data_free`, `AUTO_INCREMENT` AS `Auto_increment`, `CREATE_TIME` AS `Create_time`, `UPDATE_TIME` AS `Update_time`, `CHECK_TIME` AS `Check_time`, `TABLE_COLLATION` AS `Collation`, `CHECKSUM` AS `Checksum`, `CREATE_OPTIONS` AS `Create_options`, `TABLE_COMMENT` AS `Comment` FROM `information_schema`.`TABLES` t WHERE `TABLE_SCHEMA` IN (\'test_db\') ORDER BY Name ASC LIMIT 250 OFFSET 0', + [['def', 'test_db', 'test_table', 'BASE TABLE', 'InnoDB', '10', 'Dynamic', '3', '5461', '16384', '0', '0', '0', '4', '2011-12-13 14:15:16', null, null, 'utf8mb4_general_ci', null, '', '', '0', 'N', 'test_db', 'test_table', 'BASE TABLE', 'InnoDB', 'InnoDB', '10', 'Dynamic', '3', '5461', '16384', '0', '0', '0', '4', '2011-12-13 14:15:16', null, null, 'utf8mb4_general_ci', null, '', '']], + ['TABLE_CATALOG', 'TABLE_SCHEMA', 'TABLE_NAME', 'TABLE_TYPE', 'ENGINE', 'VERSION', 'ROW_FORMAT', 'TABLE_ROWS', 'AVG_ROW_LENGTH', 'DATA_LENGTH', 'MAX_DATA_LENGTH', 'INDEX_LENGTH', 'DATA_FREE', 'AUTO_INCREMENT', 'CREATE_TIME', 'UPDATE_TIME', 'CHECK_TIME', 'TABLE_COLLATION', 'CHECKSUM', 'CREATE_OPTIONS', 'TABLE_COMMENT', 'MAX_INDEX_LENGTH', 'TEMPORARY', 'Db', 'Name', 'TABLE_TYPE', 'Engine', 'Type', 'Version', 'Row_format', 'Rows', 'Avg_row_length', 'Data_length', 'Max_data_length', 'Index_length', 'Data_free', 'Auto_increment', 'Create_time', 'Update_time', 'Check_time', 'Collation', 'Checksum', 'Create_options', 'Comment'] + ); + // phpcs:enable $privileges = []; @@ -44,20 +65,21 @@ class PrivilegesControllerTest extends AbstractTestCase $serverPrivileges->method('getAllPrivileges') ->willReturn($privileges); - $actual = (new PrivilegesController( - ResponseRenderer::getInstance(), + $response = new ResponseRenderer(); + (new PrivilegesController( + $response, new Template(), - $db, $serverPrivileges, - $dbi - ))(['checkprivsdb' => $db]); + $GLOBALS['dbi'] + ))($this->createStub(ServerRequest::class)); + $actual = $response->getHTMLResult(); $this->assertStringContainsString( - Url::getCommon(['db' => $db], ''), + Url::getCommon(['db' => $GLOBALS['db']], ''), $actual ); - $this->assertStringContainsString($db, $actual); + $this->assertStringContainsString($GLOBALS['db'], $actual); $this->assertStringContainsString( __('User'), @@ -89,9 +111,5 @@ class PrivilegesControllerTest extends AbstractTestCase _pgettext('Create new user', 'New'), $actual ); - $this->assertStringContainsString( - Url::getCommon(['checkprivsdb' => $db]), - $actual - ); } } diff --git a/test/classes/Controllers/Database/Structure/FavoriteTableControllerTest.php b/test/classes/Controllers/Database/Structure/FavoriteTableControllerTest.php index 738bd4d077..b723148042 100644 --- a/test/classes/Controllers/Database/Structure/FavoriteTableControllerTest.php +++ b/test/classes/Controllers/Database/Structure/FavoriteTableControllerTest.php @@ -6,9 +6,11 @@ namespace PhpMyAdmin\Tests\Controllers\Database\Structure; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\Controllers\Database\Structure\FavoriteTableController; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\RecentFavoriteTable; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer as ResponseStub; use ReflectionClass; @@ -19,11 +21,26 @@ use function json_encode; */ class FavoriteTableControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void + { + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + public function testSynchronizeFavoriteTables(): void { $GLOBALS['server'] = 1; $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['PMA_PHP_SELF'] = 'index.php'; + $GLOBALS['db'] = 'db'; $favoriteInstance = $this->getMockBuilder(RecentFavoriteTable::class) ->disableOriginalConstructor() @@ -39,7 +56,6 @@ class FavoriteTableControllerTest extends AbstractTestCase $controller = new FavoriteTableController( new ResponseStub(), new Template(), - 'db', new Relation($this->dbi) ); diff --git a/test/classes/Controllers/Database/Structure/RealRowCountControllerTest.php b/test/classes/Controllers/Database/Structure/RealRowCountControllerTest.php index 07ddd9ad8d..99af60b65a 100644 --- a/test/classes/Controllers/Database/Structure/RealRowCountControllerTest.php +++ b/test/classes/Controllers/Database/Structure/RealRowCountControllerTest.php @@ -5,8 +5,11 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Database\Structure; use PhpMyAdmin\Controllers\Database\Structure\RealRowCountController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer as ResponseStub; use function json_encode; @@ -16,6 +19,20 @@ use function json_encode; */ class RealRowCountControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void + { + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + public function testRealRowCount(): void { $GLOBALS['server'] = 1; @@ -30,14 +47,14 @@ class RealRowCountControllerTest extends AbstractTestCase $_REQUEST['table'] = 'City'; - (new RealRowCountController($response, new Template(), 'world', $this->dbi))(); + (new RealRowCountController($response, new Template(), $this->dbi))($this->createStub(ServerRequest::class)); $json = $response->getJSONResult(); $this->assertEquals('4,079', $json['real_row_count']); $_REQUEST['real_row_count_all'] = 'on'; - (new RealRowCountController($response, new Template(), 'world', $this->dbi))(); + (new RealRowCountController($response, new Template(), $this->dbi))($this->createStub(ServerRequest::class)); $json = $response->getJSONResult(); $expected = [ diff --git a/test/classes/Controllers/Database/StructureControllerTest.php b/test/classes/Controllers/Database/StructureControllerTest.php index 4a52e075b0..1cd678f816 100644 --- a/test/classes/Controllers/Database/StructureControllerTest.php +++ b/test/classes/Controllers/Database/StructureControllerTest.php @@ -95,7 +95,6 @@ class StructureControllerTest extends AbstractTestCase $controller = new StructureController( $this->response, $this->template, - $GLOBALS['db'], $this->relation, $this->replication, $this->relationCleanup, @@ -143,7 +142,6 @@ class StructureControllerTest extends AbstractTestCase $controller = new StructureController( $this->response, $this->template, - $GLOBALS['db'], $this->relation, $this->replication, $this->relationCleanup, @@ -175,7 +173,6 @@ class StructureControllerTest extends AbstractTestCase $controller = new StructureController( $this->response, $this->template, - $GLOBALS['db'], $this->relation, $this->replication, $this->relationCleanup, @@ -231,7 +228,6 @@ class StructureControllerTest extends AbstractTestCase $controller = new StructureController( $this->response, $this->template, - $GLOBALS['db'], $this->relation, $this->replication, $this->relationCleanup, @@ -256,7 +252,6 @@ class StructureControllerTest extends AbstractTestCase $controller = new StructureController( $this->response, $this->template, - $GLOBALS['db'], $this->relation, $this->replication, $this->relationCleanup, @@ -291,7 +286,6 @@ class StructureControllerTest extends AbstractTestCase $controller = new StructureController( $this->response, $this->template, - $GLOBALS['db'], $this->relation, $this->replication, $this->relationCleanup, @@ -330,7 +324,6 @@ class StructureControllerTest extends AbstractTestCase $controller = new StructureController( $this->response, $this->template, - $GLOBALS['db'], $this->relation, $this->replication, $this->relationCleanup, @@ -367,7 +360,6 @@ class StructureControllerTest extends AbstractTestCase $controller = new StructureController( $this->response, $this->template, - $GLOBALS['db'], $this->relation, $this->replication, $this->relationCleanup, @@ -421,17 +413,16 @@ class StructureControllerTest extends AbstractTestCase */ public function testGetValuesForMroongaTable(): void { - global $containerBuilder; parent::loadContainerBuilder(); parent::loadDbiIntoContainerBuilder(); $GLOBALS['db'] = 'testdb'; $GLOBALS['table'] = 'mytable'; - $containerBuilder->setParameter('db', $GLOBALS['db']); - $containerBuilder->setParameter('table', $GLOBALS['table']); + $GLOBALS['containerBuilder']->setParameter('db', $GLOBALS['db']); + $GLOBALS['containerBuilder']->setParameter('table', $GLOBALS['table']); /** @var StructureController $structureController */ - $structureController = $containerBuilder->get(StructureController::class); + $structureController = $GLOBALS['containerBuilder']->get(StructureController::class); $this->assertSame( [ diff --git a/test/classes/Controllers/Export/ExportControllerTest.php b/test/classes/Controllers/Export/ExportControllerTest.php index b50d70d1dc..98594de963 100644 --- a/test/classes/Controllers/Export/ExportControllerTest.php +++ b/test/classes/Controllers/Export/ExportControllerTest.php @@ -5,11 +5,13 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Export; use PhpMyAdmin\Controllers\Export\ExportController; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Export; use PhpMyAdmin\FieldMetadata; use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; use function htmlspecialchars; @@ -25,12 +27,30 @@ use const MYSQLI_TYPE_STRING; */ class ExportControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void + { + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + public function testExportController(): void { + parent::loadDbiIntoContainerBuilder(); + $GLOBALS['server'] = 1; $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['lang'] = 'en'; $GLOBALS['PMA_PHP_SELF'] = 'index.php'; + $GLOBALS['sql_indexes'] = null; + $GLOBALS['sql_auto_increments'] = null; $GLOBALS['dblist'] = (object) ['databases' => ['test_db']]; $GLOBALS['config']->selectServer(); $GLOBALS['cfg'] = $GLOBALS['config']->settings; @@ -168,6 +188,9 @@ SQL; $exportController = new ExportController(new ResponseRenderer(), new Template(), new Export($this->dbi)); $exportController($request); $output = $this->getActualOutputForAssertion(); + + $this->assertStringNotContainsString('Missing parameter: what', $output); + $this->assertStringNotContainsString('Missing parameter: export_type', $output); $this->assertStringContainsString(htmlspecialchars($expectedOutput), $output); } } diff --git a/test/classes/Controllers/Export/Template/CreateControllerTest.php b/test/classes/Controllers/Export/Template/CreateControllerTest.php index ca43f31784..238c46fdf7 100644 --- a/test/classes/Controllers/Export/Template/CreateControllerTest.php +++ b/test/classes/Controllers/Export/Template/CreateControllerTest.php @@ -7,11 +7,13 @@ namespace PhpMyAdmin\Tests\Controllers\Export\Template; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\ConfigStorage\RelationParameters; use PhpMyAdmin\Controllers\Export\Template\CreateController; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Export\Template as ExportTemplate; use PhpMyAdmin\Export\TemplateModel; use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; /** @@ -19,10 +21,22 @@ use PhpMyAdmin\Tests\Stubs\ResponseRenderer; */ class CreateControllerTest extends AbstractTestCase { - public function testCreate(): void + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void { - global $cfg; + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + public function testCreate(): void + { $GLOBALS['server'] = 1; $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['PMA_PHP_SELF'] = 'index.php'; @@ -34,7 +48,7 @@ class CreateControllerTest extends AbstractTestCase 'export_templates' => 'table', ])->toArray(); - $cfg['Server']['user'] = 'user'; + $GLOBALS['cfg']['Server']['user'] = 'user'; $response = new ResponseRenderer(); $template = new Template(); diff --git a/test/classes/Controllers/Export/Template/DeleteControllerTest.php b/test/classes/Controllers/Export/Template/DeleteControllerTest.php index eac9eca9e3..3adb988eb9 100644 --- a/test/classes/Controllers/Export/Template/DeleteControllerTest.php +++ b/test/classes/Controllers/Export/Template/DeleteControllerTest.php @@ -6,10 +6,12 @@ namespace PhpMyAdmin\Tests\Controllers\Export\Template; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\Controllers\Export\Template\DeleteController; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Export\TemplateModel; use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; /** @@ -17,15 +19,27 @@ use PhpMyAdmin\Tests\Stubs\ResponseRenderer; */ class DeleteControllerTest extends AbstractTestCase { - public function testDelete(): void + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void { - global $cfg; + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + public function testDelete(): void + { $GLOBALS['server'] = 1; $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['PMA_PHP_SELF'] = 'index.php'; - $cfg['Server']['user'] = 'user'; + $GLOBALS['cfg']['Server']['user'] = 'user'; $response = new ResponseRenderer(); $request = $this->createStub(ServerRequest::class); diff --git a/test/classes/Controllers/Export/Template/LoadControllerTest.php b/test/classes/Controllers/Export/Template/LoadControllerTest.php index 51ab552e03..b2fcad5ed3 100644 --- a/test/classes/Controllers/Export/Template/LoadControllerTest.php +++ b/test/classes/Controllers/Export/Template/LoadControllerTest.php @@ -7,10 +7,12 @@ namespace PhpMyAdmin\Tests\Controllers\Export\Template; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\ConfigStorage\RelationParameters; use PhpMyAdmin\Controllers\Export\Template\LoadController; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Export\TemplateModel; use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; /** @@ -18,10 +20,22 @@ use PhpMyAdmin\Tests\Stubs\ResponseRenderer; */ class LoadControllerTest extends AbstractTestCase { - public function testLoad(): void + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void { - global $cfg; + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + public function testLoad(): void + { $GLOBALS['server'] = 1; $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['PMA_PHP_SELF'] = 'index.php'; @@ -33,7 +47,7 @@ class LoadControllerTest extends AbstractTestCase 'export_templates' => 'table', ])->toArray(); - $cfg['Server']['user'] = 'user'; + $GLOBALS['cfg']['Server']['user'] = 'user'; $response = new ResponseRenderer(); $request = $this->createStub(ServerRequest::class); diff --git a/test/classes/Controllers/Export/Template/UpdateControllerTest.php b/test/classes/Controllers/Export/Template/UpdateControllerTest.php index c7b04d7028..abcced8f5f 100644 --- a/test/classes/Controllers/Export/Template/UpdateControllerTest.php +++ b/test/classes/Controllers/Export/Template/UpdateControllerTest.php @@ -6,10 +6,12 @@ namespace PhpMyAdmin\Tests\Controllers\Export\Template; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\Controllers\Export\Template\UpdateController; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Export\TemplateModel; use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; /** @@ -17,15 +19,27 @@ use PhpMyAdmin\Tests\Stubs\ResponseRenderer; */ class UpdateControllerTest extends AbstractTestCase { - public function testUpdate(): void + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void { - global $cfg; + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + public function testUpdate(): void + { $GLOBALS['server'] = 1; $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['PMA_PHP_SELF'] = 'index.php'; - $cfg['Server']['user'] = 'user'; + $GLOBALS['cfg']['Server']['user'] = 'user'; $response = new ResponseRenderer(); $request = $this->createStub(ServerRequest::class); diff --git a/test/classes/Controllers/Import/ImportControllerTest.php b/test/classes/Controllers/Import/ImportControllerTest.php index 31a731d76e..c2c48534dc 100644 --- a/test/classes/Controllers/Import/ImportControllerTest.php +++ b/test/classes/Controllers/Import/ImportControllerTest.php @@ -5,17 +5,32 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Import; use PhpMyAdmin\Controllers\Import\ImportController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; /** * @covers \PhpMyAdmin\Controllers\Import\ImportController */ class ImportControllerTest extends AbstractTestCase { - public function testIndexParametrized(): void + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void { - global $containerBuilder, $db, $table, $sql_query; + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + public function testIndexParametrized(): void + { parent::loadContainerBuilder(); parent::loadDbiIntoContainerBuilder(); parent::setLanguage(); @@ -24,19 +39,20 @@ class ImportControllerTest extends AbstractTestCase $GLOBALS['server'] = 1; $GLOBALS['cfg']['Server']['user'] = 'user'; $GLOBALS['PMA_PHP_SELF'] = 'index.php'; + parent::loadResponseIntoContainerBuilder(); // Some params where not added as they where not required for this test $_POST['db'] = 'pma_test'; $_POST['table'] = 'table1'; - $db = $_POST['db']; - $table = $_POST['table']; + $GLOBALS['db'] = $_POST['db']; + $GLOBALS['table'] = $_POST['table']; $_POST['parameterized'] = 'on'; $_POST['parameters'] = [':nomEta' => 'Saint-Louis - Châteaulin', ':1' => '4']; $_POST['sql_query'] = 'SELECT A.*' . "\n" . 'FROM table1 A' . "\n" . 'WHERE A.nomEtablissement = :nomEta AND foo = :1 AND `:a` IS NULL'; - $sql_query = $_POST['sql_query']; + $GLOBALS['sql_query'] = $_POST['sql_query']; $this->dummyDbi->addResult( 'SELECT A.* FROM table1 A WHERE A.nomEtablissement = \'Saint-Louis - Châteaulin\'' @@ -55,11 +71,11 @@ class ImportControllerTest extends AbstractTestCase ); /** @var ImportController $importController */ - $importController = $containerBuilder->get(ImportController::class); + $importController = $GLOBALS['containerBuilder']->get(ImportController::class); $this->dummyDbi->addSelectDb('pma_test'); $this->dummyDbi->addSelectDb('pma_test'); - $importController(); - $this->assertAllSelectsConsumed(); + $importController($this->createStub(ServerRequest::class)); + $this->dummyDbi->assertAllSelectsConsumed(); $this->assertResponseWasSuccessfull(); $this->assertStringContainsString( @@ -73,6 +89,6 @@ class ImportControllerTest extends AbstractTestCase $this->getResponseHtmlResult() ); - $this->assertAllQueriesConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); } } diff --git a/test/classes/Controllers/JavaScriptMessagesControllerTest.php b/test/classes/Controllers/JavaScriptMessagesControllerTest.php index 0c84d4ea7c..49097f0c2b 100644 --- a/test/classes/Controllers/JavaScriptMessagesControllerTest.php +++ b/test/classes/Controllers/JavaScriptMessagesControllerTest.php @@ -7,7 +7,6 @@ namespace PhpMyAdmin\Tests\Controllers; use PhpMyAdmin\Controllers\JavaScriptMessagesController; use PHPUnit\Framework\TestCase; -use function __; use function json_decode; use function ob_end_clean; use function ob_get_contents; @@ -22,24 +21,20 @@ class JavaScriptMessagesControllerTest extends TestCase { public function testIndex(): void { - global $cfg; - - $cfg['GridEditing'] = 'double-click'; - ob_start(); (new JavaScriptMessagesController())(); $actual = ob_get_contents(); ob_end_clean(); $this->assertIsString($actual); - $this->assertStringStartsWith('var Messages = {', $actual); + $this->assertStringStartsWith('window.Messages = {', $actual); $this->assertStringEndsWith('};', $actual); - $json = substr($actual, strlen('var Messages = '), -1); + $json = substr($actual, strlen('window.Messages = '), -1); $array = json_decode($json, true); $this->assertIsArray($array); - $this->assertArrayHasKey('strConfirm', $array); - $this->assertEquals(__('Confirm'), $array['strConfirm']); + $this->assertArrayHasKey('strDoYouReally', $array); + $this->assertEquals('Do you really want to execute "%s"?', $array['strDoYouReally']); } } diff --git a/test/classes/Controllers/LintControllerTest.php b/test/classes/Controllers/LintControllerTest.php new file mode 100644 index 0000000000..d125d9b1ae --- /dev/null +++ b/test/classes/Controllers/LintControllerTest.php @@ -0,0 +1,99 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers; + +use PhpMyAdmin\Controllers\LintController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +use function json_encode; + +/** + * @covers \PhpMyAdmin\Controllers\LintController + */ +class LintControllerTest extends AbstractTestCase +{ + protected function setUp(): void + { + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + } + + public function testWithoutParams(): void + { + $_POST = []; + + $this->getLintController()($this->createStub(ServerRequest::class)); + + $output = $this->getActualOutputForAssertion(); + $this->assertJson($output); + $this->assertJsonStringEqualsJsonString('[]', $output); + } + + public function testWithoutSqlErrors(): void + { + $_POST['sql_query'] = 'SELECT * FROM `actor` WHERE `actor_id` = 1;'; + + $this->getLintController()($this->createStub(ServerRequest::class)); + + $output = $this->getActualOutputForAssertion(); + $this->assertJson($output); + $this->assertJsonStringEqualsJsonString('[]', $output); + } + + public function testWithSqlErrors(): void + { + $_POST['sql_query'] = 'SELECT * FROM `actor` WHEREE `actor_id` = 1;'; + + $expectedJson = json_encode([ + [ + 'message' => 'An alias was previously found. (near <code>`actor_id`</code>)', + 'fromLine' => 0, + 'fromColumn' => 29, + 'toLine' => 0, + 'toColumn' => 39, + 'severity' => 'error', + ], + [ + 'message' => 'Unexpected token. (near <code>`actor_id`</code>)', + 'fromLine' => 0, + 'fromColumn' => 29, + 'toLine' => 0, + 'toColumn' => 39, + 'severity' => 'error', + ], + [ + 'message' => 'Unexpected token. (near <code>=</code>)', + 'fromLine' => 0, + 'fromColumn' => 40, + 'toLine' => 0, + 'toColumn' => 41, + 'severity' => 'error', + ], + [ + 'message' => 'Unexpected token. (near <code>1</code>)', + 'fromLine' => 0, + 'fromColumn' => 42, + 'toLine' => 0, + 'toColumn' => 43, + 'severity' => 'error', + ], + ]); + $this->assertNotFalse($expectedJson); + + $this->getLintController()($this->createStub(ServerRequest::class)); + + $output = $this->getActualOutputForAssertion(); + $this->assertJson($output); + $this->assertJsonStringEqualsJsonString($expectedJson, $output); + } + + private function getLintController(): LintController + { + return new LintController(new ResponseRenderer(), new Template()); + } +} diff --git a/test/classes/Controllers/NavigationControllerTest.php b/test/classes/Controllers/NavigationControllerTest.php index f3515ab042..ededc3f9bc 100644 --- a/test/classes/Controllers/NavigationControllerTest.php +++ b/test/classes/Controllers/NavigationControllerTest.php @@ -5,7 +5,10 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers; use PhpMyAdmin\Controllers\NavigationController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use function sprintf; @@ -14,13 +17,26 @@ use function sprintf; */ class NavigationControllerTest extends AbstractTestCase { - public function testIndex(): void + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void { - global $containerBuilder; + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + public function testIndex(): void + { parent::loadContainerBuilder(); parent::loadDbiIntoContainerBuilder(); parent::setLanguage(); + $this->setTheme(); $GLOBALS['server'] = 1; $GLOBALS['PMA_PHP_SELF'] = 'index.php'; @@ -111,10 +127,10 @@ class NavigationControllerTest extends AbstractTestCase ); /** @var NavigationController $navigationController */ - $navigationController = $containerBuilder->get(NavigationController::class); + $navigationController = $GLOBALS['containerBuilder']->get(NavigationController::class); $_POST['full'] = '1'; $this->setResponseIsAjax(); - $navigationController(); + $navigationController($this->createStub(ServerRequest::class)); $this->assertResponseWasSuccessfull(); $responseMessage = $this->getResponseJsonResult()['message']; @@ -162,13 +178,11 @@ class NavigationControllerTest extends AbstractTestCase . '</div>', $responseMessage ); - $this->assertAllQueriesConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); } public function testIndexWithPosAndValue(): void { - global $containerBuilder; - parent::loadContainerBuilder(); parent::loadDbiIntoContainerBuilder(); parent::setLanguage(); @@ -267,10 +281,10 @@ class NavigationControllerTest extends AbstractTestCase ); /** @var NavigationController $navigationController */ - $navigationController = $containerBuilder->get(NavigationController::class); + $navigationController = $GLOBALS['containerBuilder']->get(NavigationController::class); $_POST['full'] = '1'; $this->setResponseIsAjax(); - $navigationController(); + $navigationController($this->createStub(ServerRequest::class)); $this->assertResponseWasSuccessfull(); $responseMessage = $this->getResponseJsonResult()['message']; @@ -430,6 +444,6 @@ class NavigationControllerTest extends AbstractTestCase . '</div>' . "\n", $responseMessage ); - $this->assertAllQueriesConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); } } diff --git a/test/classes/Controllers/Normalization/AddNewPrimaryControllerTest.php b/test/classes/Controllers/Normalization/AddNewPrimaryControllerTest.php new file mode 100644 index 0000000000..d55100fc08 --- /dev/null +++ b/test/classes/Controllers/Normalization/AddNewPrimaryControllerTest.php @@ -0,0 +1,44 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Normalization; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Normalization\AddNewPrimaryController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Normalization; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +/** + * @covers \PhpMyAdmin\Controllers\Normalization\AddNewPrimaryController + */ +class AddNewPrimaryControllerTest extends AbstractTestCase +{ + public function testDefault(): void + { + $GLOBALS['cfg']['Server']['DisableIS'] = false; + $GLOBALS['col_priv'] = false; + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + + $dbiDummy = $this->createDbiDummy(); + + $dbi = $this->createDatabaseInterface($dbiDummy); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new AddNewPrimaryController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + $this->assertStringContainsString('<table id="table_columns"', $response->getHTMLResult()); + } +} diff --git a/test/classes/Controllers/Normalization/CreateNewColumnControllerTest.php b/test/classes/Controllers/Normalization/CreateNewColumnControllerTest.php new file mode 100644 index 0000000000..2a18d763bb --- /dev/null +++ b/test/classes/Controllers/Normalization/CreateNewColumnControllerTest.php @@ -0,0 +1,45 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Normalization; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Normalization\CreateNewColumnController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Normalization; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +/** + * @covers \PhpMyAdmin\Controllers\Normalization\CreateNewColumnController + */ +class CreateNewColumnControllerTest extends AbstractTestCase +{ + public function testDefault(): void + { + $GLOBALS['cfg']['Server']['DisableIS'] = false; + $GLOBALS['col_priv'] = false; + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $_POST['numFields'] = 1; + + $dbiDummy = $this->createDbiDummy(); + + $dbi = $this->createDatabaseInterface($dbiDummy); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new CreateNewColumnController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + $this->assertStringContainsString('<table id="table_columns"', $response->getHTMLResult()); + } +} diff --git a/test/classes/Controllers/Normalization/FirstNormalForm/FirstStepControllerTest.php b/test/classes/Controllers/Normalization/FirstNormalForm/FirstStepControllerTest.php new file mode 100644 index 0000000000..b8869b3251 --- /dev/null +++ b/test/classes/Controllers/Normalization/FirstNormalForm/FirstStepControllerTest.php @@ -0,0 +1,82 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Normalization\FirstNormalForm; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Normalization\FirstNormalForm\FirstStepController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Normalization; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +use function in_array; + +/** + * @covers \PhpMyAdmin\Controllers\Normalization\FirstNormalForm\FirstStepController + */ +class FirstStepControllerTest extends AbstractTestCase +{ + /** + * @psalm-param '1nf'|'2nf'|'3nf' $expectedNormalizeTo + * + * @dataProvider providerForTestDefault + */ + public function testDefault(?string $normalizeTo, string $expectedNormalizeTo): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $_POST['normalizeTo'] = $normalizeTo; + + $dbiDummy = $this->createDbiDummy(); + $dbiDummy->addSelectDb('test_db'); + + $dbi = $this->createDatabaseInterface($dbiDummy); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new FirstStepController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + $files = $response->getHeader()->getScripts()->getFiles(); + $this->assertTrue( + in_array(['name' => 'normalization.js', 'fire' => 1], $files, true), + 'normalization.js script was not included in the response.' + ); + $this->assertTrue( + in_array(['name' => 'vendor/jquery/jquery.uitablefilter.js', 'fire' => 0], $files, true), + 'vendor/jquery/jquery.uitablefilter.js script was not included in the response.' + ); + + $output = $response->getHTMLResult(); + $this->assertStringContainsString('First step of normalization (1NF)', $output); + $this->assertStringContainsString( + '<div id=\'mainContent\' data-normalizeto=\'' . $expectedNormalizeTo . '\'>', + $output + ); + $this->assertStringContainsString('<option value=\'no_such_col\'>No such column</option>', $output); + } + + /** + * @return array<int, array{string|null, '1nf'|'2nf'|'3nf'}> + */ + public function providerForTestDefault(): iterable + { + return [ + [null, '1nf'], + ['', '1nf'], + ['invalid', '1nf'], + ['1nf', '1nf'], + ['2nf', '2nf'], + ['3nf', '3nf'], + ]; + } +} diff --git a/test/classes/Controllers/Normalization/FirstNormalForm/FourthStepControllerTest.php b/test/classes/Controllers/Normalization/FirstNormalForm/FourthStepControllerTest.php new file mode 100644 index 0000000000..a77cd1cb60 --- /dev/null +++ b/test/classes/Controllers/Normalization/FirstNormalForm/FourthStepControllerTest.php @@ -0,0 +1,50 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Normalization\FirstNormalForm; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Normalization\FirstNormalForm\FourthStepController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Normalization; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +/** + * @covers \PhpMyAdmin\Controllers\Normalization\FirstNormalForm\FourthStepController + */ +class FourthStepControllerTest extends AbstractTestCase +{ + public function testDefault(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + + $dbiDummy = $this->createDbiDummy(); + $dbiDummy->addSelectDb('test_db'); + + $dbi = $this->createDatabaseInterface($dbiDummy); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new FourthStepController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + // phpcs:disable Generic.Files.LineLength.TooLong + $this->assertSame([ + 'legendText' => 'Step 1.4 Remove redundant columns', + 'headText' => 'Do you have a group of columns which on combining gives an existing column? For example, if you have first_name, last_name and full_name then combining first_name and last_name gives full_name which is redundant.', + 'subText' => 'Check the columns which are redundant and click on remove. If no redundant column, click on \'No redundant column\'', + 'extra' => '<input type="checkbox" value="id">id [ int(11) ]<br><input type="checkbox" value="name">name [ varchar(20) ]<br><input type="checkbox" value="datetimefield">datetimefield [ datetime ]<br><br><input class="btn btn-secondary" type="submit" id="removeRedundant" value="Remove selected"><input class="btn btn-secondary" type="submit" value="No redundant column" onclick="goToFinish1NF();">', + ], $response->getJSONResult()); + // phpcs:enable + } +} diff --git a/test/classes/Controllers/Normalization/FirstNormalForm/SecondStepControllerTest.php b/test/classes/Controllers/Normalization/FirstNormalForm/SecondStepControllerTest.php new file mode 100644 index 0000000000..edce909046 --- /dev/null +++ b/test/classes/Controllers/Normalization/FirstNormalForm/SecondStepControllerTest.php @@ -0,0 +1,46 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Normalization\FirstNormalForm; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Normalization\FirstNormalForm\SecondStepController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Normalization; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +/** + * @covers \PhpMyAdmin\Controllers\Normalization\FirstNormalForm\SecondStepController + */ +class SecondStepControllerTest extends AbstractTestCase +{ + public function testDefault(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + + $dbi = $this->createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new SecondStepController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + $this->assertSame([ + 'legendText' => 'Step 1.2 Have a primary key', + 'headText' => 'Primary key already exists.', + 'subText' => 'Taking you to next step…', + 'hasPrimaryKey' => '1', + 'extra' => '', + ], $response->getJSONResult()); + } +} diff --git a/test/classes/Controllers/Normalization/FirstNormalForm/ThirdStepControllerTest.php b/test/classes/Controllers/Normalization/FirstNormalForm/ThirdStepControllerTest.php new file mode 100644 index 0000000000..0b06272051 --- /dev/null +++ b/test/classes/Controllers/Normalization/FirstNormalForm/ThirdStepControllerTest.php @@ -0,0 +1,51 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Normalization\FirstNormalForm; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Normalization\FirstNormalForm\ThirdStepController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Normalization; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +/** + * @covers \PhpMyAdmin\Controllers\Normalization\FirstNormalForm\ThirdStepController + */ +class ThirdStepControllerTest extends AbstractTestCase +{ + public function testDefault(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + + $dbiDummy = $this->createDbiDummy(); + $dbiDummy->addSelectDb('test_db'); + + $dbi = $this->createDatabaseInterface($dbiDummy); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new ThirdStepController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + // phpcs:disable Generic.Files.LineLength.TooLong + $this->assertSame([ + 'legendText' => 'Step 1.3 Move repeating groups', + 'headText' => 'Do you have a group of two or more columns that are closely related and are all repeating the same attribute? For example, a table that holds data on books might have columns such as book_id, author1, author2, author3 and so on which form a repeating group. In this case a new table (book_id, author) should be created.', + 'subText' => 'Check the columns which form a repeating group. If no such group, click on \'No repeating group\'', + 'extra' => '<input type="checkbox" value="id">id [ int(11) ]<br><input type="checkbox" value="name">name [ varchar(20) ]<br><input type="checkbox" value="datetimefield">datetimefield [ datetime ]<br><br><input class="btn btn-secondary" type="submit" id="moveRepeatingGroup" value="Done"><input class="btn btn-secondary" type="submit" value="No repeating group" onclick="goToStep4();">', + 'primary_key' => '["id"]', + ], $response->getJSONResult()); + // phpcs:enable + } +} diff --git a/test/classes/Controllers/Normalization/GetColumnsControllerTest.php b/test/classes/Controllers/Normalization/GetColumnsControllerTest.php new file mode 100644 index 0000000000..d9bc364973 --- /dev/null +++ b/test/classes/Controllers/Normalization/GetColumnsControllerTest.php @@ -0,0 +1,48 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Normalization; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Normalization\GetColumnsController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Normalization; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +/** + * @covers \PhpMyAdmin\Controllers\Normalization\GetColumnsController + */ +class GetColumnsControllerTest extends AbstractTestCase +{ + public function testDefault(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + + $dbiDummy = $this->createDbiDummy(); + $dbiDummy->addSelectDb('test_db'); + + $dbi = $this->createDatabaseInterface($dbiDummy); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new GetColumnsController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + // phpcs:disable Generic.Files.LineLength.TooLong + $this->assertSame( + '<option selected disabled>Select one…</option><option value="no_such_col">No such column</option><option value="name">name [ varchar(20) ]</option>', + $response->getHTMLResult() + ); + // phpcs:enable + } +} diff --git a/test/classes/Controllers/Normalization/MainControllerTest.php b/test/classes/Controllers/Normalization/MainControllerTest.php new file mode 100644 index 0000000000..803967e84c --- /dev/null +++ b/test/classes/Controllers/Normalization/MainControllerTest.php @@ -0,0 +1,77 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Normalization; + +use PhpMyAdmin\Controllers\Normalization\MainController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +use function in_array; + +/** + * @covers \PhpMyAdmin\Controllers\Normalization\MainController + */ +class MainControllerTest extends AbstractTestCase +{ + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void + { + parent::setUp(); + parent::setLanguage(); + parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + parent::loadContainerBuilder(); + parent::loadDbiIntoContainerBuilder(); + $GLOBALS['server'] = 1; + $GLOBALS['PMA_PHP_SELF'] = 'index.php'; + parent::loadResponseIntoContainerBuilder(); + $GLOBALS['db'] = 'my_db'; + $GLOBALS['table'] = 'test_tbl'; + } + + public function testNormalization(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $response = new ResponseRenderer(); + + $controller = new MainController($response, new Template()); + $controller($this->createStub(ServerRequest::class)); + + $files = $response->getHeader()->getScripts()->getFiles(); + $this->assertTrue( + in_array(['name' => 'normalization.js', 'fire' => 1], $files, true), + 'normalization.js script was not included in the response.' + ); + $this->assertTrue( + in_array(['name' => 'vendor/jquery/jquery.uitablefilter.js', 'fire' => 0], $files, true), + 'vendor/jquery/jquery.uitablefilter.js script was not included in the response.' + ); + + $output = $response->getHTMLResult(); + $this->assertStringContainsString( + '<form method="post" action="index.php?route=/normalization/1nf/step1&lang=en"' + . ' name="normalize" id="normalizeTable"', + $output + ); + $this->assertStringContainsString('<input type="hidden" name="db" value="test_db">', $output); + $this->assertStringContainsString('<input type="hidden" name="table" value="test_table">', $output); + $this->assertStringContainsString('type="radio" name="normalizeTo"', $output); + $this->assertStringContainsString('id="normalizeToRadio1" value="1nf" checked>', $output); + $this->assertStringContainsString('id="normalizeToRadio2" value="2nf">', $output); + $this->assertStringContainsString('id="normalizeToRadio3" value="3nf">', $output); + } +} diff --git a/test/classes/Controllers/Normalization/MoveRepeatingGroupTest.php b/test/classes/Controllers/Normalization/MoveRepeatingGroupTest.php new file mode 100644 index 0000000000..b7ff21a73a --- /dev/null +++ b/test/classes/Controllers/Normalization/MoveRepeatingGroupTest.php @@ -0,0 +1,53 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Normalization; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Normalization\MoveRepeatingGroup; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Message; +use PhpMyAdmin\Normalization; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +/** + * @covers \PhpMyAdmin\Controllers\Normalization\MoveRepeatingGroup + */ +class MoveRepeatingGroupTest extends AbstractTestCase +{ + public function testDefault(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $_POST['repeatingColumns'] = 'col1, col2'; + $_POST['newTable'] = 'new_table'; + $_POST['newColumn'] = 'new_column'; + $_POST['primary_columns'] = 'id,col1'; + + // phpcs:disable Generic.Files.LineLength.TooLong + $dbiDummy = $this->createDbiDummy(); + $dbiDummy->addSelectDb('test_db'); + $dbiDummy->addResult('CREATE TABLE `new_table` SELECT `id`,`col1`,`col1` as `new_column` FROM `test_table` UNION SELECT `id`,`col1`,`col2` as `new_column` FROM `test_table`', []); + $dbiDummy->addResult('ALTER TABLE `test_table` DROP `col1`, DROP `col2`', []); + // phpcs:enable + + $dbi = $this->createDatabaseInterface($dbiDummy); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new MoveRepeatingGroup( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + $message = Message::success('Selected repeating group has been moved to the table \'test_table\''); + $this->assertSame(['queryError' => false, 'message' => $message->getDisplay()], $response->getJSONResult()); + } +} diff --git a/test/classes/Controllers/Normalization/PartialDependenciesControllerTest.php b/test/classes/Controllers/Normalization/PartialDependenciesControllerTest.php new file mode 100644 index 0000000000..2d01962001 --- /dev/null +++ b/test/classes/Controllers/Normalization/PartialDependenciesControllerTest.php @@ -0,0 +1,56 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Normalization; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Normalization\PartialDependenciesController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Normalization; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +/** + * @covers \PhpMyAdmin\Controllers\Normalization\PartialDependenciesController + */ +class PartialDependenciesControllerTest extends AbstractTestCase +{ + public function testDefault(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + + // phpcs:disable Generic.Files.LineLength.TooLong + $dbiDummy = $this->createDbiDummy(); + $dbiDummy->addSelectDb('test_db'); + $dbiDummy->addResult('SELECT COUNT(*) FROM (SELECT * FROM `test_table` LIMIT 500) as dt;', [['0']], ['dt']); + $dbiDummy->addResult( + 'SELECT COUNT(DISTINCT `id`) as \'`id`_cnt\', COUNT(DISTINCT `name`) as \'`name`_cnt\', COUNT(DISTINCT `datetimefield`) as \'`datetimefield`_cnt\' FROM (SELECT * FROM `test_table` LIMIT 500) as dt;', + [], + ['`id`_cnt', '`name`_cnt', '`datetimefield`_cnt', '`datetimefield`_cnt', 'dt'] + ); + // phpcs:enable + + $dbi = $this->createDatabaseInterface($dbiDummy); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new PartialDependenciesController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + // phpcs:disable Generic.Files.LineLength.TooLong + $this->assertSame( + 'This list is based on a subset of the table\'s data and is not necessarily accurate. <div class="dependencies_box"><p class="d-block m-1">No partial dependencies found!</p></div>', + $response->getHTMLResult() + ); + // phpcs:enable + } +} diff --git a/test/classes/Controllers/Normalization/SecondNormalForm/CreateNewTablesControllerTest.php b/test/classes/Controllers/Normalization/SecondNormalForm/CreateNewTablesControllerTest.php new file mode 100644 index 0000000000..e9feec843c --- /dev/null +++ b/test/classes/Controllers/Normalization/SecondNormalForm/CreateNewTablesControllerTest.php @@ -0,0 +1,55 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Normalization\SecondNormalForm; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Normalization\SecondNormalForm\CreateNewTablesController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Normalization; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +use function json_encode; + +/** + * @covers \PhpMyAdmin\Controllers\Normalization\SecondNormalForm\CreateNewTablesController + */ +class CreateNewTablesControllerTest extends AbstractTestCase +{ + public function testDefault(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $_POST['pd'] = json_encode(['ID, task' => [], 'task' => ['timestamp']]); + $_POST['newTablesName'] = json_encode(['ID, task' => 'batch_log2', 'task' => 'table2']); + + $dbiDummy = $this->createDbiDummy(); + $dbiDummy->addSelectDb('test_db'); + $dbiDummy->addResult('CREATE TABLE `batch_log2` SELECT DISTINCT `ID`, `task` FROM `test_table`;', []); + $dbiDummy->addResult('CREATE TABLE `table2` SELECT DISTINCT `task`, `timestamp` FROM `test_table`;', []); + $dbiDummy->addResult('DROP TABLE `test_table`', []); + + $dbi = $this->createDatabaseInterface($dbiDummy); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new CreateNewTablesController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + $this->assertSame([ + 'legendText' => 'End of step', + 'headText' => '<h3>The second step of normalization is complete for table \'test_table\'.</h3>', + 'queryError' => false, + 'extra' => '', + ], $response->getJSONResult()); + } +} diff --git a/test/classes/Controllers/Normalization/SecondNormalForm/FirstStepControllerTest.php b/test/classes/Controllers/Normalization/SecondNormalForm/FirstStepControllerTest.php new file mode 100644 index 0000000000..c5ec7dda6f --- /dev/null +++ b/test/classes/Controllers/Normalization/SecondNormalForm/FirstStepControllerTest.php @@ -0,0 +1,46 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Normalization\SecondNormalForm; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Normalization\SecondNormalForm\FirstStepController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Normalization; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +/** + * @covers \PhpMyAdmin\Controllers\Normalization\SecondNormalForm\FirstStepController + */ +class FirstStepControllerTest extends AbstractTestCase +{ + public function testDefault(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + + $dbi = $this->createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new FirstStepController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + $this->assertSame([ + 'legendText' => 'Step 2.1 Find partial dependencies', + 'headText' => 'No partial dependencies possible as the primary key ( id ) has just one column.<br>', + 'subText' => '', + 'extra' => '<h3>Table is already in second normal form.</h3>', + 'primary_key' => 'id', + ], $response->getJSONResult()); + } +} diff --git a/test/classes/Controllers/Normalization/SecondNormalForm/NewTablesControllerTest.php b/test/classes/Controllers/Normalization/SecondNormalForm/NewTablesControllerTest.php new file mode 100644 index 0000000000..e019257735 --- /dev/null +++ b/test/classes/Controllers/Normalization/SecondNormalForm/NewTablesControllerTest.php @@ -0,0 +1,48 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Normalization\SecondNormalForm; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Normalization\SecondNormalForm\NewTablesController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Normalization; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +use function json_encode; + +/** + * @covers \PhpMyAdmin\Controllers\Normalization\SecondNormalForm\NewTablesController + */ +class NewTablesControllerTest extends AbstractTestCase +{ + public function testDefault(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $_POST['pd'] = json_encode(['ID, task' => [], 'task' => ['timestamp']]); + + $dbi = $this->createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new NewTablesController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + // phpcs:disable Generic.Files.LineLength.TooLong + $this->assertSame( + '<p><b>In order to put the original table \'test_table\' into Second normal form we need to create the following tables:</b></p><p><input type="text" name="ID, task" value="test_table">( <u>ID, task</u> )<p><input type="text" name="task" value="table2">( <u>task</u>, timestamp )', + $response->getHTMLResult() + ); + // phpcs:enable + } +} diff --git a/test/classes/Controllers/Normalization/ThirdNormalForm/CreateNewTablesControllerTest.php b/test/classes/Controllers/Normalization/ThirdNormalForm/CreateNewTablesControllerTest.php new file mode 100644 index 0000000000..a6980ce7ee --- /dev/null +++ b/test/classes/Controllers/Normalization/ThirdNormalForm/CreateNewTablesControllerTest.php @@ -0,0 +1,64 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Normalization\ThirdNormalForm; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Normalization\ThirdNormalForm\CreateNewTablesController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Normalization; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +use function json_encode; + +/** + * @covers \PhpMyAdmin\Controllers\Normalization\ThirdNormalForm\CreateNewTablesController + */ +class CreateNewTablesControllerTest extends AbstractTestCase +{ + public function testDefault(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $_POST['newTables'] = json_encode([ + 'test_table' => [ + 'event' => [ + 'pk' => 'eventID', + 'nonpk' => 'Start_time, DateOfEvent, NumberOfGuests, NameOfVenue, LocationOfVenue', + ], + 'table2' => ['pk' => 'Start_time', 'nonpk' => 'TypeOfEvent, period'], + ], + ]); + + // phpcs:disable Generic.Files.LineLength.TooLong + $dbiDummy = $this->createDbiDummy(); + $dbiDummy->addSelectDb('test_db'); + $dbiDummy->addResult('CREATE TABLE `event` SELECT DISTINCT `eventID`, `Start_time`, `DateOfEvent`, `NumberOfGuests`, `NameOfVenue`, `LocationOfVenue` FROM `test_table`;', []); + $dbiDummy->addResult('CREATE TABLE `table2` SELECT DISTINCT `Start_time`, `TypeOfEvent`, `period` FROM `test_table`;', []); + $dbiDummy->addResult('DROP TABLE `test_table`', []); + // phpcs:enable + + $dbi = $this->createDatabaseInterface($dbiDummy); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new CreateNewTablesController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + $this->assertSame([ + 'legendText' => 'End of step', + 'headText' => '<h3>The third step of normalization is complete.</h3>', + 'queryError' => false, + 'extra' => '', + ], $response->getJSONResult()); + } +} diff --git a/test/classes/Controllers/Normalization/ThirdNormalForm/FirstStepControllerTest.php b/test/classes/Controllers/Normalization/ThirdNormalForm/FirstStepControllerTest.php new file mode 100644 index 0000000000..dd55cef91e --- /dev/null +++ b/test/classes/Controllers/Normalization/ThirdNormalForm/FirstStepControllerTest.php @@ -0,0 +1,51 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Normalization\ThirdNormalForm; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Normalization\ThirdNormalForm\FirstStepController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Normalization; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +/** + * @covers \PhpMyAdmin\Controllers\Normalization\ThirdNormalForm\FirstStepController + */ +class FirstStepControllerTest extends AbstractTestCase +{ + public function testDefault(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $_POST['tables'] = ['test_table']; + + $dbiDummy = $this->createDbiDummy(); + $dbiDummy->addSelectDb('test_db'); + + $dbi = $this->createDatabaseInterface($dbiDummy); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new FirstStepController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + // phpcs:disable Generic.Files.LineLength.TooLong + $this->assertSame([ + 'legendText' => 'Step 3.1 Find transitive dependencies', + 'headText' => 'Please answer the following question(s) carefully to obtain a correct normalization.', + 'subText' => 'For each column below, please select the <b>minimal set</b> of columns among given set whose values combined together are sufficient to determine the value of the column.<br>Note: A column may have no transitive dependency, in that case you don\'t have to select any.', + 'extra' => '<b>\'name\' depends on:</b><br><form id="td_1" data-colname="name" data-tablename="test_table" class="smallIndent"><input type="checkbox" name="pd" value="name"><span>name</span><input type="checkbox" name="pd" value="datetimefield"><span>datetimefield</span></form><br><br><b>\'datetimefield\' depends on:</b><br><form id="td_2" data-colname="datetimefield" data-tablename="test_table" class="smallIndent"><input type="checkbox" name="pd" value="name"><span>name</span><input type="checkbox" name="pd" value="datetimefield"><span>datetimefield</span></form><br><br>', + ], $response->getJSONResult()); + // phpcs:enable + } +} diff --git a/test/classes/Controllers/Normalization/ThirdNormalForm/NewTablesControllerTest.php b/test/classes/Controllers/Normalization/ThirdNormalForm/NewTablesControllerTest.php new file mode 100644 index 0000000000..88d14fc7c0 --- /dev/null +++ b/test/classes/Controllers/Normalization/ThirdNormalForm/NewTablesControllerTest.php @@ -0,0 +1,82 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Normalization\ThirdNormalForm; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Normalization\ThirdNormalForm\NewTablesController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Normalization; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +use function json_encode; + +/** + * @covers \PhpMyAdmin\Controllers\Normalization\ThirdNormalForm\NewTablesController + */ +class NewTablesControllerTest extends AbstractTestCase +{ + public function testDefault(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $_POST['tables'] = json_encode([ + 'test_table' => [ + 'event', + 'event', + 'event', + 'event', + 'NameOfVenue', + 'event', + 'period', + 'event', + 'event', + ], + ]); + $_POST['pd'] = json_encode([ + '' => [], + 'event' => [ + 'TypeOfEvent', + 'period', + 'Start_time', + 'NameOfVenue', + 'LocationOfVenue', + ], + 'NameOfVenue' => ['DateOfEvent'], + 'period' => ['NumberOfGuests'], + ]); + + $dbi = $this->createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new NewTablesController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + // phpcs:disable Generic.Files.LineLength.TooLong + $this->assertSame([ + 'html' => '<p><b>In order to put the original table \'test_table\' into Third normal form we need to create the following tables:</b></p><p><input type="text" name="test_table" value="test_table">( <u>event</u>, TypeOfEvent, period, Start_time, NameOfVenue, LocationOfVenue )<p><input type="text" name="table2" value="table2">( <u>NameOfVenue</u>, DateOfEvent )<p><input type="text" name="table3" value="table3">( <u>period</u>, NumberOfGuests )', + 'newTables' => [ + 'test_table' => [ + 'test_table' => [ + 'pk' => 'event', + 'nonpk' => 'TypeOfEvent, period, Start_time, NameOfVenue, LocationOfVenue', + ], + 'table2' => ['pk' => 'NameOfVenue', 'nonpk' => 'DateOfEvent'], + 'table3' => ['pk' => 'period', 'nonpk' => 'NumberOfGuests'], + ], + ], + 'success' => true, + ], $response->getJSONResult()); + // phpcs:enable + } +} diff --git a/test/classes/Controllers/NormalizationControllerTest.php b/test/classes/Controllers/NormalizationControllerTest.php deleted file mode 100644 index 0d556e55eb..0000000000 --- a/test/classes/Controllers/NormalizationControllerTest.php +++ /dev/null @@ -1,204 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace PhpMyAdmin\Tests\Controllers; - -use PhpMyAdmin\Controllers\NormalizationController; -use PhpMyAdmin\Tests\AbstractTestCase; - -use function json_encode; - -/** - * @covers \PhpMyAdmin\Controllers\NormalizationController - */ -class NormalizationControllerTest extends AbstractTestCase -{ - protected function setUp(): void - { - parent::setUp(); - parent::setLanguage(); - parent::setTheme(); - parent::setGlobalDbi(); - parent::loadContainerBuilder(); - parent::loadDbiIntoContainerBuilder(); - $GLOBALS['server'] = 1; - $GLOBALS['PMA_PHP_SELF'] = 'index.php'; - parent::loadResponseIntoContainerBuilder(); - $GLOBALS['db'] = 'my_db'; - $GLOBALS['table'] = 'test_tbl'; - } - - public function testGetNewTables3NF(): void - { - global $containerBuilder; - - $_POST['getNewTables3NF'] = 1; - $_POST['tables'] = json_encode([ - 'test_tbl' => [ - 'event', - 'event', - 'event', - 'event', - 'NameOfVenue', - 'event', - 'period', - 'event', - 'event', - ], - ]); - $_POST['pd'] = json_encode([ - '' => [], - 'event' => [ - 'TypeOfEvent', - 'period', - 'Start_time', - 'NameOfVenue', - 'LocationOfVenue', - ], - 'NameOfVenue' => ['DateOfEvent'], - 'period' => ['NumberOfGuests'], - ]); - - $GLOBALS['goto'] = 'index.php?route=/sql'; - $containerBuilder->setParameter('db', $GLOBALS['db']); - $containerBuilder->setParameter('table', $GLOBALS['table']); - /** @var NormalizationController $normalizationController */ - $normalizationController = $containerBuilder->get(NormalizationController::class); - $normalizationController(); - - $this->assertResponseWasSuccessfull(); - - $this->getResponseJsonResult();// Will echo the contents - - $data = (string) json_encode( - [ - 'html' => '<p><b>In order to put the original table \'test_tbl\' into ' - . 'Third normal form we need to create the following tables:</b>' - . '</p><p><input type="text" name="test_tbl" value="test_tbl">' - . '( <u>event</u>, TypeOfEvent, period, Start_time, NameOfVenue, LocationOfVenue )' - . '<p><input type="text" name="table2" value="table2">' - . '( <u>NameOfVenue</u>, DateOfEvent )<p><input type="text" name="table3" value="table3">' - . '( <u>period</u>, NumberOfGuests )', - 'newTables' => [ - 'test_tbl' => [ - 'test_tbl' => [ - 'pk' => 'event', - 'nonpk' => 'TypeOfEvent, period, Start_time, NameOfVenue, LocationOfVenue', - ], - 'table2' => [ - 'pk' => 'NameOfVenue', - 'nonpk' => 'DateOfEvent', - ], - 'table3' => [ - 'pk' => 'period', - 'nonpk' => 'NumberOfGuests', - ], - ], - ], - 'success' => true, - ] - ); - $this->expectOutputString($data); - } - - public function testGetNewTables2NF(): void - { - global $containerBuilder; - - $_POST['getNewTables2NF'] = 1; - $_POST['pd'] = json_encode([ - 'ID, task' => [], - 'task' => ['timestamp'], - ]); - - $GLOBALS['goto'] = 'index.php?route=/sql'; - $containerBuilder->setParameter('db', $GLOBALS['db']); - $containerBuilder->setParameter('table', $GLOBALS['table']); - /** @var NormalizationController $normalizationController */ - $normalizationController = $containerBuilder->get(NormalizationController::class); - $normalizationController(); - $this->expectOutputString( - '<p><b>In order to put the original table \'test_tbl\' into Second normal' - . ' form we need to create the following tables:</b></p><p><input type="text" ' - . 'name="ID, task" value="test_tbl">( <u>ID, task</u> )<p><input type="text" name="task"' - . ' value="table2">( <u>task</u>, timestamp )' - ); - } - - public function testCreateNewTables2NF(): void - { - global $containerBuilder; - - $_POST['createNewTables2NF'] = 1; - $_POST['pd'] = json_encode([ - 'ID, task' => [], - 'task' => ['timestamp'], - ]); - $_POST['newTablesName'] = json_encode([ - 'ID, task' => 'batch_log2', - 'task' => 'table2', - ]); - - $GLOBALS['goto'] = 'index.php?route=/sql'; - $containerBuilder->setParameter('db', $GLOBALS['db']); - $containerBuilder->setParameter('table', $GLOBALS['table']); - /** @var NormalizationController $normalizationController */ - $normalizationController = $containerBuilder->get(NormalizationController::class); - $this->dummyDbi->addSelectDb('my_db'); - $normalizationController(); - $this->assertAllSelectsConsumed(); - - $this->assertResponseWasSuccessfull(); - - $this->assertSame( - [ - 'legendText' => 'End of step', - 'headText' => '<h3>The second step of normalization is complete for table \'test_tbl\'.</h3>', - 'queryError' => false, - 'extra' => '', - ], - $this->getResponseJsonResult() - ); - } - - public function testCreateNewTables3NF(): void - { - global $containerBuilder; - - $_POST['createNewTables3NF'] = 1; - $_POST['newTables'] = json_encode([ - 'test_tbl' => [ - 'event' => [ - 'pk' => 'eventID', - 'nonpk' => 'Start_time, DateOfEvent, NumberOfGuests, NameOfVenue, LocationOfVenue', - ], - 'table2' => [ - 'pk' => 'Start_time', - 'nonpk' => 'TypeOfEvent, period', - ], - ], - ]); - - $GLOBALS['goto'] = 'index.php?route=/sql'; - $containerBuilder->setParameter('db', $GLOBALS['db']); - $containerBuilder->setParameter('table', $GLOBALS['table']); - /** @var NormalizationController $normalizationController */ - $normalizationController = $containerBuilder->get(NormalizationController::class); - $this->dummyDbi->addSelectDb('my_db'); - $normalizationController(); - $this->assertAllSelectsConsumed(); - - $this->assertResponseWasSuccessfull(); - - $this->assertSame( - [ - 'legendText' => 'End of step', - 'headText' => '<h3>The third step of normalization is complete.</h3>', - 'queryError' => false, - 'extra' => '', - ], - $this->getResponseJsonResult() - ); - } -} diff --git a/test/classes/Controllers/Server/BinlogControllerTest.php b/test/classes/Controllers/Server/BinlogControllerTest.php index e87e429def..abd9418a42 100644 --- a/test/classes/Controllers/Server/BinlogControllerTest.php +++ b/test/classes/Controllers/Server/BinlogControllerTest.php @@ -5,8 +5,11 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Server; use PhpMyAdmin\Controllers\Server\BinlogController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; use PhpMyAdmin\Url; use PhpMyAdmin\Utils\SessionCache; @@ -16,15 +19,21 @@ use PhpMyAdmin\Utils\SessionCache; */ class BinlogControllerTest extends AbstractTestCase { - /** - * Prepares environment for the test. - */ + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + protected function setUp(): void { parent::setUp(); $GLOBALS['text_dir'] = 'ltr'; parent::setGlobalConfig(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['cfg']['MaxRows'] = 10; $GLOBALS['cfg']['ServerDefault'] = 'server'; @@ -47,8 +56,8 @@ class BinlogControllerTest extends AbstractTestCase $_POST['log'] = 'index1'; $_POST['pos'] = '3'; $this->dummyDbi->addSelectDb('mysql'); - $controller(); - $this->assertAllSelectsConsumed(); + $controller($this->createStub(ServerRequest::class)); + $this->dummyDbi->assertAllSelectsConsumed(); $actual = $response->getHTMLResult(); $this->assertStringContainsString('Select binary log to view', $actual); diff --git a/test/classes/Controllers/Server/CollationsControllerTest.php b/test/classes/Controllers/Server/CollationsControllerTest.php index 7b872d85ec..9497972e8a 100644 --- a/test/classes/Controllers/Server/CollationsControllerTest.php +++ b/test/classes/Controllers/Server/CollationsControllerTest.php @@ -5,8 +5,11 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Server; use PhpMyAdmin\Controllers\Server\CollationsController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; /** @@ -14,6 +17,12 @@ use PhpMyAdmin\Tests\Stubs\ResponseRenderer; */ class CollationsControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** * Prepares environment for the test. */ @@ -23,6 +32,9 @@ class CollationsControllerTest extends AbstractTestCase $GLOBALS['text_dir'] = 'ltr'; parent::setGlobalConfig(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; $GLOBALS['db'] = 'db'; @@ -38,8 +50,8 @@ class CollationsControllerTest extends AbstractTestCase $controller = new CollationsController($response, new Template(), $GLOBALS['dbi']); $this->dummyDbi->addSelectDb('mysql'); - $controller(); - $this->assertAllSelectsConsumed(); + $controller($this->createStub(ServerRequest::class)); + $this->dummyDbi->assertAllSelectsConsumed(); $actual = $response->getHTMLResult(); $this->assertStringContainsString('<div><strong>latin1</strong></div>', $actual); diff --git a/test/classes/Controllers/Server/Databases/CreateControllerTest.php b/test/classes/Controllers/Server/Databases/CreateControllerTest.php index 53116cfa6a..98ab64d053 100644 --- a/test/classes/Controllers/Server/Databases/CreateControllerTest.php +++ b/test/classes/Controllers/Server/Databases/CreateControllerTest.php @@ -5,8 +5,11 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Server\Databases; use PhpMyAdmin\Controllers\Server\Databases\CreateController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; use function __; @@ -17,6 +20,20 @@ use function sprintf; */ final class CreateControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void + { + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + public function testCreateDatabase(): void { $GLOBALS['server'] = 1; @@ -34,7 +51,7 @@ final class CreateControllerTest extends AbstractTestCase $_POST['new_db'] = 'test_db_error'; - $controller(); + $controller($this->createStub(ServerRequest::class)); $actual = $response->getJSONResult(); $this->assertArrayHasKey('message', $actual); @@ -48,7 +65,7 @@ final class CreateControllerTest extends AbstractTestCase $_POST['new_db'] = 'test_db'; $_POST['db_collation'] = 'utf8_general_ci'; - $controller(); + $controller($this->createStub(ServerRequest::class)); $actual = $response->getJSONResult(); $this->assertArrayHasKey('message', $actual); diff --git a/test/classes/Controllers/Server/Databases/DestroyControllerTest.php b/test/classes/Controllers/Server/Databases/DestroyControllerTest.php index 472fee3c5a..8cc5f44eb0 100644 --- a/test/classes/Controllers/Server/Databases/DestroyControllerTest.php +++ b/test/classes/Controllers/Server/Databases/DestroyControllerTest.php @@ -8,6 +8,7 @@ use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\ConfigStorage\RelationCleanup; use PhpMyAdmin\Controllers\Server\Databases\DestroyController; use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; @@ -20,10 +21,14 @@ use function __; */ class DestroyControllerTest extends AbstractTestCase { - public function testDropDatabases(): void + protected function setUp(): void { - global $cfg; + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + } + public function testDropDatabases(): void + { $GLOBALS['server'] = 1; $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['PMA_PHP_SELF'] = 'index.php'; @@ -35,7 +40,7 @@ class DestroyControllerTest extends AbstractTestCase $response = new ResponseRenderer(); $response->setAjax(true); - $cfg['AllowUserDropDatabase'] = true; + $GLOBALS['cfg']['AllowUserDropDatabase'] = true; $controller = new DestroyController( $response, @@ -45,7 +50,7 @@ class DestroyControllerTest extends AbstractTestCase new RelationCleanup($dbi, new Relation($dbi)) ); - $controller(); + $controller($this->createStub(ServerRequest::class)); $actual = $response->getJSONResult(); $this->assertArrayHasKey('message', $actual); diff --git a/test/classes/Controllers/Server/DatabasesControllerTest.php b/test/classes/Controllers/Server/DatabasesControllerTest.php index 4136f3bab2..a74da76a8a 100644 --- a/test/classes/Controllers/Server/DatabasesControllerTest.php +++ b/test/classes/Controllers/Server/DatabasesControllerTest.php @@ -7,8 +7,11 @@ namespace PhpMyAdmin\Tests\Controllers\Server; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\ConfigStorage\RelationCleanup; use PhpMyAdmin\Controllers\Server\DatabasesController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; use PhpMyAdmin\Transformations; use stdClass; @@ -20,11 +23,20 @@ use function __; */ class DatabasesControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + protected function setUp(): void { parent::setUp(); parent::setGlobalConfig(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; $GLOBALS['db'] = 'pma_test'; @@ -36,10 +48,8 @@ class DatabasesControllerTest extends AbstractTestCase public function testIndexAction(): void { - global $cfg, $dblist, $is_create_db_priv; - - $dblist = new stdClass(); - $dblist->databases = [ + $GLOBALS['dblist'] = new stdClass(); + $GLOBALS['dblist']->databases = [ 'sakila', 'employees', ]; @@ -62,8 +72,8 @@ class DatabasesControllerTest extends AbstractTestCase ); $this->dummyDbi->addSelectDb('mysql'); - $controller(); - $this->assertAllSelectsConsumed(); + $controller($this->createStub(ServerRequest::class)); + $this->dummyDbi->assertAllSelectsConsumed(); $actual = $response->getHTMLResult(); $this->assertStringContainsString('data-filter-row="SAKILA"', $actual); @@ -92,15 +102,15 @@ class DatabasesControllerTest extends AbstractTestCase $GLOBALS['dbi'] ); - $cfg['ShowCreateDb'] = true; - $is_create_db_priv = true; + $GLOBALS['cfg']['ShowCreateDb'] = true; + $GLOBALS['is_create_db_priv'] = true; $_REQUEST['statistics'] = '1'; $_REQUEST['sort_by'] = 'SCHEMA_TABLES'; $_REQUEST['sort_order'] = 'desc'; $this->dummyDbi->addSelectDb('mysql'); - $controller(); - $this->assertAllSelectsConsumed(); + $controller($this->createStub(ServerRequest::class)); + $this->dummyDbi->assertAllSelectsConsumed(); $actual = $response->getHTMLResult(); $this->assertStringNotContainsString(__('Enable statistics'), $actual); diff --git a/test/classes/Controllers/Server/EnginesControllerTest.php b/test/classes/Controllers/Server/EnginesControllerTest.php index cc411ab489..6503beb337 100644 --- a/test/classes/Controllers/Server/EnginesControllerTest.php +++ b/test/classes/Controllers/Server/EnginesControllerTest.php @@ -5,8 +5,11 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Server; use PhpMyAdmin\Controllers\Server\EnginesController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; /** @@ -14,6 +17,12 @@ use PhpMyAdmin\Tests\Stubs\ResponseRenderer; */ class EnginesControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** * Prepares environment for the test. */ @@ -23,6 +32,9 @@ class EnginesControllerTest extends AbstractTestCase $GLOBALS['text_dir'] = 'ltr'; parent::setGlobalConfig(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; $GLOBALS['db'] = 'db'; @@ -33,15 +45,13 @@ class EnginesControllerTest extends AbstractTestCase public function testIndex(): void { - global $dbi; - $response = new ResponseRenderer(); - $controller = new EnginesController($response, new Template(), $dbi); + $controller = new EnginesController($response, new Template(), $GLOBALS['dbi']); $this->dummyDbi->addSelectDb('mysql'); - $controller->__invoke(); - $this->assertAllSelectsConsumed(); + $controller->__invoke($this->createStub(ServerRequest::class)); + $this->dummyDbi->assertAllSelectsConsumed(); $actual = $response->getHTMLResult(); diff --git a/test/classes/Controllers/Server/PluginsControllerTest.php b/test/classes/Controllers/Server/PluginsControllerTest.php index a14480558c..0cba772b73 100644 --- a/test/classes/Controllers/Server/PluginsControllerTest.php +++ b/test/classes/Controllers/Server/PluginsControllerTest.php @@ -6,9 +6,11 @@ namespace PhpMyAdmin\Tests\Controllers\Server; use PhpMyAdmin\Controllers\Server\PluginsController; use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Server\Plugins; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\DummyResult; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; @@ -17,6 +19,12 @@ use PhpMyAdmin\Tests\Stubs\ResponseRenderer; */ class PluginsControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** * Prepares environment for the test. */ @@ -26,6 +34,9 @@ class PluginsControllerTest extends AbstractTestCase $GLOBALS['text_dir'] = 'ltr'; parent::setGlobalConfig(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; $GLOBALS['db'] = 'db'; @@ -68,8 +79,8 @@ class PluginsControllerTest extends AbstractTestCase $controller = new PluginsController($response, new Template(), new Plugins($dbi), $GLOBALS['dbi']); $this->dummyDbi->addSelectDb('mysql'); - $controller(); - $this->assertAllSelectsConsumed(); + $controller($this->createStub(ServerRequest::class)); + $this->dummyDbi->assertAllSelectsConsumed(); $actual = $response->getHTMLResult(); //validate 1:Items diff --git a/test/classes/Controllers/Server/Privileges/AccountLockControllerTest.php b/test/classes/Controllers/Server/Privileges/AccountLockControllerTest.php index aeaccc83df..83e6e92cad 100644 --- a/test/classes/Controllers/Server/Privileges/AccountLockControllerTest.php +++ b/test/classes/Controllers/Server/Privileges/AccountLockControllerTest.php @@ -34,6 +34,7 @@ class AccountLockControllerTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 1; $GLOBALS['text_dir'] = 'ltr'; diff --git a/test/classes/Controllers/Server/Privileges/AccountUnlockControllerTest.php b/test/classes/Controllers/Server/Privileges/AccountUnlockControllerTest.php index 036ac87d0b..0d92e31887 100644 --- a/test/classes/Controllers/Server/Privileges/AccountUnlockControllerTest.php +++ b/test/classes/Controllers/Server/Privileges/AccountUnlockControllerTest.php @@ -34,6 +34,7 @@ class AccountUnlockControllerTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 1; $GLOBALS['text_dir'] = 'ltr'; diff --git a/test/classes/Controllers/Server/PrivilegesControllerTest.php b/test/classes/Controllers/Server/PrivilegesControllerTest.php new file mode 100644 index 0000000000..99600d0fce --- /dev/null +++ b/test/classes/Controllers/Server/PrivilegesControllerTest.php @@ -0,0 +1,95 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Server; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Server\PrivilegesController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Server\PrivilegesController + */ +class PrivilegesControllerTest extends AbstractTestCase +{ + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void + { + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + + public function testPrivilegesController(): void + { + $GLOBALS['server'] = 1; + $GLOBALS['text_dir'] = 'ltr'; + $GLOBALS['PMA_PHP_SELF'] = 'index.php'; + $GLOBALS['db'] = ''; + $GLOBALS['table'] = ''; + $GLOBALS['cfg']['Server']['DisableIS'] = false; + + // phpcs:disable Generic.Files.LineLength.TooLong + $this->dummyDbi->addSelectDb('mysql'); + $this->dummyDbi->addResult( + 'SELECT *, IF(`authentication_string` = _latin1 \'\', \'N\', \'Y\') AS \'Password\' FROM `mysql`.`user` ORDER BY `User` ASC, `Host` ASC;', + [ + ['localhost', 'pma', 'password', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', '', '', '', '', '0', '0', '0', '0', 'mysql_native_password', 'password', 'N', 'N', '', '0.000000', 'Y'], + ['localhost', 'root', 'password', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', '', '', '', '', '0', '0', '0', '0', 'mysql_native_password', 'password', 'N', 'N', '', '0.000000', 'Y'], + ], + ['Host', 'User', 'Password', 'Select_priv', 'Insert_priv', 'Update_priv', 'Delete_priv', 'Create_priv', 'Drop_priv', 'Reload_priv', 'Shutdown_priv', 'Process_priv', 'File_priv', 'Grant_priv', 'References_priv', 'Index_priv', 'Alter_priv', 'Show_db_priv', 'Super_priv', 'Create_tmp_table_priv', 'Lock_tables_priv', 'Execute_priv', 'Repl_slave_priv', 'Repl_client_priv', 'Create_view_priv', 'Show_view_priv', 'Create_routine_priv', 'Alter_routine_priv', 'Create_user_priv', 'Event_priv', 'Trigger_priv', 'Create_tablespace_priv', 'Delete_history_priv', 'ssl_type', 'ssl_cipher', 'x509_issuer', 'x509_subject', 'max_questions', 'max_updates', 'max_connections', 'max_user_connections', 'plugin', 'authentication_string', 'password_expired', 'is_role', 'default_role', 'max_statement_time', 'Password'] + ); + $this->dummyDbi->addResult( + 'SELECT *, IF(`authentication_string` = _latin1 \'\', \'N\', \'Y\') AS \'Password\' FROM `mysql`.`user` ;', + [ + ['localhost', 'root', 'password', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', '', '', '', '', '0', '0', '0', '0', 'mysql_native_password', 'password', 'N', 'N', '', '0.000000', 'Y'], + ['localhost', 'pma', 'password', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', '', '', '', '', '0', '0', '0', '0', 'mysql_native_password', 'password', 'N', 'N', '', '0.000000', 'Y'], + ], + ['Host', 'User', 'Password', 'Select_priv', 'Insert_priv', 'Update_priv', 'Delete_priv', 'Create_priv', 'Drop_priv', 'Reload_priv', 'Shutdown_priv', 'Process_priv', 'File_priv', 'Grant_priv', 'References_priv', 'Index_priv', 'Alter_priv', 'Show_db_priv', 'Super_priv', 'Create_tmp_table_priv', 'Lock_tables_priv', 'Execute_priv', 'Repl_slave_priv', 'Repl_client_priv', 'Create_view_priv', 'Show_view_priv', 'Create_routine_priv', 'Alter_routine_priv', 'Create_user_priv', 'Event_priv', 'Trigger_priv', 'Create_tablespace_priv', 'Delete_history_priv', 'ssl_type', 'ssl_cipher', 'x509_issuer', 'x509_subject', 'max_questions', 'max_updates', 'max_connections', 'max_user_connections', 'plugin', 'authentication_string', 'password_expired', 'is_role', 'default_role', 'max_statement_time', 'Password'] + ); + $this->dummyDbi->addResult( + 'SHOW TABLES FROM `mysql`;', + [['columns_priv'], ['db'], ['tables_priv'], ['user']], + ['Tables_in_mysql'] + ); + $this->dummyDbi->addResult( + '(SELECT DISTINCT `User`, `Host` FROM `mysql`.`user` ) UNION (SELECT DISTINCT `User`, `Host` FROM `mysql`.`db` ) UNION (SELECT DISTINCT `User`, `Host` FROM `mysql`.`tables_priv` ) UNION (SELECT DISTINCT `User`, `Host` FROM `mysql`.`columns_priv` ) ORDER BY `User` ASC, `Host` ASC', + [['pma', 'localhost'], ['root', 'localhost']], + ['User', 'Host'] + ); + // phpcs:enable + + $request = $this->createStub(ServerRequest::class); + + $response = new ResponseRenderer(); + (new PrivilegesController($response, new Template(), new Relation($this->dbi), $this->dbi))($request); + + $actual = $response->getHTMLResult(); + $this->assertStringContainsString('User accounts overview', $actual); + $this->assertStringContainsString( + 'id="checkbox_sel_users_1" value="pma&amp;#27;localhost" name="selected_usr[]"', + $actual + ); + $this->assertStringContainsString('<code><dfn title="No privileges.">USAGE</dfn></code>', $actual); + $this->assertStringContainsString( + 'id="checkbox_sel_users_2" value="root&amp;#27;localhost" name="selected_usr[]"', + $actual + ); + $this->assertStringContainsString( + '<code><dfn title="Includes all privileges except GRANT.">ALL PRIVILEGES</dfn></code>', + $actual + ); + } +} diff --git a/test/classes/Controllers/Server/ShowEngineControllerTest.php b/test/classes/Controllers/Server/ShowEngineControllerTest.php index 2b2d04ce2d..8f607e6378 100644 --- a/test/classes/Controllers/Server/ShowEngineControllerTest.php +++ b/test/classes/Controllers/Server/ShowEngineControllerTest.php @@ -5,11 +5,13 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Server; use PhpMyAdmin\Controllers\Server\ShowEngineController; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Html\MySQLDocumentation; use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\StorageEngine; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; use function __; @@ -20,15 +22,25 @@ use function htmlspecialchars; */ class ShowEngineControllerTest extends AbstractTestCase { - public function testShowEngine(): void + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void { parent::setUp(); $GLOBALS['text_dir'] = 'ltr'; parent::setGlobalConfig(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } - global $dbi; - + public function testShowEngine(): void + { $GLOBALS['server'] = 1; $GLOBALS['db'] = 'db'; $GLOBALS['table'] = 'table'; @@ -39,12 +51,12 @@ class ShowEngineControllerTest extends AbstractTestCase $request = $this->createMock(ServerRequest::class); $this->dummyDbi->addSelectDb('mysql'); - (new ShowEngineController($response, new Template(), $dbi))($request, [ + (new ShowEngineController($response, new Template(), $GLOBALS['dbi']))($request, [ 'engine' => 'Pbxt', 'page' => 'page', ]); - $this->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllSelectsConsumed(); $actual = $response->getHTMLResult(); $enginePlugin = StorageEngine::getEngine('Pbxt'); diff --git a/test/classes/Controllers/Server/Status/AdvisorControllerTest.php b/test/classes/Controllers/Server/Status/AdvisorControllerTest.php index 2b4e496be3..ccc80b2037 100644 --- a/test/classes/Controllers/Server/Status/AdvisorControllerTest.php +++ b/test/classes/Controllers/Server/Status/AdvisorControllerTest.php @@ -4,8 +4,9 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Server\Status; -use PhpMyAdmin\Advisor; +use PhpMyAdmin\Advisory\Advisor; use PhpMyAdmin\Controllers\Server\Status\AdvisorController; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Server\Status\Data; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; @@ -32,6 +33,7 @@ class AdvisorControllerTest extends AbstractTestCase $GLOBALS['text_dir'] = 'ltr'; parent::setGlobalConfig(); parent::setTheme(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 1; $GLOBALS['PMA_PHP_SELF'] = 'index.php'; @@ -54,7 +56,7 @@ class AdvisorControllerTest extends AbstractTestCase new Advisor($GLOBALS['dbi'], new ExpressionLanguage()) ); - $controller(); + $controller($this->createStub(ServerRequest::class)); $expected = $this->template->render('server/status/advisor/index', [ 'data' => [], @@ -98,7 +100,7 @@ class AdvisorControllerTest extends AbstractTestCase $controller = new AdvisorController($this->response, $this->template, $this->data, $advisor); - $controller(); + $controller($this->createStub(ServerRequest::class)); $expected = $this->template->render('server/status/advisor/index', ['data' => $advisorData]); diff --git a/test/classes/Controllers/Server/Status/Monitor/GeneralLogControllerTest.php b/test/classes/Controllers/Server/Status/Monitor/GeneralLogControllerTest.php index f1394a3021..48b4edc25d 100644 --- a/test/classes/Controllers/Server/Status/Monitor/GeneralLogControllerTest.php +++ b/test/classes/Controllers/Server/Status/Monitor/GeneralLogControllerTest.php @@ -5,10 +5,13 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Server\Status\Monitor; use PhpMyAdmin\Controllers\Server\Status\Monitor\GeneralLogController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Server\Status\Data; use PhpMyAdmin\Server\Status\Monitor; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; /** @@ -16,6 +19,12 @@ use PhpMyAdmin\Tests\Stubs\ResponseRenderer; */ class GeneralLogControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var Data */ private $data; @@ -25,6 +34,9 @@ class GeneralLogControllerTest extends AbstractTestCase $GLOBALS['text_dir'] = 'ltr'; parent::setGlobalConfig(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; $GLOBALS['db'] = 'db'; @@ -66,8 +78,8 @@ class GeneralLogControllerTest extends AbstractTestCase $_POST['limitTypes'] = '1'; $this->dummyDbi->addSelectDb('mysql'); - $controller(); - $this->assertAllSelectsConsumed(); + $controller($this->createStub(ServerRequest::class)); + $this->dummyDbi->assertAllSelectsConsumed(); $ret = $response->getJSONResult(); $resultRows = [ diff --git a/test/classes/Controllers/Server/Status/Monitor/LogVarsControllerTest.php b/test/classes/Controllers/Server/Status/Monitor/LogVarsControllerTest.php index 13c217d78c..38fff4775c 100644 --- a/test/classes/Controllers/Server/Status/Monitor/LogVarsControllerTest.php +++ b/test/classes/Controllers/Server/Status/Monitor/LogVarsControllerTest.php @@ -5,10 +5,13 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Server\Status\Monitor; use PhpMyAdmin\Controllers\Server\Status\Monitor\LogVarsController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Server\Status\Data; use PhpMyAdmin\Server\Status\Monitor; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; /** @@ -16,6 +19,12 @@ use PhpMyAdmin\Tests\Stubs\ResponseRenderer; */ class LogVarsControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var Data */ private $data; @@ -25,6 +34,9 @@ class LogVarsControllerTest extends AbstractTestCase $GLOBALS['text_dir'] = 'ltr'; parent::setGlobalConfig(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; $GLOBALS['db'] = 'db'; @@ -59,8 +71,8 @@ class LogVarsControllerTest extends AbstractTestCase $_POST['varName'] = 'varName'; $this->dummyDbi->addSelectDb('mysql'); - $controller(); - $this->assertAllSelectsConsumed(); + $controller($this->createStub(ServerRequest::class)); + $this->dummyDbi->assertAllSelectsConsumed(); $ret = $response->getJSONResult(); $this->assertEquals($value, $ret['message']); diff --git a/test/classes/Controllers/Server/Status/Monitor/QueryAnalyzerControllerTest.php b/test/classes/Controllers/Server/Status/Monitor/QueryAnalyzerControllerTest.php index 783a1a2374..5163e328cd 100644 --- a/test/classes/Controllers/Server/Status/Monitor/QueryAnalyzerControllerTest.php +++ b/test/classes/Controllers/Server/Status/Monitor/QueryAnalyzerControllerTest.php @@ -5,10 +5,12 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Server\Status\Monitor; use PhpMyAdmin\Controllers\Server\Status\Monitor\QueryAnalyzerController; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Server\Status\Data; use PhpMyAdmin\Server\Status\Monitor; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; use PhpMyAdmin\Utils\SessionCache; @@ -17,31 +19,17 @@ use PhpMyAdmin\Utils\SessionCache; */ class QueryAnalyzerControllerTest extends AbstractTestCase { - /** @var Data */ - private $data; - protected function setUp(): void { parent::setUp(); - $GLOBALS['text_dir'] = 'ltr'; - parent::setGlobalConfig(); - parent::setTheme(); - - $GLOBALS['server'] = 1; - $GLOBALS['db'] = 'db'; - $GLOBALS['table'] = 'table'; - $GLOBALS['PMA_PHP_SELF'] = 'index.php'; - $GLOBALS['cfg']['Server']['DisableIS'] = false; - $GLOBALS['cfg']['Server']['host'] = 'localhost'; - - $this->data = new Data(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); } public function testQueryAnalyzer(): void { - global $cached_affected_rows; - - $cached_affected_rows = 'cached_affected_rows'; + $GLOBALS['cfg']['Server']['DisableIS'] = false; + $GLOBALS['cfg']['Server']['host'] = 'localhost'; + $GLOBALS['cached_affected_rows'] = 'cached_affected_rows'; SessionCache::set('profiling_supported', true); $value = [ @@ -53,21 +41,18 @@ class QueryAnalyzerControllerTest extends AbstractTestCase $response = new ResponseRenderer(); $response->setAjax(true); - $controller = new QueryAnalyzerController( - $response, - new Template(), - $this->data, - new Monitor($GLOBALS['dbi']), - $GLOBALS['dbi'] - ); + $dummyDbi = new DbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $controller = new QueryAnalyzerController($response, new Template(), new Data(), new Monitor($dbi), $dbi); $_POST['database'] = 'database'; $_POST['query'] = 'query'; - $this->dummyDbi->addSelectDb('mysql'); - $this->dummyDbi->addSelectDb('database'); - $controller(); - $this->assertAllSelectsConsumed(); + $dummyDbi->addSelectDb('mysql'); + $dummyDbi->addSelectDb('database'); + $controller($this->createStub(ServerRequest::class)); + $dummyDbi->assertAllSelectsConsumed(); $ret = $response->getJSONResult(); $this->assertEquals('cached_affected_rows', $ret['message']['affectedRows']); diff --git a/test/classes/Controllers/Server/Status/Monitor/SlowLogControllerTest.php b/test/classes/Controllers/Server/Status/Monitor/SlowLogControllerTest.php index 9ac2380439..e6545d22ff 100644 --- a/test/classes/Controllers/Server/Status/Monitor/SlowLogControllerTest.php +++ b/test/classes/Controllers/Server/Status/Monitor/SlowLogControllerTest.php @@ -5,10 +5,13 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Server\Status\Monitor; use PhpMyAdmin\Controllers\Server\Status\Monitor\SlowLogController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Server\Status\Data; use PhpMyAdmin\Server\Status\Monitor; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; /** @@ -16,6 +19,12 @@ use PhpMyAdmin\Tests\Stubs\ResponseRenderer; */ class SlowLogControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var Data */ private $data; @@ -25,6 +34,9 @@ class SlowLogControllerTest extends AbstractTestCase $GLOBALS['text_dir'] = 'ltr'; parent::setGlobalConfig(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; $GLOBALS['db'] = 'db'; @@ -53,8 +65,8 @@ class SlowLogControllerTest extends AbstractTestCase $_POST['time_end'] = '10'; $this->dummyDbi->addSelectDb('mysql'); - $controller(); - $this->assertAllSelectsConsumed(); + $controller($this->createStub(ServerRequest::class)); + $this->dummyDbi->assertAllSelectsConsumed(); $ret = $response->getJSONResult(); $resultRows = [ diff --git a/test/classes/Controllers/Server/Status/MonitorControllerTest.php b/test/classes/Controllers/Server/Status/MonitorControllerTest.php index f6dbf39dd7..dc66b5dfa9 100644 --- a/test/classes/Controllers/Server/Status/MonitorControllerTest.php +++ b/test/classes/Controllers/Server/Status/MonitorControllerTest.php @@ -5,9 +5,12 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Server\Status; use PhpMyAdmin\Controllers\Server\Status\MonitorController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Server\Status\Data; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; use function __; @@ -17,6 +20,12 @@ use function __; */ class MonitorControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var Data */ private $data; @@ -26,6 +35,9 @@ class MonitorControllerTest extends AbstractTestCase $GLOBALS['text_dir'] = 'ltr'; parent::setGlobalConfig(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; $GLOBALS['db'] = 'db'; @@ -49,8 +61,8 @@ class MonitorControllerTest extends AbstractTestCase ); $this->dummyDbi->addSelectDb('mysql'); - $controller(); - $this->assertAllSelectsConsumed(); + $controller($this->createStub(ServerRequest::class)); + $this->dummyDbi->assertAllSelectsConsumed(); $html = $response->getHTMLResult(); $this->assertStringContainsString('<div class="tabLinks row">', $html); diff --git a/test/classes/Controllers/Server/Status/Processes/RefreshControllerTest.php b/test/classes/Controllers/Server/Status/Processes/RefreshControllerTest.php index f4ac71e9f9..c83e59f578 100644 --- a/test/classes/Controllers/Server/Status/Processes/RefreshControllerTest.php +++ b/test/classes/Controllers/Server/Status/Processes/RefreshControllerTest.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Server\Status\Processes; use PhpMyAdmin\Controllers\Server\Status\Processes\RefreshController; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Server\Status\Data; use PhpMyAdmin\Server\Status\Processes; use PhpMyAdmin\Template; @@ -26,6 +27,7 @@ class RefreshControllerTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['text_dir'] = 'ltr'; parent::setGlobalConfig(); parent::setTheme(); @@ -68,7 +70,7 @@ class RefreshControllerTest extends AbstractTestCase $_POST['order_by_field'] = 'process'; $_POST['sort_order'] = 'DESC'; - $controller(); + $controller($this->createStub(ServerRequest::class)); $html = $response->getHTMLResult(); $this->assertStringContainsString('index.php?route=/server/status/processes', $html); diff --git a/test/classes/Controllers/Server/Status/ProcessesControllerTest.php b/test/classes/Controllers/Server/Status/ProcessesControllerTest.php index 2102ba3bce..daab49a4d0 100644 --- a/test/classes/Controllers/Server/Status/ProcessesControllerTest.php +++ b/test/classes/Controllers/Server/Status/ProcessesControllerTest.php @@ -5,10 +5,13 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Server\Status; use PhpMyAdmin\Controllers\Server\Status\ProcessesController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Server\Status\Data; use PhpMyAdmin\Server\Status\Processes; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; /** @@ -16,6 +19,12 @@ use PhpMyAdmin\Tests\Stubs\ResponseRenderer; */ class ProcessesControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var Data */ private $data; @@ -25,6 +34,9 @@ class ProcessesControllerTest extends AbstractTestCase $GLOBALS['text_dir'] = 'ltr'; parent::setGlobalConfig(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; $GLOBALS['db'] = 'db'; @@ -49,8 +61,8 @@ class ProcessesControllerTest extends AbstractTestCase ); $this->dummyDbi->addSelectDb('mysql'); - $controller(); - $this->assertAllSelectsConsumed(); + $controller($this->createStub(ServerRequest::class)); + $this->dummyDbi->assertAllSelectsConsumed(); $html = $response->getHTMLResult(); $this->assertStringContainsString( @@ -81,8 +93,8 @@ class ProcessesControllerTest extends AbstractTestCase $_POST['sort_order'] = 'ASC'; $this->dummyDbi->addSelectDb('mysql'); - $controller(); - $this->assertAllSelectsConsumed(); + $controller($this->createStub(ServerRequest::class)); + $this->dummyDbi->assertAllSelectsConsumed(); $html = $response->getHTMLResult(); $this->assertStringContainsString('Truncate shown queries', $html); @@ -94,8 +106,8 @@ class ProcessesControllerTest extends AbstractTestCase $_POST['sort_order'] = 'DESC'; $this->dummyDbi->addSelectDb('mysql'); - $controller(); - $this->assertAllSelectsConsumed(); + $controller($this->createStub(ServerRequest::class)); + $this->dummyDbi->assertAllSelectsConsumed(); $html = $response->getHTMLResult(); $this->assertStringContainsString('Host', $html); diff --git a/test/classes/Controllers/Server/Status/QueriesControllerTest.php b/test/classes/Controllers/Server/Status/QueriesControllerTest.php index 2856d27278..00c35c5b38 100644 --- a/test/classes/Controllers/Server/Status/QueriesControllerTest.php +++ b/test/classes/Controllers/Server/Status/QueriesControllerTest.php @@ -5,9 +5,12 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Server\Status; use PhpMyAdmin\Controllers\Server\Status\QueriesController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Server\Status\Data; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; use PhpMyAdmin\Util; @@ -20,6 +23,12 @@ use function htmlspecialchars; */ class QueriesControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var Data */ private $data; @@ -29,6 +38,9 @@ class QueriesControllerTest extends AbstractTestCase $GLOBALS['text_dir'] = 'ltr'; parent::setGlobalConfig(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; $GLOBALS['db'] = 'db'; @@ -51,15 +63,13 @@ class QueriesControllerTest extends AbstractTestCase public function testIndex(): void { - global $dbi; - $response = new ResponseRenderer(); - $controller = new QueriesController($response, new Template(), $this->data, $dbi); + $controller = new QueriesController($response, new Template(), $this->data, $GLOBALS['dbi']); $this->dummyDbi->addSelectDb('mysql'); - $controller(); - $this->assertAllSelectsConsumed(); + $controller($this->createStub(ServerRequest::class)); + $this->dummyDbi->assertAllSelectsConsumed(); $html = $response->getHTMLResult(); $hourFactor = 3600 / $this->data->status['Uptime']; diff --git a/test/classes/Controllers/Server/Status/StatusControllerTest.php b/test/classes/Controllers/Server/Status/StatusControllerTest.php index 07812a4c75..925bab1d27 100644 --- a/test/classes/Controllers/Server/Status/StatusControllerTest.php +++ b/test/classes/Controllers/Server/Status/StatusControllerTest.php @@ -5,11 +5,14 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Server\Status; use PhpMyAdmin\Controllers\Server\Status\StatusController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Replication; use PhpMyAdmin\ReplicationGui; use PhpMyAdmin\Server\Status\Data; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; /** @@ -17,12 +20,21 @@ use PhpMyAdmin\Tests\Stubs\ResponseRenderer; */ class StatusControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + protected function setUp(): void { parent::setUp(); $GLOBALS['text_dir'] = 'ltr'; parent::setGlobalConfig(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; $GLOBALS['db'] = 'db'; @@ -64,8 +76,8 @@ class StatusControllerTest extends AbstractTestCase $replicationInfo->replicaVariables = []; $this->dummyDbi->addSelectDb('mysql'); - $controller(); - $this->assertAllSelectsConsumed(); + $controller($this->createStub(ServerRequest::class)); + $this->dummyDbi->assertAllSelectsConsumed(); $html = $response->getHTMLResult(); $traffic = $bytesReceived + $bytesSent; diff --git a/test/classes/Controllers/Server/Status/VariablesControllerTest.php b/test/classes/Controllers/Server/Status/VariablesControllerTest.php index 3c6a9271f6..708dd8e803 100644 --- a/test/classes/Controllers/Server/Status/VariablesControllerTest.php +++ b/test/classes/Controllers/Server/Status/VariablesControllerTest.php @@ -5,9 +5,12 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Server\Status; use PhpMyAdmin\Controllers\Server\Status\VariablesController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Server\Status\Data; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; /** @@ -15,6 +18,12 @@ use PhpMyAdmin\Tests\Stubs\ResponseRenderer; */ class VariablesControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var Data */ private $data; @@ -23,6 +32,9 @@ class VariablesControllerTest extends AbstractTestCase parent::setUp(); parent::setGlobalConfig(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['server'] = 1; @@ -42,8 +54,8 @@ class VariablesControllerTest extends AbstractTestCase $controller = new VariablesController($response, new Template(), $this->data, $GLOBALS['dbi']); $this->dummyDbi->addSelectDb('mysql'); - $controller(); - $this->assertAllSelectsConsumed(); + $controller($this->createStub(ServerRequest::class)); + $this->dummyDbi->assertAllSelectsConsumed(); $html = $response->getHTMLResult(); $this->assertStringContainsString('<div class="card mb-3" id="tableFilter">', $html); diff --git a/test/classes/Controllers/Server/VariablesControllerTest.php b/test/classes/Controllers/Server/VariablesControllerTest.php index be8f53034e..5c608817dc 100644 --- a/test/classes/Controllers/Server/VariablesControllerTest.php +++ b/test/classes/Controllers/Server/VariablesControllerTest.php @@ -7,6 +7,7 @@ namespace PhpMyAdmin\Tests\Controllers\Server; use PhpMyAdmin\Controllers\Server\VariablesController; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Html\Generator; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Providers\ServerVariables\ServerVariablesProvider; use PhpMyAdmin\Providers\ServerVariables\VoidProvider as ServerVariablesVoidProvider; use PhpMyAdmin\ResponseRenderer; @@ -96,7 +97,7 @@ class VariablesControllerTest extends AbstractTestCase $controller = new VariablesController($response, new Template(), $dbi); - $controller(); + $controller($this->createStub(ServerRequest::class)); $html = $response->getHTMLResult(); $this->assertStringContainsString( diff --git a/test/classes/Controllers/Sql/EnumValuesControllerTest.php b/test/classes/Controllers/Sql/EnumValuesControllerTest.php index 2ed5ae0b16..fdb74b2e5b 100644 --- a/test/classes/Controllers/Sql/EnumValuesControllerTest.php +++ b/test/classes/Controllers/Sql/EnumValuesControllerTest.php @@ -5,17 +5,28 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Sql; use PhpMyAdmin\Controllers\Sql\EnumValuesController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; /** * @covers \PhpMyAdmin\Controllers\Sql\EnumValuesController */ class EnumValuesControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + protected function setUp(): void { parent::setUp(); - parent::setGlobalDbi(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; parent::loadContainerBuilder(); parent::loadDbiIntoContainerBuilder(); $GLOBALS['server'] = 1; @@ -26,8 +37,6 @@ class EnumValuesControllerTest extends AbstractTestCase public function testGetEnumValuesError(): void { - global $containerBuilder, $_POST; - $this->dummyDbi->addResult('SHOW COLUMNS FROM `cvv`.`enums` LIKE \'set\'', false); $_POST = [ @@ -40,11 +49,11 @@ class EnumValuesControllerTest extends AbstractTestCase $GLOBALS['db'] = $_POST['db']; $GLOBALS['table'] = $_POST['table']; - $containerBuilder->setParameter('db', $GLOBALS['db']); - $containerBuilder->setParameter('table', $GLOBALS['table']); + $GLOBALS['containerBuilder']->setParameter('db', $GLOBALS['db']); + $GLOBALS['containerBuilder']->setParameter('table', $GLOBALS['table']); /** @var EnumValuesController $sqlController */ - $sqlController = $containerBuilder->get(EnumValuesController::class); - $sqlController(); + $sqlController = $GLOBALS['containerBuilder']->get(EnumValuesController::class); + $sqlController($this->createStub(ServerRequest::class)); $this->assertResponseWasNotSuccessfull(); @@ -56,8 +65,6 @@ class EnumValuesControllerTest extends AbstractTestCase public function testGetEnumValuesSuccess(): void { - global $containerBuilder, $_POST; - $this->dummyDbi->addResult( 'SHOW COLUMNS FROM `cvv`.`enums` LIKE \'set\'', [ @@ -90,11 +97,11 @@ class EnumValuesControllerTest extends AbstractTestCase $GLOBALS['db'] = $_POST['db']; $GLOBALS['table'] = $_POST['table']; - $containerBuilder->setParameter('db', $GLOBALS['db']); - $containerBuilder->setParameter('table', $GLOBALS['table']); + $GLOBALS['containerBuilder']->setParameter('db', $GLOBALS['db']); + $GLOBALS['containerBuilder']->setParameter('table', $GLOBALS['table']); /** @var EnumValuesController $sqlController */ - $sqlController = $containerBuilder->get(EnumValuesController::class); - $sqlController(); + $sqlController = $GLOBALS['containerBuilder']->get(EnumValuesController::class); + $sqlController($this->createStub(ServerRequest::class)); $this->assertResponseWasSuccessfull(); diff --git a/test/classes/Controllers/Sql/SetValuesControllerTest.php b/test/classes/Controllers/Sql/SetValuesControllerTest.php index 7c7570209b..2d578cefef 100644 --- a/test/classes/Controllers/Sql/SetValuesControllerTest.php +++ b/test/classes/Controllers/Sql/SetValuesControllerTest.php @@ -5,17 +5,28 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Sql; use PhpMyAdmin\Controllers\Sql\SetValuesController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; /** * @covers \PhpMyAdmin\Controllers\Sql\SetValuesController */ class SetValuesControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + protected function setUp(): void { parent::setUp(); - parent::setGlobalDbi(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; parent::loadContainerBuilder(); parent::loadDbiIntoContainerBuilder(); $GLOBALS['server'] = 1; @@ -26,8 +37,6 @@ class SetValuesControllerTest extends AbstractTestCase public function testError(): void { - global $containerBuilder, $_POST; - $this->dummyDbi->addResult('SHOW COLUMNS FROM `cvv`.`enums` LIKE \'set\'', false); $_POST = [ @@ -40,11 +49,11 @@ class SetValuesControllerTest extends AbstractTestCase $GLOBALS['db'] = $_POST['db']; $GLOBALS['table'] = $_POST['table']; - $containerBuilder->setParameter('db', $GLOBALS['db']); - $containerBuilder->setParameter('table', $GLOBALS['table']); + $GLOBALS['containerBuilder']->setParameter('db', $GLOBALS['db']); + $GLOBALS['containerBuilder']->setParameter('table', $GLOBALS['table']); /** @var SetValuesController $sqlController */ - $sqlController = $containerBuilder->get(SetValuesController::class); - $sqlController(); + $sqlController = $GLOBALS['containerBuilder']->get(SetValuesController::class); + $sqlController($this->createStub(ServerRequest::class)); $this->assertResponseWasNotSuccessfull(); @@ -56,8 +65,6 @@ class SetValuesControllerTest extends AbstractTestCase public function testSuccess(): void { - global $containerBuilder, $_POST; - $this->dummyDbi->addResult( 'SHOW COLUMNS FROM `cvv`.`enums` LIKE \'set\'', [ @@ -90,11 +97,11 @@ class SetValuesControllerTest extends AbstractTestCase $GLOBALS['db'] = $_POST['db']; $GLOBALS['table'] = $_POST['table']; - $containerBuilder->setParameter('db', $GLOBALS['db']); - $containerBuilder->setParameter('table', $GLOBALS['table']); + $GLOBALS['containerBuilder']->setParameter('db', $GLOBALS['db']); + $GLOBALS['containerBuilder']->setParameter('table', $GLOBALS['table']); /** @var SetValuesController $sqlController */ - $sqlController = $containerBuilder->get(SetValuesController::class); - $sqlController(); + $sqlController = $GLOBALS['containerBuilder']->get(SetValuesController::class); + $sqlController($this->createStub(ServerRequest::class)); $this->assertResponseWasSuccessfull(); diff --git a/test/classes/Controllers/Table/AddFieldControllerTest.php b/test/classes/Controllers/Table/AddFieldControllerTest.php new file mode 100644 index 0000000000..939ba08b81 --- /dev/null +++ b/test/classes/Controllers/Table/AddFieldControllerTest.php @@ -0,0 +1,269 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Config; +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Table\AddFieldController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Table\ColumnsDefinition; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +/** + * @covers \PhpMyAdmin\Controllers\Table\AddFieldController + */ +class AddFieldControllerTest extends AbstractTestCase +{ + public function testInvoke(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $GLOBALS['regenerate'] = null; + $GLOBALS['cfg']['Server'] = $GLOBALS['config']->defaultServer; + $_POST = [ + 'db' => 'test_db', + 'table' => 'test_table', + 'num_fields' => '1', + 'field_where' => 'after', + 'after_field' => 'datetimefield', + ]; + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addSelectDb('test_db'); + $dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + $dbi = $this->createDatabaseInterface($dummyDbi); + $GLOBALS['dbi'] = $dbi; + + $contentCell = [ + 'column_number' => 0, + 'column_meta' => ['Type' => ''], + 'type_upper' => '', + 'default_value' => '', + 'length_values_input_size' => 8, + 'length' => '', + 'extracted_columnspec' => [], + 'submit_attribute' => null, + 'comments_map' => [], + 'fields_meta' => null, + 'is_backup' => false, + 'move_columns' => [], + 'available_mime' => [ + 'mimetype' => [ + 'Image/JPEG' => 'Image/JPEG', + 'Text/Plain' => 'Text/Plain', + 'Application/Octetstream' => 'Application/Octetstream', + 'Image/PNG' => 'Image/PNG', + 'Text/Octetstream' => 'Text/Octetstream', + ], + 'input_transformation' => [ + 'Image/JPEG: Upload', + 'Text/Plain: FileUpload', + 'Text/Plain: Iptobinary', + 'Text/Plain: Iptolong', + 'Text/Plain: JsonEditor', + 'Text/Plain: RegexValidation', + 'Text/Plain: SqlEditor', + 'Text/Plain: XmlEditor', + 'Text/Plain: Link', + 'Text/Plain: Longtoipv4', + 'Text/Plain: PreApPend', + 'Text/Plain: Substring', + ], + 'input_transformation_file' => [ + 'Input/Image_JPEG_Upload.php', + 'Input/Text_Plain_FileUpload.php', + 'Input/Text_Plain_Iptobinary.php', + 'Input/Text_Plain_Iptolong.php', + 'Input/Text_Plain_JsonEditor.php', + 'Input/Text_Plain_RegexValidation.php', + 'Input/Text_Plain_SqlEditor.php', + 'Input/Text_Plain_XmlEditor.php', + 'Text_Plain_Link.php', + 'Text_Plain_Longtoipv4.php', + 'Text_Plain_PreApPend.php', + 'Text_Plain_Substring.php', + ], + 'transformation' => [ + 'Application/Octetstream: Download', + 'Application/Octetstream: Hex', + 'Image/JPEG: Inline', + 'Image/JPEG: Link', + 'Image/PNG: Inline', + 'Text/Octetstream: Sql', + 'Text/Plain: Binarytoip', + 'Text/Plain: Bool2Text', + 'Text/Plain: Dateformat', + 'Text/Plain: External', + 'Text/Plain: Formatted', + 'Text/Plain: Imagelink', + 'Text/Plain: Json', + 'Text/Plain: Sql', + 'Text/Plain: Xml', + 'Text/Plain: Link', + 'Text/Plain: Longtoipv4', + 'Text/Plain: PreApPend', + 'Text/Plain: Substring', + ], + 'transformation_file' => [ + 'Output/Application_Octetstream_Download.php', + 'Output/Application_Octetstream_Hex.php', + 'Output/Image_JPEG_Inline.php', + 'Output/Image_JPEG_Link.php', + 'Output/Image_PNG_Inline.php', + 'Output/Text_Octetstream_Sql.php', + 'Output/Text_Plain_Binarytoip.php', + 'Output/Text_Plain_Bool2Text.php', + 'Output/Text_Plain_Dateformat.php', + 'Output/Text_Plain_External.php', + 'Output/Text_Plain_Formatted.php', + 'Output/Text_Plain_Imagelink.php', + 'Output/Text_Plain_Json.php', + 'Output/Text_Plain_Sql.php', + 'Output/Text_Plain_Xml.php', + 'Text_Plain_Link.php', + 'Text_Plain_Longtoipv4.php', + 'Text_Plain_PreApPend.php', + 'Text_Plain_Substring.php', + ], + 'input_transformation_file_quoted' => [ + 'Input/Image_JPEG_Upload\\.php', + 'Input/Text_Plain_FileUpload\\.php', + 'Input/Text_Plain_Iptobinary\\.php', + 'Input/Text_Plain_Iptolong\\.php', + 'Input/Text_Plain_JsonEditor\\.php', + 'Input/Text_Plain_RegexValidation\\.php', + 'Input/Text_Plain_SqlEditor\\.php', + 'Input/Text_Plain_XmlEditor\\.php', + 'Text_Plain_Link\\.php', + 'Text_Plain_Longtoipv4\\.php', + 'Text_Plain_PreApPend\\.php', + 'Text_Plain_Substring\\.php', + ], + 'transformation_file_quoted' => [ + 'Output/Application_Octetstream_Download\\.php', + 'Output/Application_Octetstream_Hex\\.php', + 'Output/Image_JPEG_Inline\\.php', + 'Output/Image_JPEG_Link\\.php', + 'Output/Image_PNG_Inline\\.php', + 'Output/Text_Octetstream_Sql\\.php', + 'Output/Text_Plain_Binarytoip\\.php', + 'Output/Text_Plain_Bool2Text\\.php', + 'Output/Text_Plain_Dateformat\\.php', + 'Output/Text_Plain_External\\.php', + 'Output/Text_Plain_Formatted\\.php', + 'Output/Text_Plain_Imagelink\\.php', + 'Output/Text_Plain_Json\\.php', + 'Output/Text_Plain_Sql\\.php', + 'Output/Text_Plain_Xml\\.php', + 'Text_Plain_Link\\.php', + 'Text_Plain_Longtoipv4\\.php', + 'Text_Plain_PreApPend\\.php', + 'Text_Plain_Substring\\.php', + ], + ], + 'mime_map' => [], + ]; + + $relation = new Relation($dbi); + $response = new ResponseRenderer(); + $template = new Template(); + $expected = $template->render('columns_definitions/column_definitions_form', [ + 'is_backup' => false, + 'fields_meta' => null, + 'relation_parameters' => $relation->getRelationParameters(), + 'action' => '/table/add-field', + 'form_params' => [ + 'db' => 'test_db', + 'field_where' => 'after', + 'after_field' => 'datetimefield', + 'table' => 'test_table', + 'orig_num_fields' => 1, + 'orig_field_where' => 'after', + 'orig_after_field' => 'datetimefield', + ], + 'content_cells' => [$contentCell], + 'partition_details' => [ + 'partition_by' => null, + 'partition_expr' => null, + 'subpartition_by' => null, + 'subpartition_expr' => null, + 'partition_count' => 0, + 'subpartition_count' => 0, + 'can_have_subpartitions' => false, + 'value_enabled' => false, + ], + 'primary_indexes' => null, + 'unique_indexes' => null, + 'indexes' => null, + 'fulltext_indexes' => null, + 'spatial_indexes' => null, + 'table' => 'test_table', + 'comment' => null, + 'tbl_collation' => null, + 'charsets' => [ + [ + 'name' => 'armscii8', + 'description' => 'armscii8_general_ci', + 'collations' => [['name' => 'armscii8_general_ci', 'description' => 'Armenian, case-insensitive']], + ], + [ + 'name' => 'latin1', + 'description' => 'cp1252 West European', + 'collations' => [['name' => 'latin1_swedish_ci', 'description' => 'Swedish, case-insensitive']], + ], + [ + 'name' => 'utf8', + 'description' => 'UTF-8 Unicode', + 'collations' => [ + ['name' => 'utf8_bin', 'description' => 'Unicode, binary'], + ['name' => 'utf8_general_ci', 'description' => 'Unicode, case-insensitive'], + ], + ], + [ + 'name' => 'utf8mb4', + 'description' => 'utf8mb4_0900_ai_ci', + 'collations' => [ + ['name' => 'utf8mb4_general_ci', 'description' => 'Unicode (UCA 4.0.0), case-insensitive'], + ], + ], + ], + 'tbl_storage_engine' => null, + 'storage_engines' => ['dummy' => ['name' => 'dummy', 'comment' => 'dummy comment', 'is_default' => false]], + 'connection' => null, + 'change_column' => null, + 'is_virtual_columns_supported' => true, + 'is_integers_length_restricted' => false, + 'browse_mime' => true, + 'supports_stored_keyword' => false, + 'server_version' => $dbi->getVersion(), + 'max_rows' => 25, + 'char_editing' => 'input', + 'attribute_types' => ['', 'BINARY', 'UNSIGNED', 'UNSIGNED ZEROFILL', 'on update CURRENT_TIMESTAMP'], + 'privs_available' => false, + 'max_length' => 1024, + 'have_partitioning' => true, + 'dbi' => $dbi, + 'disable_is' => true, + ]); + + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturnMap([['num_fields', null, '1']]); + + $transformations = new Transformations(); + (new AddFieldController( + $response, + $template, + $transformations, + new Config(), + $dbi, + new ColumnsDefinition($dbi, $relation, $transformations) + ))($request); + + $this->assertSame($expected, $response->getHTMLResult()); + } +} diff --git a/test/classes/Controllers/Table/ChangeControllerTest.php b/test/classes/Controllers/Table/ChangeControllerTest.php new file mode 100644 index 0000000000..0946a23444 --- /dev/null +++ b/test/classes/Controllers/Table/ChangeControllerTest.php @@ -0,0 +1,81 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Config\PageSettings; +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Table\ChangeController; +use PhpMyAdmin\FileListing; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\InsertEdit; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +/** + * @covers \PhpMyAdmin\Controllers\Table\ChangeController + */ +class ChangeControllerTest extends AbstractTestCase +{ + public function testChangeController(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addSelectDb('test_db'); + $dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + $dummyDbi->addResult( + 'SELECT * FROM `test_db`.`test_table` LIMIT 1;', + [['1', 'abcd', '2011-01-20 02:00:02']], + ['id', 'name', 'datetimefield'] + ); + $dummyDbi->addSelectDb('test_db'); + $dbi = $this->createDatabaseInterface($dummyDbi); + $GLOBALS['dbi'] = $dbi; + + $response = new ResponseRenderer(); + $pageSettings = new PageSettings('Edit'); + + $request = $this->createStub(ServerRequest::class); + + $relation = new Relation($dbi); + $template = new Template(); + (new ChangeController( + $response, + $template, + new InsertEdit($dbi, $relation, new Transformations(), new FileListing(), $template), + $relation + ))($request); + $actual = $response->getHTMLResult(); + + $this->assertStringContainsString($pageSettings->getHTML(), $actual); + $this->assertStringContainsString( + '<input type="text" name="fields[multi_edit][0][b80bb7740288fda1f201890375a60c8f]" value="NULL"' + . ' size="4" min="-2147483648" max="2147483647" data-type="INT" class="textfield"' + . ' onchange="return' + . ' verificationsAfterFieldChange(\'b80bb7740288fda1f201890375a60c8f\', \'0\',\'int(11)\')"' + . ' tabindex="1" id="field_1_3"><input type="hidden"' + . ' name="auto_increment[multi_edit][0][b80bb7740288fda1f201890375a60c8f]" value="1">', + $actual + ); + $this->assertStringContainsString( + '<input type="text" name="fields[multi_edit][0][b068931cc450442b63f5b3d276ea4297]" value="NULL" size="20"' + . ' data-maxlength="20" data-type="CHAR" class="textfield" onchange="return' + . ' verificationsAfterFieldChange(\'b068931cc450442b63f5b3d276ea4297\', \'0\',\'varchar(20)\')"' + . ' tabindex="2" id="field_2_3">', + $actual + ); + $this->assertStringContainsString( + '<input type="text" name="fields[multi_edit][0][a55dbdcc1a45ed90dbee68864d566b99]" value="NULL.000000"' + . ' size="4" data-type="DATE" class="textfield datetimefield" onchange="return' + . ' verificationsAfterFieldChange(\'a55dbdcc1a45ed90dbee68864d566b99\', \'0\',\'datetime\')"' + . ' tabindex="3" id="field_3_3"><input type="hidden"' + . ' name="fields_type[multi_edit][0][a55dbdcc1a45ed90dbee68864d566b99]" value="datetime">', + $actual + ); + } +} diff --git a/test/classes/Controllers/Table/ChangeRowsControllerTest.php b/test/classes/Controllers/Table/ChangeRowsControllerTest.php new file mode 100644 index 0000000000..ec7a501470 --- /dev/null +++ b/test/classes/Controllers/Table/ChangeRowsControllerTest.php @@ -0,0 +1,80 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Controllers\Table\ChangeController; +use PhpMyAdmin\Controllers\Table\ChangeRowsController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\ChangeRowsController + */ +class ChangeRowsControllerTest extends AbstractTestCase +{ + protected function setUp(): void + { + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + $GLOBALS['server'] = 2; + $GLOBALS['active_page'] = null; + $GLOBALS['where_clause'] = null; + $_POST = []; + } + + public function testChangeRowsController(): void + { + $_POST['rows_to_delete'] = 'row'; + + $request = $this->createStub(ServerRequest::class); + $mock = $this->createMock(ChangeController::class); + $mock->expects($this->once())->method('__invoke')->with($request); + + (new ChangeRowsController(new ResponseRenderer(), new Template(), $mock))($request); + + /** @psalm-suppress InvalidArrayOffset */ + $this->assertSame('index.php?route=/table/change&server=2&lang=en', $GLOBALS['active_page']); + /** @psalm-suppress InvalidArrayOffset */ + $this->assertSame([], $GLOBALS['where_clause']); + } + + public function testWithoutRowsToDelete(): void + { + $_POST['goto'] = 'goto'; + + $request = $this->createStub(ServerRequest::class); + $mock = $this->createMock(ChangeController::class); + $mock->expects($this->never())->method('__invoke')->with($request); + + $response = new ResponseRenderer(); + (new ChangeRowsController($response, new Template(), $mock))($request); + + $this->assertSame(['message' => 'No row selected.'], $response->getJSONResult()); + $this->assertFalse($response->hasSuccessState()); + /** @psalm-suppress InvalidArrayOffset */ + $this->assertNull($GLOBALS['active_page']); + /** @psalm-suppress InvalidArrayOffset */ + $this->assertNull($GLOBALS['where_clause']); + } + + public function testWithRowsToDelete(): void + { + $_POST['goto'] = 'goto'; + $_POST['rows_to_delete'] = ['key1' => 'row1', 'key2' => 'row2']; + + $request = $this->createStub(ServerRequest::class); + $mock = $this->createMock(ChangeController::class); + $mock->expects($this->once())->method('__invoke')->with($request); + + (new ChangeRowsController(new ResponseRenderer(), new Template(), $mock))($request); + + /** @psalm-suppress InvalidArrayOffset */ + $this->assertSame('index.php?route=/table/change&server=2&lang=en', $GLOBALS['active_page']); + /** @psalm-suppress InvalidArrayOffset */ + $this->assertSame(['row1', 'row2'], $GLOBALS['where_clause']); + } +} diff --git a/test/classes/Controllers/Table/ChartControllerTest.php b/test/classes/Controllers/Table/ChartControllerTest.php new file mode 100644 index 0000000000..19baba45f5 --- /dev/null +++ b/test/classes/Controllers/Table/ChartControllerTest.php @@ -0,0 +1,101 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Controllers\Table\ChartController; +use PhpMyAdmin\FieldMetadata; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +use const MYSQLI_NOT_NULL_FLAG; +use const MYSQLI_NUM_FLAG; +use const MYSQLI_PRI_KEY_FLAG; +use const MYSQLI_TYPE_DATE; +use const MYSQLI_TYPE_LONG; + +/** + * @covers \PhpMyAdmin\Controllers\Table\ChartController + */ +class ChartControllerTest extends AbstractTestCase +{ + public function testChartController(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'table_for_chart'; + $GLOBALS['sql_query'] = 'SELECT * FROM `test_db`.`table_for_chart`;'; + $_POST = [ + 'db' => 'test_db', + 'table' => 'table_for_chart', + 'printview' => '1', + 'sql_query' => 'SELECT * FROM `test_db`.`table_for_chart`;', + 'single_table' => 'true', + 'unlim_num_rows' => '4', + ]; + $_REQUEST['unlim_num_rows'] = '4'; + $_REQUEST['pos'] = '0'; + + $fieldsMeta = [ + new FieldMetadata( + MYSQLI_TYPE_LONG, + MYSQLI_PRI_KEY_FLAG | MYSQLI_NUM_FLAG | MYSQLI_NOT_NULL_FLAG, + (object) ['name' => 'id', 'table' => 'table_for_chart'] + ), + new FieldMetadata( + MYSQLI_TYPE_LONG, + MYSQLI_NUM_FLAG | MYSQLI_NOT_NULL_FLAG, + (object) ['name' => 'amount', 'table' => 'table_for_chart'] + ), + new FieldMetadata( + MYSQLI_TYPE_DATE, + MYSQLI_NOT_NULL_FLAG, + (object) ['name' => 'date', 'table' => 'table_for_chart'] + ), + ]; + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addSelectDb('test_db'); + $dummyDbi->addResult('SHOW TABLES LIKE \'table_for_chart\';', [['table_for_chart']]); + $dummyDbi->addSelectDb('test_db'); + $dummyDbi->addResult( + 'SELECT * FROM `test_db`.`table_for_chart`;', + [ + ['1', '7', '2022-02-08'], + ['2', '5', '2022-02-09'], + ['3', '3', '2022-02-10'], + ['4', '9', '2022-02-11'], + ], + ['id', 'amount', 'date'], + $fieldsMeta + ); + $dbi = $this->createDatabaseInterface($dummyDbi); + $GLOBALS['dbi'] = $dbi; + + $response = new ResponseRenderer(); + $template = new Template(); + $expected = $template->render('table/chart/tbl_chart', [ + 'url_params' => [ + 'db' => 'test_db', + 'table' => 'table_for_chart', + 'goto' => 'index.php?route=/sql&lang=en', + 'back' => 'index.php?route=/table/sql&lang=en', + 'reload' => 1, + ], + 'keys' => ['id', 'amount', 'date'], + 'fields_meta' => $fieldsMeta, + 'table_has_a_numeric_column' => true, + 'start_and_number_of_rows_fieldset' => [ + 'pos' => 0, + 'unlim_num_rows' => 4, + 'rows' => 25, + 'sql_query' => 'SELECT * FROM `test_db`.`table_for_chart`;', + ], + ]); + + (new ChartController($response, $template, $dbi))($this->createStub(ServerRequest::class)); + $this->assertSame($expected, $response->getHTMLResult()); + } +} diff --git a/test/classes/Controllers/Table/CreateControllerTest.php b/test/classes/Controllers/Table/CreateControllerTest.php new file mode 100644 index 0000000000..429f2f2a67 --- /dev/null +++ b/test/classes/Controllers/Table/CreateControllerTest.php @@ -0,0 +1,261 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Config; +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Table\CreateController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Table\ColumnsDefinition; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +use function array_merge; + +/** + * @covers \PhpMyAdmin\Controllers\Table\CreateController + */ +class CreateControllerTest extends AbstractTestCase +{ + public function testCreateController(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'new_test_table'; + $GLOBALS['cfg']['Server'] = $GLOBALS['config']->defaultServer; + $_POST = ['db' => 'test_db', 'table' => 'new_test_table', 'num_fields' => '2']; + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addSelectDb('test_db'); + $dummyDbi->addResult('SHOW COLUMNS FROM `test_db`.`new_test_table`', false); + $dummyDbi->addResult('SHOW FULL COLUMNS FROM `test_db`.`new_test_table`', false); + $dummyDbi->addResult('SHOW CREATE TABLE `test_db`.`new_test_table`', false); + $dbi = $this->createDatabaseInterface($dummyDbi); + $GLOBALS['dbi'] = $dbi; + + $contentCell = [ + 'column_number' => 0, + 'column_meta' => ['Type' => ''], + 'type_upper' => '', + 'default_value' => '', + 'length_values_input_size' => 8, + 'length' => '', + 'extracted_columnspec' => [], + 'submit_attribute' => null, + 'comments_map' => [], + 'fields_meta' => null, + 'is_backup' => false, + 'move_columns' => [], + 'available_mime' => [ + 'mimetype' => [ + 'Image/JPEG' => 'Image/JPEG', + 'Text/Plain' => 'Text/Plain', + 'Application/Octetstream' => 'Application/Octetstream', + 'Image/PNG' => 'Image/PNG', + 'Text/Octetstream' => 'Text/Octetstream', + ], + 'input_transformation' => [ + 'Image/JPEG: Upload', + 'Text/Plain: FileUpload', + 'Text/Plain: Iptobinary', + 'Text/Plain: Iptolong', + 'Text/Plain: JsonEditor', + 'Text/Plain: RegexValidation', + 'Text/Plain: SqlEditor', + 'Text/Plain: XmlEditor', + 'Text/Plain: Link', + 'Text/Plain: Longtoipv4', + 'Text/Plain: PreApPend', + 'Text/Plain: Substring', + ], + 'input_transformation_file' => [ + 'Input/Image_JPEG_Upload.php', + 'Input/Text_Plain_FileUpload.php', + 'Input/Text_Plain_Iptobinary.php', + 'Input/Text_Plain_Iptolong.php', + 'Input/Text_Plain_JsonEditor.php', + 'Input/Text_Plain_RegexValidation.php', + 'Input/Text_Plain_SqlEditor.php', + 'Input/Text_Plain_XmlEditor.php', + 'Text_Plain_Link.php', + 'Text_Plain_Longtoipv4.php', + 'Text_Plain_PreApPend.php', + 'Text_Plain_Substring.php', + ], + 'transformation' => [ + 'Application/Octetstream: Download', + 'Application/Octetstream: Hex', + 'Image/JPEG: Inline', + 'Image/JPEG: Link', + 'Image/PNG: Inline', + 'Text/Octetstream: Sql', + 'Text/Plain: Binarytoip', + 'Text/Plain: Bool2Text', + 'Text/Plain: Dateformat', + 'Text/Plain: External', + 'Text/Plain: Formatted', + 'Text/Plain: Imagelink', + 'Text/Plain: Json', + 'Text/Plain: Sql', + 'Text/Plain: Xml', + 'Text/Plain: Link', + 'Text/Plain: Longtoipv4', + 'Text/Plain: PreApPend', + 'Text/Plain: Substring', + ], + 'transformation_file' => [ + 'Output/Application_Octetstream_Download.php', + 'Output/Application_Octetstream_Hex.php', + 'Output/Image_JPEG_Inline.php', + 'Output/Image_JPEG_Link.php', + 'Output/Image_PNG_Inline.php', + 'Output/Text_Octetstream_Sql.php', + 'Output/Text_Plain_Binarytoip.php', + 'Output/Text_Plain_Bool2Text.php', + 'Output/Text_Plain_Dateformat.php', + 'Output/Text_Plain_External.php', + 'Output/Text_Plain_Formatted.php', + 'Output/Text_Plain_Imagelink.php', + 'Output/Text_Plain_Json.php', + 'Output/Text_Plain_Sql.php', + 'Output/Text_Plain_Xml.php', + 'Text_Plain_Link.php', + 'Text_Plain_Longtoipv4.php', + 'Text_Plain_PreApPend.php', + 'Text_Plain_Substring.php', + ], + 'input_transformation_file_quoted' => [ + 'Input/Image_JPEG_Upload\\.php', + 'Input/Text_Plain_FileUpload\\.php', + 'Input/Text_Plain_Iptobinary\\.php', + 'Input/Text_Plain_Iptolong\\.php', + 'Input/Text_Plain_JsonEditor\\.php', + 'Input/Text_Plain_RegexValidation\\.php', + 'Input/Text_Plain_SqlEditor\\.php', + 'Input/Text_Plain_XmlEditor\\.php', + 'Text_Plain_Link\\.php', + 'Text_Plain_Longtoipv4\\.php', + 'Text_Plain_PreApPend\\.php', + 'Text_Plain_Substring\\.php', + ], + 'transformation_file_quoted' => [ + 'Output/Application_Octetstream_Download\\.php', + 'Output/Application_Octetstream_Hex\\.php', + 'Output/Image_JPEG_Inline\\.php', + 'Output/Image_JPEG_Link\\.php', + 'Output/Image_PNG_Inline\\.php', + 'Output/Text_Octetstream_Sql\\.php', + 'Output/Text_Plain_Binarytoip\\.php', + 'Output/Text_Plain_Bool2Text\\.php', + 'Output/Text_Plain_Dateformat\\.php', + 'Output/Text_Plain_External\\.php', + 'Output/Text_Plain_Formatted\\.php', + 'Output/Text_Plain_Imagelink\\.php', + 'Output/Text_Plain_Json\\.php', + 'Output/Text_Plain_Sql\\.php', + 'Output/Text_Plain_Xml\\.php', + 'Text_Plain_Link\\.php', + 'Text_Plain_Longtoipv4\\.php', + 'Text_Plain_PreApPend\\.php', + 'Text_Plain_Substring\\.php', + ], + ], + 'mime_map' => [], + ]; + + $relation = new Relation($dbi); + $response = new ResponseRenderer(); + $template = new Template(); + $expected = $template->render('columns_definitions/column_definitions_form', [ + 'is_backup' => false, + 'fields_meta' => null, + 'relation_parameters' => $relation->getRelationParameters(), + 'action' => '/table/create', + 'form_params' => [ + 'db' => 'test_db', + 'reload' => 1, + 'orig_num_fields' => 2, + 'orig_field_where' => null, + 'orig_after_field' => null, + ], + 'content_cells' => [$contentCell, array_merge($contentCell, ['column_number' => 1])], + 'partition_details' => [ + 'partition_by' => null, + 'partition_expr' => null, + 'subpartition_by' => null, + 'subpartition_expr' => null, + 'partition_count' => 0, + 'subpartition_count' => 0, + 'can_have_subpartitions' => false, + 'value_enabled' => false, + ], + 'primary_indexes' => null, + 'unique_indexes' => null, + 'indexes' => null, + 'fulltext_indexes' => null, + 'spatial_indexes' => null, + 'table' => 'new_test_table', + 'comment' => null, + 'tbl_collation' => null, + 'charsets' => [ + [ + 'name' => 'armscii8', + 'description' => 'armscii8_general_ci', + 'collations' => [['name' => 'armscii8_general_ci', 'description' => 'Armenian, case-insensitive']], + ], + [ + 'name' => 'latin1', + 'description' => 'cp1252 West European', + 'collations' => [['name' => 'latin1_swedish_ci', 'description' => 'Swedish, case-insensitive']], + ], + [ + 'name' => 'utf8', + 'description' => 'UTF-8 Unicode', + 'collations' => [ + ['name' => 'utf8_bin', 'description' => 'Unicode, binary'], + ['name' => 'utf8_general_ci', 'description' => 'Unicode, case-insensitive'], + ], + ], + [ + 'name' => 'utf8mb4', + 'description' => 'utf8mb4_0900_ai_ci', + 'collations' => [ + ['name' => 'utf8mb4_general_ci', 'description' => 'Unicode (UCA 4.0.0), case-insensitive'], + ], + ], + ], + 'tbl_storage_engine' => null, + 'storage_engines' => ['dummy' => ['name' => 'dummy', 'comment' => 'dummy comment', 'is_default' => false]], + 'connection' => null, + 'change_column' => null, + 'is_virtual_columns_supported' => true, + 'is_integers_length_restricted' => false, + 'browse_mime' => true, + 'supports_stored_keyword' => false, + 'server_version' => $dbi->getVersion(), + 'max_rows' => 25, + 'char_editing' => 'input', + 'attribute_types' => ['', 'BINARY', 'UNSIGNED', 'UNSIGNED ZEROFILL', 'on update CURRENT_TIMESTAMP'], + 'privs_available' => false, + 'max_length' => 1024, + 'have_partitioning' => true, + 'dbi' => $dbi, + 'disable_is' => false, + ]); + + $transformations = new Transformations(); + (new CreateController( + $response, + $template, + $transformations, + new Config(), + $dbi, + new ColumnsDefinition($dbi, $relation, $transformations) + ))($this->createStub(ServerRequest::class)); + + $this->assertSame($expected, $response->getHTMLResult()); + } +} diff --git a/test/classes/Controllers/Table/DeleteConfirmControllerTest.php b/test/classes/Controllers/Table/DeleteConfirmControllerTest.php new file mode 100644 index 0000000000..6649972f20 --- /dev/null +++ b/test/classes/Controllers/Table/DeleteConfirmControllerTest.php @@ -0,0 +1,49 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Controllers\Table\DeleteConfirmController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\DeleteConfirmController + */ +class DeleteConfirmControllerTest extends AbstractTestCase +{ + public function testDeleteConfirmController(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $GLOBALS['sql_query'] = 'SELECT * FROM `test_db`.`test_table`'; + $_POST = [ + 'db' => 'test_db', + 'table' => 'test_table', + 'rows_to_delete' => ['`test_table`.`id` = 2', '`test_table`.`id` = 3'], + 'sql_query' => 'SELECT * FROM `test_db`.`test_table`', + ]; + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addSelectDb('test_db'); + $dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + $dbi = $this->createDatabaseInterface($dummyDbi); + $GLOBALS['dbi'] = $dbi; + + $response = new ResponseRenderer(); + $template = new Template(); + $expected = $template->render('table/delete/confirm', [ + 'db' => 'test_db', + 'table' => 'test_table', + 'selected' => ['`test_table`.`id` = 2', '`test_table`.`id` = 3'], + 'sql_query' => 'SELECT * FROM `test_db`.`test_table`', + 'is_foreign_key_check' => true, + ]); + + (new DeleteConfirmController($response, $template))($this->createStub(ServerRequest::class)); + $this->assertSame($expected, $response->getHTMLResult()); + } +} diff --git a/test/classes/Controllers/Table/DeleteRowsControllerTest.php b/test/classes/Controllers/Table/DeleteRowsControllerTest.php new file mode 100644 index 0000000000..e55650b6c8 --- /dev/null +++ b/test/classes/Controllers/Table/DeleteRowsControllerTest.php @@ -0,0 +1,70 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Controllers\Table\DeleteRowsController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\DeleteRowsController + */ +class DeleteRowsControllerTest extends AbstractTestCase +{ + public function testDeleteRowsController(): void + { + $this->setTheme(); + $GLOBALS['goto'] = null; + $GLOBALS['showtable'] = null; + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $GLOBALS['urlParams'] = []; + $GLOBALS['cfg']['Server'] = $GLOBALS['config']->defaultServer; + $GLOBALS['cfg']['Server']['DisableIS'] = true; + $_POST = [ + 'db' => 'test_db', + 'table' => 'test_table', + 'selected' => [2 => '`test_table`.`id` = 3'], + 'original_sql_query' => 'SELECT * FROM `test_db`.`test_table`', + 'fk_checks' => '1', + 'mult_btn' => 'Yes', + ]; + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addSelectDb('test_db'); + $dummyDbi->addResult('DELETE FROM `test_table` WHERE `test_table`.`id` = 3 LIMIT 1;', []); + $dummyDbi->addSelectDb('test_db'); + $dummyDbi->addResult( + 'SELECT * FROM `test_db`.`test_table` LIMIT 0, 25', + [['1', 'abcd', '2011-01-20 02:00:02'], ['2', 'foo', '2010-01-20 02:00:02']], + ['id', 'name', 'datetimefield'] + ); + $dummyDbi->addResult( + 'SELECT TABLE_NAME FROM information_schema.VIEWS WHERE TABLE_SCHEMA = \'test_db\'' + . ' AND TABLE_NAME = \'test_table\' AND IS_UPDATABLE = \'YES\'', + [], + ['TABLE_NAME'] + ); + $dbi = $this->createDatabaseInterface($dummyDbi); + $GLOBALS['dbi'] = $dbi; + + $response = new ResponseRenderer(); + (new DeleteRowsController($response, new Template(), $dbi))($this->createStub(ServerRequest::class)); + $actual = $response->getHTMLResult(); + $this->assertStringContainsString( + '<div class="alert alert-success" role="alert">Your SQL query has been executed successfully.</div>', + $actual + ); + $this->assertStringContainsString('DELETE FROM `test_table` WHERE `test_table`.`id` = 3 LIMIT 1;', $actual); + $this->assertStringContainsString('Showing rows 0 - 1 (2 total, Query took', $actual); + $this->assertStringContainsString('SELECT * FROM `test_db`.`test_table`', $actual); + $this->assertStringContainsString( + '<td data-decimals="0" data-type="string" data-originallength="4" class="data text pre_wrap">abcd</td>', + $actual + ); + } +} diff --git a/test/classes/Controllers/Table/DropColumnConfirmationControllerTest.php b/test/classes/Controllers/Table/DropColumnConfirmationControllerTest.php new file mode 100644 index 0000000000..4cd1f2e5ef --- /dev/null +++ b/test/classes/Controllers/Table/DropColumnConfirmationControllerTest.php @@ -0,0 +1,102 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Controllers\Table\DropColumnConfirmationController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\DropColumnConfirmationController + */ +class DropColumnConfirmationControllerTest extends AbstractTestCase +{ + protected function setUp(): void + { + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + } + + public function testWithValidParameters(): void + { + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturnMap([ + ['db', null, 'test_db'], + ['table', null, 'test_table'], + ['selected_fld', null, ['name', 'datetimefield']], + ]); + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addSelectDb('test_db'); + $dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + $dbi = $this->createDatabaseInterface($dummyDbi); + $GLOBALS['dbi'] = $dbi; + + $response = new ResponseRenderer(); + $response->setAjax(true); + + $template = new Template(); + $expected = $template->render('table/structure/drop_confirm', [ + 'db' => 'test_db', + 'table' => 'test_table', + 'fields' => ['name', 'datetimefield'], + ]); + + (new DropColumnConfirmationController($response, $template))($request); + + $this->assertSame(200, $response->getHttpResponseCode()); + $this->assertTrue($response->hasSuccessState()); + $this->assertSame([], $response->getJSONResult()); + $this->assertSame($expected, $response->getHTMLResult()); + } + + public function testWithoutFields(): void + { + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturnMap([ + ['db', null, 'test_db'], + ['table', null, 'test_table'], + ['selected_fld', null, null], + ]); + + $response = new ResponseRenderer(); + $response->setAjax(true); + + (new DropColumnConfirmationController($response, new Template()))($request); + + $this->assertSame(400, $response->getHttpResponseCode()); + $this->assertFalse($response->hasSuccessState()); + $this->assertSame([ + 'isErrorResponse' => true, + 'message' => 'No column selected.', + ], $response->getJSONResult()); + $this->assertSame('', $response->getHTMLResult()); + } + + public function testWithoutDatabaseAndTable(): void + { + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturnMap([ + ['db', null, null], + ['table', null, null], + ['selected_fld', null, ['name', 'datetimefield']], + ]); + + $response = new ResponseRenderer(); + $response->setAjax(true); + + (new DropColumnConfirmationController($response, new Template()))($request); + + $this->assertSame(400, $response->getHttpResponseCode()); + $this->assertFalse($response->hasSuccessState()); + $this->assertSame([ + 'isErrorResponse' => true, + 'message' => 'The database name must be a non-empty string.', + ], $response->getJSONResult()); + $this->assertSame('', $response->getHTMLResult()); + } +} diff --git a/test/classes/Controllers/Table/DropColumnControllerTest.php b/test/classes/Controllers/Table/DropColumnControllerTest.php new file mode 100644 index 0000000000..64262322e7 --- /dev/null +++ b/test/classes/Controllers/Table/DropColumnControllerTest.php @@ -0,0 +1,58 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\ConfigStorage\RelationCleanup; +use PhpMyAdmin\Controllers\Table\DropColumnController; +use PhpMyAdmin\FlashMessages; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\DropColumnController + */ +class DropColumnControllerTest extends AbstractTestCase +{ + protected function setUp(): void + { + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + } + + public function testDropColumnController(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $_POST = [ + 'db' => 'test_db', + 'table' => 'test_table', + 'selected' => ['name', 'datetimefield'], + 'mult_btn' => 'Yes', + ]; + $_SESSION = [' PMA_token ' => 'token']; + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addSelectDb('test_db'); + $dummyDbi->addResult('ALTER TABLE `test_table` DROP `name`, DROP `datetimefield`;', []); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $this->assertArrayNotHasKey('flashMessages', $_SESSION); + + (new DropColumnController( + new ResponseRenderer(), + new Template(), + $dbi, + new FlashMessages(), + new RelationCleanup($dbi, new Relation($dbi)) + ))($this->createStub(ServerRequest::class)); + + $this->assertArrayHasKey('flashMessages', $_SESSION); + /** @psalm-suppress InvalidArrayOffset */ + $this->assertSame(['success' => ['2 columns have been dropped successfully.']], $_SESSION['flashMessages']); + } +} diff --git a/test/classes/Controllers/Table/ExportControllerTest.php b/test/classes/Controllers/Table/ExportControllerTest.php new file mode 100644 index 0000000000..e86d4a1697 --- /dev/null +++ b/test/classes/Controllers/Table/ExportControllerTest.php @@ -0,0 +1,109 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Config\PageSettings; +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Table\ExportController; +use PhpMyAdmin\Encoding; +use PhpMyAdmin\Export\Options; +use PhpMyAdmin\Export\TemplateModel; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Plugins; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\ExportController + */ +class ExportControllerTest extends AbstractTestCase +{ + protected function setUp(): void + { + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + } + + public function testExportController(): void + { + parent::loadDbiIntoContainerBuilder(); + + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $GLOBALS['cfg']['Server'] = $GLOBALS['config']->defaultServer; + $GLOBALS['cfg']['Server']['DisableIS'] = true; + $GLOBALS['single_table'] = '1'; + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addResult('SELECT COUNT(*) FROM `test_db`.`test_table`', [['3']]); + $dbi = $this->createDatabaseInterface($dummyDbi); + $GLOBALS['dbi'] = $dbi; + + $response = new ResponseRenderer(); + $pageSettings = new PageSettings('Export'); + $template = new Template(); + $exportList = Plugins::getExport('table', true); + + $expected = $template->render('table/export/index', [ + 'export_type' => 'table', + 'db' => 'test_db', + 'table' => 'test_table', + 'templates' => ['is_enabled' => false, 'templates' => [], 'selected' => null], + 'sql_query' => '', + 'hidden_inputs' => [ + 'db' => 'test_db', + 'table' => 'test_table', + 'export_type' => 'table', + 'export_method' => 'quick', + 'template_id' => '', + 'single_table' => true, + ], + 'export_method' => 'quick', + 'plugins_choice' => Plugins::getChoice($exportList, 'sql'), + 'options' => Plugins::getOptions('Export', $exportList), + 'can_convert_kanji' => false, + 'exec_time_limit' => 300, + 'rows' => [ + 'allrows' => null, + 'limit_to' => null, + 'limit_from' => null, + 'unlim_num_rows' => 0, + 'number_of_rows' => '3', + ], + 'has_save_dir' => false, + 'save_dir' => '/', + 'export_is_checked' => false, + 'export_overwrite_is_checked' => false, + 'has_aliases' => false, + 'aliases' => [], + 'is_checked_lock_tables' => false, + 'is_checked_asfile' => true, + 'is_checked_as_separate_files' => false, + 'is_checked_export' => false, + 'is_checked_export_overwrite' => false, + 'is_checked_remember_file_template' => true, + 'repopulate' => false, + 'lock_tables' => false, + 'is_encoding_supported' => true, + 'encodings' => Encoding::listEncodings(), + 'export_charset' => '', + 'export_asfile' => true, + 'has_zip' => true, + 'has_gzip' => true, + 'selected_compression' => 'none', + 'filename_template' => '@TABLE@', + 'page_settings_error_html' => $pageSettings->getErrorHTML(), + 'page_settings_html' => $pageSettings->getHTML(), + ]); + + (new ExportController( + $response, + $template, + new Options(new Relation($dbi), new TemplateModel($dbi)) + ))($this->createStub(ServerRequest::class)); + $this->assertSame($expected, $response->getHTMLResult()); + } +} diff --git a/test/classes/Controllers/Table/ExportRowsControllerTest.php b/test/classes/Controllers/Table/ExportRowsControllerTest.php new file mode 100644 index 0000000000..afb5c013b8 --- /dev/null +++ b/test/classes/Controllers/Table/ExportRowsControllerTest.php @@ -0,0 +1,96 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Controllers\Table\ExportController; +use PhpMyAdmin\Controllers\Table\ExportRowsController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\ExportRowsController + */ +class ExportRowsControllerTest extends AbstractTestCase +{ + protected function setUp(): void + { + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + $GLOBALS['server'] = 2; + $GLOBALS['active_page'] = null; + $GLOBALS['single_table'] = null; + $GLOBALS['where_clause'] = null; + $_POST = []; + } + + public function testExportRowsController(): void + { + $_POST['rows_to_delete'] = 'row'; + + $controller = $this->createMock(ExportController::class); + $controller->expects($this->once())->method('__invoke'); + + (new ExportRowsController( + new ResponseRenderer(), + new Template(), + $controller + ))($this->createStub(ServerRequest::class)); + + /** @psalm-suppress InvalidArrayOffset */ + $this->assertSame('index.php?route=/table/export&server=2&lang=en', $GLOBALS['active_page']); + /** @psalm-suppress InvalidArrayOffset */ + $this->assertTrue($GLOBALS['single_table']); + /** @psalm-suppress InvalidArrayOffset */ + $this->assertSame([], $GLOBALS['where_clause']); + } + + public function testWithoutRowsToDelete(): void + { + $_POST['goto'] = 'goto'; + + $controller = $this->createMock(ExportController::class); + $controller->expects($this->never())->method('__invoke'); + + $response = new ResponseRenderer(); + (new ExportRowsController( + $response, + new Template(), + $controller + ))($this->createStub(ServerRequest::class)); + + $this->assertSame(['message' => 'No row selected.'], $response->getJSONResult()); + $this->assertFalse($response->hasSuccessState()); + /** @psalm-suppress InvalidArrayOffset */ + $this->assertNull($GLOBALS['active_page']); + /** @psalm-suppress InvalidArrayOffset */ + $this->assertNull($GLOBALS['single_table']); + /** @psalm-suppress InvalidArrayOffset */ + $this->assertNull($GLOBALS['where_clause']); + } + + public function testWithRowsToDelete(): void + { + $_POST['goto'] = 'goto'; + $_POST['rows_to_delete'] = ['key1' => 'row1', 'key2' => 'row2']; + + $controller = $this->createMock(ExportController::class); + $controller->expects($this->once())->method('__invoke'); + + (new ExportRowsController( + new ResponseRenderer(), + new Template(), + $controller + ))($this->createStub(ServerRequest::class)); + + /** @psalm-suppress InvalidArrayOffset */ + $this->assertSame('index.php?route=/table/export&server=2&lang=en', $GLOBALS['active_page']); + /** @psalm-suppress InvalidArrayOffset */ + $this->assertTrue($GLOBALS['single_table']); + /** @psalm-suppress InvalidArrayOffset */ + $this->assertSame(['row1', 'row2'], $GLOBALS['where_clause']); + } +} diff --git a/test/classes/Controllers/Table/FindReplaceControllerTest.php b/test/classes/Controllers/Table/FindReplaceControllerTest.php index 8f9ff0bc47..d37c1bc476 100644 --- a/test/classes/Controllers/Table/FindReplaceControllerTest.php +++ b/test/classes/Controllers/Table/FindReplaceControllerTest.php @@ -75,8 +75,6 @@ class FindReplaceControllerTest extends AbstractTestCase $tableSearch = new FindReplaceController( ResponseRenderer::getInstance(), new Template(), - $GLOBALS['db'], - $GLOBALS['table'], $GLOBALS['dbi'] ); $columnIndex = 0; @@ -95,13 +93,7 @@ class FindReplaceControllerTest extends AbstractTestCase public function testReplaceWithRegex(): void { - $tableSearch = new FindReplaceController( - ResponseRenderer::getInstance(), - new Template(), - $GLOBALS['db'], - $GLOBALS['table'], - $GLOBALS['dbi'] - ); + $tableSearch = new FindReplaceController(ResponseRenderer::getInstance(), new Template(), $GLOBALS['dbi']); $columnIndex = 0; $find = 'Field'; diff --git a/test/classes/Controllers/Table/GetFieldControllerTest.php b/test/classes/Controllers/Table/GetFieldControllerTest.php new file mode 100644 index 0000000000..8bb97a9522 --- /dev/null +++ b/test/classes/Controllers/Table/GetFieldControllerTest.php @@ -0,0 +1,60 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Controllers\Table\GetFieldController; +use PhpMyAdmin\Core; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +use function bin2hex; + +/** + * @covers \PhpMyAdmin\Controllers\Table\GetFieldController + */ +class GetFieldControllerTest extends AbstractTestCase +{ + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testGetFieldController(): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'table_with_blob'; + $_GET['transform_key'] = 'file'; + $_GET['sql_query'] = 'SELECT * FROM `test_db`.`table_with_blob`'; + $_GET['where_clause'] = '`table_with_blob`.`id` = 1'; + $_GET['where_clause_sign'] = Core::signSqlQuery('`table_with_blob`.`id` = 1'); + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addSelectDb('test_db'); + $dummyDbi->addResult( + 'SHOW COLUMNS FROM `test_db`.`table_with_blob`', + [ + ['id', 'int(11)', 'NO', 'PRI', null, 'auto_increment'], + ['file', 'blob', 'NO', '', null, ''], + ], + ['Field', 'Type', 'Null', 'Key', 'Default', 'Extra'] + ); + $dummyDbi->addResult( + 'SHOW INDEXES FROM `test_db`.`table_with_blob`', + [['table_with_blob', 'PRIMARY', 'id']], + ['Table', 'Key_name', 'Column_name'] + ); + $dummyDbi->addResult( + 'SELECT `file` FROM `table_with_blob` WHERE `table_with_blob`.`id` = 1;', + [[bin2hex('FILE')]], + ['file'] + ); + $dbi = $this->createDatabaseInterface($dummyDbi); + $GLOBALS['dbi'] = $dbi; + + (new GetFieldController(new ResponseRenderer(), new Template(), $dbi))($this->createStub(ServerRequest::class)); + $this->expectOutputString('46494c45'); + } +} diff --git a/test/classes/Controllers/Table/GisVisualizationControllerTest.php b/test/classes/Controllers/Table/GisVisualizationControllerTest.php new file mode 100644 index 0000000000..fd93494a86 --- /dev/null +++ b/test/classes/Controllers/Table/GisVisualizationControllerTest.php @@ -0,0 +1,117 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Controllers\Table\GisVisualizationController; +use PhpMyAdmin\Core; +use PhpMyAdmin\FieldMetadata; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Url; + +use function array_merge; + +use const MYSQLI_TYPE_GEOMETRY; +use const MYSQLI_TYPE_VAR_STRING; + +/** + * @covers \PhpMyAdmin\Controllers\Table\GisVisualizationController + */ +class GisVisualizationControllerTest extends AbstractTestCase +{ + public function testGisVisualizationController(): void + { + $GLOBALS['server'] = 2; + $GLOBALS['lang'] = 'en'; + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $_GET['sql_query'] = null; + $_POST['sql_query'] = 'SELECT * FROM `gis_all`'; + $_POST['pos'] = 0; + $_REQUEST['pos'] = 0; + $_REQUEST['unlim_num_rows'] = null; + $_SESSION['tmpval'] = []; + $_SESSION['tmpval']['max_rows'] = 'all'; + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addSelectDb('test_db'); + $dummyDbi->addResult( + 'SELECT * FROM `gis_all`', + [['POINT', 'POINT(100 250)']], + ['name', 'shape'], + [ + new FieldMetadata(MYSQLI_TYPE_VAR_STRING, 0, (object) []), + new FieldMetadata(MYSQLI_TYPE_GEOMETRY, 0, (object) []), + ] + ); + $dummyDbi->addResult( + 'SELECT ST_ASTEXT(`shape`) AS `shape`, ST_SRID(`shape`) AS `srid`' + . ' FROM (SELECT * FROM `gis_all`) AS `temp_gis` LIMIT 0, 25', + [['POINT(100 250)', '0']], + ['shape', 'srid'] + ); + $dbi = $this->createDatabaseInterface($dummyDbi); + $GLOBALS['dbi'] = $dbi; + + $params = [ + 'goto' => 'index.php?route=/database/structure&server=2&lang=en', + 'back' => 'index.php?route=/sql&server=2&lang=en', + 'sql_query' => 'SELECT * FROM `gis_all`', + 'sql_signature' => Core::signSqlQuery('SELECT * FROM `gis_all`'), + ]; + $downloadUrl = Url::getFromRoute('/table/gis-visualization', array_merge($params, [ + 'saveToFile' => true, + 'session_max_rows' => 25, + 'pos' => 0, + 'visualizationSettings[spatialColumn]' => 'shape', + 'visualizationSettings[labelColumn]' => '', + ])); + + $template = new Template(); + $expected = $template->render('table/gis_visualization/gis_visualization', [ + 'url_params' => $params, + 'download_url' => $downloadUrl, + 'label_candidates' => ['name'], + 'spatial_candidates' => ['shape'], + 'visualization_settings' => [ + 'spatialColumn' => 'shape', + 'labelColumn' => '', + 'width' => '600', + 'height' => '450', + ], + 'start_and_number_of_rows_fieldset' => [ + 'pos' => 0, + 'unlim_num_rows' => 0, + 'rows' => 25, + 'sql_query' => 'SELECT * FROM `gis_all`', + ], + 'visualization' => '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . "\n" + . '<svg version="1.1" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"' + . ' width="600" height="450"><g id="groupPanel"><circle cx="15" cy="240" r="3" name=""' + . ' id="1234567890" class="point vector" fill="white" stroke="#B02EE0" stroke-width="2"/></g></svg>', + 'draw_ol' => 'function drawOpenLayers() {if (typeof ol !== "undefined") {var olCss =' + . ' "js/vendor/openlayers/theme/ol.css";$(\'head\').append(\'<link rel="stylesheet" type="text/css"' + . ' href=\'+olCss+\'>\');var vectorLayer = new ol.source.Vector({});var map = new ol.Map({target:' + . ' \'openlayersmap\',layers: [new ol.layer.Tile({source: new ol.source.OSM()}),new ol.layer.' + . 'Vector({source: vectorLayer})],view: new ol.View({center: ol.proj.fromLonLat([37.41, 8.82]),' + . 'zoom: 4}),controls: [new ol.control.MousePosition({coordinateFormat: ol.coordinate.' + . 'createStringXY(4),projection: \'EPSG:4326\'}),new ol.control.Zoom,new ol.control.Attribution' + . ']});var fill = new ol.style.Fill({"color":"white"});var stroke = new ol.style.Stroke({"color"' + . ':[176,46,224],"width":2});var style = new ol.style.Style({image: new ol.style.Circle({fill:' + . ' fill,stroke: stroke,radius: 3}),fill: fill,stroke: stroke});var minLoc = [100, 250];var' + . ' maxLoc = [100, 250];var ext = ol.extent.boundingExtent([minLoc, maxLoc]);ext = ol.proj.' + . 'transformExtent(ext, ol.proj.get("EPSG:4326"), ol.proj.get(\'EPSG:3857\'));map.getView().' + . 'fit(ext, map.getSize());var point = new ol.Feature({geometry: (new ol.geom.Point([100,250]).' + . 'transform(ol.proj.get("EPSG:4326"), ol.proj.get(\'EPSG:3857\')))});point.setStyle(style);' + . 'vectorLayer.addFeature(point);return map;}return undefined;}', + ]); + + $response = new ResponseRenderer(); + (new GisVisualizationController($response, $template, $dbi))($this->createStub(ServerRequest::class)); + $this->assertSame($expected, $response->getHTMLResult()); + } +} diff --git a/test/classes/Controllers/Table/ImportControllerTest.php b/test/classes/Controllers/Table/ImportControllerTest.php new file mode 100644 index 0000000000..73820aa617 --- /dev/null +++ b/test/classes/Controllers/Table/ImportControllerTest.php @@ -0,0 +1,87 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Charsets; +use PhpMyAdmin\Config\PageSettings; +use PhpMyAdmin\Controllers\Table\ImportController; +use PhpMyAdmin\Encoding; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Plugins; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\ImportController + */ +class ImportControllerTest extends AbstractTestCase +{ + public function testImportController(): void + { + $this->setTheme(); + $GLOBALS['server'] = 2; + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $GLOBALS['text_dir'] = 'ltr'; + $GLOBALS['lang'] = 'en'; + $GLOBALS['PMA_PHP_SELF'] = 'index.php'; + $GLOBALS['cfg']['Server'] = $GLOBALS['config']->defaultServer; + $_GET['format'] = 'xml'; + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addSelectDb('test_db'); + $dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + $dummyDbi->addResult('SELECT @@local_infile;', [['1']]); + $dbi = $this->createDatabaseInterface($dummyDbi); + $GLOBALS['dbi'] = $dbi; + + $importList = Plugins::getImport('table'); + $choice = Plugins::getChoice($importList, 'xml'); + $options = Plugins::getOptions('Import', $importList); + + $pageSettings = new PageSettings('Import'); + $template = new Template(); + $expected = $template->render('table/import/index', [ + 'page_settings_error_html' => $pageSettings->getErrorHTML(), + 'page_settings_html' => $pageSettings->getHTML(), + 'upload_id' => 'abc1234567890', + 'handler' => 'PhpMyAdmin\Plugins\Import\Upload\UploadNoplugin', + 'hidden_inputs' => [ + 'noplugin' => 'abc1234567890', + 'import_type' => 'table', + 'db' => 'test_db', + 'table' => 'test_table', + ], + 'db' => 'test_db', + 'table' => 'test_table', + 'max_upload_size' => 2097152, + 'formatted_maximum_upload_size' => '(Max: 2,048KiB)', + 'plugins_choice' => $choice, + 'options' => $options, + 'skip_queries_default' => '0', + 'is_allow_interrupt_checked' => ' checked="checked"', + 'local_import_file' => null, + 'is_upload' => true, + 'upload_dir' => '', + 'timeout_passed_global' => null, + 'compressions' => ['gzip', 'bzip2', 'zip'], + 'is_encoding_supported' => true, + 'encodings' => Encoding::listEncodings(), + 'import_charset' => '', + 'timeout_passed' => null, + 'offset' => null, + 'can_convert_kanji' => false, + 'charsets' => Charsets::getCharsets($dbi, false), + 'is_foreign_key_check' => true, + 'user_upload_dir' => '', + 'local_files' => '', + ]); + + $response = new ResponseRenderer(); + (new ImportController($response, $template, $dbi))($this->createStub(ServerRequest::class)); + $this->assertSame($expected, $response->getHTMLResult()); + } +} diff --git a/test/classes/Controllers/Table/IndexRenameControllerTest.php b/test/classes/Controllers/Table/IndexRenameControllerTest.php new file mode 100644 index 0000000000..6eea50b492 --- /dev/null +++ b/test/classes/Controllers/Table/IndexRenameControllerTest.php @@ -0,0 +1,51 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Controllers\Table\IndexRenameController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Index; +use PhpMyAdmin\Table\Indexes; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\IndexRenameController + */ +class IndexRenameControllerTest extends AbstractTestCase +{ + public function testIndexRenameController(): void + { + $GLOBALS['server'] = 2; + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $GLOBALS['text_dir'] = 'ltr'; + $GLOBALS['PMA_PHP_SELF'] = 'index.php'; + $GLOBALS['lang'] = 'en'; + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addSelectDb('test_db'); + $dummyDbi->addSelectDb('test_db'); + $dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + $dbi = $this->createDatabaseInterface($dummyDbi); + $GLOBALS['dbi'] = $dbi; + + $template = new Template(); + $expected = $template->render('table/index_rename_form', [ + 'index' => new Index(), + 'form_params' => ['db' => 'test_db', 'table' => 'test_table'], + ]); + + $response = new ResponseRenderer(); + (new IndexRenameController( + $response, + $template, + $dbi, + new Indexes($response, $template, $dbi) + ))($this->createStub(ServerRequest::class)); + $this->assertSame($expected, $response->getHTMLResult()); + } +} diff --git a/test/classes/Controllers/Table/IndexesControllerTest.php b/test/classes/Controllers/Table/IndexesControllerTest.php index 8cd1da9ffa..d099e1959d 100644 --- a/test/classes/Controllers/Table/IndexesControllerTest.php +++ b/test/classes/Controllers/Table/IndexesControllerTest.php @@ -107,8 +107,6 @@ class IndexesControllerTest extends AbstractTestCase $ctrl = new IndexesController( $response, $template, - $GLOBALS['db'], - $GLOBALS['table'], $GLOBALS['dbi'], new Indexes($response, $template, $GLOBALS['dbi']) ); diff --git a/test/classes/Controllers/Table/Maintenance/AnalyzeControllerTest.php b/test/classes/Controllers/Table/Maintenance/AnalyzeControllerTest.php new file mode 100644 index 0000000000..37f817404a --- /dev/null +++ b/test/classes/Controllers/Table/Maintenance/AnalyzeControllerTest.php @@ -0,0 +1,54 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table\Maintenance; + +use PhpMyAdmin\Config; +use PhpMyAdmin\Controllers\Table\Maintenance\AnalyzeController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Table\Maintenance; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\Maintenance\AnalyzeController + */ +class AnalyzeControllerTest extends AbstractTestCase +{ + /** + * @param string[][]|string[]|string|null $tables + * + * @dataProvider providerForTestNoTableSelected + */ + public function testNoTableSelected($tables): void + { + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturnMap([['selected_tbl', null, $tables]]); + $dbi = $this->createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $controller = new AnalyzeController($response, new Template(), new Maintenance($dbi), new Config()); + $controller($request); + $this->assertFalse($response->hasSuccessState()); + $this->assertSame(['message' => 'No table selected.'], $response->getJSONResult()); + $this->assertSame('', $response->getHTMLResult()); + } + + /** + * @return array<int, array{string[][]|string[]|string|null}> + */ + public function providerForTestNoTableSelected(): array + { + return [ + [null], + [''], + ['table'], + [[]], + [['']], + [['table', '']], + [[['table']]], + ]; + } +} diff --git a/test/classes/Controllers/Table/Maintenance/CheckControllerTest.php b/test/classes/Controllers/Table/Maintenance/CheckControllerTest.php new file mode 100644 index 0000000000..fd38a7db07 --- /dev/null +++ b/test/classes/Controllers/Table/Maintenance/CheckControllerTest.php @@ -0,0 +1,54 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table\Maintenance; + +use PhpMyAdmin\Config; +use PhpMyAdmin\Controllers\Table\Maintenance\CheckController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Table\Maintenance; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\Maintenance\CheckController + */ +class CheckControllerTest extends AbstractTestCase +{ + /** + * @param string[][]|string[]|string|null $tables + * + * @dataProvider providerForTestNoTableSelected + */ + public function testNoTableSelected($tables): void + { + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturnMap([['selected_tbl', null, $tables]]); + $dbi = $this->createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $controller = new CheckController($response, new Template(), new Maintenance($dbi), new Config()); + $controller($request); + $this->assertFalse($response->hasSuccessState()); + $this->assertSame(['message' => 'No table selected.'], $response->getJSONResult()); + $this->assertSame('', $response->getHTMLResult()); + } + + /** + * @return array<int, array{string[][]|string[]|string|null}> + */ + public function providerForTestNoTableSelected(): array + { + return [ + [null], + [''], + ['table'], + [[]], + [['']], + [['table', '']], + [[['table']]], + ]; + } +} diff --git a/test/classes/Controllers/Table/Maintenance/ChecksumControllerTest.php b/test/classes/Controllers/Table/Maintenance/ChecksumControllerTest.php new file mode 100644 index 0000000000..f779d179e2 --- /dev/null +++ b/test/classes/Controllers/Table/Maintenance/ChecksumControllerTest.php @@ -0,0 +1,54 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table\Maintenance; + +use PhpMyAdmin\Config; +use PhpMyAdmin\Controllers\Table\Maintenance\ChecksumController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Table\Maintenance; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\Maintenance\ChecksumController + */ +class ChecksumControllerTest extends AbstractTestCase +{ + /** + * @param string[][]|string[]|string|null $tables + * + * @dataProvider providerForTestNoTableSelected + */ + public function testNoTableSelected($tables): void + { + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturnMap([['selected_tbl', null, $tables]]); + $dbi = $this->createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $controller = new ChecksumController($response, new Template(), new Maintenance($dbi), new Config()); + $controller($request); + $this->assertFalse($response->hasSuccessState()); + $this->assertSame(['message' => 'No table selected.'], $response->getJSONResult()); + $this->assertSame('', $response->getHTMLResult()); + } + + /** + * @return array<int, array{string[][]|string[]|string|null}> + */ + public function providerForTestNoTableSelected(): array + { + return [ + [null], + [''], + ['table'], + [[]], + [['']], + [['table', '']], + [[['table']]], + ]; + } +} diff --git a/test/classes/Controllers/Table/Maintenance/OptimizeControllerTest.php b/test/classes/Controllers/Table/Maintenance/OptimizeControllerTest.php new file mode 100644 index 0000000000..09eb4473f9 --- /dev/null +++ b/test/classes/Controllers/Table/Maintenance/OptimizeControllerTest.php @@ -0,0 +1,54 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table\Maintenance; + +use PhpMyAdmin\Config; +use PhpMyAdmin\Controllers\Table\Maintenance\OptimizeController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Table\Maintenance; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\Maintenance\OptimizeController + */ +class OptimizeControllerTest extends AbstractTestCase +{ + /** + * @param string[][]|string[]|string|null $tables + * + * @dataProvider providerForTestNoTableSelected + */ + public function testNoTableSelected($tables): void + { + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturnMap([['selected_tbl', null, $tables]]); + $dbi = $this->createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $controller = new OptimizeController($response, new Template(), new Maintenance($dbi), new Config()); + $controller($request); + $this->assertFalse($response->hasSuccessState()); + $this->assertSame(['message' => 'No table selected.'], $response->getJSONResult()); + $this->assertSame('', $response->getHTMLResult()); + } + + /** + * @return array<int, array{string[][]|string[]|string|null}> + */ + public function providerForTestNoTableSelected(): array + { + return [ + [null], + [''], + ['table'], + [[]], + [['']], + [['table', '']], + [[['table']]], + ]; + } +} diff --git a/test/classes/Controllers/Table/Maintenance/RepairControllerTest.php b/test/classes/Controllers/Table/Maintenance/RepairControllerTest.php new file mode 100644 index 0000000000..7ed1a0a3d4 --- /dev/null +++ b/test/classes/Controllers/Table/Maintenance/RepairControllerTest.php @@ -0,0 +1,54 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table\Maintenance; + +use PhpMyAdmin\Config; +use PhpMyAdmin\Controllers\Table\Maintenance\RepairController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Table\Maintenance; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\Maintenance\RepairController + */ +class RepairControllerTest extends AbstractTestCase +{ + /** + * @param string[][]|string[]|string|null $tables + * + * @dataProvider providerForTestNoTableSelected + */ + public function testNoTableSelected($tables): void + { + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturnMap([['selected_tbl', null, $tables]]); + $dbi = $this->createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $controller = new RepairController($response, new Template(), new Maintenance($dbi), new Config()); + $controller($request); + $this->assertFalse($response->hasSuccessState()); + $this->assertSame(['message' => 'No table selected.'], $response->getJSONResult()); + $this->assertSame('', $response->getHTMLResult()); + } + + /** + * @return array<int, array{string[][]|string[]|string|null}> + */ + public function providerForTestNoTableSelected(): array + { + return [ + [null], + [''], + ['table'], + [[]], + [['']], + [['table', '']], + [[['table']]], + ]; + } +} diff --git a/test/classes/Controllers/Table/OperationsControllerTest.php b/test/classes/Controllers/Table/OperationsControllerTest.php index 2116a642ec..59bd2ed6b0 100644 --- a/test/classes/Controllers/Table/OperationsControllerTest.php +++ b/test/classes/Controllers/Table/OperationsControllerTest.php @@ -6,19 +6,34 @@ namespace PhpMyAdmin\Tests\Controllers\Table; use PhpMyAdmin\Charsets; use PhpMyAdmin\Controllers\Table\OperationsController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\StorageEngine; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; /** * @covers \PhpMyAdmin\Controllers\Table\OperationsController */ class OperationsControllerTest extends AbstractTestCase { - public function testOperationsController(): void + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void { - global $containerBuilder; + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + public function testOperationsController(): void + { $GLOBALS['server'] = 1; $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['lang'] = 'en'; @@ -34,8 +49,8 @@ class OperationsControllerTest extends AbstractTestCase $this->loadDbiIntoContainerBuilder(); $this->loadResponseIntoContainerBuilder(); - $containerBuilder->setParameter('db', 'test_db'); - $containerBuilder->setParameter('table', 'test_table'); + $GLOBALS['containerBuilder']->setParameter('db', 'test_db'); + $GLOBALS['containerBuilder']->setParameter('table', 'test_table'); $this->dummyDbi->addSelectDb('test_db'); $this->dummyDbi->addSelectDb('test_db'); @@ -103,8 +118,8 @@ class OperationsControllerTest extends AbstractTestCase ]); /** @var OperationsController $controller */ - $controller = $containerBuilder->get(OperationsController::class); - $controller(); + $controller = $GLOBALS['containerBuilder']->get(OperationsController::class); + $controller($this->createStub(ServerRequest::class)); $this->assertEquals($expectedOutput, $this->getResponseHtmlResult()); } diff --git a/test/classes/Controllers/Table/Partition/AnalyzeControllerTest.php b/test/classes/Controllers/Table/Partition/AnalyzeControllerTest.php new file mode 100644 index 0000000000..46eb3bbb63 --- /dev/null +++ b/test/classes/Controllers/Table/Partition/AnalyzeControllerTest.php @@ -0,0 +1,52 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table\Partition; + +use PhpMyAdmin\Controllers\Table\Partition\AnalyzeController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Message; +use PhpMyAdmin\Partitioning\Maintenance; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\Partition\AnalyzeController + */ +class AnalyzeControllerTest extends AbstractTestCase +{ + /** + * @dataProvider providerForTestInvalidDatabaseAndTable + */ + public function testInvalidDatabaseAndTable(?string $partition, ?string $db, ?string $table, string $message): void + { + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturnMap([['partition_name', null, $partition]]); + $request->method('getParam')->willReturnMap([['db', null, $db], ['table', null, $table]]); + $dbi = $this->createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + + $controller = new AnalyzeController($response, new Template(), new Maintenance($dbi)); + $controller($request); + + $this->assertSame(Message::error($message)->getDisplay(), $response->getHTMLResult()); + } + + /** + * @return array<int, array{string|null, string|null, string|null, non-empty-string}> + */ + public function providerForTestInvalidDatabaseAndTable(): iterable + { + return [ + [null, null, null, 'The partition name must be a non-empty string.'], + ['', null, null, 'The partition name must be a non-empty string.'], + ['partitionName', null, null, 'The database name must be a non-empty string.'], + ['partitionName', '', null, 'The database name must be a non-empty string.'], + ['partitionName', 'databaseName', null, 'The table name must be a non-empty string.'], + ['partitionName', 'databaseName', '', 'The table name must be a non-empty string.'], + ]; + } +} diff --git a/test/classes/Controllers/Table/Partition/CheckControllerTest.php b/test/classes/Controllers/Table/Partition/CheckControllerTest.php new file mode 100644 index 0000000000..c2e0d4699d --- /dev/null +++ b/test/classes/Controllers/Table/Partition/CheckControllerTest.php @@ -0,0 +1,52 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table\Partition; + +use PhpMyAdmin\Controllers\Table\Partition\CheckController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Message; +use PhpMyAdmin\Partitioning\Maintenance; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\Partition\CheckController + */ +class CheckControllerTest extends AbstractTestCase +{ + /** + * @dataProvider providerForTestInvalidDatabaseAndTable + */ + public function testInvalidDatabaseAndTable(?string $partition, ?string $db, ?string $table, string $message): void + { + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturnMap([['partition_name', null, $partition]]); + $request->method('getParam')->willReturnMap([['db', null, $db], ['table', null, $table]]); + $dbi = $this->createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + + $controller = new CheckController($response, new Template(), new Maintenance($dbi)); + $controller($request); + + $this->assertSame(Message::error($message)->getDisplay(), $response->getHTMLResult()); + } + + /** + * @return array<int, array{string|null, string|null, string|null, non-empty-string}> + */ + public function providerForTestInvalidDatabaseAndTable(): iterable + { + return [ + [null, null, null, 'The partition name must be a non-empty string.'], + ['', null, null, 'The partition name must be a non-empty string.'], + ['partitionName', null, null, 'The database name must be a non-empty string.'], + ['partitionName', '', null, 'The database name must be a non-empty string.'], + ['partitionName', 'databaseName', null, 'The table name must be a non-empty string.'], + ['partitionName', 'databaseName', '', 'The table name must be a non-empty string.'], + ]; + } +} diff --git a/test/classes/Controllers/Table/Partition/DropControllerTest.php b/test/classes/Controllers/Table/Partition/DropControllerTest.php new file mode 100644 index 0000000000..45d4107c8e --- /dev/null +++ b/test/classes/Controllers/Table/Partition/DropControllerTest.php @@ -0,0 +1,52 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table\Partition; + +use PhpMyAdmin\Controllers\Table\Partition\DropController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Message; +use PhpMyAdmin\Partitioning\Maintenance; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\Partition\DropController + */ +class DropControllerTest extends AbstractTestCase +{ + /** + * @dataProvider providerForTestInvalidDatabaseAndTable + */ + public function testInvalidDatabaseAndTable(?string $partition, ?string $db, ?string $table, string $message): void + { + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturnMap([['partition_name', null, $partition]]); + $request->method('getParam')->willReturnMap([['db', null, $db], ['table', null, $table]]); + $dbi = $this->createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + + $controller = new DropController($response, new Template(), new Maintenance($dbi)); + $controller($request); + + $this->assertSame(Message::error($message)->getDisplay(), $response->getHTMLResult()); + } + + /** + * @return array<int, array{string|null, string|null, string|null, non-empty-string}> + */ + public function providerForTestInvalidDatabaseAndTable(): iterable + { + return [ + [null, null, null, 'The partition name must be a non-empty string.'], + ['', null, null, 'The partition name must be a non-empty string.'], + ['partitionName', null, null, 'The database name must be a non-empty string.'], + ['partitionName', '', null, 'The database name must be a non-empty string.'], + ['partitionName', 'databaseName', null, 'The table name must be a non-empty string.'], + ['partitionName', 'databaseName', '', 'The table name must be a non-empty string.'], + ]; + } +} diff --git a/test/classes/Controllers/Table/Partition/OptimizeControllerTest.php b/test/classes/Controllers/Table/Partition/OptimizeControllerTest.php new file mode 100644 index 0000000000..67be53c1d2 --- /dev/null +++ b/test/classes/Controllers/Table/Partition/OptimizeControllerTest.php @@ -0,0 +1,52 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table\Partition; + +use PhpMyAdmin\Controllers\Table\Partition\OptimizeController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Message; +use PhpMyAdmin\Partitioning\Maintenance; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\Partition\OptimizeController + */ +class OptimizeControllerTest extends AbstractTestCase +{ + /** + * @dataProvider providerForTestInvalidDatabaseAndTable + */ + public function testInvalidDatabaseAndTable(?string $partition, ?string $db, ?string $table, string $message): void + { + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturnMap([['partition_name', null, $partition]]); + $request->method('getParam')->willReturnMap([['db', null, $db], ['table', null, $table]]); + $dbi = $this->createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + + $controller = new OptimizeController($response, new Template(), new Maintenance($dbi)); + $controller($request); + + $this->assertSame(Message::error($message)->getDisplay(), $response->getHTMLResult()); + } + + /** + * @return array<int, array{string|null, string|null, string|null, non-empty-string}> + */ + public function providerForTestInvalidDatabaseAndTable(): iterable + { + return [ + [null, null, null, 'The partition name must be a non-empty string.'], + ['', null, null, 'The partition name must be a non-empty string.'], + ['partitionName', null, null, 'The database name must be a non-empty string.'], + ['partitionName', '', null, 'The database name must be a non-empty string.'], + ['partitionName', 'databaseName', null, 'The table name must be a non-empty string.'], + ['partitionName', 'databaseName', '', 'The table name must be a non-empty string.'], + ]; + } +} diff --git a/test/classes/Controllers/Table/Partition/RebuildControllerTest.php b/test/classes/Controllers/Table/Partition/RebuildControllerTest.php new file mode 100644 index 0000000000..f56fdad93d --- /dev/null +++ b/test/classes/Controllers/Table/Partition/RebuildControllerTest.php @@ -0,0 +1,52 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table\Partition; + +use PhpMyAdmin\Controllers\Table\Partition\RebuildController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Message; +use PhpMyAdmin\Partitioning\Maintenance; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\Partition\RebuildController + */ +class RebuildControllerTest extends AbstractTestCase +{ + /** + * @dataProvider providerForTestInvalidDatabaseAndTable + */ + public function testInvalidDatabaseAndTable(?string $partition, ?string $db, ?string $table, string $message): void + { + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturnMap([['partition_name', null, $partition]]); + $request->method('getParam')->willReturnMap([['db', null, $db], ['table', null, $table]]); + $dbi = $this->createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + + $controller = new RebuildController($response, new Template(), new Maintenance($dbi)); + $controller($request); + + $this->assertSame(Message::error($message)->getDisplay(), $response->getHTMLResult()); + } + + /** + * @return array<int, array{string|null, string|null, string|null, non-empty-string}> + */ + public function providerForTestInvalidDatabaseAndTable(): iterable + { + return [ + [null, null, null, 'The partition name must be a non-empty string.'], + ['', null, null, 'The partition name must be a non-empty string.'], + ['partitionName', null, null, 'The database name must be a non-empty string.'], + ['partitionName', '', null, 'The database name must be a non-empty string.'], + ['partitionName', 'databaseName', null, 'The table name must be a non-empty string.'], + ['partitionName', 'databaseName', '', 'The table name must be a non-empty string.'], + ]; + } +} diff --git a/test/classes/Controllers/Table/Partition/RepairControllerTest.php b/test/classes/Controllers/Table/Partition/RepairControllerTest.php new file mode 100644 index 0000000000..583b6c26b5 --- /dev/null +++ b/test/classes/Controllers/Table/Partition/RepairControllerTest.php @@ -0,0 +1,52 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table\Partition; + +use PhpMyAdmin\Controllers\Table\Partition\RepairController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Message; +use PhpMyAdmin\Partitioning\Maintenance; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\Partition\RepairController + */ +class RepairControllerTest extends AbstractTestCase +{ + /** + * @dataProvider providerForTestInvalidDatabaseAndTable + */ + public function testInvalidDatabaseAndTable(?string $partition, ?string $db, ?string $table, string $message): void + { + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturnMap([['partition_name', null, $partition]]); + $request->method('getParam')->willReturnMap([['db', null, $db], ['table', null, $table]]); + $dbi = $this->createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + + $controller = new RepairController($response, new Template(), new Maintenance($dbi)); + $controller($request); + + $this->assertSame(Message::error($message)->getDisplay(), $response->getHTMLResult()); + } + + /** + * @return array<int, array{string|null, string|null, string|null, non-empty-string}> + */ + public function providerForTestInvalidDatabaseAndTable(): iterable + { + return [ + [null, null, null, 'The partition name must be a non-empty string.'], + ['', null, null, 'The partition name must be a non-empty string.'], + ['partitionName', null, null, 'The database name must be a non-empty string.'], + ['partitionName', '', null, 'The database name must be a non-empty string.'], + ['partitionName', 'databaseName', null, 'The table name must be a non-empty string.'], + ['partitionName', 'databaseName', '', 'The table name must be a non-empty string.'], + ]; + } +} diff --git a/test/classes/Controllers/Table/Partition/TruncateControllerTest.php b/test/classes/Controllers/Table/Partition/TruncateControllerTest.php new file mode 100644 index 0000000000..7ba59de054 --- /dev/null +++ b/test/classes/Controllers/Table/Partition/TruncateControllerTest.php @@ -0,0 +1,52 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table\Partition; + +use PhpMyAdmin\Controllers\Table\Partition\TruncateController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Message; +use PhpMyAdmin\Partitioning\Maintenance; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\Partition\TruncateController + */ +class TruncateControllerTest extends AbstractTestCase +{ + /** + * @dataProvider providerForTestInvalidDatabaseAndTable + */ + public function testInvalidDatabaseAndTable(?string $partition, ?string $db, ?string $table, string $message): void + { + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturnMap([['partition_name', null, $partition]]); + $request->method('getParam')->willReturnMap([['db', null, $db], ['table', null, $table]]); + $dbi = $this->createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + + $controller = new TruncateController($response, new Template(), new Maintenance($dbi)); + $controller($request); + + $this->assertSame(Message::error($message)->getDisplay(), $response->getHTMLResult()); + } + + /** + * @return array<int, array{string|null, string|null, string|null, non-empty-string}> + */ + public function providerForTestInvalidDatabaseAndTable(): iterable + { + return [ + [null, null, null, 'The partition name must be a non-empty string.'], + ['', null, null, 'The partition name must be a non-empty string.'], + ['partitionName', null, null, 'The database name must be a non-empty string.'], + ['partitionName', '', null, 'The database name must be a non-empty string.'], + ['partitionName', 'databaseName', null, 'The table name must be a non-empty string.'], + ['partitionName', 'databaseName', '', 'The table name must be a non-empty string.'], + ]; + } +} diff --git a/test/classes/Controllers/Table/PrivilegesControllerTest.php b/test/classes/Controllers/Table/PrivilegesControllerTest.php index 7ca7df94d3..5490ad8cc6 100644 --- a/test/classes/Controllers/Table/PrivilegesControllerTest.php +++ b/test/classes/Controllers/Table/PrivilegesControllerTest.php @@ -5,10 +5,11 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Table; use PhpMyAdmin\Controllers\Table\PrivilegesController; -use PhpMyAdmin\ResponseRenderer; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Server\Privileges; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; use PhpMyAdmin\Url; use function __; @@ -27,17 +28,16 @@ class PrivilegesControllerTest extends AbstractTestCase parent::setUp(); parent::setLanguage(); parent::setTheme(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); } public function testIndex(): void { - global $dbi, $db, $table, $server, $cfg, $PMA_PHP_SELF; - - $db = 'db'; - $table = 'table'; - $server = 0; - $cfg['Server']['DisableIS'] = false; - $PMA_PHP_SELF = 'index.php'; + $GLOBALS['db'] = 'db'; + $GLOBALS['table'] = 'table'; + $GLOBALS['server'] = 0; + $GLOBALS['cfg']['Server']['DisableIS'] = false; + $GLOBALS['PMA_PHP_SELF'] = 'index.php'; $privileges = []; @@ -45,21 +45,21 @@ class PrivilegesControllerTest extends AbstractTestCase $serverPrivileges->method('getAllPrivileges') ->willReturn($privileges); - $actual = (new PrivilegesController( - ResponseRenderer::getInstance(), + $response = new ResponseRenderer(); + (new PrivilegesController( + $response, new Template(), - $db, - $table, $serverPrivileges, - $dbi - ))(['checkprivsdb' => $db, 'checkprivstable' => $table]); + $GLOBALS['dbi'] + ))($this->createStub(ServerRequest::class)); + $actual = $response->getHTMLResult(); - $this->assertStringContainsString($db . '.' . $table, $actual); + $this->assertStringContainsString($GLOBALS['db'] . '.' . $GLOBALS['table'], $actual); //validate 2: Url::getCommon $item = Url::getCommon([ - 'db' => $db, - 'table' => $table, + 'db' => $GLOBALS['db'], + 'table' => $GLOBALS['table'], ], ''); $this->assertStringContainsString($item, $actual); @@ -98,12 +98,5 @@ class PrivilegesControllerTest extends AbstractTestCase _pgettext('Create new user', 'New'), $actual ); - $this->assertStringContainsString( - Url::getCommon([ - 'checkprivsdb' => $db, - 'checkprivstable' => $table, - ]), - $actual - ); } } diff --git a/test/classes/Controllers/Table/RecentFavoriteControllerTest.php b/test/classes/Controllers/Table/RecentFavoriteControllerTest.php new file mode 100644 index 0000000000..b5790cae31 --- /dev/null +++ b/test/classes/Controllers/Table/RecentFavoriteControllerTest.php @@ -0,0 +1,105 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Controllers\Sql\SqlController; +use PhpMyAdmin\Controllers\Table\RecentFavoriteController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\RecentFavoriteTable; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use Psr\Container\ContainerInterface; + +/** + * @covers \PhpMyAdmin\Controllers\Table\RecentFavoriteController + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled + */ +class RecentFavoriteControllerTest extends AbstractTestCase +{ + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void + { + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + + public function testRecentFavoriteControllerWithValidDbAndTable(): void + { + $GLOBALS['server'] = 2; + $GLOBALS['text_dir'] = 'ltr'; + $GLOBALS['PMA_PHP_SELF'] = 'index.php'; + $_REQUEST['db'] = 'test_db'; + $_REQUEST['table'] = 'test_table'; + $_SESSION['relation'] = []; + + $_SESSION['tmpval'] = []; + $_SESSION['tmpval']['recentTables'][2] = [['db' => 'test_db', 'table' => 'test_table']]; + $_SESSION['tmpval']['favoriteTables'][2] = [['db' => 'test_db', 'table' => 'test_table']]; + + $controller = $this->createMock(SqlController::class); + $controller->expects($this->once())->method('__invoke'); + + $container = $this->createMock(ContainerInterface::class); + $container->expects($this->once())->method('get')->with(SqlController::class)->willReturn($controller); + $GLOBALS['containerBuilder'] = $container; + + $recent = RecentFavoriteTable::getInstance('recent'); + $favorite = RecentFavoriteTable::getInstance('favorite'); + + $this->assertSame([['db' => 'test_db', 'table' => 'test_table']], $recent->getTables()); + $this->assertSame([['db' => 'test_db', 'table' => 'test_table']], $favorite->getTables()); + + (new RecentFavoriteController(new ResponseRenderer(), new Template()))($this->createStub(ServerRequest::class)); + + $this->assertSame([['db' => 'test_db', 'table' => 'test_table']], $recent->getTables()); + $this->assertSame([['db' => 'test_db', 'table' => 'test_table']], $favorite->getTables()); + } + + public function testRecentFavoriteControllerWithInvalidDbAndTable(): void + { + $GLOBALS['server'] = 2; + $GLOBALS['text_dir'] = 'ltr'; + $GLOBALS['PMA_PHP_SELF'] = 'index.php'; + $_REQUEST['db'] = 'invalid_db'; + $_REQUEST['table'] = 'invalid_table'; + $_SESSION['relation'] = []; + + $_SESSION['tmpval'] = []; + $_SESSION['tmpval']['recentTables'][2] = [['db' => 'invalid_db', 'table' => 'invalid_table']]; + $_SESSION['tmpval']['favoriteTables'][2] = [['db' => 'invalid_db', 'table' => 'invalid_table']]; + + $this->dummyDbi->addResult('SHOW COLUMNS FROM `invalid_db`.`invalid_table`', false); + $this->dummyDbi->addResult('SHOW COLUMNS FROM `invalid_db`.`invalid_table`', false); + + $controller = $this->createMock(SqlController::class); + $controller->expects($this->once())->method('__invoke'); + + $container = $this->createMock(ContainerInterface::class); + $container->expects($this->once())->method('get')->with(SqlController::class)->willReturn($controller); + $GLOBALS['containerBuilder'] = $container; + + $recent = RecentFavoriteTable::getInstance('recent'); + $favorite = RecentFavoriteTable::getInstance('favorite'); + + $this->assertSame([['db' => 'invalid_db', 'table' => 'invalid_table']], $recent->getTables()); + $this->assertSame([['db' => 'invalid_db', 'table' => 'invalid_table']], $favorite->getTables()); + + (new RecentFavoriteController(new ResponseRenderer(), new Template()))($this->createStub(ServerRequest::class)); + + $this->assertSame([], $recent->getTables()); + $this->assertSame([], $favorite->getTables()); + } +} diff --git a/test/classes/Controllers/Table/RelationControllerTest.php b/test/classes/Controllers/Table/RelationControllerTest.php index f7e217e0ea..179af36f60 100644 --- a/test/classes/Controllers/Table/RelationControllerTest.php +++ b/test/classes/Controllers/Table/RelationControllerTest.php @@ -95,8 +95,6 @@ class RelationControllerTest extends AbstractTestCase $ctrl = new RelationController( $this->response, $this->template, - $GLOBALS['db'], - $GLOBALS['table'], new Relation($GLOBALS['dbi']), $GLOBALS['dbi'] ); @@ -130,8 +128,6 @@ class RelationControllerTest extends AbstractTestCase $ctrl = new RelationController( $this->response, $this->template, - $GLOBALS['db'], - $GLOBALS['table'], new Relation($GLOBALS['dbi']), $GLOBALS['dbi'] ); @@ -168,8 +164,6 @@ class RelationControllerTest extends AbstractTestCase $ctrl = new RelationController( $this->response, $this->template, - $GLOBALS['db'], - $GLOBALS['table'], new Relation($GLOBALS['dbi']), $GLOBALS['dbi'] ); @@ -203,8 +197,6 @@ class RelationControllerTest extends AbstractTestCase $ctrl = new RelationController( $this->response, $this->template, - $GLOBALS['db'], - $GLOBALS['table'], new Relation($GLOBALS['dbi']), $GLOBALS['dbi'] ); diff --git a/test/classes/Controllers/Table/ReplaceControllerTest.php b/test/classes/Controllers/Table/ReplaceControllerTest.php index fac53e765f..101a5266bb 100644 --- a/test/classes/Controllers/Table/ReplaceControllerTest.php +++ b/test/classes/Controllers/Table/ReplaceControllerTest.php @@ -4,27 +4,46 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Table; +use PhpMyAdmin\CheckUserPrivileges; +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\ConfigStorage\RelationCleanup; use PhpMyAdmin\ConfigStorage\RelationParameters; +use PhpMyAdmin\Controllers\Sql\SqlController; +use PhpMyAdmin\Controllers\Table\ChangeController; use PhpMyAdmin\Controllers\Table\ReplaceController; -use PhpMyAdmin\ResponseRenderer; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\FileListing; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\InsertEdit; +use PhpMyAdmin\Operations; +use PhpMyAdmin\Sql; +use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; +use Psr\Container\ContainerInterface; /** * @covers \PhpMyAdmin\Controllers\Table\ReplaceController */ class ReplaceControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + protected function setUp(): void { parent::setUp(); - parent::setLanguage(); - parent::setTheme(); - parent::setGlobalDbi(); - parent::loadContainerBuilder(); - parent::loadDbiIntoContainerBuilder(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; + $GLOBALS['showtable'] = null; $GLOBALS['PMA_PHP_SELF'] = 'index.php'; - parent::loadResponseIntoContainerBuilder(); $GLOBALS['db'] = 'my_db'; $GLOBALS['table'] = 'test_tbl'; @@ -52,9 +71,7 @@ class ReplaceControllerTest extends AbstractTestCase public function testReplace(): void { - global $containerBuilder; $GLOBALS['urlParams'] = []; - ResponseRenderer::getInstance()->setAjax(true); $_POST['db'] = $GLOBALS['db']; $_POST['table'] = $GLOBALS['table']; $_POST['ajax_request'] = 'true'; @@ -88,28 +105,55 @@ class ReplaceControllerTest extends AbstractTestCase 1 => [], ], ]; + + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + $relation = new Relation($dbi); + $transformations = new Transformations(); + $template = new Template(); + $response = new ResponseRenderer(); + $replaceController = new ReplaceController( + $response, + $template, + new InsertEdit($dbi, $relation, $transformations, new FileListing(), $template), + $transformations, + $relation, + $dbi + ); + + $request = $this->createStub(ServerRequest::class); + $sqlController = new SqlController( + $response, + $template, + new Sql( + $dbi, + $relation, + new RelationCleanup($dbi, $relation), + new Operations($dbi, $relation), + $transformations, + $template + ), + new CheckUserPrivileges($dbi), + $dbi + ); + $GLOBALS['containerBuilder'] = $this->createStub(ContainerInterface::class); + $GLOBALS['containerBuilder']->method('get')->willReturn($sqlController); + $GLOBALS['goto'] = 'index.php?route=/sql'; - $containerBuilder->setParameter('db', $GLOBALS['db']); - $containerBuilder->setParameter('table', $GLOBALS['table']); - /** @var ReplaceController $replaceController */ - $replaceController = $containerBuilder->get(ReplaceController::class); - $this->dummyDbi->addSelectDb('my_db'); - $this->dummyDbi->addSelectDb('my_db'); - $replaceController(); - $this->assertAllSelectsConsumed(); + $dummyDbi->addSelectDb('my_db'); + $dummyDbi->addSelectDb('my_db'); + $replaceController($request); + $output = $response->getHTMLResult(); + $this->dummyDbi->assertAllSelectsConsumed(); $this->assertStringContainsString( 'class="icon ic_s_success"> Showing rows 0 - 1 (2 total, Query took', - $this->getResponseHtmlResult() - ); - $this->assertStringContainsString( - 'SELECT * FROM `test_tbl`', - $this->getResponseHtmlResult() + $output ); + $this->assertStringContainsString('SELECT * FROM `test_tbl`', $output); } public function testIsInsertRow(): void { - global $containerBuilder; $GLOBALS['urlParams'] = []; $GLOBALS['goto'] = 'index.php?route=/sql'; $_POST['insert_rows'] = 5; @@ -118,37 +162,47 @@ class ReplaceControllerTest extends AbstractTestCase $GLOBALS['cfg']['Server']['host'] = 'host.tld'; $GLOBALS['cfg']['Server']['verbose'] = ''; - $this->dummyDbi->addResult( - 'SHOW TABLES LIKE \'test_tbl\';', - [ - ['test_tbl'], - ] + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + $GLOBALS['dbi'] = $dbi; + $relation = new Relation($dbi); + $transformations = new Transformations(); + $template = new Template(); + $response = new ResponseRenderer(); + $insertEdit = new InsertEdit($dbi, $relation, $transformations, new FileListing(), $template); + $replaceController = new ReplaceController( + $response, + $template, + $insertEdit, + $transformations, + $relation, + $dbi ); - $this->dummyDbi->addResult( - 'SELECT * FROM `my_db`.`test_tbl` LIMIT 1;', - [] - ); + $request = $this->createStub(ServerRequest::class); + $changeController = new ChangeController($response, $template, $insertEdit, $relation); + $GLOBALS['containerBuilder'] = $this->createStub(ContainerInterface::class); + $GLOBALS['containerBuilder']->method('get')->willReturn($changeController); + + $dummyDbi->addSelectDb('my_db'); + $dummyDbi->addSelectDb('my_db'); + $dummyDbi->addResult('SHOW TABLES LIKE \'test_tbl\';', [['test_tbl']]); + $dummyDbi->addResult('SELECT * FROM `my_db`.`test_tbl` LIMIT 1;', []); + $dummyDbi->addSelectDb('my_db'); - $containerBuilder->setParameter('db', $GLOBALS['db']); - $containerBuilder->setParameter('table', $GLOBALS['table']); - /** @var ReplaceController $replaceController */ - $replaceController = $containerBuilder->get(ReplaceController::class); - $this->dummyDbi->addSelectDb('my_db'); - $this->dummyDbi->addSelectDb('my_db'); - $this->dummyDbi->addSelectDb('my_db'); - $replaceController(); - $this->assertAllSelectsConsumed(); + $replaceController($request); + $output = $response->getHTMLResult(); + $this->dummyDbi->assertAllSelectsConsumed(); $this->assertEquals(5, $GLOBALS['cfg']['InsertRows']); $this->assertStringContainsString( '<form id="continueForm" method="post" ' . 'action="index.php?route=/table/replace&lang=en" name="continueForm">', - $this->getResponseHtmlResult() + $output ); $this->assertStringContainsString( 'Continue insertion with <input type="number" ' . 'name="insert_rows" id="insert_rows" value="5" min="1">', - $this->getResponseHtmlResult() + $output ); } } diff --git a/test/classes/Controllers/Table/SearchControllerTest.php b/test/classes/Controllers/Table/SearchControllerTest.php index 64306193ff..3bcb1c794f 100644 --- a/test/classes/Controllers/Table/SearchControllerTest.php +++ b/test/classes/Controllers/Table/SearchControllerTest.php @@ -12,6 +12,7 @@ use PhpMyAdmin\FieldMetadata; use PhpMyAdmin\Table\Search; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer as ResponseStub; use PhpMyAdmin\Types; @@ -24,6 +25,12 @@ use const MYSQLI_TYPE_LONG; */ class SearchControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var ResponseStub */ private $response; @@ -37,6 +44,9 @@ class SearchControllerTest extends AbstractTestCase { parent::setUp(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; /** * SET these to avoid undefined index error @@ -111,8 +121,6 @@ class SearchControllerTest extends AbstractTestCase $ctrl = new SearchController( $this->response, $this->template, - $GLOBALS['db'], - $GLOBALS['table'], new Search($GLOBALS['dbi']), new Relation($GLOBALS['dbi']), $GLOBALS['dbi'] @@ -127,9 +135,9 @@ class SearchControllerTest extends AbstractTestCase */ public function testGetDataRowAction(): void { - global $containerBuilder; - - parent::setGlobalDbi(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; parent::loadDbiIntoContainerBuilder(); parent::loadResponseIntoContainerBuilder(); @@ -163,11 +171,11 @@ class SearchControllerTest extends AbstractTestCase ] ); - $containerBuilder->setParameter('db', 'PMA'); - $containerBuilder->setParameter('table', 'PMA_BookMark'); + $GLOBALS['containerBuilder']->setParameter('db', 'PMA'); + $GLOBALS['containerBuilder']->setParameter('table', 'PMA_BookMark'); /** @var SearchController $ctrl */ - $ctrl = $containerBuilder->get(SearchController::class); + $ctrl = $GLOBALS['containerBuilder']->get(SearchController::class); $_POST['db'] = 'PMA'; $_POST['table'] = 'PMA_BookMark'; diff --git a/test/classes/Controllers/Table/SqlControllerTest.php b/test/classes/Controllers/Table/SqlControllerTest.php new file mode 100644 index 0000000000..d94d34a2ab --- /dev/null +++ b/test/classes/Controllers/Table/SqlControllerTest.php @@ -0,0 +1,87 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Config\PageSettings; +use PhpMyAdmin\Controllers\Table\SqlController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Html\MySQLDocumentation; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\SqlQueryForm; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\SqlController + * @covers \PhpMyAdmin\SqlQueryForm + */ +class SqlControllerTest extends AbstractTestCase +{ + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void + { + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + + public function testSqlController(): void + { + $GLOBALS['server'] = 2; + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $GLOBALS['lang'] = 'en'; + $GLOBALS['text_dir'] = 'ltr'; + $GLOBALS['PMA_PHP_SELF'] = 'index.php'; + $GLOBALS['cfg']['Server'] = $GLOBALS['config']->defaultServer; + + $this->dummyDbi->addSelectDb('test_db'); + $this->dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + + $pageSettings = new PageSettings('Sql'); + $fields = $this->dbi->getColumns('test_db', 'test_table', true); + $template = new Template(); + + $expected = $pageSettings->getHTML(); + $expected .= $template->render('sql/query', [ + 'legend' => 'Run SQL query/queries on table <a href="' + . 'index.php?route=/sql&server=2&lang=en&db=test_db&table=test_table&server=2&lang=en' + . '">test_db.test_table</a>: ' . MySQLDocumentation::show('SELECT'), + 'textarea_cols' => 40, + 'textarea_rows' => 15, + 'textarea_auto_select' => false, + 'columns_list' => [ + 'id' => $fields['id'], + 'name' => $fields['name'], + 'datetimefield' => $fields['datetimefield'], + ], + 'codemirror_enable' => true, + 'has_bookmark' => false, + 'delimiter' => ';', + 'retain_query_box' => false, + 'is_upload' => true, + 'db' => 'test_db', + 'table' => 'test_table', + 'goto' => 'index.php?route=/table/sql&server=2&lang=en', + 'query' => 'SELECT * FROM `test_table` WHERE 1', + 'display_tab' => 'full', + 'bookmarks' => [], + 'can_convert_kanji' => false, + 'is_foreign_key_check' => true, + ]); + + $response = new ResponseRenderer(); + (new SqlController($response, $template, new SqlQueryForm($template)))($this->createStub(ServerRequest::class)); + $this->assertSame($expected, $response->getHTMLResult()); + } +} diff --git a/test/classes/Controllers/Table/Structure/ChangeControllerTest.php b/test/classes/Controllers/Table/Structure/ChangeControllerTest.php index a395226662..b1a2b3cefe 100644 --- a/test/classes/Controllers/Table/Structure/ChangeControllerTest.php +++ b/test/classes/Controllers/Table/Structure/ChangeControllerTest.php @@ -6,8 +6,11 @@ namespace PhpMyAdmin\Tests\Controllers\Table\Structure; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\Controllers\Table\Structure\ChangeController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Table\ColumnsDefinition; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer as ResponseStub; use PhpMyAdmin\Transformations; use ReflectionClass; @@ -17,6 +20,20 @@ use ReflectionClass; */ class ChangeControllerTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void + { + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + public function testChangeController(): void { $GLOBALS['server'] = 1; @@ -36,11 +53,8 @@ class ChangeControllerTest extends AbstractTestCase $ctrl = new ChangeController( $response, new Template(), - $GLOBALS['db'], - $GLOBALS['table'], - new Relation($this->dbi), - new Transformations(), - $this->dbi + $this->dbi, + new ColumnsDefinition($this->dbi, new Relation($this->dbi), new Transformations()) ); $method->invokeArgs($ctrl, [null]); diff --git a/test/classes/Controllers/Table/Structure/SaveControllerTest.php b/test/classes/Controllers/Table/Structure/SaveControllerTest.php index 534a68d460..a61a2fc971 100644 --- a/test/classes/Controllers/Table/Structure/SaveControllerTest.php +++ b/test/classes/Controllers/Table/Structure/SaveControllerTest.php @@ -7,9 +7,10 @@ namespace PhpMyAdmin\Tests\Controllers\Table\Structure; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\Controllers\Table\Structure\SaveController; use PhpMyAdmin\Controllers\Table\StructureController; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; -use PhpMyAdmin\Tests\Stubs\ResponseRenderer as ResponseStub; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; use PhpMyAdmin\Transformations; use ReflectionClass; @@ -18,26 +19,107 @@ use ReflectionClass; */ class SaveControllerTest extends AbstractTestCase { + protected function setUp(): void + { + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + } + public function testSaveController(): void { + $_POST = [ + 'db' => 'test_db', + 'table' => 'test_table', + 'orig_num_fields' => '1', + 'orig_field_where' => '', + 'orig_after_field' => '', + 'selected' => ['name'], + 'field_orig' => ['name'], + 'field_type_orig' => ['VARCHAR'], + 'field_length_orig' => ['20'], + 'field_default_value_orig' => [''], + 'field_default_type_orig' => ['NONE'], + 'field_collation_orig' => ['utf8mb4_general_ci'], + 'field_attribute_orig' => [''], + 'field_null_orig' => ['NO'], + 'field_extra_orig' => [''], + 'field_comments_orig' => [''], + 'field_virtuality_orig' => [''], + 'field_expression_orig' => [''], + 'primary_indexes' => '[]', + 'unique_indexes' => '[]', + 'indexes' => '[]', + 'fulltext_indexes' => '[]', + 'spatial_indexes' => '[]', + 'field_name' => ['new_name'], + 'field_type' => ['VARCHAR'], + 'field_length' => ['21'], + 'field_default_type' => ['NONE'], + 'field_default_value' => [''], + 'field_collation' => ['utf8mb4_general_ci'], + 'field_attribute' => [''], + 'field_adjust_privileges' => ['NULL'], + 'field_comments' => [''], + 'field_virtuality' => [''], + 'field_expression' => [''], + 'field_move_to' => [''], + 'field_mimetype' => [''], + 'field_transformation' => [''], + 'field_transformation_options' => [''], + 'field_input_transformation' => [''], + 'field_input_transformation_options' => [''], + 'do_save_data' => 'Save', + ]; + + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addSelectDb('test_db'); + $dummyDbi->addResult( + 'ALTER TABLE `test_table` CHANGE `name` `new_name` VARCHAR(21)' + . ' CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;', + [] + ); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $request = $this->createStub(ServerRequest::class); + + $mock = $this->createMock(StructureController::class); + $mock->expects($this->once())->method('__invoke')->with($request); + + (new SaveController( + new ResponseRenderer(), + new Template(), + new Relation($dbi), + new Transformations(), + $dbi, + $mock + ))($request); + + $this->assertArrayNotHasKey('selected', $_POST); + } + + public function testAdjustColumnPrivileges(): void + { $GLOBALS['server'] = 1; $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['PMA_PHP_SELF'] = 'index.php'; $GLOBALS['db'] = 'db'; $GLOBALS['table'] = 'table'; + $dbi = $this->createDatabaseInterface(); + $class = new ReflectionClass(SaveController::class); $method = $class->getMethod('adjustColumnPrivileges'); $method->setAccessible(true); $ctrl = new SaveController( - new ResponseStub(), + new ResponseRenderer(), new Template(), - $GLOBALS['db'], - $GLOBALS['table'], - new Relation($this->dbi), + new Relation($dbi), new Transformations(), - $this->dbi, + $dbi, $this->createStub(StructureController::class) ); diff --git a/test/classes/Controllers/Table/StructureControllerTest.php b/test/classes/Controllers/Table/StructureControllerTest.php new file mode 100644 index 0000000000..25ce6bd468 --- /dev/null +++ b/test/classes/Controllers/Table/StructureControllerTest.php @@ -0,0 +1,162 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Config\PageSettings; +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\ConfigStorage\RelationCleanup; +use PhpMyAdmin\Controllers\Table\StructureController; +use PhpMyAdmin\CreateAddField; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\FlashMessages; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Index; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; +use PhpMyAdmin\Util; + +/** + * @covers \PhpMyAdmin\Controllers\Table\StructureController + */ +class StructureControllerTest extends AbstractTestCase +{ + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void + { + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + + public function testStructureController(): void + { + $GLOBALS['server'] = 2; + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $GLOBALS['text_dir'] = 'ltr'; + $GLOBALS['lang'] = 'en'; + $GLOBALS['PMA_PHP_SELF'] = 'index.php'; + $GLOBALS['cfg']['Server'] = $GLOBALS['config']->defaultServer; + $GLOBALS['cfg']['Server']['DisableIS'] = true; + $GLOBALS['cfg']['ShowStats'] = false; + $GLOBALS['cfg']['ShowPropertyComments'] = false; + $_SESSION['relation'] = []; + + $this->dummyDbi->addSelectDb('test_db'); + $this->dummyDbi->addSelectDb('test_db'); + $this->dummyDbi->addResult( + 'SHOW COLLATION', + [ + ['utf8mb4_general_ci', 'utf8mb4', '45', 'Yes', 'Yes', '1'], + ['armscii8_general_ci', 'armscii8', '32', 'Yes', 'Yes', '1'], + ['utf8_general_ci', 'utf8', '33', 'Yes', 'Yes', '1'], + ['utf8_bin', 'utf8', '83', '', 'Yes', '1'], + ['latin1_swedish_ci', 'latin1', '8', 'Yes', 'Yes', '1'], + ], + ['Collation', 'Charset', 'Id', 'Default', 'Compiled', 'Sortlen'] + ); + // phpcs:disable Generic.Files.LineLength.TooLong + $this->dummyDbi->addResult( + 'SELECT * FROM `information_schema`.`PARTITIONS` WHERE `TABLE_SCHEMA` = \'test_db\' AND `TABLE_NAME` = \'test_table\'', + [ + ['def', 'test_db', 'test_table', null, null, null, null, null, null, null, null, null, '3', '5461', '16384', null, '0', '0', '2022-02-21 13:34:11', null, null, null, '', '', null], + ], + ['TABLE_CATALOG', 'TABLE_SCHEMA', 'TABLE_NAME', 'PARTITION_NAME', 'SUBPARTITION_NAME', 'PARTITION_ORDINAL_POSITION', 'SUBPARTITION_ORDINAL_POSITION', 'PARTITION_METHOD', 'SUBPARTITION_METHOD', 'PARTITION_EXPRESSION', 'SUBPARTITION_EXPRESSION', 'PARTITION_DESCRIPTION', 'TABLE_ROWS', 'AVG_ROW_LENGTH', 'DATA_LENGTH', 'MAX_DATA_LENGTH', 'INDEX_LENGTH', 'DATA_FREE', 'CREATE_TIME', 'UPDATE_TIME', 'CHECK_TIME', 'CHECKSUM', 'PARTITION_COMMENT', 'NODEGROUP', 'TABLESPACE_NAME'] + ); + $this->dummyDbi->addResult( + 'SELECT DISTINCT `PARTITION_NAME` FROM `information_schema`.`PARTITIONS` WHERE `TABLE_SCHEMA` = \'test_db\' AND `TABLE_NAME` = \'test_table\'', + [[null]], + ['PARTITION_NAME'] + ); + // phpcs:enable + + $pageSettings = new PageSettings('TableStructure'); + $fields = $this->dbi->getColumns($GLOBALS['db'], $GLOBALS['table'], true); + + $request = $this->createStub(ServerRequest::class); + $request->method('getRoute')->willReturn('/table/structure'); + + $response = new ResponseRenderer(); + $relation = new Relation($this->dbi); + $template = new Template(); + (new StructureController( + $response, + $template, + $relation, + new Transformations(), + new CreateAddField($this->dbi), + new RelationCleanup($this->dbi, $relation), + $this->dbi, + new FlashMessages() + ))($request); + + $expected = $pageSettings->getHTML(); + $expected .= $template->render('table/structure/display_structure', [ + 'collations' => [ + 'utf8mb4_general_ci' => [ + 'name' => 'utf8mb4_general_ci', + 'description' => 'Unicode (UCA 4.0.0), case-insensitive', + ], + ], + 'is_foreign_key_supported' => true, + 'indexes' => Index::getFromTable($GLOBALS['table'], $GLOBALS['db']), + 'indexes_duplicates' => Index::findDuplicates($GLOBALS['table'], $GLOBALS['db']), + 'relation_parameters' => $relation->getRelationParameters(), + 'hide_structure_actions' => true, + 'db' => 'test_db', + 'table' => 'test_table', + 'db_is_system_schema' => false, + 'tbl_is_view' => false, + 'mime_map' => [], + 'tbl_storage_engine' => 'INNODB', + 'primary' => Index::getPrimary($GLOBALS['table'], $GLOBALS['db']), + 'columns_with_unique_index' => [], + 'columns_list' => ['id', 'name', 'datetimefield'], + 'table_stats' => null, + 'fields' => $fields, + 'extracted_columnspecs' => [ + 1 => Util::extractColumnSpec((string) $fields['id']['Type']), + 2 => Util::extractColumnSpec((string) $fields['name']['Type']), + 3 => Util::extractColumnSpec((string) $fields['datetimefield']['Type']), + ], + 'columns_with_index' => [], + 'central_list' => [], + 'comments_map' => [], + 'browse_mime' => true, + 'show_column_comments' => true, + 'show_stats' => false, + 'mysql_int_version' => $this->dbi->getVersion(), + 'is_mariadb' => $this->dbi->isMariaDB(), + 'text_dir' => 'ltr', + 'is_active' => false, + 'have_partitioning' => true, + 'partitions' => [], + 'partition_names' => [0 => null], + 'default_sliders_state' => 'closed', + 'attributes' => [1 => ' ', 2 => ' ', 3 => ' '], + 'displayed_fields' => [ + 1 => [ + 'text' => 'id', + 'icon' => '<img src="themes/dot.gif" title="Primary" alt="Primary" class="icon ic_b_primary">', + ], + 2 => ['text' => 'name', 'icon' => ''], + 3 => ['text' => 'datetimefield', 'icon' => ''], + ], + 'row_comments' => [1 => '', 2 => '', 3 => ''], + 'route' => '/table/structure', + ]); + + $this->assertSame($expected, $response->getHTMLResult()); + } +} diff --git a/test/classes/Controllers/Table/TrackingControllerTest.php b/test/classes/Controllers/Table/TrackingControllerTest.php new file mode 100644 index 0000000000..712566ba97 --- /dev/null +++ b/test/classes/Controllers/Table/TrackingControllerTest.php @@ -0,0 +1,92 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Table\TrackingController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\SqlQueryForm; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Tracking; + +/** + * @covers \PhpMyAdmin\Controllers\Table\TrackingController + */ +class TrackingControllerTest extends AbstractTestCase +{ + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void + { + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + + public function testTrackingController(): void + { + $GLOBALS['server'] = 2; + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $GLOBALS['text_dir'] = 'ltr'; + $GLOBALS['PMA_PHP_SELF'] = 'index.php'; + $GLOBALS['cfg']['Server']['DisableIS'] = true; + $GLOBALS['cfg']['Server']['tracking_default_statements'] = 'CREATE TABLE,ALTER TABLE,DROP TABLE'; + + $this->dummyDbi->addSelectDb('test_db'); + + $response = new ResponseRenderer(); + $template = new Template(); + (new TrackingController( + $response, + $template, + new Tracking(new SqlQueryForm($template), $template, new Relation($this->dbi), $this->dbi) + ))($this->createStub(ServerRequest::class)); + + $main = $template->render('table/tracking/main', [ + 'url_params' => [ + 'db' => $GLOBALS['db'], + 'table' => $GLOBALS['table'], + 'goto' => 'index.php?route=/table/tracking&server=2&lang=en', + 'back' => 'index.php?route=/table/tracking&server=2&lang=en', + ], + 'db' => $GLOBALS['db'], + 'table' => $GLOBALS['table'], + 'selectable_tables_num_rows' => 0, + 'selectable_tables_entries' => [], + 'selected_table' => null, + 'last_version' => 0, + 'versions' => [], + 'type' => 'table', + 'default_statements' => $GLOBALS['cfg']['Server']['tracking_default_statements'], + 'text_dir' => 'ltr', + ]); + $expected = $template->render('table/tracking/index', [ + 'active_message' => '', + 'action_message' => '', + 'delete_version' => '', + 'create_version' => '', + 'deactivate_tracking' => '', + 'activate_tracking' => '', + 'message' => '', + 'sql_dump' => '', + 'schema_snapshot' => '', + 'tracking_report_rows' => '', + 'tracking_report' => '', + 'main' => $main, + ]); + + $this->assertSame($expected, $response->getHTMLResult()); + } +} diff --git a/test/classes/Controllers/Table/TriggersControllerTest.php b/test/classes/Controllers/Table/TriggersControllerTest.php new file mode 100644 index 0000000000..37ffd6267d --- /dev/null +++ b/test/classes/Controllers/Table/TriggersControllerTest.php @@ -0,0 +1,91 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\Controllers\Table\TriggersController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\TriggersController + */ +class TriggersControllerTest extends AbstractTestCase +{ + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void + { + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + + public function testTriggersController(): void + { + $GLOBALS['server'] = 2; + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $GLOBALS['text_dir'] = 'ltr'; + $GLOBALS['PMA_PHP_SELF'] = 'index.php'; + $GLOBALS['cfg']['Server']['DisableIS'] = true; + + $this->dummyDbi->addResult('SHOW TABLES FROM `test_db`;', [['test_table']], ['Tables_in_test_db']); + $this->dummyDbi->addSelectDb('test_db'); + $this->dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + $this->dummyDbi->addResult( + 'SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`SCHEMA_PRIVILEGES`' + . ' WHERE GRANTEE=\'\'\'pma_test\'\'@\'\'localhost\'\'\' AND PRIVILEGE_TYPE=\'TRIGGER\'' + . ' AND \'test_db\' LIKE `TABLE_SCHEMA`', + [['TRIGGER']] + ); + + $template = new Template(); + (new TriggersController( + new ResponseRenderer(), + $template, + $this->dbi + ))($this->createStub(ServerRequest::class)); + + $items = [ + [ + 'name' => 'test_trigger', + 'table' => 'test_table', + 'action_timing' => 'AFTER', + 'event_manipulation' => 'INSERT', + 'definition' => 'BEGIN END', + 'definer' => 'definer@localhost', + 'full_trigger_name' => '`test_trigger`', + 'drop' => 'DROP TRIGGER IF EXISTS `test_trigger`', + 'create' => 'CREATE TRIGGER `test_trigger` AFTER INSERT ON `test_table`' . "\n" + . ' FOR EACH ROW BEGIN END' . "\n" . '//' . "\n", + ], + ]; + $rows = $template->render('database/triggers/row', [ + 'db' => $GLOBALS['db'], + 'table' => $GLOBALS['table'], + 'trigger' => $items[0], + 'has_drop_privilege' => true, + 'has_edit_privilege' => true, + 'row_class' => '', + ]); + + $this->expectOutputString($template->render('database/triggers/list', [ + 'db' => $GLOBALS['db'], + 'table' => $GLOBALS['table'], + 'items' => $items, + 'rows' => $rows, + 'has_privilege' => true, + ])); + } +} diff --git a/test/classes/Controllers/Table/ZoomSearchControllerTest.php b/test/classes/Controllers/Table/ZoomSearchControllerTest.php new file mode 100644 index 0000000000..790fd05344 --- /dev/null +++ b/test/classes/Controllers/Table/ZoomSearchControllerTest.php @@ -0,0 +1,75 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Table; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Table\ZoomSearchController; +use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Table\Search; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; + +/** + * @covers \PhpMyAdmin\Controllers\Table\ZoomSearchController + */ +class ZoomSearchControllerTest extends AbstractTestCase +{ + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void + { + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + + public function testZoomSearchController(): void + { + $GLOBALS['server'] = 2; + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $GLOBALS['text_dir'] = 'ltr'; + $GLOBALS['PMA_PHP_SELF'] = 'index.php'; + $GLOBALS['cfg']['Server']['DisableIS'] = true; + + $this->dummyDbi->addSelectDb('test_db'); + $this->dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + + $response = new ResponseRenderer(); + $template = new Template(); + $controller = new ZoomSearchController( + $response, + $template, + new Search($this->dbi), + new Relation($this->dbi), + $this->dbi + ); + $controller($this->createStub(ServerRequest::class)); + + $expected = $template->render('table/zoom_search/index', [ + 'db' => $GLOBALS['db'], + 'table' => $GLOBALS['table'], + 'goto' => 'index.php?route=/sql&server=2&lang=en', + 'self' => $controller, + 'geom_column_flag' => false, + 'column_names' => ['id', 'name', 'datetimefield'], + 'data_label' => 'name', + 'keys' => [], + 'criteria_column_names' => null, + 'criteria_column_types' => null, + 'max_plot_limit' => 500, + ]); + + $this->assertSame($expected, $response->getHTMLResult()); + } +} diff --git a/test/classes/Controllers/ThemeSetControllerTest.php b/test/classes/Controllers/ThemeSetControllerTest.php new file mode 100644 index 0000000000..1cfca6e4a7 --- /dev/null +++ b/test/classes/Controllers/ThemeSetControllerTest.php @@ -0,0 +1,90 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers; + +use PhpMyAdmin\Controllers\ThemeSetController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\ThemeManager; +use PhpMyAdmin\UserPreferences; + +/** + * @covers \PhpMyAdmin\Controllers\ThemeSetController + */ +class ThemeSetControllerTest extends AbstractTestCase +{ + protected function setUp(): void + { + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + } + + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testSetTheme(): void + { + $GLOBALS['cfg']['ThemeManager'] = true; + + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturn('theme_name'); + + $themeManager = $this->createMock(ThemeManager::class); + $themeManager->expects($this->once())->method('setActiveTheme')->with($this->equalTo('theme_name')); + $themeManager->expects($this->once())->method('setThemeCookie'); + + $userPreferences = $this->createMock(UserPreferences::class); + $userPreferences->expects($this->once())->method('load') + ->willReturn(['config_data' => ['ThemeDefault' => 'pmahomme']]); + $userPreferences->expects($this->once())->method('save') + ->with($this->equalTo(['ThemeDefault' => 'theme_name'])); + + (new ThemeSetController(new ResponseRenderer(), new Template(), $themeManager, $userPreferences))($request); + } + + /** + * @param string[]|string|null $themeName + * + * @runInSeparateProcess + * @preserveGlobalState disabled + * @dataProvider providerForTestWithoutTheme + */ + public function testWithoutTheme(bool $hasThemes, $themeName): void + { + $GLOBALS['cfg']['ThemeManager'] = $hasThemes; + + $request = $this->createStub(ServerRequest::class); + $request->method('getParsedBodyParam')->willReturn($themeName); + + $themeManager = $this->createMock(ThemeManager::class); + $themeManager->expects($this->never())->method('setActiveTheme'); + $themeManager->expects($this->never())->method('setThemeCookie'); + + $userPreferences = $this->createMock(UserPreferences::class); + $userPreferences->expects($this->never())->method('load'); + $userPreferences->expects($this->never())->method('save'); + + (new ThemeSetController(new ResponseRenderer(), new Template(), $themeManager, $userPreferences))($request); + } + + /** + * @return iterable<int, array<int, bool|string|string[]|null>> + * @psalm-return iterable<int, array{bool, string[]|string|null}> + */ + public function providerForTestWithoutTheme(): iterable + { + return [ + [true, null], + [true, ''], + [true, ['theme_name']], + [false, null], + [false, ''], + [false, ['theme_name']], + ]; + } +} diff --git a/test/classes/Controllers/Transformation/OverviewControllerTest.php b/test/classes/Controllers/Transformation/OverviewControllerTest.php index d54c44b40d..ad4774d0e5 100644 --- a/test/classes/Controllers/Transformation/OverviewControllerTest.php +++ b/test/classes/Controllers/Transformation/OverviewControllerTest.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Transformation; use PhpMyAdmin\Controllers\Transformation\OverviewController; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; @@ -25,6 +26,7 @@ class OverviewControllerTest extends AbstractTestCase parent::setUp(); parent::setGlobalConfig(); parent::setTheme(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['server'] = 1; @@ -39,7 +41,7 @@ class OverviewControllerTest extends AbstractTestCase $controller = new OverviewController($response, new Template(), new Transformations()); - $controller(); + $controller($this->createStub(ServerRequest::class)); $actual = $response->getHTMLResult(); $this->assertStringContainsString( diff --git a/test/classes/Controllers/VersionCheckControllerTest.php b/test/classes/Controllers/VersionCheckControllerTest.php new file mode 100644 index 0000000000..4d76dff873 --- /dev/null +++ b/test/classes/Controllers/VersionCheckControllerTest.php @@ -0,0 +1,121 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers; + +use PhpMyAdmin\Controllers\VersionCheckController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\VersionInformation; + +/** + * @covers \PhpMyAdmin\Controllers\VersionCheckController + */ +class VersionCheckControllerTest extends AbstractTestCase +{ + protected function setUp(): void + { + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + } + + public function testWithLatestCompatibleVersion(): void + { + $_GET = []; + $versionInfo = (object) [ + 'date' => '2022-02-11', + 'version' => '5.1.3', + 'releases' => [ + (object) [ + 'date' => '2022-02-11', + 'php_versions' => '>=7.1,<8.1', + 'version' => '5.1.3', + 'mysql_versions' => '>=5.5', + ], + (object) [ + 'date' => '2022-02-11', + 'php_versions' => '>=5.5,<8.0', + 'version' => '4.9.10', + 'mysql_versions' => '>=5.5', + ], + ], + ]; + + $versionInformation = $this->createMock(VersionInformation::class); + $versionInformation->expects($this->once())->method('getLatestVersion')->willReturn($versionInfo); + $versionInformation->expects($this->once())->method('getLatestCompatibleVersion') + ->with($this->equalTo($versionInfo->releases)) + ->willReturn(['version' => '5.1.3', 'date' => '2022-02-11']); + + (new VersionCheckController( + new ResponseRenderer(), + new Template(), + $versionInformation + ))($this->createStub(ServerRequest::class)); + + $output = $this->getActualOutputForAssertion(); + $this->assertTrue(isset($_GET['ajax_request'])); + $this->assertSame('{"version":"5.1.3","date":"2022-02-11"}', $output); + } + + public function testWithoutLatestCompatibleVersion(): void + { + $_GET = []; + $versionInfo = (object) [ + 'date' => '2022-02-11', + 'version' => '5.1.3', + 'releases' => [ + (object) [ + 'date' => '2022-02-11', + 'php_versions' => '>=7.1,<8.1', + 'version' => '5.1.3', + 'mysql_versions' => '>=5.5', + ], + (object) [ + 'date' => '2022-02-11', + 'php_versions' => '>=5.5,<8.0', + 'version' => '4.9.10', + 'mysql_versions' => '>=5.5', + ], + ], + ]; + + $versionInformation = $this->createMock(VersionInformation::class); + $versionInformation->expects($this->once())->method('getLatestVersion')->willReturn($versionInfo); + $versionInformation->expects($this->once())->method('getLatestCompatibleVersion') + ->with($this->equalTo($versionInfo->releases)) + ->willReturn(null); + + (new VersionCheckController( + new ResponseRenderer(), + new Template(), + $versionInformation + ))($this->createStub(ServerRequest::class)); + + $output = $this->getActualOutputForAssertion(); + $this->assertTrue(isset($_GET['ajax_request'])); + $this->assertSame('{"version":"","date":""}', $output); + } + + public function testWithoutLatestVersion(): void + { + $_GET = []; + + $versionInformation = $this->createMock(VersionInformation::class); + $versionInformation->expects($this->once())->method('getLatestVersion')->willReturn(null); + $versionInformation->expects($this->never())->method('getLatestCompatibleVersion'); + + (new VersionCheckController( + new ResponseRenderer(), + new Template(), + $versionInformation + ))($this->createStub(ServerRequest::class)); + + $output = $this->getActualOutputForAssertion(); + $this->assertTrue(isset($_GET['ajax_request'])); + $this->assertSame('[]', $output); + } +} diff --git a/test/classes/CoreTest.php b/test/classes/CoreTest.php index e7cb514874..d61c6533df 100644 --- a/test/classes/CoreTest.php +++ b/test/classes/CoreTest.php @@ -37,6 +37,7 @@ class CoreTest extends AbstractNetworkTestCase parent::setUp(); parent::setTheme(); parent::setLanguage(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['db'] = ''; @@ -483,7 +484,7 @@ class CoreTest extends AbstractNetworkTestCase $lang = _pgettext('PHP documentation language', 'en'); $this->assertEquals( Core::getPHPDocLink('function'), - './url.php?url=https%3A%2F%2Fwww.php.net%2Fmanual%2F' + 'index.php?route=/url&url=https%3A%2F%2Fwww.php.net%2Fmanual%2F' . $lang . '%2Ffunction' ); } @@ -511,11 +512,11 @@ class CoreTest extends AbstractNetworkTestCase return [ [ 'https://wiki.phpmyadmin.net', - './url.php?url=https%3A%2F%2Fwiki.phpmyadmin.net', + 'index.php?route=/url&url=https%3A%2F%2Fwiki.phpmyadmin.net', ], [ 'https://wiki.phpmyadmin.net', - './url.php?url=https%3A%2F%2Fwiki.phpmyadmin.net', + 'index.php?route=/url&url=https%3A%2F%2Fwiki.phpmyadmin.net', ], [ 'wiki.phpmyadmin.net', @@ -604,14 +605,9 @@ class CoreTest extends AbstractNetworkTestCase } /** - * Test for unserializing - * - * @param string $url URL to test - * @param mixed $expected Expected result - * * @dataProvider provideTestIsAllowedDomain */ - public function testIsAllowedDomain(string $url, $expected): void + public function testIsAllowedDomain(string $url, bool $expected): void { $_SERVER['SERVER_NAME'] = 'server.local'; $this->assertEquals( @@ -621,45 +617,36 @@ class CoreTest extends AbstractNetworkTestCase } /** - * Test data provider - * - * @return array + * @return array<int, array<int, bool|string>> + * @psalm-return list<array{string, bool}> */ public function provideTestIsAllowedDomain(): array { return [ - [ - 'https://www.phpmyadmin.net/', - true, - ], - [ - 'http://duckduckgo.com\\@github.com', - false, - ], - [ - 'https://github.com/', - true, - ], - [ - 'https://github.com:123/', - false, - ], - [ - 'https://user:pass@github.com:123/', - false, - ], - [ - 'https://user:pass@github.com/', - false, - ], - [ - 'https://server.local/', - true, - ], - [ - './relative/', - false, - ], + ['', false], + ['//', false], + ['https://www.phpmyadmin.net/', true], + ['https://www.phpmyadmin.net:123/', false], + ['http://duckduckgo.com\\@github.com', false], + ['https://user:pass@github.com:123/', false], + ['https://user:pass@github.com/', false], + ['https://server.local/', true], + ['./relative/', false], + ['//wiki.phpmyadmin.net', true], + ['//www.phpmyadmin.net', true], + ['//phpmyadmin.net', true], + ['//demo.phpmyadmin.net', true], + ['//docs.phpmyadmin.net', true], + ['//dev.mysql.com', true], + ['//bugs.mysql.com', true], + ['//mariadb.org', true], + ['//mariadb.com', true], + ['//php.net', true], + ['//www.php.net', true], + ['//github.com', true], + ['//www.github.com', true], + ['//www.percona.com', true], + ['//mysqldatabaseadministration.blogspot.com', true], ]; } @@ -932,11 +919,9 @@ class CoreTest extends AbstractNetworkTestCase public function testPopulateRequestWithEncryptedQueryParams(): void { - global $config; - $_SESSION = []; - $config->set('URLQueryEncryption', true); - $config->set('URLQueryEncryptionSecretKey', str_repeat('a', 32)); + $GLOBALS['config']->set('URLQueryEncryption', true); + $GLOBALS['config']->set('URLQueryEncryptionSecretKey', str_repeat('a', 32)); $_GET = ['pos' => '0', 'eq' => Url::encryptQuery('{"db":"test_db","table":"test_table"}')]; $_REQUEST = $_GET; @@ -965,11 +950,9 @@ class CoreTest extends AbstractNetworkTestCase array $encrypted, array $decrypted ): void { - global $config; - $_SESSION = []; - $config->set('URLQueryEncryption', true); - $config->set('URLQueryEncryptionSecretKey', str_repeat('a', 32)); + $GLOBALS['config']->set('URLQueryEncryption', true); + $GLOBALS['config']->set('URLQueryEncryptionSecretKey', str_repeat('a', 32)); $_GET = $encrypted; $_REQUEST = $encrypted; diff --git a/test/classes/CreateAddFieldTest.php b/test/classes/CreateAddFieldTest.php index 59f62d6348..3616ce5aff 100644 --- a/test/classes/CreateAddFieldTest.php +++ b/test/classes/CreateAddFieldTest.php @@ -22,6 +22,7 @@ class CreateAddFieldTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $this->createAddField = new CreateAddField($GLOBALS['dbi']); } diff --git a/test/classes/Crypto/CryptoTest.php b/test/classes/Crypto/CryptoTest.php index 4e525ec9ae..f136004e29 100644 --- a/test/classes/Crypto/CryptoTest.php +++ b/test/classes/Crypto/CryptoTest.php @@ -17,10 +17,8 @@ class CryptoTest extends AbstractTestCase { public function testWithValidKeyFromConfig(): void { - global $config; - $_SESSION = []; - $config->set('URLQueryEncryptionSecretKey', str_repeat('a', 32)); + $GLOBALS['config']->set('URLQueryEncryptionSecretKey', str_repeat('a', 32)); $crypto = new Crypto(); $encrypted = $crypto->encrypt('test'); @@ -31,10 +29,8 @@ class CryptoTest extends AbstractTestCase public function testWithValidKeyFromSession(): void { - global $config; - $_SESSION = ['URLQueryEncryptionSecretKey' => str_repeat('a', 32)]; - $config->set('URLQueryEncryptionSecretKey', ''); + $GLOBALS['config']->set('URLQueryEncryptionSecretKey', ''); $crypto = new Crypto(); $encrypted = $crypto->encrypt('test'); @@ -45,10 +41,8 @@ class CryptoTest extends AbstractTestCase public function testWithNewSessionKey(): void { - global $config; - $_SESSION = []; - $config->set('URLQueryEncryptionSecretKey', ''); + $GLOBALS['config']->set('URLQueryEncryptionSecretKey', ''); $crypto = new Crypto(); $encrypted = $crypto->encrypt('test'); @@ -60,17 +54,15 @@ class CryptoTest extends AbstractTestCase public function testDecryptWithInvalidKey(): void { - global $config; - $_SESSION = []; - $config->set('URLQueryEncryptionSecretKey', str_repeat('a', 32)); + $GLOBALS['config']->set('URLQueryEncryptionSecretKey', str_repeat('a', 32)); $crypto = new Crypto(); $encrypted = $crypto->encrypt('test'); $this->assertNotSame('test', $encrypted); $this->assertSame('test', $crypto->decrypt($encrypted)); - $config->set('URLQueryEncryptionSecretKey', str_repeat('b', 32)); + $GLOBALS['config']->set('URLQueryEncryptionSecretKey', str_repeat('b', 32)); $crypto = new Crypto(); $this->assertNull($crypto->decrypt($encrypted)); diff --git a/test/classes/Database/CentralColumnsTest.php b/test/classes/Database/CentralColumnsTest.php index f50226c4d7..15e86a878a 100644 --- a/test/classes/Database/CentralColumnsTest.php +++ b/test/classes/Database/CentralColumnsTest.php @@ -14,6 +14,8 @@ use function array_slice; /** * @covers \PhpMyAdmin\Database\CentralColumns + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled */ class CentralColumnsTest extends AbstractTestCase { diff --git a/test/classes/Database/Designer/CommonTest.php b/test/classes/Database/Designer/CommonTest.php index bac5348d46..e6f97fee23 100644 --- a/test/classes/Database/Designer/CommonTest.php +++ b/test/classes/Database/Designer/CommonTest.php @@ -9,6 +9,7 @@ use PhpMyAdmin\ConfigStorage\RelationParameters; use PhpMyAdmin\Database\Designer\Common; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\DummyResult; use PhpMyAdmin\Version; @@ -19,6 +20,12 @@ use function sprintf; */ class CommonTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var Common */ private $designerCommon; @@ -28,6 +35,9 @@ class CommonTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; $_SESSION = [ 'relation' => [ @@ -359,7 +369,9 @@ class CommonTest extends AbstractTestCase 'relation' => 'rel db', ])->toArray(); - parent::setGlobalDbi(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $this->loadTestDataForRelationDeleteAddTests( 'CREATE TABLE `table\'2` (`field\'1` int(11) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1' ); @@ -383,7 +395,9 @@ class CommonTest extends AbstractTestCase 'relation' => 'rel db', ])->toArray(); - parent::setGlobalDbi(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $this->loadTestDataForRelationDeleteAddTests( 'CREATE TABLE `table\'2` (`field\'1` int(11) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1' @@ -426,7 +440,9 @@ class CommonTest extends AbstractTestCase 'relation' => 'rel db', ])->toArray(); - parent::setGlobalDbi(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $this->loadTestDataForRelationDeleteAddTests( 'CREATE TABLE `table\'2` (' @@ -489,7 +505,9 @@ class CommonTest extends AbstractTestCase 'relation' => 'rel db', ])->toArray(); - parent::setGlobalDbi(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $this->loadTestDataForRelationDeleteAddTests( 'CREATE TABLE `table\'2` (`field\'1` int(11) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1' diff --git a/test/classes/Database/DesignerTest.php b/test/classes/Database/DesignerTest.php index 68d873d471..63df623eb5 100644 --- a/test/classes/Database/DesignerTest.php +++ b/test/classes/Database/DesignerTest.php @@ -27,6 +27,7 @@ class DesignerTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 1; $GLOBALS['cfg']['ServerDefault'] = 1; diff --git a/test/classes/Database/EventsTest.php b/test/classes/Database/EventsTest.php index 7bcb60d567..0d69e8d112 100644 --- a/test/classes/Database/EventsTest.php +++ b/test/classes/Database/EventsTest.php @@ -27,6 +27,7 @@ class EventsTest extends AbstractTestCase parent::setGlobalConfig(); parent::setLanguage(); parent::setTheme(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['server'] = 0; $GLOBALS['db'] = 'db'; @@ -310,9 +311,7 @@ class EventsTest extends AbstractTestCase */ public function testGetQueryFromRequest(array $request, string $query, int $num_err): void { - global $errors; - - $errors = []; + $GLOBALS['errors'] = []; unset($_POST); $_POST = $request; @@ -326,7 +325,7 @@ class EventsTest extends AbstractTestCase $GLOBALS['dbi'] = $dbi; $this->assertEquals($query, $this->events->getQueryFromRequest()); - $this->assertCount($num_err, $errors); + $this->assertCount($num_err, $GLOBALS['errors']); } /** diff --git a/test/classes/Database/QbeTest.php b/test/classes/Database/QbeTest.php index 3bdba94650..f44257155e 100644 --- a/test/classes/Database/QbeTest.php +++ b/test/classes/Database/QbeTest.php @@ -25,6 +25,7 @@ class QbeTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['db'] = 'pma_test'; $this->object = new Qbe(new Relation($GLOBALS['dbi']), new Template(), $GLOBALS['dbi'], 'pma_test'); diff --git a/test/classes/Database/RoutinesTest.php b/test/classes/Database/RoutinesTest.php index 071e3fe254..9b166c7837 100644 --- a/test/classes/Database/RoutinesTest.php +++ b/test/classes/Database/RoutinesTest.php @@ -28,6 +28,7 @@ class RoutinesTest extends AbstractTestCase parent::setGlobalConfig(); parent::setLanguage(); parent::setTheme(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['cfg']['Server']['DisableIS'] = false; $GLOBALS['cfg']['ActionLinksMode'] = 'icons'; $GLOBALS['server'] = 0; @@ -37,6 +38,7 @@ class RoutinesTest extends AbstractTestCase $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['proc_priv'] = false; $GLOBALS['is_reload_priv'] = false; + $GLOBALS['errors'] = []; $this->routines = new Routines( $GLOBALS['dbi'], @@ -1135,11 +1137,9 @@ class RoutinesTest extends AbstractTestCase */ public function testGetQueryFromRequest(array $request, string $query, int $num_err): void { - global $errors, $cfg; + $GLOBALS['cfg']['ShowFunctionFields'] = false; - $cfg['ShowFunctionFields'] = false; - - $errors = []; + $GLOBALS['errors'] = []; $old_dbi = $GLOBALS['dbi'] ?? null; $dbi = $this->getMockBuilder(DatabaseInterface::class) @@ -1180,7 +1180,7 @@ class RoutinesTest extends AbstractTestCase unset($_POST); $_POST = $request; $this->assertEquals($query, $routines->getQueryFromRequest()); - $this->assertCount($num_err, $errors); + $this->assertCount($num_err, $GLOBALS['errors']); // reset $GLOBALS['dbi'] = $old_dbi; diff --git a/test/classes/Database/TriggersTest.php b/test/classes/Database/TriggersTest.php index e67c7a5cff..89cfd7075c 100644 --- a/test/classes/Database/TriggersTest.php +++ b/test/classes/Database/TriggersTest.php @@ -26,6 +26,7 @@ class TriggersTest extends AbstractTestCase parent::setGlobalConfig(); parent::setLanguage(); parent::setTheme(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['cfg']['Server']['DisableIS'] = false; $GLOBALS['db'] = 'pma_test'; @@ -269,9 +270,7 @@ class TriggersTest extends AbstractTestCase string $query, int $num_err ): void { - global $errors; - - $errors = []; + $GLOBALS['errors'] = []; $_POST['item_definer'] = $definer; $_POST['item_name'] = $name; @@ -282,7 +281,7 @@ class TriggersTest extends AbstractTestCase $GLOBALS['server'] = 1; $this->assertEquals($query, $this->triggers->getQueryFromRequest()); - $this->assertCount($num_err, $errors); + $this->assertCount($num_err, $GLOBALS['errors']); } /** diff --git a/test/classes/DatabaseInterfaceTest.php b/test/classes/DatabaseInterfaceTest.php index 84c28aa5d1..d43f3967ad 100644 --- a/test/classes/DatabaseInterfaceTest.php +++ b/test/classes/DatabaseInterfaceTest.php @@ -18,14 +18,10 @@ use stdClass; */ class DatabaseInterfaceTest extends AbstractTestCase { - /** - * Configures test parameters. - */ protected function setUp(): void { parent::setUp(); - parent::setGlobalDbi(); - $GLOBALS['server'] = 0; + $GLOBALS['dbi'] = $this->createDatabaseInterface(); } /** @@ -40,24 +36,21 @@ class DatabaseInterfaceTest extends AbstractTestCase */ public function testGetCurrentUser($value, string $string, array $expected, bool $needsSecondCall): void { + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + SessionCache::remove('mysql_cur_user'); - $this->dummyDbi->addResult('SELECT CURRENT_USER();', $value); + $dummyDbi->addResult('SELECT CURRENT_USER();', $value); if ($needsSecondCall) { - $this->dummyDbi->addResult('SELECT CURRENT_USER();', $value); + $dummyDbi->addResult('SELECT CURRENT_USER();', $value); } - $this->assertEquals( - $expected, - $this->dbi->getCurrentUserAndHost() - ); + $this->assertEquals($expected, $dbi->getCurrentUserAndHost()); - $this->assertEquals( - $string, - $this->dbi->getCurrentUser() - ); + $this->assertEquals($string, $dbi->getCurrentUser()); - $this->assertAllQueriesConsumed(); + $dummyDbi->assertAllQueriesConsumed(); } /** @@ -103,7 +96,10 @@ class DatabaseInterfaceTest extends AbstractTestCase */ public function testPMAGetColumnMap(): void { - $this->dummyDbi->addResult( + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $dummyDbi->addResult( 'PMA_sql_query', [true], [], @@ -125,7 +121,7 @@ class DatabaseInterfaceTest extends AbstractTestCase 'view_columns2', ]; - $column_map = $this->dbi->getColumnMapFromSql($sql_query, $view_columns); + $column_map = $dbi->getColumnMapFromSql($sql_query, $view_columns); $this->assertEquals( [ @@ -144,7 +140,7 @@ class DatabaseInterfaceTest extends AbstractTestCase $column_map[1] ); - $this->assertAllQueriesConsumed(); + $dummyDbi->assertAllQueriesConsumed(); } /** @@ -152,7 +148,8 @@ class DatabaseInterfaceTest extends AbstractTestCase */ public function testGetSystemDatabase(): void { - $sd = $this->dbi->getSystemDatabase(); + $dbi = $this->createDatabaseInterface(); + $sd = $dbi->getSystemDatabase(); $this->assertInstanceOf(SystemDatabase::class, $sd); } @@ -161,14 +158,16 @@ class DatabaseInterfaceTest extends AbstractTestCase */ public function testPostConnectControl(): void { - parent::setGlobalDbi(); - $this->dummyDbi->addResult( + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $dummyDbi->addResult( 'SHOW TABLES FROM `phpmyadmin`;', [] ); $GLOBALS['db'] = ''; $GLOBALS['cfg']['Server']['only_db'] = []; - $this->dbi->postConnectControl(new Relation($this->dbi)); + $dbi->postConnectControl(new Relation($dbi)); $this->assertInstanceOf(DatabaseList::class, $GLOBALS['dblist']); } @@ -177,11 +176,13 @@ class DatabaseInterfaceTest extends AbstractTestCase */ public function testGetDbCollation(): void { + $dbi = $this->createDatabaseInterface(); + $GLOBALS['server'] = 1; // test case for system schema $this->assertEquals( 'utf8_general_ci', - $this->dbi->getDbCollation('information_schema') + $dbi->getDbCollation('information_schema') ); $GLOBALS['cfg']['Server']['DisableIS'] = false; @@ -189,7 +190,7 @@ class DatabaseInterfaceTest extends AbstractTestCase $this->assertEquals( 'utf8_general_ci', - $this->dbi->getDbCollation('pma_test') + $dbi->getDbCollation('pma_test') ); } @@ -198,9 +199,10 @@ class DatabaseInterfaceTest extends AbstractTestCase */ public function testGetServerCollation(): void { + $dbi = $this->createDatabaseInterface(); $GLOBALS['server'] = 1; $GLOBALS['cfg']['DBG']['sql'] = true; - $this->assertEquals('utf8_general_ci', $this->dbi->getServerCollation()); + $this->assertEquals('utf8_general_ci', $dbi->getServerCollation()); } /** @@ -266,16 +268,19 @@ class DatabaseInterfaceTest extends AbstractTestCase */ public function testIsAmazonRdsData(array $value, bool $expected): void { + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + SessionCache::remove('is_amazon_rds'); - $this->dummyDbi->addResult('SELECT @@basedir', $value); + $dummyDbi->addResult('SELECT @@basedir', $value); $this->assertEquals( $expected, - $this->dbi->isAmazonRds() + $dbi->isAmazonRds() ); - $this->assertAllQueriesConsumed(); + $dummyDbi->assertAllQueriesConsumed(); } /** @@ -358,23 +363,28 @@ class DatabaseInterfaceTest extends AbstractTestCase */ public function testSetCollation(): void { - $this->dummyDbi->addResult('SET collation_connection = \'utf8_czech_ci\';', [true]); - $this->dummyDbi->addResult('SET collation_connection = \'utf8mb4_bin_ci\';', [true]); - $this->dummyDbi->addResult('SET collation_connection = \'utf8_czech_ci\';', [true]); - $this->dummyDbi->addResult('SET collation_connection = \'utf8_bin_ci\';', [true]); + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $dummyDbi->addResult('SET collation_connection = \'utf8_czech_ci\';', [true]); + $dummyDbi->addResult('SET collation_connection = \'utf8mb4_bin_ci\';', [true]); + $dummyDbi->addResult('SET collation_connection = \'utf8_czech_ci\';', [true]); + $dummyDbi->addResult('SET collation_connection = \'utf8_bin_ci\';', [true]); $GLOBALS['charset_connection'] = 'utf8mb4'; - $this->dbi->setCollation('utf8_czech_ci'); - $this->dbi->setCollation('utf8mb4_bin_ci'); + $dbi->setCollation('utf8_czech_ci'); + $dbi->setCollation('utf8mb4_bin_ci'); $GLOBALS['charset_connection'] = 'utf8'; - $this->dbi->setCollation('utf8_czech_ci'); - $this->dbi->setCollation('utf8mb4_bin_ci'); + $dbi->setCollation('utf8_czech_ci'); + $dbi->setCollation('utf8mb4_bin_ci'); - $this->assertAllQueriesConsumed(); + $dummyDbi->assertAllQueriesConsumed(); } public function testGetTablesFull(): void { + $dbi = $this->createDatabaseInterface(); + $GLOBALS['cfg']['Server']['DisableIS'] = true; $expected = [ @@ -423,12 +433,14 @@ class DatabaseInterfaceTest extends AbstractTestCase ], ]; - $actual = $this->dbi->getTablesFull('test_db'); + $actual = $dbi->getTablesFull('test_db'); $this->assertEquals($expected, $actual); } public function testGetTablesFullWithInformationSchema(): void { + $dbi = $this->createDatabaseInterface(); + $GLOBALS['cfg']['Server']['DisableIS'] = false; $expected = [ @@ -479,7 +491,7 @@ class DatabaseInterfaceTest extends AbstractTestCase ], ]; - $actual = $this->dbi->getTablesFull('test_db'); + $actual = $dbi->getTablesFull('test_db'); $this->assertEquals($expected, $actual); } @@ -488,25 +500,29 @@ class DatabaseInterfaceTest extends AbstractTestCase */ public function testQueryAsControlUser(): void { + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + $sql = 'insert into PMA_bookmark A,B values(1, 2)'; - $this->dummyDbi->addResult($sql, [true]); - $this->dummyDbi->addResult($sql, [true]); - $this->dummyDbi->addResult('Invalid query', false); + $dummyDbi->addResult($sql, [true]); + $dummyDbi->addResult($sql, [true]); + $dummyDbi->addResult('Invalid query', false); $this->assertInstanceOf( ResultInterface::class, - $this->dbi->queryAsControlUser($sql) + $dbi->queryAsControlUser($sql) ); $this->assertInstanceOf( ResultInterface::class, - $this->dbi->tryQueryAsControlUser($sql) + $dbi->tryQueryAsControlUser($sql) ); - $this->assertFalse($this->dbi->tryQueryAsControlUser('Invalid query')); + $this->assertFalse($dbi->tryQueryAsControlUser('Invalid query')); } public function testGetDatabasesFullDisabledISAndSortIntColumn(): void { - parent::setGlobalDbi(); + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); $GLOBALS['db'] = ''; $GLOBALS['table'] = ''; @@ -518,22 +534,22 @@ class DatabaseInterfaceTest extends AbstractTestCase 'db1', 'db2', ]; - $this->dummyDbi->removeDefaultResults(); - $this->dummyDbi->addResult( + $dummyDbi->removeDefaultResults(); + $dummyDbi->addResult( 'SELECT @@collation_database', [ ['utf8_general_ci'], ], ['@@collation_database'] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SELECT @@collation_database', [ ['utf8_general_ci'], ], ['@@collation_database'] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SHOW TABLE STATUS FROM `db1`;', [ [ @@ -597,7 +613,7 @@ class DatabaseInterfaceTest extends AbstractTestCase ] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SHOW TABLE STATUS FROM `db2`;', [ [ @@ -660,12 +676,12 @@ class DatabaseInterfaceTest extends AbstractTestCase 'Comment', ] ); - $this->dummyDbi->addSelectDb(''); - $this->dummyDbi->addSelectDb(''); - $this->dummyDbi->addSelectDb('db1'); - $this->dummyDbi->addSelectDb('db2'); + $dummyDbi->addSelectDb(''); + $dummyDbi->addSelectDb(''); + $dummyDbi->addSelectDb('db1'); + $dummyDbi->addSelectDb('db2'); - $databaseList = $this->dbi->getDatabasesFull( + $databaseList = $dbi->getDatabasesFull( null, true, DatabaseInterface::CONNECT_USER, @@ -700,6 +716,6 @@ class DatabaseInterfaceTest extends AbstractTestCase ], ], $databaseList); - $this->assertAllQueriesConsumed(); + $dummyDbi->assertAllQueriesConsumed(); } } diff --git a/test/classes/Dbal/DatabaseNameTest.php b/test/classes/Dbal/DatabaseNameTest.php index 65e5202d1d..da029a6fd7 100644 --- a/test/classes/Dbal/DatabaseNameTest.php +++ b/test/classes/Dbal/DatabaseNameTest.php @@ -5,69 +5,60 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Dbal; use PhpMyAdmin\Dbal\DatabaseName; +use PhpMyAdmin\Dbal\InvalidDatabaseName; use PHPUnit\Framework\TestCase; -use Webmozart\Assert\InvalidArgumentException; use function str_repeat; /** * @covers \PhpMyAdmin\Dbal\DatabaseName + * @covers \PhpMyAdmin\Dbal\InvalidDatabaseName */ class DatabaseNameTest extends TestCase { - public function testEmptyName(): void - { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Expected a different value than "".'); - DatabaseName::fromValue(''); - } - - public function testNameWithTrailingWhitespace(): void - { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Expected a value not to end with " ". Got: "a "'); - DatabaseName::fromValue('a '); - } - - public function testLongName(): void + /** + * @dataProvider providerForTestValidNames + */ + public function testValidName(string $validName): void { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage( - 'Expected a value to contain at most 64 characters. Got: ' - . '"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"' - ); - DatabaseName::fromValue(str_repeat('a', 65)); + $name = DatabaseName::fromValue($validName); + $this->assertEquals($validName, $name->getName()); + $this->assertEquals($validName, (string) $name); } - public function testValidName(): void + /** + * @return iterable<int, string[]> + */ + public function providerForTestValidNames(): iterable { - $name = DatabaseName::fromValue('name'); - $this->assertEquals('name', $name->getName()); - $this->assertEquals('name', (string) $name); + yield ['name']; + yield ['0']; + yield [str_repeat('a', 64)]; } /** * @param mixed $name * - * @dataProvider providerForTestInvalidMixedNames + * @dataProvider providerForTestInvalidNames */ - public function testInvalidMixedNames($name, string $exceptionMessage): void + public function testInvalidNames($name, string $exceptionMessage): void { - $this->expectException(InvalidArgumentException::class); + $this->expectException(InvalidDatabaseName::class); $this->expectExceptionMessage($exceptionMessage); DatabaseName::fromValue($name); } /** - * @return mixed[][] - * @psalm-return non-empty-list<array{mixed, string}> + * @return iterable<string, mixed[]> + * @psalm-return iterable<string, array{mixed, non-empty-string}> */ - public function providerForTestInvalidMixedNames(): array + public function providerForTestInvalidNames(): iterable { - return [ - [null, 'Expected a string. Got: NULL'], - [1, 'Expected a string. Got: integer'], - [['db'], 'Expected a string. Got: array'], - ]; + yield 'null' => [null, 'The database name must be a non-empty string.']; + yield 'integer' => [1, 'The database name must be a non-empty string.']; + yield 'array' => [['database'], 'The database name must be a non-empty string.']; + yield 'empty string' => ['', 'The database name must be a non-empty string.']; + yield 'too long name' => [str_repeat('a', 65), 'The database name cannot be longer than 64 characters.']; + yield 'trailing space' => ['a ', 'The database name cannot end with a space character.']; } } diff --git a/test/classes/Dbal/DbiDummyTest.php b/test/classes/Dbal/DbiDummyTest.php index b1987f2ff6..9aa180dfc9 100644 --- a/test/classes/Dbal/DbiDummyTest.php +++ b/test/classes/Dbal/DbiDummyTest.php @@ -4,8 +4,10 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Dbal; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Query\Utilities; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\DummyResult; /** @@ -13,12 +15,21 @@ use PhpMyAdmin\Tests\Stubs\DummyResult; */ class DbiDummyTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** * Configures test parameters. */ protected function setUp(): void { parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['cfg']['DBG']['sql'] = false; $GLOBALS['cfg']['IconvExtraParams'] = ''; $GLOBALS['server'] = 1; diff --git a/test/classes/Dbal/TableNameTest.php b/test/classes/Dbal/TableNameTest.php index 7d195030f2..0ea928dc38 100644 --- a/test/classes/Dbal/TableNameTest.php +++ b/test/classes/Dbal/TableNameTest.php @@ -4,70 +4,61 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Dbal; +use PhpMyAdmin\Dbal\InvalidTableName; use PhpMyAdmin\Dbal\TableName; use PHPUnit\Framework\TestCase; -use Webmozart\Assert\InvalidArgumentException; use function str_repeat; /** * @covers \PhpMyAdmin\Dbal\TableName + * @covers \PhpMyAdmin\Dbal\InvalidTableName */ class TableNameTest extends TestCase { - public function testEmptyName(): void - { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Expected a different value than "".'); - TableName::fromValue(''); - } - - public function testNameWithTrailingWhitespace(): void - { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Expected a value not to end with " ". Got: "a "'); - TableName::fromValue('a '); - } - - public function testLongName(): void + /** + * @dataProvider providerForTestValidNames + */ + public function testValidName(string $validName): void { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage( - 'Expected a value to contain at most 64 characters. Got: ' - . '"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"' - ); - TableName::fromValue(str_repeat('a', 65)); + $name = TableName::fromValue($validName); + $this->assertEquals($validName, $name->getName()); + $this->assertEquals($validName, (string) $name); } - public function testValidName(): void + /** + * @return iterable<int, string[]> + */ + public function providerForTestValidNames(): iterable { - $name = TableName::fromValue('name'); - $this->assertEquals('name', $name->getName()); - $this->assertEquals('name', (string) $name); + yield ['name']; + yield ['0']; + yield [str_repeat('a', 64)]; } /** * @param mixed $name * - * @dataProvider providerForTestInvalidMixedNames + * @dataProvider providerForTestInvalidNames */ - public function testInvalidMixedNames($name, string $exceptionMessage): void + public function testInvalidNames($name, string $exceptionMessage): void { - $this->expectException(InvalidArgumentException::class); + $this->expectException(InvalidTableName::class); $this->expectExceptionMessage($exceptionMessage); TableName::fromValue($name); } /** - * @return mixed[][] - * @psalm-return non-empty-list<array{mixed, string}> + * @return iterable<string, mixed[]> + * @psalm-return iterable<string, array{mixed, non-empty-string}> */ - public function providerForTestInvalidMixedNames(): array + public function providerForTestInvalidNames(): iterable { - return [ - [null, 'Expected a string. Got: NULL'], - [1, 'Expected a string. Got: integer'], - [['table'], 'Expected a string. Got: array'], - ]; + yield 'null' => [null, 'The table name must be a non-empty string.']; + yield 'integer' => [1, 'The table name must be a non-empty string.']; + yield 'array' => [['table'], 'The table name must be a non-empty string.']; + yield 'empty string' => ['', 'The table name must be a non-empty string.']; + yield 'too long name' => [str_repeat('a', 65), 'The table name cannot be longer than 64 characters.']; + yield 'trailing space' => ['a ', 'The table name cannot end with a space character.']; } } diff --git a/test/classes/Display/DisplayPartsTest.php b/test/classes/Display/DisplayPartsTest.php new file mode 100644 index 0000000000..01adac0079 --- /dev/null +++ b/test/classes/Display/DisplayPartsTest.php @@ -0,0 +1,72 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Display; + +use PhpMyAdmin\Display\DisplayParts; +use PHPUnit\Framework\TestCase; + +/** + * @covers \PhpMyAdmin\Display\DisplayParts + */ +class DisplayPartsTest extends TestCase +{ + public function testFromArray(): void + { + $displayParts = DisplayParts::fromArray([ + 'hasEditLink' => true, + 'deleteLink' => DisplayParts::DELETE_ROW, + 'hasSortLink' => true, + 'hasNavigationBar' => true, + 'hasBookmarkForm' => true, + 'hasTextButton' => true, + 'hasPrintLink' => true, + ]); + $this->assertTrue($displayParts->hasEditLink); + $this->assertSame(DisplayParts::DELETE_ROW, $displayParts->deleteLink); + $this->assertTrue($displayParts->hasSortLink); + $this->assertTrue($displayParts->hasNavigationBar); + $this->assertTrue($displayParts->hasBookmarkForm); + $this->assertTrue($displayParts->hasTextButton); + $this->assertTrue($displayParts->hasPrintLink); + } + + public function testWith(): void + { + $displayParts = DisplayParts::fromArray([]); + $this->assertFalse($displayParts->hasEditLink); + $this->assertSame(DisplayParts::NO_DELETE, $displayParts->deleteLink); + $this->assertFalse($displayParts->hasSortLink); + $this->assertFalse($displayParts->hasNavigationBar); + $this->assertFalse($displayParts->hasBookmarkForm); + $this->assertFalse($displayParts->hasTextButton); + $this->assertFalse($displayParts->hasPrintLink); + + $displayParts = $displayParts->with([ + 'hasEditLink' => true, + 'deleteLink' => DisplayParts::KILL_PROCESS, + 'hasSortLink' => true, + 'hasNavigationBar' => true, + 'hasBookmarkForm' => true, + 'hasTextButton' => true, + 'hasPrintLink' => true, + ]); + $this->assertTrue($displayParts->hasEditLink); + $this->assertSame(DisplayParts::KILL_PROCESS, $displayParts->deleteLink); + $this->assertTrue($displayParts->hasSortLink); + $this->assertTrue($displayParts->hasNavigationBar); + $this->assertTrue($displayParts->hasBookmarkForm); + $this->assertTrue($displayParts->hasTextButton); + $this->assertTrue($displayParts->hasPrintLink); + + $displayParts = $displayParts->with([]); + $this->assertTrue($displayParts->hasEditLink); + $this->assertSame(DisplayParts::KILL_PROCESS, $displayParts->deleteLink); + $this->assertTrue($displayParts->hasSortLink); + $this->assertTrue($displayParts->hasNavigationBar); + $this->assertTrue($displayParts->hasBookmarkForm); + $this->assertTrue($displayParts->hasTextButton); + $this->assertTrue($displayParts->hasPrintLink); + } +} diff --git a/test/classes/Display/ResultsTest.php b/test/classes/Display/ResultsTest.php index a46da81ec6..31fd1632c8 100644 --- a/test/classes/Display/ResultsTest.php +++ b/test/classes/Display/ResultsTest.php @@ -6,6 +6,7 @@ namespace PhpMyAdmin\Tests\Display; use PhpMyAdmin\ConfigStorage\RelationParameters; use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Display\DisplayParts; use PhpMyAdmin\Display\Results as DisplayResults; use PhpMyAdmin\FieldMetadata; use PhpMyAdmin\Html\Generator; @@ -14,10 +15,11 @@ use PhpMyAdmin\ParseAnalyze; use PhpMyAdmin\Plugins\Transformations\Output\Text_Plain_External; use PhpMyAdmin\Plugins\Transformations\Text_Plain_Link; use PhpMyAdmin\Plugins\TransformationsPlugin; -use PhpMyAdmin\SqlParser\Parser; use PhpMyAdmin\SqlParser\Utils\Query; +use PhpMyAdmin\StatementInfo; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Transformations; use stdClass; @@ -43,6 +45,12 @@ use const MYSQLI_TYPE_TIMESTAMP; */ class ResultsTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var DisplayResults */ protected $object; @@ -55,6 +63,10 @@ class ResultsTest extends AbstractTestCase parent::setUp(); parent::setLanguage(); parent::setGlobalConfig(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + $this->setTheme(); $GLOBALS['server'] = 0; $GLOBALS['db'] = 'db'; $GLOBALS['table'] = 'table'; @@ -80,78 +92,16 @@ class ResultsTest extends AbstractTestCase */ public function testisSelect(): void { - $parser = new Parser('SELECT * FROM pma'); $this->assertTrue( $this->callFunction( $this->object, DisplayResults::class, 'isSelect', - [ - [ - 'statement' => $parser->statements[0], - 'select_from' => true, - ], - ] + [StatementInfo::fromArray(Query::getAll('SELECT * FROM pma'))] ) ); } - /** - * Test for navigation buttons - * - * @param string $caption iconic caption for button - * @param string $title text for button - * @param int $pos position for next query - * @param string $html_sql_query query ready for display - * - * @dataProvider providerForTestGetTableNavigationButton - */ - public function testGetTableNavigationButton( - string $caption, - string $title, - int $pos, - string $html_sql_query - ): void { - $GLOBALS['cfg']['TableNavigationLinksMode'] = 'icons'; - $_SESSION[' PMA_token '] = 'token'; - - $actual = $this->callFunction( - $this->object, - DisplayResults::class, - 'getTableNavigationButton', - [ - &$caption, - $title, - $pos, - $html_sql_query, - true, - ] - ); - - $this->assertStringContainsString('<form action="index.php?route=/sql', $actual); - $this->assertStringContainsString('" method="post" >', $actual); - $this->assertStringContainsString('name="sql_query" value="SELECT * FROM `pma_bookmark` WHERE 1"', $actual); - $this->assertStringContainsString('name="pos" value="1"', $actual); - $this->assertStringContainsString('value="btn" title="Submit"', $actual); - } - - /** - * Provider for testGetTableNavigationButton - * - * @return array array data for testGetTableNavigationButton - */ - public function providerForTestGetTableNavigationButton(): array - { - return [ - [ - 'btn', - 'Submit', - 1, - 'SELECT * FROM `pma_bookmark` WHERE 1', - ], - ]; - } - public function testGetClassForDateTimeRelatedFieldsCase1(): void { $this->assertEquals( @@ -422,45 +372,21 @@ class ResultsTest extends AbstractTestCase ); } - /** - * Data provider for testSetHighlightedColumnGlobalField - * - * @return array parameters and output - */ - public function dataProviderForTestSetHighlightedColumnGlobalField(): array - { - $parser = new Parser('SELECT * FROM db_name WHERE `db_name`.`tbl`.id > 0 AND `id` < 10'); - - return [ - [ - ['statement' => $parser->statements[0]], - [ - 'db_name' => 'true', - 'tbl' => 'true', - 'id' => 'true', - ], - ], - ]; - } - - /** - * Test setHighlightedColumnGlobalField - * - * @param array $analyzed_sql the analyzed query - * @param array $output setting value of setHighlightedColumnGlobalField - * - * @dataProvider dataProviderForTestSetHighlightedColumnGlobalField - */ - public function testSetHighlightedColumnGlobalField(array $analyzed_sql, array $output): void + public function testSetHighlightedColumnGlobalField(): void { + $query = 'SELECT * FROM db_name WHERE `db_name`.`tbl`.id > 0 AND `id` < 10'; $this->callFunction( $this->object, DisplayResults::class, 'setHighlightedColumnGlobalField', - [$analyzed_sql] + [StatementInfo::fromArray(Query::getAll($query))] ); - $this->assertEquals($output, $this->object->properties['highlight_columns']); + $this->assertEquals([ + 'db_name' => 'true', + 'tbl' => 'true', + 'id' => 'true', + ], $this->object->properties['highlight_columns']); } /** @@ -687,7 +613,6 @@ class ResultsTest extends AbstractTestCase * bool, * TransformationsPlugin|null, * array, - * array, * string * }} */ @@ -738,7 +663,6 @@ class ResultsTest extends AbstractTestCase false, null, ['https://www.example.com/'], - [], 'class="disableAjax">[BLOB - 4 B]</a>' . '</td>' . "\n", ], @@ -752,7 +676,6 @@ class ResultsTest extends AbstractTestCase false, $transformation_plugin, [], - [], '<td class="text-start grid_edit transformed hex">' . '1001' . '</td>' . "\n", @@ -767,7 +690,6 @@ class ResultsTest extends AbstractTestCase false, $transformation_plugin, [], - [], '<td data-decimals="0"' . "\n" . ' data-type="string"' . "\n" . ' class="grid_edit null">' . "\n" @@ -784,7 +706,6 @@ class ResultsTest extends AbstractTestCase false, null, [], - [], '<td data-decimals="0" data-type="string" ' . 'data-originallength="11" ' . 'class="grid_edit pre_wrap">foo bar baz</td>' . "\n", @@ -799,7 +720,6 @@ class ResultsTest extends AbstractTestCase false, $transformation_plugin_external, [], - [], '<td data-decimals="0" data-type="string" ' . 'data-originallength="11" ' . 'class="grid_edit text-nowrap transformed">foo bar baz</td>' . "\n", @@ -814,7 +734,6 @@ class ResultsTest extends AbstractTestCase false, null, [], - [], '<td data-decimals="0" data-type="datetime" ' . 'data-originallength="19" ' . 'class="grid_edit text-nowrap">2020-09-20 16:35:00</td>' . "\n", @@ -823,16 +742,15 @@ class ResultsTest extends AbstractTestCase } /** - * @param string $protectBinary all|blob|noblob|no - * @param string|null $column the relevant column in data row - * @param string $class the html class for column - * @param object $meta the meta-information about the field - * @param array $map the list of relations - * @param array $_url_params the parameters for generate url - * @param bool $condition_field the column should highlighted or not - * @param array $transform_options the transformation parameters - * @param array $analyzed_sql_results the analyzed query - * @param string $output the output of this function + * @param string $protectBinary all|blob|noblob|no + * @param string|null $column the relevant column in data row + * @param string $class the html class for column + * @param object $meta the meta-information about the field + * @param array $map the list of relations + * @param array $_url_params the parameters for generate url + * @param bool $condition_field the column should highlighted or not + * @param array $transform_options the transformation parameters + * @param string $output the output of this function * * @dataProvider dataProviderForTestGetDataCellForNonNumericColumns */ @@ -846,7 +764,6 @@ class ResultsTest extends AbstractTestCase bool $condition_field, ?TransformationsPlugin $transformation_plugin, array $transform_options, - array $analyzed_sql_results, string $output ): void { $_SESSION['tmpval']['display_binary'] = true; @@ -854,6 +771,7 @@ class ResultsTest extends AbstractTestCase $_SESSION['tmpval']['relational_display'] = false; $GLOBALS['cfg']['LimitChars'] = 50; $GLOBALS['cfg']['ProtectBinary'] = $protectBinary; + $statementInfo = $this->createStub(StatementInfo::class); $this->assertStringContainsString( $output, $this->callFunction( @@ -869,7 +787,7 @@ class ResultsTest extends AbstractTestCase $condition_field, $transformation_plugin, $transform_options, - $analyzed_sql_results, + $statementInfo, ] ) ); @@ -957,10 +875,10 @@ class ResultsTest extends AbstractTestCase 0, false, [], - '', + 'disabled', false, $query, - Query::getAll($query), + StatementInfo::fromArray(Query::getAll($query)), ] ); @@ -1364,18 +1282,16 @@ class ResultsTest extends AbstractTestCase public function testGetTable(): void { - global $db, $table; - $GLOBALS['cfg']['Server']['DisableIS'] = true; - $db = 'test_db'; - $table = 'test_table'; + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; $query = 'SELECT * FROM `test_db`.`test_table`;'; - $object = new DisplayResults($this->dbi, $db, $table, 1, '', $query); + $object = new DisplayResults($this->dbi, $GLOBALS['db'], $GLOBALS['table'], 1, '', $query); $object->properties['unique_id'] = 1234567890; - [$analyzedSqlResults] = ParseAnalyze::sqlQuery($query, $db); + [$statementInfo] = ParseAnalyze::sqlQuery($query, $GLOBALS['db']); $fieldsMeta = [ new FieldMetadata( MYSQLI_TYPE_DECIMAL, @@ -1389,17 +1305,17 @@ class ResultsTest extends AbstractTestCase $object->setProperties( 3, $fieldsMeta, - $analyzedSqlResults['is_count'], - $analyzedSqlResults['is_export'], - $analyzedSqlResults['is_func'], - $analyzedSqlResults['is_analyse'], + $statementInfo->isCount, + $statementInfo->isExport, + $statementInfo->isFunction, + $statementInfo->isAnalyse, 3, count($fieldsMeta), 1.234, 'ltr', - $analyzedSqlResults['is_maint'], - $analyzedSqlResults['is_explain'], - $analyzedSqlResults['is_show'], + $statementInfo->isMaint, + $statementInfo->isExplain, + $statementInfo->isShow, null, null, true, @@ -1420,17 +1336,19 @@ class ResultsTest extends AbstractTestCase $_SESSION['tmpval']['query']['27b1330f2076ef45d236f20839a92831']['max_rows'] = 25; $dtResult = $this->dbi->tryQuery($query); - $displayParts = [ - 'edit_lnk' => DisplayResults::UPDATE_ROW, - 'del_lnk' => DisplayResults::DELETE_ROW, - 'sort_lnk' => '1', - 'nav_bar' => '1', - 'bkm_form' => '1', - 'text_btn' => '0', - 'pview_lnk' => '1', - ]; + + $displayParts = DisplayParts::fromArray([ + 'hasEditLink' => true, + 'deleteLink' => DisplayParts::DELETE_ROW, + 'hasSortLink' => true, + 'hasNavigationBar' => true, + 'hasBookmarkForm' => true, + 'hasTextButton' => false, + 'hasPrintLink' => true, + ]); + $this->assertNotFalse($dtResult); - $actual = $object->getTable($dtResult, $displayParts, $analyzedSqlResults); + $actual = $object->getTable($dtResult, $displayParts, $statementInfo); $template = new Template(); @@ -1531,14 +1449,12 @@ class ResultsTest extends AbstractTestCase 'success' ), 'navigation' => [ - 'move_backward_buttons' => '', 'page_selector' => '', - 'move_forward_buttons' => '', 'number_total_page' => 1, 'has_show_all' => true, 'hidden_fields' => [ - 'db' => $db, - 'table' => $table, + 'db' => $GLOBALS['db'], + 'table' => $GLOBALS['table'], 'server' => 1, 'sql_query' => $query, 'is_browse_distinct' => false, @@ -1550,8 +1466,8 @@ class ResultsTest extends AbstractTestCase 'pos' => 0, 'sort_by_key' => [ 'hidden_fields' => [ - 'db' => $db, - 'table' => $table, + 'db' => $GLOBALS['db'], + 'table' => $GLOBALS['table'], 'server' => 1, 'sort_by_key' => '1', 'session_max_rows' => 25, @@ -1574,6 +1490,7 @@ class ResultsTest extends AbstractTestCase ], ], ], + 'is_last_page' => true, ], 'headers' => [ 'column_order' => [ @@ -1616,16 +1533,16 @@ class ResultsTest extends AbstractTestCase 'has_print_link' => true, 'has_export_link' => true, 'url_params' => [ - 'db' => $db, - 'table' => $table, + 'db' => $GLOBALS['db'], + 'table' => $GLOBALS['table'], 'printview' => '1', 'sql_query' => $query, 'single_table' => 'true', 'unlim_num_rows' => 3, ], ], - 'db' => $db, - 'table' => $table, + 'db' => $GLOBALS['db'], + 'table' => $GLOBALS['table'], 'unique_id' => 1234567890, 'sql_query' => $query, 'goto' => '', @@ -1639,4 +1556,227 @@ class ResultsTest extends AbstractTestCase $this->assertEquals($tableTemplate, $actual); } + + public function testGetTable2(): void + { + $GLOBALS['cfg']['Server']['DisableIS'] = true; + + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $query = 'SELECT COUNT(*) AS `Rows`, `name` FROM `test_table` GROUP BY `name` ORDER BY `name`'; + + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $object = new DisplayResults($dbi, $GLOBALS['db'], $GLOBALS['table'], 1, '', $query); + $object->properties['unique_id'] = 1234567890; + + [$statementInfo] = ParseAnalyze::sqlQuery($query, $GLOBALS['db']); + $fieldsMeta = [ + new FieldMetadata( + MYSQLI_TYPE_LONG, + MYSQLI_NUM_FLAG | MYSQLI_NOT_NULL_FLAG, + (object) ['name' => 'Rows'] + ), + new FieldMetadata(MYSQLI_TYPE_STRING, MYSQLI_NOT_NULL_FLAG, (object) ['name' => 'name']), + ]; + + $dummyDbi->addResult($query, [['2', 'abcd'], ['1', 'foo']], ['Rows', 'name'], $fieldsMeta); + + $object->setProperties( + 2, + $fieldsMeta, + $statementInfo->isCount, + $statementInfo->isExport, + $statementInfo->isFunction, + $statementInfo->isAnalyse, + 2, + count($fieldsMeta), + 1.234, + 'ltr', + $statementInfo->isMaint, + $statementInfo->isExplain, + $statementInfo->isShow, + null, + null, + true, + true + ); + + $_SESSION = ['tmpval' => [], ' PMA_token ' => 'token']; + $_SESSION['tmpval']['geoOption'] = ''; + $_SESSION['tmpval']['hide_transformation'] = false; + $_SESSION['tmpval']['display_blob'] = ''; + $_SESSION['tmpval']['display_binary'] = ''; + $_SESSION['tmpval']['relational_display'] = ''; + $_SESSION['tmpval']['possible_as_geometry'] = ''; + $_SESSION['tmpval']['pftext'] = ''; + $_SESSION['tmpval']['max_rows'] = 25; + $_SESSION['tmpval']['pos'] = 0; + $_SESSION['tmpval']['repeat_cells'] = 0; + $_SESSION['tmpval']['query']['f2a8e80312ca180031ad773b573adbe1']['max_rows'] = 25; + + $dtResult = $dbi->tryQuery($query); + + $displayParts = DisplayParts::fromArray([ + 'hasEditLink' => false, + 'deleteLink' => DisplayParts::NO_DELETE, + 'hasSortLink' => true, + 'hasNavigationBar' => true, + 'hasBookmarkForm' => true, + 'hasTextButton' => false, + 'hasPrintLink' => true, + ]); + + $this->assertNotFalse($dtResult); + $actual = $object->getTable($dtResult, $displayParts, $statementInfo); + + $template = new Template(); + + $tableHeadersForColumns = $template->render('display/results/table_headers_for_columns', [ + 'is_sortable' => true, + 'columns' => [ + [ + 'column_name' => 'Rows', + 'order_link' => '<a href="index.php?route=/sql&server=0&lang=en&db=test_db&table=test_table' + . '&sql_query=SELECT+COUNT%28%2A%29+AS+%60Rows%60%2C+%60name%60+FROM+%60test_table' + . '%60+GROUP+BY+%60name%60++%0AORDER+BY+%60Rows%60+ASC&sql_signature=' + . '8412b2f6bb4473905c68b2612d95d0020dda32282b3f5bf7a63fbaa98163016e&session_max_rows=25' + . '&is_browse_distinct=1&server=0&lang=en" class="sortlink">Rows<input type="hidden" value="' + . 'index.php?route=/sql&server=0&lang=en&db=test_db&table=test_table&sql_query=' + . 'SELECT+COUNT%28%2A%29+AS+%60Rows%60%2C+%60name%60+FROM+%60test_table%60+GROUP+BY+' + . '%60name%60++%0AORDER+BY+%60name%60+ASC%2C+%60Rows%60+ASC&sql_signature=' + . '6077a1df2401b3fa1ca67a940e3bb3cf6ff126ee5245137b07d68b1e7fe4075a&session_max_rows=25' + . '&is_browse_distinct=1&server=0&lang=en"></a><input type="hidden" name="url-remove-order"' + . ' value="index.php?route=/sql&db=test_db&table=test_table&sql_query=' + . 'SELECT+COUNT%28%2A%29+AS+%60Rows%60%2C+%60name%60+FROM+%60test_table%60+GROUP+BY+%60name' + . '%60+ORDER+BY+%60name%60+ASC&sql_signature=' + . 'a6daf20f5593bc5d7c62fdb7dc564994f9e4a928f4488ab41b653c264bed70e7&session_max_rows=25' + . '&is_browse_distinct=1&server=0&lang=en">' . "\n" + . '<input type="hidden" name="url-add-order" value="' + . 'index.php?route=/sql&db=test_db&table=test_table&sql_query=' + . 'SELECT+COUNT%28%2A%29+AS+%60Rows%60%2C+%60name%60+FROM+%60test_table%60+GROUP+BY+' + . '%60name%60++%0AORDER+BY+%60name%60+ASC%2C+%60Rows%60+ASC&sql_signature=' + . '6077a1df2401b3fa1ca67a940e3bb3cf6ff126ee5245137b07d68b1e7fe4075a&session_max_rows=25' + . '&is_browse_distinct=1&server=0&lang=en">', + 'comments' => '', + 'is_browse_pointer_enabled' => true, + 'is_browse_marker_enabled' => true, + 'is_column_hidden' => false, + 'is_column_numeric' => true, + ], + [ + 'column_name' => 'name', + 'order_link' => '<a href="index.php?route=/sql&server=0&lang=en&db=test_db&table=test_table' + . '&sql_query=SELECT+COUNT%28%2A%29+AS+%60Rows%60%2C+%60name%60+FROM+%60test_table' + . '%60+GROUP+BY+%60name%60++%0AORDER+BY+%60name%60+DESC&sql_signature=' + . 'de2cda64ffdeae7d1181feb386c1c47acea4de444235f1cdc29cf4556d4bae4c&session_max_rows=25' + . '&is_browse_distinct=1&server=0&lang=en" class="sortlink">name <img src="themes/dot.gif"' + . ' title="" alt="Ascending" class="icon ic_s_asc soimg"> <img src="themes/dot.gif" title=""' + . ' alt="Descending" class="icon ic_s_desc soimg hide"> <small>1</small><input type="hidden"' + . ' value="index.php?route=/sql&server=0&lang=en&db=test_db&table=test_table&sql_query=' + . 'SELECT+COUNT%28%2A%29+AS+%60Rows%60%2C+%60name%60+FROM+%60test_table%60+GROUP+BY+' + . '%60name%60++%0AORDER+BY+%60name%60+DESC&sql_signature=' + . 'de2cda64ffdeae7d1181feb386c1c47acea4de444235f1cdc29cf4556d4bae4c&session_max_rows=25' + . '&is_browse_distinct=1&server=0&lang=en"></a><input type="hidden" name="url-remove-order"' + . ' value="index.php?route=/sql&db=test_db&table=test_table&sql_query=' + . 'SELECT+COUNT%28%2A%29+AS+%60Rows%60%2C+%60name%60+FROM+%60test_table%60+GROUP+BY+' + . '%60name%60&sql_signature=1e391c9073b55f6d88696ff3b6991df45636bd24c32e7c235c8ff7ef640161ce' + . '&session_max_rows=25&is_browse_distinct=1&server=0&lang=en' + . '&discard_remembered_sort=1">' . "\n" . '<input type="hidden" name="url-add-order" value="' + . 'index.php?route=/sql&db=test_db&table=test_table&sql_query=' + . 'SELECT+COUNT%28%2A%29+AS+%60Rows%60%2C+%60name%60+FROM+%60test_table%60+GROUP+BY+' + . '%60name%60++%0AORDER+BY+%60name%60+DESC&sql_signature=' + . 'de2cda64ffdeae7d1181feb386c1c47acea4de444235f1cdc29cf4556d4bae4c&session_max_rows=25' + . '&is_browse_distinct=1&server=0&lang=en">', + 'comments' => '', + 'is_browse_pointer_enabled' => true, + 'is_browse_marker_enabled' => true, + 'is_column_hidden' => false, + 'is_column_numeric' => false, + ], + ], + ]); + + $tableTemplate = $template->render('display/results/table', [ + 'sql_query_message' => Generator::getMessage( + Message::success('Showing rows 0 - 1 (2 total, Query took 1.2340 seconds.)'), + $query, + 'success' + ), + 'navigation' => [ + 'page_selector' => '', + 'number_total_page' => 1, + 'has_show_all' => true, + 'hidden_fields' => [ + 'db' => $GLOBALS['db'], + 'table' => $GLOBALS['table'], + 'server' => 1, + 'sql_query' => $query, + 'is_browse_distinct' => true, + 'goto' => '', + ], + 'session_max_rows' => 'all', + 'is_showing_all' => false, + 'max_rows' => 25, + 'pos' => 0, + 'sort_by_key' => [], + 'is_last_page' => true, + ], + 'headers' => [ + 'column_order' => [], + 'options' => '$optionsBlock', + 'has_bulk_actions_form' => false, + 'button' => '<thead><tr>' . "\n", + 'table_headers_for_columns' => $tableHeadersForColumns, + 'column_at_right_side' => "\n" . '<td class="d-print-none"></td>', + ], + 'body' => '<tr><td data-decimals="0" data-type="int" class="' + . 'text-end data not_null text-nowrap">2</td>' . "\n" + . '<td data-decimals="0" data-type="string" data-originallength="4" class="' + . 'data not_null relation text pre_wrap"><a href="index.php?route=/sql&server=0&lang=en' + . '&db=test_db&table=test_table&pos=0&sql_signature=' + . '435bef10ad40031af7da88ea735cdc55ee91ac589b93adf10a10101b00e4d7ac&sql_query=' + . 'SELECT+%2A+FROM+%60test_db%60.%60test_table%60+WHERE+%60name%60+%3D+%27abcd%27&server=0&lang=en' + . '" title="abcd">abcd</a></td>' . "\n" + . '</tr>' . "\n" + . '<tr><td data-decimals="0" data-type="int" class="' + . 'text-end data not_null text-nowrap">1</td>' . "\n" + . '<td data-decimals="0" data-type="string" data-originallength="3" class="' + . 'data not_null relation text pre_wrap"><a href="index.php?route=/sql&server=0&lang=en&db=test_db' + . '&table=test_table&pos=0&sql_signature=' + . '8b25f948acdbde1631297c34c6fe773c1751dfed5e59a30e3ee909773512e297&sql_query=' + . 'SELECT+%2A+FROM+%60test_db%60.%60test_table%60+WHERE+%60name%60+%3D+%27foo%27&server=0&lang=en"' + . ' title="foo">foo</a></td>' . "\n" + . '</tr>' . "\n", + 'bulk_links' => [], + 'operations' => [ + 'has_procedure' => false, + 'has_geometry' => false, + 'has_print_link' => true, + 'has_export_link' => true, + 'url_params' => [ + 'db' => $GLOBALS['db'], + 'table' => $GLOBALS['table'], + 'printview' => '1', + 'sql_query' => $query, + 'single_table' => 'true', + 'unlim_num_rows' => 2, + ], + ], + 'db' => $GLOBALS['db'], + 'table' => $GLOBALS['table'], + 'unique_id' => 1234567890, + 'sql_query' => $query, + 'goto' => '', + 'unlim_num_rows' => 2, + 'displaywork' => false, + 'relwork' => false, + 'save_cells_at_once' => false, + 'default_sliders_state' => 'closed', + 'text_dir' => 'ltr', + ]); + + $this->assertEquals($tableTemplate, $actual); + } } diff --git a/test/classes/Engines/BdbTest.php b/test/classes/Engines/BdbTest.php index 1be43f6603..9d43f4ac26 100644 --- a/test/classes/Engines/BdbTest.php +++ b/test/classes/Engines/BdbTest.php @@ -24,6 +24,7 @@ class BdbTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $this->object = new Bdb('bdb'); } diff --git a/test/classes/Engines/BinlogTest.php b/test/classes/Engines/BinlogTest.php index 045dc6d983..1010b0327a 100644 --- a/test/classes/Engines/BinlogTest.php +++ b/test/classes/Engines/BinlogTest.php @@ -22,6 +22,7 @@ class BinlogTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $this->object = new Binlog('binlog'); } diff --git a/test/classes/Engines/InnodbTest.php b/test/classes/Engines/InnodbTest.php index 268ef2e322..62d0597bf1 100644 --- a/test/classes/Engines/InnodbTest.php +++ b/test/classes/Engines/InnodbTest.php @@ -24,6 +24,7 @@ class InnodbTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $this->object = new Innodb('innodb'); } diff --git a/test/classes/Engines/MemoryTest.php b/test/classes/Engines/MemoryTest.php index a24b1e955c..0d09df7f55 100644 --- a/test/classes/Engines/MemoryTest.php +++ b/test/classes/Engines/MemoryTest.php @@ -22,6 +22,7 @@ class MemoryTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $this->object = new Memory('memory'); } diff --git a/test/classes/Engines/MrgMyisamTest.php b/test/classes/Engines/MrgMyisamTest.php index 20ac355d6a..3829b8cc67 100644 --- a/test/classes/Engines/MrgMyisamTest.php +++ b/test/classes/Engines/MrgMyisamTest.php @@ -22,6 +22,7 @@ class MrgMyisamTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $this->object = new MrgMyisam('mrg_myisam'); } diff --git a/test/classes/Engines/MyisamTest.php b/test/classes/Engines/MyisamTest.php index 1ab9145aae..668777c551 100644 --- a/test/classes/Engines/MyisamTest.php +++ b/test/classes/Engines/MyisamTest.php @@ -24,6 +24,7 @@ class MyisamTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $this->object = new Myisam('myisam'); } diff --git a/test/classes/Engines/NdbclusterTest.php b/test/classes/Engines/NdbclusterTest.php index b723987614..1f65215904 100644 --- a/test/classes/Engines/NdbclusterTest.php +++ b/test/classes/Engines/NdbclusterTest.php @@ -22,6 +22,7 @@ class NdbclusterTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $this->object = new Ndbcluster('nbdcluster'); } diff --git a/test/classes/Engines/PbxtTest.php b/test/classes/Engines/PbxtTest.php index 4881791135..28fa15b8fe 100644 --- a/test/classes/Engines/PbxtTest.php +++ b/test/classes/Engines/PbxtTest.php @@ -26,7 +26,7 @@ class PbxtTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); - + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $this->object = new Pbxt('pbxt'); } diff --git a/test/classes/Engines/PerformanceSchemaTest.php b/test/classes/Engines/PerformanceSchemaTest.php index 8829cf4562..1f774a63da 100644 --- a/test/classes/Engines/PerformanceSchemaTest.php +++ b/test/classes/Engines/PerformanceSchemaTest.php @@ -22,6 +22,7 @@ class PerformanceSchemaTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $this->object = new PerformanceSchema('PERFORMANCE_SCHEMA'); } diff --git a/test/classes/ErrorHandlerTest.php b/test/classes/ErrorHandlerTest.php index c540338ac6..c11f5b2abc 100644 --- a/test/classes/ErrorHandlerTest.php +++ b/test/classes/ErrorHandlerTest.php @@ -32,6 +32,8 @@ class ErrorHandlerTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['lang'] = 'en'; + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $this->object = new ErrorHandler(); $_SESSION['errors'] = []; $GLOBALS['server'] = 0; diff --git a/test/classes/ErrorReportTest.php b/test/classes/ErrorReportTest.php index 19373305fc..14db8db1cc 100644 --- a/test/classes/ErrorReportTest.php +++ b/test/classes/ErrorReportTest.php @@ -5,9 +5,11 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests; use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Error; use PhpMyAdmin\ErrorReport; use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Utils\HttpRequest; use PhpMyAdmin\Version; @@ -24,12 +26,21 @@ use const JSON_UNESCAPED_SLASHES; */ class ErrorReportTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var ErrorReport $errorReport */ private $errorReport; protected function setUp(): void { parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; $GLOBALS['cfg']['ServerDefault'] = 1; $GLOBALS['cfg']['ProxyUrl'] = ''; @@ -217,7 +228,7 @@ class ErrorReportTest extends AbstractTestCase ' if (response.success) {', ' // Get the column min value.', ' var min = response.column_data.min', - ' ? \'(\' + Messages.strColumnMin +', + ' ? \'(\' + window.Messages.strColumnMin +', ' this.completion.cm.removeKeyMap(this.keyMap);', ' \' \' + response.column_data.min + \')\'', ' : \'\';', diff --git a/test/classes/ErrorTest.php b/test/classes/ErrorTest.php index 27061e0988..2dab5dad49 100644 --- a/test/classes/ErrorTest.php +++ b/test/classes/ErrorTest.php @@ -120,7 +120,7 @@ class ErrorTest extends AbstractTestCase public function testGetBacktraceDisplay(): void { $this->assertStringContainsString( - 'PHPUnit\Framework\TestResult->run(<Class:PhpMyAdmin\Tests\ErrorTest>)<br>', + 'PHPUnit\Framework\TestResult->run(<Class:PhpMyAdmin\Tests\ErrorTest>)', $this->object->getBacktraceDisplay() ); } @@ -130,10 +130,18 @@ class ErrorTest extends AbstractTestCase */ public function testGetDisplay(): void { + $actual = $this->object->getDisplay(); + $this->assertStringStartsWith( + '<div class="alert alert-danger" role="alert"><p><strong>Warning</strong> in error.txt#15</p>' + . '<img src="themes/dot.gif" title="" alt="" class="icon ic_s_error"> Compile Error' + . '<p class="mt-3"><strong>Backtrace</strong></p><ol class="list-group"><li class="list-group-item">', + $actual + ); $this->assertStringContainsString( - '<div class="alert alert-danger" role="alert"><strong>Warning</strong>', - $this->object->getDisplay() + 'PHPUnit\Framework\TestResult->run(<Class:PhpMyAdmin\Tests\ErrorTest>)</li><li class="list-group-item">', + $actual ); + $this->assertStringEndsWith('</li></ol></div>' . "\n", $actual); } /** diff --git a/test/classes/Export/OptionsTest.php b/test/classes/Export/OptionsTest.php index 0ad51d2d82..42ccd9da87 100644 --- a/test/classes/Export/OptionsTest.php +++ b/test/classes/Export/OptionsTest.php @@ -27,6 +27,9 @@ class OptionsTest extends AbstractTestCase parent::setUp(); parent::setLanguage(); parent::setGlobalConfig(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + parent::loadDbiIntoContainerBuilder(); + $GLOBALS['cfg']['Server']['host'] = 'localhost'; $GLOBALS['cfg']['Server']['user'] = 'pma_user'; $GLOBALS['server'] = 0; @@ -52,12 +55,10 @@ class OptionsTest extends AbstractTestCase public function testGetOptions(): void { - global $cfg; - - $cfg['Export']['method'] = 'XML'; - $cfg['SaveDir'] = '/tmp'; - $cfg['ZipDump'] = false; - $cfg['GZipDump'] = false; + $GLOBALS['cfg']['Export']['method'] = 'XML'; + $GLOBALS['cfg']['SaveDir'] = '/tmp'; + $GLOBALS['cfg']['ZipDump'] = false; + $GLOBALS['cfg']['GZipDump'] = false; $export_type = 'server'; $db = 'PMA'; @@ -110,35 +111,35 @@ class OptionsTest extends AbstractTestCase 'db' => $db, 'table' => $table, 'export_type' => $export_type, - 'export_method' => $cfg['Export']['method'], + 'export_method' => $GLOBALS['cfg']['Export']['method'], 'template_id' => '', ], - 'export_method' => $cfg['Export']['method'], + 'export_method' => $GLOBALS['cfg']['Export']['method'], 'plugins_choice' => $dropdown, 'options' => Plugins::getOptions('Export', $exportList), 'can_convert_kanji' => Encoding::canConvertKanji(), - 'exec_time_limit' => $cfg['ExecTimeLimit'], + 'exec_time_limit' => $GLOBALS['cfg']['ExecTimeLimit'], 'rows' => [], 'has_save_dir' => true, - 'save_dir' => Util::userDir($cfg['SaveDir']), - 'export_is_checked' => $cfg['Export']['quick_export_onserver'], - 'export_overwrite_is_checked' => $cfg['Export']['quick_export_onserver_overwrite'], + 'save_dir' => Util::userDir($GLOBALS['cfg']['SaveDir']), + 'export_is_checked' => $GLOBALS['cfg']['Export']['quick_export_onserver'], + 'export_overwrite_is_checked' => $GLOBALS['cfg']['Export']['quick_export_onserver_overwrite'], 'has_aliases' => false, 'aliases' => [], - 'is_checked_lock_tables' => $cfg['Export']['lock_tables'], - 'is_checked_asfile' => $cfg['Export']['asfile'], - 'is_checked_as_separate_files' => $cfg['Export']['as_separate_files'], - 'is_checked_export' => $cfg['Export']['onserver'], - 'is_checked_export_overwrite' => $cfg['Export']['onserver_overwrite'], - 'is_checked_remember_file_template' => $cfg['Export']['remember_file_template'], + 'is_checked_lock_tables' => $GLOBALS['cfg']['Export']['lock_tables'], + 'is_checked_asfile' => $GLOBALS['cfg']['Export']['asfile'], + 'is_checked_as_separate_files' => $GLOBALS['cfg']['Export']['as_separate_files'], + 'is_checked_export' => $GLOBALS['cfg']['Export']['onserver'], + 'is_checked_export_overwrite' => $GLOBALS['cfg']['Export']['onserver_overwrite'], + 'is_checked_remember_file_template' => $GLOBALS['cfg']['Export']['remember_file_template'], 'repopulate' => '', 'lock_tables' => '', 'is_encoding_supported' => true, 'encodings' => Encoding::listEncodings(), - 'export_charset' => $cfg['Export']['charset'], - 'export_asfile' => $cfg['Export']['asfile'], - 'has_zip' => $cfg['ZipDump'], - 'has_gzip' => $cfg['GZipDump'], + 'export_charset' => $GLOBALS['cfg']['Export']['charset'], + 'export_asfile' => $GLOBALS['cfg']['Export']['asfile'], + 'has_zip' => $GLOBALS['cfg']['ZipDump'], + 'has_gzip' => $GLOBALS['cfg']['GZipDump'], 'selected_compression' => 'none', 'filename_template' => 'user value for test', ]; diff --git a/test/classes/ExportTest.php b/test/classes/ExportTest.php index c86716a73a..5f2f714302 100644 --- a/test/classes/ExportTest.php +++ b/test/classes/ExportTest.php @@ -4,8 +4,14 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests; +use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\Export; use PhpMyAdmin\Plugins\Export\ExportPhparray; +use PhpMyAdmin\Plugins\Export\ExportSql; +use PhpMyAdmin\Transformations; +use stdClass; + +use function htmlspecialchars; /** * @covers \PhpMyAdmin\Export @@ -13,23 +19,10 @@ use PhpMyAdmin\Plugins\Export\ExportPhparray; */ class ExportTest extends AbstractTestCase { - /** @var Export */ - private $export; - - /** - * Sets up the fixture - */ - protected function setUp(): void - { - parent::setUp(); - $this->export = new Export($GLOBALS['dbi']); - } - - /** - * Test for mergeAliases - */ public function testMergeAliases(): void { + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + $export = new Export($GLOBALS['dbi']); $aliases1 = [ 'test_db' => [ 'alias' => 'aliastest', @@ -88,27 +81,30 @@ class ExportTest extends AbstractTestCase ], ], ]; - $actual = $this->export->mergeAliases($aliases1, $aliases2); + $actual = $export->mergeAliases($aliases1, $aliases2); $this->assertEquals($expected, $actual); } - /** - * Test for getFinalFilenameAndMimetypeForFilename - */ public function testGetFinalFilenameAndMimetypeForFilename(): void { - $exportPlugin = new ExportPhparray(); - $finalFileName = $this->export->getFinalFilenameAndMimetypeForFilename($exportPlugin, 'zip', 'myfilename'); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + $export = new Export($GLOBALS['dbi']); + $exportPlugin = new ExportPhparray( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ); + $finalFileName = $export->getFinalFilenameAndMimetypeForFilename($exportPlugin, 'zip', 'myfilename'); $this->assertSame([ 'myfilename.php.zip', 'application/zip', ], $finalFileName); - $finalFileName = $this->export->getFinalFilenameAndMimetypeForFilename($exportPlugin, 'gzip', 'myfilename'); + $finalFileName = $export->getFinalFilenameAndMimetypeForFilename($exportPlugin, 'gzip', 'myfilename'); $this->assertSame([ 'myfilename.php.gz', 'application/x-gzip', ], $finalFileName); - $finalFileName = $this->export->getFinalFilenameAndMimetypeForFilename( + $finalFileName = $export->getFinalFilenameAndMimetypeForFilename( $exportPlugin, 'gzip', 'export.db1.table1.file' @@ -118,4 +114,150 @@ class ExportTest extends AbstractTestCase 'application/x-gzip', ], $finalFileName); } + + public function testExportDatabase(): void + { + $GLOBALS['plugin_param'] = ['export_type' => 'database', 'single_table' => false]; + $GLOBALS['sql_create_view'] = 'something'; + $GLOBALS['output_kanji_conversion'] = false; + $GLOBALS['buffer_needed'] = false; + $GLOBALS['asfile'] = false; + $GLOBALS['sql_structure_or_data'] = 'structure_and_data'; + $GLOBALS['cfg']['Server']['DisableIS'] = false; + $GLOBALS['sql_insert_syntax'] = 'both'; + $GLOBALS['sql_max_query_size'] = '50000'; + + // phpcs:disable Generic.Files.LineLength.TooLong + $dbiDummy = $this->createDbiDummy(); + $dbiDummy->addResult( + 'SELECT TABLE_NAME FROM information_schema.VIEWS WHERE TABLE_SCHEMA = \'test_db\' AND TABLE_NAME = \'test_table\'', + [], + ['TABLE_NAME'] + ); + $dbiDummy->addResult( + 'SELECT *, `TABLE_SCHEMA` AS `Db`, `TABLE_NAME` AS `Name`, `TABLE_TYPE` AS `TABLE_TYPE`, `ENGINE` AS `Engine`, `ENGINE` AS `Type`, `VERSION` AS `Version`, `ROW_FORMAT` AS `Row_format`, `TABLE_ROWS` AS `Rows`, `AVG_ROW_LENGTH` AS `Avg_row_length`, `DATA_LENGTH` AS `Data_length`, `MAX_DATA_LENGTH` AS `Max_data_length`, `INDEX_LENGTH` AS `Index_length`, `DATA_FREE` AS `Data_free`, `AUTO_INCREMENT` AS `Auto_increment`, `CREATE_TIME` AS `Create_time`, `UPDATE_TIME` AS `Update_time`, `CHECK_TIME` AS `Check_time`, `TABLE_COLLATION` AS `Collation`, `CHECKSUM` AS `Checksum`, `CREATE_OPTIONS` AS `Create_options`, `TABLE_COMMENT` AS `Comment` FROM `information_schema`.`TABLES` t WHERE `TABLE_SCHEMA` IN (\'test_db\') AND t.`TABLE_NAME` = \'test_table\' ORDER BY Name ASC', + [['def', 'test_db', 'test_table', 'BASE TABLE', 'InnoDB', '10', 'Dynamic', '3', '5461', '16384', '0', '0', '0', '4', '2011-12-13 14:15:16', null, null, 'utf8mb4_general_ci', null, '', '', '0', 'N', 'test_db', 'test_table', 'BASE TABLE', 'InnoDB', 'InnoDB', '10', 'Dynamic', '3', '5461', '16384', '0', '0', '0', '4', '2011-12-13 14:15:16', null, null, 'utf8mb4_general_ci', null, '', '']], + ['TABLE_CATALOG', 'TABLE_SCHEMA', 'TABLE_NAME', 'TABLE_TYPE', 'ENGINE', 'VERSION', 'ROW_FORMAT', 'TABLE_ROWS', 'AVG_ROW_LENGTH', 'DATA_LENGTH', 'MAX_DATA_LENGTH', 'INDEX_LENGTH', 'DATA_FREE', 'AUTO_INCREMENT', 'CREATE_TIME', 'UPDATE_TIME', 'CHECK_TIME', 'TABLE_COLLATION', 'CHECKSUM', 'CREATE_OPTIONS', 'TABLE_COMMENT', 'MAX_INDEX_LENGTH', 'TEMPORARY', 'Db', 'Name', 'TABLE_TYPE', 'Engine', 'Type', 'Version', 'Row_format', 'Rows', 'Avg_row_length', 'Data_length', 'Max_data_length', 'Index_length', 'Data_free', 'Auto_increment', 'Create_time', 'Update_time', 'Check_time', 'Collation', 'Checksum', 'Create_options', 'Comment'] + ); + $dbiDummy->addResult( + 'SELECT `id`, `name`, `datetimefield` FROM `test_db`.`test_table`', + [ + ['1', 'abcd', '2011-01-20 02:00:02'], + ['2', 'foo', '2010-01-20 02:00:02'], + ['3', 'Abcd', '2012-01-20 02:00:02'], + ], + ['id', 'name', 'datetimefield'] + ); + // phpcs:enable + + $dbi = $this->createDatabaseInterface($dbiDummy); + $GLOBALS['dbi'] = $dbi; + $export = new Export($dbi); + + $export->exportDatabase( + 'test_db', + ['test_table'], + 'structure_and_data', + ['test_table'], + ['test_table'], + new ExportSql(new Relation($dbi), $export, new Transformations()), + "\n", + 'index.php?route=/database/export&db=test_db', + 'database', + false, + true, + false, + false, + [], + '' + ); + + $expected = <<<SQL + +INSERT INTO test_table (id, name, datetimefield) VALUES +('1', 'abcd', '2011-01-20 02:00:02'), +('2', 'foo', '2010-01-20 02:00:02'), +('3', 'Abcd', '2012-01-20 02:00:02'); + +SQL; + + $this->assertSame(htmlspecialchars($expected), $this->getActualOutputForAssertion()); + } + + public function testExportServer(): void + { + $GLOBALS['plugin_param'] = ['export_type' => 'server', 'single_table' => false]; + $GLOBALS['dblist'] = new stdClass(); + $GLOBALS['dblist']->databases = ['test_db']; + $GLOBALS['output_kanji_conversion'] = false; + $GLOBALS['buffer_needed'] = false; + $GLOBALS['asfile'] = false; + $GLOBALS['cfg']['Server']['DisableIS'] = false; + $GLOBALS['sql_structure_or_data'] = 'structure_and_data'; + $GLOBALS['sql_insert_syntax'] = 'both'; + $GLOBALS['sql_max_query_size'] = '50000'; + + // phpcs:disable Generic.Files.LineLength.TooLong + $dbiDummy = $this->createDbiDummy(); + $dbiDummy->addResult( + 'SHOW TABLES FROM `test_db`;', + [['test_table']], + ['Tables_in_test_db'] + ); + $dbiDummy->addResult( + 'SELECT DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = \'test_db\' LIMIT 1', + [['utf8mb4_general_ci']], + ['DEFAULT_COLLATION_NAME'] + ); + $dbiDummy->addResult( + 'SELECT TABLE_NAME FROM information_schema.VIEWS WHERE TABLE_SCHEMA = \'test_db\' AND TABLE_NAME = \'test_table\'', + [], + ['TABLE_NAME'] + ); + $dbiDummy->addResult( + 'SELECT *, `TABLE_SCHEMA` AS `Db`, `TABLE_NAME` AS `Name`, `TABLE_TYPE` AS `TABLE_TYPE`, `ENGINE` AS `Engine`, `ENGINE` AS `Type`, `VERSION` AS `Version`, `ROW_FORMAT` AS `Row_format`, `TABLE_ROWS` AS `Rows`, `AVG_ROW_LENGTH` AS `Avg_row_length`, `DATA_LENGTH` AS `Data_length`, `MAX_DATA_LENGTH` AS `Max_data_length`, `INDEX_LENGTH` AS `Index_length`, `DATA_FREE` AS `Data_free`, `AUTO_INCREMENT` AS `Auto_increment`, `CREATE_TIME` AS `Create_time`, `UPDATE_TIME` AS `Update_time`, `CHECK_TIME` AS `Check_time`, `TABLE_COLLATION` AS `Collation`, `CHECKSUM` AS `Checksum`, `CREATE_OPTIONS` AS `Create_options`, `TABLE_COMMENT` AS `Comment` FROM `information_schema`.`TABLES` t WHERE `TABLE_SCHEMA` IN (\'test_db\') AND t.`TABLE_NAME` = \'test_table\' ORDER BY Name ASC', + [['def', 'test_db', 'test_table', 'BASE TABLE', 'InnoDB', '10', 'Dynamic', '3', '5461', '16384', '0', '0', '0', '4', '2011-12-13 14:15:16', null, null, 'utf8mb4_general_ci', null, '', '', '0', 'N', 'test_db', 'test_table', 'BASE TABLE', 'InnoDB', 'InnoDB', '10', 'Dynamic', '3', '5461', '16384', '0', '0', '0', '4', '2011-12-13 14:15:16', null, null, 'utf8mb4_general_ci', null, '', '']], + ['TABLE_CATALOG', 'TABLE_SCHEMA', 'TABLE_NAME', 'TABLE_TYPE', 'ENGINE', 'VERSION', 'ROW_FORMAT', 'TABLE_ROWS', 'AVG_ROW_LENGTH', 'DATA_LENGTH', 'MAX_DATA_LENGTH', 'INDEX_LENGTH', 'DATA_FREE', 'AUTO_INCREMENT', 'CREATE_TIME', 'UPDATE_TIME', 'CHECK_TIME', 'TABLE_COLLATION', 'CHECKSUM', 'CREATE_OPTIONS', 'TABLE_COMMENT', 'MAX_INDEX_LENGTH', 'TEMPORARY', 'Db', 'Name', 'TABLE_TYPE', 'Engine', 'Type', 'Version', 'Row_format', 'Rows', 'Avg_row_length', 'Data_length', 'Max_data_length', 'Index_length', 'Data_free', 'Auto_increment', 'Create_time', 'Update_time', 'Check_time', 'Collation', 'Checksum', 'Create_options', 'Comment'] + ); + $dbiDummy->addResult( + 'SELECT `id`, `name`, `datetimefield` FROM `test_db`.`test_table`', + [ + ['1', 'abcd', '2011-01-20 02:00:02'], + ['2', 'foo', '2010-01-20 02:00:02'], + ['3', 'Abcd', '2012-01-20 02:00:02'], + ], + ['id', 'name', 'datetimefield'] + ); + // phpcs:enable + + $dbi = $this->createDatabaseInterface($dbiDummy); + $GLOBALS['dbi'] = $dbi; + $export = new Export($dbi); + + $export->exportServer( + ['test_db'], + 'structure_and_data', + new ExportSql(new Relation($dbi), $export, new Transformations()), + "\n", + 'index.php?route=/server/export', + 'server', + false, + true, + false, + false, + [], + '' + ); + + $expected = <<<SQL +CREATE DATABASE IF NOT EXISTS test_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;USE test_db; +INSERT INTO test_table (id, name, datetimefield) VALUES +('1', 'abcd', '2011-01-20 02:00:02'), +('2', 'foo', '2010-01-20 02:00:02'), +('3', 'Abcd', '2012-01-20 02:00:02'); + +SQL; + + $this->assertSame(htmlspecialchars($expected), $this->getActualOutputForAssertion()); + } } diff --git a/test/classes/FooterTest.php b/test/classes/FooterTest.php index 679734704f..074495acad 100644 --- a/test/classes/FooterTest.php +++ b/test/classes/FooterTest.php @@ -7,6 +7,7 @@ namespace PhpMyAdmin\Tests; use ArrayIterator; use PhpMyAdmin\ErrorHandler; use PhpMyAdmin\Footer; +use PhpMyAdmin\Template; use function json_encode; @@ -31,6 +32,7 @@ class FooterTest extends AbstractTestCase parent::setLanguage(); parent::setGlobalConfig(); parent::setTheme(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $_SERVER['SCRIPT_NAME'] = 'index.php'; $GLOBALS['PMA_PHP_SELF'] = 'index.php'; $GLOBALS['db'] = ''; @@ -123,8 +125,11 @@ class FooterTest extends AbstractTestCase { $footer = new Footer(); $footer->setAjax(true); + $template = new Template(); $this->assertEquals( - '', + $template->render('modals/function_confirm') . "\n" + . $template->render('modals/add_index') . "\n" + . $template->render('modals/page_settings') . "\n", $footer->getDisplay() ); } @@ -162,8 +167,12 @@ class FooterTest extends AbstractTestCase { $footer = new Footer(); $footer->setMinimal(); + $template = new Template(); $this->assertEquals( - " </div>\n </body>\n</html>\n", + $template->render('modals/function_confirm') . "\n" + . $template->render('modals/add_index') . "\n" + . $template->render('modals/page_settings') + . "\n </div>\n </body>\n</html>\n", $footer->getDisplay() ); } diff --git a/test/classes/Gis/GisGeometryCollectionTest.php b/test/classes/Gis/GisGeometryCollectionTest.php index 42b366cda3..50ecca2b0c 100644 --- a/test/classes/Gis/GisGeometryCollectionTest.php +++ b/test/classes/Gis/GisGeometryCollectionTest.php @@ -14,6 +14,8 @@ use function preg_match; /** * @covers \PhpMyAdmin\Gis\GisGeometryCollection + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled */ class GisGeometryCollectionTest extends AbstractTestCase { diff --git a/test/classes/Gis/GisLineStringTest.php b/test/classes/Gis/GisLineStringTest.php index fbfa38029f..6f766e56b2 100644 --- a/test/classes/Gis/GisLineStringTest.php +++ b/test/classes/Gis/GisLineStringTest.php @@ -12,6 +12,8 @@ use function preg_match; /** * @covers \PhpMyAdmin\Gis\GisLineString + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled */ class GisLineStringTest extends GisGeomTestCase { diff --git a/test/classes/Gis/GisMultiLineStringTest.php b/test/classes/Gis/GisMultiLineStringTest.php index 0afc3680e0..85c31f75a0 100644 --- a/test/classes/Gis/GisMultiLineStringTest.php +++ b/test/classes/Gis/GisMultiLineStringTest.php @@ -12,6 +12,8 @@ use function preg_match; /** * @covers \PhpMyAdmin\Gis\GisMultiLineString + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled */ class GisMultiLineStringTest extends GisGeomTestCase { diff --git a/test/classes/Gis/GisMultiPointTest.php b/test/classes/Gis/GisMultiPointTest.php index 5ec5dcebcf..e7ed5134e2 100644 --- a/test/classes/Gis/GisMultiPointTest.php +++ b/test/classes/Gis/GisMultiPointTest.php @@ -12,6 +12,8 @@ use function preg_match; /** * @covers \PhpMyAdmin\Gis\GisMultiPoint + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled */ class GisMultiPointTest extends GisGeomTestCase { diff --git a/test/classes/Gis/GisMultiPolygonTest.php b/test/classes/Gis/GisMultiPolygonTest.php index ac388a790a..d91c88d722 100644 --- a/test/classes/Gis/GisMultiPolygonTest.php +++ b/test/classes/Gis/GisMultiPolygonTest.php @@ -12,6 +12,8 @@ use function preg_match; /** * @covers \PhpMyAdmin\Gis\GisMultiPolygon + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled */ class GisMultiPolygonTest extends GisGeomTestCase { diff --git a/test/classes/Gis/GisPointTest.php b/test/classes/Gis/GisPointTest.php index 8f5192b09d..e18c03990e 100644 --- a/test/classes/Gis/GisPointTest.php +++ b/test/classes/Gis/GisPointTest.php @@ -10,6 +10,8 @@ use TCPDF; /** * @covers \PhpMyAdmin\Gis\GisPoint + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled */ class GisPointTest extends GisGeomTestCase { diff --git a/test/classes/Gis/GisPolygonTest.php b/test/classes/Gis/GisPolygonTest.php index 98598e9b92..037b18fbe7 100644 --- a/test/classes/Gis/GisPolygonTest.php +++ b/test/classes/Gis/GisPolygonTest.php @@ -12,6 +12,8 @@ use function preg_match; /** * @covers \PhpMyAdmin\Gis\GisPolygon + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled */ class GisPolygonTest extends GisGeomTestCase { diff --git a/test/classes/HeaderTest.php b/test/classes/HeaderTest.php index 20a17bd698..386d14598b 100644 --- a/test/classes/HeaderTest.php +++ b/test/classes/HeaderTest.php @@ -26,6 +26,7 @@ class HeaderTest extends AbstractTestCase parent::setUp(); parent::setTheme(); parent::setLanguage(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['message'] = 'phpmyadminmessage'; @@ -100,7 +101,7 @@ class HeaderTest extends AbstractTestCase { $header = new Header(); $this->assertStringContainsString( - 'CommonParams.setAll', + 'window.CommonParams.setAll', $header->getJsParamsCode() ); } @@ -148,16 +149,14 @@ class HeaderTest extends AbstractTestCase string $expectedXCsp, string $expectedWebKitCsp ): void { - global $cfg; - $header = new Header(); $date = (string) gmdate(DATE_RFC1123); - $cfg['AllowThirdPartyFraming'] = $frameOptions; - $cfg['CSPAllow'] = $cspAllow; - $cfg['CaptchaLoginPrivateKey'] = $privateKey; - $cfg['CaptchaLoginPublicKey'] = $publicKey; - $cfg['CaptchaCsp'] = $captchaCsp; + $GLOBALS['cfg']['AllowThirdPartyFraming'] = $frameOptions; + $GLOBALS['cfg']['CSPAllow'] = $cspAllow; + $GLOBALS['cfg']['CaptchaLoginPrivateKey'] = $privateKey; + $GLOBALS['cfg']['CaptchaLoginPublicKey'] = $publicKey; + $GLOBALS['cfg']['CaptchaCsp'] = $captchaCsp; $expected = [ 'X-Frame-Options' => $expectedFrameOptions, diff --git a/test/classes/Html/GeneratorTest.php b/test/classes/Html/GeneratorTest.php index f483c8c008..39f3ee6b8a 100644 --- a/test/classes/Html/GeneratorTest.php +++ b/test/classes/Html/GeneratorTest.php @@ -47,7 +47,6 @@ class GeneratorTest extends AbstractTestCase */ public function testGetDbLinkNull(): void { - global $cfg; $GLOBALS['db'] = 'test_db'; $GLOBALS['server'] = 99; $database = $GLOBALS['db']; @@ -178,7 +177,7 @@ class GeneratorTest extends AbstractTestCase $target = 'docu'; $lang = _pgettext('PHP documentation language', 'en'); - $expected = '<a href="./url.php?url=https%3A%2F%2Fwww.php.net%2Fmanual%2F' . $lang + $expected = '<a href="index.php?route=/url&url=https%3A%2F%2Fwww.php.net%2Fmanual%2F' . $lang . '%2F' . $target . '" target="documentation">' . '<img src="themes/dot.gif" title="' . __('Documentation') . '" alt="' . __('Documentation') . '" class="icon ic_b_help"></a>'; @@ -283,14 +282,15 @@ class GeneratorTest extends AbstractTestCase ], [ [ - 'url.php?url=http://phpmyadmin.net/', + 'index.php?route=/url&url=http://phpmyadmin.net/', null, 'text', [], '_blank', ], 1000, - '<a href="url.php?url=http://phpmyadmin.net/" target="_blank" rel="noopener noreferrer">text</a>', + '<a href="index.php?route=/url&url=http://phpmyadmin.net/" target="_blank"' + . ' rel="noopener noreferrer">text</a>', ], [ [ @@ -355,19 +355,17 @@ class GeneratorTest extends AbstractTestCase */ public function testGetServerSSL(): void { - global $cfg; - $sslNotUsed = '<span class="">SSL is not being used</span>' - . ' <a href="./url.php?url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2Flatest%2Fsetup.html%23ssl"' + . ' <a href="index.php?route=/url&url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2Flatest%2Fsetup.html%23ssl"' . ' target="documentation"><img src="themes/dot.gif" title="Documentation" alt="Documentation"' . ' class="icon ic_b_help"></a>'; $sslNotUsedCaution = '<span class="text-danger">SSL is not being used</span>' - . ' <a href="./url.php?url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2Flatest%2Fsetup.html%23ssl"' + . ' <a href="index.php?route=/url&url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2Flatest%2Fsetup.html%23ssl"' . ' target="documentation"><img src="themes/dot.gif" title="Documentation" alt="Documentation"' . ' class="icon ic_b_help"></a>'; - $cfg['Server'] = [ + $GLOBALS['cfg']['Server'] = [ 'ssl' => false, 'host' => '127.0.0.1', ]; @@ -376,29 +374,29 @@ class GeneratorTest extends AbstractTestCase Generator::getServerSSL() ); - $cfg['Server'] = [ + $GLOBALS['cfg']['Server'] = [ 'ssl' => false, 'host' => 'custom.host', ]; - $cfg['MysqlSslWarningSafeHosts'] = ['localhost', '127.0.0.1']; + $GLOBALS['cfg']['MysqlSslWarningSafeHosts'] = ['localhost', '127.0.0.1']; $this->assertEquals( $sslNotUsedCaution, Generator::getServerSSL() ); - $cfg['Server'] = [ + $GLOBALS['cfg']['Server'] = [ 'ssl' => false, 'host' => 'custom.host', ]; - $cfg['MysqlSslWarningSafeHosts'] = ['localhost', '127.0.0.1', 'custom.host']; + $GLOBALS['cfg']['MysqlSslWarningSafeHosts'] = ['localhost', '127.0.0.1', 'custom.host']; $this->assertEquals( $sslNotUsed, Generator::getServerSSL() ); - $cfg['Server'] = [ + $GLOBALS['cfg']['Server'] = [ 'ssl' => false, 'ssl_verify' => true, 'host' => 'custom.host', @@ -409,7 +407,7 @@ class GeneratorTest extends AbstractTestCase Generator::getServerSSL() ); - $cfg['Server'] = [ + $GLOBALS['cfg']['Server'] = [ 'ssl' => true, 'ssl_verify' => false, 'host' => 'custom.host', @@ -417,13 +415,13 @@ class GeneratorTest extends AbstractTestCase $this->assertEquals( '<span class="text-danger">SSL is used with disabled verification</span>' - . ' <a href="./url.php?url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2Flatest%2Fsetup.html%23ssl"' + . ' <a href="index.php?route=/url&url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2Flatest%2Fsetup.html%23ssl"' . ' target="documentation"><img src="themes/dot.gif" title="Documentation" alt="Documentation"' . ' class="icon ic_b_help"></a>', Generator::getServerSSL() ); - $cfg['Server'] = [ + $GLOBALS['cfg']['Server'] = [ 'ssl' => true, 'ssl_verify' => true, 'host' => 'custom.host', @@ -431,13 +429,13 @@ class GeneratorTest extends AbstractTestCase $this->assertEquals( '<span class="text-danger">SSL is used without certification authority</span>' - . ' <a href="./url.php?url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2Flatest%2Fsetup.html%23ssl"' + . ' <a href="index.php?route=/url&url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2Flatest%2Fsetup.html%23ssl"' . ' target="documentation"><img src="themes/dot.gif" title="Documentation" alt="Documentation"' . ' class="icon ic_b_help"></a>', Generator::getServerSSL() ); - $cfg['Server'] = [ + $GLOBALS['cfg']['Server'] = [ 'ssl' => true, 'ssl_verify' => true, 'ssl_ca' => '/etc/ssl/ca.crt', @@ -446,7 +444,7 @@ class GeneratorTest extends AbstractTestCase $this->assertEquals( '<span class="">SSL is used</span>' - . ' <a href="./url.php?url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2Flatest%2Fsetup.html%23ssl"' + . ' <a href="index.php?route=/url&url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2Flatest%2Fsetup.html%23ssl"' . ' target="documentation"><img src="themes/dot.gif" title="Documentation" alt="Documentation"' . ' class="icon ic_b_help"></a>', Generator::getServerSSL() diff --git a/test/classes/Html/MySQLDocumentationTest.php b/test/classes/Html/MySQLDocumentationTest.php index 9057667c5c..7e84e66501 100644 --- a/test/classes/Html/MySQLDocumentationTest.php +++ b/test/classes/Html/MySQLDocumentationTest.php @@ -18,7 +18,7 @@ class MySQLDocumentationTest extends AbstractTestCase $GLOBALS['cfg']['ServerDefault'] = 1; $this->assertEquals( - '<a href="./url.php?url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen' + '<a href="index.php?route=/url&url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen' . '%2Flatest%2Fpage.html%23anchor" target="documentation"><img src="themes/dot.gif"' . ' title="Documentation" alt="Documentation" class="icon ic_b_help"></a>', MySQLDocumentation::showDocumentation('page', 'anchor') diff --git a/test/classes/Http/ServerRequestTest.php b/test/classes/Http/ServerRequestTest.php new file mode 100644 index 0000000000..3cabf9ba81 --- /dev/null +++ b/test/classes/Http/ServerRequestTest.php @@ -0,0 +1,50 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Http; + +use PhpMyAdmin\Http\ServerRequest; +use PHPUnit\Framework\TestCase; +use Psr\Http\Message\ServerRequestInterface; + +/** + * @covers \PhpMyAdmin\Http\ServerRequest + */ +class ServerRequestTest extends TestCase +{ + /** + * @param array<string, string> $get + * @param array<string, string> $post + * + * @dataProvider providerForTestGetRoute + */ + public function testGetRoute(string $expected, array $get, array $post): void + { + $requestStub = $this->createStub(ServerRequestInterface::class); + $requestStub->method('getQueryParams')->willReturn($get); + $requestStub->method('getParsedBody')->willReturn($post); + $request = new ServerRequest($requestStub); + $this->assertSame($expected, $request->getRoute()); + } + + /** + * @return array<int, array<int, array<string, string>|string>> + * @psalm-return array<int, array{string, array<string, string>, array<string, string>}> + */ + public function providerForTestGetRoute(): iterable + { + return [ + ['/', [], []], + ['/test', ['route' => '/test'], []], + ['/test', [], ['route' => '/test']], + ['/test-get', ['route' => '/test-get'], ['route' => '/test-post']], + ['/database/structure', ['db' => 'db'], []], + ['/sql', ['db' => 'db', 'table' => 'table'], []], + ['/test', ['route' => '/test', 'db' => 'db'], []], + ['/test', ['route' => '/test', 'db' => 'db', 'table' => 'table'], []], + ['/', [], ['db' => 'db']], + ['/', [], ['db' => 'db', 'table' => 'table']], + ]; + } +} diff --git a/test/classes/Import/SimulateDmlTest.php b/test/classes/Import/SimulateDmlTest.php index f756119e02..276aa6cdd0 100644 --- a/test/classes/Import/SimulateDmlTest.php +++ b/test/classes/Import/SimulateDmlTest.php @@ -5,10 +5,12 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Import; use PhpMyAdmin\Core; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Html\Generator; use PhpMyAdmin\Import\SimulateDml; use PhpMyAdmin\SqlParser\Parser; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Url; /** @@ -16,15 +18,32 @@ use PhpMyAdmin\Url; */ class SimulateDmlTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + + protected function setUp(): void + { + parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; + } + /** * @dataProvider providerForTestGetMatchedRows */ public function testGetMatchedRows(string $sqlQuery, string $simulatedQuery): void { $GLOBALS['db'] = 'PMA'; - $object = new SimulateDml($this->dbi); + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addSelectDb('PMA'); + $dbi = $this->createDatabaseInterface($dummyDbi); + + $object = new SimulateDml($dbi); $parser = new Parser($sqlQuery); - $this->dummyDbi->addSelectDb('PMA'); $simulatedData = $object->getMatchedRows($sqlQuery, $parser, $parser->statements[0]); @@ -34,7 +53,7 @@ class SimulateDmlTest extends AbstractTestCase 'sql_signature' => Core::signSqlQuery($simulatedQuery), ]); - $this->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllSelectsConsumed(); $this->assertEquals([ 'sql_query' => Generator::formatSql($sqlQuery), 'matched_rows' => 2, diff --git a/test/classes/ImportTest.php b/test/classes/ImportTest.php index 6cd7ea0225..a7d17eebfb 100644 --- a/test/classes/ImportTest.php +++ b/test/classes/ImportTest.php @@ -24,8 +24,15 @@ class ImportTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['cfg']['ServerDefault'] = ''; + $GLOBALS['complete_query'] = null; + $GLOBALS['display_query'] = null; + $GLOBALS['skip_queries'] = null; + $GLOBALS['max_sql_len'] = null; + $GLOBALS['sql_query_disabled'] = null; + $GLOBALS['executed_queries'] = null; $this->import = new Import(); } @@ -34,40 +41,38 @@ class ImportTest extends AbstractTestCase */ public function testCheckTimeout(): void { - global $timestamp, $maximum_time, $timeout_passed; - //Reinit values. - $timestamp = time(); - $maximum_time = 0; - $timeout_passed = false; + $GLOBALS['timestamp'] = time(); + $GLOBALS['maximum_time'] = 0; + $GLOBALS['timeout_passed'] = false; $this->assertFalse($this->import->checkTimeout()); //Reinit values. - $timestamp = time(); - $maximum_time = 0; - $timeout_passed = true; + $GLOBALS['timestamp'] = time(); + $GLOBALS['maximum_time'] = 0; + $GLOBALS['timeout_passed'] = true; $this->assertFalse($this->import->checkTimeout()); //Reinit values. - $timestamp = time(); - $maximum_time = 30; - $timeout_passed = true; + $GLOBALS['timestamp'] = time(); + $GLOBALS['maximum_time'] = 30; + $GLOBALS['timeout_passed'] = true; $this->assertTrue($this->import->checkTimeout()); //Reinit values. - $timestamp = time() - 15; - $maximum_time = 30; - $timeout_passed = false; + $GLOBALS['timestamp'] = time() - 15; + $GLOBALS['maximum_time'] = 30; + $GLOBALS['timeout_passed'] = false; $this->assertFalse($this->import->checkTimeout()); //Reinit values. - $timestamp = time() - 60; - $maximum_time = 30; - $timeout_passed = false; + $GLOBALS['timestamp'] = time() - 60; + $GLOBALS['maximum_time'] = 30; + $GLOBALS['timeout_passed'] = false; $this->assertTrue($this->import->checkTimeout()); } @@ -552,56 +557,27 @@ class ImportTest extends AbstractTestCase $GLOBALS['run_query'] = true; $sqlData = []; - $query = 'SELECT 1'; - $full = 'SELECT 1'; - - $this->import->runQuery($query, $full, $sqlData); + $this->import->runQuery('SELECT 1', $sqlData); $this->assertSame([], $sqlData); - $this->assertSame([ - 'sql' => 'SELECT 1;', - 'full' => 'SELECT 1;', - ], $GLOBALS['import_run_buffer']); - $this->assertNull($GLOBALS['sql_query']); + $this->assertSame('', $GLOBALS['sql_query']); $this->assertNull($GLOBALS['complete_query']); $this->assertNull($GLOBALS['display_query']); - $query = 'SELECT 2'; - $full = 'SELECT 2'; + $this->import->runQuery('SELECT 2', $sqlData); - $this->import->runQuery($query, $full, $sqlData); - - $this->assertSame([ - 'valid_sql' => ['SELECT 1;'], - 'valid_full' => ['SELECT 1;'], - 'valid_queries' => 1, - ], $sqlData); - $this->assertSame([ - 'sql' => 'SELECT 2;', - 'full' => 'SELECT 2;', - ], $GLOBALS['import_run_buffer']); + $this->assertSame(['SELECT 1;'], $sqlData); $this->assertSame('SELECT 1;', $GLOBALS['sql_query']); $this->assertSame('SELECT 1;', $GLOBALS['complete_query']); $this->assertSame('SELECT 1;', $GLOBALS['display_query']); - $query = ''; - $full = ''; - - $this->import->runQuery($query, $full, $sqlData); + $this->import->runQuery('', $sqlData); $this->assertSame([ - 'valid_sql' => [ - 'SELECT 1;', - 'SELECT 2;', - ], - 'valid_full' => [ - 'SELECT 1;', - 'SELECT 2;', - ], - 'valid_queries' => 2, + 'SELECT 1;', + 'SELECT 2;', ], $sqlData); - $this->assertArrayNotHasKey('import_run_buffer', $GLOBALS); $this->assertSame('SELECT 2;', $GLOBALS['sql_query']); $this->assertSame('SELECT 1;SELECT 2;', $GLOBALS['complete_query']); $this->assertSame('SELECT 1;SELECT 2;', $GLOBALS['display_query']); diff --git a/test/classes/InsertEditTest.php b/test/classes/InsertEditTest.php index 13ee204b74..af43d48400 100644 --- a/test/classes/InsertEditTest.php +++ b/test/classes/InsertEditTest.php @@ -4,14 +4,19 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests; +use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\Core; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Dbal\Warning; use PhpMyAdmin\FieldMetadata; +use PhpMyAdmin\FileListing; use PhpMyAdmin\InsertEdit; use PhpMyAdmin\ResponseRenderer; use PhpMyAdmin\Table; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\DummyResult; +use PhpMyAdmin\Transformations; use PhpMyAdmin\Url; use ReflectionProperty; use stdClass; @@ -33,6 +38,12 @@ use const MYSQLI_TYPE_TINY; */ class InsertEditTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var InsertEdit */ private $insertEdit; @@ -45,6 +56,9 @@ class InsertEditTest extends AbstractTestCase parent::setLanguage(); parent::setGlobalConfig(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; $GLOBALS['PMA_PHP_SELF'] = 'index.php'; $GLOBALS['cfg']['ServerDefault'] = 1; @@ -72,7 +86,13 @@ class InsertEditTest extends AbstractTestCase $GLOBALS['cfg']['Confirm'] = true; $GLOBALS['cfg']['LoginCookieValidity'] = 1440; $GLOBALS['cfg']['enable_drag_drop_import'] = true; - $this->insertEdit = new InsertEdit($GLOBALS['dbi']); + $this->insertEdit = new InsertEdit( + $this->dbi, + new Relation($this->dbi), + new Transformations(), + new FileListing(), + new Template() + ); } /** @@ -200,7 +220,13 @@ class InsertEditTest extends AbstractTestCase ); $GLOBALS['dbi'] = $dbi; - $this->insertEdit = new InsertEdit($GLOBALS['dbi']); + $this->insertEdit = new InsertEdit( + $GLOBALS['dbi'], + new Relation($GLOBALS['dbi']), + new Transformations(), + new FileListing(), + new Template() + ); $result = $this->callFunction( $this->insertEdit, InsertEdit::class, @@ -254,7 +280,13 @@ class InsertEditTest extends AbstractTestCase ->will($this->returnValue($meta_arr)); $GLOBALS['dbi'] = $dbi; - $this->insertEdit = new InsertEdit($GLOBALS['dbi']); + $this->insertEdit = new InsertEdit( + $GLOBALS['dbi'], + new Relation($GLOBALS['dbi']), + new Transformations(), + new FileListing(), + new Template() + ); $result = $this->callFunction( $this->insertEdit, @@ -363,7 +395,13 @@ class InsertEditTest extends AbstractTestCase ->will($this->returnValue($resultStub)); $GLOBALS['dbi'] = $dbi; - $this->insertEdit = new InsertEdit($GLOBALS['dbi']); + $this->insertEdit = new InsertEdit( + $GLOBALS['dbi'], + new Relation($GLOBALS['dbi']), + new Transformations(), + new FileListing(), + new Template() + ); $result = $this->callFunction( $this->insertEdit, @@ -1107,7 +1145,7 @@ class InsertEditTest extends AbstractTestCase ); $this->assertEquals( - "a\n\na\n" + "a\na\n" . '<textarea name="fieldsb" class="char charField" ' . 'data-maxlength="25" rows="7" cols="1" dir="/" ' . 'id="field_1_3" c tabindex="34" data-type="CHAR">' @@ -1416,7 +1454,13 @@ class InsertEditTest extends AbstractTestCase ->getMock(); $GLOBALS['dbi'] = $dbi; - $this->insertEdit = new InsertEdit($GLOBALS['dbi']); + $this->insertEdit = new InsertEdit( + $GLOBALS['dbi'], + new Relation($GLOBALS['dbi']), + new Transformations(), + new FileListing(), + new Template() + ); $current_row['f'] = '123'; $extracted_columnspec['spec_in_brackets'] = '20'; @@ -1641,7 +1685,13 @@ class InsertEditTest extends AbstractTestCase $GLOBALS['dbi'] = $dbi; $GLOBALS['db'] = 'db'; $GLOBALS['table'] = 'table'; - $this->insertEdit = new InsertEdit($GLOBALS['dbi']); + $this->insertEdit = new InsertEdit( + $GLOBALS['dbi'], + new Relation($GLOBALS['dbi']), + new Transformations(), + new FileListing(), + new Template() + ); $this->insertEdit->setSessionForEditNext('`a` = 2'); $this->assertEquals('CONCAT(`table`.`orgname`) IS NULL', $_SESSION['edit_next']); @@ -1740,7 +1790,13 @@ class InsertEditTest extends AbstractTestCase $GLOBALS['cfg']['IgnoreMultiSubmitErrors'] = false; $_POST['submit_type'] = ''; - $this->insertEdit = new InsertEdit($GLOBALS['dbi']); + $this->insertEdit = new InsertEdit( + $GLOBALS['dbi'], + new Relation($GLOBALS['dbi']), + new Transformations(), + new FileListing(), + new Template() + ); $result = $this->insertEdit->executeSqlQuery([], $query); $this->assertEquals(['sql_query' => 'SELECT * FROM `test_db`.`test_table`;'], $result[0]); @@ -1761,7 +1817,13 @@ class InsertEditTest extends AbstractTestCase $GLOBALS['cfg']['IgnoreMultiSubmitErrors'] = true; $_POST['submit_type'] = ''; - $this->insertEdit = new InsertEdit($GLOBALS['dbi']); + $this->insertEdit = new InsertEdit( + $GLOBALS['dbi'], + new Relation($GLOBALS['dbi']), + new Transformations(), + new FileListing(), + new Template() + ); $result = $this->insertEdit->executeSqlQuery([], $query); $this->assertEquals(['sql_query' => 'SELECT * FROM `test_db`.`test_table`;'], $result[0]); @@ -1788,7 +1850,13 @@ class InsertEditTest extends AbstractTestCase ->will($this->returnValue($warnings)); $GLOBALS['dbi'] = $dbi; - $this->insertEdit = new InsertEdit($GLOBALS['dbi']); + $this->insertEdit = new InsertEdit( + $GLOBALS['dbi'], + new Relation($GLOBALS['dbi']), + new Transformations(), + new FileListing(), + new Template() + ); $result = $this->callFunction( $this->insertEdit, @@ -1833,7 +1901,13 @@ class InsertEditTest extends AbstractTestCase ->will($this->returnValue('2')); $GLOBALS['dbi'] = $dbi; - $this->insertEdit = new InsertEdit($GLOBALS['dbi']); + $this->insertEdit = new InsertEdit( + $GLOBALS['dbi'], + new Relation($GLOBALS['dbi']), + new Transformations(), + new FileListing(), + new Template() + ); $result = $this->insertEdit->getDisplayValueForForeignTableColumn('=1', $map, 'f'); @@ -2151,7 +2225,7 @@ class InsertEditTest extends AbstractTestCase public function testGetCurrentValueAsAnArrayForMultipleEdit(): void { // case 2 - $multi_edit_funcs = ['UUID']; + $multi_edit_function = 'UUID'; $this->dummyDbi->addResult( 'SELECT UUID()', @@ -2159,76 +2233,57 @@ class InsertEditTest extends AbstractTestCase ['uuid1234'],// Minimal working setup for 2FA ] ); - $this->insertEdit = new InsertEdit($GLOBALS['dbi']); + + $this->insertEdit = new InsertEdit( + $GLOBALS['dbi'], + new Relation($GLOBALS['dbi']), + new Transformations(), + new FileListing(), + new Template() + ); $result = $this->insertEdit->getCurrentValueAsAnArrayForMultipleEdit( - $multi_edit_funcs, - [], - [], - 'currVal', - [], - [], - [], - '0' + $multi_edit_function, + null, + 'currVal' ); $this->assertEquals("'uuid1234'", $result); // case 3 - $multi_edit_funcs = ['AES_ENCRYPT']; - $multi_edit_salt = ['']; + $multi_edit_function = 'AES_ENCRYPT'; + $multi_edit_salt = ''; $result = $this->insertEdit->getCurrentValueAsAnArrayForMultipleEdit( - $multi_edit_funcs, + $multi_edit_function, $multi_edit_salt, - [], - "'", - [], - ['func'], - ['func'], - '0' + "'" ); $this->assertEquals("AES_ENCRYPT('\\'','')", $result); // case 4 - $multi_edit_funcs = ['func']; - $multi_edit_salt = []; + $multi_edit_function = 'ABS'; $result = $this->insertEdit->getCurrentValueAsAnArrayForMultipleEdit( - $multi_edit_funcs, - $multi_edit_salt, - [], - "'", - [], - ['func'], - ['func'], - '0' + $multi_edit_function, + null, + "'" ); - $this->assertEquals("func('\\'')", $result); + $this->assertEquals("ABS('\\'')", $result); // case 5 - $multi_edit_funcs = ['RAND']; + $multi_edit_function = 'RAND'; $result = $this->insertEdit->getCurrentValueAsAnArrayForMultipleEdit( - $multi_edit_funcs, - $multi_edit_salt, - [], - '', - [], - ['func'], - ['RAND'], - '0' + $multi_edit_function, + null, + '' ); $this->assertEquals('RAND()', $result); // case 6 - $multi_edit_funcs = ['PHP_PASSWORD_HASH']; + $multi_edit_function = 'PHP_PASSWORD_HASH'; $result = $this->insertEdit->getCurrentValueAsAnArrayForMultipleEdit( - $multi_edit_funcs, - $multi_edit_salt, - [], - "a'c", - [], - [], - [], - '0' + $multi_edit_function, + null, + "a'c" ); $this->assertTrue(password_verify("a'c", mb_substr($result, 1, -1))); } @@ -2238,7 +2293,13 @@ class InsertEditTest extends AbstractTestCase */ public function testGetCurrentValueForDifferentTypes(): void { - $this->insertEdit = new InsertEdit($GLOBALS['dbi']); + $this->insertEdit = new InsertEdit( + $GLOBALS['dbi'], + new Relation($GLOBALS['dbi']), + new Transformations(), + new FileListing(), + new Template() + ); $result = $this->insertEdit->getCurrentValueForDifferentTypes( '123', @@ -2246,15 +2307,13 @@ class InsertEditTest extends AbstractTestCase [], '', [], - 0, [], [], [], true, true, '', - 'test_table', - [] + 'test_table' ); $this->assertEquals('123', $result); @@ -2266,15 +2325,13 @@ class InsertEditTest extends AbstractTestCase ['test'], '', [1], - 0, [], [], [], true, true, '', - 'test_table', - [] + 'test_table' ); $this->assertEquals('NULL', $result); @@ -2286,15 +2343,13 @@ class InsertEditTest extends AbstractTestCase ['test'], '', [], - 0, [], [], [], true, true, '', - 'test_table', - [] + 'test_table' ); $this->assertEquals("''", $result); @@ -2307,15 +2362,13 @@ class InsertEditTest extends AbstractTestCase ['set'], '', [], - 0, [], [], [], true, true, '', - 'test_table', - [] + 'test_table' ); $this->assertEquals("''", $result); @@ -2327,15 +2380,13 @@ class InsertEditTest extends AbstractTestCase ['protected'], '', [], - 0, ['name'], [], [], true, true, '`id` = 4', - 'test_table', - [] + 'test_table' ); $this->assertEquals('0x313031', $result); @@ -2347,15 +2398,13 @@ class InsertEditTest extends AbstractTestCase ['protected'], '', [], - 0, ['a'], [], [], true, true, '', - 'test_table', - [] + 'test_table' ); $this->assertEquals('', $result); @@ -2367,15 +2416,13 @@ class InsertEditTest extends AbstractTestCase ['bit'], '20\'12', [], - 0, ['a'], [], [], true, true, '', - 'test_table', - [] + 'test_table' ); $this->assertEquals("b'00010'", $result); @@ -2387,15 +2434,13 @@ class InsertEditTest extends AbstractTestCase ['date'], '20\'12', [], - 0, ['a'], [], [], true, true, '', - 'test_table', - [] + 'test_table' ); $this->assertEquals("'20\\'12'", $result); @@ -2408,15 +2453,13 @@ class InsertEditTest extends AbstractTestCase ['set'], '', [], - 0, [], [1], [], true, true, '', - 'test_table', - [] + 'test_table' ); $this->assertEquals('NULL', $result); @@ -2428,15 +2471,13 @@ class InsertEditTest extends AbstractTestCase ['protected'], '', [], - 0, ['a'], [], [1], true, true, '', - 'test_table', - [] + 'test_table' ); $this->assertEquals("''", $result); @@ -2475,7 +2516,13 @@ class InsertEditTest extends AbstractTestCase ->will($this->onConsecutiveCalls(false, '123', '2013-08-28 06:34:14')); $GLOBALS['dbi'] = $dbi; - $this->insertEdit = new InsertEdit($GLOBALS['dbi']); + $this->insertEdit = new InsertEdit( + $GLOBALS['dbi'], + new Relation($GLOBALS['dbi']), + new Transformations(), + new FileListing(), + new Template() + ); $this->insertEdit->verifyWhetherValueCanBeTruncatedAndAppendExtraData('db', 'table', 'a', $extra_data); @@ -2514,7 +2561,13 @@ class InsertEditTest extends AbstractTestCase ])); $GLOBALS['dbi'] = $dbi; - $this->insertEdit = new InsertEdit($GLOBALS['dbi']); + $this->insertEdit = new InsertEdit( + $GLOBALS['dbi'], + new Relation($GLOBALS['dbi']), + new Transformations(), + new FileListing(), + new Template() + ); $result = $this->insertEdit->getTableColumns('db', 'table'); @@ -2562,7 +2615,13 @@ class InsertEditTest extends AbstractTestCase $response->setAccessible(true); $response->setValue($responseMock); - $this->insertEdit = new InsertEdit($dbi); + $this->insertEdit = new InsertEdit( + $GLOBALS['dbi'], + new Relation($GLOBALS['dbi']), + new Transformations(), + new FileListing(), + new Template() + ); $result = $this->insertEdit->determineInsertOrEdit('1', 'db', 'table'); @@ -2641,7 +2700,13 @@ class InsertEditTest extends AbstractTestCase ); $GLOBALS['dbi'] = $dbi; - $this->insertEdit = new InsertEdit($GLOBALS['dbi']); + $this->insertEdit = new InsertEdit( + $GLOBALS['dbi'], + new Relation($GLOBALS['dbi']), + new Transformations(), + new FileListing(), + new Template() + ); $this->assertEquals( [], diff --git a/test/classes/ListDatabaseTest.php b/test/classes/ListDatabaseTest.php index bf45751b4a..ba32b5cf6f 100644 --- a/test/classes/ListDatabaseTest.php +++ b/test/classes/ListDatabaseTest.php @@ -24,6 +24,7 @@ class ListDatabaseTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 1; $GLOBALS['cfg']['Server']['DisableIS'] = false; $GLOBALS['cfg']['Server']['only_db'] = ['single\\_db']; diff --git a/test/classes/MenuTest.php b/test/classes/MenuTest.php index 3298ee5c85..01a943cc14 100644 --- a/test/classes/MenuTest.php +++ b/test/classes/MenuTest.php @@ -5,13 +5,21 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests; use PhpMyAdmin\Core; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Menu; +use PhpMyAdmin\Tests\Stubs\DbiDummy; /** * @covers \PhpMyAdmin\Menu */ class MenuTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** * Configures global environment. */ @@ -19,6 +27,9 @@ class MenuTest extends AbstractTestCase { parent::setUp(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['cfg']['Server']['DisableIS'] = false; $GLOBALS['server'] = 0; diff --git a/test/classes/MessageTest.php b/test/classes/MessageTest.php index d9b9b9f7ed..d3073e6278 100644 --- a/test/classes/MessageTest.php +++ b/test/classes/MessageTest.php @@ -352,7 +352,7 @@ class MessageTest extends AbstractTestCase ], [ '[a@https://example.com/@Documentation]link[/a]', - '<a href="./url.php?url=https%3A%2F%2Fexample.com%2F" target="Documentation">link</a>', + '<a href="index.php?route=/url&url=https%3A%2F%2Fexample.com%2F" target="Documentation">link</a>', ], [ '[a@./non-existing@Documentation]link[/a]', @@ -360,19 +360,19 @@ class MessageTest extends AbstractTestCase ], [ '[doc@foo]link[/doc]', - '<a href="./url.php?url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2F' + '<a href="index.php?route=/url&url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2F' . 'latest%2Fsetup.html%23foo" ' . 'target="documentation">link</a>', ], [ '[doc@page@anchor]link[/doc]', - '<a href="./url.php?url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2F' + '<a href="index.php?route=/url&url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2F' . 'latest%2Fpage.html%23anchor" ' . 'target="documentation">link</a>', ], [ '[doc@faqmysql]link[/doc]', - '<a href="./url.php?url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2F' + '<a href="index.php?route=/url&url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2F' . 'latest%2Ffaq.html%23faqmysql" ' . 'target="documentation">link</a>', ], @@ -463,7 +463,7 @@ class MessageTest extends AbstractTestCase { $this->object->setMessage('[kbd]test[/kbd] [doc@cfg_Example]test[/doc]'); $this->assertEquals( - '<kbd>test</kbd> <a href="./url.php?url=https%3A%2F%2Fdocs.phpmyadmin.' + '<kbd>test</kbd> <a href="index.php?route=/url&url=https%3A%2F%2Fdocs.phpmyadmin.' . 'net%2Fen%2Flatest%2Fconfig.html%23cfg_Example"' . ' target="documentation">test</a>', $this->object->getMessage() diff --git a/test/classes/Navigation/NavigationTest.php b/test/classes/Navigation/NavigationTest.php index 2bd6169455..d59712cb3c 100644 --- a/test/classes/Navigation/NavigationTest.php +++ b/test/classes/Navigation/NavigationTest.php @@ -27,6 +27,7 @@ class NavigationTest extends AbstractTestCase { parent::setUp(); parent::setLanguage(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 1; $GLOBALS['db'] = 'db'; $GLOBALS['table'] = ''; diff --git a/test/classes/Navigation/NavigationTreeTest.php b/test/classes/Navigation/NavigationTreeTest.php index 6b16dbaab5..b803efe6fb 100644 --- a/test/classes/Navigation/NavigationTreeTest.php +++ b/test/classes/Navigation/NavigationTreeTest.php @@ -25,6 +25,7 @@ class NavigationTreeTest extends AbstractTestCase parent::setLanguage(); parent::setGlobalConfig(); parent::setTheme(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 1; $GLOBALS['cfg']['Server']['host'] = 'localhost'; $GLOBALS['cfg']['Server']['user'] = 'user'; @@ -37,7 +38,7 @@ class NavigationTreeTest extends AbstractTestCase $GLOBALS['table'] = ''; $GLOBALS['PMA_PHP_SELF'] = ''; - $this->object = new NavigationTree(new Template(), $this->dbi); + $this->object = new NavigationTree(new Template(), $GLOBALS['dbi']); } /** @@ -83,22 +84,26 @@ class NavigationTreeTest extends AbstractTestCase $GLOBALS['cfg']['NavigationTreeDbSeparator'] = '__'; // phpcs:disable Generic.Files.LineLength.TooLong - $this->dummyDbi->addResult( + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addResult( 'SELECT `SCHEMA_NAME` FROM `INFORMATION_SCHEMA`.`SCHEMATA`, (SELECT DB_first_level FROM ( SELECT DISTINCT SUBSTRING_INDEX(SCHEMA_NAME, \'__\', 1) DB_first_level FROM INFORMATION_SCHEMA.SCHEMATA WHERE TRUE ) t ORDER BY DB_first_level ASC LIMIT 0, 100) t2 WHERE TRUE AND 1 = LOCATE(CONCAT(DB_first_level, \'__\'), CONCAT(SCHEMA_NAME, \'__\')) ORDER BY SCHEMA_NAME ASC', [['functions__a'], ['functions__b']], ['SCHEMA_NAME'] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SELECT COUNT(*) FROM ( SELECT DISTINCT SUBSTRING_INDEX(SCHEMA_NAME, \'__\', 1) DB_first_level FROM INFORMATION_SCHEMA.SCHEMATA WHERE TRUE ) t', [['2']] ); - $this->dummyDbi->addResult( + $dummyDbi->addResult( 'SELECT COUNT(*) FROM ( SELECT DISTINCT SUBSTRING_INDEX(SCHEMA_NAME, \'__\', 1) DB_first_level FROM INFORMATION_SCHEMA.SCHEMATA WHERE TRUE ) t', [['2']] ); // phpcs:enable - $object = new NavigationTree(new Template(), $this->dbi); + $dbi = $this->createDatabaseInterface($dummyDbi); + $GLOBALS['dbi'] = $dbi; + + $object = new NavigationTree(new Template(), $dbi); $result = $object->renderState(); $this->assertStringContainsString('<li class="first navGroup">', $result); $this->assertStringContainsString('functions' . "\n", $result); diff --git a/test/classes/Navigation/NodeFactoryTest.php b/test/classes/Navigation/NodeFactoryTest.php index 6429b8be6c..fa10e6f3bb 100644 --- a/test/classes/Navigation/NodeFactoryTest.php +++ b/test/classes/Navigation/NodeFactoryTest.php @@ -19,6 +19,7 @@ class NodeFactoryTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; } diff --git a/test/classes/Navigation/Nodes/NodeColumnContainerTest.php b/test/classes/Navigation/Nodes/NodeColumnContainerTest.php index dc7faa2da9..a2244827e6 100644 --- a/test/classes/Navigation/Nodes/NodeColumnContainerTest.php +++ b/test/classes/Navigation/Nodes/NodeColumnContainerTest.php @@ -18,6 +18,7 @@ class NodeColumnContainerTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; } diff --git a/test/classes/Navigation/Nodes/NodeColumnTest.php b/test/classes/Navigation/Nodes/NodeColumnTest.php index 783be7c7c1..fd66b85fb2 100644 --- a/test/classes/Navigation/Nodes/NodeColumnTest.php +++ b/test/classes/Navigation/Nodes/NodeColumnTest.php @@ -18,6 +18,7 @@ class NodeColumnTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; } diff --git a/test/classes/Navigation/Nodes/NodeDatabaseChildTest.php b/test/classes/Navigation/Nodes/NodeDatabaseChildTest.php index 29980932a3..dc55061f2a 100644 --- a/test/classes/Navigation/Nodes/NodeDatabaseChildTest.php +++ b/test/classes/Navigation/Nodes/NodeDatabaseChildTest.php @@ -31,6 +31,7 @@ class NodeDatabaseChildTest extends AbstractTestCase parent::setUp(); parent::setTheme(); parent::setLanguage(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['cfg']['DefaultTabDatabase'] = 'structure'; $GLOBALS['server'] = 1; $GLOBALS['cfg']['ServerDefault'] = 1; diff --git a/test/classes/Navigation/Nodes/NodeDatabaseTest.php b/test/classes/Navigation/Nodes/NodeDatabaseTest.php index 84d3476516..83bbeb6f5f 100644 --- a/test/classes/Navigation/Nodes/NodeDatabaseTest.php +++ b/test/classes/Navigation/Nodes/NodeDatabaseTest.php @@ -19,6 +19,7 @@ class NodeDatabaseTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['cfg']['DefaultTabDatabase'] = 'structure'; $GLOBALS['cfg']['MaxNavigationItems'] = 250; diff --git a/test/classes/Navigation/Nodes/NodeEventContainerTest.php b/test/classes/Navigation/Nodes/NodeEventContainerTest.php index 017d407694..dac6b635b4 100644 --- a/test/classes/Navigation/Nodes/NodeEventContainerTest.php +++ b/test/classes/Navigation/Nodes/NodeEventContainerTest.php @@ -18,6 +18,7 @@ class NodeEventContainerTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; } diff --git a/test/classes/Navigation/Nodes/NodeEventTest.php b/test/classes/Navigation/Nodes/NodeEventTest.php index 39a5ba03e5..a771a6f564 100644 --- a/test/classes/Navigation/Nodes/NodeEventTest.php +++ b/test/classes/Navigation/Nodes/NodeEventTest.php @@ -18,6 +18,7 @@ class NodeEventTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; } diff --git a/test/classes/Navigation/Nodes/NodeFunctionContainerTest.php b/test/classes/Navigation/Nodes/NodeFunctionContainerTest.php index 2dc2733899..dc7c03e2a5 100644 --- a/test/classes/Navigation/Nodes/NodeFunctionContainerTest.php +++ b/test/classes/Navigation/Nodes/NodeFunctionContainerTest.php @@ -18,6 +18,7 @@ class NodeFunctionContainerTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; } diff --git a/test/classes/Navigation/Nodes/NodeFunctionTest.php b/test/classes/Navigation/Nodes/NodeFunctionTest.php index be9e9cd892..94e26fc85a 100644 --- a/test/classes/Navigation/Nodes/NodeFunctionTest.php +++ b/test/classes/Navigation/Nodes/NodeFunctionTest.php @@ -18,6 +18,7 @@ class NodeFunctionTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; } diff --git a/test/classes/Navigation/Nodes/NodeIndexContainerTest.php b/test/classes/Navigation/Nodes/NodeIndexContainerTest.php index d5769ae9c6..f3539fd815 100644 --- a/test/classes/Navigation/Nodes/NodeIndexContainerTest.php +++ b/test/classes/Navigation/Nodes/NodeIndexContainerTest.php @@ -18,6 +18,7 @@ class NodeIndexContainerTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; } diff --git a/test/classes/Navigation/Nodes/NodeIndexTest.php b/test/classes/Navigation/Nodes/NodeIndexTest.php index a0db18b579..d28f0e407f 100644 --- a/test/classes/Navigation/Nodes/NodeIndexTest.php +++ b/test/classes/Navigation/Nodes/NodeIndexTest.php @@ -18,6 +18,7 @@ class NodeIndexTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; } diff --git a/test/classes/Navigation/Nodes/NodeProcedureContainerTest.php b/test/classes/Navigation/Nodes/NodeProcedureContainerTest.php index 3b431dd193..107d675d63 100644 --- a/test/classes/Navigation/Nodes/NodeProcedureContainerTest.php +++ b/test/classes/Navigation/Nodes/NodeProcedureContainerTest.php @@ -18,6 +18,7 @@ class NodeProcedureContainerTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; } diff --git a/test/classes/Navigation/Nodes/NodeProcedureTest.php b/test/classes/Navigation/Nodes/NodeProcedureTest.php index 79ab299be7..ace18da739 100644 --- a/test/classes/Navigation/Nodes/NodeProcedureTest.php +++ b/test/classes/Navigation/Nodes/NodeProcedureTest.php @@ -18,6 +18,7 @@ class NodeProcedureTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; } diff --git a/test/classes/Navigation/Nodes/NodeTableContainerTest.php b/test/classes/Navigation/Nodes/NodeTableContainerTest.php index ef0c7a27b0..b93b4adc52 100644 --- a/test/classes/Navigation/Nodes/NodeTableContainerTest.php +++ b/test/classes/Navigation/Nodes/NodeTableContainerTest.php @@ -18,6 +18,7 @@ class NodeTableContainerTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['cfg']['NavigationTreeEnableGrouping'] = true; $GLOBALS['cfg']['NavigationTreeDbSeparator'] = '_'; diff --git a/test/classes/Navigation/Nodes/NodeTableTest.php b/test/classes/Navigation/Nodes/NodeTableTest.php index 739d868854..f9c9916d26 100644 --- a/test/classes/Navigation/Nodes/NodeTableTest.php +++ b/test/classes/Navigation/Nodes/NodeTableTest.php @@ -18,6 +18,7 @@ class NodeTableTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['cfg']['NavigationTreeDefaultTabTable'] = 'search'; diff --git a/test/classes/Navigation/Nodes/NodeTest.php b/test/classes/Navigation/Nodes/NodeTest.php index 1978139743..41b92a8aa7 100644 --- a/test/classes/Navigation/Nodes/NodeTest.php +++ b/test/classes/Navigation/Nodes/NodeTest.php @@ -22,6 +22,7 @@ class NodeTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['cfg']['Server']['DisableIS'] = false; } diff --git a/test/classes/Navigation/Nodes/NodeTriggerContainerTest.php b/test/classes/Navigation/Nodes/NodeTriggerContainerTest.php index 2817dc341c..d4f2b4d632 100644 --- a/test/classes/Navigation/Nodes/NodeTriggerContainerTest.php +++ b/test/classes/Navigation/Nodes/NodeTriggerContainerTest.php @@ -18,6 +18,7 @@ class NodeTriggerContainerTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; } diff --git a/test/classes/Navigation/Nodes/NodeTriggerTest.php b/test/classes/Navigation/Nodes/NodeTriggerTest.php index 37d94e9278..c09ea33c43 100644 --- a/test/classes/Navigation/Nodes/NodeTriggerTest.php +++ b/test/classes/Navigation/Nodes/NodeTriggerTest.php @@ -18,6 +18,7 @@ class NodeTriggerTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; } diff --git a/test/classes/Navigation/Nodes/NodeViewContainerTest.php b/test/classes/Navigation/Nodes/NodeViewContainerTest.php index 9cbcd9b852..f1ef7bdd54 100644 --- a/test/classes/Navigation/Nodes/NodeViewContainerTest.php +++ b/test/classes/Navigation/Nodes/NodeViewContainerTest.php @@ -18,6 +18,7 @@ class NodeViewContainerTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['cfg']['NavigationTreeEnableGrouping'] = true; $GLOBALS['cfg']['NavigationTreeDbSeparator'] = '_'; diff --git a/test/classes/Navigation/Nodes/NodeViewTest.php b/test/classes/Navigation/Nodes/NodeViewTest.php index f6158dae3f..b2f5185c2d 100644 --- a/test/classes/Navigation/Nodes/NodeViewTest.php +++ b/test/classes/Navigation/Nodes/NodeViewTest.php @@ -18,6 +18,7 @@ class NodeViewTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; } diff --git a/test/classes/NormalizationTest.php b/test/classes/NormalizationTest.php index d867021de4..120e6e8226 100644 --- a/test/classes/NormalizationTest.php +++ b/test/classes/NormalizationTest.php @@ -9,9 +9,9 @@ use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Message; use PhpMyAdmin\Normalization; use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Transformations; use PhpMyAdmin\Types; -use PhpMyAdmin\Url; use stdClass; use function __; @@ -23,6 +23,12 @@ use function json_encode; */ class NormalizationTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var Normalization */ private $normalization; @@ -32,6 +38,9 @@ class NormalizationTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['cfg']['LimitChars'] = 50; $GLOBALS['cfg']['ServerDefault'] = 'PMA_server'; $GLOBALS['cfg']['ShowHint'] = true; @@ -445,25 +454,6 @@ class NormalizationTest extends AbstractTestCase } /** - * Test for getHtmlForNormalizeTable - */ - public function testgetHtmlForNormalizeTable(): void - { - $result = $this->normalization->getHtmlForNormalizeTable(); - $this->assertStringContainsString( - '<form method="post" action="' . Url::getFromRoute('/normalization') - . '" name="normalize" id="normalizeTable"', - $result - ); - $this->assertStringContainsString('<input type="hidden" name="step1" value="1">', $result); - - $this->assertStringContainsString('type="radio" name="normalizeTo"', $result); - $this->assertStringContainsString('id="normalizeToRadio1" value="1nf" checked>', $result); - $this->assertStringContainsString('id="normalizeToRadio2" value="2nf">', $result); - $this->assertStringContainsString('id="normalizeToRadio3" value="3nf">', $result); - } - - /** * Test for findPartialDependencies */ public function testFindPartialDependencies(): void diff --git a/test/classes/OperationsTest.php b/test/classes/OperationsTest.php index fea0406c4a..ff5cc8f608 100644 --- a/test/classes/OperationsTest.php +++ b/test/classes/OperationsTest.php @@ -5,7 +5,9 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests; use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Operations; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use function array_merge; @@ -14,12 +16,21 @@ use function array_merge; */ class OperationsTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var Operations */ private $object; protected function setUp(): void { parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; @@ -31,10 +42,8 @@ class OperationsTest extends AbstractTestCase */ public function testGetPartitionMaintenanceChoices(string $tableName, array $extraChoice): void { - global $db, $table; - - $db = 'database'; - $table = $tableName; + $GLOBALS['db'] = 'database'; + $GLOBALS['table'] = $tableName; $choices = [ 'ANALYZE' => 'Analyze', diff --git a/test/classes/ParseAnalyzeTest.php b/test/classes/ParseAnalyzeTest.php new file mode 100644 index 0000000000..05ede35b81 --- /dev/null +++ b/test/classes/ParseAnalyzeTest.php @@ -0,0 +1,65 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests; + +use PhpMyAdmin\ParseAnalyze; +use PhpMyAdmin\ResponseRenderer; +use PhpMyAdmin\StatementInfo; + +/** + * @covers \PhpMyAdmin\ParseAnalyze + */ +class ParseAnalyzeTest extends AbstractTestCase +{ + protected function setUp(): void + { + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + } + + public function testSqlQuery(): void + { + $GLOBALS['lang'] = 'en'; + ResponseRenderer::getInstance()->setAjax(false); + + $GLOBALS['unparsed_sql'] = ''; + + $actual = ParseAnalyze::sqlQuery('SELECT * FROM `sakila`.`actor`', 'sakila_test'); + + /** @psalm-suppress TypeDoesNotContainType */ + $this->assertSame('SELECT * FROM `sakila`.`actor`', $GLOBALS['unparsed_sql']); + $this->assertCount(3, $actual); + $this->assertInstanceOf(StatementInfo::class, $actual[0]); + $this->assertSame('sakila', $actual[1]); + $this->assertSame('actor', $actual[2]); + $this->assertTrue($actual[0]->reload); + $this->assertNotEmpty($actual[0]->selectTables); + $this->assertSame([['actor', 'sakila']], $actual[0]->selectTables); + $this->assertNotEmpty($actual[0]->selectExpression); + $this->assertSame(['*'], $actual[0]->selectExpression); + } + + public function testSqlQuery2(): void + { + $GLOBALS['lang'] = 'en'; + ResponseRenderer::getInstance()->setAjax(false); + + $GLOBALS['unparsed_sql'] = ''; + + $actual = ParseAnalyze::sqlQuery('SELECT `first_name`, `title` FROM `actor`, `film`', 'sakila'); + + /** @psalm-suppress TypeDoesNotContainType */ + $this->assertSame('SELECT `first_name`, `title` FROM `actor`, `film`', $GLOBALS['unparsed_sql']); + $this->assertCount(3, $actual); + $this->assertInstanceOf(StatementInfo::class, $actual[0]); + $this->assertSame('sakila', $actual[1]); + $this->assertSame('', $actual[2]); + $this->assertFalse($actual[0]->reload); + $this->assertNotEmpty($actual[0]->selectTables); + $this->assertSame([['actor', null], ['film', null]], $actual[0]->selectTables); + $this->assertNotEmpty($actual[0]->selectExpression); + $this->assertSame(['`first_name`', '`title`'], $actual[0]->selectExpression); + } +} diff --git a/test/classes/Partitioning/PartitionTest.php b/test/classes/Partitioning/PartitionTest.php index 83105e1f13..b2f492184a 100644 --- a/test/classes/Partitioning/PartitionTest.php +++ b/test/classes/Partitioning/PartitionTest.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Partitioning; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Partitioning\Partition; use PhpMyAdmin\Tests\AbstractTestCase; @@ -12,6 +13,12 @@ use PhpMyAdmin\Tests\AbstractTestCase; */ class PartitionTest extends AbstractTestCase { + protected function setUp(): void + { + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + } + public function testGetPartitionMethodReturnsNull(): void { $GLOBALS['server'] = 1; @@ -25,4 +32,51 @@ class PartitionTest extends AbstractTestCase $actual = Partition::getPartitionMethod('database', 'range_partition_method'); $this->assertEquals('RANGE', $actual); } + + /** + * @param string|false $varValue + * @param array<int, array<string, string>> $pluginValue + * + * @dataProvider providerForTestHavePartitioning + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testHavePartitioning(bool $expected, int $version, $varValue, array $pluginValue): void + { + $mock = $this->createStub(DatabaseInterface::class); + $mock->method('getVersion')->willReturn($version); + $mock->method('fetchValue')->willReturn($varValue); + $mock->method('fetchResult')->willReturn($pluginValue); + $GLOBALS['dbi'] = $mock; + $this->assertSame($expected, Partition::havePartitioning()); + } + + /** + * @return array<string, array<int, bool|int|string|array<int, array<string, string>>>> + * @psalm-return array<string, array{bool, positive-int, string|false, list<array{Name: string}>}> + */ + public function providerForTestHavePartitioning(): array + { + return [ + '5.5.0 with partitioning support' => [true, 50500, '1', []], + '5.5.0 without partitioning support' => [false, 50500, '0', []], + '5.6.0 with partitioning support' => [ + true, + 50600, + false, + [ + ['Name' => 'mysql_native_password'], + ['Name' => 'partition'], + ['Name' => 'InnoDB'], + ], + ], + '5.6.0 without partitioning support' => [ + false, + 50600, + false, + [['Name' => 'mysql_native_password'], ['Name' => 'InnoDB']], + ], + '8.0.0' => [true, 80000, false, []], + ]; + } } diff --git a/test/classes/Plugins/Auth/AuthenticationConfigTest.php b/test/classes/Plugins/Auth/AuthenticationConfigTest.php index 9c55499836..6187b54850 100644 --- a/test/classes/Plugins/Auth/AuthenticationConfigTest.php +++ b/test/classes/Plugins/Auth/AuthenticationConfigTest.php @@ -29,6 +29,7 @@ class AuthenticationConfigTest extends AbstractTestCase parent::setLanguage(); parent::setGlobalConfig(); parent::setTheme(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['db'] = 'db'; $GLOBALS['table'] = 'table'; @@ -96,7 +97,7 @@ class AuthenticationConfigTest extends AbstractTestCase ); $this->assertStringContainsString( - '<strong>MySQL said: </strong><a href="./url.php?url=https%3A%2F%2F' . + '<strong>MySQL said: </strong><a href="index.php?route=/url&url=https%3A%2F%2F' . 'dev.mysql.com%2Fdoc%2Frefman%2F5.5%2Fen%2Fserver-error-reference.html"' . ' target="mysql_doc">' . '<img src="themes/dot.gif" title="Documentation" alt="Documentation" ' . diff --git a/test/classes/Plugins/Auth/AuthenticationCookieTest.php b/test/classes/Plugins/Auth/AuthenticationCookieTest.php index 2f693930bb..8e6d650fe3 100644 --- a/test/classes/Plugins/Auth/AuthenticationCookieTest.php +++ b/test/classes/Plugins/Auth/AuthenticationCookieTest.php @@ -6,7 +6,6 @@ namespace PhpMyAdmin\Tests\Plugins\Auth; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\ErrorHandler; -use PhpMyAdmin\Footer; use PhpMyAdmin\Header; use PhpMyAdmin\Plugins\Auth\AuthenticationCookie; use PhpMyAdmin\ResponseRenderer; @@ -45,6 +44,7 @@ class AuthenticationCookieTest extends AbstractNetworkTestCase parent::setLanguage(); parent::setTheme(); parent::setGlobalConfig(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['db'] = 'db'; @@ -53,6 +53,7 @@ class AuthenticationCookieTest extends AbstractNetworkTestCase $this->object = new AuthenticationCookie(); $GLOBALS['PMA_PHP_SELF'] = '/phpmyadmin/'; $GLOBALS['cfg']['Server']['DisableIS'] = false; + $GLOBALS['conn_error'] = null; } /** @@ -99,16 +100,6 @@ class AuthenticationCookieTest extends AbstractNetworkTestCase ->with() ->will($this->returnValue(false)); - // mock footer - $mockFooter = $this->getMockBuilder(Footer::class) - ->disableOriginalConstructor() - ->onlyMethods(['setMinimal']) - ->getMock(); - - $mockFooter->expects($this->once()) - ->method('setMinimal') - ->with(); - // mock header $mockHeader = $this->getMockBuilder(Header::class) @@ -142,9 +133,8 @@ class AuthenticationCookieTest extends AbstractNetworkTestCase // set mocked headers and footers $mockResponse->expects($this->once()) - ->method('getFooter') - ->with() - ->will($this->returnValue($mockFooter)); + ->method('setMinimalFooter') + ->with(); $mockResponse->expects($this->once()) ->method('getHeader') @@ -256,9 +246,8 @@ class AuthenticationCookieTest extends AbstractNetworkTestCase ->will($this->returnValue(false)); $mockResponse->expects($this->once()) - ->method('getFooter') - ->with() - ->will($this->returnValue(new Footer())); + ->method('setMinimalFooter') + ->with(); $mockResponse->expects($this->once()) ->method('getHeader') @@ -313,7 +302,7 @@ class AuthenticationCookieTest extends AbstractNetworkTestCase $this->assertStringContainsString( '<input class="btn btn-primary g-recaptcha" data-sitekey="testpubkey"' - . ' data-callback="Functions_recaptchaCallback" value="Log in" type="submit" id="input_go">', + . ' data-callback="recaptchaCallback" value="Log in" type="submit" id="input_go">', $result ); } @@ -331,9 +320,8 @@ class AuthenticationCookieTest extends AbstractNetworkTestCase ->will($this->returnValue(false)); $mockResponse->expects($this->once()) - ->method('getFooter') - ->with() - ->will($this->returnValue(new Footer())); + ->method('setMinimalFooter') + ->with(); $mockResponse->expects($this->once()) ->method('getHeader') diff --git a/test/classes/Plugins/Auth/AuthenticationHttpTest.php b/test/classes/Plugins/Auth/AuthenticationHttpTest.php index 25e0144f62..60f31c105d 100644 --- a/test/classes/Plugins/Auth/AuthenticationHttpTest.php +++ b/test/classes/Plugins/Auth/AuthenticationHttpTest.php @@ -5,7 +5,6 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Plugins\Auth; use PhpMyAdmin\DatabaseInterface; -use PhpMyAdmin\Footer; use PhpMyAdmin\Header; use PhpMyAdmin\Plugins\Auth\AuthenticationHttp; use PhpMyAdmin\ResponseRenderer; @@ -31,6 +30,7 @@ class AuthenticationHttpTest extends AbstractNetworkTestCase parent::setUp(); parent::setGlobalConfig(); parent::setTheme(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['cfg']['Servers'] = []; $GLOBALS['server'] = 0; $GLOBALS['db'] = 'db'; @@ -53,25 +53,10 @@ class AuthenticationHttpTest extends AbstractNetworkTestCase } /** - * @param mixed $set_minimal set minimal - * @param mixed $body_id body id - * @param mixed $set_title set title - * @param mixed[] ...$headers headers + * @param mixed[] ...$headers */ - public function doMockResponse($set_minimal, $body_id, $set_title, ...$headers): void + public function doMockResponse(int $set_minimal, int $body_id, int $set_title, ...$headers): void { - // mock footer - $mockFooter = $this->getMockBuilder(Footer::class) - ->disableOriginalConstructor() - ->onlyMethods(['setMinimal']) - ->getMock(); - - $mockFooter->expects($this->exactly($set_minimal)) - ->method('setMinimal') - ->with(); - - // mock header - $mockHeader = $this->getMockBuilder(Header::class) ->disableOriginalConstructor() ->onlyMethods( @@ -98,10 +83,9 @@ class AuthenticationHttpTest extends AbstractNetworkTestCase // set mocked headers and footers $mockResponse = $this->mockResponse($headers); - $mockResponse->expects($this->exactly($set_title)) - ->method('getFooter') - ->with() - ->will($this->returnValue($mockFooter)); + $mockResponse->expects($this->exactly($set_minimal)) + ->method('setMinimalFooter') + ->with(); $mockResponse->expects($this->exactly($set_title)) ->method('getHeader') diff --git a/test/classes/Plugins/Auth/AuthenticationSignonTest.php b/test/classes/Plugins/Auth/AuthenticationSignonTest.php index a0424bd7b9..94d9246393 100644 --- a/test/classes/Plugins/Auth/AuthenticationSignonTest.php +++ b/test/classes/Plugins/Auth/AuthenticationSignonTest.php @@ -34,6 +34,7 @@ class AuthenticationSignonTest extends AbstractNetworkTestCase parent::setLanguage(); parent::setGlobalConfig(); parent::setTheme(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['db'] = 'db'; $GLOBALS['table'] = 'table'; diff --git a/test/classes/Plugins/Export/ExportCodegenTest.php b/test/classes/Plugins/Export/ExportCodegenTest.php index 6534f491b9..4ea73cfdb2 100644 --- a/test/classes/Plugins/Export/ExportCodegenTest.php +++ b/test/classes/Plugins/Export/ExportCodegenTest.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Plugins\Export; +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Export; use PhpMyAdmin\Plugins\Export\ExportCodegen; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup; @@ -11,6 +13,7 @@ use PhpMyAdmin\Properties\Options\Items\HiddenPropertyItem; use PhpMyAdmin\Properties\Options\Items\SelectPropertyItem; use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Transformations; use ReflectionClass; use ReflectionMethod; use ReflectionProperty; @@ -33,8 +36,13 @@ class ExportCodegenTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; - $this->object = new ExportCodegen(); + $this->object = new ExportCodegen( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ); } /** diff --git a/test/classes/Plugins/Export/ExportCsvTest.php b/test/classes/Plugins/Export/ExportCsvTest.php index 6599c71fd3..e84d4553cc 100644 --- a/test/classes/Plugins/Export/ExportCsvTest.php +++ b/test/classes/Plugins/Export/ExportCsvTest.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Plugins\Export; +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Export; use PhpMyAdmin\Plugins\Export\ExportCsv; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup; @@ -12,6 +14,7 @@ use PhpMyAdmin\Properties\Options\Items\HiddenPropertyItem; use PhpMyAdmin\Properties\Options\Items\TextPropertyItem; use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Transformations; use ReflectionMethod; use ReflectionProperty; @@ -34,13 +37,22 @@ class ExportCsvTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['db'] = ''; $GLOBALS['table'] = ''; $GLOBALS['lang'] = ''; $GLOBALS['text_dir'] = ''; $GLOBALS['PMA_PHP_SELF'] = ''; - $this->object = new ExportCsv(); + $GLOBALS['csv_enclosed'] = null; + $GLOBALS['csv_separator'] = null; + $GLOBALS['save_filename'] = null; + + $this->object = new ExportCsv( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ); } /** diff --git a/test/classes/Plugins/Export/ExportExcelTest.php b/test/classes/Plugins/Export/ExportExcelTest.php index 14daf5f35f..514cb399ec 100644 --- a/test/classes/Plugins/Export/ExportExcelTest.php +++ b/test/classes/Plugins/Export/ExportExcelTest.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Plugins\Export; +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Export; use PhpMyAdmin\Plugins\Export\ExportExcel; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup; @@ -13,6 +15,7 @@ use PhpMyAdmin\Properties\Options\Items\SelectPropertyItem; use PhpMyAdmin\Properties\Options\Items\TextPropertyItem; use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Transformations; use ReflectionMethod; use ReflectionProperty; @@ -33,8 +36,13 @@ class ExportExcelTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; - $this->object = new ExportExcel(); + $this->object = new ExportExcel( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ); } /** diff --git a/test/classes/Plugins/Export/ExportHtmlwordTest.php b/test/classes/Plugins/Export/ExportHtmlwordTest.php index 19c0263d21..47d8de8022 100644 --- a/test/classes/Plugins/Export/ExportHtmlwordTest.php +++ b/test/classes/Plugins/Export/ExportHtmlwordTest.php @@ -7,6 +7,7 @@ namespace PhpMyAdmin\Tests\Plugins\Export; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\ConfigStorage\RelationParameters; use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Export; use PhpMyAdmin\Plugins\Export\ExportHtmlword; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup; @@ -15,7 +16,9 @@ use PhpMyAdmin\Properties\Options\Items\RadioPropertyItem; use PhpMyAdmin\Properties\Options\Items\TextPropertyItem; use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\DummyResult; +use PhpMyAdmin\Transformations; use ReflectionMethod; use ReflectionProperty; @@ -30,6 +33,12 @@ use function ob_start; */ class ExportHtmlwordTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var ExportHtmlword */ protected $object; @@ -39,8 +48,15 @@ class ExportHtmlwordTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 0; - $this->object = new ExportHtmlword(); + $this->object = new ExportHtmlword( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ); $GLOBALS['output_kanji_conversion'] = false; $GLOBALS['output_charset_conversion'] = false; $GLOBALS['buffer_needed'] = false; @@ -316,6 +332,7 @@ class ExportHtmlwordTest extends AbstractTestCase { $this->object = $this->getMockBuilder(ExportHtmlword::class) ->onlyMethods(['formatOneColumnDefinition']) + ->disableOriginalConstructor() ->getMock(); // case 1 @@ -367,6 +384,7 @@ class ExportHtmlwordTest extends AbstractTestCase { $this->object = $this->getMockBuilder(ExportHtmlword::class) ->onlyMethods(['formatOneColumnDefinition']) + ->setConstructorArgs([new Relation($GLOBALS['dbi']), new Export($GLOBALS['dbi']), new Transformations()]) ->getMock(); $keys = [ @@ -625,7 +643,7 @@ class ExportHtmlwordTest extends AbstractTestCase 'test' ) ); - $this->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllSelectsConsumed(); $result = ob_get_clean(); $this->assertEquals( @@ -677,7 +695,7 @@ class ExportHtmlwordTest extends AbstractTestCase 'test' ) ); - $this->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllSelectsConsumed(); $result = ob_get_clean(); $this->assertEquals( diff --git a/test/classes/Plugins/Export/ExportJsonTest.php b/test/classes/Plugins/Export/ExportJsonTest.php index 882d206218..fb8a622817 100644 --- a/test/classes/Plugins/Export/ExportJsonTest.php +++ b/test/classes/Plugins/Export/ExportJsonTest.php @@ -4,12 +4,15 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Plugins\Export; +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Export; use PhpMyAdmin\Plugins\Export\ExportJson; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup; use PhpMyAdmin\Properties\Options\Items\HiddenPropertyItem; use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Transformations; use PhpMyAdmin\Version; use ReflectionMethod; use ReflectionProperty; @@ -31,13 +34,18 @@ class ExportJsonTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['output_kanji_conversion'] = false; $GLOBALS['output_charset_conversion'] = false; $GLOBALS['buffer_needed'] = false; $GLOBALS['asfile'] = true; $GLOBALS['save_on_server'] = false; - $this->object = new ExportJson(); + $this->object = new ExportJson( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ); } /** diff --git a/test/classes/Plugins/Export/ExportLatexTest.php b/test/classes/Plugins/Export/ExportLatexTest.php index c0e78f1d66..94d717021c 100644 --- a/test/classes/Plugins/Export/ExportLatexTest.php +++ b/test/classes/Plugins/Export/ExportLatexTest.php @@ -7,6 +7,7 @@ namespace PhpMyAdmin\Tests\Plugins\Export; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\ConfigStorage\RelationParameters; use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Export; use PhpMyAdmin\Plugins\Export\ExportLatex; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup; @@ -16,6 +17,7 @@ use PhpMyAdmin\Properties\Options\Items\TextPropertyItem; use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use PhpMyAdmin\Tests\AbstractTestCase; use PhpMyAdmin\Tests\Stubs\DummyResult; +use PhpMyAdmin\Transformations; use ReflectionMethod; use function __; @@ -38,6 +40,7 @@ class ExportLatexTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['output_kanji_conversion'] = false; $GLOBALS['output_charset_conversion'] = false; @@ -49,7 +52,11 @@ class ExportLatexTest extends AbstractTestCase $GLOBALS['plugin_param']['single_table'] = false; $GLOBALS['db'] = 'db'; $GLOBALS['table'] = 'table'; - $this->object = new ExportLatex(); + $this->object = new ExportLatex( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ); } /** diff --git a/test/classes/Plugins/Export/ExportMediawikiTest.php b/test/classes/Plugins/Export/ExportMediawikiTest.php index 0d50d8305a..e34009459f 100644 --- a/test/classes/Plugins/Export/ExportMediawikiTest.php +++ b/test/classes/Plugins/Export/ExportMediawikiTest.php @@ -4,7 +4,9 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Plugins\Export; +use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Export; use PhpMyAdmin\Plugins\Export\ExportMediawiki; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup; @@ -13,6 +15,7 @@ use PhpMyAdmin\Properties\Options\Items\BoolPropertyItem; use PhpMyAdmin\Properties\Options\Items\RadioPropertyItem; use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Transformations; use ReflectionMethod; use ReflectionProperty; @@ -36,6 +39,7 @@ class ExportMediawikiTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['output_kanji_conversion'] = false; $GLOBALS['output_charset_conversion'] = false; @@ -47,7 +51,11 @@ class ExportMediawikiTest extends AbstractTestCase $GLOBALS['lang'] = 'en'; $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['PMA_PHP_SELF'] = ''; - $this->object = new ExportMediawiki(); + $this->object = new ExportMediawiki( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ); } /** diff --git a/test/classes/Plugins/Export/ExportOdsTest.php b/test/classes/Plugins/Export/ExportOdsTest.php index 2c2268e4b8..4029e353f4 100644 --- a/test/classes/Plugins/Export/ExportOdsTest.php +++ b/test/classes/Plugins/Export/ExportOdsTest.php @@ -4,7 +4,9 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Plugins\Export; +use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Export; use PhpMyAdmin\FieldMetadata; use PhpMyAdmin\Plugins\Export\ExportOds; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; @@ -15,6 +17,7 @@ use PhpMyAdmin\Properties\Options\Items\TextPropertyItem; use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use PhpMyAdmin\Tests\AbstractTestCase; use PhpMyAdmin\Tests\Stubs\DummyResult; +use PhpMyAdmin\Transformations; use ReflectionMethod; use ReflectionProperty; use stdClass; @@ -45,13 +48,18 @@ class ExportOdsTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['output_kanji_conversion'] = false; $GLOBALS['output_charset_conversion'] = false; $GLOBALS['buffer_needed'] = false; $GLOBALS['asfile'] = true; $GLOBALS['save_on_server'] = false; - $this->object = new ExportOds(); + $this->object = new ExportOds( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ); } /** @@ -357,7 +365,7 @@ class ExportOdsTest extends AbstractTestCase $this->assertEquals( '<table:table table:name="table"><table:table-row><table:table-cell ' . - 'office:value-type="string"><text:p>fna"me</text:p></table:table' . + 'office:value-type="string"><text:p>fna\"me</text:p></table:table' . '-cell><table:table-cell office:value-type="string"><text:p>' . 'fnam/<e2</text:p></table:table-cell></table:table-row>' . '</table:table>', diff --git a/test/classes/Plugins/Export/ExportOdtTest.php b/test/classes/Plugins/Export/ExportOdtTest.php index fb63ff84a0..9f9c4c4a19 100644 --- a/test/classes/Plugins/Export/ExportOdtTest.php +++ b/test/classes/Plugins/Export/ExportOdtTest.php @@ -7,6 +7,7 @@ namespace PhpMyAdmin\Tests\Plugins\Export; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\ConfigStorage\RelationParameters; use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Export; use PhpMyAdmin\FieldMetadata; use PhpMyAdmin\Plugins\Export\ExportOdt; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; @@ -16,7 +17,9 @@ use PhpMyAdmin\Properties\Options\Items\RadioPropertyItem; use PhpMyAdmin\Properties\Options\Items\TextPropertyItem; use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\DummyResult; +use PhpMyAdmin\Transformations; use ReflectionMethod; use stdClass; @@ -36,6 +39,12 @@ use const MYSQLI_TYPE_STRING; */ class ExportOdtTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var ExportOdt */ protected $object; @@ -45,6 +54,9 @@ class ExportOdtTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 0; $GLOBALS['output_kanji_conversion'] = false; $GLOBALS['output_charset_conversion'] = false; @@ -55,7 +67,11 @@ class ExportOdtTest extends AbstractTestCase $GLOBALS['plugin_param']['export_type'] = 'table'; $GLOBALS['plugin_param']['single_table'] = false; $GLOBALS['cfg']['Server']['DisableIS'] = true; - $this->object = new ExportOdt(); + $this->object = new ExportOdt( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ); } /** @@ -469,7 +485,7 @@ class ExportOdtTest extends AbstractTestCase 'is-list-header="true">Dumping data for table table</text:h><table:' . 'table table:name="table_structure"><table:table-column table:number-' . 'columns-repeated="2"/><table:table-row><table:table-cell office:' . - 'value-type="string"><text:p>fna"me</text:p></table:table-cell>' . + 'value-type="string"><text:p>fna\"me</text:p></table:table-cell>' . '<table:table-cell office:value-type="string"><text:p>fnam/<e2' . '</text:p></table:table-cell></table:table-row></table:table>', $GLOBALS['odt_buffer'] @@ -536,7 +552,7 @@ class ExportOdtTest extends AbstractTestCase $this->object->getTableDefStandIn('test_db', 'test_table', "\n"), '' ); - $this->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllSelectsConsumed(); $this->assertEquals( '<table:table table:name="test_table_data">' @@ -569,6 +585,7 @@ class ExportOdtTest extends AbstractTestCase { $this->object = $this->getMockBuilder(ExportOdt::class) ->onlyMethods(['formatOneColumnDefinition']) + ->setConstructorArgs([new Relation($GLOBALS['dbi']), new Export($GLOBALS['dbi']), new Transformations()]) ->getMock(); // case 1 @@ -789,7 +806,7 @@ class ExportOdtTest extends AbstractTestCase 'test' ) ); - $this->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllSelectsConsumed(); $this->assertEquals( '<text:h text:outline-level="2" text:style-name="Heading_2" text:is-list-header="true">' @@ -863,7 +880,7 @@ class ExportOdtTest extends AbstractTestCase 'test' ) ); - $this->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllSelectsConsumed(); $this->assertEquals( '<text:h text:outline-level="2" text:style-name="Heading_2" text:is-list-header="true">' @@ -905,7 +922,7 @@ class ExportOdtTest extends AbstractTestCase 'test' ) ); - $this->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllSelectsConsumed(); $this->assertEquals( '<text:h text:outline-level="2" text:style-name="Heading_2" text:is-list-header="true">' diff --git a/test/classes/Plugins/Export/ExportPdfTest.php b/test/classes/Plugins/Export/ExportPdfTest.php index e7165c1680..9a06351244 100644 --- a/test/classes/Plugins/Export/ExportPdfTest.php +++ b/test/classes/Plugins/Export/ExportPdfTest.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Plugins\Export; +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Export; use PhpMyAdmin\Plugins\Export\ExportPdf; use PhpMyAdmin\Plugins\Export\Helpers\Pdf; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; @@ -12,6 +14,7 @@ use PhpMyAdmin\Properties\Options\Items\RadioPropertyItem; use PhpMyAdmin\Properties\Options\Items\TextPropertyItem; use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Transformations; use ReflectionMethod; use ReflectionProperty; @@ -33,13 +36,18 @@ class ExportPdfTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['output_kanji_conversion'] = false; $GLOBALS['output_charset_conversion'] = false; $GLOBALS['buffer_needed'] = false; $GLOBALS['asfile'] = true; $GLOBALS['save_on_server'] = false; - $this->object = new ExportPdf(); + $this->object = new ExportPdf( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ); } /** diff --git a/test/classes/Plugins/Export/ExportPhparrayTest.php b/test/classes/Plugins/Export/ExportPhparrayTest.php index 75e805a521..3e7c67f004 100644 --- a/test/classes/Plugins/Export/ExportPhparrayTest.php +++ b/test/classes/Plugins/Export/ExportPhparrayTest.php @@ -4,12 +4,15 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Plugins\Export; +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Export; use PhpMyAdmin\Plugins\Export\ExportPhparray; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup; use PhpMyAdmin\Properties\Options\Items\HiddenPropertyItem; use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Transformations; use ReflectionMethod; use ReflectionProperty; @@ -32,6 +35,7 @@ class ExportPhparrayTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['output_kanji_conversion'] = false; $GLOBALS['output_charset_conversion'] = false; @@ -43,7 +47,11 @@ class ExportPhparrayTest extends AbstractTestCase $GLOBALS['lang'] = 'en'; $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['PMA_PHP_SELF'] = ''; - $this->object = new ExportPhparray(); + $this->object = new ExportPhparray( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ); } /** diff --git a/test/classes/Plugins/Export/ExportSqlTest.php b/test/classes/Plugins/Export/ExportSqlTest.php index 94240e1f44..c907de040b 100644 --- a/test/classes/Plugins/Export/ExportSqlTest.php +++ b/test/classes/Plugins/Export/ExportSqlTest.php @@ -7,6 +7,7 @@ namespace PhpMyAdmin\Tests\Plugins\Export; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\ConfigStorage\RelationParameters; use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Export; use PhpMyAdmin\FieldMetadata; use PhpMyAdmin\Plugins\Export\ExportSql; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; @@ -21,6 +22,7 @@ use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use PhpMyAdmin\Table; use PhpMyAdmin\Tests\AbstractTestCase; use PhpMyAdmin\Tests\Stubs\DummyResult; +use PhpMyAdmin\Transformations; use ReflectionMethod; use stdClass; @@ -51,6 +53,7 @@ class ExportSqlTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['db'] = ''; $GLOBALS['table'] = ''; @@ -65,7 +68,16 @@ class ExportSqlTest extends AbstractTestCase $GLOBALS['plugin_param'] = []; $GLOBALS['plugin_param']['export_type'] = 'table'; $GLOBALS['plugin_param']['single_table'] = false; - $this->object = new ExportSql(); + $GLOBALS['sql_constraints'] = null; + $GLOBALS['sql_backquotes'] = null; + $GLOBALS['sql_indexes'] = null; + $GLOBALS['sql_auto_increments'] = null; + + $this->object = new ExportSql( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ); } /** @@ -735,12 +747,12 @@ class ExportSqlTest extends AbstractTestCase ); $GLOBALS['dbi'] = $dbi; - $result = $method->invoke($this->object, 'db', 'view', "\n", false); + $result = $method->invoke($this->object, 'db', 'view', "\n"); $this->assertEquals( "CREATE TABLE IF NOT EXISTS `view`(\n" . " `fname` char COLLATE utf-8 DEFAULT NULL COMMENT 'cmt'\n" . - ")\n", + ");\n", $result ); } @@ -1070,6 +1082,7 @@ class ExportSqlTest extends AbstractTestCase // case 3 $GLOBALS['sql_views_as_tables'] = false; + $GLOBALS['sql_backquotes'] = null; ob_start(); $this->assertTrue( diff --git a/test/classes/Plugins/Export/ExportTexytextTest.php b/test/classes/Plugins/Export/ExportTexytextTest.php index 7b6482a5c1..ea50468b47 100644 --- a/test/classes/Plugins/Export/ExportTexytextTest.php +++ b/test/classes/Plugins/Export/ExportTexytextTest.php @@ -7,6 +7,7 @@ namespace PhpMyAdmin\Tests\Plugins\Export; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\ConfigStorage\RelationParameters; use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Export; use PhpMyAdmin\Plugins\Export\ExportTexytext; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup; @@ -15,6 +16,8 @@ use PhpMyAdmin\Properties\Options\Items\RadioPropertyItem; use PhpMyAdmin\Properties\Options\Items\TextPropertyItem; use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; +use PhpMyAdmin\Transformations; use ReflectionMethod; use ReflectionProperty; @@ -28,6 +31,12 @@ use function ob_start; */ class ExportTexytextTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var ExportTexytext */ protected $object; @@ -37,6 +46,9 @@ class ExportTexytextTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 0; $GLOBALS['output_kanji_conversion'] = false; $GLOBALS['buffer_needed'] = false; @@ -51,7 +63,11 @@ class ExportTexytextTest extends AbstractTestCase $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['PMA_PHP_SELF'] = ''; $GLOBALS['cfg']['Server']['DisableIS'] = true; - $this->object = new ExportTexytext(); + $this->object = new ExportTexytext( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ); } /** @@ -222,7 +238,7 @@ class ExportTexytextTest extends AbstractTestCase { $this->dummyDbi->addSelectDb('test_db'); $result = $this->object->getTableDefStandIn('test_db', 'test_table', "\n"); - $this->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllSelectsConsumed(); $this->assertEquals( '|------' . "\n" @@ -239,6 +255,7 @@ class ExportTexytextTest extends AbstractTestCase { $this->object = $this->getMockBuilder(ExportTexytext::class) ->onlyMethods(['formatOneColumnDefinition']) + ->setConstructorArgs([new Relation($GLOBALS['dbi']), new Export($GLOBALS['dbi']), new Transformations()]) ->getMock(); // case 1 @@ -366,7 +383,7 @@ class ExportTexytextTest extends AbstractTestCase 'test' ) ); - $this->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllSelectsConsumed(); $result = ob_get_clean(); $this->assertIsString($result); @@ -417,7 +434,7 @@ class ExportTexytextTest extends AbstractTestCase 'test' ) ); - $this->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllSelectsConsumed(); $result = ob_get_clean(); $this->assertEquals( @@ -444,7 +461,7 @@ class ExportTexytextTest extends AbstractTestCase 'test' ) ); - $this->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllSelectsConsumed(); $result = ob_get_clean(); $this->assertEquals( diff --git a/test/classes/Plugins/Export/ExportXmlTest.php b/test/classes/Plugins/Export/ExportXmlTest.php index 5f4e77d118..41fcbf02d8 100644 --- a/test/classes/Plugins/Export/ExportXmlTest.php +++ b/test/classes/Plugins/Export/ExportXmlTest.php @@ -4,7 +4,9 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Plugins\Export; +use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Export; use PhpMyAdmin\Plugins\Export\ExportXml; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup; @@ -13,6 +15,7 @@ use PhpMyAdmin\Properties\Options\Items\HiddenPropertyItem; use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use PhpMyAdmin\Table; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Transformations; use ReflectionMethod; use ReflectionProperty; @@ -35,6 +38,7 @@ class ExportXmlTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['output_kanji_conversion'] = false; $GLOBALS['buffer_needed'] = false; @@ -45,7 +49,12 @@ class ExportXmlTest extends AbstractTestCase $GLOBALS['plugin_param']['single_table'] = false; $GLOBALS['db'] = 'db'; $GLOBALS['cfg']['Server']['DisableIS'] = true; - $this->object = new ExportXml(); + $GLOBALS['crlf'] = "\n"; + $this->object = new ExportXml( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ); } /** diff --git a/test/classes/Plugins/Export/ExportYamlTest.php b/test/classes/Plugins/Export/ExportYamlTest.php index 417ef9fecf..32d51f3581 100644 --- a/test/classes/Plugins/Export/ExportYamlTest.php +++ b/test/classes/Plugins/Export/ExportYamlTest.php @@ -4,12 +4,15 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Plugins\Export; +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Export; use PhpMyAdmin\Plugins\Export\ExportYaml; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup; use PhpMyAdmin\Properties\Options\Items\HiddenPropertyItem; use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Transformations; use ReflectionMethod; use ReflectionProperty; @@ -32,6 +35,7 @@ class ExportYamlTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['output_kanji_conversion'] = false; $GLOBALS['buffer_needed'] = false; @@ -43,7 +47,11 @@ class ExportYamlTest extends AbstractTestCase $GLOBALS['lang'] = 'en'; $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['PMA_PHP_SELF'] = ''; - $this->object = new ExportYaml(); + $this->object = new ExportYaml( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ); } /** diff --git a/test/classes/Plugins/Import/ImportCsvTest.php b/test/classes/Plugins/Import/ImportCsvTest.php index 4798f278aa..963acdebc9 100644 --- a/test/classes/Plugins/Import/ImportCsvTest.php +++ b/test/classes/Plugins/Import/ImportCsvTest.php @@ -8,6 +8,7 @@ use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\File; use PhpMyAdmin\Plugins\Import\ImportCsv; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use function __; use function basename; @@ -17,6 +18,12 @@ use function basename; */ class ImportCsvTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var ImportCsv */ protected $object; @@ -27,11 +34,28 @@ class ImportCsvTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 0; $GLOBALS['plugin_param'] = 'csv'; - $this->object = new ImportCsv(); + $GLOBALS['errorUrl'] = 'index.php?route=/'; + $GLOBALS['error'] = false; + $GLOBALS['db'] = ''; + $GLOBALS['table'] = ''; + $GLOBALS['sql_query'] = ''; + $GLOBALS['message'] = null; + $GLOBALS['csv_columns'] = null; + $GLOBALS['timeout_passed'] = null; + $GLOBALS['maximum_time'] = null; + $GLOBALS['charset_conversion'] = null; + $GLOBALS['skip_queries'] = null; + $GLOBALS['max_sql_len'] = null; + $GLOBALS['executed_queries'] = null; + $GLOBALS['run_query'] = null; + $GLOBALS['go_sql'] = null; - unset($GLOBALS['db']); + $this->object = new ImportCsv(); //setting $GLOBALS['finished'] = false; @@ -97,8 +121,8 @@ class ImportCsvTest extends AbstractTestCase public function testDoImport(): void { //$sql_query_disabled will show the import SQL detail - global $sql_query, $sql_query_disabled; - $sql_query_disabled = false; + + $GLOBALS['sql_query_disabled'] = false; $importHandle = new File($GLOBALS['import_file']); $importHandle->open(); @@ -107,10 +131,13 @@ class ImportCsvTest extends AbstractTestCase $this->object->doImport($importHandle); //asset that all sql are executed - $this->assertStringContainsString('CREATE DATABASE IF NOT EXISTS `CSV_DB 1` DEFAULT CHARACTER', $sql_query); + $this->assertStringContainsString( + 'CREATE DATABASE IF NOT EXISTS `CSV_DB 1` DEFAULT CHARACTER', + $GLOBALS['sql_query'] + ); $this->assertStringContainsString( 'CREATE TABLE IF NOT EXISTS `CSV_DB 1`.`' . $GLOBALS['import_file_name'] . '`', - $sql_query + $GLOBALS['sql_query'] ); $this->assertTrue($GLOBALS['finished']); @@ -124,8 +151,8 @@ class ImportCsvTest extends AbstractTestCase public function testDoPartialImport(): void { //$sql_query_disabled will show the import SQL detail - global $sql_query, $sql_query_disabled; - $sql_query_disabled = false; + + $GLOBALS['sql_query_disabled'] = false; $importHandle = new File($GLOBALS['import_file']); $importHandle->open(); @@ -139,8 +166,14 @@ class ImportCsvTest extends AbstractTestCase $this->object->doImport($importHandle); //asset that all sql are executed - $this->assertStringContainsString('CREATE DATABASE IF NOT EXISTS `ImportTestDb` DEFAULT CHARACTER', $sql_query); - $this->assertStringContainsString('CREATE TABLE IF NOT EXISTS `ImportTestDb`.`ImportTestTable`', $sql_query); + $this->assertStringContainsString( + 'CREATE DATABASE IF NOT EXISTS `ImportTestDb` DEFAULT CHARACTER', + $GLOBALS['sql_query'] + ); + $this->assertStringContainsString( + 'CREATE TABLE IF NOT EXISTS `ImportTestDb`.`ImportTestTable`', + $GLOBALS['sql_query'] + ); $this->assertTrue($GLOBALS['finished']); @@ -177,8 +210,8 @@ class ImportCsvTest extends AbstractTestCase public function testDoImportNotAnalysis(): void { //$sql_query_disabled will show the import SQL detail - global $sql_query, $sql_query_disabled; - $sql_query_disabled = false; + + $GLOBALS['sql_query_disabled'] = false; $importHandle = new File($GLOBALS['import_file']); $importHandle->open(); @@ -187,11 +220,14 @@ class ImportCsvTest extends AbstractTestCase $this->object->doImport($importHandle); //asset that all sql are executed - $this->assertStringContainsString('CREATE DATABASE IF NOT EXISTS `CSV_DB 1` DEFAULT CHARACTER', $sql_query); + $this->assertStringContainsString( + 'CREATE DATABASE IF NOT EXISTS `CSV_DB 1` DEFAULT CHARACTER', + $GLOBALS['sql_query'] + ); $this->assertStringContainsString( 'CREATE TABLE IF NOT EXISTS `CSV_DB 1`.`' . $GLOBALS['import_file_name'] . '`', - $sql_query + $GLOBALS['sql_query'] ); $this->assertTrue($GLOBALS['finished']); @@ -205,14 +241,16 @@ class ImportCsvTest extends AbstractTestCase public function testDoImportNormal(): void { //$sql_query_disabled will show the import SQL detail - global $sql_query, $sql_query_disabled; - $sql_query_disabled = false; + + $GLOBALS['sql_query_disabled'] = false; $GLOBALS['import_type'] = 'query'; $GLOBALS['import_file'] = 'none'; $GLOBALS['csv_terminated'] = ','; $GLOBALS['import_text'] = '"Row 1","Row 2"' . "\n" . '"123","456"'; - parent::setGlobalDbi(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $this->dummyDbi->addResult( 'SHOW DATABASES', @@ -232,11 +270,11 @@ class ImportCsvTest extends AbstractTestCase . 'CREATE TABLE IF NOT EXISTS `CSV_DB 1`.`db_test` (`COL 1` varchar(5), `COL 2` varchar(5))' . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;;INSERT INTO `CSV_DB 1`.`db_test`' . ' (`COL 1`, `COL 2`) VALUES (\'Row 1\', \'Row 2\'),' . "\n" . ' (\'123\', \'456\');;', - $sql_query + $GLOBALS['sql_query'] ); $this->assertEquals(true, $GLOBALS['finished']); - $this->assertAllQueriesConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); } /** @@ -247,8 +285,8 @@ class ImportCsvTest extends AbstractTestCase public function testDoImportSkipHeaders(): void { //$sql_query_disabled will show the import SQL detail - global $sql_query, $sql_query_disabled; - $sql_query_disabled = false; + + $GLOBALS['sql_query_disabled'] = false; $GLOBALS['import_type'] = 'query'; $GLOBALS['import_file'] = 'none'; $GLOBALS['csv_terminated'] = ','; @@ -256,7 +294,9 @@ class ImportCsvTest extends AbstractTestCase $_REQUEST['csv_col_names'] = 'something'; - parent::setGlobalDbi(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $this->dummyDbi->addResult( 'SHOW DATABASES', @@ -276,10 +316,10 @@ class ImportCsvTest extends AbstractTestCase . 'CREATE TABLE IF NOT EXISTS `CSV_DB 1`.`db_test` (`Row 1` int(3), `Row 2` int(3))' . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;;INSERT INTO `CSV_DB 1`.`db_test`' . ' (`Row 1`, `Row 2`) VALUES (123, 456);;', - $sql_query + $GLOBALS['sql_query'] ); $this->assertEquals(true, $GLOBALS['finished']); - $this->assertAllQueriesConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); } } diff --git a/test/classes/Plugins/Import/ImportLdiTest.php b/test/classes/Plugins/Import/ImportLdiTest.php index 8450b80c8d..caf7023de0 100644 --- a/test/classes/Plugins/Import/ImportLdiTest.php +++ b/test/classes/Plugins/Import/ImportLdiTest.php @@ -9,7 +9,6 @@ use PhpMyAdmin\File; use PhpMyAdmin\Plugins\Import\ImportLdi; use PhpMyAdmin\Tests\AbstractTestCase; use PhpMyAdmin\Tests\Stubs\DummyResult; -use PHPUnit\Framework\MockObject\MockObject; use function __; @@ -18,12 +17,6 @@ use function __; */ class ImportLdiTest extends AbstractTestCase { - /** @var ImportLdi */ - protected $object; - - /** @var DatabaseInterface */ - protected $dbi; - /** * Sets up the fixture, for example, opens a network connection. * This method is called before a test is executed. @@ -31,6 +24,19 @@ class ImportLdiTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + $GLOBALS['charset_conversion'] = null; + $GLOBALS['ldi_terminated'] = null; + $GLOBALS['ldi_escaped'] = null; + $GLOBALS['ldi_columns'] = null; + $GLOBALS['ldi_enclosed'] = null; + $GLOBALS['ldi_new_line'] = null; + $GLOBALS['max_sql_len'] = null; + $GLOBALS['sql_query'] = ''; + $GLOBALS['executed_queries'] = null; + $GLOBALS['skip_queries'] = null; + $GLOBALS['run_query'] = null; + $GLOBALS['go_sql'] = null; //setting $GLOBALS['server'] = 0; $GLOBALS['plugin_param'] = 'table'; @@ -54,24 +60,6 @@ class ImportLdiTest extends AbstractTestCase $GLOBALS['cfg']['Import']['ldi_columns'] = ''; $GLOBALS['cfg']['Import']['ldi_local_option'] = false; $GLOBALS['table'] = 'phpmyadmintest'; - - //Mock DBI - $this->dbi = $this->getMockBuilder(DatabaseInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $GLOBALS['dbi'] = $this->dbi; - - $this->object = new ImportLdi(); - } - - /** - * Tears down the fixture, for example, closes a network connection. - * This method is called after a test is executed. - */ - protected function tearDown(): void - { - parent::tearDown(); - unset($this->object); } /** @@ -81,7 +69,7 @@ class ImportLdiTest extends AbstractTestCase */ public function testGetProperties(): void { - $properties = $this->object->getProperties(); + $properties = (new ImportLdi())->getProperties(); $this->assertEquals( __('CSV using LOAD DATA'), $properties->getText() @@ -99,12 +87,8 @@ class ImportLdiTest extends AbstractTestCase */ public function testGetPropertiesAutoLdi(): void { - /** - * The \PhpMyAdmin\DatabaseInterface mocked object - * - * @var MockObject $dbi - */ - $dbi = $this->dbi; + $dbi = $this->createMock(DatabaseInterface::class); + $GLOBALS['dbi'] = $dbi; $resultStub = $this->createMock(DummyResult::class); @@ -118,8 +102,7 @@ class ImportLdiTest extends AbstractTestCase ->will($this->returnValue('ON')); $GLOBALS['cfg']['Import']['ldi_local_option'] = 'auto'; - $this->object = new ImportLdi(); - $properties = $this->object->getProperties(); + $properties = (new ImportLdi())->getProperties(); $this->assertTrue($GLOBALS['cfg']['Import']['ldi_local_option']); $this->assertEquals( __('CSV using LOAD DATA'), @@ -139,14 +122,9 @@ class ImportLdiTest extends AbstractTestCase public function testDoImport(): void { //$sql_query_disabled will show the import SQL detail - global $sql_query, $sql_query_disabled; - $sql_query_disabled = false; - /** - * The \PhpMyAdmin\DatabaseInterface mocked object - * - * @var MockObject $dbi - */ - $dbi = $this->dbi; + + $GLOBALS['sql_query_disabled'] = false; + $dbi = $this->createMock(DatabaseInterface::class); $dbi->expects($this->any())->method('escapeString') ->will($this->returnArgument(0)); $GLOBALS['dbi'] = $dbi; @@ -155,12 +133,12 @@ class ImportLdiTest extends AbstractTestCase $importHandle->open(); //Test function called - $this->object->doImport($importHandle); + (new ImportLdi())->doImport($importHandle); //asset that all sql are executed $this->assertStringContainsString( 'LOAD DATA INFILE \'test/test_data/db_test_ldi.csv\' INTO TABLE `phpmyadmintest`', - $sql_query + $GLOBALS['sql_query'] ); $this->assertTrue($GLOBALS['finished']); @@ -173,11 +151,10 @@ class ImportLdiTest extends AbstractTestCase */ public function testDoImportInvalidFile(): void { - global $import_file; - $import_file = 'none'; + $GLOBALS['import_file'] = 'none'; //Test function called - $this->object->doImport(); + (new ImportLdi())->doImport(); // We handle only some kind of data! $this->assertStringContainsString( @@ -195,51 +172,43 @@ class ImportLdiTest extends AbstractTestCase */ public function testDoImportLDISetting(): void { - global $ldi_local_option, $ldi_replace, $ldi_ignore, $ldi_terminated, - $ldi_enclosed, $ldi_new_line, $skip_queries; - //$sql_query_disabled will show the import SQL detail - global $sql_query, $sql_query_disabled; - $sql_query_disabled = false; - /** - * The \PhpMyAdmin\DatabaseInterface mocked object - * - * @var MockObject $dbi - */ - $dbi = $this->dbi; + + $GLOBALS['sql_query_disabled'] = false; + $dbi = $this->createMock(DatabaseInterface::class); $dbi->expects($this->any())->method('escapeString') ->will($this->returnArgument(0)); $GLOBALS['dbi'] = $dbi; - $ldi_local_option = true; - $ldi_replace = true; - $ldi_ignore = true; - $ldi_terminated = ','; - $ldi_enclosed = ')'; - $ldi_new_line = 'newline_mark'; - $skip_queries = true; + $GLOBALS['ldi_local_option'] = true; + $GLOBALS['ldi_replace'] = true; + $GLOBALS['ldi_ignore'] = true; + $GLOBALS['ldi_terminated'] = ','; + $GLOBALS['ldi_enclosed'] = ')'; + $GLOBALS['ldi_new_line'] = 'newline_mark'; + $GLOBALS['skip_queries'] = true; $importHandle = new File($GLOBALS['import_file']); $importHandle->open(); //Test function called - $this->object->doImport($importHandle); + (new ImportLdi())->doImport($importHandle); //asset that all sql are executed //replace $this->assertStringContainsString( 'LOAD DATA LOCAL INFILE \'test/test_data/db_test_ldi.csv\' REPLACE INTO TABLE `phpmyadmintest`', - $sql_query + $GLOBALS['sql_query'] ); //FIELDS TERMINATED - $this->assertStringContainsString("FIELDS TERMINATED BY ','", $sql_query); + $this->assertStringContainsString("FIELDS TERMINATED BY ','", $GLOBALS['sql_query']); //LINES TERMINATED - $this->assertStringContainsString("LINES TERMINATED BY 'newline_mark'", $sql_query); + $this->assertStringContainsString("LINES TERMINATED BY 'newline_mark'", $GLOBALS['sql_query']); //IGNORE - $this->assertStringContainsString('IGNORE 1 LINES', $sql_query); + $this->assertStringContainsString('IGNORE 1 LINES', $GLOBALS['sql_query']); $this->assertTrue($GLOBALS['finished']); } diff --git a/test/classes/Plugins/Import/ImportMediawikiTest.php b/test/classes/Plugins/Import/ImportMediawikiTest.php index 7c2423609b..8e74ce9abb 100644 --- a/test/classes/Plugins/Import/ImportMediawikiTest.php +++ b/test/classes/Plugins/Import/ImportMediawikiTest.php @@ -26,7 +26,20 @@ class ImportMediawikiTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; + $GLOBALS['error'] = null; + $GLOBALS['timeout_passed'] = null; + $GLOBALS['maximum_time'] = null; + $GLOBALS['charset_conversion'] = null; + $GLOBALS['db'] = ''; + $GLOBALS['skip_queries'] = null; + $GLOBALS['max_sql_len'] = null; + $GLOBALS['sql_query_disabled'] = null; + $GLOBALS['sql_query'] = ''; + $GLOBALS['executed_queries'] = null; + $GLOBALS['run_query'] = null; + $GLOBALS['go_sql'] = null; $GLOBALS['plugin_param'] = 'database'; $this->object = new ImportMediawiki(); @@ -87,7 +100,6 @@ class ImportMediawikiTest extends AbstractTestCase public function testDoImport(): void { //$import_notice will show the import detail result - global $import_notice; //Mock DBI $dbi = $this->getMockBuilder(DatabaseInterface::class) @@ -117,12 +129,12 @@ class ImportMediawikiTest extends AbstractTestCase //asset that all databases and tables are imported $this->assertStringContainsString( 'The following structures have either been created or altered.', - $import_notice + $GLOBALS['import_notice'] ); - $this->assertStringContainsString('Go to database: `mediawiki_DB`', $import_notice); - $this->assertStringContainsString('Edit settings for `mediawiki_DB`', $import_notice); - $this->assertStringContainsString('Go to table: `pma_bookmarktest`', $import_notice); - $this->assertStringContainsString('Edit settings for `pma_bookmarktest`', $import_notice); + $this->assertStringContainsString('Go to database: `mediawiki_DB`', $GLOBALS['import_notice']); + $this->assertStringContainsString('Edit settings for `mediawiki_DB`', $GLOBALS['import_notice']); + $this->assertStringContainsString('Go to table: `pma_bookmarktest`', $GLOBALS['import_notice']); + $this->assertStringContainsString('Edit settings for `pma_bookmarktest`', $GLOBALS['import_notice']); $this->assertTrue($GLOBALS['finished']); } } diff --git a/test/classes/Plugins/Import/ImportOdsTest.php b/test/classes/Plugins/Import/ImportOdsTest.php index 10f289f035..1b80aba6f9 100644 --- a/test/classes/Plugins/Import/ImportOdsTest.php +++ b/test/classes/Plugins/Import/ImportOdsTest.php @@ -4,9 +4,11 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Plugins\Import; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\File; use PhpMyAdmin\Plugins\Import\ImportOds; use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use function __; use function str_repeat; @@ -17,6 +19,12 @@ use function str_repeat; */ class ImportOdsTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var ImportOds */ protected $object; @@ -27,8 +35,20 @@ class ImportOdsTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['plugin_param'] = 'csv'; + $GLOBALS['error'] = null; + $GLOBALS['timeout_passed'] = null; + $GLOBALS['maximum_time'] = null; + $GLOBALS['charset_conversion'] = null; + $GLOBALS['db'] = ''; + $GLOBALS['skip_queries'] = null; + $GLOBALS['max_sql_len'] = null; + $GLOBALS['executed_queries'] = null; + $GLOBALS['run_query'] = null; + $GLOBALS['sql_query'] = ''; + $GLOBALS['go_sql'] = null; $this->object = new ImportOds(); //setting @@ -89,13 +109,15 @@ class ImportOdsTest extends AbstractTestCase { //$sql_query_disabled will show the import SQL detail //$import_notice will show the import detail result - global $import_notice, $sql_query, $sql_query_disabled; - $sql_query_disabled = false; + + $GLOBALS['sql_query_disabled'] = false; $GLOBALS['import_file'] = 'test/test_data/db_test.ods'; $_REQUEST['ods_empty_rows'] = true; - parent::setGlobalDbi(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $importHandle = new File($GLOBALS['import_file']); $importHandle->setDecompressContent(true); @@ -106,23 +128,23 @@ class ImportOdsTest extends AbstractTestCase $this->assertStringContainsString( 'CREATE DATABASE IF NOT EXISTS `ODS_DB` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci', - $sql_query + $GLOBALS['sql_query'] ); - $this->assertStringContainsString('CREATE TABLE IF NOT EXISTS `ODS_DB`.`pma_bookmark`', $sql_query); + $this->assertStringContainsString('CREATE TABLE IF NOT EXISTS `ODS_DB`.`pma_bookmark`', $GLOBALS['sql_query']); $this->assertStringContainsString( 'INSERT INTO `ODS_DB`.`pma_bookmark` (`A`, `B`, `C`, `D`) VALUES (1, \'dbbase\', NULL, \'ddd\');', - $sql_query + $GLOBALS['sql_query'] ); //asset that all databases and tables are imported $this->assertStringContainsString( 'The following structures have either been created or altered.', - $import_notice + $GLOBALS['import_notice'] ); - $this->assertStringContainsString('Go to database: `ODS_DB`', $import_notice); - $this->assertStringContainsString('Edit settings for `ODS_DB`', $import_notice); - $this->assertStringContainsString('Go to table: `pma_bookmark`', $import_notice); - $this->assertStringContainsString('Edit settings for `pma_bookmark`', $import_notice); + $this->assertStringContainsString('Go to database: `ODS_DB`', $GLOBALS['import_notice']); + $this->assertStringContainsString('Edit settings for `ODS_DB`', $GLOBALS['import_notice']); + $this->assertStringContainsString('Go to table: `pma_bookmark`', $GLOBALS['import_notice']); + $this->assertStringContainsString('Edit settings for `pma_bookmark`', $GLOBALS['import_notice']); //asset that the import process is finished $this->assertTrue($GLOBALS['finished']); @@ -147,14 +169,16 @@ class ImportOdsTest extends AbstractTestCase { //$sql_query_disabled will show the import SQL detail //$import_notice will show the import detail result - global $import_notice, $sql_query, $sql_query_disabled; - $sql_query_disabled = false; + + $GLOBALS['sql_query_disabled'] = false; $GLOBALS['import_file'] = 'test/test_data/import-slim.ods.xml'; $_REQUEST['ods_col_names'] = true; $_REQUEST['ods_empty_rows'] = $odsEmptyRowsMode; - parent::setGlobalDbi(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $importHandle = new File($GLOBALS['import_file']); $importHandle->setDecompressContent(false);// Not compressed @@ -226,18 +250,18 @@ class ImportOdsTest extends AbstractTestCase . ' (\'12\')' . ($odsEmptyRowsMode ? '' : ',' . "\n" . ' (NULL)') . ($odsEmptyRowsMode ? ';;' : ',' . "\n" . ' (NULL);;'), - $sql_query + $GLOBALS['sql_query'] ); //asset that all databases and tables are imported $this->assertStringContainsString( 'The following structures have either been created or altered.', - $import_notice + $GLOBALS['import_notice'] ); - $this->assertStringContainsString('Go to database: `ODS_DB`', $import_notice); - $this->assertStringContainsString('Edit settings for `ODS_DB`', $import_notice); - $this->assertStringContainsString('Go to table: `Shop`', $import_notice); - $this->assertStringContainsString('Edit settings for `Shop`', $import_notice); + $this->assertStringContainsString('Go to database: `ODS_DB`', $GLOBALS['import_notice']); + $this->assertStringContainsString('Edit settings for `ODS_DB`', $GLOBALS['import_notice']); + $this->assertStringContainsString('Go to table: `Shop`', $GLOBALS['import_notice']); + $this->assertStringContainsString('Edit settings for `Shop`', $GLOBALS['import_notice']); //asset that the import process is finished $this->assertTrue($GLOBALS['finished']); diff --git a/test/classes/Plugins/Import/ImportShpTest.php b/test/classes/Plugins/Import/ImportShpTest.php index b9f06b56c0..81be0427b8 100644 --- a/test/classes/Plugins/Import/ImportShpTest.php +++ b/test/classes/Plugins/Import/ImportShpTest.php @@ -28,6 +28,18 @@ class ImportShpTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['error'] = null; + $GLOBALS['buffer'] = null; + $GLOBALS['maximum_time'] = null; + $GLOBALS['charset_conversion'] = null; + $GLOBALS['eof'] = null; + $GLOBALS['db'] = ''; + $GLOBALS['skip_queries'] = null; + $GLOBALS['max_sql_len'] = null; + $GLOBALS['sql_query'] = ''; + $GLOBALS['executed_queries'] = null; + $GLOBALS['run_query'] = null; + $GLOBALS['go_sql'] = null; $GLOBALS['server'] = 0; //setting @@ -114,13 +126,14 @@ class ImportShpTest extends AbstractTestCase { //$sql_query_disabled will show the import SQL detail //$import_notice will show the import detail result - global $import_notice, $sql_query, $sql_query_disabled; - $sql_query_disabled = false; + + $GLOBALS['sql_query_disabled'] = false; + $GLOBALS['db'] = ''; //Test function called $this->runImport('test/test_data/dresden_osm.shp.zip'); - $this->assertMessages($import_notice); + $this->assertMessages($GLOBALS['import_notice']); $endsWith = "13.737122 51.0542065)))'))"; @@ -135,7 +148,7 @@ class ImportShpTest extends AbstractTestCase . '13.7372661 51.0540944,' . '13.7370842 51.0541711,' . $endsWith, - $sql_query + $GLOBALS['sql_query'] ); } @@ -149,8 +162,9 @@ class ImportShpTest extends AbstractTestCase { //$sql_query_disabled will show the import SQL detail //$import_notice will show the import detail result - global $import_notice, $sql_query, $sql_query_disabled; - $sql_query_disabled = false; + + $GLOBALS['sql_query_disabled'] = false; + $GLOBALS['db'] = ''; //Test function called $this->runImport('test/test_data/timezone.shp.zip'); @@ -158,7 +172,7 @@ class ImportShpTest extends AbstractTestCase // asset that all sql are executed $this->assertStringContainsString( 'CREATE DATABASE IF NOT EXISTS `SHP_DB` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci', - $sql_query + $GLOBALS['sql_query'] ); // dbase extension will generate different sql statement @@ -167,26 +181,29 @@ class ImportShpTest extends AbstractTestCase 'CREATE TABLE IF NOT EXISTS `SHP_DB`.`TBL_NAME` ' . '(`SPATIAL` geometry, `ID` int(2), `AUTHORITY` varchar(25), `NAME` varchar(42)) ' . 'DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;', - $sql_query + $GLOBALS['sql_query'] ); $this->assertStringContainsString( 'INSERT INTO `SHP_DB`.`TBL_NAME` (`SPATIAL`, `ID`, `AUTHORITY`, `NAME`) VALUES', - $sql_query + $GLOBALS['sql_query'] ); } else { $this->assertStringContainsString( 'CREATE TABLE IF NOT EXISTS `SHP_DB`.`TBL_NAME` (`SPATIAL` geometry)', - $sql_query + $GLOBALS['sql_query'] ); - $this->assertStringContainsString('INSERT INTO `SHP_DB`.`TBL_NAME` (`SPATIAL`) VALUES', $sql_query); + $this->assertStringContainsString( + 'INSERT INTO `SHP_DB`.`TBL_NAME` (`SPATIAL`) VALUES', + $GLOBALS['sql_query'] + ); } - $this->assertStringContainsString("GeomFromText('POINT(1294523.1759236", $sql_query); + $this->assertStringContainsString("GeomFromText('POINT(1294523.1759236", $GLOBALS['sql_query']); //asset that all databases and tables are imported - $this->assertMessages($import_notice); + $this->assertMessages($GLOBALS['import_notice']); } /** diff --git a/test/classes/Plugins/Import/ImportSqlTest.php b/test/classes/Plugins/Import/ImportSqlTest.php index 6222cf9cd1..94853c7201 100644 --- a/test/classes/Plugins/Import/ImportSqlTest.php +++ b/test/classes/Plugins/Import/ImportSqlTest.php @@ -24,7 +24,18 @@ class ImportSqlTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; + $GLOBALS['error'] = null; + $GLOBALS['timeout_passed'] = null; + $GLOBALS['maximum_time'] = null; + $GLOBALS['charset_conversion'] = null; + $GLOBALS['skip_queries'] = null; + $GLOBALS['max_sql_len'] = null; + $GLOBALS['sql_query'] = ''; + $GLOBALS['executed_queries'] = null; + $GLOBALS['run_query'] = null; + $GLOBALS['go_sql'] = null; $this->object = new ImportSql(); @@ -59,8 +70,8 @@ class ImportSqlTest extends AbstractTestCase public function testDoImport(): void { //$sql_query_disabled will show the import SQL detail - global $sql_query, $sql_query_disabled; - $sql_query_disabled = false; + + $GLOBALS['sql_query_disabled'] = false; //Mock DBI $dbi = $this->getMockBuilder(DatabaseInterface::class) @@ -75,11 +86,11 @@ class ImportSqlTest extends AbstractTestCase $this->object->doImport($importHandle); //asset that all sql are executed - $this->assertStringContainsString('SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"', $sql_query); - $this->assertStringContainsString('CREATE TABLE IF NOT EXISTS `pma_bookmark`', $sql_query); + $this->assertStringContainsString('SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"', $GLOBALS['sql_query']); + $this->assertStringContainsString('CREATE TABLE IF NOT EXISTS `pma_bookmark`', $GLOBALS['sql_query']); $this->assertStringContainsString( 'INSERT INTO `pma_bookmark` (`id`, `dbase`, `user`, `label`, `query`) VALUES', - $sql_query + $GLOBALS['sql_query'] ); $this->assertTrue($GLOBALS['finished']); diff --git a/test/classes/Plugins/Import/ImportXmlTest.php b/test/classes/Plugins/Import/ImportXmlTest.php index c90bb97e1c..17c80d8c38 100644 --- a/test/classes/Plugins/Import/ImportXmlTest.php +++ b/test/classes/Plugins/Import/ImportXmlTest.php @@ -28,7 +28,20 @@ class ImportXmlTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; + $GLOBALS['error'] = null; + $GLOBALS['timeout_passed'] = null; + $GLOBALS['maximum_time'] = null; + $GLOBALS['charset_conversion'] = null; + $GLOBALS['db'] = ''; + $GLOBALS['skip_queries'] = null; + $GLOBALS['max_sql_len'] = null; + $GLOBALS['sql_query_disabled'] = null; + $GLOBALS['sql_query'] = ''; + $GLOBALS['executed_queries'] = null; + $GLOBALS['run_query'] = null; + $GLOBALS['go_sql'] = null; $this->object = new ImportXml(); @@ -91,7 +104,6 @@ class ImportXmlTest extends AbstractTestCase public function testDoImport(): void { //$import_notice will show the import detail result - global $import_notice; //Mock DBI $dbi = $this->getMockBuilder(DatabaseInterface::class) @@ -121,12 +133,12 @@ class ImportXmlTest extends AbstractTestCase //asset that all databases and tables are imported $this->assertStringContainsString( 'The following structures have either been created or altered.', - $import_notice + $GLOBALS['import_notice'] ); - $this->assertStringContainsString('Go to database: `phpmyadmintest`', $import_notice); - $this->assertStringContainsString('Edit settings for `phpmyadmintest`', $import_notice); - $this->assertStringContainsString('Go to table: `pma_bookmarktest`', $import_notice); - $this->assertStringContainsString('Edit settings for `pma_bookmarktest`', $import_notice); + $this->assertStringContainsString('Go to database: `phpmyadmintest`', $GLOBALS['import_notice']); + $this->assertStringContainsString('Edit settings for `phpmyadmintest`', $GLOBALS['import_notice']); + $this->assertStringContainsString('Go to table: `pma_bookmarktest`', $GLOBALS['import_notice']); + $this->assertStringContainsString('Edit settings for `pma_bookmarktest`', $GLOBALS['import_notice']); $this->assertTrue($GLOBALS['finished']); } } diff --git a/test/classes/Plugins/Schema/DiaRelationSchemaTest.php b/test/classes/Plugins/Schema/DiaRelationSchemaTest.php index 679c8b8a0b..a295ed1a27 100644 --- a/test/classes/Plugins/Schema/DiaRelationSchemaTest.php +++ b/test/classes/Plugins/Schema/DiaRelationSchemaTest.php @@ -23,6 +23,7 @@ class DiaRelationSchemaTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $_REQUEST['page_number'] = 33; $_REQUEST['dia_show_color'] = true; $_REQUEST['dia_show_keys'] = true; diff --git a/test/classes/Plugins/Schema/EpsRelationSchemaTest.php b/test/classes/Plugins/Schema/EpsRelationSchemaTest.php index aaaeb11612..0a52c0c512 100644 --- a/test/classes/Plugins/Schema/EpsRelationSchemaTest.php +++ b/test/classes/Plugins/Schema/EpsRelationSchemaTest.php @@ -22,6 +22,7 @@ class EpsRelationSchemaTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $_REQUEST['page_number'] = 33; $_REQUEST['eps_show_color'] = true; $_REQUEST['eps_show_keys'] = true; diff --git a/test/classes/Plugins/Schema/ExportRelationSchemaTest.php b/test/classes/Plugins/Schema/ExportRelationSchemaTest.php index bca05ad3a6..52bdf6a217 100644 --- a/test/classes/Plugins/Schema/ExportRelationSchemaTest.php +++ b/test/classes/Plugins/Schema/ExportRelationSchemaTest.php @@ -22,6 +22,7 @@ class ExportRelationSchemaTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $_REQUEST['page_number'] = 33; $this->object = new ExportRelationSchema('information_schema', null); } diff --git a/test/classes/Plugins/Schema/PdfRelationSchemaTest.php b/test/classes/Plugins/Schema/PdfRelationSchemaTest.php index c43e21431d..6753923df8 100644 --- a/test/classes/Plugins/Schema/PdfRelationSchemaTest.php +++ b/test/classes/Plugins/Schema/PdfRelationSchemaTest.php @@ -22,6 +22,7 @@ class PdfRelationSchemaTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $_REQUEST['page_number'] = 33; $_REQUEST['pdf_show_grid'] = true; $_REQUEST['pdf_show_color'] = true; diff --git a/test/classes/Plugins/Schema/SvgRelationSchemaTest.php b/test/classes/Plugins/Schema/SvgRelationSchemaTest.php index 1d3610cf56..d9ffae446c 100644 --- a/test/classes/Plugins/Schema/SvgRelationSchemaTest.php +++ b/test/classes/Plugins/Schema/SvgRelationSchemaTest.php @@ -23,6 +23,7 @@ class SvgRelationSchemaTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $_REQUEST['page_number'] = 33; $_REQUEST['svg_show_color'] = true; $_REQUEST['svg_show_keys'] = true; diff --git a/test/classes/Plugins/Transformations/TransformationPluginsTest.php b/test/classes/Plugins/Transformations/TransformationPluginsTest.php index 5a9344bef9..dfdcdadf0a 100644 --- a/test/classes/Plugins/Transformations/TransformationPluginsTest.php +++ b/test/classes/Plugins/Transformations/TransformationPluginsTest.php @@ -49,9 +49,9 @@ class TransformationPluginsTest extends AbstractTestCase parent::setUp(); parent::setLanguage(); // For Application Octetstream Download plugin - global $row, $fields_meta; - $fields_meta = []; - $row = [ + + $GLOBALS['fields_meta'] = []; + $GLOBALS['row'] = [ 'pma' => 'aaa', 'pca' => 'bbb', ]; diff --git a/test/classes/PluginsTest.php b/test/classes/PluginsTest.php index 697d82e48a..02f7c42ef6 100644 --- a/test/classes/PluginsTest.php +++ b/test/classes/PluginsTest.php @@ -4,20 +4,28 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests; +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Export; use PhpMyAdmin\Plugins; +use PhpMyAdmin\Transformations; /** * @covers \PhpMyAdmin\Plugins */ class PluginsTest extends AbstractTestCase { - public function testGetExport(): void + protected function setUp(): void { - global $plugin_param; + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + parent::loadDbiIntoContainerBuilder(); + } + public function testGetExport(): void + { $GLOBALS['server'] = 1; $plugins = Plugins::getExport('database', false); - $this->assertEquals(['export_type' => 'database', 'single_table' => false], $plugin_param); + $this->assertEquals(['export_type' => 'database', 'single_table' => false], $GLOBALS['plugin_param']); $this->assertIsArray($plugins); $this->assertCount(14, $plugins); $this->assertContainsOnlyInstancesOf(Plugins\ExportPlugin::class, $plugins); @@ -25,10 +33,8 @@ class PluginsTest extends AbstractTestCase public function testGetImport(): void { - global $plugin_param; - $plugins = Plugins::getImport('database'); - $this->assertEquals('database', $plugin_param); + $this->assertEquals('database', $GLOBALS['plugin_param']); $this->assertIsArray($plugins); $this->assertCount(6, $plugins); $this->assertContainsOnlyInstancesOf(Plugins\ImportPlugin::class, $plugins); @@ -56,21 +62,19 @@ class PluginsTest extends AbstractTestCase string $option, ?bool $timeoutPassed ): void { - global $cfg, $strLatexContinued, $strLatexStructure, $timeout_passed; - $_GET = []; $_REQUEST = []; if ($timeoutPassed !== null) { - $timeout_passed = $timeoutPassed; + $GLOBALS['timeout_passed'] = $timeoutPassed; $_REQUEST[$option] = $actualGet; } elseif ($actualGet !== null) { $_GET[$option] = $actualGet; } - $strLatexContinued = '(continued)'; - $strLatexStructure = 'Structure of table @TABLE@'; + $GLOBALS['strLatexContinued'] = '(continued)'; + $GLOBALS['strLatexStructure'] = 'Structure of table @TABLE@'; /** @psalm-suppress InvalidArrayOffset, PossiblyInvalidArrayAssignment */ - $cfg[$section][$option] = $actualConfig; + $GLOBALS['cfg'][$section][$option] = $actualConfig; $default = Plugins::getDefault($section, $option); $this->assertSame($expected, $default); } @@ -102,15 +106,29 @@ class PluginsTest extends AbstractTestCase public function testGetChoice(): void { - global $plugin_param; - $GLOBALS['server'] = 1; - $plugin_param = ['export_type' => 'database', 'single_table' => false]; + $GLOBALS['plugin_param'] = ['export_type' => 'database', 'single_table' => false]; $exportList = [ - new Plugins\Export\ExportJson(), - new Plugins\Export\ExportOds(), - new Plugins\Export\ExportSql(), - new Plugins\Export\ExportXml(), + new Plugins\Export\ExportJson( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ), + new Plugins\Export\ExportOds( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ), + new Plugins\Export\ExportSql( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ), + new Plugins\Export\ExportXml( + new Relation($GLOBALS['dbi']), + new Export($GLOBALS['dbi']), + new Transformations() + ), ]; $actual = Plugins::getChoice($exportList, 'xml'); $expected = [ diff --git a/test/classes/ProfilingTest.php b/test/classes/ProfilingTest.php index eb73b8711c..7a286bb628 100644 --- a/test/classes/ProfilingTest.php +++ b/test/classes/ProfilingTest.php @@ -14,16 +14,15 @@ class ProfilingTest extends AbstractTestCase { public function testIsSupported(): void { - global $dbi, $server; - - $server = 1; + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + $GLOBALS['server'] = 1; SessionCache::set('profiling_supported', true); - $condition = Profiling::isSupported($dbi); + $condition = Profiling::isSupported($GLOBALS['dbi']); $this->assertTrue($condition); SessionCache::set('profiling_supported', false); - $condition = Profiling::isSupported($dbi); + $condition = Profiling::isSupported($GLOBALS['dbi']); $this->assertFalse($condition); } } diff --git a/test/classes/ReplicationGuiTest.php b/test/classes/ReplicationGuiTest.php index 11f0136205..7f3e366237 100644 --- a/test/classes/ReplicationGuiTest.php +++ b/test/classes/ReplicationGuiTest.php @@ -27,6 +27,7 @@ class ReplicationGuiTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); //$_POST $_POST['primary_add_user'] = 'primary_add_user'; diff --git a/test/classes/ResponseTest.php b/test/classes/ResponseTest.php index 4593b06bee..6a59f26cdf 100644 --- a/test/classes/ResponseTest.php +++ b/test/classes/ResponseTest.php @@ -14,6 +14,7 @@ class ResponseTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['lang'] = 'en'; $GLOBALS['server'] = 1; diff --git a/test/classes/RoutingTest.php b/test/classes/RoutingTest.php index b632837f02..7bc7db5852 100644 --- a/test/classes/RoutingTest.php +++ b/test/classes/RoutingTest.php @@ -68,62 +68,4 @@ class RoutingTest extends AbstractTestCase $this->assertInstanceOf(Dispatcher::class, $dispatcher); $this->assertSame($expected, $dispatcher->dispatch('GET', '/')); } - - /** - * Test for Routing::getCurrentRoute - */ - public function testGetCurrentRouteNoParams(): void - { - $this->assertSame('/', Routing::getCurrentRoute()); - } - - /** - * Test for Routing::getCurrentRoute - */ - public function testGetCurrentRouteGet(): void - { - $_GET['route'] = '/test'; - $this->assertSame('/test', Routing::getCurrentRoute()); - } - - /** - * Test for Routing::getCurrentRoute - */ - public function testGetCurrentRoutePost(): void - { - unset($_GET['route']); - $_POST['route'] = '/testpost'; - $this->assertSame('/testpost', Routing::getCurrentRoute()); - } - - /** - * Test for Routing::getCurrentRoute - */ - public function testGetCurrentRouteGetIsOverPost(): void - { - $_GET['route'] = '/testget'; - $_POST['route'] = '/testpost'; - $this->assertSame('/testget', Routing::getCurrentRoute()); - } - - /** - * Test for Routing::getCurrentRoute - */ - public function testGetCurrentRouteRedirectDbStructure(): void - { - unset($_POST['route']); - unset($_GET['route']); - $_GET['db'] = 'testDB'; - $this->assertSame('/database/structure', Routing::getCurrentRoute()); - } - - /** - * Test for Routing::getCurrentRoute - */ - public function testGetCurrentRouteRedirectSql(): void - { - $_GET['db'] = 'testDB'; - $_GET['table'] = 'tableTest'; - $this->assertSame('/sql', Routing::getCurrentRoute()); - } } diff --git a/test/classes/SanitizeTest.php b/test/classes/SanitizeTest.php index 8242733b7b..3c4fe6b5a5 100644 --- a/test/classes/SanitizeTest.php +++ b/test/classes/SanitizeTest.php @@ -42,7 +42,7 @@ class SanitizeTest extends AbstractTestCase unset($GLOBALS['server']); unset($GLOBALS['lang']); $this->assertEquals( - '<a href="./url.php?url=https%3A%2F%2Fwww.phpmyadmin.net%2F" target="target">link</a>', + '<a href="index.php?route=/url&url=https%3A%2F%2Fwww.phpmyadmin.net%2F" target="target">link</a>', Sanitize::sanitizeMessage('[a@https://www.phpmyadmin.net/@target]link[/a]') ); @@ -60,7 +60,7 @@ class SanitizeTest extends AbstractTestCase public function testDoc(string $link, string $expected): void { $this->assertEquals( - '<a href="./url.php?url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2Flatest%2F' + '<a href="index.php?route=/url&url=https%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2Flatest%2F' . $expected . '" target="documentation">doclink</a>', Sanitize::sanitizeMessage('[doc@' . $link . ']doclink[/doc]') ); @@ -121,7 +121,7 @@ class SanitizeTest extends AbstractTestCase public function testLinkAndXssInHref(): void { $this->assertEquals( - '<a href="./url.php?url=https%3A%2F%2Fdocs.phpmyadmin.net%2F">doc</a>' + '<a href="index.php?route=/url&url=https%3A%2F%2Fdocs.phpmyadmin.net%2F">doc</a>' . '[a@javascript:alert(\'XSS\');@target]link</a>', Sanitize::sanitizeMessage( '[a@https://docs.phpmyadmin.net/]doc[/a][a@javascript:alert(\'XSS\');@target]link[/a]' @@ -402,13 +402,13 @@ class SanitizeTest extends AbstractTestCase ], [ false, - './url.php?url=https://example.com', + 'index.php?route=/url&url=https://example.com', false, false, ], [ true, - './url.php?url=https%3a%2f%2fexample.com', + 'index.php?route=/url&url=https%3a%2f%2fexample.com', false, false, ], diff --git a/test/classes/ScriptsTest.php b/test/classes/ScriptsTest.php index 30ad0a4578..37f5e838af 100644 --- a/test/classes/ScriptsTest.php +++ b/test/classes/ScriptsTest.php @@ -52,7 +52,7 @@ class ScriptsTest extends AbstractTestCase $actual ); $this->assertStringContainsString('.add(\'common.js\', 1)', $actual); - $this->assertStringContainsString('AJAX.fireOnload(\'common.js\')', $actual); + $this->assertStringContainsString('window.AJAX.fireOnload(\'common.js\')', $actual); } /** diff --git a/test/classes/Server/PluginsTest.php b/test/classes/Server/PluginsTest.php index 620aeed64b..98deec792e 100644 --- a/test/classes/Server/PluginsTest.php +++ b/test/classes/Server/PluginsTest.php @@ -18,6 +18,12 @@ class PluginsTest extends AbstractTestCase /** @var Plugins */ private $plugins; + protected function setUp(): void + { + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + } + public function testGetAll(): void { $GLOBALS['cfg']['MaxCharactersInDisplayedSQL'] = 1000; diff --git a/test/classes/Server/PrivilegesTest.php b/test/classes/Server/PrivilegesTest.php index cee9e1e941..2a2a1ebba7 100644 --- a/test/classes/Server/PrivilegesTest.php +++ b/test/classes/Server/PrivilegesTest.php @@ -6,7 +6,6 @@ namespace PhpMyAdmin\Tests\Server; use mysqli_result; use mysqli_stmt; -use PhpMyAdmin\Config; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\ConfigStorage\RelationCleanup; use PhpMyAdmin\ConfigStorage\RelationParameters; @@ -34,109 +33,29 @@ use function implode; */ class PrivilegesTest extends AbstractTestCase { - /** @var Privileges $serverPrivileges */ - private $serverPrivileges; + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; - /** - * Prepares environment for the test. - */ protected function setUp(): void { parent::setUp(); - parent::setLanguage(); - parent::setGlobalConfig(); - parent::setTheme(); - $GLOBALS['cfg']['Server']['DisableIS'] = false; - $GLOBALS['table'] = 'table'; - $GLOBALS['server'] = 1; - $GLOBALS['db'] = 'db'; - $GLOBALS['hostname'] = 'hostname'; - $GLOBALS['username'] = 'username'; - - $relation = new Relation($GLOBALS['dbi']); - $this->serverPrivileges = new Privileges( - new Template(), - $GLOBALS['dbi'], - $relation, - new RelationCleanup($GLOBALS['dbi'], $relation), - new Plugins($GLOBALS['dbi']) - ); - - $_POST['pred_password'] = 'none'; - - $_SESSION['relation'] = []; - $_SESSION['relation'][$GLOBALS['server']] = RelationParameters::fromArray([ - 'db' => 'pmadb', - 'users' => 'users', - 'usergroups' => 'usergroups', - 'menuswork' => true, - 'trackingwork' => true, - 'tracking' => 'tracking', - ])->toArray(); - - $pmaconfig = $this->getMockBuilder(Config::class) - ->disableOriginalConstructor() - ->getMock(); - - $GLOBALS['config'] = $pmaconfig; - - //Mock DBI - $dbi = $this->getMockBuilder(DatabaseInterface::class) - ->disableOriginalConstructor() - ->getMock(); - - $dbi->expects($this->any()) - ->method('fetchResult') - ->will( - $this->returnValue( - [ - 'grant user1 select', - 'grant user2 delete', - ] - ) - ); - - $fetchSingleRow = [ - 'password' => 'pma_password', - 'Table_priv' => 'pri1, pri2', - 'Type' => 'Type', - '@@old_passwords' => 0, - ]; - $dbi->expects($this->any())->method('fetchSingleRow') - ->will($this->returnValue($fetchSingleRow)); - - $fetchValue = ['key1' => 'value1']; - $dbi->expects($this->any())->method('fetchValue') - ->will($this->returnValue($fetchValue)); - - $resultStub = $this->createMock(DummyResult::class); - - $dbi->expects($this->any())->method('tryQuery') - ->will($this->returnValue($resultStub)); - - $dbi->expects($this->any())->method('escapeString') - ->will($this->returnArgument(0)); - - $dbi->expects($this->any())->method('isCreateUser') - ->will($this->returnValue(true)); - $dbi->expects($this->any())->method('isGrantUser') - ->will($this->returnValue(true)); - - $GLOBALS['dbi'] = $dbi; - $this->serverPrivileges->dbi = $dbi; - $this->serverPrivileges->relation->dbi = $dbi; - $GLOBALS['is_reload_priv'] = true; + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; } - /** - * Test for getDataForDBInfo - */ public function testGetDataForDBInfo(): void { $_REQUEST['username'] = 'PMA_username'; $_REQUEST['hostname'] = 'PMA_hostname'; $_REQUEST['tablename'] = 'PMA_tablename'; $_REQUEST['dbname'] = 'PMA_dbname'; + + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface()); + [ $username, $hostname, @@ -145,7 +64,7 @@ class PrivilegesTest extends AbstractTestCase $routinename, $db_and_table, $dbname_is_wildcard, - ] = $this->serverPrivileges->getDataForDBInfo(); + ] = $serverPrivileges->getDataForDBInfo(); $this->assertEquals('PMA_username', $username); $this->assertEquals('PMA_hostname', $hostname); $this->assertEquals('PMA_dbname', $dbname); @@ -162,7 +81,7 @@ class PrivilegesTest extends AbstractTestCase $routinename, $db_and_table, $dbname_is_wildcard, - ] = $this->serverPrivileges->getDataForDBInfo(); + ] = $serverPrivileges->getDataForDBInfo(); $this->assertEquals('PMA_pred_dbname', $dbname); $this->assertEquals('PMA_pred__tablename', $tablename); $this->assertEquals('`PMA_pred_dbname`.`PMA_pred__tablename`', $db_and_table); @@ -177,7 +96,7 @@ class PrivilegesTest extends AbstractTestCase $routinename, $db_and_table, $dbname_is_wildcard, - ] = $this->serverPrivileges->getDataForDBInfo(); + ] = $serverPrivileges->getDataForDBInfo(); $this->assertEquals('PMA\_pred\_dbname', $dbname); $this->assertEquals('PMA_pred__tablename', $tablename); $this->assertEquals('`PMA_pred_dbname`.`PMA_pred__tablename`', $db_and_table); @@ -191,7 +110,7 @@ class PrivilegesTest extends AbstractTestCase $tablename,, $db_and_table, $dbname_is_wildcard, - ] = $this->serverPrivileges->getDataForDBInfo(); + ] = $serverPrivileges->getDataForDBInfo(); $this->assertEquals(['PMA\_pred\_dbname', 'PMADbname2'], $dbname); $this->assertEquals(null, $tablename); $this->assertEquals(['PMA\_pred\_dbname.*', 'PMADbname2.*'], $db_and_table); @@ -205,52 +124,49 @@ class PrivilegesTest extends AbstractTestCase $tablename,, $db_and_table, $dbname_is_wildcard, - ] = $this->serverPrivileges->getDataForDBInfo(); + ] = $serverPrivileges->getDataForDBInfo(); $this->assertEquals(['PMA\_dbname', 'PMADbname2'], $dbname); $this->assertEquals(null, $tablename); $this->assertEquals(['PMA\_dbname.*', 'PMADbname2.*'], $db_and_table); $this->assertEquals(false, $dbname_is_wildcard); } - /** - * Test for wildcardEscapeForGrant - */ public function testWildcardEscapeForGrant(): void { + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface()); + $dbname = ''; $tablename = ''; - $db_and_table = $this->serverPrivileges->wildcardEscapeForGrant($dbname, $tablename); + $db_and_table = $serverPrivileges->wildcardEscapeForGrant($dbname, $tablename); $this->assertEquals('*.*', $db_and_table); $dbname = 'dbname'; $tablename = ''; - $db_and_table = $this->serverPrivileges->wildcardEscapeForGrant($dbname, $tablename); + $db_and_table = $serverPrivileges->wildcardEscapeForGrant($dbname, $tablename); $this->assertEquals('`dbname`.*', $db_and_table); $dbname = 'dbname'; $tablename = 'tablename'; - $db_and_table = $this->serverPrivileges->wildcardEscapeForGrant($dbname, $tablename); + $db_and_table = $serverPrivileges->wildcardEscapeForGrant($dbname, $tablename); $this->assertEquals('`dbname`.`tablename`', $db_and_table); } - /** - * Test for rangeOfUsers - */ public function testRangeOfUsers(): void { - $ret = $this->serverPrivileges->rangeOfUsers('INIT'); - $this->assertEquals(" WHERE `User` LIKE 'INIT%' OR `User` LIKE 'init%'", $ret); + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface()); - $ret = $this->serverPrivileges->rangeOfUsers(); + $ret = $serverPrivileges->rangeOfUsers('INIT'); + $this->assertEquals(' WHERE `User` LIKE \'INIT%\' OR `User` LIKE \'init%\'', $ret); + + $ret = $serverPrivileges->rangeOfUsers(); $this->assertEquals('', $ret); } - /** - * Test for getTableGrantsArray - */ public function testGetTableGrantsArray(): void { - $ret = $this->serverPrivileges->getTableGrantsArray(); + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface()); + + $ret = $serverPrivileges->getTableGrantsArray(); $this->assertEquals( [ 'Delete', @@ -269,12 +185,11 @@ class PrivilegesTest extends AbstractTestCase ); } - /** - * Test for getGrantsArray - */ public function testGetGrantsArray(): void { - $ret = $this->serverPrivileges->getGrantsArray(); + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface()); + + $ret = $serverPrivileges->getGrantsArray(); $this->assertEquals( [ 'Select_priv', @@ -293,30 +208,30 @@ class PrivilegesTest extends AbstractTestCase ); } - /** - * Test for getSqlQueryForDisplayPrivTable - */ public function testGetSqlQueryForDisplayPrivTable(): void { + $dbi = $this->createDatabaseInterface(); + $serverPrivileges = $this->getPrivileges($dbi); + $username = 'pma_username'; $db = '*'; $table = 'pma_table'; $hostname = 'pma_hostname'; //$db == '*' - $ret = $this->serverPrivileges->getSqlQueryForDisplayPrivTable($db, $table, $username, $hostname); + $ret = $serverPrivileges->getSqlQueryForDisplayPrivTable($db, $table, $username, $hostname); $sql = 'SELECT * FROM `mysql`.`user`' - . " WHERE `User` = '" . $GLOBALS['dbi']->escapeString($username) . "'" - . " AND `Host` = '" . $GLOBALS['dbi']->escapeString($hostname) . "';"; + . " WHERE `User` = '" . $dbi->escapeString($username) . "'" + . " AND `Host` = '" . $dbi->escapeString($hostname) . "';"; $this->assertEquals($sql, $ret); //$table == '*' $db = 'pma_db'; $table = '*'; - $ret = $this->serverPrivileges->getSqlQueryForDisplayPrivTable($db, $table, $username, $hostname); + $ret = $serverPrivileges->getSqlQueryForDisplayPrivTable($db, $table, $username, $hostname); $sql = 'SELECT * FROM `mysql`.`db`' - . " WHERE `User` = '" . $GLOBALS['dbi']->escapeString($username) . "'" - . " AND `Host` = '" . $GLOBALS['dbi']->escapeString($hostname) . "'" + . " WHERE `User` = '" . $dbi->escapeString($username) . "'" + . " AND `Host` = '" . $dbi->escapeString($hostname) . "'" . ' AND `Db` = \'' . $db . '\''; $this->assertEquals($sql, $ret); @@ -324,35 +239,47 @@ class PrivilegesTest extends AbstractTestCase //$table == 'pma_table' $db = 'pma_db'; $table = 'pma_table'; - $ret = $this->serverPrivileges->getSqlQueryForDisplayPrivTable($db, $table, $username, $hostname); + $ret = $serverPrivileges->getSqlQueryForDisplayPrivTable($db, $table, $username, $hostname); $sql = 'SELECT `Table_priv`' . ' FROM `mysql`.`tables_priv`' - . " WHERE `User` = '" . $GLOBALS['dbi']->escapeString($username) . "'" - . " AND `Host` = '" . $GLOBALS['dbi']->escapeString($hostname) . "'" + . " WHERE `User` = '" . $dbi->escapeString($username) . "'" + . " AND `Host` = '" . $dbi->escapeString($hostname) . "'" . " AND `Db` = '" . Util::unescapeMysqlWildcards($db) . "'" - . " AND `Table_name` = '" . $GLOBALS['dbi']->escapeString($table) . "';"; + . " AND `Table_name` = '" . $dbi->escapeString($table) . "';"; $this->assertEquals($sql, $ret); // SQL escaping $db = "db' AND"; $table = 'pma_table'; - $ret = $this->serverPrivileges->getSqlQueryForDisplayPrivTable($db, $table, $username, $hostname); + $ret = $serverPrivileges->getSqlQueryForDisplayPrivTable($db, $table, $username, $hostname); $this->assertEquals( 'SELECT `Table_priv` FROM `mysql`.`tables_priv` ' . "WHERE `User` = 'pma_username' AND " - . "`Host` = 'pma_hostname' AND `Db` = 'db' AND' AND " + . "`Host` = 'pma_hostname' AND `Db` = 'db\' AND' AND " . "`Table_name` = 'pma_table';", $ret ); } - /** - * Test for getDataForChangeOrCopyUser - */ public function testGetDataForChangeOrCopyUser(): void { + $GLOBALS['lang'] = 'en'; + + $dummyDbi = $this->createDbiDummy(); + // phpcs:disable Generic.Files.LineLength.TooLong + $dummyDbi->addResult( + 'SELECT * FROM `mysql`.`user` WHERE `User` = \'PMA_old_username\' AND `Host` = \'PMA_old_hostname\';', + [ + ['PMA_old_hostname', 'PMA_old_username', 'pma_password', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', '', '', '', '', '0', '0', '0', '0', 'mysql_native_password', 'pma_password', 'N', 'N', '', '0.000000'], + ], + ['Host', 'User', 'Password', 'Select_priv', 'Insert_priv', 'Update_priv', 'Delete_priv', 'Create_priv', 'Drop_priv', 'Reload_priv', 'Shutdown_priv', 'Process_priv', 'File_priv', 'Grant_priv', 'References_priv', 'Index_priv', 'Alter_priv', 'Show_db_priv', 'Super_priv', 'Create_tmp_table_priv', 'Lock_tables_priv', 'Execute_priv', 'Repl_slave_priv', 'Repl_client_priv', 'Create_view_priv', 'Show_view_priv', 'Create_routine_priv', 'Alter_routine_priv', 'Create_user_priv', 'Event_priv', 'Trigger_priv', 'Create_tablespace_priv', 'Delete_history_priv', 'ssl_type', 'ssl_cipher', 'x509_issuer', 'x509_subject', 'max_questions', 'max_updates', 'max_connections', 'max_user_connections', 'plugin', 'authentication_string', 'password_expired', 'is_role', 'default_role', 'max_statement_time'] + ); + // phpcs:enable + + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface($dummyDbi)); + //$_POST['change_copy'] not set - [$queries, $password] = $this->serverPrivileges->getDataForChangeOrCopyUser(); + [$queries, $password] = $serverPrivileges->getDataForChangeOrCopyUser(); $this->assertEquals(null, $queries); $this->assertEquals(null, $queries); @@ -360,7 +287,7 @@ class PrivilegesTest extends AbstractTestCase $_POST['change_copy'] = true; $_POST['old_username'] = 'PMA_old_username'; $_POST['old_hostname'] = 'PMA_old_hostname'; - [$queries, $password] = $this->serverPrivileges->getDataForChangeOrCopyUser(); + [$queries, $password] = $serverPrivileges->getDataForChangeOrCopyUser(); $this->assertEquals('pma_password', $password); $this->assertEquals( [], @@ -369,15 +296,20 @@ class PrivilegesTest extends AbstractTestCase unset($_POST['change_copy']); } - /** - * Test for getListForExportUserDefinition - */ public function testGetHtmlForExportUserDefinition(): void { + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addResult( + 'SHOW GRANTS FOR \'PMA_username\'@\'PMA_hostname\'', + [['grant user2 delete'], ['grant user1 select']], + ['Grants for PMA_username@PMA_hostname'] + ); + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface($dummyDbi)); + $username = 'PMA_username'; $hostname = 'PMA_hostname'; - [$title, $export] = $this->serverPrivileges->getListForExportUserDefinition($username, $hostname); + [$title, $export] = $serverPrivileges->getListForExportUserDefinition($username, $hostname); //validate 1: $export $this->assertStringContainsString('grant user2 delete', $export); @@ -390,15 +322,24 @@ class PrivilegesTest extends AbstractTestCase $this->assertStringContainsString($title_user, $title); } - /** - * Test for addUser - */ public function testAddUser(): void { - // Case 1 : Test with Newer version - $GLOBALS['dbi']->expects($this->any())->method('getVersion') - ->will($this->returnValue(50706)); - $this->serverPrivileges->dbi = $GLOBALS['dbi']; + $GLOBALS['cfg']['Server']['DisableIS'] = false; + $GLOBALS['username'] = 'pma_username'; + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addResult('SELECT \'1\' FROM `mysql`.`user` WHERE `User` = \'\' AND `Host` = \'localhost\';', []); + $dummyDbi->addResult('SET `old_passwords` = 0;', []); + $dummyDbi->addResult( + 'CREATE USER \'\'@\'localhost\' IDENTIFIED WITH mysql_native_password AS \'pma_dbname\';', + [] + ); + $dummyDbi->addResult('GRANT USAGE ON *.* TO \'\'@\'localhost\' REQUIRE NONE;', []); + $dummyDbi->addResult('GRANT ALL PRIVILEGES ON `pma_dbname`.* TO \'\'@\'localhost\';', []); + + $dbi = $this->createDatabaseInterface($dummyDbi); + $dbi->setVersion(50706); + $serverPrivileges = $this->getPrivileges($dbi); $dbname = 'pma_dbname'; $username = 'pma_username'; @@ -415,7 +356,7 @@ class PrivilegesTest extends AbstractTestCase $ret_message,,, $sql_query, $_add_user_error, - ] = $this->serverPrivileges->addUser($dbname, $username, $hostname, $dbname, true); + ] = $serverPrivileges->addUser($dbname, $username, $hostname, $dbname, true); $this->assertEquals( 'You have added a new user.', $ret_message->getMessage() @@ -429,15 +370,24 @@ class PrivilegesTest extends AbstractTestCase $this->assertFalse($_add_user_error); } - /** - * Test for addUser - */ public function testAddUserOld(): void { - $GLOBALS['dbi']->expects($this->any())->method('getVersion') - ->will($this->returnValue(50506)); - $this->serverPrivileges->dbi = $GLOBALS['dbi']; + $GLOBALS['cfg']['Server']['DisableIS'] = false; + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addResult('SELECT \'1\' FROM `mysql`.`user` WHERE `User` = \'\' AND `Host` = \'localhost\';', []); + $dummyDbi->addResult('SET `old_passwords` = 0;', []); + $dummyDbi->addResult('CREATE USER \'\'@\'localhost\';', []); + $dummyDbi->addResult('SET `old_passwords` = 0;', []); + $dummyDbi->addResult('SET PASSWORD FOR \'\'@\'localhost\' = \'pma_dbname\';', []); + $dummyDbi->addResult('GRANT USAGE ON *.* TO \'\'@\'localhost\' REQUIRE NONE;', []); + $dummyDbi->addResult('GRANT ALL PRIVILEGES ON `pma_dbname`.* TO \'\'@\'localhost\';', []); + + $dbi = $this->createDatabaseInterface($dummyDbi); + $dbi->setVersion(50506); + $serverPrivileges = $this->getPrivileges($dbi); + $GLOBALS['username'] = 'username'; $dbname = 'pma_dbname'; $username = 'pma_username'; $hostname = 'pma_hostname'; @@ -453,7 +403,7 @@ class PrivilegesTest extends AbstractTestCase $ret_message,,, $sql_query, $_add_user_error, - ] = $this->serverPrivileges->addUser($dbname, $username, $hostname, $dbname, true); + ] = $serverPrivileges->addUser($dbname, $username, $hostname, $dbname, true); $this->assertEquals( 'You have added a new user.', @@ -469,18 +419,23 @@ class PrivilegesTest extends AbstractTestCase $this->assertFalse($_add_user_error); } - /** - * Test for updatePassword - */ public function testUpdatePassword(): void { + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addResult( + 'ALTER USER \'pma_username\'@\'pma_hostname\' IDENTIFIED WITH mysql_native_password BY \'pma_pw\'', + [] + ); + $dummyDbi->addResult('FLUSH PRIVILEGES;', []); + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface($dummyDbi)); + $username = 'pma_username'; $hostname = 'pma_hostname'; $err_url = 'error.php'; $_POST['pma_pw'] = 'pma_pw'; $_POST['authentication_plugin'] = 'mysql_native_password'; - $message = $this->serverPrivileges->updatePassword($err_url, $username, $hostname); + $message = $serverPrivileges->updatePassword($err_url, $username, $hostname); $this->assertEquals( 'The password for \'pma_username\'@\'pma_hostname\' was changed successfully.', @@ -488,11 +443,20 @@ class PrivilegesTest extends AbstractTestCase ); } - /** - * Test for getMessageAndSqlQueryForPrivilegesRevoke - */ public function testGetMessageAndSqlQueryForPrivilegesRevoke(): void { + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addResult( + 'REVOKE ALL PRIVILEGES ON `pma_dbname`.`pma_tablename` FROM \'pma_username\'@\'pma_hostname\';', + [] + ); + $dummyDbi->addResult( + 'REVOKE GRANT OPTION ON `pma_dbname`.`pma_tablename` FROM \'pma_username\'@\'pma_hostname\';', + [] + ); + + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface($dummyDbi)); + $dbname = 'pma_dbname'; $username = 'pma_username'; $hostname = 'pma_hostname'; @@ -503,7 +467,7 @@ class PrivilegesTest extends AbstractTestCase $_POST['createdb-3'] = true; $_POST['Grant_priv'] = 'Y'; $_POST['max_questions'] = 1000; - [$message, $sql_query] = $this->serverPrivileges->getMessageAndSqlQueryForPrivilegesRevoke( + [$message, $sql_query] = $serverPrivileges->getMessageAndSqlQueryForPrivilegesRevoke( $dbname, $tablename, $username, @@ -524,11 +488,15 @@ class PrivilegesTest extends AbstractTestCase ); } - /** - * Test for updatePrivileges - */ public function testUpdatePrivileges(): void { + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addResult( + 'REVOKE ALL PRIVILEGES ON `pma_dbname`.`pma_tablename` FROM \'pma_username\'@\'pma_hostname\';', + [] + ); + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface($dummyDbi)); + $dbname = 'pma_dbname'; $username = 'pma_username'; $hostname = 'pma_hostname'; @@ -539,7 +507,7 @@ class PrivilegesTest extends AbstractTestCase $_POST['createdb-3'] = true; $_POST['Grant_priv'] = 'Y'; $_POST['max_questions'] = 1000; - [$sql_query, $message] = $this->serverPrivileges->updatePrivileges( + [$sql_query, $message] = $serverPrivileges->updatePrivileges( $username, $hostname, $tablename, @@ -557,11 +525,11 @@ class PrivilegesTest extends AbstractTestCase ); } - /** - * Test for updatePrivileges - */ public function testUpdatePrivilegesBeforeMySql8Dot11(): void { + $dbi = $this->createDatabaseInterface(); + $serverPrivileges = $this->getPrivileges($dbi); + $dbname = ''; $username = 'pma_username'; $hostname = 'pma_hostname'; @@ -586,9 +554,9 @@ class PrivilegesTest extends AbstractTestCase ->method('escapeString') ->will($this->returnArgument(0)); - $this->serverPrivileges->dbi = $dbi; + $serverPrivileges->dbi = $dbi; - [$sql_query, $message] = $this->serverPrivileges->updatePrivileges( + [$sql_query, $message] = $serverPrivileges->updatePrivileges( $username, $hostname, $tablename, @@ -608,11 +576,10 @@ class PrivilegesTest extends AbstractTestCase ); } - /** - * Test for updatePrivileges - */ public function testUpdatePrivilegesAfterMySql8Dot11(): void { + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface()); + $dbname = ''; $username = 'pma_username'; $hostname = 'pma_hostname'; @@ -637,9 +604,9 @@ class PrivilegesTest extends AbstractTestCase ->method('escapeString') ->will($this->returnArgument(0)); - $this->serverPrivileges->dbi = $dbi; + $serverPrivileges->dbi = $dbi; - [$sql_query, $message] = $this->serverPrivileges->updatePrivileges( + [$sql_query, $message] = $serverPrivileges->updatePrivileges( $username, $hostname, $tablename, @@ -661,43 +628,25 @@ class PrivilegesTest extends AbstractTestCase } /** - * Test for getHtmlToDisplayPrivilegesTable - * * @group medium */ public function testGetHtmlToDisplayPrivilegesTable(): void { $GLOBALS['hostname'] = 'hostname'; $GLOBALS['username'] = 'username'; - $GLOBALS['dbi'] = DatabaseInterface::load(new DbiDummy()); + $dbi = DatabaseInterface::load(new DbiDummy()); - $relation = new Relation($GLOBALS['dbi']); - $serverPrivileges = new Privileges( - new Template(), - $GLOBALS['dbi'], - $relation, - new RelationCleanup($GLOBALS['dbi'], $relation), - new Plugins($GLOBALS['dbi']) - ); + $serverPrivileges = $this->getPrivileges($dbi); $html = $serverPrivileges->getHtmlToDisplayPrivilegesTable(); $GLOBALS['username'] = 'username'; - //validate 1: fieldset - $this->assertStringContainsString( - '<fieldset id="fieldset_user_privtable_footer" class="pma-fieldset tblFooters">', - $html - ); - //validate 2: button - $this->assertStringContainsString( - __('Go'), - $html - ); + $this->assertStringContainsString('Update user privileges', $html); //validate 3: getHtmlForGlobalOrDbSpecificPrivs - $this->assertStringContainsString('<fieldset class="pma-fieldset" id="fieldset_user_global_rights">', $html); + $this->assertStringContainsString('<div class="card">', $html); $this->assertStringContainsString( - '<legend data-submenu-label="' . __('Global') . '">', + '<div class="card-header js-submenu-label" data-submenu-label="' . __('Global') . '">', $html ); $this->assertStringContainsString( @@ -731,7 +680,7 @@ class PrivilegesTest extends AbstractTestCase //validate 5: getHtmlForResourceLimits $this->assertStringContainsString( - '<legend>' . __('Resource limits') . '</legend>', + '<div class="card-header">' . __('Resource limits') . '</div>', $html ); $this->assertStringContainsString( @@ -749,21 +698,22 @@ class PrivilegesTest extends AbstractTestCase $html ); - $this->assertStringContainsString('<legend>SSL</legend>', $html); + $this->assertStringContainsString('<div class="card-header">SSL</div>', $html); $this->assertStringContainsString('value="NONE"', $html); $this->assertStringContainsString('value="ANY"', $html); $this->assertStringContainsString('value="X509"', $html); $this->assertStringContainsString('value="SPECIFIED"', $html); } - /** - * Test case for getSqlQueriesForDisplayAndAddUser - */ public function testGetSqlQueriesForDisplayAndAddUserMySql8011(): void { - $GLOBALS['dbi']->expects($this->any())->method('getVersion') - ->will($this->returnValue(80011)); - $this->serverPrivileges->dbi = $GLOBALS['dbi']; + $GLOBALS['cfg']['Server']['DisableIS'] = false; + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addResult('SET `old_passwords` = 0;', []); + $dbi = $this->createDatabaseInterface($dummyDbi); + $dbi->setVersion(80011); + $serverPrivileges = $this->getPrivileges($dbi); $username = 'PMA_username'; $hostname = 'PMA_hostname'; @@ -774,7 +724,7 @@ class PrivilegesTest extends AbstractTestCase [ $create_user_real, $create_user_show, - ] = $this->serverPrivileges->getSqlQueriesForDisplayAndAddUser($username, $hostname, $password); + ] = $serverPrivileges->getSqlQueriesForDisplayAndAddUser($username, $hostname, $password); //validate 1: $create_user_real $this->assertEquals( @@ -789,14 +739,13 @@ class PrivilegesTest extends AbstractTestCase ); } - /** - * Test case for getSqlQueriesForDisplayAndAddUser - */ public function testGetSqlQueriesForDisplayAndAddUserMySql8016(): void { - $GLOBALS['dbi']->expects($this->any())->method('getVersion') - ->will($this->returnValue(80016)); - $this->serverPrivileges->dbi = $GLOBALS['dbi']; + $GLOBALS['cfg']['Server']['DisableIS'] = false; + + $dbi = $this->createDatabaseInterface(); + $dbi->setVersion(80016); + $serverPrivileges = $this->getPrivileges($dbi); $username = 'PMA_username'; $hostname = 'PMA_hostname'; @@ -806,7 +755,7 @@ class PrivilegesTest extends AbstractTestCase [ $create_user_real, $create_user_show, - ] = $this->serverPrivileges->getSqlQueriesForDisplayAndAddUser($username, $hostname, $password); + ] = $serverPrivileges->getSqlQueriesForDisplayAndAddUser($username, $hostname, $password); //validate 1: $create_user_real $this->assertEquals( @@ -818,14 +767,17 @@ class PrivilegesTest extends AbstractTestCase $this->assertEquals('CREATE USER \'PMA_username\'@\'PMA_hostname\' IDENTIFIED BY \'***\';', $create_user_show); } - /** - * Test for getSqlQueriesForDisplayAndAddUser - */ public function testGetSqlQueriesForDisplayAndAddUser(): void { - $GLOBALS['dbi']->expects($this->any())->method('getVersion') - ->will($this->returnValue(50706)); - $this->serverPrivileges->dbi = $GLOBALS['dbi']; + $GLOBALS['cfg']['Server']['DisableIS'] = false; + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addResult('SET `old_passwords` = 0;', []); + $dummyDbi->addResult('GRANT USAGE ON *.* TO \'PMA_username\'@\'PMA_hostname\' REQUIRE NONE;', []); + + $dbi = $this->createDatabaseInterface($dummyDbi); + $dbi->setVersion(50706); + $serverPrivileges = $this->getPrivileges($dbi); $username = 'PMA_username'; $hostname = 'PMA_hostname'; @@ -841,7 +793,7 @@ class PrivilegesTest extends AbstractTestCase $sql_query,,, $alter_real_sql_query, $alter_sql_query, - ] = $this->serverPrivileges->getSqlQueriesForDisplayAndAddUser($username, $hostname, $password); + ] = $serverPrivileges->getSqlQueriesForDisplayAndAddUser($username, $hostname, $password); //validate 1: $create_user_real $this->assertEquals( @@ -856,17 +808,17 @@ class PrivilegesTest extends AbstractTestCase ); //validate 3:$real_sql_query - $this->assertEquals("GRANT USAGE ON *.* TO 'PMA_username'@'PMA_hostname' REQUIRE NONE;", $real_sql_query); + $this->assertEquals('GRANT USAGE ON *.* TO \'PMA_username\'@\'PMA_hostname\' REQUIRE NONE;', $real_sql_query); //validate 4:$sql_query - $this->assertEquals("GRANT USAGE ON *.* TO 'PMA_username'@'PMA_hostname' REQUIRE NONE;", $sql_query); + $this->assertEquals('GRANT USAGE ON *.* TO \'PMA_username\'@\'PMA_hostname\' REQUIRE NONE;', $sql_query); $this->assertSame('', $alter_real_sql_query); $this->assertSame('', $alter_sql_query); //Test for addUserAndCreateDatabase - [$sql_query, $message] = $this->serverPrivileges->addUserAndCreateDatabase( + [$sql_query, $message] = $serverPrivileges->addUserAndCreateDatabase( false, $real_sql_query, $sql_query, @@ -881,7 +833,7 @@ class PrivilegesTest extends AbstractTestCase ); //validate 5: $sql_query - $this->assertEquals("GRANT USAGE ON *.* TO 'PMA_username'@'PMA_hostname' REQUIRE NONE;", $sql_query); + $this->assertEquals('GRANT USAGE ON *.* TO \'PMA_username\'@\'PMA_hostname\' REQUIRE NONE;', $sql_query); $this->assertInstanceOf(Message::class, $message); @@ -892,18 +844,17 @@ class PrivilegesTest extends AbstractTestCase ); } - /** - * Test for getHtmlForTableSpecificPrivileges - */ public function testGetHtmlToDisplayPrivilegesTableWithTableSpecific(): void { - $dbi_old = $GLOBALS['dbi']; - $GLOBALS['dbi'] = DatabaseInterface::load(new DbiDummy()); - $this->serverPrivileges->dbi = $GLOBALS['dbi']; + $dbi = $this->createDatabaseInterface(); + $serverPrivileges = $this->getPrivileges($dbi); + + $dbi = DatabaseInterface::load(new DbiDummy()); + $serverPrivileges->dbi = $dbi; $GLOBALS['username'] = 'PMA_username'; $GLOBALS['hostname'] = 'PMA_hostname'; - $html = $this->serverPrivileges->getHtmlToDisplayPrivilegesTable('PMA_db', 'PMA_table'); + $html = $serverPrivileges->getHtmlToDisplayPrivilegesTable('PMA_db', 'PMA_table'); $this->assertStringContainsString('checkbox_Update_priv_none', $html); $this->assertStringContainsString('<dfn title="Allows changing data.">UPDATE</dfn>', $html); @@ -934,19 +885,15 @@ class PrivilegesTest extends AbstractTestCase _pgettext('None privileges', 'None'), $html ); - - $GLOBALS['dbi'] = $dbi_old; - $this->serverPrivileges->dbi = $dbi_old; } - /** - * Test for getHtmlForLoginInformationFields - */ public function testGetHtmlForLoginInformationFields(): void { + $dbi = $this->createDatabaseInterface(); + $serverPrivileges = $this->getPrivileges($dbi); + $GLOBALS['username'] = 'pma_username'; - $dbi_old = $GLOBALS['dbi']; $dbi = $this->getMockBuilder(DatabaseInterface::class) ->disableOriginalConstructor() ->getMock(); @@ -966,10 +913,9 @@ class PrivilegesTest extends AbstractTestCase ->method('escapeString') ->will($this->returnArgument(0)); - $GLOBALS['dbi'] = $dbi; - $this->serverPrivileges->dbi = $dbi; + $serverPrivileges->dbi = $dbi; - $html = $this->serverPrivileges->getHtmlForLoginInformationFields(); + $html = $serverPrivileges->getHtmlForLoginInformationFields(); //validate 1: __('Login Information') $this->assertStringContainsString( @@ -995,23 +941,19 @@ class PrivilegesTest extends AbstractTestCase ) ); $this->assertStringContainsString($output, $html); - - $GLOBALS['dbi'] = $dbi_old; - $this->serverPrivileges->dbi = $dbi_old; } - /** - * Test for getWithClauseForAddUserAndUpdatePrivs - */ public function testGetWithClauseForAddUserAndUpdatePrivs(): void { + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface()); + $_POST['Grant_priv'] = 'Y'; $_POST['max_questions'] = 10; $_POST['max_connections'] = 20; $_POST['max_updates'] = 30; $_POST['max_user_connections'] = 40; - $sql_query = $this->serverPrivileges->getWithClauseForAddUserAndUpdatePrivs(); + $sql_query = $serverPrivileges->getWithClauseForAddUserAndUpdatePrivs(); $expect = 'WITH GRANT OPTION MAX_QUERIES_PER_HOUR 10 ' . 'MAX_CONNECTIONS_PER_HOUR 20' . ' MAX_UPDATES_PER_HOUR 30 MAX_USER_CONNECTIONS 40'; @@ -1019,13 +961,13 @@ class PrivilegesTest extends AbstractTestCase } /** - * Test for getHtmlForAddUser - * * @group medium */ public function testGetHtmlForAddUser(): void { - $dbi_old = $GLOBALS['dbi']; + $dbi = $this->createDatabaseInterface(); + $serverPrivileges = $this->getPrivileges($dbi); + $dbi = $this->getMockBuilder(DatabaseInterface::class) ->disableOriginalConstructor() ->getMock(); @@ -1047,12 +989,11 @@ class PrivilegesTest extends AbstractTestCase $dbi->expects($this->any())->method('isGrantUser') ->will($this->returnValue(true)); - $GLOBALS['dbi'] = $dbi; - $this->serverPrivileges->dbi = $dbi; + $serverPrivileges->dbi = $dbi; $dbname = 'pma_dbname'; - $html = $this->serverPrivileges->getHtmlForAddUser($dbname); + $html = $serverPrivileges->getHtmlForAddUser($dbname); //validate 1: Url::getHiddenInputs $this->assertStringContainsString( @@ -1062,7 +1003,7 @@ class PrivilegesTest extends AbstractTestCase //validate 2: getHtmlForLoginInformationFields $this->assertStringContainsString( - $this->serverPrivileges->getHtmlForLoginInformationFields('new'), + $serverPrivileges->getHtmlForLoginInformationFields('new'), $html ); @@ -1080,31 +1021,24 @@ class PrivilegesTest extends AbstractTestCase //validate 4: getHtmlToDisplayPrivilegesTable $this->assertStringContainsString( - $this->serverPrivileges->getHtmlToDisplayPrivilegesTable('*', '*', false), + $serverPrivileges->getHtmlToDisplayPrivilegesTable('*', '*', false), $html ); //validate 5: button - $this->assertStringContainsString( - __('Go'), - $html - ); - - $GLOBALS['dbi'] = $dbi_old; - $this->serverPrivileges->dbi = $dbi_old; + $this->assertStringContainsString('Create user', $html); } - /** - * Test for getUserLink - */ public function testGetUserLink(): void { + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface()); + $username = 'pma_username'; $hostname = 'pma_hostname'; $dbname = 'pma_dbname'; $tablename = 'pma_tablename'; - $html = $this->serverPrivileges->getUserLink('edit', $username, $hostname, $dbname, $tablename, ''); + $html = $serverPrivileges->getUserLink('edit', $username, $hostname, $dbname, $tablename, ''); $dbname = 'pma_dbname'; $url_html = Url::getCommon([ @@ -1121,7 +1055,7 @@ class PrivilegesTest extends AbstractTestCase ); $dbname = 'pma_dbname'; - $html = $this->serverPrivileges->getUserLink('revoke', $username, $hostname, $dbname, $tablename, ''); + $html = $serverPrivileges->getUserLink('revoke', $username, $hostname, $dbname, $tablename, ''); $dbname = 'pma_dbname'; $url_html = Url::getCommon( @@ -1141,7 +1075,7 @@ class PrivilegesTest extends AbstractTestCase $html ); - $html = $this->serverPrivileges->getUserLink('export', $username, $hostname); + $html = $serverPrivileges->getUserLink('export', $username, $hostname); $url_html = Url::getCommon([ 'username' => $username, @@ -1156,17 +1090,16 @@ class PrivilegesTest extends AbstractTestCase ); } - /** - * Test for getUserLink - */ public function testGetUserLinkWildcardsEscaped(): void { + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface()); + $username = 'pma\_username'; $hostname = 'pma\_hostname'; $dbname = 'pma\_dbname'; $tablename = 'pma\_tablename'; - $html = $this->serverPrivileges->getUserLink('edit', $username, $hostname, $dbname, $tablename, ''); + $html = $serverPrivileges->getUserLink('edit', $username, $hostname, $dbname, $tablename, ''); $dbname = 'pma\_dbname'; $url_html = Url::getCommon([ @@ -1183,7 +1116,7 @@ class PrivilegesTest extends AbstractTestCase ); $dbname = 'pma\_dbname'; - $html = $this->serverPrivileges->getUserLink('revoke', $username, $hostname, $dbname, $tablename, ''); + $html = $serverPrivileges->getUserLink('revoke', $username, $hostname, $dbname, $tablename, ''); $dbname = 'pma\_dbname'; $url_html = Url::getCommon( @@ -1203,7 +1136,7 @@ class PrivilegesTest extends AbstractTestCase $html ); - $html = $this->serverPrivileges->getUserLink('export', $username, $hostname); + $html = $serverPrivileges->getUserLink('export', $username, $hostname); $url_html = Url::getCommon([ 'username' => $username, @@ -1218,11 +1151,15 @@ class PrivilegesTest extends AbstractTestCase ); } - /** - * Test for getExtraDataForAjaxBehavior - */ public function testGetExtraDataForAjaxBehavior(): void { + $GLOBALS['cfg']['Server']['DisableIS'] = false; + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addResult('SELECT * FROM `mysql`.`user` WHERE `User` = \'username\';', []); + + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface($dummyDbi)); + $password = 'pma_password'; $sql_query = 'pma_sql_query'; $username = 'pma_username'; @@ -1235,7 +1172,7 @@ class PrivilegesTest extends AbstractTestCase $_GET['username'] = 'username'; $_POST['update_privs'] = 'update_privs'; - $extra_data = $this->serverPrivileges->getExtraDataForAjaxBehavior($password, $sql_query, $hostname, $username); + $extra_data = $serverPrivileges->getExtraDataForAjaxBehavior($password, $sql_query, $hostname, $username); //user_exists $this->assertFalse($extra_data['user_exists']); @@ -1267,51 +1204,59 @@ class PrivilegesTest extends AbstractTestCase //new_privileges $this->assertStringContainsString( - implode(', ', $this->serverPrivileges->extractPrivInfo(null, true)), + implode(', ', $serverPrivileges->extractPrivInfo(null, true)), $extra_data['new_privileges'] ); } - /** - * Test for getUserGroupForUser - */ public function testGetUserGroupForUser(): void { - $username = 'pma_username'; - - $dbi_old = $GLOBALS['dbi']; - $dbi = $this->getMockBuilder(DatabaseInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $expected_userGroup = 'pma_usergroup'; - - $dbi->expects($this->any())->method('fetchValue') - ->will($this->returnValue($expected_userGroup)); - $dbi->expects($this->any()) - ->method('escapeString') - ->will($this->returnArgument(0)); - - $GLOBALS['dbi'] = $dbi; - $this->serverPrivileges->dbi = $dbi; + $GLOBALS['server'] = 1; + $_SESSION['relation'] = []; + $_SESSION['relation'][$GLOBALS['server']] = RelationParameters::fromArray([ + 'db' => 'pmadb', + 'users' => 'users', + 'usergroups' => 'usergroups', + 'menuswork' => true, + ])->toArray(); - $returned_userGroup = $this->serverPrivileges->getUserGroupForUser($username); + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addResult( + 'SELECT `usergroup` FROM `pmadb`.`users` WHERE `username` = \'pma_username\' LIMIT 1', + [['pma_usergroup']] + ); - $this->assertEquals($expected_userGroup, $returned_userGroup); + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface($dummyDbi)); - $GLOBALS['dbi'] = $dbi_old; - $this->serverPrivileges->dbi = $dbi_old; + $this->assertEquals('pma_usergroup', $serverPrivileges->getUserGroupForUser('pma_username')); } - /** - * Test for getUsersOverview - */ public function testGetUsersOverview(): void { + $GLOBALS['cfg']['Server']['DisableIS'] = false; + + $GLOBALS['server'] = 1; + $_SESSION['relation'] = []; + $_SESSION['relation'][$GLOBALS['server']] = RelationParameters::fromArray([ + 'db' => 'pmadb', + 'users' => 'users', + 'usergroups' => 'usergroups', + 'menuswork' => true, + 'trackingwork' => true, + 'tracking' => 'tracking', + ])->toArray(); + + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addResult('SELECT * FROM `pmadb`.`users`', []); + $dummyDbi->addResult('SELECT COUNT(*) FROM `pmadb`.`usergroups`', [['0']]); + + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface($dummyDbi)); + $resultStub = $this->createMock(DummyResult::class); $db_rights = []; $text_dir = 'text_dir'; - $html = $this->serverPrivileges->getUsersOverview($resultStub, $db_rights, $text_dir); + $html = $serverPrivileges->getUsersOverview($resultStub, $db_rights, $text_dir); //Url::getHiddenInputs $this->assertStringContainsString( @@ -1386,11 +1331,10 @@ class PrivilegesTest extends AbstractTestCase ); } - /** - * Test for getDataForDeleteUsers - */ public function testGetDataForDeleteUsers(): void { + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface()); + $_POST['change_copy'] = 'change_copy'; $_POST['old_hostname'] = 'old_hostname'; $_POST['old_username'] = 'old_username'; @@ -1399,7 +1343,7 @@ class PrivilegesTest extends AbstractTestCase $queries = []; - $ret = $this->serverPrivileges->getDataForDeleteUsers($queries); + $ret = $serverPrivileges->getDataForDeleteUsers($queries); $item = [ "# Deleting 'old_username'@'old_hostname' ...", @@ -1408,12 +1352,13 @@ class PrivilegesTest extends AbstractTestCase $this->assertEquals($item, $ret); } - /** - * Test for getAddUserHtmlFieldset - */ public function testGetAddUserHtmlFieldset(): void { - $html = $this->serverPrivileges->getAddUserHtmlFieldset(); + $GLOBALS['cfg']['Server']['DisableIS'] = false; + + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface()); + + $html = $serverPrivileges->getAddUserHtmlFieldset(); $this->assertStringContainsString( Url::getCommon(['adduser' => 1], ''), @@ -1429,11 +1374,17 @@ class PrivilegesTest extends AbstractTestCase ); } - /** - * Test for getHtmlHeaderForUserProperties - */ public function testGetHtmlHeaderForUserProperties(): void { + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addResult( + 'SELECT \'1\' FROM `mysql`.`user` WHERE `User` = \'username\' AND `Host` = \'hostname\';', + [['1']] + ); + $dummyDbi->addResult('SHOW COLUMNS FROM `tablename`.`tablename`;', []); + + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface($dummyDbi)); + $dbname_is_wildcard = true; $url_dbname = 'url_dbname'; $dbname = 'dbname'; @@ -1442,15 +1393,14 @@ class PrivilegesTest extends AbstractTestCase $tablename = 'tablename'; $_REQUEST['tablename'] = 'tablename'; - // $this->serverPrivileges->dbi->expects($this->once())->method('tryQuery')->with - - $html = $this->serverPrivileges->getHtmlForUserProperties( + $html = $serverPrivileges->getHtmlForUserProperties( $dbname_is_wildcard, $url_dbname, $username, $hostname, $tablename, - $_REQUEST['tablename'] + $_REQUEST['tablename'], + '/server/privileges' ); //title @@ -1505,20 +1455,16 @@ class PrivilegesTest extends AbstractTestCase $this->assertStringContainsString($dbname, $html); } - /** - * Tests for getHtmlForViewUsersError - */ public function testGetHtmlForViewUsersError(): void { + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface()); + $this->assertStringContainsString( 'Not enough privilege to view users.', - $this->serverPrivileges->getHtmlForViewUsersError() + $serverPrivileges->getHtmlForViewUsersError() ); } - /** - * Tests for getHtmlForUserProperties - */ public function testGetHtmlForUserProperties(): void { $this->dummyDbi->addResult( @@ -1549,19 +1495,20 @@ class PrivilegesTest extends AbstractTestCase ['Column_name', 'Column_priv'] ); - $relation = new Relation($this->dbi); - $serverPrivileges = new Privileges( - new Template(), - $this->dbi, - $relation, - new RelationCleanup($this->dbi, $relation), - new Plugins($this->dbi) - ); + $serverPrivileges = $this->getPrivileges($this->dbi); $GLOBALS['username'] = 'user'; $GLOBALS['hostname'] = 'host'; - $actual = $serverPrivileges->getHtmlForUserProperties(false, 'sakila', 'user', 'host', 'sakila', 'actor'); + $actual = $serverPrivileges->getHtmlForUserProperties( + false, + 'sakila', + 'user', + 'host', + 'sakila', + 'actor', + '/server/privileges' + ); $this->assertStringContainsString('addUsersForm', $actual); $this->assertStringContainsString('SELECT', $actual); $this->assertStringContainsString('Allows reading data.', $actual); @@ -1627,13 +1574,46 @@ class PrivilegesTest extends AbstractTestCase $this->assertStringContainsString((string) $item, $actual); } - /** - * Tests for getHtmlForUserOverview - */ public function testGetHtmlForUserOverview(): void { + $GLOBALS['cfg']['Server']['DisableIS'] = false; + $GLOBALS['lang'] = 'en'; + $GLOBALS['is_reload_priv'] = true; + + $dummyDbi = $this->createDbiDummy(); + // phpcs:disable Generic.Files.LineLength.TooLong + $dummyDbi->addResult( + 'SELECT *, IF(`authentication_string` = _latin1 \'\', \'N\', \'Y\') AS \'Password\' FROM `mysql`.`user` ORDER BY `User` ASC, `Host` ASC;', + [ + ['localhost', 'pma', 'password', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', '', '', '', '', '0', '0', '0', '0', 'mysql_native_password', 'password', 'N', 'N', '', '0.000000', 'Y'], + ['localhost', 'root', 'password', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', '', '', '', '', '0', '0', '0', '0', 'mysql_native_password', 'password', 'N', 'N', '', '0.000000', 'Y'], + ], + ['Host', 'User', 'Password', 'Select_priv', 'Insert_priv', 'Update_priv', 'Delete_priv', 'Create_priv', 'Drop_priv', 'Reload_priv', 'Shutdown_priv', 'Process_priv', 'File_priv', 'Grant_priv', 'References_priv', 'Index_priv', 'Alter_priv', 'Show_db_priv', 'Super_priv', 'Create_tmp_table_priv', 'Lock_tables_priv', 'Execute_priv', 'Repl_slave_priv', 'Repl_client_priv', 'Create_view_priv', 'Show_view_priv', 'Create_routine_priv', 'Alter_routine_priv', 'Create_user_priv', 'Event_priv', 'Trigger_priv', 'Create_tablespace_priv', 'Delete_history_priv', 'ssl_type', 'ssl_cipher', 'x509_issuer', 'x509_subject', 'max_questions', 'max_updates', 'max_connections', 'max_user_connections', 'plugin', 'authentication_string', 'password_expired', 'is_role', 'default_role', 'max_statement_time', 'Password'] + ); + $dummyDbi->addResult( + 'SELECT *, IF(`authentication_string` = _latin1 \'\', \'N\', \'Y\') AS \'Password\' FROM `mysql`.`user` ;', + [ + ['localhost', 'root', 'password', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', '', '', '', '', '0', '0', '0', '0', 'mysql_native_password', 'password', 'N', 'N', '', '0.000000', 'Y'], + ['localhost', 'pma', 'password', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', '', '', '', '', '0', '0', '0', '0', 'mysql_native_password', 'password', 'N', 'N', '', '0.000000', 'Y'], + ], + ['Host', 'User', 'Password', 'Select_priv', 'Insert_priv', 'Update_priv', 'Delete_priv', 'Create_priv', 'Drop_priv', 'Reload_priv', 'Shutdown_priv', 'Process_priv', 'File_priv', 'Grant_priv', 'References_priv', 'Index_priv', 'Alter_priv', 'Show_db_priv', 'Super_priv', 'Create_tmp_table_priv', 'Lock_tables_priv', 'Execute_priv', 'Repl_slave_priv', 'Repl_client_priv', 'Create_view_priv', 'Show_view_priv', 'Create_routine_priv', 'Alter_routine_priv', 'Create_user_priv', 'Event_priv', 'Trigger_priv', 'Create_tablespace_priv', 'Delete_history_priv', 'ssl_type', 'ssl_cipher', 'x509_issuer', 'x509_subject', 'max_questions', 'max_updates', 'max_connections', 'max_user_connections', 'plugin', 'authentication_string', 'password_expired', 'is_role', 'default_role', 'max_statement_time', 'Password'] + ); + $dummyDbi->addResult( + 'SHOW TABLES FROM `mysql`;', + [['columns_priv'], ['db'], ['tables_priv'], ['user']], + ['Tables_in_mysql'] + ); + $dummyDbi->addResult( + '(SELECT DISTINCT `User`, `Host` FROM `mysql`.`user` ) UNION (SELECT DISTINCT `User`, `Host` FROM `mysql`.`db` ) UNION (SELECT DISTINCT `User`, `Host` FROM `mysql`.`tables_priv` ) UNION (SELECT DISTINCT `User`, `Host` FROM `mysql`.`columns_priv` ) ORDER BY `User` ASC, `Host` ASC', + [['pma', 'localhost'], ['root', 'localhost']], + ['User', 'Host'] + ); + // phpcs:enable + + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface($dummyDbi)); + $_REQUEST = ['ajax_page_request' => '1']; - $actual = $this->serverPrivileges->getHtmlForUserOverview('ltr'); + $actual = $serverPrivileges->getHtmlForUserOverview('ltr'); $this->assertStringContainsString('Note: MySQL privilege names are expressed in English.', $actual); $this->assertStringContainsString( 'Note: phpMyAdmin gets the users’ privileges directly from MySQL’s privilege tables.', @@ -1641,16 +1621,52 @@ class PrivilegesTest extends AbstractTestCase ); } - /** - * Tests for getHtmlForAllTableSpecificRights - */ public function testGetHtmlForAllTableSpecificRights(): void { + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addResult( + 'SHOW TABLES FROM `mysql`;', + [['columns_priv'], ['db'], ['tables_priv'], ['user']], + ['Tables_in_mysql'] + ); + $dummyDbi->addResult( + 'SHOW TABLES FROM `mysql`;', + [['columns_priv'], ['db'], ['tables_priv'], ['user']], + ['Tables_in_mysql'] + ); + // phpcs:disable Generic.Files.LineLength.TooLong + $dummyDbi->addResult( + '( SELECT DISTINCT `Table_name` FROM `mysql`.`columns_priv` WHERE `User` = \'pma\' AND `Host` = \'host\' AND `Db` LIKE \'pmadb\') ORDER BY `Table_name` ASC', + [], + ['Table_name'] + ); + $dummyDbi->addResult( + 'SELECT `Table_name`, `Table_priv`, IF(`Column_priv` = _latin1 \'\', 0, 1) AS \'Column_priv\' FROM `mysql`.`tables_priv` WHERE `User` = \'pma\' AND `Host` = \'host\' AND `Db` LIKE \'pmadb\' ORDER BY `Table_name` ASC;', + [], + ['Table_name', 'Table_priv', 'Column_priv'] + ); + $dummyDbi->addResult( + '( SELECT DISTINCT `Db` FROM `mysql`.`tables_priv` WHERE `User` = \'pma2\' AND `Host` = \'host2\') UNION ( SELECT DISTINCT `Db` FROM `mysql`.`columns_priv` WHERE `User` = \'pma2\' AND `Host` = \'host2\') ORDER BY `Db` ASC', + [], + ['Db'] + ); + $dummyDbi->addResult( + 'SELECT * FROM `mysql`.`db` WHERE `User` = \'pma2\' AND `Host` = \'host2\' ORDER BY `Db` ASC', + [], + ['Host', 'Db', 'User', 'Select_priv', 'Insert_priv', 'Update_priv', 'Delete_priv', 'Create_priv', 'Drop_priv', 'Reload_priv', 'Shutdown_priv', 'Process_priv', 'File_priv', 'Grant_priv', 'References_priv', 'Index_priv', 'Alter_priv', 'Show_db_priv', 'Super_priv', 'Create_tmp_table_priv', 'Lock_tables_priv', 'Execute_priv', 'Repl_slave_priv', 'Repl_client_priv', 'Create_view_priv', 'Show_view_priv', 'Create_routine_priv', 'Alter_routine_priv', 'Create_user_priv', 'Event_priv', 'Trigger_priv', 'Create_tablespace_priv', 'Delete_history_priv'] + ); + // phpcs:enable + + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface($dummyDbi)); + // Test case 1 - $actual = $this->serverPrivileges->getHtmlForAllTableSpecificRights('pma', 'host', 'table', 'pmadb'); + $actual = $serverPrivileges->getHtmlForAllTableSpecificRights('pma', 'host', 'table', 'pmadb'); $this->assertStringContainsString('<input type="hidden" name="username" value="pma">', $actual); $this->assertStringContainsString('<input type="hidden" name="hostname" value="host">', $actual); - $this->assertStringContainsString('<legend data-submenu-label="Table">', $actual); + $this->assertStringContainsString( + '<div class="card-header js-submenu-label" data-submenu-label="Table">', + $actual + ); $this->assertStringContainsString('Table-specific privileges', $actual); // Test case 2 @@ -1660,31 +1676,28 @@ class PrivilegesTest extends AbstractTestCase 'y', 'z', ]; - $actual = $this->serverPrivileges->getHtmlForAllTableSpecificRights('pma2', 'host2', 'database', ''); - $this->assertStringContainsString('<legend data-submenu-label="Database">', $actual); + $actual = $serverPrivileges->getHtmlForAllTableSpecificRights('pma2', 'host2', 'database', ''); + $this->assertStringContainsString( + '<div class="card-header js-submenu-label" data-submenu-label="Database">', + $actual + ); $this->assertStringContainsString('Database-specific privileges', $actual); } - /** - * Tests for getHtmlForInitials - */ public function testGetHtmlForInitials(): void { - // Setup for the test - $dbi = $this->getMockBuilder(DatabaseInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $resultStub = $this->createMock(DummyResult::class); + $GLOBALS['lang'] = 'en'; - $dbi->expects($this->once()) - ->method('tryQuery') - ->will($this->returnValue($resultStub)); - $resultStub->expects($this->atLeastOnce()) - ->method('fetchRow') - ->will($this->onConsecutiveCalls(['-'], [])); - $this->serverPrivileges->dbi = $dbi; + $dummyDbi = $this->createDbiDummy(); + $dummyDbi->addResult( + 'SELECT DISTINCT UPPER(LEFT(`User`,1)) FROM `user` ORDER BY UPPER(LEFT(`User`,1)) ASC', + [['-']] + ); - $actual = $this->serverPrivileges->getHtmlForInitials(['"' => true]); + $dbi = $this->createDatabaseInterface($dummyDbi); + $serverPrivileges = $this->getPrivileges($dbi); + + $actual = $serverPrivileges->getHtmlForInitials(['"' => true]); $this->assertStringContainsString( '<a class="page-link" href="#" tabindex="-1" aria-disabled="true">A</a>', $actual @@ -1704,11 +1717,11 @@ class PrivilegesTest extends AbstractTestCase $this->assertStringContainsString('Show all', $actual); } - /** - * Tests for getDbRightsForUserOverview - */ public function testGetDbRightsForUserOverview(): void { + $dbi = $this->createDatabaseInterface(); + $serverPrivileges = $this->getPrivileges($dbi); + $resultStub = $this->createMock(DummyResult::class); //Mock DBI @@ -1737,8 +1750,7 @@ class PrivilegesTest extends AbstractTestCase ->will($this->returnArgument(0)); $_GET['initial'] = 'A'; - $GLOBALS['dbi'] = $dbi; - $this->serverPrivileges->dbi = $dbi; + $serverPrivileges->dbi = $dbi; $expected = [ 'pmauser' => [ @@ -1751,15 +1763,15 @@ class PrivilegesTest extends AbstractTestCase ], ], ]; - $actual = $this->serverPrivileges->getDbRightsForUserOverview(); + $actual = $serverPrivileges->getDbRightsForUserOverview(); $this->assertEquals($expected, $actual); } - /** - * Tests for deleteUser - */ public function testDeleteUser(): void { + $dbi = $this->createDatabaseInterface(); + $serverPrivileges = $this->getPrivileges($dbi); + $resultStub = $this->createMock(DummyResult::class); //Mock DBI @@ -1776,12 +1788,11 @@ class PrivilegesTest extends AbstractTestCase ->method('escapeString') ->will($this->returnArgument(0)); - $GLOBALS['dbi'] = $dbi; - $this->serverPrivileges->dbi = $dbi; + $serverPrivileges->dbi = $dbi; // Test case 1 : empty queries $queries = []; - $actual = $this->serverPrivileges->deleteUser($queries); + $actual = $serverPrivileges->deleteUser($queries); $this->assertArrayHasKey(0, $actual); $this->assertArrayHasKey(1, $actual); $this->assertEquals('', $actual[0]); @@ -1793,7 +1804,7 @@ class PrivilegesTest extends AbstractTestCase // Test case 2 : all successful queries $_POST['mode'] = 3; $queries = ['foo']; - $actual = $this->serverPrivileges->deleteUser($queries); + $actual = $serverPrivileges->deleteUser($queries); $this->assertArrayHasKey(0, $actual); $this->assertArrayHasKey(1, $actual); $this->assertEquals("foo\n# Reloading the privileges …\nFLUSH PRIVILEGES;", $actual[0]); @@ -1805,7 +1816,7 @@ class PrivilegesTest extends AbstractTestCase // Test case 3 : failing queries $_POST['mode'] = 1; $queries = ['bar']; - $actual = $this->serverPrivileges->deleteUser($queries); + $actual = $serverPrivileges->deleteUser($queries); $this->assertArrayHasKey(0, $actual); $this->assertArrayHasKey(1, $actual); $this->assertEquals('bar', $actual[0]); @@ -1817,13 +1828,12 @@ class PrivilegesTest extends AbstractTestCase public function testGetFormForChangePassword(): void { - global $route; + $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface()); $username = 'pma_username'; $hostname = 'pma_hostname'; - $route = '/server/privileges'; - $html = $this->serverPrivileges->getFormForChangePassword($username, $hostname, false); + $html = $serverPrivileges->getFormForChangePassword($username, $hostname, false, '/server/privileges'); $this->assertStringContainsString( Url::getFromRoute('/server/privileges'), @@ -1848,7 +1858,7 @@ class PrivilegesTest extends AbstractTestCase //labels $this->assertStringContainsString( - __('Change password'), + 'change_password_form', $html ); $this->assertStringContainsString( @@ -1907,4 +1917,11 @@ class PrivilegesTest extends AbstractTestCase $this->assertEquals(['Host' => 'test.host', 'User' => 'test.user', 'account_locked' => 'Y'], $actual); } + + private function getPrivileges(DatabaseInterface $dbi): Privileges + { + $relation = new Relation($dbi); + + return new Privileges(new Template(), $dbi, $relation, new RelationCleanup($dbi, $relation), new Plugins($dbi)); + } } diff --git a/test/classes/Server/SysInfo/SysInfoTest.php b/test/classes/Server/SysInfo/SysInfoTest.php index 897345e9c9..6ffafcaadb 100644 --- a/test/classes/Server/SysInfo/SysInfoTest.php +++ b/test/classes/Server/SysInfo/SysInfoTest.php @@ -31,6 +31,8 @@ class SysInfoTest extends AbstractTestCase /** * Data provider for OS detection tests. + * + * @return string[][] */ public function sysInfoOsProvider(): array { @@ -67,6 +69,6 @@ class SysInfoTest extends AbstractTestCase */ public function testGetSysInfoSupported(): void { - $this->assertTrue(SysInfo::get()->supported()); + $this->assertTrue(SysInfo::get()::isSupported()); } } diff --git a/test/classes/SqlQueryFormTest.php b/test/classes/SqlQueryFormTest.php index fdf4d7711d..ff74ff5be9 100644 --- a/test/classes/SqlQueryFormTest.php +++ b/test/classes/SqlQueryFormTest.php @@ -6,10 +6,12 @@ namespace PhpMyAdmin\Tests; use PhpMyAdmin\ConfigStorage\RelationParameters; use PhpMyAdmin\Core; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Encoding; use PhpMyAdmin\Html\MySQLDocumentation; use PhpMyAdmin\SqlQueryForm; use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Url; use function __; @@ -20,6 +22,12 @@ use function htmlspecialchars; */ class SqlQueryFormTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var SqlQueryForm */ private $sqlQueryForm; @@ -30,6 +38,9 @@ class SqlQueryFormTest extends AbstractTestCase { parent::setUp(); parent::setLanguage(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $this->sqlQueryForm = new SqlQueryForm(new Template()); //$GLOBALS @@ -67,7 +78,9 @@ class SqlQueryFormTest extends AbstractTestCase $GLOBALS['cfg']['Server']['pmadb'] = 'pmadb'; $GLOBALS['cfg']['Server']['bookmarktable'] = 'bookmarktable'; - parent::setGlobalDbi(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $this->dummyDbi->addResult( 'SHOW FULL COLUMNS FROM `PMA_db`.`PMA_table`', [ diff --git a/test/classes/SqlTest.php b/test/classes/SqlTest.php index 4fc9be9328..1034123efb 100644 --- a/test/classes/SqlTest.php +++ b/test/classes/SqlTest.php @@ -6,11 +6,13 @@ namespace PhpMyAdmin\Tests; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\ConfigStorage\RelationCleanup; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\FieldMetadata; use PhpMyAdmin\Operations; use PhpMyAdmin\ParseAnalyze; use PhpMyAdmin\Sql; use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Transformations; use stdClass; @@ -23,6 +25,12 @@ use const MYSQLI_TYPE_VAR_STRING; */ class SqlTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var Sql */ private $sql; @@ -34,6 +42,9 @@ class SqlTest extends AbstractTestCase parent::setUp(); parent::setLanguage(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; $GLOBALS['db'] = 'db'; $GLOBALS['table'] = 'table'; @@ -50,6 +61,7 @@ class SqlTest extends AbstractTestCase $GLOBALS['cfg']['LoginCookieValidity'] = 1440; $GLOBALS['cfg']['enable_drag_drop_import'] = true; $GLOBALS['PMA_PHP_SELF'] = 'index.php'; + $GLOBALS['showtable'] = null; $relation = new Relation($GLOBALS['dbi']); $this->sql = new Sql( @@ -71,11 +83,12 @@ class SqlTest extends AbstractTestCase $GLOBALS['_SESSION']['tmpval']['pos'] = 1; $GLOBALS['_SESSION']['tmpval']['max_rows'] = 2; - $analyzed_sql_results = $this->parseAndAnalyze('SELECT * FROM test LIMIT 0, 10'); - $this->assertEquals( - 'SELECT * FROM test LIMIT 1, 2 ', - $this->callFunction($this->sql, Sql::class, 'getSqlWithLimitClause', [&$analyzed_sql_results]) - ); + $this->assertEquals('SELECT * FROM test LIMIT 1, 2 ', $this->callFunction( + $this->sql, + Sql::class, + 'getSqlWithLimitClause', + [ParseAnalyze::sqlQuery('SELECT * FROM test LIMIT 0, 10', $GLOBALS['db'])[0]] + )); } /** @@ -88,31 +101,31 @@ class SqlTest extends AbstractTestCase $this->assertTrue( $this->callFunction($this->sql, Sql::class, 'isRememberSortingOrder', [ - $this->parseAndAnalyze('SELECT * FROM tbl'), + ParseAnalyze::sqlQuery('SELECT * FROM tbl', $GLOBALS['db'])[0], ]) ); $this->assertFalse( $this->callFunction($this->sql, Sql::class, 'isRememberSortingOrder', [ - $this->parseAndAnalyze('SELECT col FROM tbl'), + ParseAnalyze::sqlQuery('SELECT col FROM tbl', $GLOBALS['db'])[0], ]) ); $this->assertFalse( $this->callFunction($this->sql, Sql::class, 'isRememberSortingOrder', [ - $this->parseAndAnalyze('SELECT 1'), + ParseAnalyze::sqlQuery('SELECT 1', $GLOBALS['db'])[0], ]) ); $this->assertFalse( $this->callFunction($this->sql, Sql::class, 'isRememberSortingOrder', [ - $this->parseAndAnalyze('SELECT col1, col2 FROM tbl'), + ParseAnalyze::sqlQuery('SELECT col1, col2 FROM tbl', $GLOBALS['db'])[0], ]) ); $this->assertFalse( $this->callFunction($this->sql, Sql::class, 'isRememberSortingOrder', [ - $this->parseAndAnalyze('SELECT COUNT(*) from tbl'), + ParseAnalyze::sqlQuery('SELECT COUNT(*) from tbl', $GLOBALS['db'])[0], ]) ); } @@ -127,13 +140,13 @@ class SqlTest extends AbstractTestCase $this->assertTrue( $this->callFunction($this->sql, Sql::class, 'isAppendLimitClause', [ - $this->parseAndAnalyze('SELECT * FROM tbl'), + ParseAnalyze::sqlQuery('SELECT * FROM tbl', $GLOBALS['db'])[0], ]) ); $this->assertFalse( $this->callFunction($this->sql, Sql::class, 'isAppendLimitClause', [ - $this->parseAndAnalyze('SELECT * from tbl LIMIT 0, 10'), + ParseAnalyze::sqlQuery('SELECT * from tbl LIMIT 0, 10', $GLOBALS['db'])[0], ]) ); } @@ -144,17 +157,17 @@ class SqlTest extends AbstractTestCase $GLOBALS['_SESSION']['tmpval']['max_rows'] = 10; $this->assertTrue(Sql::isJustBrowsing( - $this->parseAndAnalyze('SELECT * FROM db.tbl'), + ParseAnalyze::sqlQuery('SELECT * FROM db.tbl', $GLOBALS['db'])[0], null )); $this->assertTrue(Sql::isJustBrowsing( - $this->parseAndAnalyze('SELECT * FROM tbl WHERE 1'), + ParseAnalyze::sqlQuery('SELECT * FROM tbl WHERE 1', $GLOBALS['db'])[0], null )); $this->assertFalse(Sql::isJustBrowsing( - $this->parseAndAnalyze('SELECT * from tbl1, tbl2 LIMIT 0, 10'), + ParseAnalyze::sqlQuery('SELECT * from tbl1, tbl2 LIMIT 0, 10', $GLOBALS['db'])[0], null )); } @@ -166,19 +179,19 @@ class SqlTest extends AbstractTestCase { $this->assertTrue( $this->callFunction($this->sql, Sql::class, 'isDeleteTransformationInfo', [ - $this->parseAndAnalyze('ALTER TABLE tbl DROP COLUMN col'), + ParseAnalyze::sqlQuery('ALTER TABLE tbl DROP COLUMN col', $GLOBALS['db'])[0], ]) ); $this->assertTrue( $this->callFunction($this->sql, Sql::class, 'isDeleteTransformationInfo', [ - $this->parseAndAnalyze('DROP TABLE tbl'), + ParseAnalyze::sqlQuery('DROP TABLE tbl', $GLOBALS['db'])[0], ]) ); $this->assertFalse( $this->callFunction($this->sql, Sql::class, 'isDeleteTransformationInfo', [ - $this->parseAndAnalyze('SELECT * from tbl'), + ParseAnalyze::sqlQuery('SELECT * from tbl', $GLOBALS['db'])[0], ]) ); } @@ -190,7 +203,7 @@ class SqlTest extends AbstractTestCase { $this->assertTrue( $this->sql->hasNoRightsToDropDatabase( - $this->parseAndAnalyze('DROP DATABASE db'), + ParseAnalyze::sqlQuery('DROP DATABASE db', $GLOBALS['db'])[0], false, false ) @@ -198,7 +211,7 @@ class SqlTest extends AbstractTestCase $this->assertFalse( $this->sql->hasNoRightsToDropDatabase( - $this->parseAndAnalyze('DROP TABLE tbl'), + ParseAnalyze::sqlQuery('DROP TABLE tbl', $GLOBALS['db'])[0], false, false ) @@ -206,7 +219,7 @@ class SqlTest extends AbstractTestCase $this->assertFalse( $this->sql->hasNoRightsToDropDatabase( - $this->parseAndAnalyze('SELECT * from tbl'), + ParseAnalyze::sqlQuery('SELECT * from tbl', $GLOBALS['db'])[0], false, false ) @@ -341,18 +354,6 @@ class SqlTest extends AbstractTestCase ); } - /** - * @return mixed - */ - private function parseAndAnalyze(string $sqlQuery) - { - global $db; - - [$analyzedSqlResults] = ParseAnalyze::sqlQuery($sqlQuery, $db); - - return $analyzedSqlResults; - } - public function dataProviderCountQueryResults(): array { // sql query @@ -553,8 +554,6 @@ class SqlTest extends AbstractTestCase $_SESSION['tmpval'] = $sessionTmpVal; - $analyzed_sql_results = $sqlQuery === null ? [] : $this->parseAndAnalyze($sqlQuery); - $result = $this->callFunction( $this->sql, Sql::class, @@ -564,7 +563,7 @@ class SqlTest extends AbstractTestCase $justBrowsing, 'my_dataset',// db 'company_users',// table - $analyzed_sql_results, + ParseAnalyze::sqlQuery($sqlQuery ?? '', $GLOBALS['db'])[0], ] ); $this->assertSame($expectedNumRows, $result); diff --git a/test/classes/StatementInfoTest.php b/test/classes/StatementInfoTest.php new file mode 100644 index 0000000000..21e41a96be --- /dev/null +++ b/test/classes/StatementInfoTest.php @@ -0,0 +1,159 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests; + +use PhpMyAdmin\SqlParser\Parser; +use PhpMyAdmin\StatementInfo; +use PHPUnit\Framework\TestCase; + +/** + * @covers \PhpMyAdmin\StatementInfo + */ +class StatementInfoTest extends TestCase +{ + public function testFromArray(): void + { + $parser = new Parser('SELECT * FROM `sakila`.`actor`'); + $statement = $parser->statements[0]; + $info = [ + 'distinct' => false, + 'drop_database' => false, + 'group' => false, + 'having' => false, + 'is_affected' => false, + 'is_analyse' => false, + 'is_count' => false, + 'is_delete' => false, + 'is_explain' => false, + 'is_export' => false, + 'is_func' => false, + 'is_group' => false, + 'is_insert' => false, + 'is_maint' => false, + 'is_procedure' => false, + 'is_replace' => false, + 'is_select' => true, + 'is_show' => false, + 'is_subquery' => false, + 'join' => false, + 'limit' => false, + 'offset' => false, + 'order' => false, + 'querytype' => 'SELECT', + 'reload' => false, + 'select_from' => true, + 'union' => false, + 'parser' => $parser, + 'statement' => $statement, + 'select_tables' => [['actor', null]], + 'select_expr' => ['*'], + ]; + + $statementInfo = StatementInfo::fromArray($info); + + $this->assertFalse($statementInfo->distinct); + $this->assertFalse($statementInfo->dropDatabase); + $this->assertFalse($statementInfo->group); + $this->assertFalse($statementInfo->having); + $this->assertFalse($statementInfo->isAffected); + $this->assertFalse($statementInfo->isAnalyse); + $this->assertFalse($statementInfo->isCount); + $this->assertFalse($statementInfo->isDelete); + $this->assertFalse($statementInfo->isExplain); + $this->assertFalse($statementInfo->isExport); + $this->assertFalse($statementInfo->isFunction); + $this->assertFalse($statementInfo->isGroup); + $this->assertFalse($statementInfo->isInsert); + $this->assertFalse($statementInfo->isMaint); + $this->assertFalse($statementInfo->isProcedure); + $this->assertFalse($statementInfo->isReplace); + $this->assertTrue($statementInfo->isSelect); + $this->assertFalse($statementInfo->isShow); + $this->assertFalse($statementInfo->isSubquery); + $this->assertFalse($statementInfo->join); + $this->assertFalse($statementInfo->limit); + $this->assertFalse($statementInfo->offset); + $this->assertFalse($statementInfo->order); + $this->assertSame('SELECT', $statementInfo->queryType); + $this->assertFalse($statementInfo->reload); + $this->assertTrue($statementInfo->selectFrom); + $this->assertFalse($statementInfo->union); + $this->assertNotNull($statementInfo->parser); + $this->assertNotNull($statementInfo->statement); + $this->assertNotEmpty($statementInfo->selectTables); + $this->assertNotEmpty($statementInfo->selectExpression); + $this->assertSame($info['parser'], $statementInfo->parser); + $this->assertSame($info['statement'], $statementInfo->statement); + $this->assertSame($info['select_tables'], $statementInfo->selectTables); + $this->assertSame($info['select_expr'], $statementInfo->selectExpression); + } + + public function testFromArrayWithEmptyStatement(): void + { + $info = [ + 'distinct' => false, + 'drop_database' => false, + 'group' => false, + 'having' => false, + 'is_affected' => false, + 'is_analyse' => false, + 'is_count' => false, + 'is_delete' => false, + 'is_explain' => false, + 'is_export' => false, + 'is_func' => false, + 'is_group' => false, + 'is_insert' => false, + 'is_maint' => false, + 'is_procedure' => false, + 'is_replace' => false, + 'is_select' => false, + 'is_show' => false, + 'is_subquery' => false, + 'join' => false, + 'limit' => false, + 'offset' => false, + 'order' => false, + 'querytype' => false, + 'reload' => false, + 'select_from' => false, + 'union' => false, + ]; + + $statementInfo = StatementInfo::fromArray($info); + + $this->assertFalse($statementInfo->distinct); + $this->assertFalse($statementInfo->dropDatabase); + $this->assertFalse($statementInfo->group); + $this->assertFalse($statementInfo->having); + $this->assertFalse($statementInfo->isAffected); + $this->assertFalse($statementInfo->isAnalyse); + $this->assertFalse($statementInfo->isCount); + $this->assertFalse($statementInfo->isDelete); + $this->assertFalse($statementInfo->isExplain); + $this->assertFalse($statementInfo->isExport); + $this->assertFalse($statementInfo->isFunction); + $this->assertFalse($statementInfo->isGroup); + $this->assertFalse($statementInfo->isInsert); + $this->assertFalse($statementInfo->isMaint); + $this->assertFalse($statementInfo->isProcedure); + $this->assertFalse($statementInfo->isReplace); + $this->assertFalse($statementInfo->isSelect); + $this->assertFalse($statementInfo->isShow); + $this->assertFalse($statementInfo->isSubquery); + $this->assertFalse($statementInfo->join); + $this->assertFalse($statementInfo->limit); + $this->assertFalse($statementInfo->offset); + $this->assertFalse($statementInfo->order); + $this->assertFalse($statementInfo->queryType); + $this->assertFalse($statementInfo->reload); + $this->assertFalse($statementInfo->selectFrom); + $this->assertFalse($statementInfo->union); + $this->assertNull($statementInfo->parser); + $this->assertNull($statementInfo->statement); + $this->assertEmpty($statementInfo->selectTables); + $this->assertEmpty($statementInfo->selectExpression); + } +} diff --git a/test/classes/StorageEngineTest.php b/test/classes/StorageEngineTest.php index 85381fcf57..430f2bc253 100644 --- a/test/classes/StorageEngineTest.php +++ b/test/classes/StorageEngineTest.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests; use PhpMyAdmin\Cache; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Engines\Bdb; use PhpMyAdmin\Engines\Berkeleydb; use PhpMyAdmin\Engines\Binlog; @@ -18,6 +19,7 @@ use PhpMyAdmin\Engines\Ndbcluster; use PhpMyAdmin\Engines\Pbxt; use PhpMyAdmin\Engines\PerformanceSchema; use PhpMyAdmin\StorageEngine; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PHPUnit\Framework\MockObject\MockObject; use function json_encode; @@ -27,6 +29,12 @@ use function json_encode; */ class StorageEngineTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + /** @var StorageEngine|MockObject */ protected $object; @@ -37,6 +45,9 @@ class StorageEngineTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; $this->object = $this->getMockForAbstractClass( StorageEngine::class, @@ -55,7 +66,8 @@ class StorageEngineTest extends AbstractTestCase } /** - * Test for getStorageEngines + * @runInSeparateProcess + * @preserveGlobalState disabled */ public function testGetStorageEngines(): void { @@ -334,7 +346,7 @@ class StorageEngineTest extends AbstractTestCase $this->dummyDbi->addResult('SELECT mroonga_command(\'object_list\');', false); $this->assertFalse(StorageEngine::hasMroongaEngine()); - $this->assertAllQueriesConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); } public function testGetMroongaLengths(): void @@ -702,9 +714,9 @@ class StorageEngineTest extends AbstractTestCase $this->dummyDbi->addSelectDb('my_db'); $lengths = StorageEngine::getMroongaLengths('my_db', 'idx_correo'); - $this->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllSelectsConsumed(); $this->assertSame([4521984, 578126], $lengths); - $this->assertAllQueriesConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); } } diff --git a/test/classes/Stubs/DbiDummy.php b/test/classes/Stubs/DbiDummy.php index e33e553f40..ed32b12e08 100644 --- a/test/classes/Stubs/DbiDummy.php +++ b/test/classes/Stubs/DbiDummy.php @@ -165,6 +165,11 @@ class DbiDummy implements DbiExtension return $unUsed; } + public function assertAllQueriesConsumed(): void + { + Assert::assertSame([], $this->getUnUsedQueries(), 'Some queries where not used!'); + } + /** * @return false|int|null */ @@ -421,9 +426,7 @@ class DbiDummy implements DbiExtension */ public function affectedRows($link = null, $get_from_cache = true) { - global $cached_affected_rows; - - return $cached_affected_rows ?? 0; + return $GLOBALS['cached_affected_rows'] ?? 0; } /** @@ -552,6 +555,16 @@ class DbiDummy implements DbiExtension return $this->filoQueries[$result]; } + public function assertAllSelectsConsumed(): void + { + Assert::assertSame([], $this->getUnUsedDatabaseSelects(), 'Some database selects where not used!'); + } + + public function assertAllErrorCodesConsumed(): void + { + Assert::assertFalse($this->hasUnUsedErrors(), 'Some error codes where not used!'); + } + private function init(): void { /** diff --git a/test/classes/Stubs/ResponseRenderer.php b/test/classes/Stubs/ResponseRenderer.php index 8f1c9a43f5..99e79cdd4f 100644 --- a/test/classes/Stubs/ResponseRenderer.php +++ b/test/classes/Stubs/ResponseRenderer.php @@ -48,6 +48,9 @@ class ResponseRenderer extends \PhpMyAdmin\ResponseRenderer $this->isAjax = false; $GLOBALS['lang'] = 'en'; + $GLOBALS['server'] = $GLOBALS['server'] ?? 1; + $GLOBALS['text_dir'] = $GLOBALS['text_dir'] ?? 'ltr'; + $GLOBALS['PMA_PHP_SELF'] = $GLOBALS['PMA_PHP_SELF'] ?? 'index.php'; $this->header = new Header(); $this->footer = new Footer(); } diff --git a/test/classes/SystemDatabaseTest.php b/test/classes/SystemDatabaseTest.php index 8652a4eae9..ab0716a9b9 100644 --- a/test/classes/SystemDatabaseTest.php +++ b/test/classes/SystemDatabaseTest.php @@ -27,6 +27,7 @@ class SystemDatabaseTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); /** * SET these to avoid undefine d index error */ diff --git a/test/classes/Table/ColumnsDefinitionTest.php b/test/classes/Table/ColumnsDefinitionTest.php new file mode 100644 index 0000000000..84015d6281 --- /dev/null +++ b/test/classes/Table/ColumnsDefinitionTest.php @@ -0,0 +1,207 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Table; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\FieldMetadata; +use PhpMyAdmin\Table\ColumnsDefinition; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Transformations; + +use function array_merge; + +use const MYSQLI_TYPE_STRING; + +/** + * @covers \PhpMyAdmin\Table\ColumnsDefinition + */ +class ColumnsDefinitionTest extends AbstractTestCase +{ + public function testDisplayForm(): void + { + $GLOBALS['cfg']['Server']['DisableIS'] = false; + $dummyDbi = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dummyDbi); + $GLOBALS['dbi'] = $dbi; + + // phpcs:disable Generic.Files.LineLength.TooLong + $columnMeta = ['Field' => 'actor_id', 'Type' => 'smallint(5) unsigned', 'Collation' => null, 'Null' => 'NO', 'Key' => 'PRI', 'Default' => null, 'Extra' => 'auto_increment', 'Privileges' => 'select,insert,update,references', 'Comment' => '']; + $dummyDbi->addResult( + 'SHOW FULL COLUMNS FROM `sakila`.`actor`', + [ + ['actor_id', 'smallint(5) unsigned', null, 'NO', 'PRI', null, 'auto_increment', 'select,insert,update,references', ''], + ['first_name', 'varchar(45)', 'utf8mb4_general_ci', 'NO', '', null, '', 'select,insert,update,references', ''], + ['last_name', 'varchar(45)', 'utf8mb4_general_ci', 'NO', 'MUL', null, '', 'select,insert,update,references', ''], + ['last_update', 'timestamp', null, 'NO', '', 'current_timestamp()', 'on update current_timestamp()', 'select,insert,update,references', ''], + ], + ['Field', 'Type', 'Collation', 'Null', 'Key', 'Default', 'Extra', 'Privileges', 'Comment'] + ); + $dummyDbi->addResult( + 'SHOW INDEXES FROM `sakila`.`actor`', + [ + ['actor', '0', 'PRIMARY', '1', 'actor_id', 'A', '2', null, null, '', 'BTREE', '', '', 'NO'], + ['actor', '1', 'idx_actor_last_name', '1', 'last_name', 'A', '2', null, null, '', 'BTREE', '', '', 'NO'], + ], + ['Table', 'Non_unique', 'Key_name', 'Seq_in_index', 'Column_name', 'Collation', 'Cardinality', 'Sub_part', 'Packed', 'Null', 'Index_type', 'Comment', 'Index_comment', 'Ignored'] + ); + // phpcs:enable + $dummyDbi->addResult( + 'SELECT * FROM `sakila`.`actor` LIMIT 1', + [['1', 'PENELOPE', 'GUINESS', '2006-02-15 04:34:33']], + ['actor_id', 'first_name', 'last_name', 'last_update'] + ); + $createTable = <<<'SQL' +CREATE TABLE `actor` ( + `actor_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, + `first_name` varchar(45) NOT NULL, + `last_name` varchar(45) NOT NULL, + `last_update` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), + PRIMARY KEY (`actor_id`), + KEY `idx_actor_last_name` (`last_name`) +) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8mb4 +SQL; + $dummyDbi->addResult( + 'SHOW CREATE TABLE `sakila`.`actor`', + [['actor', $createTable]], + ['actor_id', 'first_name', 'last_name', 'last_update'] + ); + + $relation = new Relation($dbi); + $columnsDefinition = new ColumnsDefinition($dbi, $relation, new Transformations()); + + $GLOBALS['server'] = 1; + $GLOBALS['db'] = 'sakila'; + $GLOBALS['table'] = 'actor'; + $GLOBALS['col_priv'] = true; + $GLOBALS['is_reload_priv'] = true; + $GLOBALS['mime_map'] = null; + $_SESSION['relation'] = []; + + $actual = $columnsDefinition->displayForm('/table/structure/save', 1, null, ['actor_id'], [$columnMeta]); + + $contentCell = [ + 'column_number' => 0, + 'column_meta' => array_merge($columnMeta, ['DefaultType' => 'NONE', 'DefaultValue' => '']), + 'type_upper' => 'SMALLINT', + 'default_value' => '', + 'length_values_input_size' => 8, + 'length' => '5', + 'extracted_columnspec' => [ + 'type' => 'smallint', + 'spec_in_brackets' => '5', + 'enum_set_values' => [], + 'print_type' => 'smallint(5)', + 'binary' => false, + 'unsigned' => true, + 'zerofill' => false, + 'attribute' => 'UNSIGNED', + 'can_contain_collation' => false, + 'displayed_type' => 'smallint(5)', + ], + 'submit_attribute' => null, + 'comments_map' => [], + 'fields_meta' => [$columnMeta], + 'is_backup' => true, + 'move_columns' => [ + new FieldMetadata(MYSQLI_TYPE_STRING, 0, (object) ['name' => 'actor_id']), + new FieldMetadata(MYSQLI_TYPE_STRING, 0, (object) ['name' => 'first_name']), + new FieldMetadata(MYSQLI_TYPE_STRING, 0, (object) ['name' => 'last_name']), + new FieldMetadata(MYSQLI_TYPE_STRING, 0, (object) ['name' => 'last_update']), + ], + 'available_mime' => [], + 'mime_map' => [], + ]; + $expected = [ + 'is_backup' => true, + 'fields_meta' => [$columnMeta], + 'relation_parameters' => $relation->getRelationParameters(), + 'action' => '/table/structure/save', + 'form_params' => [ + 'db' => 'sakila', + 'table' => 'actor', + 'orig_num_fields' => 1, + 'orig_field_where' => null, + 'orig_after_field' => null, + 'selected[0]' => 'actor_id', + 'field_orig[0]' => 'actor_id', + 'field_type_orig[0]' => 'SMALLINT', + 'field_length_orig[0]' => '5', + 'field_default_value_orig[0]' => '', + 'field_default_type_orig[0]' => 'NONE', + 'field_collation_orig[0]' => '', + 'field_attribute_orig[0]' => 'UNSIGNED', + 'field_null_orig[0]' => 'NO', + 'field_extra_orig[0]' => 'auto_increment', + 'field_comments_orig[0]' => '', + 'field_virtuality_orig[0]' => '', + 'field_expression_orig[0]' => '', + ], + 'content_cells' => [$contentCell], + 'partition_details' => [ + 'partition_by' => null, + 'partition_expr' => null, + 'subpartition_by' => null, + 'subpartition_expr' => null, + 'partition_count' => 0, + 'subpartition_count' => 0, + 'can_have_subpartitions' => false, + 'value_enabled' => false, + ], + 'primary_indexes' => null, + 'unique_indexes' => null, + 'indexes' => null, + 'fulltext_indexes' => null, + 'spatial_indexes' => null, + 'table' => null, + 'comment' => null, + 'tbl_collation' => null, + 'charsets' => [ + [ + 'name' => 'armscii8', + 'description' => 'armscii8_general_ci', + 'collations' => [['name' => 'armscii8_general_ci', 'description' => 'Armenian, case-insensitive']], + ], + [ + 'name' => 'latin1', + 'description' => 'cp1252 West European', + 'collations' => [['name' => 'latin1_swedish_ci', 'description' => 'Swedish, case-insensitive']], + ], + [ + 'name' => 'utf8', + 'description' => 'UTF-8 Unicode', + 'collations' => [ + ['name' => 'utf8_bin', 'description' => 'Unicode, binary'], + ['name' => 'utf8_general_ci', 'description' => 'Unicode, case-insensitive'], + ], + ], + [ + 'name' => 'utf8mb4', + 'description' => 'utf8mb4_0900_ai_ci', + 'collations' => [ + ['name' => 'utf8mb4_general_ci', 'description' => 'Unicode (UCA 4.0.0), case-insensitive'], + ], + ], + ], + 'tbl_storage_engine' => null, + 'storage_engines' => ['dummy' => ['name' => 'dummy', 'comment' => 'dummy comment', 'is_default' => false]], + 'connection' => null, + 'change_column' => null, + 'is_virtual_columns_supported' => true, + 'is_integers_length_restricted' => false, + 'browse_mime' => true, + 'supports_stored_keyword' => false, + 'server_version' => $dbi->getVersion(), + 'max_rows' => 25, + 'char_editing' => 'input', + 'attribute_types' => ['', 'BINARY', 'UNSIGNED', 'UNSIGNED ZEROFILL', 'on update CURRENT_TIMESTAMP'], + 'privs_available' => true, + 'max_length' => 1024, + 'have_partitioning' => true, + 'disable_is' => false, + ]; + + $this->assertEquals($expected, $actual); + } +} diff --git a/test/classes/Table/SearchTest.php b/test/classes/Table/SearchTest.php index d90f6cda23..9da2ed4d8b 100644 --- a/test/classes/Table/SearchTest.php +++ b/test/classes/Table/SearchTest.php @@ -18,9 +18,9 @@ class SearchTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); - global $dbi; + $GLOBALS['dbi'] = $this->createDatabaseInterface(); - $this->search = new Search($dbi); + $this->search = new Search($GLOBALS['dbi']); } public function testBuildSqlQuery(): void diff --git a/test/classes/TableTest.php b/test/classes/TableTest.php index c95cff3d68..75d0d2a759 100644 --- a/test/classes/TableTest.php +++ b/test/classes/TableTest.php @@ -943,9 +943,7 @@ class TableTest extends AbstractTestCase */ public function testIsMergeCase2(): void { - global $dbi; - - $dbi->getCache()->cacheTableContent( + $GLOBALS['dbi']->getCache()->cacheTableContent( ['PMA', 'PMA_BookMark'], ['ENGINE' => 'MERGE'] ); @@ -961,9 +959,7 @@ class TableTest extends AbstractTestCase */ public function testIsMergeCase3(): void { - global $dbi; - - $dbi->getCache()->cacheTableContent( + $GLOBALS['dbi']->getCache()->cacheTableContent( ['PMA', 'PMA_BookMark'], ['ENGINE' => 'MRG_MYISAM'] ); diff --git a/test/classes/TemplateTest.php b/test/classes/TemplateTest.php index 6c915f42ba..dba4b249e5 100644 --- a/test/classes/TemplateTest.php +++ b/test/classes/TemplateTest.php @@ -31,15 +31,13 @@ class TemplateTest extends AbstractTestCase */ public function testGetTwigEnvironment(): void { - global $cfg; - $this->loadContainerBuilder(); - $cfg['environment'] = 'production'; + $GLOBALS['cfg']['environment'] = 'production'; $twig = Template::getTwigEnvironment(null); $this->assertFalse($twig->isDebug()); $this->assertFalse(TransNode::$enableAddDebugInfo); - $cfg['environment'] = 'development'; + $GLOBALS['cfg']['environment'] = 'development'; $twig = Template::getTwigEnvironment(null); $this->assertTrue($twig->isDebug()); $this->assertTrue(TransNode::$enableAddDebugInfo); diff --git a/test/classes/ThemeTest.php b/test/classes/ThemeTest.php index 51c7a41c25..32762d6512 100644 --- a/test/classes/ThemeTest.php +++ b/test/classes/ThemeTest.php @@ -28,13 +28,11 @@ class ThemeTest extends AbstractTestCase */ protected function setUp(): void { - global $theme; - parent::setUp(); parent::setTheme(); $this->object = new Theme(); - $this->backup = $theme; - $theme = $this->object; + $this->backup = $GLOBALS['theme']; + $GLOBALS['theme'] = $this->object; parent::setGlobalConfig(); $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['server'] = '99'; @@ -46,10 +44,8 @@ class ThemeTest extends AbstractTestCase */ protected function tearDown(): void { - global $theme; - parent::tearDown(); - $theme = $this->backup; + $GLOBALS['theme'] = $this->backup; } /** @@ -83,7 +79,7 @@ class ThemeTest extends AbstractTestCase $this->object->setFsPath(ROOT_PATH . 'test/classes/_data/gen_version_info/'); $this->assertTrue($this->object->loadInfo()); $this->assertEquals('Test Theme', $this->object->getName()); - $this->assertEquals('5.1', $this->object->getVersion()); + $this->assertEquals('5.3', $this->object->getVersion()); } /** diff --git a/test/classes/TrackerTest.php b/test/classes/TrackerTest.php index a642d4c2e8..1ce3e5689b 100644 --- a/test/classes/TrackerTest.php +++ b/test/classes/TrackerTest.php @@ -23,6 +23,9 @@ class TrackerTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + parent::loadDbiIntoContainerBuilder(); + /** * SET these to avoid undefined index error */ @@ -33,6 +36,7 @@ class TrackerTest extends AbstractTestCase $GLOBALS['cfg']['Server']['tracking_default_statements'] = ''; $GLOBALS['cfg']['Server']['tracking_version_auto_create'] = ''; $GLOBALS['cfg']['Server']['DisableIS'] = false; + $GLOBALS['export_type'] = null; $_SESSION['relation'] = []; $_SESSION['relation'][$GLOBALS['server']] = RelationParameters::fromArray([ @@ -499,14 +503,17 @@ class TrackerTest extends AbstractTestCase [ [ "pma'db", + DatabaseInterface::CONNECT_USER, "pma\'db", ], [ "pma'table", + DatabaseInterface::CONNECT_USER, "pma\'table", ], [ '1.0', + DatabaseInterface::CONNECT_USER, '1.0', ], ] diff --git a/test/classes/TrackingTest.php b/test/classes/TrackingTest.php index 2400c3dd19..6f30fa4c7a 100644 --- a/test/classes/TrackingTest.php +++ b/test/classes/TrackingTest.php @@ -31,6 +31,7 @@ class TrackingTest extends AbstractTestCase { parent::setUp(); parent::setTheme(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 1; $GLOBALS['db'] = 'PMA_db'; diff --git a/test/classes/TransformationsTest.php b/test/classes/TransformationsTest.php index f5062a63a0..8cf29c9fb3 100644 --- a/test/classes/TransformationsTest.php +++ b/test/classes/TransformationsTest.php @@ -22,6 +22,7 @@ class TransformationsTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['table'] = 'table'; $GLOBALS['db'] = 'db'; $GLOBALS['cfg'] = [ @@ -100,7 +101,8 @@ class TransformationsTest extends AbstractTestCase } /** - * Test for getting available types. + * @runInSeparateProcess + * @preserveGlobalState disabled */ public function testGetTypes(): void { diff --git a/test/classes/TwoFactorTest.php b/test/classes/TwoFactorTest.php index 48e04cb3bc..42c92d98df 100644 --- a/test/classes/TwoFactorTest.php +++ b/test/classes/TwoFactorTest.php @@ -6,7 +6,9 @@ namespace PhpMyAdmin\Tests; use CodeLts\U2F\U2FServer\RegistrationRequest; use CodeLts\U2F\U2FServer\SignRequest; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Plugins\TwoFactor\Application; +use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\TwoFactor; use function count; @@ -21,10 +23,19 @@ use const JSON_UNESCAPED_SLASHES; */ class TwoFactorTest extends AbstractTestCase { + /** @var DatabaseInterface */ + protected $dbi; + + /** @var DbiDummy */ + protected $dummyDbi; + protected function setUp(): void { parent::setUp(); parent::setTheme(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $GLOBALS['server'] = 1; $GLOBALS['db'] = ''; $GLOBALS['table'] = 'table'; @@ -40,7 +51,7 @@ class TwoFactorTest extends AbstractTestCase protected function tearDown(): void { - $this->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllSelectsConsumed(); } private function initStorageConfigAndData(): void @@ -66,7 +77,9 @@ class TwoFactorTest extends AbstractTestCase $GLOBALS['cfg']['Server']['designer_settings'] = ''; $GLOBALS['cfg']['Server']['export_templates'] = ''; - parent::setGlobalDbi(); + $this->dummyDbi = $this->createDbiDummy(); + $this->dbi = $this->createDatabaseInterface($this->dummyDbi); + $GLOBALS['dbi'] = $this->dbi; $this->dummyDbi->removeDefaultResults(); @@ -175,7 +188,7 @@ class TwoFactorTest extends AbstractTestCase $this->assertTrue($object->check()); $this->assertEquals('', $object->render()); - $this->assertAllQueriesConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); $this->loadResultForConfig(['type' => 'db']); $this->loadQueriesForConfigure(''); @@ -216,7 +229,7 @@ class TwoFactorTest extends AbstractTestCase $GLOBALS['cfg']['DBG']['simple2fa'] = true; $object = $this->getTwoFactorAndLoadConfig('user', null); - $this->assertAllQueriesConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); $this->loadResultForConfig([]); $this->loadQueriesForConfigure('simple'); @@ -225,7 +238,7 @@ class TwoFactorTest extends AbstractTestCase $backend = $object->getBackend(); $this->assertEquals('simple', $backend::$id); - $this->assertAllQueriesConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); $this->loadResultForConfig([]); $this->loadQueriesForConfigure(''); @@ -234,14 +247,14 @@ class TwoFactorTest extends AbstractTestCase $backend = $object->getBackend(); $this->assertEquals('', $backend::$id); - $this->assertAllQueriesConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); $this->initStorageConfigAndData();// Needs a re-init $GLOBALS['cfg']['DBG']['simple2fa'] = false; $object = $this->getTwoFactorAndLoadConfig('user', null); $this->assertFalse($object->configure('simple')); - $this->assertAllQueriesConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); } /** @@ -275,7 +288,7 @@ class TwoFactorTest extends AbstractTestCase $google2fa->getTimestamp() ); - $this->assertAllQueriesConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); $this->loadResultForConfig([]); $this->loadQueriesForConfigure('application', [ 'secret' => $object->config['settings']['secret'], @@ -283,7 +296,7 @@ class TwoFactorTest extends AbstractTestCase $this->assertTrue($object->configure('application')); - $this->assertAllQueriesConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); unset($_POST['2fa_code']); /* Check code */ @@ -405,7 +418,7 @@ class TwoFactorTest extends AbstractTestCase . 'ZLVGZuelRPU2FOVU9XUXhSZDlUV3o1YUZPZzgiLCAib3JpZ2luIjogImh0dHA6XC9cL2RlbW8uZXhhbXB' . 'sZS5jb20iLCAidHlwIjogIm5hdmlnYXRvci5pZC5maW5pc2hFbnJvbGxtZW50IiB9", "errorCode": 0 }'; - $this->assertAllQueriesConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); $this->loadResultForConfig([]); $this->loadQueriesForConfigure('key', [ 'registrations' => [ @@ -454,7 +467,7 @@ class TwoFactorTest extends AbstractTestCase . 'yejRmVWpnYzBRN2ciLCAib3JpZ2luIjogImh0dHA6XC9cL2RlbW8uZXhhbXBsZS5jb20iLCAidHlwI' . 'jogIm5hdmlnYXRvci5pZC5nZXRBc3NlcnRpb24iIH0=", "keyHandle": "CTUayZo8hCBeC-sGQJC' . 'hC0wW-bBg99bmOlGCgw8XGq4dLsxO3yWh9mRYArZxocP5hBB1pEGB3bbJYiM-5acc5w", "errorCode": 0 }'; - $this->assertAllQueriesConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); $this->loadResultForConfig([]); $this->loadQueriesForConfigure('key', [ 'registrations' => [ @@ -481,7 +494,7 @@ class TwoFactorTest extends AbstractTestCase ], ]); $this->assertTrue($object->check(true)); - $this->assertAllQueriesConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); } /** diff --git a/test/classes/TypesTest.php b/test/classes/TypesTest.php index d69b102e05..222d8cd454 100644 --- a/test/classes/TypesTest.php +++ b/test/classes/TypesTest.php @@ -21,6 +21,7 @@ class TypesTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $this->object = new Types($GLOBALS['dbi']); } diff --git a/test/classes/UrlTest.php b/test/classes/UrlTest.php index 0e54fe1fbe..5708af34f6 100644 --- a/test/classes/UrlTest.php +++ b/test/classes/UrlTest.php @@ -188,9 +188,7 @@ class UrlTest extends AbstractTestCase */ public function testBuildHttpQueryWithUrlQueryEncryptionDisabled() { - global $config; - - $config->set('URLQueryEncryption', false); + $GLOBALS['config']->set('URLQueryEncryption', false); $params = ['db' => 'test_db', 'table' => 'test_table', 'pos' => 0]; $this->assertEquals('db=test_db&table=test_table&pos=0', Url::buildHttpQuery($params)); } @@ -200,11 +198,9 @@ class UrlTest extends AbstractTestCase */ public function testBuildHttpQueryWithUrlQueryEncryptionEnabled() { - global $config; - $_SESSION = []; - $config->set('URLQueryEncryption', true); - $config->set('URLQueryEncryptionSecretKey', str_repeat('a', 32)); + $GLOBALS['config']->set('URLQueryEncryption', true); + $GLOBALS['config']->set('URLQueryEncryptionSecretKey', str_repeat('a', 32)); $params = ['db' => 'test_db', 'table' => 'test_table', 'pos' => 0]; $query = Url::buildHttpQuery($params); @@ -232,11 +228,9 @@ class UrlTest extends AbstractTestCase */ public function testQueryEncryption() { - global $config; - $_SESSION = []; - $config->set('URLQueryEncryption', true); - $config->set('URLQueryEncryptionSecretKey', str_repeat('a', 32)); + $GLOBALS['config']->set('URLQueryEncryption', true); + $GLOBALS['config']->set('URLQueryEncryptionSecretKey', str_repeat('a', 32)); $query = '{"db":"test_db","table":"test_table"}'; $encrypted = Url::encryptQuery($query); diff --git a/test/classes/UserPasswordTest.php b/test/classes/UserPasswordTest.php index 1486cb785d..97ba76fc2d 100644 --- a/test/classes/UserPasswordTest.php +++ b/test/classes/UserPasswordTest.php @@ -25,6 +25,7 @@ class UserPasswordTest extends AbstractTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $relation = new Relation($GLOBALS['dbi']); $serverPrivileges = new Privileges( diff --git a/test/classes/UserPreferencesTest.php b/test/classes/UserPreferencesTest.php index b60810d631..edcfc2c1bb 100644 --- a/test/classes/UserPreferencesTest.php +++ b/test/classes/UserPreferencesTest.php @@ -28,6 +28,7 @@ class UserPreferencesTest extends AbstractNetworkTestCase protected function setUp(): void { parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $GLOBALS['server'] = 0; $GLOBALS['text_dir'] = 'ltr'; $GLOBALS['PMA_PHP_SELF'] = '/phpmyadmin/'; diff --git a/test/classes/UtilTest.php b/test/classes/UtilTest.php index e03cd28fe4..0c24278741 100644 --- a/test/classes/UtilTest.php +++ b/test/classes/UtilTest.php @@ -4,11 +4,9 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests; -use PhpMyAdmin\Core; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\FieldMetadata; use PhpMyAdmin\MoTranslator\Loader; -use PhpMyAdmin\ResponseRenderer; use PhpMyAdmin\SqlParser\Context; use PhpMyAdmin\SqlParser\Token; use PhpMyAdmin\Util; @@ -53,6 +51,7 @@ class UtilTest extends AbstractTestCase parent::setUp(); parent::setLanguage(); parent::setTheme(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); } /** @@ -344,52 +343,6 @@ class UtilTest extends AbstractTestCase ); } - public function testCheckParameterMissing(): void - { - parent::setGlobalConfig(); - $_REQUEST = []; - $GLOBALS['text_dir'] = 'ltr'; - $GLOBALS['PMA_PHP_SELF'] = Core::getenv('PHP_SELF'); - $GLOBALS['db'] = 'db'; - $GLOBALS['table'] = 'table'; - $GLOBALS['server'] = 1; - $GLOBALS['cfg']['ServerDefault'] = 1; - $GLOBALS['cfg']['AllowThirdPartyFraming'] = false; - ResponseRenderer::getInstance()->setAjax(false); - - $this->expectOutputRegex('/Missing parameter: field/'); - - Util::checkParameters( - [ - 'db', - 'table', - 'field', - ] - ); - } - - public function testCheckParameter(): void - { - parent::setGlobalConfig(); - $GLOBALS['cfg'] = ['ServerDefault' => 1]; - $GLOBALS['text_dir'] = 'ltr'; - $GLOBALS['PMA_PHP_SELF'] = Core::getenv('PHP_SELF'); - $GLOBALS['db'] = 'dbDatabase'; - $GLOBALS['table'] = 'tblTable'; - $GLOBALS['field'] = 'test_field'; - $GLOBALS['sql_query'] = 'SELECT * FROM tblTable;'; - - $this->expectOutputString(''); - Util::checkParameters( - [ - 'db', - 'table', - 'field', - 'sql_query', - ] - ); - } - /** * Test for Util::convertBitDefaultValue * @@ -561,7 +514,7 @@ class UtilTest extends AbstractTestCase /** * Data provider for testExpandUserString * - * @return array + * @return array<int, string[]> */ public function providerExpandUserString(): array { diff --git a/test/classes/Utils/ForeignKeyTest.php b/test/classes/Utils/ForeignKeyTest.php index e792de8985..a941b2a9c5 100644 --- a/test/classes/Utils/ForeignKeyTest.php +++ b/test/classes/Utils/ForeignKeyTest.php @@ -13,6 +13,12 @@ use PhpMyAdmin\Utils\ForeignKey; */ class ForeignKeyTest extends AbstractTestCase { + protected function setUp(): void + { + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + } + /** * foreign key supported test * diff --git a/test/classes/Utils/GisTest.php b/test/classes/Utils/GisTest.php index d30cf24d62..193dccf870 100644 --- a/test/classes/Utils/GisTest.php +++ b/test/classes/Utils/GisTest.php @@ -16,6 +16,12 @@ use function hex2bin; */ class GisTest extends AbstractTestCase { + protected function setUp(): void + { + parent::setUp(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); + } + /** * @param string $expectedQuery The query to expect * @param array $returnData The data to return for fetchRow diff --git a/test/classes/Utils/HttpRequestTest.php b/test/classes/Utils/HttpRequestTest.php index 3824aa15e8..77deb3602c 100644 --- a/test/classes/Utils/HttpRequestTest.php +++ b/test/classes/Utils/HttpRequestTest.php @@ -26,6 +26,7 @@ class HttpRequestTest extends AbstractTestCase { parent::setUp(); parent::setProxySettings(); + $GLOBALS['dbi'] = $this->createDatabaseInterface(); $this->httpRequest = new HttpRequest(); } diff --git a/test/classes/Utils/SessionCacheTest.php b/test/classes/Utils/SessionCacheTest.php index 488bf06874..0cfaffea52 100644 --- a/test/classes/Utils/SessionCacheTest.php +++ b/test/classes/Utils/SessionCacheTest.php @@ -14,11 +14,9 @@ class SessionCacheTest extends TestCase { public function testGet(): void { - global $cfg, $server; - $_SESSION = []; - $cfg['Server']['user'] = null; - $server = 'server'; + $GLOBALS['cfg']['Server']['user'] = null; + $GLOBALS['server'] = 'server'; SessionCache::set('test_data', 5); SessionCache::set('test_data_2', 5); @@ -30,11 +28,9 @@ class SessionCacheTest extends TestCase public function testRemove(): void { - global $cfg, $server; - $_SESSION = []; - $cfg['Server']['user'] = null; - $server = 'server'; + $GLOBALS['cfg']['Server']['user'] = null; + $GLOBALS['server'] = 'server'; SessionCache::set('test_data', 25); SessionCache::set('test_data_2', 25); @@ -47,11 +43,9 @@ class SessionCacheTest extends TestCase public function testSet(): void { - global $cfg, $server; - $_SESSION = []; - $cfg['Server']['user'] = null; - $server = 'server'; + $GLOBALS['cfg']['Server']['user'] = null; + $GLOBALS['server'] = 'server'; SessionCache::set('test_data', 25); SessionCache::set('test_data', 5); @@ -62,11 +56,9 @@ class SessionCacheTest extends TestCase public function testHas(): void { - global $cfg, $server; - $_SESSION = []; - $cfg['Server']['user'] = null; - $server = 'server'; + $GLOBALS['cfg']['Server']['user'] = null; + $GLOBALS['server'] = 'server'; SessionCache::set('test_data', 5); SessionCache::set('test_data_2', 5); @@ -82,11 +74,9 @@ class SessionCacheTest extends TestCase public function testKeyWithoutUser(): void { - global $cfg, $server; - $_SESSION = []; - $cfg['Server']['user'] = null; - $server = 123; + $GLOBALS['cfg']['Server']['user'] = null; + $GLOBALS['server'] = 123; SessionCache::set('test_data', 5); $this->assertArrayHasKey('cache', $_SESSION); @@ -99,11 +89,9 @@ class SessionCacheTest extends TestCase public function testKeyWithUser(): void { - global $cfg, $server; - $_SESSION = []; - $cfg['Server']['user'] = 'test_user'; - $server = 123; + $GLOBALS['cfg']['Server']['user'] = 'test_user'; + $GLOBALS['server'] = 123; SessionCache::set('test_data', 5); $this->assertArrayHasKey('cache', $_SESSION); diff --git a/test/classes/_data/gen_version_info/theme.json b/test/classes/_data/gen_version_info/theme.json index 2f0456d5d7..90e76b7828 100644 --- a/test/classes/_data/gen_version_info/theme.json +++ b/test/classes/_data/gen_version_info/theme.json @@ -1,7 +1,7 @@ { "name": "Test Theme", - "version": "5.1", + "version": "5.3", "author": "phpMyAdmin developers", "url": "https://www.phpmyadmin.net/", - "supports": ["5.1", "5.2"] + "supports": ["5.2", "5.3"] } diff --git a/test/javascript/sql.test.js b/test/javascript/sql.test.js index e2b333329d..0fb6b29654 100644 --- a/test/javascript/sql.test.js +++ b/test/javascript/sql.test.js @@ -1,6 +1,8 @@ /* eslint-env node, jest */ +/* global Sql */ -const Sql = require('phpmyadmin/sql'); +import 'phpmyadmin/ajax'; +import 'phpmyadmin/sql'; describe('SQL', () => { test('test URL encode', () => { diff --git a/test/jest/file-transformer.js b/test/jest/file-transformer.js deleted file mode 100644 index 81ea49b9a1..0000000000 --- a/test/jest/file-transformer.js +++ /dev/null @@ -1,17 +0,0 @@ -/* eslint-env node */ - -module.exports = { - process (sourceContents, filename) { - // The file is a source file and can contain @test-module annotations - if (filename.indexOf('js/src') !== -1) { - if (sourceContents.includes('@test-module')) { - // Annotation detected, add some code to the source file - const moduleName = sourceContents.match(/@test-module (.*)/)[1]; - // eslint-disable-next-line no-param-reassign - sourceContents += '\r\nmodule.exports = ' + moduleName + ';\r\n'; - } - return sourceContents; - } - return sourceContents; - }, -}; diff --git a/test/jest/test-env.js b/test/jest/test-env.js deleted file mode 100644 index 3276c5fa93..0000000000 --- a/test/jest/test-env.js +++ /dev/null @@ -1,8 +0,0 @@ -/* eslint-env node */ - -const $ = require('jquery'); -global.$ = $; -global.jQuery = $; -global.CommonParams = require('phpmyadmin/common'); -global.AJAX = require('phpmyadmin/ajax'); -global.Functions = require('phpmyadmin/functions'); diff --git a/test/selenium/ChangePasswordTest.php b/test/selenium/ChangePasswordTest.php index dbb6125b81..f04a7690f4 100644 --- a/test/selenium/ChangePasswordTest.php +++ b/test/selenium/ChangePasswordTest.php @@ -80,7 +80,7 @@ class ChangePasswordTest extends TestBase $this->byId('nopass_1')->click(); } - $this->byCssSelector('#change_password_dialog + div button')->click(); + $this->byId('changePasswordGoButton')->click(); $ele = $this->waitForElement('cssSelector', '.alert-success'); $this->assertEquals( 'The profile has been updated.', diff --git a/test/selenium/CreateRemoveUserTest.php b/test/selenium/CreateRemoveUserTest.php index ec442666c8..3868daf2e9 100644 --- a/test/selenium/CreateRemoveUserTest.php +++ b/test/selenium/CreateRemoveUserTest.php @@ -4,6 +4,9 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Selenium; +use function bin2hex; +use function random_bytes; + /** * @coversNothing */ @@ -37,7 +40,7 @@ class CreateRemoveUserTest extends TestBase { parent::setUp(); $this->skipIfNotSuperUser(); - $this->txtUsername = 'pma_user'; + $this->txtUsername = 'test_user_' . bin2hex(random_bytes(4)); $this->txtPassword = 'abc_123'; $this->login(); } @@ -102,7 +105,7 @@ class CreateRemoveUserTest extends TestBase $this->byId('dropUsersDbCheckbox')->click(); $this->byId('buttonGo')->click(); - $this->waitForElement('cssSelector', 'button.submitOK')->click(); + $this->waitForElement('id', 'functionConfirmOkButton')->click(); $this->acceptAlert(); $success = $this->waitForElement('cssSelector', '.alert-success'); diff --git a/test/selenium/Database/EventsTest.php b/test/selenium/Database/EventsTest.php index 9e4a7d7ef9..3d6317b52d 100644 --- a/test/selenium/Database/EventsTest.php +++ b/test/selenium/Database/EventsTest.php @@ -111,7 +111,7 @@ class EventsTest extends TestBase ->click()// Click to free the mouse ->perform(); - $this->byXPath("//button[contains(., 'Go')]")->click(); + $this->byCssSelector('div.ui-dialog-buttonset button:nth-child(1)')->click(); $this->waitForElement( 'xpath', @@ -174,7 +174,7 @@ class EventsTest extends TestBase $this->byName('item_interval_value')->clear(); $this->byName('item_interval_value')->sendKeys('2'); - $this->byXPath("//button[contains(., 'Go')]")->click(); + $this->byCssSelector('div.ui-dialog-buttonset button:nth-child(1)')->click(); $this->waitForElement( 'xpath', @@ -207,7 +207,7 @@ class EventsTest extends TestBase $this->waitForElement('xpath', '//div[contains(., "Event scheduler status")]'); $this->byPartialLinkText('Drop')->click(); - $this->waitForElement('className', 'submitOK')->click(); + $this->waitForElement('id', 'functionConfirmOkButton')->click(); $this->waitAjaxMessage(); diff --git a/test/selenium/Database/OperationsTest.php b/test/selenium/Database/OperationsTest.php index c7e2504610..f115f177b8 100644 --- a/test/selenium/Database/OperationsTest.php +++ b/test/selenium/Database/OperationsTest.php @@ -68,7 +68,7 @@ class OperationsTest extends TestBase $this->byCssSelector("form#rename_db_form input[type='submit']")->click(); - $this->waitForElement('cssSelector', 'button.submitOK')->click(); + $this->waitForElement('id', 'functionConfirmOkButton')->click(); $this->waitForElement( 'xpath', diff --git a/test/selenium/Database/ProceduresTest.php b/test/selenium/Database/ProceduresTest.php index 496c0136f1..5a2531b624 100644 --- a/test/selenium/Database/ProceduresTest.php +++ b/test/selenium/Database/ProceduresTest.php @@ -149,7 +149,7 @@ class ProceduresTest extends TestBase 'READS SQL DATA' ); - $this->byXPath("//button[contains(., 'Go')]")->click(); + $this->byCssSelector('div.ui-dialog-buttonset button:nth-child(1)')->click(); $this->waitForElement( 'xpath', @@ -185,7 +185,7 @@ class ProceduresTest extends TestBase $this->byName('item_param_length[0]')->clear(); $this->byName('item_param_length[0]')->sendKeys('30'); - $this->byXPath("//button[contains(., 'Go')]")->click(); + $this->byCssSelector('div.ui-dialog-buttonset button:nth-child(1)')->click(); $this->waitForElement( 'xpath', @@ -209,7 +209,7 @@ class ProceduresTest extends TestBase $this->waitForElement('id', 'checkAllCheckbox'); $this->byPartialLinkText('Drop')->click(); - $this->waitForElement('cssSelector', 'button.submitOK')->click(); + $this->waitForElement('id', 'functionConfirmOkButton')->click(); $this->waitAjaxMessage(); diff --git a/test/selenium/Database/StructureTest.php b/test/selenium/Database/StructureTest.php index 0eaed7fd7b..185ed39be9 100644 --- a/test/selenium/Database/StructureTest.php +++ b/test/selenium/Database/StructureTest.php @@ -49,7 +49,7 @@ class StructureTest extends TestBase { $this->byXPath("(//a[contains(., 'Empty')])[1]")->click(); - $this->waitForElement('cssSelector', 'button.submitOK')->click(); + $this->waitForElement('id', 'functionConfirmOkButton')->click(); $this->assertNotNull( $this->waitForElement( diff --git a/test/selenium/Database/TriggersTest.php b/test/selenium/Database/TriggersTest.php index f819d25210..1d0c33b16c 100644 --- a/test/selenium/Database/TriggersTest.php +++ b/test/selenium/Database/TriggersTest.php @@ -92,7 +92,7 @@ class TriggersTest extends TestBase $proc = 'UPDATE ' . $this->databaseName . '.`test_table2` SET val=val+1'; $this->typeInTextArea($proc); - $this->byXPath("//button[contains(., 'Go')]")->click(); + $this->byCssSelector('div.ui-dialog-buttonset button:nth-child(1)')->click(); $this->waitForElement( 'xpath', @@ -147,7 +147,7 @@ class TriggersTest extends TestBase $proc = 'UPDATE ' . $this->databaseName . '.`test_table2` SET val=val+10'; $this->typeInTextArea($proc); - $this->byXPath("//button[contains(., 'Go')]")->click(); + $this->byCssSelector('div.ui-dialog-buttonset button:nth-child(1)')->click(); $this->waitForElement( 'xpath', @@ -182,7 +182,7 @@ class TriggersTest extends TestBase $this->waitForElement('id', 'checkAllCheckbox'); $this->byPartialLinkText('Drop')->click(); - $this->waitForElement('cssSelector', 'button.submitOK')->click(); + $this->waitForElement('id', 'functionConfirmOkButton')->click(); $this->waitAjaxMessage(); diff --git a/test/selenium/ExportTest.php b/test/selenium/ExportTest.php index ffa7ef8fad..94aca69911 100644 --- a/test/selenium/ExportTest.php +++ b/test/selenium/ExportTest.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Selenium; +use function sleep; + /** * @coversNothing */ @@ -159,13 +161,16 @@ class ExportTest extends TestBase $this->scrollIntoView('checkbox_sql_if_not_exists'); $ele = $this->byId('checkbox_sql_if_not_exists'); if (! $ele->isSelected()) { - $this->byCssSelector('label[for=checkbox_sql_if_not_exists]')->click(); + $this->waitForElement('cssSelector', 'label[for=checkbox_sql_if_not_exists]')->click(); } } $this->scrollToBottom(); + sleep(2); + $this->scrollToBottom(); + + $this->waitForElement('id', 'buttonGo')->click(); - $this->byId('buttonGo')->click(); $this->waitAjax(); return $this->waitForElement('id', 'textSQLDUMP')->getText(); diff --git a/test/selenium/Table/BrowseTest.php b/test/selenium/Table/BrowseTest.php index f8b98e5c68..cd26211d63 100644 --- a/test/selenium/Table/BrowseTest.php +++ b/test/selenium/Table/BrowseTest.php @@ -313,7 +313,16 @@ class BrowseTest extends TestBase $this->byId('buttonYes')->click(); $this->waitAjax(); - $success = $this->waitForElement('className', 'alert-success'); + + $success = $this->waitForElement( + 'cssSelector', + '.sqlqueryresults > .result_query:nth-child(1) > .alert-success' + ); + $this->assertStringContainsString('Your SQL query has been executed successfully.', $success->getText()); + $success = $this->waitForElement( + 'cssSelector', + '.sqlqueryresults > .result_query:nth-child(2) > .alert-success' + ); $this->assertStringContainsString('Showing rows', $success->getText()); $this->assertFalse( diff --git a/test/selenium/Table/OperationsTest.php b/test/selenium/Table/OperationsTest.php index 5088e65669..3d0044be1c 100644 --- a/test/selenium/Table/OperationsTest.php +++ b/test/selenium/Table/OperationsTest.php @@ -185,7 +185,7 @@ class OperationsTest extends TestBase $this->scrollToBottom(); $this->waitUntilElementIsVisible('id', 'drop_tbl_anchor', 30); $this->byId('truncate_tbl_anchor')->click(); - $this->byCssSelector('button.submitOK')->click(); + $this->waitForElement('id', 'functionConfirmOkButton')->click(); $this->waitAjax(); $this->waitForElement( @@ -212,7 +212,7 @@ class OperationsTest extends TestBase $dropLink = $this->waitUntilElementIsVisible('partialLinkText', 'Delete the table (DROP)', 30); $this->scrollToBottom(); $dropLink->click(); - $this->byCssSelector('button.submitOK')->click(); + $this->waitForElement('id', 'functionConfirmOkButton')->click(); $this->waitAjax(); $this->waitForElement( diff --git a/test/selenium/TestBase.php b/test/selenium/TestBase.php index e1c6d6aefd..3689609224 100644 --- a/test/selenium/TestBase.php +++ b/test/selenium/TestBase.php @@ -21,6 +21,7 @@ use InvalidArgumentException; use PHPUnit\Framework\TestCase; use Throwable; +use function bin2hex; use function curl_close; use function curl_errno; use function curl_error; @@ -36,12 +37,9 @@ use function is_string; use function json_decode; use function json_encode; use function mb_strtolower; -use function mb_substr; -use function mt_getrandmax; use function preg_match; -use function random_int; +use function random_bytes; use function reset; -use function sha1; use function sprintf; use function strlen; use function substr; @@ -159,7 +157,7 @@ abstract class TestBase extends TestCase */ protected function createDatabase(): void { - $this->databaseName = $this->getDbPrefix() . mb_substr(sha1((string) random_int(0, mt_getrandmax())), 0, 7); + $this->databaseName = $this->getDbPrefix() . bin2hex(random_bytes(4)); $this->dbQuery( 'CREATE DATABASE IF NOT EXISTS `' . $this->databaseName . '`; USE `' . $this->databaseName . '`;' ); @@ -1075,7 +1073,7 @@ JS; $this->webDriver->executeAsyncScript( 'var callback = arguments[arguments.length - 1];' . 'function startWaitingForAjax() {' - . ' if (! AJAX.active) {' + . ' if (! window.AJAX.active) {' . ' callback();' . ' } else {' . ' setTimeout(startWaitingForAjax, 200);' @@ -1091,7 +1089,7 @@ JS; public function waitAjaxMessage(): void { /* Get current message count */ - $ajax_message_count = $this->webDriver->executeScript('return ajaxMessageCount;'); + $ajax_message_count = $this->webDriver->executeScript('return Functions.getAjaxMessageCount();'); /* Ensure the popup is gone */ $this->waitForElementNotPresent('id', 'ajax_message_num_' . $ajax_message_count); } diff --git a/test/selenium/TrackingTest.php b/test/selenium/TrackingTest.php index 49c2fb2d2e..70220eaf2f 100644 --- a/test/selenium/TrackingTest.php +++ b/test/selenium/TrackingTest.php @@ -163,7 +163,7 @@ class TrackingTest extends TestBase $this->moveto($ele); $this->click(); - $this->waitForElement('cssSelector', 'button.submitOK')->click(); + $this->waitForElement('id', 'functionConfirmOkButton')->click(); $this->waitAjax(); $this->waitForElement( diff --git a/test/stubs/Query.stub b/test/stubs/Query.stub new file mode 100644 index 0000000000..9a09dacd5c --- /dev/null +++ b/test/stubs/Query.stub @@ -0,0 +1,53 @@ +<?php + +namespace PhpMyAdmin\SqlParser; + +class Core {} +class Parser extends Core {} +abstract class Statement {} + +namespace PhpMyAdmin\SqlParser\Utils; + +use PhpMyAdmin\SqlParser\Parser; +use PhpMyAdmin\SqlParser\Statement; + +class Query +{ + /** + * @param string $query + * @return array{ + * distinct: bool, + * drop_database: bool, + * group: bool, + * having: bool, + * is_affected: bool, + * is_analyse: bool, + * is_count: bool, + * is_delete: bool, + * is_explain: bool, + * is_export: bool, + * is_func: bool, + * is_group: bool, + * is_insert: bool, + * is_maint: bool, + * is_procedure: bool, + * is_replace: bool, + * is_select: bool, + * is_show: bool, + * is_subquery: bool, + * join: bool, + * limit: bool, + * offset: bool, + * order: bool, + * querytype: ('ALTER'|'ANALYZE'|'CALL'|'CHECK'|'CHECKSUM'|'CREATE'|'DELETE'|'DROP'|'EXPLAIN'|'INSERT'|'LOAD'|'OPTIMIZE'|'REPAIR'|'REPLACE'|'SELECT'|'SET'|'SHOW'|'UPDATE'|false), + * reload: bool, + * select_from: bool, + * union: bool, + * parser?: Parser, + * statement?: Statement, + * select_tables?: list<array{string|null, string|null}>, + * select_expr?: list<string|null> + * } + */ + public static function getAll($query); +} |