"git@git.drupal.org:issue/bootstrap_barrio-3382683.git" did not exist on "62da5df9654522490a325af1ba401d42038b90b6"
Newer
Older

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

Ted Bowman
committed
use Drupal\automatic_updates\CronUpdater;

Adam G-H
committed
use Drupal\automatic_updates\Updater;

Kunal Sachdev
committed
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Tests\automatic_updates\Traits\ValidationTestTrait;
use Drupal\Tests\package_manager\Kernel\PackageManagerKernelTestBase;
use Drupal\Tests\package_manager\Kernel\TestStageTrait;

Adam G-H
committed
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7\Utils;
use Psr\Http\Message\RequestInterface;

Adam G-H
committed
/**
* Base class for kernel tests of the Automatic Updates module.
*/
abstract class AutomaticUpdatesKernelTestBase extends PackageManagerKernelTestBase {

Adam G-H
committed
use ValidationTestTrait;

Adam G-H
committed
/**
* {@inheritdoc}
*/

Adam G-H
committed
protected static $modules = [
'automatic_updates_test_cron',
'system',
'update',
'update_test',
];

Adam G-H
committed

Kunal Sachdev
committed
/**
* The mocked HTTP client that returns metadata about available updates.
*
* We need to preserve this as a class property so that we can re-inject it
* into the container when a rebuild is triggered by module installation.
*
* @var \GuzzleHttp\Client
*
* @see ::register()
*/
private $client;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
// If Package Manager's file system permissions validator is disabled, also
// disable the Automatic Updates validator which wraps it.
if (in_array('package_manager.validator.file_system', $this->disableValidators, TRUE)) {
$this->disableValidators[] = 'automatic_updates.validator.file_system_permissions';
}
// Always disable the Xdebug validator to allow test to run with Xdebug on.
$this->disableValidators[] = 'automatic_updates.validator.xdebug';
parent::setUp();
// The Update module's default configuration must be installed for our
// fake release metadata to be fetched.
$this->installConfig('update');
// Make the update system think that all of System's post-update functions

Kunal Sachdev
committed
// have run.
$this->registerPostUpdateFunctions();
// By default, pretend we're running Drupal core 9.8.1 and a non-security
// update to 9.8.2 is available.

Kunal Sachdev
committed
$this->setCoreVersion('9.8.1');
$this->setReleaseMetadata(['drupal' => __DIR__ . '/../../fixtures/release-history/drupal.9.8.2.xml']);
// Set a last cron run time so that the cron frequency validator will run
// from a sane state.
// @see \Drupal\automatic_updates\Validator\CronFrequencyValidator
$this->container->get('state')->set('system.cron_last', time());

Adam G-H
committed
// @todo Remove this when TUF integration is stable.
$this->container->get('automatic_updates_test_cron.enabler')->enableCron();

Adam G-H
committed
/**
* Sets the current (running) version of core, as known to the Update module.
*
* @param string $version
* The current version of core.
*/
protected function setCoreVersion(string $version): void {
$this->config('update_test.settings')
->set('system_info.#all.version', $version)
->save();
}

Kunal Sachdev
committed
/**
* {@inheritdoc}
*/
public function register(ContainerBuilder $container) {
parent::register($container);
// If we previously set up a mock HTTP client in ::setReleaseMetadata(),
// re-inject it into the container.
if ($this->client) {
$container->set('http_client', $this->client);
}

Adam G-H
committed
// Use the test-only implementations of the regular and cron updaters.
$overrides = [
'automatic_updates.updater' => TestUpdater::class,
'automatic_updates.cron_updater' => TestCronUpdater::class,
];
foreach ($overrides as $service_id => $class) {
if ($container->hasDefinition($service_id)) {
$container->getDefinition($service_id)->setClass($class);
}
}

Kunal Sachdev
committed
}

Adam G-H
committed
/**
* Sets the release metadata file to use when fetching available updates.
*

Ted Bowman
committed
* @param string[] $files
* The paths of the XML metadata files to use, keyed by project name.

Adam G-H
committed
*/

Ted Bowman
committed
protected function setReleaseMetadata(array $files): void {
$responses = [];
foreach ($files as $project => $file) {

Ted Bowman
committed
$metadata = Utils::tryFopen($file, 'r');
$responses["/release-history/$project/current"] = new Response(200, [], Utils::streamFor($metadata));

Ted Bowman
committed
}
$callable = function (RequestInterface $request) use ($responses): Response {
return $responses[$request->getUri()->getPath()] ?? new Response(404);
};
// The mock handler's queue consist of same callable as many times as the
// number of requests we expect to be made for update XML because it will
// retrieve one item off the queue for each request.
// @see \GuzzleHttp\Handler\MockHandler::__invoke()
$handler = new MockHandler(array_fill(0, count($responses), $callable));

Kunal Sachdev
committed
$this->client = new Client([

Adam G-H
committed
'handler' => HandlerStack::create($handler),
]);

Kunal Sachdev
committed
$this->container->set('http_client', $this->client);

Adam G-H
committed
}
}

Ted Bowman
committed
/**

Adam G-H
committed
* A test-only version of the regular updater to override internals.

Ted Bowman
committed
*/

Adam G-H
committed
class TestUpdater extends Updater {

Ted Bowman
committed
use TestStageTrait;

Adam G-H
committed
/**
* {@inheritdoc}
*/
public function setMetadata(string $key, $data): void {
parent::setMetadata($key, $data);
}

Adam G-H
committed
}
/**
* A test-only version of the cron updater to override and expose internals.
*/
class TestCronUpdater extends CronUpdater {

Ted Bowman
committed
use TestStageTrait;