Files
portal/app/tests/Feature/Sales/AdAudiencePlatformApiTest.php
T
Дмитрий ec6bdbfb19 feat(прогрев): разъезд API «Реклама на кандидатов» по площадкам {platform}
GET/PATCH /api/sales/warming/{platform}, GET .../firms, POST .../toggle
и .../assign заменяют общую /api/sales/ad-audience*; настройки и статус
площадки читаются из sales_ad_audience_platforms, членство фирмы —
по ch_yandex/ch_vk/ch_mts. Метод channels() (массовый мультивыбор)
убран — заменён точечным toggle. Неизвестная площадка → 404 через
platformOr404() в контроллере (не через route whereIn — иначе
непойманный сегмент проваливается в Route::fallback).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 11:11:39 +03:00

100 lines
3.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
use App\Models\SalesAdAudienceFirm;
use App\Models\SalesAdAudiencePlatform;
use App\Models\SalesUser;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\Concerns\SharesSupplierPdo;
/**
* API «Реклама на кандидатов» по площадкам (Task 4+5 плана трёх площадок).
*
* Одна общая ручка /api/sales/ad-audience разъезжается на три:
* /api/sales/warming/{yandex|vk|mts}. Настройки и статус — построчно
* в sales_ad_audience_platforms; days/сроки воронки пока общие
* (sales_ad_audience_state). Членство фирмы в площадке — булевы
* ch_yandex/ch_vk/ch_mts на sales_ad_audience_firms.
*
* Аутентификация — как в AdAudienceScreenTest: SalesUser::create() + actingAs('sales')
* (у SalesUser нет HasFactory/factory()).
*/
uses(DatabaseTransactions::class, SharesSupplierPdo::class);
function actingHead(): SalesUser
{
$head = SalesUser::create([
'name' => 'Начальник '.uniqid(),
'email' => 'warminghead'.uniqid().'@sales.local',
'password' => bcrypt('secret'),
'role' => 'head',
'is_active' => true,
]);
test()->actingAs($head, 'sales');
return $head;
}
it('отдаёт настройки именно запрошенной площадки', function () {
actingHead();
SalesAdAudiencePlatform::forCode('vk')->update(['status' => 'waiting_volume']);
test()->getJson('/api/sales/warming/vk')
->assertOk()
->assertJsonPath('data.platform', 'vk')
->assertJsonPath('data.min_phones', 2000)
->assertJsonPath('data.status', 'waiting_volume');
});
it('неизвестную площадку отвергает', function () {
actingHead();
test()->getJson('/api/sales/warming/facebook')->assertNotFound();
});
it('рубильник пишется в строку площадки', function () {
actingHead();
test()->patchJson('/api/sales/warming/vk', ['enabled' => true])->assertOk();
expect(SalesAdAudiencePlatform::forCode('vk')->enabled)->toBeTrue();
});
it('менеджеру доступ закрыт', function () {
$m = SalesUser::create([
'name' => 'Менеджер '.uniqid(),
'email' => 'warmingmgr'.uniqid().'@sales.local',
'password' => bcrypt('secret'),
'role' => 'manager',
'is_active' => true,
]);
test()->actingAs($m, 'sales');
test()->getJson('/api/sales/warming/yandex')->assertForbidden();
});
it('в список площадки попадают только её подписанные фирмы', function () {
actingHead();
SalesAdAudienceFirm::create(['firm_name' => 'Только Яндекс', 'ch_yandex' => true]);
SalesAdAudienceFirm::create(['firm_name' => 'Только ВК', 'ch_vk' => true]);
test()->getJson('/api/sales/warming/vk/firms')
->assertOk()
->assertJsonCount(1, 'firms')
->assertJsonPath('firms.0.firm_name', 'Только ВК');
});
it('переключатель добавляет и убирает фирму с площадки', function () {
actingHead();
$firm = SalesAdAudienceFirm::create(['firm_name' => 'Плавающая', 'ch_vk' => false]);
test()->postJson("/api/sales/warming/vk/firms/{$firm->id}/toggle", ['on' => true])->assertOk();
expect($firm->fresh()->ch_vk)->toBeTrue();
test()->postJson("/api/sales/warming/vk/firms/{$firm->id}/toggle", ['on' => false])->assertOk();
expect($firm->fresh()->ch_vk)->toBeFalse();
});