Add tests for CopyStructureController and fix HTML fixture
Signed-off-by: Satyam <satyam.gupta756@gmail.com>
This commit is contained in:
parent
3d7ad3e477
commit
fd5e5b84a7
@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Tests\Controllers\Database\Structure;
|
||||
|
||||
use PhpMyAdmin\Controllers\Database\Structure\CopyStructureController;
|
||||
use PhpMyAdmin\Current;
|
||||
use PhpMyAdmin\Dbal\DatabaseInterface;
|
||||
use PhpMyAdmin\DbTableExists;
|
||||
use PhpMyAdmin\Http\Factory\ServerRequestFactory;
|
||||
use PhpMyAdmin\Tests\AbstractTestCase;
|
||||
use PhpMyAdmin\Tests\Stubs\ResponseRenderer as ResponseStub;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
|
||||
#[CoversClass(CopyStructureController::class)]
|
||||
final class CopyStructureControllerTest extends AbstractTestCase
|
||||
{
|
||||
public function testReturnErrorWhenNoDatabaseSet(): void
|
||||
{
|
||||
Current::$database = '';
|
||||
|
||||
$dbi = $this->createDatabaseInterface();
|
||||
DatabaseInterface::$instance = $dbi;
|
||||
|
||||
$response = new ResponseStub();
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withQueryParams(['db' => '']);
|
||||
|
||||
(new CopyStructureController($response, $dbi, new DbTableExists($dbi)))($request);
|
||||
|
||||
self::assertFalse($response->hasSuccessState());
|
||||
self::assertStringContainsString('No databases selected', $response->getJSONResult()['message']);
|
||||
}
|
||||
|
||||
public function testReturnErrorWhenDatabaseNameInvalid(): void
|
||||
{
|
||||
Current::$database = 'test_db';
|
||||
|
||||
$dbi = $this->createDatabaseInterface();
|
||||
DatabaseInterface::$instance = $dbi;
|
||||
|
||||
$response = new ResponseStub();
|
||||
// empty 'db' param → DatabaseName::tryFrom returns null
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withQueryParams(['db' => '']);
|
||||
|
||||
(new CopyStructureController($response, $dbi, new DbTableExists($dbi)))($request);
|
||||
|
||||
self::assertFalse($response->hasSuccessState());
|
||||
self::assertStringContainsString('No databases selected', $response->getJSONResult()['message']);
|
||||
}
|
||||
|
||||
public function testReturnsSqlForTablesOnly(): void
|
||||
{
|
||||
Current::$database = 'test_db';
|
||||
|
||||
$createSql = "CREATE TABLE `orders` (\n `id` int(11) NOT NULL\n) ENGINE=InnoDB";
|
||||
|
||||
$dbiDummy = $this->createDbiDummy();
|
||||
// DbTableExists::selectDatabase() + $this->dbi->selectDb() both call selectDb
|
||||
$dbiDummy->addSelectDb('test_db');
|
||||
$dbiDummy->addSelectDb('test_db');
|
||||
// getTables() call
|
||||
$dbiDummy->addResult(
|
||||
'SHOW TABLES FROM `test_db`;',
|
||||
[['orders']],
|
||||
);
|
||||
// showCreate() for orders
|
||||
$dbiDummy->addResult(
|
||||
'SHOW CREATE TABLE `test_db`.`orders`',
|
||||
[['orders', $createSql]],
|
||||
['Table', 'Create Table'],
|
||||
);
|
||||
|
||||
$dbi = $this->createDatabaseInterface($dbiDummy);
|
||||
DatabaseInterface::$instance = $dbi;
|
||||
|
||||
// Pre-seed the TABLE_TYPE cache so isView() returns false without an extra query
|
||||
$dbi->getCache()->cacheTableValue('test_db', 'orders', 'TABLE_TYPE', 'BASE TABLE');
|
||||
|
||||
$response = new ResponseStub();
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withQueryParams(['db' => 'test_db'])
|
||||
->withParsedBody(['db' => 'test_db']);
|
||||
|
||||
(new CopyStructureController($response, $dbi, new DbTableExists($dbi)))($request);
|
||||
|
||||
self::assertTrue($response->hasSuccessState());
|
||||
$sql = $response->getJSONResult()['sql'];
|
||||
self::assertStringContainsString('-- Database: test_db', $sql);
|
||||
self::assertStringContainsString($createSql, $sql);
|
||||
self::assertStringNotContainsString('-- Views', $sql);
|
||||
|
||||
$dbiDummy->assertAllSelectsConsumed();
|
||||
$dbiDummy->assertAllQueriesConsumed();
|
||||
}
|
||||
|
||||
public function testReturnsSqlWithViewsSeparated(): void
|
||||
{
|
||||
Current::$database = 'test_db';
|
||||
|
||||
$tableSql = "CREATE TABLE `products` (\n `id` int(11) NOT NULL\n) ENGINE=InnoDB";
|
||||
$viewSql = "CREATE VIEW `v_products` AS SELECT * FROM `products`";
|
||||
|
||||
$dbiDummy = $this->createDbiDummy();
|
||||
$dbiDummy->addSelectDb('test_db');
|
||||
$dbiDummy->addSelectDb('test_db');
|
||||
$dbiDummy->addResult(
|
||||
'SHOW TABLES FROM `test_db`;',
|
||||
[['products'], ['v_products']],
|
||||
);
|
||||
$dbiDummy->addResult(
|
||||
'SHOW CREATE TABLE `test_db`.`products`',
|
||||
[['products', $tableSql]],
|
||||
['Table', 'Create Table'],
|
||||
);
|
||||
$dbiDummy->addResult(
|
||||
'SHOW CREATE TABLE `test_db`.`v_products`',
|
||||
[['v_products', $viewSql]],
|
||||
['Table', 'Create Table'],
|
||||
);
|
||||
|
||||
$dbi = $this->createDatabaseInterface($dbiDummy);
|
||||
DatabaseInterface::$instance = $dbi;
|
||||
|
||||
$dbi->getCache()->cacheTableValue('test_db', 'products', 'TABLE_TYPE', 'BASE TABLE');
|
||||
$dbi->getCache()->cacheTableValue('test_db', 'v_products', 'TABLE_TYPE', 'VIEW');
|
||||
|
||||
$response = new ResponseStub();
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withQueryParams(['db' => 'test_db'])
|
||||
->withParsedBody(['db' => 'test_db']);
|
||||
|
||||
(new CopyStructureController($response, $dbi, new DbTableExists($dbi)))($request);
|
||||
|
||||
self::assertTrue($response->hasSuccessState());
|
||||
$sql = $response->getJSONResult()['sql'];
|
||||
self::assertStringContainsString('-- Database: test_db', $sql);
|
||||
self::assertStringContainsString($tableSql, $sql);
|
||||
self::assertStringContainsString('-- Views', $sql);
|
||||
self::assertStringContainsString($viewSql, $sql);
|
||||
// Views section must come after tables
|
||||
self::assertGreaterThan(
|
||||
strpos($sql, $tableSql),
|
||||
strpos($sql, '-- Views'),
|
||||
);
|
||||
|
||||
$dbiDummy->assertAllSelectsConsumed();
|
||||
$dbiDummy->assertAllQueriesConsumed();
|
||||
}
|
||||
|
||||
public function testReturnsSqlForEmptyDatabase(): void
|
||||
{
|
||||
Current::$database = 'empty_db';
|
||||
|
||||
$dbiDummy = $this->createDbiDummy();
|
||||
$dbiDummy->addSelectDb('empty_db');
|
||||
$dbiDummy->addSelectDb('empty_db');
|
||||
$dbiDummy->addResult('SHOW TABLES FROM `empty_db`;', []);
|
||||
|
||||
$dbi = $this->createDatabaseInterface($dbiDummy);
|
||||
DatabaseInterface::$instance = $dbi;
|
||||
|
||||
$response = new ResponseStub();
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withQueryParams(['db' => 'empty_db'])
|
||||
->withParsedBody(['db' => 'empty_db']);
|
||||
|
||||
(new CopyStructureController($response, $dbi, new DbTableExists($dbi)))($request);
|
||||
|
||||
self::assertTrue($response->hasSuccessState());
|
||||
$sql = $response->getJSONResult()['sql'];
|
||||
self::assertStringContainsString('-- Database: empty_db', $sql);
|
||||
self::assertStringNotContainsString('CREATE TABLE', $sql);
|
||||
self::assertStringNotContainsString('-- Views', $sql);
|
||||
|
||||
$dbiDummy->assertAllSelectsConsumed();
|
||||
$dbiDummy->assertAllQueriesConsumed();
|
||||
}
|
||||
}
|
||||
@ -363,6 +363,9 @@
|
||||
<hr>
|
||||
<p class="d-print-none">
|
||||
<button type="button" class="btn btn-link p-0 jsPrintButton"><span class="text-nowrap"><img src="themes/dot.gif" title="Print" alt="Print" class="icon ic_b_print"> Print</span></button>
|
||||
<button type="button" id="copyStructureBtn" class="btn btn-link p-0">
|
||||
<span class="text-nowrap"><img src="themes/dot.gif" title="Copy DB Structure" alt="Copy DB Structure" class="icon ic_b_export"> Copy DB Structure</span>
|
||||
</button>
|
||||
<a href="index.php?route=/database/data-dictionary&db=test_db&goto=index.php%3Froute%3D%2Fdatabase%2Fstructure%26lang%3Den&lang=en">
|
||||
<span class="text-nowrap"><img src="themes/dot.gif" title="Data dictionary" alt="Data dictionary" class="icon ic_b_tblanalyse"> Data dictionary</span>
|
||||
</a>
|
||||
|
||||
@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Tests\Controllers\Table\Structure;
|
||||
|
||||
use PhpMyAdmin\Controllers\Table\Structure\CopyStructureController;
|
||||
use PhpMyAdmin\Current;
|
||||
use PhpMyAdmin\Dbal\DatabaseInterface;
|
||||
use PhpMyAdmin\DbTableExists;
|
||||
use PhpMyAdmin\Http\Factory\ServerRequestFactory;
|
||||
use PhpMyAdmin\Tests\AbstractTestCase;
|
||||
use PhpMyAdmin\Tests\Stubs\ResponseRenderer as ResponseStub;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
|
||||
#[CoversClass(CopyStructureController::class)]
|
||||
final class CopyStructureControllerTest extends AbstractTestCase
|
||||
{
|
||||
public function testReturnErrorWhenNoDatabaseSet(): void
|
||||
{
|
||||
Current::$database = '';
|
||||
Current::$table = 'orders';
|
||||
|
||||
$dbi = $this->createDatabaseInterface();
|
||||
DatabaseInterface::$instance = $dbi;
|
||||
|
||||
$response = new ResponseStub();
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withQueryParams(['db' => '', 'table' => 'orders']);
|
||||
|
||||
(new CopyStructureController($response, $dbi, new DbTableExists($dbi)))($request);
|
||||
|
||||
self::assertFalse($response->hasSuccessState());
|
||||
self::assertStringContainsString('No databases selected', $response->getJSONResult()['message']);
|
||||
}
|
||||
|
||||
public function testReturnErrorWhenNoTableSet(): void
|
||||
{
|
||||
Current::$database = 'test_db';
|
||||
Current::$table = '';
|
||||
|
||||
$dbi = $this->createDatabaseInterface();
|
||||
DatabaseInterface::$instance = $dbi;
|
||||
|
||||
$response = new ResponseStub();
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withQueryParams(['db' => 'test_db', 'table' => '']);
|
||||
|
||||
(new CopyStructureController($response, $dbi, new DbTableExists($dbi)))($request);
|
||||
|
||||
self::assertFalse($response->hasSuccessState());
|
||||
self::assertStringContainsString('No table selected', $response->getJSONResult()['message']);
|
||||
}
|
||||
|
||||
public function testReturnErrorWhenDatabaseNameInvalid(): void
|
||||
{
|
||||
Current::$database = 'test_db';
|
||||
Current::$table = 'orders';
|
||||
|
||||
// Controller calls selectDb(Current::$database) before the DatabaseName check
|
||||
$dbiDummy = $this->createDbiDummy();
|
||||
$dbiDummy->addSelectDb('test_db');
|
||||
$dbi = $this->createDatabaseInterface($dbiDummy);
|
||||
DatabaseInterface::$instance = $dbi;
|
||||
|
||||
$response = new ResponseStub();
|
||||
// 'db' param is empty → DatabaseName::tryFrom returns null
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withQueryParams(['db' => '', 'table' => 'orders']);
|
||||
|
||||
(new CopyStructureController($response, $dbi, new DbTableExists($dbi)))($request);
|
||||
|
||||
self::assertFalse($response->hasSuccessState());
|
||||
self::assertStringContainsString('No databases selected', $response->getJSONResult()['message']);
|
||||
|
||||
$dbiDummy->assertAllSelectsConsumed();
|
||||
}
|
||||
|
||||
public function testReturnsSqlForTable(): void
|
||||
{
|
||||
Current::$database = 'test_db';
|
||||
Current::$table = 'orders';
|
||||
|
||||
$createSql = "CREATE TABLE `orders` (\n `id` int(11) NOT NULL\n) ENGINE=InnoDB";
|
||||
|
||||
$dbiDummy = $this->createDbiDummy();
|
||||
// 1st: controller calls selectDb(Current::$database)
|
||||
// 2nd: DbTableExists::selectDatabase() calls selectDb($databaseName)
|
||||
$dbiDummy->addSelectDb('test_db');
|
||||
$dbiDummy->addSelectDb('test_db');
|
||||
// DbTableExists::hasTable issues SELECT 1 FROM `db`.`table` LIMIT 1
|
||||
$dbiDummy->addResult('SELECT 1 FROM `test_db`.`orders` LIMIT 1;', [['1']]);
|
||||
// showCreate()
|
||||
$dbiDummy->addResult(
|
||||
'SHOW CREATE TABLE `test_db`.`orders`',
|
||||
[['orders', $createSql]],
|
||||
['Table', 'Create Table'],
|
||||
);
|
||||
|
||||
$dbi = $this->createDatabaseInterface($dbiDummy);
|
||||
DatabaseInterface::$instance = $dbi;
|
||||
|
||||
$response = new ResponseStub();
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withQueryParams(['db' => 'test_db', 'table' => 'orders'])
|
||||
->withParsedBody(['db' => 'test_db', 'table' => 'orders']);
|
||||
|
||||
(new CopyStructureController($response, $dbi, new DbTableExists($dbi)))($request);
|
||||
|
||||
self::assertTrue($response->hasSuccessState());
|
||||
self::assertSame($createSql, $response->getJSONResult()['sql']);
|
||||
|
||||
$dbiDummy->assertAllSelectsConsumed();
|
||||
$dbiDummy->assertAllQueriesConsumed();
|
||||
}
|
||||
|
||||
public function testReturnsSqlForView(): void
|
||||
{
|
||||
Current::$database = 'test_db';
|
||||
Current::$table = 'v_orders';
|
||||
|
||||
$viewSql = 'CREATE VIEW `v_orders` AS SELECT * FROM `orders`';
|
||||
|
||||
$dbiDummy = $this->createDbiDummy();
|
||||
$dbiDummy->addSelectDb('test_db');
|
||||
$dbiDummy->addSelectDb('test_db');
|
||||
$dbiDummy->addResult('SELECT 1 FROM `test_db`.`v_orders` LIMIT 1;', [['1']]);
|
||||
$dbiDummy->addResult(
|
||||
'SHOW CREATE TABLE `test_db`.`v_orders`',
|
||||
[['v_orders', $viewSql]],
|
||||
['Table', 'Create Table'],
|
||||
);
|
||||
|
||||
$dbi = $this->createDatabaseInterface($dbiDummy);
|
||||
DatabaseInterface::$instance = $dbi;
|
||||
|
||||
$response = new ResponseStub();
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withQueryParams(['db' => 'test_db', 'table' => 'v_orders'])
|
||||
->withParsedBody(['db' => 'test_db', 'table' => 'v_orders']);
|
||||
|
||||
(new CopyStructureController($response, $dbi, new DbTableExists($dbi)))($request);
|
||||
|
||||
self::assertTrue($response->hasSuccessState());
|
||||
self::assertSame($viewSql, $response->getJSONResult()['sql']);
|
||||
|
||||
$dbiDummy->assertAllSelectsConsumed();
|
||||
$dbiDummy->assertAllQueriesConsumed();
|
||||
}
|
||||
|
||||
public function testReturnErrorWhenTableDoesNotExist(): void
|
||||
{
|
||||
Current::$database = 'test_db';
|
||||
Current::$table = 'ghost_table';
|
||||
|
||||
$dbiDummy = $this->createDbiDummy();
|
||||
$dbiDummy->addSelectDb('test_db');
|
||||
$dbiDummy->addSelectDb('test_db');
|
||||
// hasTable SELECT fails (table not found)
|
||||
$dbiDummy->addResult('SELECT 1 FROM `test_db`.`ghost_table` LIMIT 1;', false);
|
||||
|
||||
$dbi = $this->createDatabaseInterface($dbiDummy);
|
||||
DatabaseInterface::$instance = $dbi;
|
||||
|
||||
$response = new ResponseStub();
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withQueryParams(['db' => 'test_db', 'table' => 'ghost_table'])
|
||||
->withParsedBody(['db' => 'test_db', 'table' => 'ghost_table']);
|
||||
|
||||
(new CopyStructureController($response, $dbi, new DbTableExists($dbi)))($request);
|
||||
|
||||
self::assertFalse($response->hasSuccessState());
|
||||
self::assertStringContainsString('No table selected', $response->getJSONResult()['message']);
|
||||
|
||||
$dbiDummy->assertAllSelectsConsumed();
|
||||
$dbiDummy->assertAllQueriesConsumed();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user