Fix guest demo UX and enforce guest limits
This commit is contained in:
@@ -4,6 +4,7 @@ namespace Tests\Feature;
|
||||
|
||||
use App\Enums\PhotoLiveStatus;
|
||||
use App\Models\Event;
|
||||
use App\Models\EventJoinTokenEvent;
|
||||
use App\Models\EventPackage;
|
||||
use App\Models\GuestPolicySetting;
|
||||
use App\Models\MediaStorageTarget;
|
||||
@@ -223,6 +224,44 @@ class GuestJoinTokenFlowTest extends TestCase
|
||||
->assertJsonPath('demo_read_only', true);
|
||||
}
|
||||
|
||||
public function test_guest_limit_counts_unique_devices(): void
|
||||
{
|
||||
$event = $this->createPublishedEvent();
|
||||
$package = Package::factory()->endcustomer()->create([
|
||||
'max_guests' => 2,
|
||||
]);
|
||||
|
||||
$eventPackage = EventPackage::create([
|
||||
'event_id' => $event->id,
|
||||
'package_id' => $package->id,
|
||||
'purchased_price' => $package->price,
|
||||
'purchased_at' => now(),
|
||||
'used_photos' => 0,
|
||||
'used_guests' => 0,
|
||||
'gallery_expires_at' => now()->addDays(7),
|
||||
]);
|
||||
|
||||
$token = $this->tokenService->createToken($event);
|
||||
|
||||
$this->withHeader('X-Device-Id', 'device-guest')
|
||||
->getJson("/api/v1/events/{$token->token}")
|
||||
->assertOk();
|
||||
|
||||
$this->assertSame(1, $eventPackage->refresh()->used_guests);
|
||||
|
||||
$this->withHeader('X-Device-Id', 'device-guest')
|
||||
->getJson("/api/v1/events/{$token->token}")
|
||||
->assertOk();
|
||||
|
||||
$this->assertSame(1, $eventPackage->refresh()->used_guests);
|
||||
|
||||
$this->withHeader('X-Device-Id', 'device-guest-2')
|
||||
->getJson("/api/v1/events/{$token->token}")
|
||||
->assertOk();
|
||||
|
||||
$this->assertSame(2, $eventPackage->refresh()->used_guests);
|
||||
}
|
||||
|
||||
public function test_guest_event_response_includes_live_show_settings(): void
|
||||
{
|
||||
$event = $this->createPublishedEvent();
|
||||
@@ -241,6 +280,44 @@ class GuestJoinTokenFlowTest extends TestCase
|
||||
->assertJsonPath('live_show.moderation_mode', 'manual');
|
||||
}
|
||||
|
||||
public function test_guest_join_blocks_new_devices_after_grace_limit(): void
|
||||
{
|
||||
$event = $this->createPublishedEvent();
|
||||
$package = Package::factory()->endcustomer()->create([
|
||||
'max_guests' => 1,
|
||||
]);
|
||||
|
||||
EventPackage::create([
|
||||
'event_id' => $event->id,
|
||||
'package_id' => $package->id,
|
||||
'purchased_price' => $package->price,
|
||||
'purchased_at' => now(),
|
||||
'used_photos' => 0,
|
||||
'used_guests' => 11,
|
||||
'gallery_expires_at' => now()->addDays(7),
|
||||
]);
|
||||
|
||||
$token = $this->tokenService->createToken($event);
|
||||
|
||||
$this->withHeader('X-Device-Id', 'new-device')
|
||||
->getJson("/api/v1/events/{$token->token}")
|
||||
->assertStatus(402)
|
||||
->assertJsonPath('error.code', 'guest_limit_exceeded');
|
||||
|
||||
EventJoinTokenEvent::create([
|
||||
'event_join_token_id' => $token->id,
|
||||
'event_id' => $event->id,
|
||||
'tenant_id' => $event->tenant_id,
|
||||
'event_type' => 'access_granted',
|
||||
'device_id' => 'known-device',
|
||||
'occurred_at' => now(),
|
||||
]);
|
||||
|
||||
$this->withHeader('X-Device-Id', 'known-device')
|
||||
->getJson("/api/v1/events/{$token->token}")
|
||||
->assertOk();
|
||||
}
|
||||
|
||||
public function test_guest_cannot_upload_photo_with_demo_token(): void
|
||||
{
|
||||
Storage::fake('public');
|
||||
|
||||
@@ -161,6 +161,36 @@ class PackageLimitEvaluatorTest extends TestCase
|
||||
$this->assertTrue($summary['can_add_guests']);
|
||||
}
|
||||
|
||||
public function test_guest_limits_apply_grace_buffer_before_blocking(): void
|
||||
{
|
||||
Config::set('package-limits.guest_grace', 10);
|
||||
|
||||
$package = Package::factory()->endcustomer()->create([
|
||||
'max_guests' => 5,
|
||||
]);
|
||||
|
||||
$tenant = Tenant::factory()->create();
|
||||
$event = Event::factory()->for($tenant)->create();
|
||||
|
||||
$eventPackage = EventPackage::create([
|
||||
'event_id' => $event->id,
|
||||
'package_id' => $package->id,
|
||||
'purchased_price' => $package->price,
|
||||
'purchased_at' => now(),
|
||||
'used_photos' => 0,
|
||||
'used_guests' => 5,
|
||||
'gallery_expires_at' => now()->addDays(7),
|
||||
])->fresh(['package']);
|
||||
|
||||
$summary = $this->evaluator->summarizeEventPackage($eventPackage);
|
||||
$this->assertSame('warning', $summary['guests']['state']);
|
||||
|
||||
$eventPackage->update(['used_guests' => 15]);
|
||||
|
||||
$summary = $this->evaluator->summarizeEventPackage($eventPackage->fresh(['package']));
|
||||
$this->assertSame('limit_reached', $summary['guests']['state']);
|
||||
}
|
||||
|
||||
public function test_assess_photo_upload_respects_extra_limits(): void
|
||||
{
|
||||
$package = Package::factory()->endcustomer()->create([
|
||||
|
||||
@@ -134,14 +134,14 @@ class PackageUsageTrackerTest extends TestCase
|
||||
'purchased_price' => $package->price,
|
||||
'purchased_at' => now(),
|
||||
'used_photos' => 0,
|
||||
'used_guests' => 2,
|
||||
'used_guests' => 12,
|
||||
'gallery_expires_at' => now()->addDays(7),
|
||||
])->fresh(['package']);
|
||||
|
||||
/** @var PackageUsageTracker $tracker */
|
||||
$tracker = app(PackageUsageTracker::class);
|
||||
|
||||
$tracker->recordGuestUsage($eventPackage, 1, 1);
|
||||
$tracker->recordGuestUsage($eventPackage, 11, 1);
|
||||
|
||||
EventFacade::assertDispatched(EventPackageGuestLimitReached::class);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user