'Менеджер '.uniqid(), 'email' => 'mgr'.uniqid().'@sales.local', 'password' => bcrypt('secret'), 'role' => 'manager', ], $attrs)); } function makeHead(array $attrs = []): SalesUser { return SalesUser::create(array_merge([ 'name' => 'Руководитель '.uniqid(), 'email' => 'head'.uniqid().'@sales.local', 'password' => bcrypt('secret'), 'role' => 'head', 'is_active' => true, ], $attrs)); } function makeService(): SalesAttachmentService { return app(SalesAttachmentService::class); } // ── lookup() ───────────────────────────────────────────────────────────────── test('lookup находит тенанта по contact_email', function (): void { $tenant = Tenant::factory()->create(['contact_email' => 'client-email@example.com']); $found = makeService()->lookup('client-email@example.com'); expect($found)->not->toBeNull() ->and($found->id)->toBe($tenant->id); }); test('lookup находит тенанта по ИНН из tenant_requisites', function (): void { $tenant = Tenant::factory()->create(); TenantRequisites::create([ 'tenant_id' => $tenant->id, 'subject_type' => 'sole_proprietor', 'contact_name' => 'Тест ИП', 'contact_phone' => '+79000000001', 'inn' => '245210851872', ]); $found = makeService()->lookup('245210851872'); expect($found)->not->toBeNull() ->and($found->id)->toBe($tenant->id); }); test('lookup возвращает null если нет совпадения ни по email ни по ИНН', function (): void { $result = makeService()->lookup('nobody@nowhere.test'); expect($result)->toBeNull(); }); // ── submit() — not_found ────────────────────────────────────────────────────── test('submit для несуществующего логина создаёт заявку not_found и шлёт AttachmentNotFoundMail', function (): void { Mail::fake(); $manager = makeManager(); $req = makeService()->submit($manager, 'nobody@nowhere.test'); expect($req)->toBeInstanceOf(SalesAttachmentRequest::class) ->and($req->status)->toBe('not_found') ->and($req->sales_user_id)->toBe($manager->id) ->and($req->login_input)->toBe('nobody@nowhere.test') ->and($req->tenant_id)->toBeNull(); Mail::assertQueued(AttachmentNotFoundMail::class, fn ($mail): bool => $mail->hasTo($manager->email) ); }); // ── submit() — свободный клиент ─────────────────────────────────────────────── test('submit для свободного клиента создаёт pending-заявку и шлёт AttachmentSubmittedMail менеджеру и начальнику', function (): void { Mail::fake(); $manager = makeManager(); $head = makeHead(); $tenant = Tenant::factory()->create(['contact_email' => 'free-client@example.com']); $req = makeService()->submit($manager, 'free-client@example.com'); expect($req->status)->toBe('pending') ->and($req->tenant_id)->toBe($tenant->id) ->and($req->comment)->toBeNull(); // Письмо должно уйти менеджеру Mail::assertQueued(AttachmentSubmittedMail::class, fn ($mail): bool => $mail->hasTo($manager->email) ); // Письмо должно уйти начальнику Mail::assertQueued(AttachmentSubmittedMail::class, fn ($mail): bool => $mail->hasTo($head->email) ); }); // ── submit() — клиент уже занят другим менеджером ───────────────────────────── test('submit для клиента занятого другим менеджером создаёт pending с комментарием о конфликте', function (): void { Mail::fake(); $manager = makeManager(); $otherManager = makeManager(['name' => 'Другой Менеджер']); $tenant = Tenant::factory()->create(['contact_email' => 'taken-client@example.com']); SalesClientAssignment::create([ 'sales_user_id' => $otherManager->id, 'tenant_id' => $tenant->id, 'tariff_params' => [], 'assigned_at' => now(), ]); $req = makeService()->submit($manager, 'taken-client@example.com'); expect($req->status)->toBe('pending') ->and($req->tenant_id)->toBe($tenant->id) ->and($req->comment)->toContain('Другой Менеджер'); }); // ── submit() — клиент уже у этого менеджера ────────────────────────────────── test('submit для клиента уже привязанного к этому менеджеру бросает DomainException', function (): void { Mail::fake(); $manager = makeManager(); $tenant = Tenant::factory()->create(['contact_email' => 'own-client@example.com']); SalesClientAssignment::create([ 'sales_user_id' => $manager->id, 'tenant_id' => $tenant->id, 'tariff_params' => [], 'assigned_at' => now(), ]); expect(fn (): SalesAttachmentRequest => makeService()->submit($manager, 'own-client@example.com')) ->toThrow(DomainException::class, 'Этот клиент уже ваш.'); });