Newer
Older

Adam G-H
committed
<?php

omkar podey
committed
declare(strict_types = 1);

Adam G-H
committed
namespace Drupal\Tests\automatic_updates\Functional;
use Drupal\automatic_updates\CronUpdater;

Adam G-H
committed
use Drupal\Core\Site\Settings;

Adam G-H
committed
use Drupal\package_manager_bypass\Beginner;

Ted Bowman
committed
use Drupal\package_manager_bypass\Stager;

Adam G-H
committed
use Drupal\Tests\BrowserTestBase;

Travis Carden
committed
use Drupal\Tests\package_manager\Traits\AssertPreconditionsTrait;
use Drupal\Tests\package_manager\Traits\FixtureUtilityTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;

Adam G-H
committed
/**
* Base class for functional tests of the Automatic Updates module.

Yash Rode
committed
*
* @internal

Adam G-H
committed
*/
abstract class AutomaticUpdatesFunctionalTestBase extends BrowserTestBase {

Travis Carden
committed
use AssertPreconditionsTrait;
use FixtureUtilityTrait;

Ted Bowman
committed

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

Adam G-H
committed
protected static $modules = [
'automatic_updates',

Adam G-H
committed
'automatic_updates_test_disable_validators',

Adam G-H
committed
'package_manager_bypass',

Adam G-H
committed
];

Ted Bowman
committed
/**
* The service IDs of any validators to disable.
*
* @var string[]
*/
protected $disableValidators = [

Adam G-H
committed
// Disable the Composer executable validator, since it may cause the tests
// to fail if a supported version of Composer is unavailable to the web
// server. This should be okay in most situations because, apart from the
// validator, only Composer Stager needs run Composer, and
// package_manager_bypass is disabling those operations.

Yash Rode
committed
// @todo https://www.drupal.org/project/automatic_updates/issues/3320755.

Adam G-H
committed
'package_manager.validator.composer_executable',

Adam G-H
committed
// Always allow tests to run with Xdebug on.

Kunal Sachdev
committed
'package_manager.validator.xdebug',

Kunal Sachdev
committed
];
/**
* {@inheritdoc}
*/
protected function setUp(): void {

Ted Bowman
committed
parent::setUp();
$this->disableValidators($this->disableValidators);
$this->useFixtureDirectoryAsActive(__DIR__ . '/../../../package_manager/tests/fixtures/fake_site');
// @todo Remove in https://www.drupal.org/project/automatic_updates/issues/3284443
$this->config('automatic_updates.settings')->set('cron', CronUpdater::SECURITY)->save();

Kunal Sachdev
committed
}

Adam G-H
committed
/**
* {@inheritdoc}
*/
protected function installModulesFromClassProperty(ContainerInterface $container): void {
$container->get('module_installer')->install([

Ted Bowman
committed
'package_manager_test_release_history',
]);
$this->container = $container->get('kernel')->getContainer();
// To prevent tests from making real requests to the Internet, use fake
// release metadata that exposes a pretend Drupal 9.8.2 release.
$this->setReleaseMetadata(__DIR__ . '/../../../package_manager/tests/fixtures/release-history/drupal.9.8.2.xml');
parent::installModulesFromClassProperty($container);
}

Kunal Sachdev
committed
/**
* {@inheritdoc}
*/
protected function tearDown(): void {

omkar podey
committed
// If automatic_updates is installed, ensure any stage directory created
// during the test is cleaned up.

Kunal Sachdev
committed
$service_id = 'automatic_updates.updater';
if ($this->container->has($service_id)) {
$this->container->get($service_id)->destroy(TRUE);
}
parent::tearDown();
}

Adam G-H
committed
/**

Adam G-H
committed
* Disables validators in the test site's settings.

Ted Bowman
committed
*
* This modifies the service container such that the disabled validators are

Adam G-H
committed
* not defined at all. This method will have no effect unless the
* automatic_updates_test_disable_validators module is installed.

Adam G-H
committed
*

Ted Bowman
committed
* @param string[] $validators

Adam G-H
committed
* The service IDs of the validators to disable.

Adam G-H
committed
*
* @see \Drupal\automatic_updates_test_disable_validators\AutomaticUpdatesTestDisableValidatorsServiceProvider::alter()

Adam G-H
committed
*/

Ted Bowman
committed
protected function disableValidators(array $validators): void {

Adam G-H
committed
$key = 'automatic_updates_test_disable_validators';
$disabled_validators = Settings::get($key, []);

Ted Bowman
committed
foreach ($validators as $service_id) {

Adam G-H
committed
$disabled_validators[] = $service_id;

Ted Bowman
committed
}

Adam G-H
committed
$this->writeSettings([
'settings' => [
$key => (object) [
'value' => $disabled_validators,
'required' => TRUE,
],
],
]);
$this->rebuildContainer();

Adam G-H
committed
}

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();
}
/**
* Sets the release metadata file to use when fetching available updates.
*
* @param string $file
* The path of the XML metadata file to use.
*/
protected function setReleaseMetadata(string $file): void {
$this->assertFileIsReadable($file);

Adam G-H
committed
$this->config('update.settings')
->set('fetch.url', $this->baseUrl . '/test-release-history')

Adam G-H
committed
->save();

Theresa Grannum
committed
[$project] = explode('.', basename($file, '.xml'), 2);
$xml_map = $this->config('update_test.settings')->get('xml_map') ?? [];
$xml_map[$project] = $file;

Adam G-H
committed
$this->config('update_test.settings')
->set('xml_map', $xml_map)

Adam G-H
committed
->save();
}

