createMock(EffectiveHelpdeskSettingsService::class); $settings->method('isConfigured')->willReturn(true); $settings->method('getODataBaseUrl')->willReturn('https://bc.example.com:7048/BusinessCentral-NUP/ODataV4'); $settings->method('getCompanyName')->willReturn('Test Company'); $settings->method('getAuthMode')->willReturn(HelpdeskSettingsGateway::AUTH_MODE_BASIC); $settings->method('getBasicUser')->willReturn('tester'); $settings->method('getBasicPassword')->willReturn('secret'); $oauthTokenService = $this->createMock(HelpdeskOAuthTokenService::class); $sessionStore = $this->createMock(SessionStoreInterface::class); $sessionStore->method('all')->willReturn([ 'current_tenant' => ['id' => 1], ]); return new class($settings, $oauthTokenService, $sessionStore, $response) extends BcSoapGateway { /** * @param array{http_code:int,body:string,error:string} $fakeResponse */ public function __construct( EffectiveHelpdeskSettingsService $settings, HelpdeskOAuthTokenService $oauthTokenService, SessionStoreInterface $sessionStore, private readonly array $fakeResponse ) { parent::__construct($settings, $oauthTokenService, $sessionStore); } protected function sendSoapRequest( string $endpoint, string $soapAction, string $requestBody, array $headers, string $basicUser, string $basicPassword ): array { return $this->fakeResponse; } }; } public function testGetTicketCommunicationTextReturnsErrorForEmptyTicketNo(): void { $gateway = $this->createGateway([ 'http_code' => 200, 'body' => '', 'error' => '', ]); $result = $gateway->getTicketCommunicationText(''); $this->assertFalse($result['ok']); $this->assertSame('Missing ticket number', $result['error']); } public function testGetTicketCommunicationTextParsesSuccessfulResponse(): void { $soapBody = <<<'XML' 0 Hallo aus SOAP line 1 XML; $gateway = $this->createGateway([ 'http_code' => 200, 'body' => $soapBody, 'error' => '', ]); $result = $gateway->getTicketCommunicationText('T26-1216'); $this->assertTrue($result['ok']); $this->assertTrue($result['soap_used']); $this->assertSame(0, $result['return_value']); $this->assertSame('Hallo aus SOAP', $result['communication_text']); $this->assertSame('line 1', $result['message_entries']); } public function testGetTicketCommunicationTextReturnsErrorWhenReturnCodeIndicatesFailure(): void { $soapBody = <<<'XML' 400 XML; $gateway = $this->createGateway([ 'http_code' => 200, 'body' => $soapBody, 'error' => '', ]); $result = $gateway->getTicketCommunicationText('T26-1216'); $this->assertFalse($result['ok']); $this->assertSame(400, $result['return_value']); $this->assertSame('BC SOAP returned error code 400', $result['error']); } public function testGetTicketCommunicationTextReturnsErrorForInvalidSoapXml(): void { $gateway = $this->createGateway([ 'http_code' => 200, 'body' => 'invalid-xml', 'error' => '', ]); $result = $gateway->getTicketCommunicationText('T26-1216'); $this->assertFalse($result['ok']); $this->assertSame('Invalid SOAP XML response', $result['error']); } public function testGetTicketFileReturnsErrorForInvalidEntryNo(): void { $gateway = $this->createGateway(['http_code' => 200, 'body' => '', 'error' => '']); $result = $gateway->getTicketFile(0); $this->assertFalse($result['ok']); $this->assertSame('Invalid entry number', $result['error']); } public function testGetTicketFileReturnsErrorOnHttpFailure(): void { $gateway = $this->createGateway(['http_code' => 500, 'body' => '', 'error' => '']); $result = $gateway->getTicketFile(42); $this->assertFalse($result['ok']); $this->assertStringContainsString('HTTP 500', $result['error']); } public function testGetTicketFileReturnsErrorOnNon100ReturnValue(): void { $body = << 400 XML; $gateway = $this->createGateway(['http_code' => 200, 'body' => $body, 'error' => '']); $result = $gateway->getTicketFile(42); $this->assertFalse($result['ok']); $this->assertStringContainsString('error code 400', $result['error']); } public function testGetTicketFileDecodesBase64Parts(): void { $content = 'Hello World'; $b64 = base64_encode($content); $body = << 100 {$b64} XML; $gateway = $this->createGateway(['http_code' => 200, 'body' => $body, 'error' => '']); $result = $gateway->getTicketFile(42); $this->assertTrue($result['ok']); $this->assertSame($content, $result['data']); } public function testGetTicketFileHandlesMultipleParts(): void { $part1 = base64_encode('Hello '); $part2 = base64_encode('World'); // Multiple parts are concatenated as base64 before decoding $combinedB64 = base64_encode('Hello World'); $body = << 100 {$combinedB64} XML; $gateway = $this->createGateway(['http_code' => 200, 'body' => $body, 'error' => '']); $result = $gateway->getTicketFile(42); $this->assertTrue($result['ok']); $this->assertSame('Hello World', $result['data']); } }