function StageCommitExceptionTest::testCommitException

Tests exception handling during calls to Composer Stager commit.

@dataProvider providerCommitException

Parameters

string $thrown_class: The throwable class that should be thrown by Composer Stager.

string $expected_class: The expected exception class, if different from $thrown_class.

File

core/modules/package_manager/tests/src/Kernel/StageCommitExceptionTest.php, line 79

Class

StageCommitExceptionTest
@coversDefaultClass \Drupal\package_manager\SandboxManagerBase @covers \Drupal\package_manager\PackageManagerUninstallValidator @group package_manager @internal

Namespace

Drupal\Tests\package_manager\Kernel

Code

public function testCommitException(string $thrown_class, string $expected_class) : void {
    $stage = $this->createStage();
    $stage->create();
    $stage->require([
        'drupal/core:9.8.1',
    ]);
    $throwable_arguments = [
        'A very bad thing happened',
        123,
    ];
    // Composer Stager's exception messages are usually translatable, so they
    // need to be wrapped by a TranslatableMessage object.
    if (is_subclass_of($thrown_class, ExceptionInterface::class)) {
        $throwable_arguments[0] = $this->createComposeStagerMessage($throwable_arguments[0]);
    }
    // PreconditionException requires a preconditions object.
    if ($thrown_class === PreconditionException::class) {
        array_unshift($throwable_arguments, $this->createMock(PreconditionInterface::class));
    }
    LoggingCommitter::setException($thrown_class, ...$throwable_arguments);
    try {
        $stage->apply();
        $this->fail('Expected an exception.');
    } catch (\Throwable $exception) {
        $this->assertInstanceOf($expected_class, $exception);
        $this->assertSame(123, $exception->getCode());
        // This needs to be done because we always use the message from
        // \Drupal\package_manager\Stage::getFailureMarkerMessage() when throwing
        // ApplyFailedException.
        if ($expected_class == ApplyFailedException::class) {
            $this->assertMatchesRegularExpression("/^Staged changes failed to apply, and the site is in an indeterminate state. It is strongly recommended to restore the code and database from a backup. Caused by {$thrown_class}, with this message: A very bad thing happened\nBacktrace:\n#0 .*/", $exception->getMessage());
        }
        else {
            $this->assertSame('A very bad thing happened', $exception->getMessage());
        }
        $failure_marker = $this->container
            ->get(FailureMarker::class);
        if ($exception instanceof ApplyFailedException) {
            $this->assertFileExists($failure_marker->getPath());
            $this->assertFalse($stage->isApplying());
        }
        else {
            $failure_marker->assertNotExists();
        }
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.