Kunal Sachdev
committed
/**
* Checks for available updates.
*
* Assumes that a user with appropriate permissions is logged in.
*/
protected function checkForUpdates(): void {
$this->drupalGet('/admin/reports/updates');
$this->getSession()->getPage()->clickLink('Check manually');
$this->checkForMetaRefresh();
}
/**
* Asserts that we are on the "update ready" form.

Kunal Sachdev
committed
*

Theresa Grannum
committed
* @param string $target_version
* The target version of Drupal core.
*/

Theresa Grannum
committed
protected function assertUpdateReady(string $target_version): void {

Kunal Sachdev
committed
$assert_session = $this->assertSession();
$assert_session->addressMatches('/\/admin\/automatic-update-ready\/[a-zA-Z0-9_\-]+$/');

Theresa Grannum
committed
$assert_session->pageTextContainsOnce('Drupal core will be updated to ' . $target_version);
}

Ted Bowman
committed
/**
* Copies a fixture directory to a temporary directory.
*
* @param string $fixture_directory
* The fixture directory.
*
* @return string
* The temporary directory.
*/
protected function copyFixtureToTempDirectory(string $fixture_directory): string {
$temp_directory = $this->root . DIRECTORY_SEPARATOR . $this->siteDirectory . DIRECTORY_SEPARATOR . $this->randomMachineName(20);
static::copyFixtureFilesTo($fixture_directory, $temp_directory);

Ted Bowman
committed
return $temp_directory;
}
/**
* Sets a fixture directory to use as the active directory.
*
* @param string $fixture_directory
* The fixture directory.
*/
protected function useFixtureDirectoryAsActive(string $fixture_directory): void {
// Create a temporary directory from our fixture directory that will be
// unique for each test run. This will enable changing files in the
// directory and not affect other tests.
$active_dir = $this->copyFixtureToTempDirectory($fixture_directory);
Beginner::setFixturePath($active_dir);
$this->container->get('package_manager.path_locator')
->setPaths($active_dir, $active_dir . '/vendor', '', NULL);

Ted Bowman
committed
}
/**
* Sets a fixture directory to use as the staged directory.
*
* @param string $fixture_directory
* The fixture directory.
*/
protected function useFixtureDirectoryAsStaged(string $fixture_directory): void {
// Create a temporary directory from our fixture directory that will be
// unique for each test run. This will enable changing files in the
// directory and not affect other tests.
$staged_dir = $this->copyFixtureToTempDirectory($fixture_directory);
Stager::setFixturePath($staged_dir);

Ted Bowman
committed
}