Files
portal/app/tests/Feature/ClientTg/ManualFlowTest.php
T

72 lines
3.4 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
use App\Jobs\ClientTg\RunTelegramCampaignJob;
use App\Models\ClientTg\Campaign;
use App\Models\Tenant;
use App\Models\User;
use App\Services\ClientTg\RobotResult;
use App\Services\ClientTg\TelegramRobotRunner;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Queue;
/**
* Ручной сквозной сценарий в песочнице (план §Сессия 3, задача 3.4):
* создать (API) → запустить (API) → джоб (робот ЗАМОКАН, mode:draft) →
* статус draft_ready + matched виден клиенту в API.
*
* Робот кабинета МТС не трогаем (замокан). Синтетические номера 7999… — реальные НИКОГДА.
*/
uses(RefreshDatabase::class);
beforeEach(function () {
$this->tenant = Tenant::factory()->create();
$this->user = User::factory()->create(['tenant_id' => $this->tenant->id]);
$this->actingAs($this->user);
config(['client_tg.sandbox' => true]);
});
it('песочница: создать → запустить → робот-черновик → draft_ready + matched виден в API', function () {
Queue::fake();
// Робот замокан: черновик готов, нашлось 2 совпадения в кабинете МТС.
$mock = Mockery::mock(TelegramRobotRunner::class);
$mock->shouldReceive('run')->once()->andReturn(new RobotResult(ok: true, matched: 2));
app()->instance(TelegramRobotRunner::class, $mock);
// 1. Клиент создаёт черновик из списка своих номеров.
$create = $this->postJson('/api/telegram/campaigns', [
'ad_text' => 'Заходите в наш канал',
'ad_link' => 'https://t.me/example_channel',
'audience_kind' => 'list',
'budget_cap_rub' => '1000.00',
'phones' => ['79990000001', '79990000002'],
]);
$create->assertCreated()->assertJsonPath('status', Campaign::STATUS_DRAFT);
$id = $create->json('id');
expect($create->json('planned_count'))->toBe(2);
// 2. Клиент жмёт «Запустить» — кампания в очереди, джоб поставлен.
$this->postJson("/api/telegram/campaigns/{$id}/launch")
->assertOk()
->assertJsonPath('status', Campaign::STATUS_QUEUED);
Queue::assertPushed(RunTelegramCampaignJob::class);
// 3. Отрабатывает воркер очереди (робот замокан) — доводит до черновика.
// Зовём handle через контейнер: под Queue::fake() dispatchSync не выполняется,
// а нам нужен реальный прогон джоба с замоканным роботом.
app()->call([new RunTelegramCampaignJob($id, $this->tenant->id), 'handle']);
// 4. Клиент видит в кабинете: черновик готов, совпадений — 2.
$this->getJson("/api/telegram/campaigns/{$id}")
->assertOk()
->assertJsonPath('campaign.status', Campaign::STATUS_DRAFT_READY)
->assertJsonPath('campaign.matched_count', 2);
// Список тоже отражает финальный статус.
$index = $this->getJson('/api/telegram/campaigns')->assertOk();
expect(collect($index->json('campaigns'))->firstWhere('id', $id)['status'])
->toBe(Campaign::STATUS_DRAFT_READY);
});