DatabaseEloquentBroadcastingTest.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. <?php
  2. namespace Illuminate\Tests\Integration\Database;
  3. use Illuminate\Broadcasting\BroadcastEvent;
  4. use Illuminate\Contracts\Broadcasting\Broadcaster;
  5. use Illuminate\Contracts\Broadcasting\Factory as BroadcastingFactory;
  6. use Illuminate\Database\Eloquent\BroadcastableModelEventOccurred;
  7. use Illuminate\Database\Eloquent\BroadcastsEvents;
  8. use Illuminate\Database\Eloquent\Model;
  9. use Illuminate\Database\Eloquent\SoftDeletes;
  10. use Illuminate\Database\Schema\Blueprint;
  11. use Illuminate\Support\Arr;
  12. use Illuminate\Support\Facades\Event;
  13. use Illuminate\Support\Facades\Schema;
  14. use Mockery as m;
  15. class DatabaseEloquentBroadcastingTest extends DatabaseTestCase
  16. {
  17. protected function defineDatabaseMigrationsAfterDatabaseRefreshed()
  18. {
  19. Schema::create('test_eloquent_broadcasting_users', function (Blueprint $table) {
  20. $table->increments('id');
  21. $table->string('name');
  22. $table->softDeletes();
  23. $table->timestamps();
  24. });
  25. }
  26. public function testBasicBroadcasting()
  27. {
  28. Event::fake([BroadcastableModelEventOccurred::class]);
  29. $model = new TestEloquentBroadcastUser;
  30. $model->name = 'Taylor';
  31. $model->save();
  32. Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {
  33. return $event->model instanceof TestEloquentBroadcastUser
  34. && count($event->broadcastOn()) === 1
  35. && $event->model->name === 'Taylor'
  36. && $event->broadcastOn()[0]->name == "private-Illuminate.Tests.Integration.Database.TestEloquentBroadcastUser.{$event->model->id}";
  37. });
  38. }
  39. public function testChannelRouteFormatting()
  40. {
  41. $model = new TestEloquentBroadcastUser;
  42. $this->assertEquals('Illuminate.Tests.Integration.Database.TestEloquentBroadcastUser.{testEloquentBroadcastUser}', $model->broadcastChannelRoute());
  43. }
  44. public function testBroadcastingOnModelTrashing()
  45. {
  46. Event::fake([BroadcastableModelEventOccurred::class]);
  47. $model = new SoftDeletableTestEloquentBroadcastUser;
  48. $model->name = 'Bean';
  49. $model->saveQuietly();
  50. $model->delete();
  51. Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {
  52. return $event->model instanceof SoftDeletableTestEloquentBroadcastUser
  53. && $event->event() == 'trashed'
  54. && count($event->broadcastOn()) === 1
  55. && $event->model->name === 'Bean'
  56. && $event->broadcastOn()[0]->name == "private-Illuminate.Tests.Integration.Database.SoftDeletableTestEloquentBroadcastUser.{$event->model->id}";
  57. });
  58. }
  59. public function testBroadcastingForSpecificEventsOnly()
  60. {
  61. Event::fake([BroadcastableModelEventOccurred::class]);
  62. $model = new TestEloquentBroadcastUserOnSpecificEventsOnly;
  63. $model->name = 'James';
  64. $model->save();
  65. Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {
  66. return $event->model instanceof TestEloquentBroadcastUserOnSpecificEventsOnly
  67. && $event->event() == 'created'
  68. && count($event->broadcastOn()) === 1
  69. && $event->model->name === 'James'
  70. && $event->broadcastOn()[0]->name == "private-Illuminate.Tests.Integration.Database.TestEloquentBroadcastUserOnSpecificEventsOnly.{$event->model->id}";
  71. });
  72. $model->name = 'Graham';
  73. $model->save();
  74. Event::assertNotDispatched(function (BroadcastableModelEventOccurred $event) {
  75. return $event->model instanceof TestEloquentBroadcastUserOnSpecificEventsOnly
  76. && $event->model->name === 'Graham'
  77. && $event->event() == 'updated';
  78. });
  79. }
  80. public function testBroadcastNameDefault()
  81. {
  82. Event::fake([BroadcastableModelEventOccurred::class]);
  83. $model = new TestEloquentBroadcastUser;
  84. $model->name = 'Mohamed';
  85. $model->save();
  86. Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {
  87. return $event->model instanceof TestEloquentBroadcastUser
  88. && $event->model->name === 'Mohamed'
  89. && $event->broadcastAs() === 'TestEloquentBroadcastUserCreated'
  90. && $this->assertHandldedBroadcastableEvent($event, function (array $channels, string $eventName, array $payload) {
  91. return $eventName === 'TestEloquentBroadcastUserCreated';
  92. });
  93. });
  94. }
  95. public function testBroadcastNameCanBeDefined()
  96. {
  97. Event::fake([BroadcastableModelEventOccurred::class]);
  98. $model = new TestEloquentBroadcastUserWithSpecificBroadcastName;
  99. $model->name = 'Nuno';
  100. $model->save();
  101. Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {
  102. return $event->model instanceof TestEloquentBroadcastUserWithSpecificBroadcastName
  103. && $event->model->name === 'Nuno'
  104. && $event->broadcastAs() === 'foo'
  105. && $this->assertHandldedBroadcastableEvent($event, function (array $channels, string $eventName, array $payload) {
  106. return $eventName === 'foo';
  107. });
  108. });
  109. $model->name = 'Dries';
  110. $model->save();
  111. Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {
  112. return $event->model instanceof TestEloquentBroadcastUserWithSpecificBroadcastName
  113. && $event->model->name === 'Dries'
  114. && $event->broadcastAs() === 'TestEloquentBroadcastUserWithSpecificBroadcastNameUpdated'
  115. && $this->assertHandldedBroadcastableEvent($event, function (array $channels, string $eventName, array $payload) {
  116. return $eventName === 'TestEloquentBroadcastUserWithSpecificBroadcastNameUpdated';
  117. });
  118. });
  119. }
  120. public function testBroadcastPayloadDefault()
  121. {
  122. Event::fake([BroadcastableModelEventOccurred::class]);
  123. $model = new TestEloquentBroadcastUser;
  124. $model->name = 'Nuno';
  125. $model->save();
  126. Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {
  127. return $event->model instanceof TestEloquentBroadcastUser
  128. && $event->model->name === 'Nuno'
  129. && is_null($event->broadcastWith())
  130. && $this->assertHandldedBroadcastableEvent($event, function (array $channels, string $eventName, array $payload) {
  131. return Arr::has($payload, ['model', 'connection', 'queue', 'socket']);
  132. });
  133. });
  134. }
  135. public function testBroadcastPayloadCanBeDefined()
  136. {
  137. Event::fake([BroadcastableModelEventOccurred::class]);
  138. $model = new TestEloquentBroadcastUserWithSpecificBroadcastPayload;
  139. $model->name = 'Dries';
  140. $model->save();
  141. Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {
  142. return $event->model instanceof TestEloquentBroadcastUserWithSpecificBroadcastPayload
  143. && $event->model->name === 'Dries'
  144. && $event->broadcastWith() === ['foo' => 'bar']
  145. && $this->assertHandldedBroadcastableEvent($event, function (array $channels, string $eventName, array $payload) {
  146. return Arr::has($payload, ['foo', 'socket']);
  147. });
  148. });
  149. $model->name = 'Graham';
  150. $model->save();
  151. Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {
  152. return $event->model instanceof TestEloquentBroadcastUserWithSpecificBroadcastPayload
  153. && $event->model->name === 'Graham'
  154. && is_null($event->broadcastWith())
  155. && $this->assertHandldedBroadcastableEvent($event, function (array $channels, string $eventName, array $payload) {
  156. return Arr::has($payload, ['model', 'connection', 'queue', 'socket']);
  157. });
  158. });
  159. }
  160. private function assertHandldedBroadcastableEvent(BroadcastableModelEventOccurred $event, \Closure $closure)
  161. {
  162. $broadcaster = m::mock(Broadcaster::class);
  163. $broadcaster->shouldReceive('broadcast')->once()
  164. ->withArgs(function (array $channels, string $eventName, array $payload) use ($closure) {
  165. return $closure($channels, $eventName, $payload);
  166. });
  167. $manager = m::mock(BroadcastingFactory::class);
  168. $manager->shouldReceive('connection')->once()->with(null)->andReturn($broadcaster);
  169. (new BroadcastEvent($event))->handle($manager);
  170. return true;
  171. }
  172. }
  173. class TestEloquentBroadcastUser extends Model
  174. {
  175. use BroadcastsEvents;
  176. protected $table = 'test_eloquent_broadcasting_users';
  177. }
  178. class SoftDeletableTestEloquentBroadcastUser extends Model
  179. {
  180. use BroadcastsEvents, SoftDeletes;
  181. protected $table = 'test_eloquent_broadcasting_users';
  182. }
  183. class TestEloquentBroadcastUserOnSpecificEventsOnly extends Model
  184. {
  185. use BroadcastsEvents;
  186. protected $table = 'test_eloquent_broadcasting_users';
  187. public function broadcastOn($event)
  188. {
  189. switch ($event) {
  190. case 'created':
  191. return [$this];
  192. }
  193. }
  194. }
  195. class TestEloquentBroadcastUserWithSpecificBroadcastName extends Model
  196. {
  197. use BroadcastsEvents;
  198. protected $table = 'test_eloquent_broadcasting_users';
  199. public function broadcastAs($event)
  200. {
  201. switch ($event) {
  202. case 'created':
  203. return 'foo';
  204. }
  205. }
  206. }
  207. class TestEloquentBroadcastUserWithSpecificBroadcastPayload extends Model
  208. {
  209. use BroadcastsEvents;
  210. protected $table = 'test_eloquent_broadcasting_users';
  211. public function broadcastWith($event)
  212. {
  213. switch ($event) {
  214. case 'created':
  215. return ['foo' => 'bar'];
  216. }
  217. }
  218. }