From 8c353c10ac1a872cf40f33d1b046b66a8fea857a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Wed, 8 Nov 2023 13:04:51 +0100 Subject: [PATCH] Add tests to cover morphTo with hybrid MongoDB and SQL --- tests/HybridRelationsTest.php | 66 +++++++++++++++++++++++++++++++++++ tests/Models/Book.php | 6 ++++ tests/Models/SqlBook.php | 18 +++++++--- tests/Models/SqlPhoto.php | 46 ++++++++++++++++++++++++ tests/Models/SqlRole.php | 6 ++-- tests/Models/SqlUser.php | 12 +++++-- tests/Models/User.php | 6 ++-- 7 files changed, 147 insertions(+), 13 deletions(-) create mode 100644 tests/Models/SqlPhoto.php diff --git a/tests/HybridRelationsTest.php b/tests/HybridRelationsTest.php index 9ff6264e5..418ea1d07 100644 --- a/tests/HybridRelationsTest.php +++ b/tests/HybridRelationsTest.php @@ -7,8 +7,10 @@ use Illuminate\Database\SQLiteConnection; use Illuminate\Support\Facades\DB; use MongoDB\Laravel\Tests\Models\Book; +use MongoDB\Laravel\Tests\Models\Photo; use MongoDB\Laravel\Tests\Models\Role; use MongoDB\Laravel\Tests\Models\SqlBook; +use MongoDB\Laravel\Tests\Models\SqlPhoto; use MongoDB\Laravel\Tests\Models\SqlRole; use MongoDB\Laravel\Tests\Models\SqlUser; use MongoDB\Laravel\Tests\Models\User; @@ -29,6 +31,7 @@ public function setUp(): void SqlUser::executeSchema(); SqlBook::executeSchema(); SqlRole::executeSchema(); + SqlPhoto::executeSchema(); } public function tearDown(): void @@ -36,6 +39,10 @@ public function tearDown(): void SqlUser::truncate(); SqlBook::truncate(); SqlRole::truncate(); + SqlPhoto::truncate(); + Photo::truncate(); + Book::truncate(); + User::truncate(); } public function testSqlRelations() @@ -210,4 +217,63 @@ public function testHybridWith() $this->assertEquals($user->id, $user->books->count()); }); } + + public function testHybridMorphToMongoDB(): void + { + $user = SqlUser::create(['name' => 'John Doe']); + + $photo = Photo::create(['url' => 'http://graph.facebook.com/john.doe/picture']); + $photo = $user->photos()->save($photo); + + $this->assertEquals(1, $user->photos->count()); + $this->assertEquals($photo->id, $user->photos->first()->id); + + $user = SqlUser::find($user->id); + $this->assertEquals(1, $user->photos->count()); + $this->assertEquals($photo->id, $user->photos->first()->id); + + $book = SqlBook::create(['title' => 'Game of Thrones']); + $photo = Photo::create(['url' => 'http://graph.facebook.com/gameofthrones/picture']); + $book->photo()->save($photo); + + $this->assertNotNull($book->photo); + $this->assertEquals($photo->id, $book->photo->id); + + $book = SqlBook::where('title', $book->title)->get()->first(); + $this->assertNotNull($book->photo); + $this->assertEquals($photo->id, $book->photo->id); + + $photo = Photo::first(); + $this->assertEquals($photo->hasImage->name, $user->name); + } + + public function testHybridMorphToSql(): void + { + $user = User::create(['name' => 'John Doe']); + + $photo = SqlPhoto::create(['url' => 'http://graph.facebook.com/john.doe/picture']); + $photo->save(); + $photo = $user->photos()->save($photo); + + $this->assertEquals(1, $user->photos->count()); + $this->assertEquals($photo->id, $user->photos->first()->id); + + $user = User::find($user->id); + $this->assertEquals(1, $user->photos->count()); + $this->assertEquals($photo->id, $user->photos->first()->id); + + $book = Book::create(['title' => 'Game of Thrones']); + $photo = SqlPhoto::create(['url' => 'http://graph.facebook.com/gameofthrones/picture']); + $book->photo()->save($photo); + + $this->assertNotNull($book->photo); + $this->assertEquals($photo->id, $book->photo->id); + + $book = Book::where('title', $book->title)->get()->first(); + $this->assertNotNull($book->photo); + $this->assertEquals($photo->id, $book->photo->id); + + $photo = SqlPhoto::first(); + $this->assertEquals($photo->hasImage->name, $user->name); + } } diff --git a/tests/Models/Book.php b/tests/Models/Book.php index 70d566fe2..1a455b3b2 100644 --- a/tests/Models/Book.php +++ b/tests/Models/Book.php @@ -5,6 +5,7 @@ namespace MongoDB\Laravel\Tests\Models; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\MorphOne; use MongoDB\Laravel\Eloquent\Model as Eloquent; /** @@ -28,4 +29,9 @@ public function sqlAuthor(): BelongsTo { return $this->belongsTo(SqlUser::class, 'author_id'); } + + public function photo(): MorphOne + { + return $this->morphOne(SqlPhoto::class, 'has_image'); + } } diff --git a/tests/Models/SqlBook.php b/tests/Models/SqlBook.php index babc984eb..cf3cf27eb 100644 --- a/tests/Models/SqlBook.php +++ b/tests/Models/SqlBook.php @@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\Model as EloquentModel; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\MorphOne; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\SQLiteBuilder; use Illuminate\Support\Facades\Schema; @@ -17,16 +18,23 @@ class SqlBook extends EloquentModel { use HybridRelations; - protected $connection = 'sqlite'; - protected $table = 'books'; + protected $connection = 'sqlite'; + protected $table = 'book'; protected static $unguarded = true; - protected $primaryKey = 'title'; + protected $primaryKey = 'title'; + public $incrementing = false; + protected $casts = ['title' => 'string']; public function author(): BelongsTo { return $this->belongsTo(User::class, 'author_id'); } + public function photo(): MorphOne + { + return $this->morphOne(Photo::class, 'has_image'); + } + /** * Check if we need to run the schema. */ @@ -35,8 +43,8 @@ public static function executeSchema(): void $schema = Schema::connection('sqlite'); assert($schema instanceof SQLiteBuilder); - $schema->dropIfExists('books'); - $schema->create('books', function (Blueprint $table) { + $schema->dropIfExists('book'); + $schema->create('book', function (Blueprint $table) { $table->string('title'); $table->string('author_id')->nullable(); $table->integer('sql_user_id')->unsigned()->nullable(); diff --git a/tests/Models/SqlPhoto.php b/tests/Models/SqlPhoto.php new file mode 100644 index 000000000..384e44686 --- /dev/null +++ b/tests/Models/SqlPhoto.php @@ -0,0 +1,46 @@ +morphTo(); + } + + /** + * Check if we need to run the schema. + */ + public static function executeSchema() + { + $schema = Schema::connection('sqlite'); + assert($schema instanceof SQLiteBuilder); + + $schema->dropIfExists('photo'); + $schema->create('photo', function (Blueprint $table) { + $table->increments('id'); + $table->string('url'); + $table->string('has_image_id')->nullable(); + $table->string('has_image_type')->nullable(); + $table->timestamps(); + }); + } +} diff --git a/tests/Models/SqlRole.php b/tests/Models/SqlRole.php index 17c01e819..0fde283fe 100644 --- a/tests/Models/SqlRole.php +++ b/tests/Models/SqlRole.php @@ -18,7 +18,7 @@ class SqlRole extends EloquentModel use HybridRelations; protected $connection = 'sqlite'; - protected $table = 'roles'; + protected $table = 'role'; protected static $unguarded = true; public function user(): BelongsTo @@ -39,8 +39,8 @@ public static function executeSchema() $schema = Schema::connection('sqlite'); assert($schema instanceof SQLiteBuilder); - $schema->dropIfExists('roles'); - $schema->create('roles', function (Blueprint $table) { + $schema->dropIfExists('role'); + $schema->create('role', function (Blueprint $table) { $table->string('type'); $table->string('user_id'); $table->timestamps(); diff --git a/tests/Models/SqlUser.php b/tests/Models/SqlUser.php index 1fe11276a..1d9453839 100644 --- a/tests/Models/SqlUser.php +++ b/tests/Models/SqlUser.php @@ -11,6 +11,7 @@ use Illuminate\Database\Schema\SQLiteBuilder; use Illuminate\Support\Facades\Schema; use MongoDB\Laravel\Eloquent\HybridRelations; +use MongoDB\Laravel\Relations\MorphMany; use function assert; @@ -19,7 +20,7 @@ class SqlUser extends EloquentModel use HybridRelations; protected $connection = 'sqlite'; - protected $table = 'users'; + protected $table = 'user'; protected static $unguarded = true; public function books(): HasMany @@ -32,6 +33,11 @@ public function role(): HasOne return $this->hasOne(Role::class); } + public function photos(): MorphMany + { + return $this->morphMany(Photo::class, 'has_image'); + } + public function sqlBooks(): HasMany { return $this->hasMany(SqlBook::class); @@ -45,8 +51,8 @@ public static function executeSchema(): void $schema = Schema::connection('sqlite'); assert($schema instanceof SQLiteBuilder); - $schema->dropIfExists('users'); - $schema->create('users', function (Blueprint $table) { + $schema->dropIfExists('user'); + $schema->create('user', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->timestamps(); diff --git a/tests/Models/User.php b/tests/Models/User.php index 4e0d7294c..d4c27bb62 100644 --- a/tests/Models/User.php +++ b/tests/Models/User.php @@ -17,6 +17,8 @@ use MongoDB\Laravel\Eloquent\HybridRelations; use MongoDB\Laravel\Eloquent\MassPrunable; use MongoDB\Laravel\Eloquent\Model as Eloquent; +use MongoDB\Laravel\Relations\EmbedsMany; +use MongoDB\Laravel\Relations\MorphMany; /** * @property string $_id @@ -91,12 +93,12 @@ public function groups() return $this->belongsToMany(Group::class, 'groups', 'users', 'groups', '_id', '_id', 'groups'); } - public function photos() + public function photos(): MorphMany { return $this->morphMany(Photo::class, 'has_image'); } - public function addresses() + public function addresses(): EmbedsMany { return $this->embedsMany(Address::class); }