From 1eb84f4abe0ec5b7cb794d4993ecd8f97656d5aa Mon Sep 17 00:00:00 2001 From: Ivan Vermeyen Date: Sat, 29 Feb 2020 15:39:34 +0100 Subject: [PATCH] Handle string values in resolveRouteBinding() (#22) Fix resolveRouteBinding() method when route value is string --- src/Traits/OptimusEncodedRouteKey.php | 8 +++ tests/Traits/OptimusEncodedRouteKeyTest.php | 64 +++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/src/Traits/OptimusEncodedRouteKey.php b/src/Traits/OptimusEncodedRouteKey.php index 34ffe2f..c292249 100644 --- a/src/Traits/OptimusEncodedRouteKey.php +++ b/src/Traits/OptimusEncodedRouteKey.php @@ -25,6 +25,14 @@ public function getRouteKey() */ public function resolveRouteBinding($value) { + if (is_string($value) && ctype_digit($value)) { + $value = (int) $value; + } + + if (!is_int($value)) { + return null; + } + $id = $this->getOptimus()->decode($value); return $this->where($this->getRouteKeyName(), '=', $id)->first(); diff --git a/tests/Traits/OptimusEncodedRouteKeyTest.php b/tests/Traits/OptimusEncodedRouteKeyTest.php index 0df5612..e75e86c 100644 --- a/tests/Traits/OptimusEncodedRouteKeyTest.php +++ b/tests/Traits/OptimusEncodedRouteKeyTest.php @@ -19,6 +19,7 @@ use Cog\Tests\Laravel\Optimus\Stubs\Models\UserWithDefaultOptimusConnection; use Illuminate\Routing\Middleware\SubstituteBindings; use Illuminate\Support\Facades\Route; +use Jenssegers\Optimus\Optimus as JenssegersOptimus; class OptimusEncodedRouteKeyTest extends AbstractTestCase { @@ -85,6 +86,69 @@ public function testEncodedRouteKeyIsUsedWhenGeneratingNamedRouteUrls(): void $this->assertEquals($expectedUrl, $generatedUrl); } + public function testNonExistingIDsReturnNull() + { + $user = $this->createUserWithDefaultOptimusConnection(); + $resolvedUser = $user->resolveRouteBinding(999); + + $this->assertNull($resolvedUser); + } + + public function testStringValuesReturnNull() + { + $user = $this->createUserWithDefaultOptimusConnection(); + $resolvedUser = $user->resolveRouteBinding('not-an-integer'); + + $this->assertNull($resolvedUser); + } + + public function testStringValuesContainingIntegersReturnNull() + { + $user = $this->createUserWithDefaultOptimusConnection(); + $resolvedUser = $user->resolveRouteBinding('1-not-just-an-integer'); + + $this->assertNull($resolvedUser); + } + + public function testStringValuesContainingEncodedRouteKeysReturnNull() + { + $user = $this->createUserWithDefaultOptimusConnection(); + $encodedRouteKey = $user->getRouteKey(); + $resolvedUser = $user->resolveRouteBinding("{$encodedRouteKey}-suffix-to-the-encoded-route-key"); + + $this->assertNull($resolvedUser); + } + + public function testArrayValuesReturnNull() + { + $user = $this->createUserWithDefaultOptimusConnection(); + $encodedRouteKey = $user->getRouteKey(); + $resolvedUser = $user->resolveRouteBinding([$encodedRouteKey]); + + $this->assertNull($resolvedUser); + } + + public function testFloatValuesReturnNull() + { + $user = $this->createUserWithDefaultOptimusConnection(); + $resolvedUser = $user->resolveRouteBinding(12.3); + + $this->assertNull($resolvedUser); + } + + public function testExistingIntegerValuesBelow256AreResolved() + { + $user = $this->createUserWithDefaultOptimusConnection(); + + $optimus = $this->mock(JenssegersOptimus::class); + $optimus->shouldReceive('decode')->with(123)->andReturn($user->id); + Optimus::shouldReceive('connection')->andReturn($optimus); + + $resolvedUser = $user->resolveRouteBinding(123); + + $this->assertTrue($user->is($resolvedUser)); + } + /** * Create a test user with default Optimus connection in the database. *