DatabaseEloquentPolymorphicIntegrationTest.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <?php
  2. namespace Illuminate\Tests\Database;
  3. use Illuminate\Database\Capsule\Manager as DB;
  4. use Illuminate\Database\Eloquent\Model as Eloquent;
  5. use PHPUnit\Framework\TestCase;
  6. class DatabaseEloquentPolymorphicIntegrationTest extends TestCase
  7. {
  8. protected function setUp(): void
  9. {
  10. $db = new DB;
  11. $db->addConnection([
  12. 'driver' => 'sqlite',
  13. 'database' => ':memory:',
  14. ]);
  15. $db->bootEloquent();
  16. $db->setAsGlobal();
  17. $this->createSchema();
  18. }
  19. /**
  20. * Setup the database schema.
  21. *
  22. * @return void
  23. */
  24. public function createSchema()
  25. {
  26. $this->schema()->create('users', function ($table) {
  27. $table->increments('id');
  28. $table->string('email')->unique();
  29. $table->timestamps();
  30. });
  31. $this->schema()->create('posts', function ($table) {
  32. $table->increments('id');
  33. $table->integer('user_id');
  34. $table->string('title');
  35. $table->text('body');
  36. $table->timestamps();
  37. });
  38. $this->schema()->create('comments', function ($table) {
  39. $table->increments('id');
  40. $table->integer('commentable_id');
  41. $table->string('commentable_type');
  42. $table->integer('user_id');
  43. $table->text('body');
  44. $table->timestamps();
  45. });
  46. $this->schema()->create('likes', function ($table) {
  47. $table->increments('id');
  48. $table->integer('likeable_id');
  49. $table->string('likeable_type');
  50. $table->timestamps();
  51. });
  52. }
  53. /**
  54. * Tear down the database schema.
  55. *
  56. * @return void
  57. */
  58. protected function tearDown(): void
  59. {
  60. $this->schema()->drop('users');
  61. $this->schema()->drop('posts');
  62. $this->schema()->drop('comments');
  63. }
  64. public function testItLoadsRelationshipsAutomatically()
  65. {
  66. $this->seedData();
  67. $like = TestLikeWithSingleWith::first();
  68. $this->assertTrue($like->relationLoaded('likeable'));
  69. $this->assertEquals(TestComment::first(), $like->likeable);
  70. }
  71. public function testItLoadsChainedRelationshipsAutomatically()
  72. {
  73. $this->seedData();
  74. $like = TestLikeWithSingleWith::first();
  75. $this->assertTrue($like->likeable->relationLoaded('commentable'));
  76. $this->assertEquals(TestPost::first(), $like->likeable->commentable);
  77. }
  78. public function testItLoadsNestedRelationshipsAutomatically()
  79. {
  80. $this->seedData();
  81. $like = TestLikeWithNestedWith::first();
  82. $this->assertTrue($like->relationLoaded('likeable'));
  83. $this->assertTrue($like->likeable->relationLoaded('owner'));
  84. $this->assertEquals(TestUser::first(), $like->likeable->owner);
  85. }
  86. public function testItLoadsNestedRelationshipsOnDemand()
  87. {
  88. $this->seedData();
  89. $like = TestLike::with('likeable.owner')->first();
  90. $this->assertTrue($like->relationLoaded('likeable'));
  91. $this->assertTrue($like->likeable->relationLoaded('owner'));
  92. $this->assertEquals(TestUser::first(), $like->likeable->owner);
  93. }
  94. public function testItLoadsNestedMorphRelationshipsOnDemand()
  95. {
  96. $this->seedData();
  97. TestPost::first()->likes()->create([]);
  98. $likes = TestLike::with('likeable.owner')->get()->loadMorph('likeable', [
  99. TestComment::class => ['commentable'],
  100. TestPost::class => 'comments',
  101. ]);
  102. $this->assertTrue($likes[0]->relationLoaded('likeable'));
  103. $this->assertTrue($likes[0]->likeable->relationLoaded('owner'));
  104. $this->assertTrue($likes[0]->likeable->relationLoaded('commentable'));
  105. $this->assertTrue($likes[1]->relationLoaded('likeable'));
  106. $this->assertTrue($likes[1]->likeable->relationLoaded('owner'));
  107. $this->assertTrue($likes[1]->likeable->relationLoaded('comments'));
  108. }
  109. public function testItLoadsNestedMorphRelationshipCountsOnDemand()
  110. {
  111. $this->seedData();
  112. TestPost::first()->likes()->create([]);
  113. TestComment::first()->likes()->create([]);
  114. $likes = TestLike::with('likeable.owner')->get()->loadMorphCount('likeable', [
  115. TestComment::class => ['likes'],
  116. TestPost::class => 'comments',
  117. ]);
  118. $this->assertTrue($likes[0]->relationLoaded('likeable'));
  119. $this->assertTrue($likes[0]->likeable->relationLoaded('owner'));
  120. $this->assertEquals(2, $likes[0]->likeable->likes_count);
  121. $this->assertTrue($likes[1]->relationLoaded('likeable'));
  122. $this->assertTrue($likes[1]->likeable->relationLoaded('owner'));
  123. $this->assertEquals(1, $likes[1]->likeable->comments_count);
  124. $this->assertTrue($likes[2]->relationLoaded('likeable'));
  125. $this->assertTrue($likes[2]->likeable->relationLoaded('owner'));
  126. $this->assertEquals(2, $likes[2]->likeable->likes_count);
  127. }
  128. /**
  129. * Helpers...
  130. */
  131. protected function seedData()
  132. {
  133. $taylor = TestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);
  134. $taylor->posts()->create(['title' => 'A title', 'body' => 'A body'])
  135. ->comments()->create(['body' => 'A comment body', 'user_id' => 1])
  136. ->likes()->create([]);
  137. }
  138. /**
  139. * Get a database connection instance.
  140. *
  141. * @return \Illuminate\Database\Connection
  142. */
  143. protected function connection()
  144. {
  145. return Eloquent::getConnectionResolver()->connection();
  146. }
  147. /**
  148. * Get a schema builder instance.
  149. *
  150. * @return \Illuminate\Database\Schema\Builder
  151. */
  152. protected function schema()
  153. {
  154. return $this->connection()->getSchemaBuilder();
  155. }
  156. }
  157. /**
  158. * Eloquent Models...
  159. */
  160. class TestUser extends Eloquent
  161. {
  162. protected $table = 'users';
  163. protected $guarded = [];
  164. public function posts()
  165. {
  166. return $this->hasMany(TestPost::class, 'user_id');
  167. }
  168. }
  169. /**
  170. * Eloquent Models...
  171. */
  172. class TestPost extends Eloquent
  173. {
  174. protected $table = 'posts';
  175. protected $guarded = [];
  176. public function comments()
  177. {
  178. return $this->morphMany(TestComment::class, 'commentable');
  179. }
  180. public function owner()
  181. {
  182. return $this->belongsTo(TestUser::class, 'user_id');
  183. }
  184. public function likes()
  185. {
  186. return $this->morphMany(TestLike::class, 'likeable');
  187. }
  188. }
  189. /**
  190. * Eloquent Models...
  191. */
  192. class TestComment extends Eloquent
  193. {
  194. protected $table = 'comments';
  195. protected $guarded = [];
  196. protected $with = ['commentable'];
  197. public function owner()
  198. {
  199. return $this->belongsTo(TestUser::class, 'user_id');
  200. }
  201. public function commentable()
  202. {
  203. return $this->morphTo();
  204. }
  205. public function likes()
  206. {
  207. return $this->morphMany(TestLike::class, 'likeable');
  208. }
  209. }
  210. class TestLike extends Eloquent
  211. {
  212. protected $table = 'likes';
  213. protected $guarded = [];
  214. public function likeable()
  215. {
  216. return $this->morphTo();
  217. }
  218. }
  219. class TestLikeWithSingleWith extends Eloquent
  220. {
  221. protected $table = 'likes';
  222. protected $guarded = [];
  223. protected $with = ['likeable'];
  224. public function likeable()
  225. {
  226. return $this->morphTo();
  227. }
  228. }
  229. class TestLikeWithNestedWith extends Eloquent
  230. {
  231. protected $table = 'likes';
  232. protected $guarded = [];
  233. protected $with = ['likeable.owner'];
  234. public function likeable()
  235. {
  236. return $this->morphTo();
  237. }
  238. }