Skip to content
Snippets Groups Projects
Commit 2aa20c66 authored by omkar podey's avatar omkar podey Committed by Adam G-H
Browse files

Issue #3312373 by omkar.podey, phenaproxima: Automatic Updates Extensions'...

Issue #3312373 by omkar.podey, phenaproxima: Automatic Updates Extensions' UpdateReady form should dispatch StatusCheckEvent
parent fea79bb2
No related branches found
No related tags found
No related merge requests found
......@@ -2,9 +2,11 @@
namespace Drupal\automatic_updates_extensions\Form;
use Drupal\automatic_updates\Validation\ReadinessTrait;
use Drupal\package_manager\Event\StatusCheckEvent;
use Drupal\package_manager\Exception\ApplyFailedException;
use Drupal\package_manager\ProjectInfo;
use Drupal\package_manager\Validator\StagedDBUpdateValidator;
use Drupal\package_manager\ValidationResult;
use Drupal\automatic_updates_extensions\BatchProcessor;
use Drupal\automatic_updates\BatchProcessor as AutoUpdatesBatchProcessor;
use Drupal\automatic_updates_extensions\ExtensionUpdater;
......@@ -18,7 +20,9 @@ use Drupal\Core\State\StateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\package_manager\Exception\StageException;
use Drupal\package_manager\Exception\StageOwnershipException;
use Drupal\system\SystemManager;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* Defines a form to commit staged updates.
......@@ -28,6 +32,10 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
*/
final class UpdateReady extends FormBase {
use ReadinessTrait {
formatResult as traitFormatResult;
}
/**
* The updater service.
*
......@@ -50,18 +58,18 @@ final class UpdateReady extends FormBase {
protected $moduleList;
/**
* The staged database update validator service.
* The renderer service.
*
* @var \Drupal\package_manager\Validator\StagedDBUpdateValidator
* @var \Drupal\Core\Render\RendererInterface
*/
protected $stagedDatabaseUpdateValidator;
protected $renderer;
/**
* The renderer service.
* The event dispatcher.
*
* @var \Drupal\Core\Render\RendererInterface
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
*/
protected $renderer;
protected $eventDispatcher;
/**
* Constructs a new UpdateReady object.
......@@ -74,18 +82,18 @@ final class UpdateReady extends FormBase {
* The state service.
* @param \Drupal\Core\Extension\ModuleExtensionList $module_list
* The module list service.
* @param \Drupal\package_manager\Validator\StagedDBUpdateValidator $staged_database_update_validator
* The staged database update validator service.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer service.
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
* Event dispatcher service.
*/
public function __construct(ExtensionUpdater $updater, MessengerInterface $messenger, StateInterface $state, ModuleExtensionList $module_list, StagedDBUpdateValidator $staged_database_update_validator, RendererInterface $renderer) {
public function __construct(ExtensionUpdater $updater, MessengerInterface $messenger, StateInterface $state, ModuleExtensionList $module_list, RendererInterface $renderer, EventDispatcherInterface $event_dispatcher) {
$this->updater = $updater;
$this->setMessenger($messenger);
$this->state = $state;
$this->moduleList = $module_list;
$this->stagedDatabaseUpdateValidator = $staged_database_update_validator;
$this->renderer = $renderer;
$this->eventDispatcher = $event_dispatcher;
}
/**
......@@ -104,8 +112,8 @@ final class UpdateReady extends FormBase {
$container->get('messenger'),
$container->get('state'),
$container->get('extension.list.module'),
$container->get('package_manager.validator.staged_database_updates'),
$container->get('renderer')
$container->get('renderer'),
$container->get('event_dispatcher')
);
}
......@@ -127,23 +135,6 @@ final class UpdateReady extends FormBase {
$messages = [];
// If there are any installed extension with database updates in the staging
// area, warn the user that they might be sent to update.php once the staged
// changes have been applied.
$pending_updates = $this->stagedDatabaseUpdateValidator->getExtensionsWithDatabaseUpdates($this->updater);
if ($pending_updates) {
natcasesort($pending_updates);
$message_item_list = [
'#theme' => 'item_list',
'#prefix' => '<p>' . $this->t('Possible database updates were detected in the following extensions; you may be redirected to the database update page in order to complete the update process.') . '</p>',
'#items' => $pending_updates,
'#context' => [
'list_style' => 'automatic-updates-extensions__pending-database-updates',
],
];
$messages[MessengerInterface::TYPE_WARNING][] = $this->renderer->renderRoot($message_item_list);
}
// Don't set any messages if the form has been submitted, because we don't
// want them to be set during form submit.
if (!$form_state->getUserInput()) {
......@@ -177,6 +168,21 @@ final class UpdateReady extends FormBase {
'#type' => 'checkbox',
'#default_value' => TRUE,
];
// Don't run the status checks once the form has been submitted.
if (!$form_state->getUserInput()) {
$event = new StatusCheckEvent($this->updater);
$this->eventDispatcher->dispatch($event);
/** @var \Drupal\package_manager\ValidationResult[] $results */
$results = $event->getResults();
// This will have no effect if $results is empty.
$this->displayResults($results, $this->messenger(), $this->renderer);
// If any errors occurred, return the form early so the user cannot
// continue.
if ($this->getOverallSeverity($results) === SystemManager::REQUIREMENT_ERROR) {
return $form;
}
}
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Continue'),
......@@ -332,4 +338,25 @@ final class UpdateReady extends FormBase {
];
}
/**
* {@inheritdoc}
*
* @todo Remove this in https://www.drupal.org/project/automatic_updates/issues/3313414.
*/
protected function formatResult(ValidationResult $result) {
$messages = $result->getMessages();
if (count($messages) > 1) {
return [
'#theme' => 'item_list__automatic_updates_validation_results',
'#prefix' => $result->getSummary(),
'#items' => $messages,
'#context' => [
'list_style' => 'automatic-updates-extensions__pending-database-updates',
],
];
}
return $this->traitFormatResult($result);
}
}
......@@ -6,9 +6,11 @@ use Drupal\automatic_updates\Event\ReadinessCheckEvent;
use Drupal\automatic_updates_test\EventSubscriber\TestSubscriber1;
use Drupal\package_manager_test_validation\StagedDatabaseUpdateValidator;
use Drupal\package_manager\Event\PreApplyEvent;
use Drupal\package_manager\Event\StatusCheckEvent;
use Drupal\package_manager\ValidationResult;
use Drupal\package_manager_bypass\Committer;
use Drupal\package_manager_bypass\Stager;
use Drupal\package_manager_test_validation\EventSubscriber\TestSubscriber;
use Drupal\Tests\automatic_updates\Functional\AutomaticUpdatesFunctionalTestBase;
use Drupal\Tests\automatic_updates\Traits\ValidationTestTrait;
use Drupal\Tests\automatic_updates_extensions\Traits\FormTestTrait;
......@@ -192,11 +194,11 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
// Ensure that a list of pending database updates is visible, along with a
// short explanation, in the warning messages.
$warning_messages = $assert_session->elementExists('xpath', '//div[@data-drupal-messages]//div[@aria-label="Warning message"]');
$this->assertStringContainsString('Possible database updates were detected in the following extensions; you may be redirected to the database update page in order to complete the update process.', $warning_messages->getText());
$this->assertStringContainsString('Possible database updates have been detected in the following extensions.', $warning_messages->getText());
$pending_updates = $warning_messages->findAll('css', 'ul.item-list__automatic-updates-extensions__pending-database-updates li');
$this->assertCount(2, $pending_updates);
$this->assertSame('Automatic Updates Theme With Updates', $pending_updates[0]->getText());
$this->assertSame('System', $pending_updates[1]->getText());
$this->assertSame('System', $pending_updates[0]->getText());
$this->assertSame('Automatic Updates Theme With Updates', $pending_updates[1]->getText());
$page->pressButton('Continue');
$this->checkForMetaRefresh();
......@@ -450,9 +452,63 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$this->clickLink('Update Extensions');
$this->assertTableShowsUpdates('Semver Test', '8.1.0', '8.1.1');
$this->assertUpdatesCount(1);
$assert->pageTextContains(static::$warningsExplanation);
$this->checkForMetaRefresh();
$assert->pageTextNotContains(static::$errorsExplanation);
$assert->elementExists('css', '#edit-projects-semver-test')->check();
$assert->checkboxChecked('edit-projects-semver-test');
$assert->pageTextContains(static::$warningsExplanation);
$assert->buttonExists('Update');
// Add warnings from StatusCheckEvent.
$summary_status_check_event = t('Some summary');
$messages_status_check_event = [
"The only thing we're allowed to do is to",
"believe that we won't regret the choice",
"we made.",
];
$warning_status_check_event = ValidationResult::createWarning($messages_status_check_event, $summary_status_check_event);
TestSubscriber::setTestResult([$warning_status_check_event], StatusCheckEvent::class);
$this->getSession()->getPage()->pressButton('Update');
$this->checkForMetaRefresh();
$assert->buttonExists('Continue');
$assert->pageTextContains($summary_status_check_event);
foreach ($messages_status_check_event as $message) {
$assert->pageTextContains($message);
}
}
/**
* Tests that messages from StatusCheckEvent are shown on the confirmation form.
*/
public function testStatusErrorMessages(): void {
$this->setReleaseMetadata(__DIR__ . '/../../fixtures/release-history/semver_test.1.1.xml');
$assert = $this->assertSession();
$this->setProjectInstalledVersion(['semver_test' => '8.1.0']);
$this->checkForUpdates();
$this->drupalGet('admin/reports/updates/automatic-update-extensions');
$this->assertTableShowsUpdates('Semver Test', '8.1.0', '8.1.1');
$this->assertUpdatesCount(1);
$this->getSession()->reload();
$assert->elementExists('css', '#edit-projects-semver-test')->check();
$assert->checkboxChecked('edit-projects-semver-test');
$assert->buttonExists('Update');
$messages = [
"The only thing we're allowed to do is to",
"believe that we won't regret the choice",
"we made.",
];
$summary = t('Some summary');
$error = ValidationResult::createError($messages, $summary);
TestSubscriber::setTestResult([$error], StatusCheckEvent::class);
$this->getSession()->getPage()->pressButton('Update');
$this->checkForMetaRefresh();
$assert->pageTextContains(static::$errorsExplanation);
$assert->pageTextNotContains(static::$warningsExplanation);
$assert->pageTextContains($summary);
foreach ($messages as $message) {
$assert->pageTextContains($message);
}
$assert->buttonNotExists('Continue');
}
/**
......
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