Files
ladill-events/tests/Feature/EventMailCalendarSyncTest.php
T
isaaccladandCursor a00f032b5b
Deploy Ladill Events / deploy (push) Successful in 52s
Fix Events mail calendar sync when virtual sessions lack ids.
Generate session ids before upserting and fall back to the main event date so August events reach Mail calendar.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-04 12:27:48 +00:00

154 lines
5.6 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\QrCode;
use App\Models\User;
use App\Services\Events\EventMailCalendarSyncService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Http;
use Tests\TestCase;
class EventMailCalendarSyncTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
config([
'mail_calendar.api_url' => 'https://mail.ladill.com/api/service/v1',
'mail_calendar.api_key' => 'test-events-mail-key',
'identity.api_url' => 'https://ladill.com/api',
'identity.api_key' => 'test-identity-key',
]);
Http::fake([
'https://ladill.com/api/identity/mailbox-link*' => Http::response(['data' => []]),
'https://mail.ladill.com/*' => Http::response(['data' => ['id' => 55]], 201),
]);
}
public function test_in_person_event_syncs_to_mail_calendar(): void
{
$owner = User::factory()->create(['public_id' => 'usr-cal-1', 'email' => 'host@example.com']);
$event = $this->makeEvent($owner, [
'format' => 'in_person',
'name' => 'Town hall',
'starts_at' => now()->addWeek()->toDateString(),
'ends_at' => now()->addWeek()->addHours(3)->toDateString(),
]);
app(EventMailCalendarSyncService::class)->sync($event, $owner);
Http::assertSent(function ($request) use ($event) {
return str_contains($request->url(), '/calendar/events')
&& $request['mailbox_email'] === 'host@example.com'
&& $request['external_ref'] === 'events:'.$event->id
&& $request['title'] === 'Town hall';
});
$this->assertSame(
['events:'.$event->id => 55],
data_get($event->fresh()->payload, 'calendar_sync.items'),
);
}
public function test_virtual_session_syncs_one_entry_with_meet_join_url(): void
{
$owner = User::factory()->create(['public_id' => 'usr-cal-3', 'email' => 'host@example.com']);
$event = $this->makeEvent($owner, [
'format' => 'virtual',
'name' => 'Product launch',
'starts_at' => now()->addWeek()->toDateString(),
'virtual_sessions' => [[
'id' => 'vs-main',
'title' => 'Main stage',
'scheduled_at' => now()->addWeek()->toIso8601String(),
'duration_minutes' => 90,
'join_url' => 'https://meet.ladill.com/join/demo',
]],
]);
app(EventMailCalendarSyncService::class)->sync($event, $owner);
Http::assertSent(function ($request) use ($event) {
return str_contains($request->url(), '/calendar/events')
&& $request['external_ref'] === 'events:'.$event->id.':session:vs-main'
&& $request['join_url'] === 'https://meet.ladill.com/join/demo';
});
$this->assertSame(1, collect(Http::recorded())->filter(
fn (array $pair) => str_contains($pair[0]->url(), '/calendar/events'),
)->count());
}
public function test_virtual_session_without_id_still_syncs_to_mail_calendar(): void
{
$owner = User::factory()->create(['public_id' => 'usr-cal-4', 'email' => 'host@example.com']);
$event = $this->makeEvent($owner, [
'format' => 'virtual',
'name' => 'NextGen Summit 2026',
'starts_at' => '2026-08-26',
'ends_at' => '2026-08-27',
'virtual_sessions' => [[
'id' => null,
'title' => 'NextGen Summit',
'scheduled_at' => '2026-08-26',
'duration_minutes' => 180,
]],
]);
app(EventMailCalendarSyncService::class)->sync($event, $owner);
Http::assertSent(function ($request) use ($event) {
return str_contains($request->url(), '/calendar/events')
&& str_starts_with((string) $request['external_ref'], 'events:'.$event->id.':session:vs-')
&& $request['title'] === 'NextGen Summit';
});
$this->assertNotEmpty(data_get($event->fresh()->payload, 'calendar_sync.items'));
}
public function test_uses_linked_mailbox_when_available(): void
{
Http::fake([
'https://mail.ladill.com/*' => Http::response(['data' => ['id' => 77]], 201),
]);
$this->mock(\App\Services\Identity\IdentityClient::class, function ($mock) {
$mock->shouldReceive('mailboxLinkStatus')
->once()
->andReturn(['linked_mailbox' => 'owner@customdomain.com']);
});
$owner = User::factory()->create(['public_id' => 'usr-cal-2', 'email' => 'sso@ladill.com']);
$event = $this->makeEvent($owner, [
'format' => 'in_person',
'name' => 'Gala',
'starts_at' => now()->addWeek()->toDateString(),
]);
app(EventMailCalendarSyncService::class)->sync($event, $owner);
Http::assertSent(function ($request) {
return str_contains($request->url(), '/calendar/events')
&& ($request['mailbox_email'] ?? '') === 'owner@customdomain.com';
});
}
/** @param array<string, mixed> $content */
private function makeEvent(User $owner, array $content): QrCode
{
return QrCode::create([
'user_id' => $owner->id,
'short_code' => 'evt-cal-'.uniqid(),
'type' => QrCode::TYPE_EVENT,
'label' => (string) ($content['name'] ?? 'Event'),
'payload' => ['content' => $content, 'style' => []],
'is_active' => true,
]);
}
}