function WorkspacePublisherTest::testPublishThrowableRollback
Same name and namespace in other branches
- main core/modules/workspaces/tests/src/Kernel/WorkspacePublisherTest.php \Drupal\Tests\workspaces\Kernel\WorkspacePublisherTest::testPublishThrowableRollback()
Tests that a throwable during publish is logged and rolls back the save.
Attributes
#[DataProvider('providerPublishThrowableRollback')]
File
-
core/
modules/ workspaces/ tests/ src/ Kernel/ WorkspacePublisherTest.php, line 129
Class
- WorkspacePublisherTest
- Tests workspace publishing.
Namespace
Drupal\Tests\workspaces\KernelCode
public function testPublishThrowableRollback(string $thrown) : void {
$logger = new TestLogger();
$this->container
->get(LoggerChannelFactoryInterface::class)
->get('workspaces')
->addLogger($logger);
// Create two nodes in Live and capture their default revision IDs.
$node_1 = $this->createNode([
'title' => 'node_1 live',
]);
$node_2 = $this->createNode([
'title' => 'node_2 live',
]);
$node_1_live_vid = $node_1->getRevisionId();
$node_2_live_vid = $node_2->getRevisionId();
// Create a workspace and add a workspace-specific revision for each node.
$workspace = Workspace::create([
'id' => 'stage',
'label' => 'Stage',
]);
$workspace->save();
$this->switchToWorkspace('stage');
$storage = $this->entityTypeManager
->getStorage('node');
foreach ([
$node_1,
$node_2,
] as $node) {
$edited = $storage->loadUnchanged($node->id());
$edited->title = 'workspace edit';
$edited->save();
}
// Throw on the second presave inside the publisher's save loop, so the
// first node's save has already happened inside the open transaction. The
// data provider covers both \Exception and \Error subclasses; the
// publisher's catch block must handle any \Throwable.
$this->throwOnNodePresaveClass = $thrown;
try {
$workspace->publish();
} catch (\Throwable) {
}
// Rollback proof: the first node's in-flight save was undone.
$this->switchToLive();
$this->assertSame($node_1_live_vid, $storage->loadUnchanged($node_1->id())
->getRevisionId());
$this->assertSame($node_2_live_vid, $storage->loadUnchanged($node_2->id())
->getRevisionId());
// The publisher logged the throwable on its channel.
$this->assertTrue($logger->hasRecordThatPasses(static fn(array $record): bool => ($record['context']['@message'] ?? '') === 'Simulated node presave failure.', RfcLogLevel::ERROR));
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.