← Code-Übersicht

FallbackWetellSourceAdapterTest.php

Pfad: tests/Rechnung/FallbackWetellSourceAdapterTest.php

Ext: php

Größe: 4124 Bytes

Geändert: 2026-07-16 18:20:06+02

<?php

declare (strict_types=1);
namespace Tests\Rechnung;

use Demo\Domain\Rechnung\InvoiceLoggerPort;
use Demo\Domain\Rechnung\SourceInvoice;
use Demo\Domain\Rechnung\WetellAuthenticationException;
use Demo\Domain\Rechnung\WetellSourcePort;
use Demo\Infrastructure\Rechnung\FallbackWetellSourceAdapter;
use PHPUnit\Framework\TestCase;
use RuntimeException;
/**
 * Sichert die eindeutige Adapter-Session.
 */
final class FallbackWetellSourceAdapterTest extends TestCase
{
    /** Erfolgreicher Primary bleibt fuer Discovery und Download aktiv. */
    public function testPrimarySessionWirdNichtGemischt(): void
    {
        $primary = $this->portal(false);
        $fallback = $this->portal(false);
        $adapter = new FallbackWetellSourceAdapter($primary, $fallback, $this->logger());
        $session = $adapter->login('u', 'p');
        $adapter->discoverInvoices();
        $adapter->downloadInvoicePdf('https://mein.wetell.de/x.pdf');
        self::assertSame(['login', 'discover', 'download'], $primary->calls);
        self::assertSame([], $fallback->calls);
        self::assertTrue($session->belongsTo($adapter));
    }
    /** Fallback wird vor seiner Nutzung selbst eingeloggt. */
    public function testFallbackErhaeltEigenenLogin(): void
    {
        $primary = $this->portal(true);
        $fallback = $this->portal(false);
        $adapter = new FallbackWetellSourceAdapter($primary, $fallback, $this->logger());
        $adapter->login('u', 'p');
        $adapter->discoverInvoices();
        self::assertSame(['login'], $primary->calls);
        self::assertSame(['login', 'discover'], $fallback->calls);
    }
    /** Authentifizierungsfehler duerfen keinen technischen Fallback ausloesen. */
    public function testAuthenticationFailureIsNotSwallowed(): void
    {
        $primary = new class implements WetellSourcePort {
            public function login(string $username, string $password): \Demo\Domain\Rechnung\WetellSessionHandle
            {
                throw new WetellAuthenticationException('auth');
            }
            public function discoverInvoices(): array { return []; }
            public function downloadInvoicePdf(string $downloadUrl): string { return ''; }
        };
        $fallback = $this->portal(false);
        $adapter = new FallbackWetellSourceAdapter($primary, $fallback, $this->logger());
        try {
            $adapter->login('u', 'p');
            self::fail('Authentifizierungsfehler erwartet');
        } catch (WetellAuthenticationException) {
            self::assertSame([], $fallback->calls);
        }
    }
    /** @return WetellSourcePort&object{calls:list<string>} Portal-Spy. */
    private function portal(bool $failLogin): WetellSourcePort
    {
        return new class($failLogin) implements WetellSourcePort
        {
            /** @var list<string> */
            public array $calls = [];
            public function __construct(private readonly bool $failLogin)
            {
            }
            public function login(string $username, string $password): \Demo\Domain\Rechnung\WetellSessionHandle
            {
                $this->calls[] = 'login';
                if ($this->failLogin) {
                    throw new RuntimeException('fail');
                }
                return \Demo\Domain\Rechnung\WetellSessionHandle::issue($this);
            }
            public function discoverInvoices(): array
            {
                $this->calls[] = 'discover';
                return [new SourceInvoice('x', 'WEtell GmbH', 'https://mein.wetell.de/x.pdf')];
            }
            public function downloadInvoicePdf(string $downloadUrl): string
            {
                $this->calls[] = 'download';
                return '%PDF-' . str_repeat('x', 100);
            }
        };
    }
    /** Erzeugt einen stillen Logger. */
    private function logger(): InvoiceLoggerPort
    {
        return new class implements InvoiceLoggerPort
        {
            public function logStep(string $runId, string $step, string $status, array $context = []): void
            {
            }
        };
    }
}

Frühere Versionen

Version Zeitpunkt Operation
62 2026-07-16 20:20:52.019324+02 UPDATE
56 2026-07-16 20:18:22.873442+02 UPDATE