diff --git a/src/Form/UpdaterForm.php b/src/Form/UpdaterForm.php index d121735fcb1097b269705fbfb9d4ae8108070b39..0de0dd7309e79a1d2bb7ed8b575add55d7149afd 100644 --- a/src/Form/UpdaterForm.php +++ b/src/Form/UpdaterForm.php @@ -12,6 +12,7 @@ use Drupal\Core\Batch\BatchBuilder; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Link; +use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\State\StateInterface; use Drupal\Core\Url; use Drupal\package_manager\Exception\StageException; @@ -137,17 +138,10 @@ class UpdaterForm extends FormBase { // @todo Until https://www.drupal.org/i/3264849 is fixed, we can only show // one release on the form. First, try to show the latest release in the // currently installed minor. Failing that, try to show the latest - // release in the next minor. If neither of those are available, just - // show the first available release. + // release in the next minor. $recommended_release = $this->releaseChooser->getLatestInInstalledMinor(); if (!$recommended_release) { $recommended_release = $this->releaseChooser->getLatestInNextMinor(); - if (!$recommended_release) { - // @todo Do not list an update that can't be validated in - // https://www.drupal.org/i/3271235. - $updates = $project_info->getInstallableReleases(); - $recommended_release = array_pop($updates); - } } } catch (\RuntimeException $e) { @@ -160,12 +154,20 @@ class UpdaterForm extends FormBase { // @todo Should we be using the Update module's library here, or our own? $form['#attached']['library'][] = 'update/drupal.update.admin'; - // If we're already up-to-date, there's nothing else we need to do. + $project = $project_info->getProjectInfo(); if ($recommended_release === NULL) { - // @todo Link to the Available Updates report if there are other updates - // that are not supported by this module in - // https://www.drupal.org/i/3271235. - $this->messenger()->addMessage('No update available'); + if ($project['status'] === UpdateManagerInterface::CURRENT) { + $this->messenger()->addMessage($this->t('No update available')); + } + else { + $message = $this->t('Updates were found, but they must be performed manually. See <a href=":url">the list of available updates</a> for more information.', [ + ':url' => Url::fromRoute('update.status')->toString(), + ]); + // If the current release is old, but otherwise secure and supported, + // this should be a regular status message. In any other case, urgent + // action is needed so flag it as an error. + $this->messenger()->addMessage($message, $project['status'] === UpdateManagerInterface::NOT_CURRENT ? MessengerInterface::TYPE_STATUS : MessengerInterface::TYPE_ERROR); + } return $form; } @@ -176,7 +178,6 @@ class UpdaterForm extends FormBase { ], ]; - $project = $project_info->getProjectInfo(); if (empty($project['title']) || empty($project['link'])) { throw new \UnexpectedValueException('Expected project data to have a title and link.'); } diff --git a/tests/src/Functional/UpdaterFormNoRecommendedReleaseMessageTest.php b/tests/src/Functional/UpdaterFormNoRecommendedReleaseMessageTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d8cef338eb80aefce7f5e55ec3f3709b4ad69624 --- /dev/null +++ b/tests/src/Functional/UpdaterFormNoRecommendedReleaseMessageTest.php @@ -0,0 +1,98 @@ +<?php + +namespace Drupal\Tests\automatic_updates\Functional; + +/** + * Tests messages on the updater form when there is no recommended release. + * + * @group automatic_updates + */ +class UpdaterFormNoRecommendedReleaseMessageTest extends AutomaticUpdatesFunctionalTestBase { + + /** + * {@inheritdoc} + */ + protected $defaultTheme = 'stark'; + + /** + * {@inheritdoc} + */ + protected static $modules = [ + 'automatic_updates', + 'automatic_updates_test', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + + $account = $this->drupalCreateUser([ + 'administer software updates', + 'administer site configuration', + ]); + $this->drupalLogin($account); + } + + /** + * Data provider for ::testMessages(). + * + * @return array[] + * Sets of arguments to pass to the test method. + */ + public function providerMessages(): array { + return [ + 'current' => [ + __DIR__ . '/../../fixtures/release-history/drupal.9.8.1-security.xml', + '9.8.1', + FALSE, + 'status', + ], + 'not current' => [ + __DIR__ . '/../../fixtures/release-history/drupal.9.8.2.xml', + '9.7.1', + TRUE, + 'status', + ], + 'insecure' => [ + __DIR__ . '/../../fixtures/release-history/drupal.9.8.1-security.xml', + '9.7.1', + TRUE, + 'error', + ], + ]; + } + + /** + * Tests messages when there is no recommended release. + * + * @param string $release_metadata + * The path of the release metadata to use. + * @param string $installed_version + * The currently installed version of Drupal core. + * @param bool $updates_available + * Whether or not any available updates will be detected. + * @param string $expected_message_type + * The expected type of message (status or error). + * + * @dataProvider providerMessages + */ + public function testMessages(string $release_metadata, string $installed_version, bool $updates_available, string $expected_message_type): void { + $this->setReleaseMetadata($release_metadata); + $this->setCoreVersion($installed_version); + $this->checkForUpdates(); + $this->drupalGet('/admin/reports/updates/automatic-update'); + + $assert_session = $this->assertSession(); + if ($updates_available) { + $assert_session->statusMessageContains('Updates were found, but they must be performed manually.', $expected_message_type); + $assert_session->linkExists('the list of available updates'); + } + else { + $assert_session->statusMessageContains('No update available', $expected_message_type); + } + $assert_session->buttonNotExists('Update'); + } + +} diff --git a/tests/src/Functional/UpdaterFormTest.php b/tests/src/Functional/UpdaterFormTest.php index 453ee42a33959e880739803bbcb083be6f52eaae..354fbc5b842874a1dc36f3fed5963d710ba5ff00 100644 --- a/tests/src/Functional/UpdaterFormTest.php +++ b/tests/src/Functional/UpdaterFormTest.php @@ -106,7 +106,6 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { $this->drupalGet($update_form_url); $assert_session = $this->assertSession(); - $assert_session->statusCodeEquals(200); $assert_session->pageTextContains('No update available'); $assert_session->buttonNotExists('Update'); } @@ -239,7 +238,9 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { $this->drupalGet($update_form_url); $assert_session = $this->assertSession(); - $assert_session->pageTextContainsOnce('Drupal cannot be automatically updated from its current version, 9.7.1, to the recommended version, 9.8.1, because automatic updates from one minor version to another are not supported.'); + $assert_session->pageTextContains('Updates were found, but they must be performed manually. See the list of available updates for more information.'); + $this->clickLink('the list of available updates'); + $assert_session->elementExists('css', 'table.update'); $assert_session->buttonNotExists('Update'); }