EloquentPivotEventsTest.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <?php
  2. namespace Illuminate\Tests\Integration\Database;
  3. use Illuminate\Database\Eloquent\Model;
  4. use Illuminate\Database\Eloquent\Relations\Pivot;
  5. use Illuminate\Database\Schema\Blueprint;
  6. use Illuminate\Support\Facades\Schema;
  7. class EloquentPivotEventsTest extends DatabaseTestCase
  8. {
  9. protected function setUp(): void
  10. {
  11. parent::setUp();
  12. // clear event log between requests
  13. PivotEventsTestCollaborator::$eventsCalled = [];
  14. }
  15. protected function defineDatabaseMigrationsAfterDatabaseRefreshed()
  16. {
  17. Schema::create('users', function (Blueprint $table) {
  18. $table->increments('id');
  19. $table->string('email');
  20. $table->timestamps();
  21. });
  22. Schema::create('projects', function (Blueprint $table) {
  23. $table->increments('id');
  24. $table->string('name');
  25. $table->timestamps();
  26. });
  27. Schema::create('project_users', function (Blueprint $table) {
  28. $table->integer('user_id');
  29. $table->integer('project_id');
  30. $table->text('permissions')->nullable();
  31. $table->string('role')->nullable();
  32. });
  33. }
  34. public function testPivotWillTriggerEventsToBeFired()
  35. {
  36. $user = PivotEventsTestUser::forceCreate(['email' => 'taylor@laravel.com']);
  37. $user2 = PivotEventsTestUser::forceCreate(['email' => 'ralph@ralphschindler.com']);
  38. $project = PivotEventsTestProject::forceCreate(['name' => 'Test Project']);
  39. $project->collaborators()->attach($user);
  40. $this->assertEquals(['saving', 'creating', 'created', 'saved'], PivotEventsTestCollaborator::$eventsCalled);
  41. PivotEventsTestCollaborator::$eventsCalled = [];
  42. $project->collaborators()->sync([$user2->id]);
  43. $this->assertEquals(['deleting', 'deleted', 'saving', 'creating', 'created', 'saved'], PivotEventsTestCollaborator::$eventsCalled);
  44. PivotEventsTestCollaborator::$eventsCalled = [];
  45. $project->collaborators()->sync([$user->id => ['role' => 'owner'], $user2->id => ['role' => 'contributor']]);
  46. $this->assertEquals(['saving', 'creating', 'created', 'saved', 'saving', 'updating', 'updated', 'saved'], PivotEventsTestCollaborator::$eventsCalled);
  47. PivotEventsTestCollaborator::$eventsCalled = [];
  48. $project->collaborators()->detach($user);
  49. $this->assertEquals(['deleting', 'deleted'], PivotEventsTestCollaborator::$eventsCalled);
  50. }
  51. public function testPivotWithPivotCriteriaTriggerEventsToBeFiredOnCreateUpdateNoneOnDetach()
  52. {
  53. $user = PivotEventsTestUser::forceCreate(['email' => 'taylor@laravel.com']);
  54. $user2 = PivotEventsTestUser::forceCreate(['email' => 'ralph@ralphschindler.com']);
  55. $project = PivotEventsTestProject::forceCreate(['name' => 'Test Project']);
  56. $project->contributors()->sync([$user->id, $user2->id]);
  57. $this->assertEquals(['saving', 'creating', 'created', 'saved', 'saving', 'creating', 'created', 'saved'], PivotEventsTestCollaborator::$eventsCalled);
  58. PivotEventsTestCollaborator::$eventsCalled = [];
  59. $project->contributors()->detach($user->id);
  60. $this->assertEquals([], PivotEventsTestCollaborator::$eventsCalled);
  61. }
  62. public function testCustomPivotUpdateEventHasExistingAttributes()
  63. {
  64. $_SERVER['pivot_attributes'] = false;
  65. $user = PivotEventsTestUser::forceCreate([
  66. 'email' => 'taylor@laravel.com',
  67. ]);
  68. $project = PivotEventsTestProject::forceCreate([
  69. 'name' => 'Test Project',
  70. ]);
  71. $project->collaborators()->attach($user, ['permissions' => ['foo', 'bar']]);
  72. $project->collaborators()->updateExistingPivot($user->id, ['role' => 'Lead Developer']);
  73. $this->assertEquals(
  74. [
  75. 'user_id' => '1',
  76. 'project_id' => '1',
  77. 'permissions' => '["foo","bar"]',
  78. 'role' => 'Lead Developer',
  79. ],
  80. $_SERVER['pivot_attributes']
  81. );
  82. }
  83. public function testCustomPivotUpdateEventHasDirtyCorrect()
  84. {
  85. $_SERVER['pivot_dirty_attributes'] = false;
  86. $user = PivotEventsTestUser::forceCreate([
  87. 'email' => 'taylor@laravel.com',
  88. ]);
  89. $project = PivotEventsTestProject::forceCreate([
  90. 'name' => 'Test Project',
  91. ]);
  92. $project->collaborators()->attach($user, ['permissions' => ['foo', 'bar'], 'role' => 'Developer']);
  93. $project->collaborators()->updateExistingPivot($user->id, ['role' => 'Lead Developer']);
  94. $this->assertSame(['role' => 'Lead Developer'], $_SERVER['pivot_dirty_attributes']);
  95. }
  96. }
  97. class PivotEventsTestUser extends Model
  98. {
  99. public $table = 'users';
  100. }
  101. class PivotEventsTestProject extends Model
  102. {
  103. public $table = 'projects';
  104. public function collaborators()
  105. {
  106. return $this->belongsToMany(
  107. PivotEventsTestUser::class, 'project_users', 'project_id', 'user_id'
  108. )->using(PivotEventsTestCollaborator::class);
  109. }
  110. public function contributors()
  111. {
  112. return $this->belongsToMany(PivotEventsTestUser::class, 'project_users', 'project_id', 'user_id')
  113. ->using(PivotEventsTestCollaborator::class)
  114. ->wherePivot('role', 'contributor');
  115. }
  116. }
  117. class PivotEventsTestCollaborator extends Pivot
  118. {
  119. public $table = 'project_users';
  120. protected $casts = [
  121. 'permissions' => 'json',
  122. ];
  123. public static $eventsCalled = [];
  124. public static function boot()
  125. {
  126. parent::boot();
  127. static::creating(function ($model) {
  128. static::$eventsCalled[] = 'creating';
  129. });
  130. static::created(function ($model) {
  131. static::$eventsCalled[] = 'created';
  132. });
  133. static::updating(function ($model) {
  134. static::$eventsCalled[] = 'updating';
  135. });
  136. static::updated(function ($model) {
  137. $_SERVER['pivot_attributes'] = $model->getAttributes();
  138. $_SERVER['pivot_dirty_attributes'] = $model->getDirty();
  139. static::$eventsCalled[] = 'updated';
  140. });
  141. static::saving(function ($model) {
  142. static::$eventsCalled[] = 'saving';
  143. });
  144. static::saved(function ($model) {
  145. static::$eventsCalled[] = 'saved';
  146. });
  147. static::deleting(function ($model) {
  148. static::$eventsCalled[] = 'deleting';
  149. });
  150. static::deleted(function ($model) {
  151. static::$eventsCalled[] = 'deleted';
  152. });
  153. }
  154. }