Skip to content
Snippets Groups Projects
Commit bae30a06 authored by Ted Bowman's avatar Ted Bowman
Browse files

Issue #3280403 by kunal.sachdev, tedbow: Show all updates for all supported...

Issue #3280403 by kunal.sachdev, tedbow: Show all updates for all supported branches in the current major on the update form
parent cef552a4
No related branches found
No related tags found
1 merge request!350Issue #3280403: Show all updates for all supported branches in the current major on the update form
...@@ -199,4 +199,15 @@ final class ProjectInfo { ...@@ -199,4 +199,15 @@ final class ProjectInfo {
return FALSE; return FALSE;
} }
/**
* Gets the supported branches of the project.
*
* @return string[]
* The supported branches.
*/
public function getSupportedBranches(): array {
$available_updates = $this->getAvailableProjects()[$this->name];
return isset($available_updates['supported_branches']) ? explode(',', $available_updates['supported_branches']) : [];
}
} }
<?xml version="1.0" encoding="utf-8"?>
<!--
Contains metadata about the following (fake) releases of Drupal core, all of which are secure, in order:
* 10.0.0
* 9.7.2
* 9.7.1
* 9.7.0
* 9.6.1
* 9.6.0
* 9.5.1
* 9.5.0
* 9.4.0, which is in an unsupported branch
* 9.7.x-dev
-->
<project xmlns:dc="http://purl.org/dc/elements/1.1/">
<title>Drupal</title>
<short_name>drupal</short_name>
<dc:creator>Drupal</dc:creator>
<supported_branches>9.5.,9.6.,9.7.,10.0.</supported_branches>
<project_status>published</project_status>
<link>http://example.com/project/drupal</link>
<terms>
<term>
<name>Projects</name>
<value>Drupal project</value>
</term>
</terms>
<releases>
<release>
<name>Drupal 10.0.0</name>
<version>10.0.0</version>
<status>published</status>
<release_link>http://example.com/drupal-10-0-0-release</release_link>
<download_link>http://example.com/drupal-10-0-0.tar.gz</download_link>
<date>1250425521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.7.2</name>
<version>9.7.2</version>
<status>published</status>
<release_link>http://example.com/drupal-9-7-2-release</release_link>
<download_link>http://example.com/drupal-9-7-2.tar.gz</download_link>
<date>1250425521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.7.1</name>
<version>9.7.1</version>
<status>published</status>
<release_link>http://example.com/drupal-9-7-1-release</release_link>
<download_link>http://example.com/drupal-9-7-1.tar.gz</download_link>
<date>1250425521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.7.0</name>
<version>9.7.0</version>
<status>published</status>
<release_link>http://example.com/drupal-9-7-0-release</release_link>
<download_link>http://example.com/drupal-9-7-0.tar.gz</download_link>
<date>1250424521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.6.1</name>
<version>9.6.1</version>
<status>published</status>
<release_link>http://example.com/drupal-9-6-1-release</release_link>
<download_link>http://example.com/drupal-9-6-1.tar.gz</download_link>
<date>1250425521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.6.0</name>
<version>9.6.0</version>
<status>published</status>
<release_link>http://example.com/drupal-9-6-0-release</release_link>
<download_link>http://example.com/drupal-9-6-0.tar.gz</download_link>
<date>1250424521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.5.1</name>
<version>9.5.1</version>
<status>published</status>
<release_link>http://example.com/drupal-9-5-1-release</release_link>
<download_link>http://example.com/drupal-9-5-1.tar.gz</download_link>
<date>1250425521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.5.0</name>
<version>9.5.0</version>
<status>published</status>
<release_link>http://example.com/drupal-9-5-0-release</release_link>
<download_link>http://example.com/drupal-9-5-0.tar.gz</download_link>
<date>1250424521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.4.0</name>
<version>9.4.0</version>
<status>published</status>
<release_link>http://example.com/drupal-9-4-0-release</release_link>
<download_link>http://example.com/drupal-9-4-0.tar.gz</download_link>
<date>1240424421</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.7.x-dev</name>
<version>9.7.x-dev</version>
<status>published</status>
<release_link>http://example.com/drupal-9-7-x-dex-release</release_link>
<download_link>http://example.com/drupal-9-7-x-dex.tar.gz</download_link>
<date>1250424521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
</releases>
</project>
<?xml version="1.0" encoding="utf-8"?>
<!--
Contains metadata about releases of Drupal core with no supported branches:
-->
<project xmlns:dc="http://purl.org/dc/elements/1.1/">
<title>Drupal</title>
<short_name>drupal</short_name>
<dc:creator>Drupal</dc:creator>
<supported_branches/>
<project_status>published</project_status>
<link>http://example.com/project/drupal</link>
<terms>
<term>
<name>Projects</name>
<value>Drupal project</value>
</term>
</terms>
</project>
<?xml version="1.0" encoding="utf-8"?>
<!--
Contains metadata about releases of Drupal core with <supported_branches></supported_branches> not set:
-->
<project xmlns:dc="http://purl.org/dc/elements/1.1/">
<title>Drupal</title>
<short_name>drupal</short_name>
<dc:creator>Drupal</dc:creator>
<project_status>published</project_status>
<link>http://example.com/project/drupal</link>
<terms>
<term>
<name>Projects</name>
<value>Drupal project</value>
</term>
</terms>
</project>
...@@ -242,4 +242,52 @@ class ProjectInfoTest extends PackageManagerKernelTestBase { ...@@ -242,4 +242,52 @@ class ProjectInfoTest extends PackageManagerKernelTestBase {
$this->assertSame($expected_to_be_safe, $project_info->isInstalledVersionSafe()); $this->assertSame($expected_to_be_safe, $project_info->isInstalledVersionSafe());
} }
/**
* Data provider for testGetSupportedBranches().
*
* @return mixed[][]
* The test cases.
*/
public function providerGetSupportedBranches(): array {
$dir = __DIR__ . '/../../fixtures/release-history/';
return [
'xml with supported branches' => [
$dir . 'drupal.10.0.0.xml',
[
'9.5.',
'9.6.',
'9.7.',
'10.0.',
],
],
'xml with supported branches not set' => [
$dir . 'drupal.9.8.1-supported_branches_not_set.xml',
[],
],
'xml with empty supported branches' => [
$dir . 'drupal.9.8.1-empty_supported_branches.xml',
[
'',
],
],
];
}
/**
* @covers ::getSupportedBranches()
*
* @param string $release_xml
* The path of the release metadata.
* @param string[] $expected_supported_branches
* The expected supported branches.
*
* @dataProvider providerGetSupportedBranches
*/
public function testGetSupportedBranches(string $release_xml, array $expected_supported_branches): void {
$this->setReleaseMetadata(['drupal' => $release_xml]);
$project_info = new ProjectInfo('drupal');
$this->assertSame($expected_supported_branches, $project_info->getSupportedBranches());
}
} }
...@@ -174,13 +174,19 @@ final class UpdaterForm extends UpdateFormBase { ...@@ -174,13 +174,19 @@ final class UpdaterForm extends UpdateFormBase {
]; ];
$project_info = new ProjectInfo('drupal'); $project_info = new ProjectInfo('drupal');
$installed_version = ExtensionVersion::createFromVersionString($project_info->getInstalledVersion());
try { try {
// @todo Until https://www.drupal.org/i/3264849 is fixed, we can only show $support_branches = $project_info->getSupportedBranches();
// one release on the form. First, try to show the latest release in the $releases = [];
// currently installed minor. Failing that, try to show the latest foreach ($support_branches as $support_branch) {
// release in the next minor. $support_branch_extension_version = ExtensionVersion::createFromSupportBranch($support_branch);
$installed_minor_release = $this->releaseChooser->getLatestInInstalledMinor($this->updater); if ($support_branch_extension_version->getMajorVersion() === $installed_version->getMajorVersion() && $support_branch_extension_version->getMinorVersion() >= $installed_version->getMinorVersion()) {
$next_minor_release = $this->releaseChooser->getLatestInNextMinor($this->updater); $recent_release_in_minor = $this->releaseChooser->getMostRecentReleaseInMinor($this->updater, $support_branch . '0');
if ($recent_release_in_minor) {
$releases[$support_branch] = $recent_release_in_minor;
}
}
}
} }
catch (\RuntimeException $e) { catch (\RuntimeException $e) {
$form['message'] = [ $form['message'] = [
...@@ -197,7 +203,7 @@ final class UpdaterForm extends UpdateFormBase { ...@@ -197,7 +203,7 @@ final class UpdaterForm extends UpdateFormBase {
} }
$this->displayResults($results, $this->renderer); $this->displayResults($results, $this->renderer);
$project = $project_info->getProjectInfo(); $project = $project_info->getProjectInfo();
if ($installed_minor_release === NULL && $next_minor_release === NULL) { if (empty($releases)) {
if ($project['status'] === UpdateManagerInterface::CURRENT) { if ($project['status'] === UpdateManagerInterface::CURRENT) {
$this->messenger()->addMessage($this->t('No update available')); $this->messenger()->addMessage($this->t('No update available'));
} }
...@@ -249,72 +255,82 @@ final class UpdaterForm extends UpdateFormBase { ...@@ -249,72 +255,82 @@ final class UpdaterForm extends UpdateFormBase {
$type = 'update-recommended'; $type = 'update-recommended';
} }
$create_update_buttons = !$stage_exists && ValidationResult::getOverallSeverity($results) !== SystemManager::REQUIREMENT_ERROR; $create_update_buttons = !$stage_exists && ValidationResult::getOverallSeverity($results) !== SystemManager::REQUIREMENT_ERROR;
if ($installed_minor_release) {
$installed_version = ExtensionVersion::createFromVersionString($project_info->getInstalledVersion()); $installed_minor_release = FALSE;
$form['installed_minor'] = $this->createReleaseTable( $next_minor_release_count = 0;
$installed_minor_release, foreach ($releases as $release) {
$release_status, $release_version = ExtensionVersion::createFromVersionString($release->getVersion());
$this->t('Latest version of Drupal @major.@minor (currently installed):', [ if ($release_version->getMinorVersion() === $installed_version->getMinorVersion()) {
'@major' => $installed_version->getMajorVersion(), $installed_minor_release = TRUE;
'@minor' => $installed_version->getMinorVersion(), $installed_version = ExtensionVersion::createFromVersionString($project_info->getInstalledVersion());
]), $form['installed_minor'] = $this->createReleaseTable(
$type, $release,
$create_update_buttons, $release_status,
// Any update in the current minor should be the primary update. $this->t('Latest version of Drupal @major.@minor (currently installed):', [
TRUE, '@major' => $installed_version->getMajorVersion(),
); '@minor' => $installed_version->getMinorVersion(),
} ]),
if ($next_minor_release) { $type,
// If there is no update in the current minor make the button for the next $create_update_buttons,
// minor primary unless the project status is 'CURRENT' or 'NOT_CURRENT'. // Any update in the current minor should be the primary update.
// 'NOT_CURRENT' does not denote that installed version is not a valid TRUE,
// only that there is newer version available. );
$is_primary = !$installed_minor_release && !($project['status'] === UpdateManagerInterface::CURRENT || $project['status'] === UpdateManagerInterface::NOT_CURRENT);
$next_minor_version = ExtensionVersion::createFromVersionString($next_minor_release->getVersion());
// Since updating to another minor version of Drupal is more disruptive
// than updating within the currently installed minor version, ensure we
// display a link to the release notes for the first (x.y.0) release of
// the next minor version, which will inform site owners of any potential
// pitfalls or major changes. We should always be able to get release info
// for it; if we can't, that's an error condition.
$first_release_version = $next_minor_version->getMajorVersion() . '.' . $next_minor_version->getMinorVersion() . '.0';
$available_updates = update_get_available(TRUE);
if (isset($available_updates['drupal']['releases'][$first_release_version])) {
$next_minor_first_release = ProjectRelease::createFromArray($available_updates['drupal']['releases'][$first_release_version]);
} }
else { else {
throw new \LogicException("Release information for Drupal $first_release_version is not available."); $next_minor_release_count++;
} if ($next_minor_release_count === 1) {
if ($this->moduleHandler->moduleExists('help')) {
$url = Url::fromRoute('help.page')
->setRouteParameter('name', 'automatic_updates')
->setOption('fragment', 'minor-update');
$form['minor_update_help'] = [
'#markup' => $this->t('The following updates are in newer minor version of Drupal. <a href=":url">Learn more about updating to another minor version.</a>', [
':url' => $url->toString(),
]),
'#prefix' => '<p>',
'#suffix' => '</p>',
];
}
}
// If there is no update in the current minor make the button for the
// next minor primary unless the project status is 'CURRENT' or
// 'NOT_CURRENT'. 'NOT_CURRENT' does not denote that installed version
// is not a valid only that there is newer version available.
if (!isset($is_primary)) {
$is_primary = !$installed_minor_release && !($project['status'] === UpdateManagerInterface::CURRENT || $project['status'] === UpdateManagerInterface::NOT_CURRENT);
}
else {
$is_primary = FALSE;
}
if ($this->moduleHandler->moduleExists('help')) { // Since updating to another minor version of Drupal is more
$url = Url::fromRoute('help.page') // disruptive than updating within the currently installed minor
->setRouteParameter('name', 'automatic_updates') // version, ensure we display a link to the release notes for the
->setOption('fragment', 'minor-update'); // first (x.y.0) release of the next minor version, which will inform
// site owners of any potential pitfalls or major changes. We should
// always be able to get release info for it; if we can't, that's an
// error condition.
$first_release_version = $release_version->getMajorVersion() . '.' . $release_version->getMinorVersion() . '.0';
$available_updates = update_get_available(TRUE);
// @todo In https://www.drupal.org/i/3310666 handle if the .0 release is
// not available, and only pre-releases are available.
$next_minor_first_release = ProjectRelease::createFromArray($available_updates['drupal']['releases'][$first_release_version]);
// @todo Updating this wording in https://www.drupal.org/i/3280403 to $form["next_minor_$next_minor_release_count"] = $this->createReleaseTable(
// reflect that multiple minor branches may be visible. $release,
$form['minor_update_help'] = [ $installed_minor_release ? $this->t('Minor update') : $release_status,
'#markup' => $this->t('The following updates are in the next minor version of Drupal. <a href=":url">Learn more about updating to another minor version.</a>', [ $this->t('Latest version of Drupal @major.@minor (next minor) (<a href=":url">Release notes</a>):', [
':url' => $url->toString(), '@major' => $release_version->getMajorVersion(),
'@minor' => $release_version->getMinorVersion(),
':url' => $next_minor_first_release->getReleaseUrl(),
]), ]),
'#prefix' => '<p>', $installed_minor_release ? 'update-optional' : $type,
'#suffix' => '</p>', $create_update_buttons,
]; $is_primary
);
} }
$form['next_minor'] = $this->createReleaseTable(
$next_minor_release,
$installed_minor_release ? $this->t('Minor update') : $release_status,
$this->t('Latest version of Drupal @major.@minor (next minor) (<a href=":url">Release notes</a>):', [
'@major' => $next_minor_version->getMajorVersion(),
'@minor' => $next_minor_version->getMinorVersion(),
':url' => $next_minor_first_release->getReleaseUrl(),
]),
$installed_minor_release ? 'update-optional' : $type,
$create_update_buttons,
$is_primary
);
} }
$form['backup'] = [ $form['backup'] = [
......
...@@ -75,7 +75,7 @@ final class ReleaseChooser { ...@@ -75,7 +75,7 @@ final class ReleaseChooser {
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* If the given semantic version number does not contain a patch version. * If the given semantic version number does not contain a patch version.
*/ */
protected function getMostRecentReleaseInMinor(Updater $updater, string $version): ?ProjectRelease { public function getMostRecentReleaseInMinor(Updater $updater, string $version): ?ProjectRelease {
if (static::getPatchVersion($version) === NULL) { if (static::getPatchVersion($version) === NULL) {
throw new \InvalidArgumentException("The version number $version does not contain a patch version"); throw new \InvalidArgumentException("The version number $version does not contain a patch version");
} }
......
...@@ -130,11 +130,11 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -130,11 +130,11 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$assert_session = $this->assertSession(); $assert_session = $this->assertSession();
$assert_minor_update_help = function () use ($assert_session): void { $assert_minor_update_help = function () use ($assert_session): void {
$assert_session->pageTextContains('The following updates are in the next minor version of Drupal. Learn more about updating to another minor version.'); $assert_session->pageTextContainsOnce('The following updates are in newer minor version of Drupal. Learn more about updating to another minor version.');
$assert_session->linkExists('Learn more about updating to another minor version.'); $assert_session->linkExists('Learn more about updating to another minor version.');
}; };
$assert_no_minor_update_help = function () use ($assert_session): void { $assert_no_minor_update_help = function () use ($assert_session): void {
$assert_session->pageTextNotContains('The following updates are in the next minor version of Drupal. Learn more about updating to another minor version.'); $assert_session->pageTextNotContains('The following updates are in newer minor version of Drupal. Learn more about updating to another minor version.');
}; };
$page = $this->getSession()->getPage(); $page = $this->getSession()->getPage();
...@@ -158,7 +158,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -158,7 +158,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
// Check the form when there is an update in the installed minor only. // Check the form when there is an update in the installed minor only.
$assert_session->pageTextContainsOnce('Currently installed: 9.8.0 (Security update required!)'); $assert_session->pageTextContainsOnce('Currently installed: 9.8.0 (Security update required!)');
$this->checkReleaseTable('#edit-installed-minor', '.update-update-security', '9.8.1', TRUE, 'Latest version of Drupal 9.8 (currently installed):'); $this->checkReleaseTable('#edit-installed-minor', '.update-update-security', '9.8.1', TRUE, 'Latest version of Drupal 9.8 (currently installed):');
$assert_session->elementNotExists('css', '#edit-next-minor'); $assert_session->elementNotExists('css', '#edit-next-minor-1');
$assert_no_minor_update_help(); $assert_no_minor_update_help();
// Check the form when there is an update in the next minor only. // Check the form when there is an update in the next minor only.
...@@ -166,9 +166,9 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -166,9 +166,9 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$this->setCoreVersion('9.7.0'); $this->setCoreVersion('9.7.0');
$page->clickLink('Check manually'); $page->clickLink('Check manually');
$this->checkForMetaRefresh(); $this->checkForMetaRefresh();
$this->checkReleaseTable('#edit-next-minor', '.update-update-recommended', '9.8.1', TRUE, 'Latest version of Drupal 9.8 (next minor) (Release notes):'); $this->checkReleaseTable('#edit-next-minor-1', '.update-update-recommended', '9.8.1', TRUE, 'Latest version of Drupal 9.8 (next minor) (Release notes):');
$assert_minor_update_help(); $assert_minor_update_help();
$this->assertReleaseNotesLink(9, 8); $this->assertReleaseNotesLink(9, 8, '#edit-next-minor-1');
$assert_session->pageTextContainsOnce('Currently installed: 9.7.0 (Not supported!)'); $assert_session->pageTextContainsOnce('Currently installed: 9.7.0 (Not supported!)');
$assert_session->elementNotExists('css', '#edit-installed-minor'); $assert_session->elementNotExists('css', '#edit-installed-minor');
...@@ -180,7 +180,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -180,7 +180,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$this->checkForMetaRefresh(); $this->checkForMetaRefresh();
$assert_session->pageTextContainsOnce('Currently installed: 9.7.0 (Update available)'); $assert_session->pageTextContainsOnce('Currently installed: 9.7.0 (Update available)');
$this->checkReleaseTable('#edit-installed-minor', '.update-update-recommended', '9.7.1', TRUE, 'Latest version of Drupal 9.7 (currently installed):'); $this->checkReleaseTable('#edit-installed-minor', '.update-update-recommended', '9.7.1', TRUE, 'Latest version of Drupal 9.7 (currently installed):');
$assert_session->elementNotExists('css', '#edit-next-minor'); $assert_session->elementNotExists('css', '#edit-next-minor-1');
$assert_no_minor_update_help(); $assert_no_minor_update_help();
// Check that if minor updates are enabled the update in the next minor will // Check that if minor updates are enabled the update in the next minor will
...@@ -188,8 +188,8 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -188,8 +188,8 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$this->config('automatic_updates.settings')->set('allow_core_minor_updates', TRUE)->save(); $this->config('automatic_updates.settings')->set('allow_core_minor_updates', TRUE)->save();
$this->getSession()->reload(); $this->getSession()->reload();
$this->checkReleaseTable('#edit-installed-minor', '.update-update-recommended', '9.7.1', TRUE, 'Latest version of Drupal 9.7 (currently installed):'); $this->checkReleaseTable('#edit-installed-minor', '.update-update-recommended', '9.7.1', TRUE, 'Latest version of Drupal 9.7 (currently installed):');
$this->checkReleaseTable('#edit-next-minor', '.update-update-optional', '9.8.2', FALSE, 'Latest version of Drupal 9.8 (next minor) (Release notes):'); $this->checkReleaseTable('#edit-next-minor-1', '.update-update-optional', '9.8.2', FALSE, 'Latest version of Drupal 9.8 (next minor) (Release notes):');
$this->assertReleaseNotesLink(9, 8); $this->assertReleaseNotesLink(9, 8, '#edit-next-minor-1');
$assert_minor_update_help(); $assert_minor_update_help();
$this->setCoreVersion('9.7.1'); $this->setCoreVersion('9.7.1');
...@@ -197,8 +197,39 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -197,8 +197,39 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$this->checkForMetaRefresh(); $this->checkForMetaRefresh();
$assert_session->pageTextContainsOnce('Currently installed: 9.7.1 (Update available)'); $assert_session->pageTextContainsOnce('Currently installed: 9.7.1 (Update available)');
$assert_session->elementNotExists('css', '#edit-installed-minor'); $assert_session->elementNotExists('css', '#edit-installed-minor');
$this->checkReleaseTable('#edit-next-minor', '.update-update-recommended', '9.8.2', FALSE, 'Latest version of Drupal 9.8 (next minor) (Release notes):'); $this->checkReleaseTable('#edit-next-minor-1', '.update-update-recommended', '9.8.2', FALSE, 'Latest version of Drupal 9.8 (next minor) (Release notes):');
$this->assertReleaseNotesLink(9, 8); $this->assertReleaseNotesLink(9, 8, '#edit-next-minor-1');
$assert_minor_update_help();
// Check that if minor updates are enabled then updates in the next minors
// are visible.
$this->config('automatic_updates.settings')->set('allow_core_minor_updates', TRUE)->save();
$this->setReleaseMetadata(__DIR__ . '/../../../package_manager/tests/fixtures/release-history/drupal.10.0.0.xml');
$this->setCoreVersion('9.5.0');
$page->clickLink('Check manually');
$this->checkForMetaRefresh();
$assert_session->pageTextNotContains('10.0.0');
$assert_session->pageTextContainsOnce('Currently installed: 9.5.0 (Update available)');
$this->checkReleaseTable('#edit-installed-minor', '.update-update-recommended', '9.5.1', TRUE, 'Latest version of Drupal 9.5 (currently installed):');
$this->checkReleaseTable('#edit-next-minor-1', '.update-update-optional', '9.6.1', FALSE, 'Latest version of Drupal 9.6 (next minor) (Release notes):');
$this->assertReleaseNotesLink(9, 6, '#edit-next-minor-1');
$this->checkReleaseTable('#edit-next-minor-2', '.update-update-optional', '9.7.2', FALSE, 'Latest version of Drupal 9.7 (next minor) (Release notes):');
$this->assertReleaseNotesLink(9, 7, '#edit-next-minor-2');
$assert_minor_update_help();
// Check that if installed version is unsupported and minor updates are
// enabled then updates in the next minors are visible.
$this->setCoreVersion('9.4.0');
$page->clickLink('Check manually');
$this->checkForMetaRefresh();
$assert_session->pageTextNotContains('10.0.0');
$assert_session->pageTextContainsOnce('Currently installed: 9.4.0 (Not supported!)');
$this->checkReleaseTable('#edit-next-minor-1', '.update-update-recommended', '9.5.1', TRUE, 'Latest version of Drupal 9.5 (next minor) (Release notes):');
$this->assertReleaseNotesLink(9, 5, '#edit-next-minor-1');
$this->checkReleaseTable('#edit-next-minor-2', '.update-update-recommended', '9.6.1', FALSE, 'Latest version of Drupal 9.6 (next minor) (Release notes):');
$this->assertReleaseNotesLink(9, 6, '#edit-next-minor-2');
$this->checkReleaseTable('#edit-next-minor-3', '.update-update-recommended', '9.7.2', FALSE, 'Latest version of Drupal 9.7 (next minor) (Release notes):');
$this->assertReleaseNotesLink(9, 7, '#edit-next-minor-3');
$assert_minor_update_help(); $assert_minor_update_help();
$this->assertUpdateStagedTimes(0); $this->assertUpdateStagedTimes(0);
...@@ -898,10 +929,12 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -898,10 +929,12 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
* Major version of next minor release. * Major version of next minor release.
* @param int $minor * @param int $minor
* Minor version of next minor release. * Minor version of next minor release.
* @param string $selector
* The selector.
*/ */
private function assertReleaseNotesLink(int $major, int $minor): void { private function assertReleaseNotesLink(int $major, int $minor, string $selector): void {
$assert_session = $this->assertSession(); $assert_session = $this->assertSession();
$row = $assert_session->elementExists('css', '#edit-next-minor'); $row = $assert_session->elementExists('css', $selector);
$link_href = $assert_session->elementExists('named', ['link', 'Release notes'], $row)->getAttribute('href'); $link_href = $assert_session->elementExists('named', ['link', 'Release notes'], $row)->getAttribute('href');
$this->assertSame('http://example.com/drupal-' . $major . '-' . $minor . '-0-release', $link_href); $this->assertSame('http://example.com/drupal-' . $major . '-' . $minor . '-0-release', $link_href);
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace Drupal\Tests\automatic_updates\Kernel; namespace Drupal\Tests\automatic_updates\Kernel;
use Drupal\Core\Extension\ExtensionVersion;
use Drupal\update\ProjectRelease; use Drupal\update\ProjectRelease;
/** /**
...@@ -140,6 +141,7 @@ class ReleaseChooserTest extends AutomaticUpdatesKernelTestBase { ...@@ -140,6 +141,7 @@ class ReleaseChooserTest extends AutomaticUpdatesKernelTestBase {
* *
* @covers ::getLatestInInstalledMinor * @covers ::getLatestInInstalledMinor
* @covers ::getLatestInNextMinor * @covers ::getLatestInNextMinor
* @covers ::getMostRecentReleaseInMinor
*/ */
public function testReleases(string $updater_service, bool $minor_support, string $installed_version, ?string $current_minor, ?string $next_minor): void { public function testReleases(string $updater_service, bool $minor_support, string $installed_version, ?string $current_minor, ?string $next_minor): void {
$this->setCoreVersion($installed_version); $this->setCoreVersion($installed_version);
...@@ -150,6 +152,14 @@ class ReleaseChooserTest extends AutomaticUpdatesKernelTestBase { ...@@ -150,6 +152,14 @@ class ReleaseChooserTest extends AutomaticUpdatesKernelTestBase {
$updater = $this->container->get($updater_service); $updater = $this->container->get($updater_service);
$this->assertReleaseVersion($current_minor, $chooser->getLatestInInstalledMinor($updater)); $this->assertReleaseVersion($current_minor, $chooser->getLatestInInstalledMinor($updater));
$this->assertReleaseVersion($next_minor, $chooser->getLatestInNextMinor($updater)); $this->assertReleaseVersion($next_minor, $chooser->getLatestInNextMinor($updater));
$this->assertReleaseVersion($current_minor, $chooser->getMostRecentReleaseInMinor($updater, $this->getRelativeVersion($installed_version, 0)));
$next_minor_version = $this->getRelativeVersion($installed_version, 1);
$this->assertReleaseVersion($next_minor, $chooser->getMostRecentReleaseInMinor($updater, $next_minor_version));
$previous_minor_version = $this->getRelativeVersion($installed_version, -1);
// The chooser should never return a release for a minor before the
// currently installed version.
$this->assertReleaseVersion(NULL, $chooser->getMostRecentReleaseInMinor($updater, $previous_minor_version));
} }
/** /**
...@@ -170,4 +180,20 @@ class ReleaseChooserTest extends AutomaticUpdatesKernelTestBase { ...@@ -170,4 +180,20 @@ class ReleaseChooserTest extends AutomaticUpdatesKernelTestBase {
} }
} }
/**
* Gets a version number in a minor version relative to another version.
*
* @param string $version
* The version string.
* @param int $minor_offset
* The minor offset.
*
* @return string
* The first patch release in a minor relative to the version string.
*/
private function getRelativeVersion(string $version, int $minor_offset): string {
$installed_version_object = ExtensionVersion::createFromVersionString($version);
return $installed_version_object->getMajorVersion() . '.' . (((int) $installed_version_object->getMinorVersion()) + $minor_offset) . '.0';
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment