Skip to content

Commit

Permalink
TASK: Introduce test to assert behaviour when catchup hooks use the p…
Browse files Browse the repository at this point in the history
…ersistence manager
  • Loading branch information
mhsdesign committed Dec 4, 2024
1 parent bccea53 commit 4c41482
Showing 1 changed file with 120 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php

declare(strict_types=1);

namespace Neos\ContentRepository\BehavioralTests\Tests\Functional\Subscription;

use Doctrine\DBAL\Connection;
use Neos\Behat\FlowEntitiesTrait;
use Neos\ContentRepository\Core\Feature\ContentStreamCreation\Event\ContentStreamWasCreated;
use Neos\ContentRepository\Core\Subscription\SubscriptionStatus;
use Neos\EventStore\Model\Event\SequenceNumber;
use Neos\Flow\Persistence\PersistenceManagerInterface;
use Neos\Flow\ResourceManagement\PersistentResource;
use Neos\Flow\ResourceManagement\ResourceRepository;

final class CatchUpHookWithPersistenceTest extends AbstractSubscriptionEngineTestCase
{
use FlowEntitiesTrait;

/**
* @before
*/
public function setupFlowEntities()
{
$this->truncateAndSetupFlowEntities();
}

/** @test */
public function commitOnConnection_onAfterEvent()
{
$this->eventStore->setup();
$this->fakeProjection->expects(self::once())->method('setUp');
$this->fakeProjection->expects(self::once())->method('apply');
$this->subscriptionEngine->setup();
$this->subscriptionEngine->boot();

// commit two events. but only the first will never be seen
$this->commitExampleContentStreamEvent();
$this->commitExampleContentStreamEvent();

$this->catchupHookForFakeProjection->expects(self::once())->method('onBeforeCatchUp')->with(SubscriptionStatus::ACTIVE);
$this->catchupHookForFakeProjection->expects(self::once())->method('onBeforeEvent')->with(self::isInstanceOf(ContentStreamWasCreated::class));
$this->catchupHookForFakeProjection->expects(self::once())->method('onAfterEvent')->willReturnCallback(function () {
$this->getObject(Connection::class)->commit();
});
$this->catchupHookForFakeProjection->expects(self::never())->method('onAfterCatchUp');

self::assertEmpty(
$this->secondFakeProjection->getState()->findAppliedSequenceNumbers()
);

$actualException = null;
try {
$this->subscriptionEngine->catchUpActive();
} catch (\Throwable $e) {
$actualException = $e;
}
self::assertInstanceOf(\Doctrine\DBAL\ConnectionException::class, $actualException);

// todo invalid state, use own connection for cr?!
$this->expectOkayStatus('Vendor.Package:SecondFakeProjection', SubscriptionStatus::ACTIVE, SequenceNumber::none());
self::assertEquals(
[SequenceNumber::fromInteger(1)],
$this->secondFakeProjection->getState()->findAppliedSequenceNumbers()
);
}

/** @test */
public function persistAll_onAfterEvent_willUseTheTransaction()
{
$this->eventStore->setup();
$this->fakeProjection->expects(self::once())->method('setUp');
$this->fakeProjection->expects(self::once())->method('apply');
$this->subscriptionEngine->setup();
$this->subscriptionEngine->boot();

// commit one event
$this->commitExampleContentStreamEvent();

$persistentResource = new PersistentResource();
$persistentResource->disableLifecycleEvents();
$persistentResource->setFilename($expectedName = 'test_cr_catchup.empty');
$persistentResource->setFileSize(0);
$persistentResource->setCollectionName('default');
$persistentResource->setMediaType('text/plain');
$persistentResource->setSha1($sha1 = '67f22467d829a254d53fa5cf019787c23c57bbef');

self::assertTrue($this->getObject(PersistenceManagerInterface::class)->isNewObject($persistentResource));

$this->catchupHookForFakeProjection->expects(self::once())->method('onBeforeCatchUp')->with(SubscriptionStatus::ACTIVE);
$this->catchupHookForFakeProjection->expects(self::once())->method('onBeforeEvent')->with(self::isInstanceOf(ContentStreamWasCreated::class));
$this->catchupHookForFakeProjection->expects(self::once())->method('onAfterEvent')->willReturnCallback(function () use ($persistentResource) {
$this->getObject(ResourceRepository::class)->add($persistentResource);
$this->getObject(PersistenceManagerInterface::class)->persistAll();
});
$this->catchupHookForFakeProjection->expects(self::once())->method('onAfterCatchUp');

self::assertEmpty(
$this->secondFakeProjection->getState()->findAppliedSequenceNumbers()
);

$result = $this->subscriptionEngine->catchUpActive();
self::assertNull($result->errors);

$this->expectOkayStatus('Vendor.Package:SecondFakeProjection', SubscriptionStatus::ACTIVE, SequenceNumber::fromInteger(1));
self::assertEquals(
[SequenceNumber::fromInteger(1)],
$this->secondFakeProjection->getState()->findAppliedSequenceNumbers()
);

// check that the object was persisted and re-fetch it from the database
self::assertFalse($this->getObject(PersistenceManagerInterface::class)->isNewObject($persistentResource));
$this->getObject(PersistenceManagerInterface::class)->clearState();

$actuallyPersisted = $this->getObject(ResourceRepository::class)->findOneBySha1($sha1);

self::assertEquals($sha1, $actuallyPersisted->getSha1());
self::assertEquals($expectedName, $actuallyPersisted->getFilename());
}
}

0 comments on commit 4c41482

Please sign in to comment.