'https://ladill.com/api/billing', 'billing.api_key' => 'events-billing-key', 'events.pro.enabled' => true, 'events.pro.price_minor' => 4900, 'events.plans.pro.price_minor' => 4900, 'events.plans.enterprise.price_minor' => 14900, 'events.free.max_live_events' => 2, 'events.free.max_tickets_per_month' => 100, ]); } public function test_free_plan_respects_live_event_and_registration_caps(): void { $user = User::factory()->create([ 'public_id' => (string) Str::uuid(), 'email' => 'demo-free@ladill.com', ]); $this->artisan('demo:seed', [ 'identity' => $user->email, '--plan' => 'free', ])->assertSuccessful(); $this->assertSame('free', app(SubscriptionService::class)->planKey($user)); $this->assertNull(ProSubscription::query()->where('user_id', $user->id)->first()); $events = QrCode::query() ->where('user_id', $user->id) ->where('type', QrCode::TYPE_EVENT) ->count(); $regs = QrEventRegistration::query()->where('user_id', $user->id)->count(); $this->assertLessThanOrEqual(2, $events); $this->assertGreaterThan(0, $events); $this->assertLessThan(100, $regs); $this->assertSame(0, QrCode::query()->where('user_id', $user->id)->where('type', QrCode::TYPE_ITINERARY)->count()); } public function test_pro_plan_assigns_subscription_and_seeds_paid_payloads(): void { $user = User::factory()->create([ 'public_id' => (string) Str::uuid(), 'email' => 'demo-pro@ladill.com', ]); $this->artisan('demo:seed', [ 'identity' => $user->public_id, '--plan' => 'pro', ])->assertSuccessful(); $this->assertSame('pro', app(SubscriptionService::class)->planKey($user)); $sub = ProSubscription::query()->where('user_id', $user->id)->first(); $this->assertNotNull($sub); $this->assertTrue($sub->current_period_end->isFuture()); $this->assertFalse($sub->auto_renew); $events = QrCode::query() ->where('user_id', $user->id) ->where('type', QrCode::TYPE_EVENT) ->get(); $this->assertGreaterThan(2, $events->count()); $this->assertSame('ticketing', $events->first()->content()['mode'] ?? null); $this->assertGreaterThan(0, QrCode::query()->where('user_id', $user->id)->where('type', QrCode::TYPE_ITINERARY)->count()); $this->assertGreaterThan(50, QrEventRegistration::query()->where('user_id', $user->id)->count()); } public function test_command_is_idempotent_and_reset_reseeds(): void { $user = User::factory()->create([ 'public_id' => (string) Str::uuid(), 'email' => 'demo-enterprise@ladill.com', ]); $this->artisan('demo:seed', ['identity' => $user->email, '--plan' => 'enterprise'])->assertSuccessful(); $firstEvents = QrCode::query()->where('user_id', $user->id)->where('type', QrCode::TYPE_EVENT)->count(); $firstRegs = QrEventRegistration::query()->where('user_id', $user->id)->count(); $this->artisan('demo:seed', ['identity' => $user->email, '--plan' => 'enterprise'])->assertSuccessful(); $this->assertSame($firstEvents, QrCode::query()->where('user_id', $user->id)->where('type', QrCode::TYPE_EVENT)->count()); $this->assertSame($firstRegs, QrEventRegistration::query()->where('user_id', $user->id)->count()); $this->artisan('demo:seed', [ 'identity' => $user->email, '--plan' => 'free', '--reset' => true, ])->assertSuccessful(); $this->assertSame('free', app(SubscriptionService::class)->planKey($user->fresh())); $this->assertLessThanOrEqual(2, QrCode::query()->where('user_id', $user->id)->where('type', QrCode::TYPE_EVENT)->count()); $this->assertLessThan(100, QrEventRegistration::query()->where('user_id', $user->id)->count()); } public function test_creates_mirror_when_enough_identity_options_given(): void { $publicId = (string) Str::uuid(); $this->artisan('demo:seed', [ 'identity' => 'demo-new@ladill.com', '--plan' => 'free', '--public-id' => $publicId, '--email' => 'demo-new@ladill.com', '--name' => 'Demo New', ])->assertSuccessful(); $user = User::query()->where('public_id', $publicId)->first(); $this->assertNotNull($user); $this->assertSame('demo-new@ladill.com', $user->email); } public function test_pro_plan_uses_demo_world_attendees_and_speakers(): void { $user = User::factory()->create([ 'public_id' => (string) Str::uuid(), 'email' => 'demo-pro@ladill.com', ]); $this->artisan('demo:seed', [ 'identity' => $user->email, '--plan' => 'pro', ])->assertSuccessful(); $registration = QrEventRegistration::query() ->where('user_id', $user->id) ->where('attendee_name', 'Ama Mensah') ->first(); $this->assertNotNull($registration); $this->assertSame(DemoWorld::personByKey('ama-mensah')['email'], $registration->attendee_email); $this->assertSame(DemoWorld::personByKey('ama-mensah')['phone'], $registration->attendee_phone); $programme = QrCode::query() ->where('user_id', $user->id) ->where('type', QrCode::TYPE_ITINERARY) ->first(); $this->assertNotNull($programme); $host = $programme->content()['days'][0]['items'][0]['host'] ?? null; $this->assertSame('Ama Mensah', $host); } }