Files
portal/app/tests/Feature/Supplier/SupplierProjectImporterTest.php
T

101 lines
5.0 KiB
PHP

<?php
declare(strict_types=1);
use App\Models\Tenant;
use App\Services\Supplier\Import\SupplierProjectImporter;
use App\Services\Supplier\SupplierPortalClient;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\Concerns\SharesSupplierPdo;
uses(DatabaseTransactions::class);
uses(SharesSupplierPdo::class);
/**
* @param list<array<string, mixed>> $rows
*/
function importerWithRows(array $rows): SupplierProjectImporter
{
$client = Mockery::mock(SupplierPortalClient::class);
$client->shouldReceive('listProjects')->andReturn($rows);
return new SupplierProjectImporter($client);
}
test('buildPlan groups B1/B2/B3 call rows into one planned project, limit = sum', function (): void {
$tenant = Tenant::factory()->create();
$plan = importerWithRows([
['id' => '4001', 'src' => 'rt', 'type' => 'calls', 'content' => '79991112233', 'tag' => 'Каранга', 'lim' => '6', 'status' => true, 'regions' => '', 'workdays' => ['1', '2', '3', '4', '5']],
['id' => '4002', 'src' => 'bl', 'type' => 'calls', 'content' => '79991112233', 'tag' => 'Каранга', 'lim' => '6', 'status' => true, 'regions' => '', 'workdays' => ['1', '2', '3', '4', '5']],
['id' => '4003', 'src' => 'mt', 'type' => 'calls', 'content' => '79991112233', 'tag' => 'Каранга', 'lim' => '6', 'status' => true, 'regions' => '', 'workdays' => ['1', '2', '3', '4', '5']],
])->buildPlan($tenant->id);
expect($plan['planned'])->toHaveCount(1);
$p = $plan['planned'][0];
expect($p['signal_type'])->toBe('call');
expect($p['signal_identifier'])->toBe('79991112233');
expect($p['daily_limit_target'])->toBe(18);
expect($p['delivery_days_mask'])->toBe(31);
expect($p['tag'])->toBe('Каранга');
expect($p['regions'])->toBe([]);
expect(collect($p['platforms'])->pluck('platform')->sort()->values()->all())->toBe(['B1', 'B2', 'B3']);
expect(collect($p['platforms'])->firstWhere('platform', 'B1')['external_id'])->toBe(4001);
});
test('buildPlan skips inactive rows (status=false)', function (): void {
$tenant = Tenant::factory()->create();
$plan = importerWithRows([
['id' => '5001', 'src' => 'rt', 'type' => 'calls', 'content' => '79995550000', 'tag' => 'X', 'lim' => '5', 'status' => false, 'regions' => '', 'workdays' => []],
])->buildPlan($tenant->id);
expect($plan['planned'])->toHaveCount(0);
});
test('buildPlan skips dop2 (unsupported source) and reports it', function (): void {
$tenant = Tenant::factory()->create();
$plan = importerWithRows([
['id' => '6001', 'src' => 'dop2', 'type' => 'calls', 'content' => '79996660000', 'tag' => 'X', 'lim' => '5', 'status' => true, 'regions' => '', 'workdays' => []],
])->buildPlan($tenant->id);
expect($plan['planned'])->toHaveCount(0);
expect(collect($plan['skipped'])->pluck('reason'))->toContain('unsupported_source');
});
test('buildPlan reverse-maps regions and unions across platforms', function (): void {
$tenant = Tenant::factory()->create();
$plan = importerWithRows([
['id' => '7001', 'src' => 'rt', 'type' => 'hosts', 'content' => 'okna.ru', 'tag' => 'Окна', 'lim' => '3', 'status' => true, 'regions' => '24', 'workdays' => [], 'regions_reverse' => false],
['id' => '7002', 'src' => 'bl', 'type' => 'hosts', 'content' => 'okna.ru', 'tag' => 'Окна', 'lim' => '3', 'status' => true, 'regions' => '77', 'workdays' => [], 'regions_reverse' => false],
['id' => '7003', 'src' => 'mt', 'type' => 'hosts', 'content' => 'okna.ru', 'tag' => 'Окна', 'lim' => '3', 'status' => true, 'regions' => '24', 'workdays' => [], 'regions_reverse' => false],
])->buildPlan($tenant->id);
expect($plan['planned'][0]['regions'])->toBe([29, 82]);
});
test('buildPlan treats any empty-regions platform as all-Russia', function (): void {
$tenant = Tenant::factory()->create();
$plan = importerWithRows([
['id' => '7101', 'src' => 'rt', 'type' => 'hosts', 'content' => 'all.ru', 'tag' => 'A', 'lim' => '3', 'status' => true, 'regions' => '24', 'workdays' => [], 'regions_reverse' => false],
['id' => '7102', 'src' => 'bl', 'type' => 'hosts', 'content' => 'all.ru', 'tag' => 'A', 'lim' => '3', 'status' => true, 'regions' => '', 'workdays' => [], 'regions_reverse' => false],
])->buildPlan($tenant->id);
expect($plan['planned'][0]['regions'])->toBe([]);
});
test('buildPlan skips group when any active row has regions_reverse=true', function (): void {
$tenant = Tenant::factory()->create();
$plan = importerWithRows([
['id' => '7201', 'src' => 'rt', 'type' => 'hosts', 'content' => 'excl.ru', 'tag' => 'A', 'lim' => '3', 'status' => true, 'regions' => '24', 'workdays' => [], 'regions_reverse' => true],
['id' => '7202', 'src' => 'bl', 'type' => 'hosts', 'content' => 'excl.ru', 'tag' => 'A', 'lim' => '3', 'status' => true, 'regions' => '24', 'workdays' => [], 'regions_reverse' => false],
])->buildPlan($tenant->id);
expect($plan['planned'])->toHaveCount(0);
expect(collect($plan['skipped'])->pluck('reason'))->toContain('regions_exclude');
});