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

81 lines
3.3 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
use App\Jobs\Supplier\SyncSupplierProjectsJob;
use App\Models\Project;
use App\Models\SupplierProject;
use App\Models\Tenant;
use App\Services\Supplier\Channel\AjaxProjectChannel;
use Carbon\Carbon;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Tests\Concerns\SharesSupplierPdo;
uses(DatabaseTransactions::class, SharesSupplierPdo::class);
/**
* Эпик 5 Task 5.1 — по завершении вечерней заливки джоб пишет строку-сводку
* в supplier_sync_runs (для экрана SaaS-admin «Интеграция с поставщиком»).
*/
beforeEach(function (): void {
Carbon::setTestNow(Carbon::parse('2026-05-27 18:06:00', 'Europe/Moscow'));
DB::table('supplier_sync_runs')->delete();
});
afterEach(fn () => Carbon::setTestNow());
it('пишет run-сводку даже когда нет eligible-проектов (groups_total=0, status=ok)', function (): void {
(new SyncSupplierProjectsJob)->handle(app(AjaxProjectChannel::class));
$run = DB::table('supplier_sync_runs')->latest('id')->first();
expect($run)->not->toBeNull();
expect((int) $run->groups_total)->toBe(0);
expect((int) $run->synced_ok)->toBe(0);
expect($run->status)->toBe('ok');
expect($run->started_at)->not->toBeNull();
expect($run->finished_at)->not->toBeNull();
});
it('считает синхронизированную группу в синку run-сводки (groups_total=1, synced_ok=1)', function (): void {
$tenant = Tenant::factory()->create();
$project = Project::factory()->create([
'tenant_id' => $tenant->id,
'is_active' => true,
'signal_type' => 'site',
'signal_identifier' => 'okna-run.example.com',
'daily_limit_target' => 9,
'delivery_days_mask' => 127,
'regions' => [82, 83],
]);
insertSnapshotForTomorrow($project, regions: '{82,83}');
Http::fake([
'crm.bp-gr.ru/admin/visit/rt-project-save' => Http::response(
['status' => 'OK', 'message' => '', 'result' => null, 'id' => '2001'],
200,
),
'crm.bp-gr.ru/admin/visit/rt-projects-load*' => Http::response(
['projects' => [
['id' => '2001', 'src' => 'rt', 'name' => 'okna-run.example.com', 'tag' => 'РФ', 'type' => 'hosts', 'content' => 'okna-run.example.com'],
['id' => '2002', 'src' => 'bl', 'name' => 'okna-run.example.com', 'tag' => 'РФ', 'type' => 'hosts', 'content' => 'okna-run.example.com'],
['id' => '2003', 'src' => 'mt', 'name' => 'okna-run.example.com', 'tag' => 'РФ', 'type' => 'hosts', 'content' => 'okna-run.example.com'],
]],
200,
),
]);
(new SyncSupplierProjectsJob)->handle(app(AjaxProjectChannel::class));
// Группа реально создалась у поставщика.
expect(SupplierProject::on('pgsql_supplier')->where('unique_key', 'okna-run.example.com')->count())->toBe(3);
$run = DB::table('supplier_sync_runs')->latest('id')->first();
expect($run)->not->toBeNull();
expect((int) $run->groups_total)->toBe(1);
expect((int) $run->synced_ok)->toBe(1);
expect((int) $run->failed)->toBe(0);
expect($run->status)->toBe('ok');
});