Skip to content
Snippets Groups Projects

Resolve #3408835 "Sqlitedatabaseexcluder accidentally includes"

1 unresolved thread
1 file
+ 76
97
Compare changes
  • Side-by-side
  • Inline
@@ -48,126 +48,105 @@ class SqliteDatabaseExcluderTest extends PackageManagerKernelTestBase {
}
/**
* Tests that SQLite database files are excluded from stage operations.
*/
public function testSqliteDatabaseFilesExcluded(): void {
// In this test, we want to perform the actual stage operations so that we
// can be sure that files are staged as expected.
$this->setSetting('package_manager_bypass_composer_stager', FALSE);
// Ensure we have an up-to-date container.
$this->container = $this->container->get('kernel')->rebuildContainer();
$active_dir = $this->container->get(PathLocator::class)->getProjectRoot();
// Mock a SQLite database connection to a file in the active directory. The
// file should not be staged.
$this->mockDatabase->getConnectionOptions()
->willReturn([
'database' => 'sites/example.com/db.sqlite',
])
->shouldBeCalled();
$stage = $this->createStage();
$stage->create();
$stage->require(['ext-json:*']);
$stage_dir = $stage->getStageDirectory();
$excluded = [
"sites/example.com/db.sqlite",
"sites/example.com/db.sqlite-shm",
"sites/example.com/db.sqlite-wal",
];
foreach ($excluded as $path) {
$this->assertFileExists("$active_dir/$path");
$this->assertFileDoesNotExist("$stage_dir/$path");
}
$stage->apply();
// The excluded files should still be in the active directory.
foreach ($excluded as $path) {
$this->assertFileExists("$active_dir/$path");
}
}
/**
* Data provider for testPathProcessing().
*
* @return string[][]
* Data provider for ::testSqliteDatabaseFilesExcluded().
* @return array[]
* The test cases.
*/
public function providerPathProcessing(): array {
public function providerSqliteDatabaseFilesExcluded(): array {
return [
'relative path, in site directory' => [
'sites/example.com/db.sqlite',
[
'sites/example.com/db.sqlite',
'sites/example.com/db.sqlite-shm',
'sites/example.com/db.sqlite-wal',
],
// If the database is at a relative path, it should be excluded relative
// to the web root.
'relative path in relocated web root' => [
'www',
'db.sqlite',
'www/db.sqlite',
],
'relative path, web root is project root' => [
'',
'db.sqlite',
'db.sqlite',
],
'relative path, at root' => [
// If the database is at an absolute path in the project root, it should
// be excluded relative to the project root.
'absolute path in relocated web root' => [
'www',
'<PROJECT_ROOT>/www/db.sqlite',
'www/db.sqlite',
],
'absolute path, web root is project root' => [
'',
'<PROJECT_ROOT>/db.sqlite',
'db.sqlite',
[
'db.sqlite',
'db.sqlite-shm',
'db.sqlite-wal',
],
],
'absolute path, in site directory' => [
'/sites/example.com/db.sqlite',
[
'sites/example.com/db.sqlite',
'sites/example.com/db.sqlite-shm',
'sites/example.com/db.sqlite-wal',
],
// If the database is outside the project root, the excluder doesn't need
// to do anything.
'absolute path outside of project, relocated web root' => [
'www',
'/path/to/database.sqlite',
FALSE,
],
'absolute path, at root' => [
'/db.sqlite',
[
'db.sqlite',
'db.sqlite-shm',
'db.sqlite-wal',
],
'absolute path outside of project, web root is project root' => [
'',
'/path/to/database.sqlite',
FALSE,
],
];
}
/**
* Tests SQLite database path processing.
*
* This test ensures that SQLite database paths are processed properly (e.g.,
* converting an absolute path to a relative path) before being flagged for
* exclusion.
* Tests that SQLite database files are excluded from stage operations.
*
* @param string $database_path
* The path of the SQLite database, as set in the database connection
* options. If it begins with a slash, it will be prefixed with the path of
* the active directory.
* @param string[] $expected_exclusions
* The database paths which should be flagged for exclusion.
* @param string $web_root
* The web root that should be returned by the path locator. See
* \Drupal\package_manager\PathLocator::getWebRoot().
* @param string $db_path
* The path of the SQLite database, as it should be reported by the database
* connection. This can be a relative or absolute path; it does not need to
* actually exist.
* @param string|false $expected_excluded_path
* The path to the database, as it should be given to
* CollectPathsToExcludeEvent. If FALSE, the database is located outside the
* project and therefore is not excluded.
*
* @dataProvider providerPathProcessing
* @dataProvider providerSqliteDatabaseFilesExcluded
*/
public function testPathProcessing(string $database_path, array $expected_exclusions): void {
public function testSqliteDatabaseFilesExcluded(string $web_root, string $db_path, string|false $expected_excluded_path): void {
/** @var \Drupal\package_manager_bypass\MockPathLocator $path_locator */
$path_locator = $this->container->get(PathLocator::class);
$path_factory = $this->container->get(PathFactoryInterface::class);
// If the database path should be treated as absolute, prefix it with the
// path of the active directory.
if (str_starts_with($database_path, '/')) {
$database_path = $path_locator->getProjectRoot() . $database_path;
}
$project_root = $path_locator->getProjectRoot();
$path_locator->setPaths(
$project_root,
$path_locator->getVendorDirectory(),
$web_root,
$path_locator->getStagingRoot(),
);
$this->mockDatabase->getConnectionOptions()
->willReturn([
'database' => $database_path,
'database' => str_replace('<PROJECT_ROOT>', $project_root, $db_path),
])
->shouldBeCalled();
$event = new CollectPathsToExcludeEvent($this->createStage(), $path_locator, $path_factory);
$actual_exclusions = $this->container->get('event_dispatcher')
$event = new CollectPathsToExcludeEvent(
$this->createStage(),
$path_locator,
$this->container->get(PathFactoryInterface::class),
);
$actual_excluded_paths = $this->container->get('event_dispatcher')
->dispatch($event)
->getAll();
// All of the expected exclusions should be flagged.
$this->assertEmpty(array_diff($expected_exclusions, $actual_exclusions));
if (is_string($expected_excluded_path)) {
$expected_exclusions = [
$expected_excluded_path,
$expected_excluded_path . '-shm',
$expected_excluded_path . '-wal',
];
$this->assertEmpty(array_diff($expected_exclusions, $actual_excluded_paths));
}
else {
$this->assertStringNotContainsString(basename($db_path), serialize($actual_excluded_paths));
}
}
}
Loading