driver(), which reads * config('broadcasting.default') and builds its OWN instance — a container * binding for BroadcasterContract is a separate, unrelated seam that * driver() never consults. No live Reverb server is needed: auth() is pure * PHP — channel authorization is an HMAC signature computed locally, never a * call over the network. */ function bindRealBroadcaster(): void { config()->set('broadcasting.default', 'reverb'); config()->set('broadcasting.connections.reverb.key', 'test-key'); config()->set('broadcasting.connections.reverb.secret', 'test-secret'); config()->set('broadcasting.connections.reverb.app_id', 'test-app-id'); config()->set('broadcasting.connections.reverb.options', [ 'host' => '127.0.0.1', 'port' => 6001, 'scheme' => 'http', 'useTLS' => false, ]); // routes/channels.php ran once already, at boot, registering admin.runs // against whichever broadcaster 'null' (this suite's forced default) // resolved to at the time. Switching the default config above builds a // brand new driver instance on next use — it does not retroactively // register anything on it. Re-requiring the routes file does. require base_path('routes/channels.php'); } function authorizeAdminRunsChannel() { return test()->post('/broadcasting/auth', [ 'channel_name' => 'private-admin.runs', 'socket_id' => '1234.1234', ]); } it('lets an operator authorize the console live-feed channel on the operator guard', function () { bindRealBroadcaster(); $operator = Operator::factory()->role('Owner')->create(); $this->actingAs($operator, 'operator'); // actingAs() also flips Auth's DEFAULT guard to 'operator' (Auth:: // shouldUse()) — nothing does that for a real request to this route in // production (/broadcasting/auth carries only the 'web' middleware // group, never auth:operator,web), so left alone this would make the // bare/default guard resolve the operator too and mask exactly the bug // this test exists to catch. Reset so only the 'operator' GUARD INSTANCE // (already given its user by actingAs() above, untouched by shouldUse()) // has the operator signed in — matching a real session. Auth::shouldUse('web'); authorizeAdminRunsChannel()->assertOk(); }); it('refuses a guest on the console live-feed channel', function () { bindRealBroadcaster(); authorizeAdminRunsChannel()->assertForbidden(); }); it('refuses a signed-in portal customer who is not an operator', function () { bindRealBroadcaster(); $user = User::factory()->create(); $this->actingAs($user); // Signed in on 'web', not 'operator' — retrieveUser() now finds THIS // user (guards => ['operator', 'web']) and reaches the channel's own // callback, which must still refuse them: they hold no operator role. authorizeAdminRunsChannel()->assertForbidden(); });