From 59510ec19da36bd44a176eb753fc3f79a0e33b6a Mon Sep 17 00:00:00 2001 From: holtkamp Date: Thu, 12 Sep 2024 09:51:42 +0200 Subject: [PATCH] fix: ensure early return of response is respected when conditional Middleware is involved --- src/Harmony.php | 9 ++++++-- tests/HarmonyTest.php | 50 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/Harmony.php b/src/Harmony.php index e82ff34..bc26d11 100644 --- a/src/Harmony.php +++ b/src/Harmony.php @@ -12,6 +12,7 @@ use function array_key_exists; use function assert; +use function count; class Harmony implements RequestHandlerInterface { @@ -128,13 +129,17 @@ protected function executeCondition(array $conditionArray): void return; } + //When the Condition evaluates to true: instantiate a new/branched Harmony instance to process the conditional Middleware $harmony = new Harmony($this->request, $this->response); $callable($harmony, $this->request); + + //Add remaining Middleware of the current Harmony instance to the new/branched Harmony instance and run it + for ($i = $this->currentMiddleware + 1; $i < count($this->middleware); $i++) { + $harmony->middleware[] = $this->middleware[$i]; + } $harmony->run(); $this->request = $harmony->request; $this->response = $harmony->response; - - $this->handle($this->request); } } diff --git a/tests/HarmonyTest.php b/tests/HarmonyTest.php index 643017d..04d5b83 100644 --- a/tests/HarmonyTest.php +++ b/tests/HarmonyTest.php @@ -76,6 +76,56 @@ public function returnAfterSecondMiddleware(): void $this->assertEquals(500, $response->getStatusCode()); } + /** + * @test + */ + public function returnResponseWhenConditionIsInvolved(): void + { + $harmony = $this->createHarmony(); + $harmony->addMiddleware(new FakeMiddleware()); + $harmony->addCondition( + new StubCondition(true), + static fn (Harmony $harmony): Harmony => $harmony->addMiddleware(new InternalServerErrorMiddleware(new DummyResponse())) + ); + $middlewareSecond = new SpyMiddleware(); + $harmony->addMiddleware($middlewareSecond); + + $harmony->run(); + + $this->assertFalse($middlewareSecond->isInvoked()); + } + + /** + * @test + */ + public function returnResponseWhenMultipleConditionsAreInvolved(): void + { + $harmony = $this->createHarmony(); + $harmony->addMiddleware(new FakeMiddleware()); + $middlewareFirst = new SpyMiddleware(); + $harmony->addMiddleware($middlewareFirst); + + $middlewareSecond = new SpyMiddleware(); + $harmony->addCondition( + new StubCondition(true), + static fn (Harmony $harmony): Harmony => $harmony->addMiddleware($middlewareSecond) + ); + + $harmony->addCondition( + new StubCondition(true), + static fn (Harmony $harmony): Harmony => $harmony->addMiddleware(new InternalServerErrorMiddleware(new DummyResponse())) + ); + + $middlewareThird = new SpyMiddleware(); + $harmony->addMiddleware($middlewareThird); + + $harmony->run(); + + $this->assertTrue($middlewareFirst->isInvoked()); + $this->assertTrue($middlewareSecond->isInvoked()); + $this->assertFalse($middlewareThird->isInvoked()); + } + /** * @test */