Skip to content
Snippets Groups Projects
Commit 0b5234db authored by Adam G-H's avatar Adam G-H
Browse files

Issue #3246203 by phenaproxima, tedbow: Replace PreCommitEvent and...

Issue #3246203 by phenaproxima, tedbow: Replace PreCommitEvent and PostCommitEvent with PreApplyEvent and PostApplyEvent
parent 4b1e77b4
No related branches found
No related tags found
No related merge requests found
......@@ -165,4 +165,26 @@ class Stage {
}
}
/**
* Returns a Composer utility object for the active directory.
*
* @return \Drupal\package_manager\ComposerUtility
* The Composer utility object.
*/
public function getActiveComposer(): ComposerUtility {
$dir = $this->pathLocator->getActiveDirectory();
return ComposerUtility::createForDirectory($dir);
}
/**
* Returns a Composer utility object for the stage directory.
*
* @return \Drupal\package_manager\ComposerUtility
* The Composer utility object.
*/
public function getStageComposer(): ComposerUtility {
$dir = $this->pathLocator->getStageDirectory();
return ComposerUtility::createForDirectory($dir);
}
}
<?php
namespace Drupal\automatic_updates\Event;
/**
* Event fired when a staged update has been committed.
*/
class PostCommitEvent extends UpdateEvent {
}
<?php
namespace Drupal\automatic_updates\Event;
use Drupal\package_manager\ComposerUtility;
use Drupal\package_manager\Event\ExcludedPathsTrait;
/**
* Event fired before staged changes are copied into the active site.
*
* Validation results added by subscribers are not cached.
*/
class PreCommitEvent extends UpdateEvent {
use ExcludedPathsTrait;
/**
* The Composer utility object for the stage directory.
*
* @var \Drupal\package_manager\ComposerUtility
*/
protected $stageComposer;
/**
* Constructs a new PreCommitEvent object.
*
* @param \Drupal\package_manager\ComposerUtility $active_composer
* A Composer utility object for the active directory.
* @param \Drupal\package_manager\ComposerUtility $stage_composer
* A Composer utility object for the stage directory.
*/
public function __construct(ComposerUtility $active_composer, ComposerUtility $stage_composer) {
parent::__construct($active_composer);
$this->stageComposer = $stage_composer;
}
/**
* Returns a Composer utility object for the stage directory.
*
* @return \Drupal\package_manager\ComposerUtility
* The Composer utility object for the stage directory.
*/
public function getStageComposer(): ComposerUtility {
return $this->stageComposer;
}
}
......@@ -2,6 +2,7 @@
namespace Drupal\automatic_updates\Event;
use Drupal\package_manager\Event\PostApplyEvent;
use Drupal\update\UpdateManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
......@@ -40,7 +41,7 @@ class UpdateRefreshSubscriber implements EventSubscriberInterface {
*/
public static function getSubscribedEvents() {
return [
PostCommitEvent::class => ['clearData', 1000],
PostApplyEvent::class => ['clearData', 1000],
];
}
......
......@@ -2,8 +2,6 @@
namespace Drupal\automatic_updates;
use Drupal\automatic_updates\Event\PostCommitEvent;
use Drupal\automatic_updates\Event\PreCommitEvent;
use Drupal\automatic_updates\Event\PreStartEvent;
use Drupal\automatic_updates\Event\UpdateEvent;
use Drupal\automatic_updates\Exception\UpdateException;
......@@ -134,15 +132,7 @@ class Updater {
* Commits the current update.
*/
public function commit(): void {
$active_dir = $this->pathLocator->getActiveDirectory();
$active_composer = ComposerUtility::createForDirectory($active_dir);
$stage_dir = $this->pathLocator->getStageDirectory();
$stage_composer = ComposerUtility::createForDirectory($stage_dir);
$this->dispatchUpdateEvent(new PreCommitEvent($active_composer, $stage_composer));
$this->stage->apply();
$this->dispatchUpdateEvent(new PostCommitEvent($active_composer));
}
/**
......
......@@ -2,7 +2,7 @@
namespace Drupal\automatic_updates\Validator;
use Drupal\automatic_updates\Event\PreCommitEvent;
use Drupal\package_manager\Event\PreApplyEvent;
use Drupal\package_manager\ValidationResult;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
......@@ -28,13 +28,14 @@ final class StagedProjectsValidator implements EventSubscriberInterface {
/**
* Validates the staged packages.
*
* @param \Drupal\automatic_updates\Event\PreCommitEvent $event
* @param \Drupal\package_manager\Event\PreApplyEvent $event
* The event object.
*/
public function validateStagedProjects(PreCommitEvent $event): void {
public function validateStagedProjects(PreApplyEvent $event): void {
$stage = $event->getStage();
try {
$active_packages = $event->getActiveComposer()->getDrupalExtensionPackages();
$staged_packages = $event->getStageComposer()->getDrupalExtensionPackages();
$active_packages = $stage->getActiveComposer()->getDrupalExtensionPackages();
$staged_packages = $stage->getStageComposer()->getDrupalExtensionPackages();
}
catch (\Throwable $e) {
$result = ValidationResult::createError([
......@@ -123,7 +124,7 @@ final class StagedProjectsValidator implements EventSubscriberInterface {
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events[PreCommitEvent::class][] = ['validateStagedProjects'];
$events[PreApplyEvent::class][] = ['validateStagedProjects'];
return $events;
}
......
......@@ -2,11 +2,11 @@
namespace Drupal\automatic_updates_test\ReadinessChecker;
use Drupal\automatic_updates\Event\PreCommitEvent;
use Drupal\automatic_updates\Event\PreStartEvent;
use Drupal\automatic_updates\Event\ReadinessCheckEvent;
use Drupal\automatic_updates\Event\UpdateEvent;
use Drupal\Core\State\StateInterface;
use Drupal\package_manager\Event\PreApplyEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
......@@ -63,12 +63,12 @@ class TestChecker1 implements EventSubscriberInterface {
/**
* Adds test result to an update event from a state setting.
*
* @param \Drupal\automatic_updates\Event\UpdateEvent $event
* @param object $event
* The update event.
* @param string $state_key
* The state key.
*/
protected function addResults(UpdateEvent $event, string $state_key): void {
protected function addResults(object $event, string $state_key): void {
$results = $this->state->get($state_key, []);
if ($results instanceof \Throwable) {
throw $results;
......@@ -89,13 +89,13 @@ class TestChecker1 implements EventSubscriberInterface {
}
/**
* Adds test results for the pre-commit event.
* Adds test results for the pre-apply event.
*
* @param \Drupal\automatic_updates\Event\UpdateEvent $event
* @param \Drupal\package_manager\Event\PreApplyEvent $event
* The update event.
*/
public function runPreCommitChecks(UpdateEvent $event): void {
$this->addResults($event, static::STATE_KEY . "." . PreCommitEvent::class);
public function runPreApplyChecks(PreApplyEvent $event): void {
$this->addResults($event, static::STATE_KEY . "." . PreApplyEvent::class);
}
/**
......@@ -115,7 +115,7 @@ class TestChecker1 implements EventSubscriberInterface {
$priority = defined('AUTOMATIC_UPDATES_TEST_SET_PRIORITY') ? AUTOMATIC_UPDATES_TEST_SET_PRIORITY : 5;
$events[ReadinessCheckEvent::class][] = ['runPreChecks', $priority];
$events[PreStartEvent::class][] = ['runStartChecks', $priority];
$events[PreCommitEvent::class][] = ['runPreCommitChecks', $priority];
$events[PreApplyEvent::class][] = ['runPreApplyChecks', $priority];
return $events;
}
......
<?php
namespace Drupal\Tests\automatic_updates\Unit;
namespace Drupal\Tests\automatic_updates\Kernel\ReadinessValidation;
use Drupal\automatic_updates\Event\PreCommitEvent;
use Drupal\automatic_updates\Validator\StagedProjectsValidator;
use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\package_manager\ComposerUtility;
use Drupal\Tests\UnitTestCase;
use Drupal\package_manager\Event\PreApplyEvent;
use Drupal\package_manager\PathLocator;
use Drupal\Tests\automatic_updates\Kernel\AutomaticUpdatesKernelTestBase;
/**
* @coversDefaultClass \Drupal\automatic_updates\Validator\StagedProjectsValidator
* @covers \Drupal\automatic_updates\Validator\StagedProjectsValidator
*
* @group automatic_updates
*/
class StagedProjectsValidatorTest extends UnitTestCase {
class StagedProjectsValidatorTest extends AutomaticUpdatesKernelTestBase {
/**
* Creates a pre-commit event object for testing.
* {@inheritdoc}
*/
protected static $modules = [
'automatic_updates',
'package_manager',
];
/**
* Runs the validator under test against an arbitrary pair of directories.
*
* @param string $active_dir
* The active directory.
* The active directory to validate.
* @param string $stage_dir
* The stage directory.
* The stage directory to validate.
*
* @return \Drupal\automatic_updates\Event\PreCommitEvent
* The event object.
* @return \Drupal\package_manager\ValidationResult[]
* The validation results.
*/
private function createEvent(string $active_dir, string $stage_dir): PreCommitEvent {
return new PreCommitEvent(
ComposerUtility::createForDirectory($active_dir),
ComposerUtility::createForDirectory($stage_dir)
private function validate(string $active_dir, string $stage_dir): array {
$locator = $this->prophesize(PathLocator::class);
$locator->getActiveDirectory()->willReturn($active_dir);
$locator->getStageDirectory()->willReturn($stage_dir);
$this->container->set('package_manager.path_locator', $locator->reveal());
$event = new PreApplyEvent(
$this->container->get('package_manager.stage')
);
$this->container->get('event_dispatcher')->dispatch($event);
return $event->getResults();
}
/**
* Tests that if an exception is thrown, the update event will absorb it.
* Tests that if an exception is thrown, the event will absorb it.
*/
public function testUpdateEventConsumesExceptionResults(): void {
$message = 'An exception thrown by Composer at runtime.';
$composer = $this->prophesize(ComposerUtility::class);
$composer->getDrupalExtensionPackages()
->willThrow(new \RuntimeException($message));
$event = new PreCommitEvent($composer->reveal(), $composer->reveal());
$validator = new StagedProjectsValidator(new TestTranslationManager());
$validator->validateStagedProjects($event);
$results = $event->getResults();
public function testEventConsumesExceptionResults(): void {
$results = $this->validate('/fake/active/dir', '/fake/stage/dir');
$this->assertCount(1, $results);
$messages = reset($results)->getMessages();
$this->assertCount(1, $messages);
$this->assertSame($message, (string) reset($messages));
$this->assertStringContainsString('Composer could not find the config file: /fake/active/dir/composer.json', (string) reset($messages));
}
/**
......@@ -67,17 +69,12 @@ class StagedProjectsValidatorTest extends UnitTestCase {
* The expected error messages.
*
* @dataProvider providerErrors
*
* @covers ::validateStagedProjects
*/
public function testErrors(string $fixtures_dir, string $expected_summary, array $expected_messages): void {
$this->assertNotEmpty($fixtures_dir);
$this->assertDirectoryExists($fixtures_dir);
$event = $this->createEvent("$fixtures_dir/active", "$fixtures_dir/staged");
$validator = new StagedProjectsValidator(new TestTranslationManager());
$validator->validateStagedProjects($event);
$results = $event->getResults();
$results = $this->validate("$fixtures_dir/active", "$fixtures_dir/staged");
$this->assertCount(1, $results);
$result = array_pop($results);
$this->assertSame($expected_summary, (string) $result->getSummary());
......@@ -87,7 +84,6 @@ class StagedProjectsValidatorTest extends UnitTestCase {
$actual_message = array_shift($actual_messages);
$this->assertSame($message, (string) $actual_message);
}
}
/**
......@@ -97,7 +93,7 @@ class StagedProjectsValidatorTest extends UnitTestCase {
* Test cases for testErrors().
*/
public function providerErrors(): array {
$fixtures_folder = realpath(__DIR__ . '/../../fixtures/project_staged_validation');
$fixtures_folder = realpath(__DIR__ . '/../../../fixtures/project_staged_validation');
return [
'new_project_added' => [
"$fixtures_folder/new_project_added",
......@@ -128,15 +124,10 @@ class StagedProjectsValidatorTest extends UnitTestCase {
/**
* Tests validation when there are no errors.
*
* @covers ::validateStagedProjects
*/
public function testNoErrors(): void {
$fixtures_dir = realpath(__DIR__ . '/../../fixtures/project_staged_validation/no_errors');
$event = $this->createEvent("$fixtures_dir/active", "$fixtures_dir/staged");
$validator = new StagedProjectsValidator(new TestTranslationManager());
$validator->validateStagedProjects($event);
$results = $event->getResults();
$fixtures_dir = realpath(__DIR__ . '/../../../fixtures/project_staged_validation/no_errors');
$results = $this->validate("$fixtures_dir/active", "$fixtures_dir/staged");
$this->assertIsArray($results);
$this->assertEmpty($results);
}
......@@ -145,12 +136,9 @@ class StagedProjectsValidatorTest extends UnitTestCase {
* Tests validation when a composer.lock file is not found.
*/
public function testNoLockFile(): void {
$fixtures_dir = realpath(__DIR__ . '/../../fixtures/project_staged_validation/no_errors');
$fixtures_dir = realpath(__DIR__ . '/../../../fixtures/project_staged_validation/no_errors');
$event = $this->createEvent("$fixtures_dir/active", $fixtures_dir);
$validator = new StagedProjectsValidator(new TestTranslationManager());
$validator->validateStagedProjects($event);
$results = $event->getResults();
$results = $this->validate("$fixtures_dir/active", $fixtures_dir);
$this->assertCount(1, $results);
$result = array_pop($results);
$this->assertSame("No lockfile found. Unable to read locked packages", (string) $result->getMessages()[0]);
......@@ -158,34 +146,3 @@ class StagedProjectsValidatorTest extends UnitTestCase {
}
}
/**
* Implements a translation manager in tests.
*
* @todo Copied from core/modules/user/tests/src/Unit/PermissionHandlerTest.php
* when moving to core open an issue consolidate this test class.
*/
class TestTranslationManager implements TranslationInterface {
/**
* {@inheritdoc}
*/
public function translate($string, array $args = [], array $options = []) {
return new TranslatableMarkup($string, $args, $options, $this);
}
/**
* {@inheritdoc}
*/
public function translateString(TranslatableMarkup $translated_string) {
return $translated_string->getUntranslatedString();
}
/**
* {@inheritdoc}
*/
public function formatPlural($count, $singular, $plural, array $args = [], array $options = []) {
return new PluralTranslatableMarkup($count, $singular, $plural, $args, $options, $this);
}
}
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