StagedDBUpdateValidatorTest.php
Namespace
Drupal\Tests\package_manager\KernelFile
-
core/
modules/ package_manager/ tests/ src/ Kernel/ StagedDBUpdateValidatorTest.php
View source
<?php
declare (strict_types=1);
namespace Drupal\Tests\package_manager\Kernel;
use Drupal\package_manager\PathLocator;
use Drupal\package_manager\ValidationResult;
/**
* @covers \Drupal\package_manager\Validator\SandboxDatabaseUpdatesValidator
* @group package_manager
* @internal
*/
class StagedDBUpdateValidatorTest extends PackageManagerKernelTestBase {
/**
* {@inheritdoc}
*/
protected function setUp() : void {
parent::setUp();
$this->container
->get('theme_installer')
->install([
'stark',
]);
$this->assertFalse($this->container
->get('module_handler')
->moduleExists('views'));
$this->assertFalse($this->container
->get('theme_handler')
->themeExists('olivero'));
// Ensure that all the extensions we're testing with have database update
// files in the active directory.
$active_dir = $this->container
->get(PathLocator::class)
->getProjectRoot();
// System and Stark are installed, so they are used to test what happens
// when database updates are detected in installed extensions. Views and
// Olivero are not installed, so they are used to test what happens when
// non-installed extensions have database updates.
$extensions = [
'core/modules/system',
'core/themes/stark',
'core/modules/views',
'core/themes/olivero',
];
foreach ($extensions as $extension_path) {
$extension_path = $active_dir . '/' . $extension_path;
mkdir($extension_path, 0777, TRUE);
$extension_name = basename($extension_path);
// Ensure each extension has a .install and a .post_update.php file with
// an empty update function in it.
foreach ([
'install',
'post_update.php',
] as $suffix) {
$function_name = match ($suffix) { 'install' => $extension_name . '_update_1000',
'post_update.php' => $extension_name . '_post_update_test',
};
file_put_contents("{$extension_path}/{$extension_name}.{$suffix}", "<?php\nfunction {$function_name}() {}");
}
}
}
/**
* Data provider for ::testStagedDatabaseUpdates().
*
* @return array[]
* The test cases.
*/
public static function providerStagedDatabaseUpdate() : array {
$summary = t('Database updates have been detected in the following extensions.');
return [
'schema update in installed module' => [
'core/modules/system',
'install',
[
ValidationResult::createWarning([
t('System'),
], $summary),
],
],
'post-update in installed module' => [
'core/modules/system',
'post_update.php',
[
ValidationResult::createWarning([
t('System'),
], $summary),
],
],
'schema update in installed theme' => [
'core/themes/stark',
'install',
[
ValidationResult::createWarning([
t('Stark'),
], $summary),
],
],
'post-update in installed theme' => [
'core/themes/stark',
'post_update.php',
[
ValidationResult::createWarning([
t('Stark'),
], $summary),
],
],
// The validator should ignore changes in any extensions that aren't
// installed.
'schema update in non-installed module' => [
'core/modules/views',
'install',
[],
],
'post-update in non-installed module' => [
'core/modules/views',
'post_update.php',
[],
],
'schema update in non-installed theme' => [
'core/themes/olivero',
'install',
[],
],
'post-update in non-installed theme' => [
'core/themes/olivero',
'post_update.php',
[],
],
];
}
/**
* Tests validation of staged database updates.
*
* @param string $extension_dir
* The directory of the extension that should have database updates,
* relative to the stage directory.
* @param string $file_extension
* The extension of the update file, without the leading period. Must be
* either `install` or `post_update.php`.
* @param \Drupal\package_manager\ValidationResult[] $expected_results
* The expected validation results.
*
* @dataProvider providerStagedDatabaseUpdate
*/
public function testStagedDatabaseUpdate(string $extension_dir, string $file_extension, array $expected_results) : void {
$extension_name = basename($extension_dir);
$relative_file_path = $extension_dir . '/' . $extension_name . '.' . $file_extension;
$stage = $this->createStage();
$stage->create();
// Nothing has been changed in the stage, so ensure the validator doesn't
// detect any changes.
$this->assertStatusCheckResults([], $stage);
$staged_update_file = $stage->getSandboxDirectory() . '/' . $relative_file_path;
$this->assertFileIsWritable($staged_update_file);
// Now add a "real" update function -- either a schema update or a
// post-update, depending on what $file_extension is -- and ensure that the
// validator detects it.
$update_function_name = match ($file_extension) { 'install' => $extension_name . '_update_1001',
'post_update.php' => $extension_name . '_post_update_' . $this->randomMachineName(),
};
file_put_contents($staged_update_file, "function {$update_function_name}() {}\n", FILE_APPEND);
$this->assertStatusCheckResults($expected_results, $stage);
// Add a bunch of functions which are named similarly to real schema update
// and post-update functions, but not quite right, to ensure they are
// ignored by the validator. Also throw an anonymous function in there to
// ensure those are ignored as well.
$code = <<<END
<?php
function {<span class="php-variable">$extension_name</span>}_update() { \$foo = function () {}; }
function {<span class="php-variable">$extension_name</span>}_update_string_123() {}
function {<span class="php-variable">$extension_name</span>}_update__123() {}
function ({<span class="php-variable">$extension_name</span>}}__post_update_test() {}
function ({<span class="php-variable">$extension_name</span>}}_post_update() {}
END;
file_put_contents($staged_update_file, $code);
$this->assertStatusCheckResults([], $stage);
// If the update file is deleted from the stage, the validator should not
// detect any database updates.
unlink($staged_update_file);
$this->assertStatusCheckResults([], $stage);
// If the update file doesn't exist in the active directory, but does exist
// in the stage with a legitimate schema update or post-update function, the
// validator should detect it.
$project_root = $this->container
->get(PathLocator::class)
->getProjectRoot();
unlink($project_root . '/' . $relative_file_path);
file_put_contents($staged_update_file, "<?php\nfunction {$update_function_name}() {}");
$this->assertStatusCheckResults($expected_results, $stage);
}
/**
* Tests that the validator disregards unclaimed stages.
*/
public function testUnclaimedStage() : void {
$stage = $this->createStage();
$stage->create();
$this->assertStatusCheckResults([], $stage);
// A new, unclaimed stage should be ignored by the validator.
$this->assertStatusCheckResults([], $this->createStage());
}
}
Classes
Title | Deprecated | Summary |
---|---|---|
StagedDBUpdateValidatorTest | @covers \Drupal\package_manager\Validator\SandboxDatabaseUpdatesValidator @group package_manager @internal |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.