Deploy Ladill Meet / deploy (push) Successful in 1m30s
Verify speaker tokens from Events on join, grant panelist role for linked webinars, and point bulk comms links to the attendees page instead of the JSON preview API. Co-authored-by: Cursor <cursoragent@cursor.com>
220 lines
7.4 KiB
PHP
220 lines
7.4 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Http\Middleware\EnsurePlatformSession;
|
|
use App\Models\Member;
|
|
use App\Models\Organization;
|
|
use App\Models\Room;
|
|
use App\Models\Session;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Tests\TestCase;
|
|
|
|
class EventsJoinGateTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected User $user;
|
|
|
|
protected Organization $organization;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->withoutMiddleware(EnsurePlatformSession::class);
|
|
|
|
config([
|
|
'meet.events_api_url' => 'https://events.test/api/service/v1',
|
|
'meet.events_api_key' => 'test-events-key',
|
|
]);
|
|
|
|
$this->user = User::create([
|
|
'public_id' => 'host-events-001',
|
|
'name' => 'Event Host',
|
|
'email' => 'host@example.com',
|
|
]);
|
|
|
|
$this->organization = Organization::create([
|
|
'owner_ref' => $this->user->public_id,
|
|
'name' => 'Events Org',
|
|
'slug' => 'events-org',
|
|
'timezone' => 'UTC',
|
|
'settings' => ['onboarded' => true],
|
|
]);
|
|
|
|
Member::create([
|
|
'owner_ref' => $this->user->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'user_ref' => $this->user->public_id,
|
|
'role' => 'owner',
|
|
]);
|
|
|
|
$base = rtrim((string) config('billing.api_url'), '/');
|
|
Http::fake([
|
|
$base.'/can-afford*' => Http::response(['affordable' => true]),
|
|
$base.'/debit' => Http::response(['ok' => true]),
|
|
$base.'/balance*' => Http::response(['balance_minor' => 100000]),
|
|
'https://events.test/api/service/v1/events/*/verify-registration' => Http::response([
|
|
'registration' => [
|
|
'attendee_name' => 'Registered Guest',
|
|
'attendee_email' => 'guest@example.com',
|
|
'badge_code' => 'BADGE123',
|
|
],
|
|
]),
|
|
'https://events.test/api/service/v1/events/*/verify-speaker' => Http::response([
|
|
'speaker' => [
|
|
'name' => 'Keynote Speaker',
|
|
'email' => 'speaker@example.com',
|
|
'role' => 'Keynote',
|
|
],
|
|
]),
|
|
]);
|
|
}
|
|
|
|
public function test_events_linked_webinar_shows_registration_gate_for_guest(): void
|
|
{
|
|
$room = $this->createEventsLinkedRoom('webinar');
|
|
|
|
$this->get('/r/'.$room->uuid)
|
|
->assertOk()
|
|
->assertSee('Register for event', false)
|
|
->assertSee('Already registered?', false)
|
|
->assertDontSee('How should we show your name?', false);
|
|
}
|
|
|
|
public function test_badge_verification_leads_to_display_name_screen(): void
|
|
{
|
|
$room = $this->createEventsLinkedRoom('webinar');
|
|
|
|
$this->post('/r/'.$room->uuid.'/verify-badge', ['badge_code' => 'BADGE123'])
|
|
->assertRedirect(route('meet.join', $room));
|
|
|
|
$this->get('/r/'.$room->uuid)
|
|
->assertOk()
|
|
->assertSee('How should we show your name?', false)
|
|
->assertSee('value="Registered Guest"', false)
|
|
->assertDontSee('Register for event', false);
|
|
}
|
|
|
|
public function test_verified_guest_can_join_live_webinar_with_display_name_only(): void
|
|
{
|
|
$room = $this->createEventsLinkedRoom('webinar', [
|
|
'settings' => array_merge(config('meet.default_settings'), [
|
|
'join_before_host' => true,
|
|
'waiting_room' => false,
|
|
]),
|
|
]);
|
|
|
|
$session = Session::create([
|
|
'owner_ref' => $this->user->public_id,
|
|
'room_id' => $room->id,
|
|
'media_room_name' => 'room-'.$room->uuid,
|
|
'status' => 'live',
|
|
'started_at' => now(),
|
|
]);
|
|
$room->update(['status' => 'live']);
|
|
|
|
$this->post('/r/'.$room->uuid.'/verify-badge', ['badge_code' => 'BADGE123'])
|
|
->assertRedirect(route('meet.join', $room));
|
|
|
|
$this->post('/r/'.$room->uuid.'/enter', [
|
|
'display_name' => 'Registered Guest',
|
|
])->assertRedirect(route('meet.room', $session));
|
|
|
|
$this->assertDatabaseHas('meet_participants', [
|
|
'session_id' => $session->id,
|
|
'display_name' => 'Registered Guest',
|
|
'email' => 'guest@example.com',
|
|
'role' => 'attendee',
|
|
]);
|
|
}
|
|
|
|
public function test_badge_query_param_auto_verifies_on_join_url(): void
|
|
{
|
|
$room = $this->createEventsLinkedRoom('webinar');
|
|
|
|
$this->get('/r/'.$room->uuid.'?badge=BADGE123')
|
|
->assertRedirect(route('meet.join', $room));
|
|
|
|
$this->get('/r/'.$room->uuid)
|
|
->assertOk()
|
|
->assertSee('How should we show your name?', false);
|
|
}
|
|
|
|
public function test_host_skips_registration_gate(): void
|
|
{
|
|
$room = $this->createEventsLinkedRoom('webinar');
|
|
|
|
$this->actingAs($this->user)
|
|
->get('/r/'.$room->uuid)
|
|
->assertOk()
|
|
->assertSee('Joining as', false)
|
|
->assertDontSee('Register for event', false);
|
|
}
|
|
|
|
public function test_speaker_token_skips_registration_gate_and_grants_panelist_role(): void
|
|
{
|
|
$room = $this->createEventsLinkedRoom('webinar', [
|
|
'settings' => array_merge(config('meet.default_settings'), [
|
|
'join_before_host' => true,
|
|
'waiting_room' => false,
|
|
]),
|
|
]);
|
|
|
|
$session = Session::create([
|
|
'owner_ref' => $this->user->public_id,
|
|
'room_id' => $room->id,
|
|
'media_room_name' => 'room-'.$room->uuid,
|
|
'status' => 'live',
|
|
'started_at' => now(),
|
|
]);
|
|
$room->update(['status' => 'live']);
|
|
|
|
$this->get('/r/'.$room->uuid.'?speaker=speaker-token-123')
|
|
->assertRedirect(route('meet.join', $room));
|
|
|
|
$this->get('/r/'.$room->uuid)
|
|
->assertOk()
|
|
->assertSee('How should we show your name?', false)
|
|
->assertDontSee('Register for event', false);
|
|
|
|
$this->post('/r/'.$room->uuid.'/enter', [
|
|
'display_name' => 'Keynote Speaker',
|
|
])->assertRedirect(route('meet.room', $session));
|
|
|
|
$this->assertDatabaseHas('meet_participants', [
|
|
'session_id' => $session->id,
|
|
'display_name' => 'Keynote Speaker',
|
|
'email' => 'speaker@example.com',
|
|
'role' => 'panelist',
|
|
]);
|
|
}
|
|
|
|
/** @param array<string, mixed> $overrides */
|
|
protected function createEventsLinkedRoom(string $type, array $overrides = []): Room
|
|
{
|
|
return Room::create(array_merge([
|
|
'owner_ref' => $this->user->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'host_user_ref' => $this->user->public_id,
|
|
'title' => 'Linked session',
|
|
'type' => $type,
|
|
'status' => 'scheduled',
|
|
'scheduled_at' => now()->addDay(),
|
|
'timezone' => 'UTC',
|
|
'settings' => config('meet.default_settings'),
|
|
'source' => [
|
|
'app' => 'events',
|
|
'entity_type' => 'virtual_session',
|
|
'entity_id' => 'vs-test',
|
|
'event_id' => '42',
|
|
'event_title' => 'Summit 2026',
|
|
'short_code' => 'summit26',
|
|
'registration_url' => 'https://ladl.link/summit26',
|
|
],
|
|
], $overrides));
|
|
}
|
|
}
|