create([ 'tenant_id' => $tenantId, 'status' => Campaign::STATUS_LAUNCHED, 'ad_text' => 'Приходите к нам в канал', 'ad_link' => 'https://t.me/example_channel', 'ord_category' => 'Размещение рекламы', 'budget_cap_rub' => '1000.00', 'audience_kind' => Campaign::AUDIENCE_LIST, 'planned_count' => 2, 'estimated_cost_rub' => '0.00', 'created_by' => 1, ]); } it('одобрение шлёт in-app всем активным юзерам тенанта с текстом «одобрена/запущена»', function () { $tenant = Tenant::factory()->create(); $u1 = User::factory()->create(['tenant_id' => $tenant->id, 'is_active' => true]); $u2 = User::factory()->create(['tenant_id' => $tenant->id, 'is_active' => true]); $campaign = tgApproveCampaign($tenant->id); app(NotificationService::class)->notifyTelegramCampaignApproved($tenant, $campaign); expect(InAppNotification::where('user_id', $u1->id)->exists())->toBeTrue() ->and(InAppNotification::where('user_id', $u2->id)->exists())->toBeTrue(); $notif = InAppNotification::where('user_id', $u1->id)->first(); expect($notif->title)->toContain('одобрена') ->and($notif->body)->toContain('показы пошли'); }); it('уведомление об одобрении доходит даже без включённых настроек уведомлений', function () { $tenant = Tenant::factory()->create(); // Дефолтные настройки фабрики НЕ содержат события tg_campaign_approved — // проверяем, что уведомление доходит без pref-гейта. $user = User::factory()->create(['tenant_id' => $tenant->id, 'is_active' => true]); $campaign = tgApproveCampaign($tenant->id); app(NotificationService::class)->notifyTelegramCampaignApproved($tenant, $campaign); expect(InAppNotification::where('user_id', $user->id)->exists())->toBeTrue(); }); it('неактивный пользователь уведомление об одобрении НЕ получает', function () { $tenant = Tenant::factory()->create(); $user = User::factory()->create(['tenant_id' => $tenant->id, 'is_active' => false]); $campaign = tgApproveCampaign($tenant->id); app(NotificationService::class)->notifyTelegramCampaignApproved($tenant, $campaign); // 🪤 Считаем уведомления ИМЕННО этого пользователя, а не всю таблицу целиком. // Глобальный `count()` проходил в одиночку и падал в полном прогоне: любая строка, // пережившая соседний тест, засчитывалась нам как «уведомление всё-таки ушло». expect(InAppNotification::where('user_id', $user->id)->count())->toBe(0); }); it('изоляция тенанта: чужой активный юзер уведомление НЕ получает', function () { $tenant = Tenant::factory()->create(); $tenantB = Tenant::factory()->create(); $foreign = User::factory()->create(['tenant_id' => $tenantB->id, 'is_active' => true]); $campaign = tgApproveCampaign($tenant->id); app(NotificationService::class)->notifyTelegramCampaignApproved($tenant, $campaign); expect(InAppNotification::where('user_id', $foreign->id)->exists())->toBeFalse(); });