1
0
Files
breadcrumb-the-shire/modules/helpdesk/tests/Module/Helpdesk/Service/DebitorSearchServiceTest.php
fs ea786f5341 feat(helpdesk): add multi-tenant BC connection settings with risk radar refinements
Introduce per-tenant override for helpdesk BC connection config.
New table helpdesk_tenant_settings stores tenant-specific credentials
with encrypted secrets (AES-256-GCM). EffectiveHelpdeskSettingsService
resolves global vs tenant config per request. Settings UI extended with
tenant override tab, toggle, and dual editing mode.

All runtime consumers (OData, SOAP, OAuth) read through the new
resolver. Token cache flushed on any config change. Default behavior
unchanged — tenants use global config until override explicitly enabled.

Also includes risk radar UI refinements: Stripe-style card redesign
with accent borders and score pills, removal of redundant KPI tiles
and search, and filtering of zero-score entries.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 10:29:59 +02:00

162 lines
5.6 KiB
PHP

<?php
namespace MintyPHP\Tests\Module\Helpdesk\Service;
use MintyPHP\Module\Helpdesk\Service\BcODataGateway;
use MintyPHP\Module\Helpdesk\Service\DebitorSearchService;
use MintyPHP\Module\Helpdesk\Service\EffectiveHelpdeskSettingsService;
use PHPUnit\Framework\TestCase;
class DebitorSearchServiceTest extends TestCase
{
private function createService(?BcODataGateway $gateway = null, bool $isConfigured = true): DebitorSearchService
{
$gateway = $gateway ?? $this->createMock(BcODataGateway::class);
$settings = $this->createMock(EffectiveHelpdeskSettingsService::class);
$settings->method('isConfigured')->willReturn($isConfigured);
return new DebitorSearchService($gateway, $settings);
}
public function testSearchReturnsEmptyStatusForEmptyQuery(): void
{
$service = $this->createService();
$result = $service->search('');
$this->assertSame('empty', $result['status']);
$this->assertSame([], $result['results']);
}
public function testSearchReturnsTooShortForSingleCharacter(): void
{
$service = $this->createService();
$result = $service->search('A');
$this->assertSame('too_short', $result['status']);
}
public function testSearchReturnsNotConfiguredWhenBcNotConfigured(): void
{
$service = $this->createService(null, false);
$result = $service->search('Test Company');
$this->assertSame('not_configured', $result['status']);
$this->assertNotEmpty($result['error']);
}
public function testSearchReturnsSuccessWithResults(): void
{
$gateway = $this->createMock(BcODataGateway::class);
$gateway->expects($this->once())
->method('searchCustomers')
->with('Musterfirma')
->willReturn([
['No' => '10254', 'Name' => 'Musterfirma GmbH', 'City' => 'Berlin'],
]);
$service = $this->createService($gateway);
$result = $service->search('Musterfirma');
$this->assertSame('success', $result['status']);
$this->assertCount(1, $result['results']);
$this->assertSame('10254', $result['results'][0]['No']);
}
public function testSearchReturnsNoResultsWhenEmpty(): void
{
$gateway = $this->createMock(BcODataGateway::class);
$gateway->expects($this->once())
->method('searchCustomers')
->willReturn([]);
$service = $this->createService($gateway);
$result = $service->search('xyz-nonexistent');
$this->assertSame('no_results', $result['status']);
$this->assertSame([], $result['results']);
}
public function testSearchReturnsErrorOnBcConnectionFailure(): void
{
$gateway = $this->createMock(BcODataGateway::class);
$gateway->expects($this->once())
->method('searchCustomers')
->willThrowException(new \RuntimeException('Connection refused'));
$service = $this->createService($gateway);
$result = $service->search('Musterfirma');
$this->assertSame('error', $result['status']);
$this->assertNotEmpty($result['error']);
}
public function testListForGridReturnsNotConfiguredWhenBcNotConfigured(): void
{
$service = $this->createService(null, false);
$result = $service->listForGrid([]);
$this->assertSame('not_configured', $result['status']);
$this->assertSame([], $result['rows']);
$this->assertSame(0, $result['total']);
}
public function testListForGridReturnsSuccessWithRowsAndTotal(): void
{
$gateway = $this->createMock(BcODataGateway::class);
$gateway->expects($this->once())
->method('listCustomers')
->with('Muster', 'Berlin', 10, 0, 'Name', 'asc')
->willReturn([
'rows' => [
['No' => '10000', 'Name' => 'Muster GmbH', 'City' => 'Berlin'],
],
'total' => 42,
]);
$service = $this->createService($gateway);
$result = $service->listForGrid([
'search' => 'Muster',
'city' => 'Berlin',
'limit' => 10,
'offset' => 0,
'order' => 'Name',
'dir' => 'asc',
]);
$this->assertSame('success', $result['status']);
$this->assertCount(1, $result['rows']);
$this->assertSame(42, $result['total']);
}
public function testListForGridReturnsErrorWhenGatewayFails(): void
{
$gateway = $this->createMock(BcODataGateway::class);
$gateway->expects($this->once())
->method('listCustomers')
->willThrowException(new \RuntimeException('Connection refused'));
$service = $this->createService($gateway);
$result = $service->listForGrid(['search' => 'Muster']);
$this->assertSame('error', $result['status']);
$this->assertSame([], $result['rows']);
$this->assertSame(0, $result['total']);
}
public function testListForGridNormalizesLimitAndOffsetBounds(): void
{
$gateway = $this->createMock(BcODataGateway::class);
$gateway->expects($this->once())
->method('listCustomers')
->with('', '', 100, 0, 'Name', 'asc')
->willReturn([
'rows' => [],
'total' => 0,
]);
$service = $this->createService($gateway);
$result = $service->listForGrid([
'limit' => 999,
'offset' => -5,
'order' => 'Name',
'dir' => 'asc',
]);
$this->assertSame('success', $result['status']);
}
}