create(); Event::factory()->count(3)->create(['tenant_id' => $tenant->id]); $this->assertCount(3, $tenant->events()->get()); } public function test_tenant_has_photos_through_events(): void { $tenant = Tenant::factory()->create(); $event = Event::factory()->create(['tenant_id' => $tenant->id]); Photo::factory()->count(2)->create(['event_id' => $event->id]); $this->assertCount(2, $tenant->photos()->get()); } public function test_tenant_has_many_package_purchases(): void { $tenant = Tenant::factory()->create(); $package = Package::factory()->create(); PackagePurchase::factory()->count(2)->create([ 'tenant_id' => $tenant->id, 'package_id' => $package->id, ]); $this->assertCount(2, $tenant->purchases()->get()); } public function test_active_subscription_accessor_returns_true_when_active_package_exists(): void { $tenant = Tenant::factory()->create(); $package = Package::factory()->create(['type' => 'reseller']); TenantPackage::factory()->create([ 'tenant_id' => $tenant->id, 'package_id' => $package->id, 'active' => true, ]); $this->assertTrue($tenant->fresh()->active_subscription); } public function test_active_subscription_accessor_returns_false_without_active_package(): void { $tenant = Tenant::factory()->create(); $this->assertFalse($tenant->fresh()->active_subscription); } public function test_increment_used_events_returns_false_without_active_package(): void { $tenant = Tenant::factory()->create(); $this->assertFalse($tenant->incrementUsedEvents()); } public function test_increment_used_events_updates_active_package(): void { $tenant = Tenant::factory()->create(); $package = Package::factory()->create(['type' => 'reseller']); $tenantPackage = TenantPackage::factory()->create([ 'tenant_id' => $tenant->id, 'package_id' => $package->id, 'active' => true, 'used_events' => 1, ]); $this->assertTrue($tenant->incrementUsedEvents(2)); $this->assertEquals(3, $tenantPackage->fresh()->used_events); } public function test_consume_event_allowance_dispatches_notifications_and_updates_usage(): void { EventFacade::fake([ TenantPackageEventThresholdReached::class, TenantPackageEventLimitReached::class, ]); Config::set('package-limits.event_thresholds', [0.5]); $tenant = Tenant::factory()->create(); $package = Package::factory()->create([ 'type' => 'reseller', 'max_events_per_year' => 4, ]); $tenantPackage = TenantPackage::factory()->create([ 'tenant_id' => $tenant->id, 'package_id' => $package->id, 'active' => true, 'used_events' => 1, ]); $this->assertTrue($tenant->consumeEventAllowance()); EventFacade::assertDispatched(TenantPackageEventThresholdReached::class); EventFacade::assertNotDispatched(TenantPackageEventLimitReached::class); $tenantPackage->refresh(); $this->assertSame(2, $tenantPackage->used_events); $this->assertNotNull($tenantPackage->event_warning_sent_at); $this->assertSame(0.5, (float) $tenantPackage->event_warning_threshold); } public function test_settings_cast_to_array(): void { $tenant = Tenant::factory()->create([ 'settings' => ['theme' => 'dark', 'logo' => 'logo.png'], ]); $this->assertIsArray($tenant->settings); $this->assertSame('dark', $tenant->settings['theme']); } public function test_features_cast_to_array(): void { $tenant = Tenant::factory()->create([ 'features' => ['photo_likes' => true, 'analytics' => false], ]); $this->assertIsArray($tenant->features); $this->assertTrue($tenant->features['photo_likes']); $this->assertFalse($tenant->features['analytics']); } }