Lines 100.00% 14 / 14
Functions and Methods 100.00% 4 / 4
Classes and Traits 100.00% 1 / 1
Name Lines Functions and Methods CRAP Classes and Traits
RecordingRegistryEditor 100.00% 14 / 14 100.00% 4 / 4 7 100.00% 1 / 1
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 refuseUpdates 100.00% 1 / 1 100.00% 1 / 1 1
 updateEntity 100.00% 9 / 9 100.00% 1 / 1 3
 findCurrentEntry 100.00% 3 / 3 100.00% 1 / 1 2
1<?php
2
3declare(strict_types=1);
4
5namespace Stewart\Testing\Registry;
6
7use Stewart\Contracts\Entity\EntityId;
8use Stewart\Contracts\Exception\RegistryEditException;
9use Stewart\Contracts\Registry\RegisteredEntity;
10use Stewart\Contracts\Registry\RegistryEditor;
11use Stewart\Contracts\Registry\Update\EntityRegistryUpdate;
12use Stewart\Testing\Registry\Collection\RecordedRegistryUpdateCollection;
13
14// Without a registry every entity counts as present with an empty entry.
15final class RecordingRegistryEditor implements RegistryEditor
16{
17    public private(set) RecordedRegistryUpdateCollection $updates;
18
19    private ?RegistryEditException $refusal = null;
20
21    public function __construct(private readonly ?InMemoryRegistry $registry = null)
22    {
23        $this->updates = RecordedRegistryUpdateCollection::empty();
24    }
25
26    public function refuseUpdates(RegistryEditException $refusal): void
27    {
28        $this->refusal = $refusal;
29    }
30
31    public function updateEntity(EntityId|string $entityId, EntityRegistryUpdate $update): RegisteredEntity
32    {
33        $entityId = EntityId::fromStringOrId($entityId);
34
35        if ($update->isEmpty()) {
36            throw RegistryEditException::nothingToUpdate($entityId);
37        }
38
39        if ($this->refusal !== null) {
40            throw $this->refusal;
41        }
42
43        $updated = $update->applyTo($this->findCurrentEntry($entityId));
44        $this->updates = $this->updates->withRecordedUpdate(new RecordedRegistryUpdate($entityId, $update));
45        $this->registry?->seedEntity($updated);
46
47        return $updated;
48    }
49
50    /** @throws RegistryEditException */
51    private function findCurrentEntry(EntityId $entityId): RegisteredEntity
52    {
53        if ($this->registry === null) {
54            return new RegisteredEntity($entityId);
55        }
56
57        return $this->registry->findEntity($entityId) ?? throw RegistryEditException::notFound($entityId);
58    }
59}