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

95 lines
4.3 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
use App\Models\SalesAdAudienceFirm;
use App\Models\SalesAdAudienceWarmingEpisode;
use App\Models\SalesUser;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\Concerns\SharesSupplierPdo;
/**
* B2: «Греть»/«Убрать» на экране площадки пишут летопись эпизодов прогрева.
*
* open при loaded→warming (toggle on / warm), close при warming→удалено (toggle off /
* unassign). open идемпотентен — повторное «Греть» уже греющейся фирмы не плодит
* второй открытый эпизод (защита в WarmingEpisodeRecorder). Хелперы локальные
* (wiring_*) — тест самодостаточен и падает по нужной причине при запуске в одиночку.
*/
uses(DatabaseTransactions::class, SharesSupplierPdo::class);
function wiringFirm(): SalesAdAudienceFirm
{
return SalesAdAudienceFirm::create(['firm_name' => 'Тест', 'warmup_started_at' => now()]);
}
function wiringHead(): SalesUser
{
return SalesUser::create([
'name' => 'Начальник '.uniqid(),
'email' => 'wiringhead'.uniqid().'@sales.local',
'password' => bcrypt('secret'),
'role' => 'head',
'is_active' => true,
]);
}
it('«Греть» открывает эпизод канала', function () {
$firm = wiringFirm();
$this->actingAs(wiringHead(), 'sales')
->postJson('/api/sales/warming/yandex/warm', ['firm_ids' => [$firm->id]])
->assertOk();
$ep = SalesAdAudienceWarmingEpisode::where('firm_id', $firm->id)->where('channel', 'yandex')->sole();
expect($ep->ended_at)->toBeNull();
});
it('повторное «Греть» уже греющейся фирмы второго открытого эпизода не создаёт', function () {
$firm = wiringFirm();
$head = wiringHead();
$this->actingAs($head, 'sales')->postJson('/api/sales/warming/yandex/warm', ['firm_ids' => [$firm->id]])->assertOk();
$this->actingAs($head, 'sales')->postJson('/api/sales/warming/yandex/warm', ['firm_ids' => [$firm->id]])->assertOk();
expect(SalesAdAudienceWarmingEpisode::where('firm_id', $firm->id)->where('channel', 'yandex')->count())->toBe(1);
});
it('«Убрать» закрывает открытый эпизод канала', function () {
$firm = wiringFirm();
$head = wiringHead();
$this->actingAs($head, 'sales')->postJson('/api/sales/warming/yandex/warm', ['firm_ids' => [$firm->id]])->assertOk();
$this->actingAs($head, 'sales')->postJson('/api/sales/warming/yandex/unassign', ['firm_ids' => [$firm->id]])->assertOk();
$ep = SalesAdAudienceWarmingEpisode::where('firm_id', $firm->id)->where('channel', 'yandex')->sole();
expect($ep->ended_at)->not->toBeNull();
});
it('тумблер on=true открывает, on=false закрывает эпизод', function () {
$firm = wiringFirm();
$head = wiringHead();
$this->actingAs($head, 'sales')
->postJson("/api/sales/warming/yandex/firms/{$firm->id}/toggle", ['on' => true])->assertOk();
expect(SalesAdAudienceWarmingEpisode::where('firm_id', $firm->id)->whereNull('ended_at')->count())->toBe(1);
$this->actingAs($head, 'sales')
->postJson("/api/sales/warming/yandex/firms/{$firm->id}/toggle", ['on' => false])->assertOk();
expect(SalesAdAudienceWarmingEpisode::where('firm_id', $firm->id)->whereNull('ended_at')->count())->toBe(0);
});
it('«Убрать» не трогает открытый эпизод другого канала той же фирмы', function () {
$firm = wiringFirm();
$head = wiringHead();
$this->actingAs($head, 'sales')->postJson('/api/sales/warming/yandex/warm', ['firm_ids' => [$firm->id]])->assertOk();
$this->actingAs($head, 'sales')->postJson('/api/sales/warming/vk/warm', ['firm_ids' => [$firm->id]])->assertOk();
$this->actingAs($head, 'sales')->postJson('/api/sales/warming/yandex/unassign', ['firm_ids' => [$firm->id]])->assertOk();
$vk = SalesAdAudienceWarmingEpisode::where('firm_id', $firm->id)->where('channel', 'vk')->sole();
$yandex = SalesAdAudienceWarmingEpisode::where('firm_id', $firm->id)->where('channel', 'yandex')->sole();
expect($vk->ended_at)->toBeNull()
->and($yandex->ended_at)->not->toBeNull();
});