diff --git a/tests/ModelTest.php b/tests/ModelTest.php index 21523c7..1042a07 100644 --- a/tests/ModelTest.php +++ b/tests/ModelTest.php @@ -16,10 +16,14 @@ use Jenssegers\Mongodb\Eloquent\Model; use Jenssegers\Mongodb\Tests\Models\Book; use Jenssegers\Mongodb\Tests\Models\Guarded; +use Jenssegers\Mongodb\Tests\Models\IdIsBinaryUuid; +use Jenssegers\Mongodb\Tests\Models\IdIsInt; +use Jenssegers\Mongodb\Tests\Models\IdIsString; use Jenssegers\Mongodb\Tests\Models\Item; use Jenssegers\Mongodb\Tests\Models\MemberStatus; use Jenssegers\Mongodb\Tests\Models\Soft; use Jenssegers\Mongodb\Tests\Models\User; +use MongoDB\BSON\Binary; use MongoDB\BSON\ObjectID; use MongoDB\BSON\UTCDateTime; @@ -325,11 +329,103 @@ public function testSoftDelete(): void $this->assertEquals(2, Soft::count()); } - public function testPrimaryKey(): void + /** + * @dataProvider provideId + */ + public function testPrimaryKey(string $model, $id, $expected, bool $expectedFound): void + { + $model::truncate(); + $expectedType = get_debug_type($expected); + + $document = new $model; + $this->assertEquals('_id', $document->getKeyName()); + + $document->_id = $id; + $document->save(); + $this->assertSame($expectedType, get_debug_type($document->_id)); + $this->assertEquals($expected, $document->_id); + $this->assertSame($expectedType, get_debug_type($document->getKey())); + $this->assertEquals($expected, $document->getKey()); + + $check = $model::find($id); + + if ($expectedFound) { + $this->assertNotNull($check, 'Not found'); + $this->assertSame($expectedType, get_debug_type($check->_id)); + $this->assertEquals($id, $check->_id); + $this->assertSame($expectedType, get_debug_type($check->getKey())); + $this->assertEquals($id, $check->getKey()); + } else { + $this->assertNull($check, 'Found'); + } + } + + public static function provideId(): iterable + { + yield 'int' => [ + 'model' => User::class, + 'id' => 10, + 'expected' => 10, + // Don't expect this to be found, as the int is cast to string for the query + 'expectedFound' => false, + ]; + + yield 'cast as int' => [ + 'model' => IdIsInt::class, + 'id' => 10, + 'expected' => 10, + 'expectedFound' => true, + ]; + + yield 'string' => [ + 'model' => User::class, + 'id' => 'user-10', + 'expected' => 'user-10', + 'expectedFound' => true, + ]; + + yield 'cast as string' => [ + 'model' => IdIsString::class, + 'id' => 'user-10', + 'expected' => 'user-10', + 'expectedFound' => true, + ]; + + $objectId = new ObjectID(); + yield 'ObjectID' => [ + 'model' => User::class, + 'id' => $objectId, + 'expected' => (string) $objectId, + 'expectedFound' => true, + ]; + + $binaryUuid = new Binary(hex2bin('0c103357380648c9a84b867dcb625cfb'), Binary::TYPE_UUID); + yield 'BinaryUuid' => [ + 'model' => User::class, + 'id' => $binaryUuid, + 'expected' => (string) $binaryUuid, + 'expectedFound' => true, + ]; + + yield 'cast as BinaryUuid' => [ + 'model' => IdIsBinaryUuid::class, + 'id' => $binaryUuid, + 'expected' => (string) $binaryUuid, + 'expectedFound' => true, + ]; + + $date = new UTCDateTime(); + yield 'UTCDateTime' => [ + 'model' => User::class, + 'id' => $date, + 'expected' => $date, + // Don't expect this to be found, as the original value is stored as UTCDateTime but then cast to string + 'expectedFound' => false, + ]; + } + + public function testCustomPrimaryKey(): void { - $user = new User; - $this->assertEquals('_id', $user->getKeyName()); - $book = new Book; $this->assertEquals('title', $book->getKeyName()); diff --git a/tests/Models/IdIsBinaryUuid.php b/tests/Models/IdIsBinaryUuid.php new file mode 100644 index 0000000..1d8c592 --- /dev/null +++ b/tests/Models/IdIsBinaryUuid.php @@ -0,0 +1,17 @@ + BinaryUuid::class, + ]; +} diff --git a/tests/Models/IdIsInt.php b/tests/Models/IdIsInt.php new file mode 100644 index 0000000..d721320 --- /dev/null +++ b/tests/Models/IdIsInt.php @@ -0,0 +1,17 @@ + 'int', + ]; +} diff --git a/tests/Models/IdIsString.php b/tests/Models/IdIsString.php new file mode 100644 index 0000000..48a2845 --- /dev/null +++ b/tests/Models/IdIsString.php @@ -0,0 +1,16 @@ + 'string', + ]; +}