Files
portal/app/tests/Feature/Sales/SalesWarmingStateApiTest.php
T

65 lines
3.0 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
use App\Models\SalesAdAudienceFirm;
use App\Models\SalesAdAudienceWarmingEpisode;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\Concerns\SharesSupplierPdo;
/**
* B6: read-API состояния прогрева для внешней службы «Поиск клиентов» (finder).
*
* POST /api/sales/integration/warming-state { inns: [...] } (сервис-токен) →
* { data: { <inn>: {active, channels:{code:{live,count}}} } } — та же форма значков
* витрины, что в воронке (кусок B), считанная из летописи эпизодов, но матч фирм по
* firm_inn. finder-сторона (колонки «Греются/Прогреты») — в самой Python-службе, вне репо.
*
* SharesSupplierPdo обязателен: фирмы/эпизоды на pgsql_supplier.
* План: docs/superpowers/plans/2026-07-23-progrev-vitrina-kusok-B.md Task B6.
*/
uses(DatabaseTransactions::class, SharesSupplierPdo::class);
beforeEach(function () {
config(['sales.integration_token' => 'TESTTOKEN']);
});
it('без токена → 401', function () {
$this->postJson('/api/sales/integration/warming-state', ['inns' => ['7700000001']])
->assertUnauthorized();
});
it('отдаёт состояние прогрева по ИНН из летописи (live/count)', function () {
$firm = SalesAdAudienceFirm::create([
'firm_name' => 'Гарант', 'firm_inn' => '7700000001', 'warmup_started_at' => now(),
]);
// Яндекс — открытый эпизод (идёт сейчас); СМС — два закрытых события (×2).
SalesAdAudienceWarmingEpisode::create(['firm_id' => $firm->id, 'channel' => 'yandex', 'started_at' => now()]);
foreach ([now()->subDays(3), now()] as $t) {
SalesAdAudienceWarmingEpisode::create(['firm_id' => $firm->id, 'channel' => 'sms', 'started_at' => $t, 'ended_at' => $t]);
}
$w = $this->postJson('/api/sales/integration/warming-state', ['inns' => ['7700000001']], ['X-Sales-Token' => 'TESTTOKEN'])
->assertOk()
->json('data.7700000001');
expect($w['active'])->toBeTrue()
->and($w['channels']['yandex']['live'])->toBeTrue()
->and($w['channels']['yandex']['count'])->toBe(1)
->and($w['channels']['sms']['count'])->toBe(2)
->and($w['channels']['sms']['live'])->toBeFalse();
});
it('неизвестный ИНН → пустой прогрев', function () {
$res = $this->postJson('/api/sales/integration/warming-state', ['inns' => ['9999999999']], ['X-Sales-Token' => 'TESTTOKEN'])
->assertOk();
expect($res->json('data.9999999999.active'))->toBeFalse()
->and($res->json('data.9999999999.channels'))->toBe([]);
});
it('валидация: inns обязателен непустой массив → 422', function () {
$this->postJson('/api/sales/integration/warming-state', [], ['X-Sales-Token' => 'TESTTOKEN'])
->assertStatus(422);
});