Newer
Older

Adam G-H
committed
<?php
namespace Drupal\Tests\package_manager\Kernel;

Adam G-H
committed
use Drupal\Core\DependencyInjection\ContainerBuilder;

Adam G-H
committed
use Drupal\KernelTests\KernelTestBase;
use Drupal\package_manager\Event\StageEvent;
use Drupal\package_manager\Exception\StageException;
use Drupal\package_manager\Exception\StageValidationException;

Adam G-H
committed
use Drupal\package_manager\Stage;
use Drupal\Tests\package_manager\Traits\ValidationTestTrait;
/**
* Base class for kernel tests of Package Manager's functionality.
*/
abstract class PackageManagerKernelTestBase extends KernelTestBase {
use ValidationTestTrait;
/**
* {@inheritdoc}
*/
protected static $modules = [
'package_manager',
'package_manager_bypass',
];

Adam G-H
committed
/**
* {@inheritdoc}
*/
public function register(ContainerBuilder $container) {
parent::register($container);
$this->disableValidators($container);
}
/**
* Disables any validators that will interfere with this test.
*/
protected function disableValidators(ContainerBuilder $container): void {
// Disable the filesystem permissions validator, since we cannot guarantee
// that the current code base will be writable in all testing situations.
// We test this validator functionally in Automatic Updates' build tests,
// since those do give us control over the filesystem permissions.
// @see \Drupal\Tests\automatic_updates\Build\CoreUpdateTest::assertReadOnlyFileSystemError()
// @see \Drupal\Tests\package_manager\Kernel\WritableFileSystemValidatorTest
$container->removeDefinition('package_manager.validator.file_system');
}

Adam G-H
committed
/**
* Creates a stage object for testing purposes.

Adam G-H
committed
*
* @return \Drupal\Tests\package_manager\Kernel\TestStage
* A stage object, with test-only modifications.

Adam G-H
committed
*/
protected function createStage(): TestStage {
return new TestStage(

Adam G-H
committed
$this->container->get('package_manager.path_locator'),
$this->container->get('package_manager.beginner'),
$this->container->get('package_manager.stager'),
$this->container->get('package_manager.committer'),

Ted Bowman
committed
$this->container->get('file_system'),

Adam G-H
committed
$this->container->get('event_dispatcher'),

Ted Bowman
committed
$this->container->get('tempstore.shared')

Adam G-H
committed
);
}
/**
* Asserts validation results are returned from a stage life cycle event.
*
* @param \Drupal\package_manager\ValidationResult[] $expected_results
* The expected validation results.
* @param string|null $event_class
* (optional) The class of the event which should return the results. Must
* be passed if $expected_results is not empty.
*/
protected function assertResults(array $expected_results, string $event_class = NULL): void {
$stage = $this->createStage();

Adam G-H
committed
try {
$stage->create();
$stage->require(['drupal/core:9.8.1']);
$stage->apply();
$stage->destroy();
// If we did not get an exception, ensure we didn't expect any results.
$this->assertEmpty($expected_results);

Adam G-H
committed
}
catch (StageValidationException $e) {
$this->assertNotEmpty($expected_results);

Adam G-H
committed
$this->assertValidationResultsEqual($expected_results, $e->getResults());
// TestStage::dispatch() attaches the event object to the exception so
// that we can analyze it.
$this->assertNotEmpty($event_class);

Adam G-H
committed
$this->assertInstanceOf($event_class, $e->event);
}
}

Ted Bowman
committed
/**
* Marks all pending post-update functions as completed.
*
* Since kernel tests don't normally install modules and register their
* updates, this method makes sure that we are testing from a clean, fully
* up-to-date state.
*/
protected function registerPostUpdateFunctions(): void {
$updates = $this->container->get('update.post_update_registry')
->getPendingUpdateFunctions();
$this->container->get('keyvalue')
->get('post_update')
->set('existing_updates', $updates);
}

Adam G-H
committed
}
/**
* Defines a stage specifically for testing purposes.
*/
class TestStage extends Stage {
/**
* {@inheritdoc}
*/
protected function dispatch(StageEvent $event): void {
try {
parent::dispatch($event);
}
catch (StageException $e) {
// Attach the event object to the exception so that test code can verify
// that the exception was thrown when a specific event was dispatched.
$e->event = $event;
throw $e;
}
}
}