Skip to content
Snippets Groups Projects
Commit dc42bf12 authored by Theresa Grannum's avatar Theresa Grannum Committed by Ted Bowman
Browse files

Issue #3267386 by Theresa.Grannum, tedbow: Automatic Updates Extensions: run...

Issue #3267386 by Theresa.Grannum, tedbow: Automatic Updates Extensions: run readiness checks to determine if an update is possible
parent 424d9476
No related branches found
No related tags found
No related merge requests found
...@@ -7,3 +7,4 @@ automatic_updates_extensions.update: ...@@ -7,3 +7,4 @@ automatic_updates_extensions.update:
_permission: 'administer software updates' _permission: 'administer software updates'
options: options:
_admin_route: TRUE _admin_route: TRUE
_automatic_updates_readiness_messages: skip
...@@ -2,39 +2,71 @@ ...@@ -2,39 +2,71 @@
namespace Drupal\automatic_updates_extensions\Form; namespace Drupal\automatic_updates_extensions\Form;
use Drupal\automatic_updates\Updater; use Drupal\automatic_updates\Event\ReadinessCheckEvent;
use Drupal\automatic_updates\Validation\ReadinessTrait;
use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\package_manager\Stage;
use Drupal\system\SystemManager;
use Drupal\update\UpdateManagerInterface; use Drupal\update\UpdateManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/** /**
* A form for selecting extension updates. * A form for selecting extension updates.
*/ */
class UpdaterForm extends FormBase { class UpdaterForm extends FormBase {
use ReadinessTrait;
/** /**
* The updater service. * The updater service.
* *
* @var \Drupal\automatic_updates\Updater * @var \Drupal\automatic_updates\Updater
*/ */
private $updater; private $stage;
/**
* The event dispatcher service.
*
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
*/
private $eventDispatcher;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public static function create(ContainerInterface $container) { public static function create(ContainerInterface $container) {
return new static($container->get('automatic_updates.updater')); // @todo Create a our servcie that extends stage instead of creating a
// generic stage class here.
$stage = new Stage(
$container->get('config.factory'),
$container->get('package_manager.path_locator'),
$container->get('package_manager.beginner'),
$container->get('package_manager.stager'),
$container->get('package_manager.committer'),
$container->get('file_system'),
$container->get('event_dispatcher'),
$container->get('tempstore.shared'),
$container->get('datetime.time')
);
return new static(
$stage,
$container->get('event_dispatcher'),
);
} }
/** /**
* Constructs a new UpdaterForm object. * Constructs a new UpdaterForm object.
* *
* @param \Drupal\automatic_updates\Updater $updater * @param \Drupal\package_manager\Stage $stage
* The extension updater service. * The stage service.
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
* The extension event dispatcher service.
*/ */
public function __construct(Updater $updater) { public function __construct(Stage $stage, EventDispatcherInterface $event_dispatcher) {
$this->updater = $updater; $this->stage = $stage;
$this->eventDispatcher = $event_dispatcher;
} }
/** /**
...@@ -87,9 +119,22 @@ class UpdaterForm extends FormBase { ...@@ -87,9 +119,22 @@ class UpdaterForm extends FormBase {
'#empty' => $this->t('There are no available updates.'), '#empty' => $this->t('There are no available updates.'),
'#attributes' => ['class' => ['update-recommended']], '#attributes' => ['class' => ['update-recommended']],
]; ];
if ($update_projects) {
if ($form_state->getUserInput()) {
$results = [];
}
else {
$event = new ReadinessCheckEvent($this->stage);
$this->eventDispatcher->dispatch($event);
$results = $event->getResults();
}
$this->displayResults($results, $this->messenger());
$security_level = $this->getOverallSeverity($results);
if ($update_projects && $security_level !== SystemManager::REQUIREMENT_ERROR) {
$form['actions'] = $this->actions($form_state); $form['actions'] = $this->actions($form_state);
} }
return $form; return $form;
} }
...@@ -104,7 +149,7 @@ class UpdaterForm extends FormBase { ...@@ -104,7 +149,7 @@ class UpdaterForm extends FormBase {
*/ */
protected function actions(FormStateInterface $form_state): array { protected function actions(FormStateInterface $form_state): array {
$actions = ['#type' => 'actions']; $actions = ['#type' => 'actions'];
if (!$this->updater->isAvailable()) { if (!$this->stage->isAvailable()) {
// If the form has been submitted do not display this error message // If the form has been submitted do not display this error message
// because ::deleteExistingUpdate() may run on submit. The message will // because ::deleteExistingUpdate() may run on submit. The message will
// still be displayed on form build if needed. // still be displayed on form build if needed.
...@@ -130,7 +175,7 @@ class UpdaterForm extends FormBase { ...@@ -130,7 +175,7 @@ class UpdaterForm extends FormBase {
* Submit function to delete an existing in-progress update. * Submit function to delete an existing in-progress update.
*/ */
public function deleteExistingUpdate(): void { public function deleteExistingUpdate(): void {
$this->updater->destroy(TRUE); $this->stage->destroy(TRUE);
$this->messenger()->addMessage($this->t("Staged update deleted")); $this->messenger()->addMessage($this->t("Staged update deleted"));
} }
......
...@@ -2,7 +2,11 @@ ...@@ -2,7 +2,11 @@
namespace Drupal\Tests\automatic_updates_extensions\Functional; namespace Drupal\Tests\automatic_updates_extensions\Functional;
use Drupal\automatic_updates\Event\ReadinessCheckEvent;
use Drupal\automatic_updates_test\EventSubscriber\TestSubscriber1;
use Drupal\package_manager\ValidationResult;
use Drupal\Tests\automatic_updates\Functional\AutomaticUpdatesFunctionalTestBase; use Drupal\Tests\automatic_updates\Functional\AutomaticUpdatesFunctionalTestBase;
use Drupal\Tests\automatic_updates\Traits\ValidationTestTrait;
/** /**
* Tests updating using the form. * Tests updating using the form.
...@@ -11,6 +15,8 @@ use Drupal\Tests\automatic_updates\Functional\AutomaticUpdatesFunctionalTestBase ...@@ -11,6 +15,8 @@ use Drupal\Tests\automatic_updates\Functional\AutomaticUpdatesFunctionalTestBase
*/ */
class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
use ValidationTestTrait;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
...@@ -35,7 +41,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -35,7 +41,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
protected function setUp():void { protected function setUp(): void {
parent::setUp(); parent::setUp();
$this->setReleaseMetadata(__DIR__ . '/../../../../tests/fixtures/release-history/semver_test.1.1.xml'); $this->setReleaseMetadata(__DIR__ . '/../../../../tests/fixtures/release-history/semver_test.1.1.xml');
} }
...@@ -63,13 +69,26 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -63,13 +69,26 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
'hidden' => FALSE, 'hidden' => FALSE,
], ],
]; ];
$this->config('update_test.settings')->set('system_info', $system_info)->save(); $this->config('update_test.settings')
->set('system_info', $system_info)
->save();
}
/**
* Asserts the table shows the updates.
*/
private function assertTableShowsUpdates() {
$assert = $this->assertSession();
$assert->elementTextContains('css', '.update-recommended td:nth-of-type(2)', 'Semver Test');
$assert->elementTextContains('css', '.update-recommended td:nth-of-type(3)', '8.1.0');
$assert->elementTextContains('css', '.update-recommended td:nth-of-type(4)', '8.1.1');
$assert->elementsCount('css', '.update-recommended tbody tr', 1);
} }
/** /**
* Tests the form when a module requires an update. * Tests the form when a module requires an update.
*/ */
public function testHasUpdate():void { public function testHasUpdate(): void {
$assert = $this->assertSession(); $assert = $this->assertSession();
$user = $this->createUser(['administer site configuration']); $user = $this->createUser(['administer site configuration']);
$this->drupalLogin($user); $this->drupalLogin($user);
...@@ -81,20 +100,18 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -81,20 +100,18 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$user = $this->createUser(['administer software updates']); $user = $this->createUser(['administer software updates']);
$this->drupalLogin($user); $this->drupalLogin($user);
$this->drupalGet('/admin/automatic-update-extensions'); $this->drupalGet('/admin/automatic-update-extensions');
$this->assertTableShowsUpdates();
$assert->pageTextContains('Automatic Updates Form'); $assert->pageTextContains('Automatic Updates Form');
$assert->elementTextContains('css', '.update-recommended td:nth-of-type(2)', 'Semver Test');
$assert->elementTextContains('css', '.update-recommended td:nth-of-type(3)', '8.1.0');
$assert->elementTextContains('css', '.update-recommended td:nth-of-type(4)', '8.1.1');
$assert->elementsCount('css', '.update-recommended tbody tr', 1);
$assert->buttonExists('Update'); $assert->buttonExists('Update');
} }
/** /**
* Tests the form when there are no available updates. * Tests the form when there are no available updates.
*/ */
public function testNoUpdate():void { public function testNoUpdate(): void {
$assert = $this->assertSession(); $assert = $this->assertSession();
$user = $this->createUser(['administer site configuration', $user = $this->createUser([
'administer site configuration',
'administer software updates', 'administer software updates',
]); ]);
$this->drupalLogin($user); $this->drupalLogin($user);
...@@ -105,4 +122,50 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -105,4 +122,50 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$assert->buttonNotExists('Update'); $assert->buttonNotExists('Update');
} }
/**
* Test the form for errors.
*/
public function testErrors(): void {
$assert = $this->assertSession();
$user = $this->createUser([
'administer site configuration',
'administer software updates',
]);
$this->drupalLogin($user);
$this->setProjectInstalledVersion('8.1.0');
$this->checkForUpdates();
$this->drupalGet('/admin/automatic-update-extensions');
$this->assertTableShowsUpdates();
$message = t("You've not experienced Shakespeare until you have read him in the original Klingon.");
$error = ValidationResult::createError([$message]);
TestSubscriber1::setTestResult([$error], ReadinessCheckEvent::class);
$this->getSession()->reload();
$assert->pageTextContains($message);
$assert->pageTextContains(static::$errorsExplanation);
$assert->pageTextNotContains(static::$warningsExplanation);
$assert->buttonNotExists('Update');
}
/**
* Test the form for warning messages.
*/
public function testWarnings(): void {
$assert = $this->assertSession();
$user = $this->createUser([
'administer site configuration',
'administer software updates',
]);
$this->drupalLogin($user);
$this->setProjectInstalledVersion('8.1.0');
$this->checkForUpdates();
$message = t("Warning! Updating this module may cause an error.");
$warning = ValidationResult::createWarning([$message]);
TestSubscriber1::setTestResult([$warning], ReadinessCheckEvent::class);
$this->drupalGet('/admin/automatic-update-extensions');
$this->assertTableShowsUpdates();
$assert->pageTextContains(static::$warningsExplanation);
$assert->pageTextNotContains(static::$errorsExplanation);
$assert->buttonExists('Update');
}
} }
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