From e2a7653ef060f42d54b3f793569558a3761c69b7 Mon Sep 17 00:00:00 2001 From: damienharper Date: Thu, 10 Mar 2022 14:32:35 +0100 Subject: [PATCH] Small transaction processor/hydrator refactoring --- .../Transaction/TransactionHydrator.php | 2 - .../Transaction/TransactionProcessor.php | 2 +- .../Transaction/TransactionProcessorTest.php | 224 +++++++++++++++++- 3 files changed, 224 insertions(+), 4 deletions(-) diff --git a/src/Provider/Doctrine/Auditing/Transaction/TransactionHydrator.php b/src/Provider/Doctrine/Auditing/Transaction/TransactionHydrator.php index 014b9a45..78c92b2c 100644 --- a/src/Provider/Doctrine/Auditing/Transaction/TransactionHydrator.php +++ b/src/Provider/Doctrine/Auditing/Transaction/TransactionHydrator.php @@ -102,7 +102,6 @@ private function hydrateWithScheduledCollectionUpdates(Transaction $transaction, $transaction->trackAuditEvent(Transaction::DISSOCIATE, [ $collection->getOwner(), $entity, - $this->id($entityManager, $entity), $mapping, ]); } @@ -128,7 +127,6 @@ private function hydrateWithScheduledCollectionDeletions(Transaction $transactio $transaction->trackAuditEvent(Transaction::DISSOCIATE, [ $collection->getOwner(), $entity, - $this->id($entityManager, $entity), $mapping, ]); } diff --git a/src/Provider/Doctrine/Auditing/Transaction/TransactionProcessor.php b/src/Provider/Doctrine/Auditing/Transaction/TransactionProcessor.php index e59df227..4a9be7be 100644 --- a/src/Provider/Doctrine/Auditing/Transaction/TransactionProcessor.php +++ b/src/Provider/Doctrine/Auditing/Transaction/TransactionProcessor.php @@ -159,7 +159,7 @@ private function processAssociations(Transaction $transaction, EntityManagerInte private function processDissociations(Transaction $transaction, EntityManagerInterface $entityManager): void { - foreach ($transaction->getDissociated() as [$source, $target, $id, $mapping]) { + foreach ($transaction->getDissociated() as [$source, $target, $mapping]) { $this->dissociate($entityManager, $source, $target, $mapping, $transaction->getTransactionHash()); } } diff --git a/tests/Provider/Doctrine/Auditing/Transaction/TransactionProcessorTest.php b/tests/Provider/Doctrine/Auditing/Transaction/TransactionProcessorTest.php index dcb2b631..a046ee43 100644 --- a/tests/Provider/Doctrine/Auditing/Transaction/TransactionProcessorTest.php +++ b/tests/Provider/Doctrine/Auditing/Transaction/TransactionProcessorTest.php @@ -5,8 +5,8 @@ namespace DH\Auditor\Tests\Provider\Doctrine\Auditing\Transaction; use DateTimeImmutable; -use DH\Auditor\Model\Transaction; use DH\Auditor\Provider\Doctrine\Auditing\Transaction\TransactionProcessor; +use DH\Auditor\Provider\Doctrine\Model\Transaction; use DH\Auditor\Provider\Doctrine\Persistence\Reader\Reader; use DH\Auditor\Provider\Doctrine\Service\StorageService; use DH\Auditor\Tests\Provider\Doctrine\Fixtures\Entity\Standard\Blog\Author; @@ -580,6 +580,228 @@ public function testDissociateManyToMany(): void ], $entry->getDiffs(), 'audit entry diffs is ok.'); } + public function testProcessInsertions(): void + { + $reader = new Reader($this->provider); + $processor = new TransactionProcessor($this->provider); + + /** @var StorageService $storageService */ + $storageService = $this->provider->getStorageServiceForEntity(Author::class); + $entityManager = $storageService->getEntityManager(); + + $transaction = new Transaction($entityManager); + + $author = new Author(); + $author + ->setId(1) + ->setFullname('John Doe') + ->setEmail('john.doe@gmail.com') + ; + + $transaction->trackAuditEvent(Transaction::INSERT, [ + $author, + [ + 'fullname' => [null, 'John Doe'], + 'email' => [null, 'john.doe@gmail.com'], + ], + ]); + + $processor->process($transaction); + + $audits = $reader->createQuery(Author::class)->execute(); + self::assertCount(1, $audits, 'TransactionProcessor::processInsertions() creates an "'.Transaction::INSERT.'" audit entry.'); + } + + public function testProcessUpdates(): void + { + $reader = new Reader($this->provider); + $processor = new TransactionProcessor($this->provider); + + /** @var StorageService $storageService */ + $storageService = $this->provider->getStorageServiceForEntity(Author::class); + $entityManager = $storageService->getEntityManager(); + + $transaction = new Transaction($entityManager); + + $author = new Author(); + $author + ->setId(1) + ->setFullname('John Doze') + ->setEmail('john.doze@gmail.com') + ; + + $transaction->trackAuditEvent(Transaction::UPDATE, [ + $author, + [ + 'fullname' => ['John Doe', 'John Doze'], + 'email' => ['john.doe@gmail.com', 'john.doze@gmail.com'], + ], + ]); + + $processor->process($transaction); + + $audits = $reader->createQuery(Author::class)->execute(); + self::assertCount(1, $audits, 'TransactionProcessor::processUpdates() creates an "'.Transaction::UPDATE.'" audit entry.'); + + $transaction->reset(); + + $transaction->trackAuditEvent(Transaction::UPDATE, [ + $author, + [], + ]); + + $processor->process($transaction); + + $audits = $reader->createQuery(Author::class)->execute(); + self::assertCount(1, $audits, 'TransactionProcessor::processUpdates() does not create an "'.Transaction::UPDATE.'" audit entry with empty diffs.'); + } + + public function testProcessAssociations(): void + { + $reader = new Reader($this->provider); + $processor = new TransactionProcessor($this->provider); + + /** @var StorageService $storageService */ + $storageService = $this->provider->getStorageServiceForEntity(Author::class); + $entityManager = $storageService->getEntityManager(); + + $transaction = new Transaction($entityManager); + + $author = new Author(); + $author + ->setId(1) + ->setFullname('John Doe') + ->setEmail('john.doe@gmail.com') + ; + + $post = new Post(); + $post + ->setId(1) + ->setAuthor($author) + ->setTitle('First post') + ->setBody('Here is the body') + ->setCreatedAt(new DateTimeImmutable()) + ; + + $mapping = [ + 'fieldName' => 'posts', + 'mappedBy' => 'author', + 'targetEntity' => Post::class, + 'cascade' => [ + 0 => 'persist', + 1 => 'remove', + ], + 'orphanRemoval' => false, + 'fetch' => 2, + 'type' => 4, + 'inversedBy' => null, + 'isOwningSide' => false, + 'sourceEntity' => Author::class, + 'isCascadeRemove' => true, + 'isCascadePersist' => true, + 'isCascadeRefresh' => false, + 'isCascadeMerge' => false, + 'isCascadeDetach' => false, + ]; + + $transaction->trackAuditEvent(Transaction::ASSOCIATE, [ + $author, + $post, + $mapping, + ]); + + $processor->process($transaction); + + $audits = $reader->createQuery(Author::class)->execute(); + self::assertCount(1, $audits, 'TransactionProcessor::processAssociations() creates an "'.Transaction::ASSOCIATE.'" audit entry.'); + } + + public function testProcessDissociations(): void + { + $reader = new Reader($this->provider); + $processor = new TransactionProcessor($this->provider); + + /** @var StorageService $storageService */ + $storageService = $this->provider->getStorageServiceForEntity(Author::class); + $entityManager = $storageService->getEntityManager(); + + $transaction = new Transaction($entityManager); + + $author = new Author(); + $author + ->setId(1) + ->setFullname('John Doe') + ->setEmail('john.doe@gmail.com') + ; + + $post = new Post(); + $post + ->setId(1) + ->setAuthor($author) + ->setTitle('First post') + ->setBody('Here is the body') + ->setCreatedAt(new DateTimeImmutable()) + ; + + $mapping = [ + 'fieldName' => 'posts', + 'mappedBy' => 'author', + 'targetEntity' => Post::class, + 'cascade' => ['persist', 'remove'], + 'orphanRemoval' => false, + 'fetch' => 2, + 'type' => 4, + 'inversedBy' => null, + 'isOwningSide' => false, + 'sourceEntity' => Author::class, + 'isCascadeRemove' => true, + 'isCascadePersist' => true, + 'isCascadeRefresh' => false, + 'isCascadeMerge' => false, + 'isCascadeDetach' => false, + ]; + + $transaction->trackAuditEvent(Transaction::DISSOCIATE, [ + $author, + $post, + $mapping, + ]); + + $processor->process($transaction); + + $audits = $reader->createQuery(Author::class)->execute(); + self::assertCount(1, $audits, 'TransactionProcessor::processDissociations() creates an "'.Transaction::DISSOCIATE.'" audit entry.'); + } + + public function testProcessDeletions(): void + { + $reader = new Reader($this->provider); + $processor = new TransactionProcessor($this->provider); + + /** @var StorageService $storageService */ + $storageService = $this->provider->getStorageServiceForEntity(Author::class); + $entityManager = $storageService->getEntityManager(); + + $transaction = new Transaction($entityManager); + + $author = new Author(); + $author + ->setId(1) + ->setFullname('John Doe') + ->setEmail('john.doe@gmail.com') + ; + + $transaction->trackAuditEvent(Transaction::REMOVE, [ + $author, + 1, + ]); + + $processor->process($transaction); + + $audits = $reader->createQuery(Author::class)->execute(); + self::assertCount(1, $audits, 'TransactionProcessor::processDeletions() creates a "'.Transaction::REMOVE.'" audit entry.'); + } + private function configureEntities(): void { $this->provider->getConfiguration()->setEntities([