thenEventIsTestDomainEventWithPayoad()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 2
1
<?php declare(strict_types = 1);
2
3
namespace TomCizek\ResponseRecorder\Tests\Application;
4
5
use Closure;
6
use Exception;
7
use PHPUnit\Framework\TestCase;
8
use Prooph\ServiceBus\EventBus;
9
use Prooph\ServiceBus\Exception\CommandDispatchException;
10
use Psr\Log\NullLogger;
11
use TomCizek\ResponseRecorder\Application\ResponseRecorder;
12
use TomCizek\ResponseRecorder\Application\ResponseRecorder\BasicMutationResponse;
13
use TomCizek\ResponseRecorder\Application\ResponseRecorder\MutationResponse\ErrorCollection\ShowableMutationError;
14
use TomCizek\ResponseRecorder\Tests\FakeImplementations\TestDomainEvent;
15
use TomCizek\ResponseRecorder\Tests\FakeImplementations\TestShowableTranslatableException;
16
use TomCizek\ResponseRecorder\Tests\FakeImplementations\TestTranslatableDomainErrorDomainEvent;
17
18
class ResponseRecorderTest extends TestCase
19
{
20
	/** @var ResponseRecorder */
21
	private $sut;
22
23
	/** @var EventBus */
24
	private $eventBus;
25
26
	public function setUp(): void
27
	{
28
		parent::setUp();
29
30
		$this->eventBus = new EventBus();
31
32
		$this->sut = new ResponseRecorder($this->eventBus, new NullLogger());
33
34
	}
35
36
	public function testRecordOn_EmptyFunction_ShouldReturnEmptyResponse(): void
37
	{
38
		$response = $this->whenRecordOnFunctionThat(
39
			$this->doNothing()
40
		);
41
		$this->thenCountOfErrorsOnResponseIs($response, 0);
42
		$this->thenCountOfDomainEventsIs($response, 0);
43
	}
44
45 View Code Duplication
	public function testRecordOn_FunctionThrowingFatalError_ShouldReturnResponseWithOneFatalError(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
46
	{
47
		$response = $this->whenRecordOnFunctionThat(
48
			$this->throwFatalException()
49
		);
50
51
		$this->thenCountOfErrorsOnResponseIs($response, 1);
52
		$this->thenCountOfDomainEventsIs($response, 0);
53
		$this->thenFirstErrorHasMessage($response, ResponseRecorder::FATAL_ERROR_MESSAGE);
54
	}
55
56
	public function testRecordOn_FunctionThrowingShowableError_ShouldReturnResponseWithShowableError(): void
57
	{
58
59
		$testMessage = 'test_message';
60
		$testParams = ['foo' => 'bar'];
61
62
		$response = $this->whenRecordOnFunctionThat(
63
			$this->throwShowableException($testMessage, $testParams)
64
		);
65
66
		$this->thenCountOfErrorsOnResponseIs($response, 1);
67
		$this->thenCountOfDomainEventsIs($response, 0);
68
		$this->thenFirstErrorHasMessage($response, $testMessage);
69
		$this->thenFirstErrorHasMessageParams($response, $testParams);
70
	}
71
72
	public function testRecordOn_FunctionThrowingCommandDispatchExceptionWithPreviousShowableException_ShouldReturnResponseWithShowableError(
73
	): void
74
	{
75
		$testMessage = 'test_message';
76
		$testParams = ['foo' => 'bar'];
77
78
		$response = $this->whenRecordOnFunctionThat(
79
			$this->throwCommandDispatchExceptionWithPreviousShowable($testMessage, $testParams)
80
		);
81
82
		$this->thenCountOfErrorsOnResponseIs($response, 1);
83
		$this->thenCountOfDomainEventsIs($response, 0);
84
		$this->thenFirstErrorHasMessage($response, $testMessage);
85
		$this->thenFirstErrorHasMessageParams($response, $testParams);
86
	}
87
88 View Code Duplication
	public function testRecordOn_FunctionThrowingCommandDispatchExceptionWithPreviousFatalException_ShouldReturnResponseWithShowableFatalError(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
89
	): void
90
	{
91
		$response = $this->whenRecordOnFunctionThat(
92
			$this->throwCommandDispatchExceptionWithPreviousFatal()
93
		);
94
95
		$this->thenCountOfErrorsOnResponseIs($response, 1);
96
		$this->thenCountOfDomainEventsIs($response, 0);
97
		$this->thenFirstErrorHasMessage($response, ResponseRecorder::FATAL_ERROR_MESSAGE);
98
	}
99
100
	public function testRecordOn_FunctionDispatchingErrorDomainEvent_ShouldReturnResponseWithShowableError(): void
101
	{
102
		$testPayload = ['test_payload'];
103
		$testErrorDomainEvent = new TestTranslatableDomainErrorDomainEvent($testPayload);
104
105
		$eventBus = $this->eventBus;
106
		$response = $this->whenRecordOnFunctionThat(
107
			$this->dispatchMessageEventOnce($testErrorDomainEvent, $eventBus)
108
		);
109
110
		$this->thenCountOfErrorsOnResponseIs($response, 1);
111
		$this->thenCountOfDomainEventsIs($response, 1);
112
		$this->thenFirstErrorHasMessage($response, TestTranslatableDomainErrorDomainEvent::TEST_ERROR_MESSAGE);
113
		$this->thenFirstErrorHasMessageParams($response, TestTranslatableDomainErrorDomainEvent::TEST_ERROR_MESSAGE_PARAMS);
114
	}
115
116 View Code Duplication
	public function testRecordOn_FunctionDispatchingTwoErrorDomainEventAndThrowingException_ShouldReturnResponseWith2EventsAnd3Errors(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
117
	): void
118
	{
119
		$testPayload = ['test_payload'];
120
		$testErrorDomainEvent = new TestTranslatableDomainErrorDomainEvent($testPayload);
121
122
		$eventBus = $this->eventBus;
123
		$response = $this->whenRecordOnFunctionThat(
124
			$this->dispatchMessageTwoTimesAndThrowException($testErrorDomainEvent, $eventBus)
125
		);
126
127
		$this->thenCountOfErrorsOnResponseIs($response, 3);
128
		$this->thenCountOfDomainEventsIs($response, 2);
129
	}
130
131
	public function testRecordOn_FunctionDispatchingStringEvent_ShouldReturnEmptyResponse(): void
132
	{
133
134
		$testMessage = 'test_message';
135
136
		$eventBus = $this->eventBus;
137
		$response = $this->whenRecordOnFunctionThat(
138
			$this->dispatchMessageEventOnce($testMessage, $eventBus)
139
		);
140
141
		$this->thenCountOfErrorsOnResponseIs($response, 0);
142
		$this->thenCountOfDomainEventsIs($response, 0);
143
	}
144
145 View Code Duplication
	public function testRecordOn_FunctionDispatchingEvent_ShouldReturnResponseWithEvent(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
146
	{
147
		$testPayload = ['test_payload'];
148
		$testDomainEvent = new TestDomainEvent($testPayload);
149
150
		$eventBus = $this->eventBus;
151
		$response = $this->whenRecordOnFunctionThat(
152
			$this->dispatchMessageEventOnce($testDomainEvent, $eventBus)
153
		);
154
155
		$this->thenCountOfErrorsOnResponseIs($response, 0);
156
		$this->thenCountOfDomainEventsIs($response, 1);
157
		$this->thenEventIsTestDomainEventWithPayoad($response, $testPayload);
158
	}
159
160
	private function whenRecordOnFunctionThat(Closure $doSomething): BasicMutationResponse
161
	{
162
		return $this->sut->recordOn($doSomething);
163
	}
164
165
	private function dispatchMessageEventOnce($domainEventMessage, EventBus $eventBus): Closure
166
	{
167
		return function () use ($domainEventMessage, $eventBus) {
168
			$eventBus->dispatch($domainEventMessage);
169
		};
170
	}
171
172
	private function dispatchMessageTwoTimesAndThrowException($domainEventMessage, EventBus $eventBus): Closure
173
	{
174
		return function () use ($domainEventMessage, $eventBus) {
175
			$eventBus->dispatch($domainEventMessage);
176
			$eventBus->dispatch($domainEventMessage);
177
			throw new Exception();
178
		};
179
	}
180
181
	private function throwFatalException(): Closure
182
	{
183
		return function () {
184
			throw new Exception();
185
		};
186
	}
187
188
	private function throwShowableException($domainEventMessage, array $testParams): Closure
189
	{
190
		return function () use ($domainEventMessage, $testParams) {
191
			throw new TestShowableTranslatableException($domainEventMessage, $testParams);
192
		};
193
	}
194
195
	private function throwCommandDispatchExceptionWithPreviousShowable($domainEventMessage, array $testParams): Closure
196
	{
197
		return function () use ($domainEventMessage, $testParams) {
198
			$previous = new TestShowableTranslatableException($domainEventMessage, $testParams);
199
			throw new CommandDispatchException('', 0, $previous);
200
		};
201
	}
202
203
	private function throwCommandDispatchExceptionWithPreviousFatal(): Closure
204
	{
205
		return function () {
206
			$previous = new Exception();
207
			throw new CommandDispatchException('', 0, $previous);
208
		};
209
	}
210
211
	private function thenCountOfErrorsOnResponseIs(BasicMutationResponse $response, int $expectedCount): void
212
	{
213
		self::assertCount($expectedCount, $response->getErrors());
214
	}
215
216
	protected function thenCountOfDomainEventsIs(BasicMutationResponse $response, int $expectedCount): void
217
	{
218
		self::assertCount($expectedCount, $response->getDomainEvents());
219
	}
220
221 View Code Duplication
	protected function thenFirstErrorHasMessage(BasicMutationResponse $response, $message): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
222
	{
223
		$error = $response->getErrors()->getAll()[0];
224
225
		self::assertInstanceOf(ShowableMutationError::class, $error);
226
		self::assertEquals($message, $error->getErrorMessage());
227
	}
228
229 View Code Duplication
	private function thenFirstErrorHasMessageParams(BasicMutationResponse $response, $params)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
230
	{
231
		$error = $response->getErrors()->getAll()[0];
232
233
		self::assertInstanceOf(ShowableMutationError::class, $error);
234
		self::assertEquals($params, $error->getErrorMessageParams());
235
	}
236
237
	protected function thenEventIsTestDomainEventWithPayoad(BasicMutationResponse $response, $testPayload): void
238
	{
239
		$event = $response->getDomainEvents()->getAll()[0];
240
241
		self::assertInstanceOf(TestDomainEvent::class, $event);
242
		self::assertEquals($testPayload, $event->payload());
243
	}
244
245
	protected function doNothing(): Closure
246
	{
247
		return function () {
248
		};
249
	}
250
}
251