'Max', 'lastname' => 'Mustermann', 'street' => 'Hauptstrasse', 'house_number' => '5', 'postal_code' => '10115', 'city' => 'Berlin', 'country_code' => 'DE', 'email' => 'max@example.com', 'phone' => '+4930123456', ], $overrides); } beforeEach(function () { config([ 'dhl.config_source' => 'env', 'dhl.international_countries' => ['AT', 'ES'], ]); }); it('marks a complete supported address as valid', function () { $result = (new DhlAddressValidator)->validate(validDhlAddress()); expect($result['status'])->toBe('valid') ->and($result['can_create_label'])->toBeTrue() ->and($result['errors'])->toBeEmpty() ->and($result['warnings'])->toBeEmpty() ->and($result['validation_available'])->toBeTrue() ->and($result['validation_level'])->toBe('formal_dach') ->and($result['validation_message'])->toBe('Formale DACH-Pruefung aktiv: Pflichtfelder, PLZ-Format, Plausibilitaet und Packstation-Regeln werden geprueft. Eine echte Adressdatenbank-/DHL-Leitcodepruefung ist nicht angebunden.'); }); it('blocks unsupported destination countries', function () { $result = (new DhlAddressValidator)->validate(validDhlAddress([ 'country_code' => 'FR', 'postal_code' => '75001', ])); expect($result['status'])->toBe('error') ->and($result['can_create_label'])->toBeFalse() ->and($result['errors'])->toContain('DHL-Versand in das Zielland FR ist aktuell nicht freigegeben.'); }); it('blocks invalid postal code formats for enabled countries', function () { $result = (new DhlAddressValidator)->validate(validDhlAddress([ 'country_code' => 'AT', 'postal_code' => '10115', ])); expect($result['status'])->toBe('error') ->and($result['errors'])->toContain('Oesterreichische Postleitzahl muss 4 Ziffern haben.'); }); it('validates swiss postal codes when switzerland is enabled', function () { config([ 'dhl.config_source' => 'env', 'dhl.international_countries' => ['AT', 'CH'], ]); $result = (new DhlAddressValidator)->validate(validDhlAddress([ 'country_code' => 'CH', 'postal_code' => '8000', ])); expect($result['validation_available'])->toBeTrue() ->and($result['validation_level'])->toBe('formal_dach') ->and($result['errors'])->not->toContain('Schweizer Postleitzahl muss 4 Ziffern haben.'); }); it('marks supported countries without country specific validation as basic checks', function () { config([ 'dhl.config_source' => 'env', 'dhl.international_countries' => ['FR'], ]); $result = (new DhlAddressValidator)->validate(validDhlAddress([ 'country_code' => 'FR', 'postal_code' => '75001', ])); expect($result['status'])->toBe('warning') ->and($result['can_create_label'])->toBeTrue() ->and($result['validation_available'])->toBeFalse() ->and($result['validation_level'])->toBe('basic') ->and($result['validation_message'])->toBe('Fuer dieses Zielland ist aktuell nur eine Basis-Adresspruefung verfuegbar.') ->and($result['warnings'])->toContain('Fuer dieses Zielland ist aktuell nur eine Basis-Adresspruefung verfuegbar. Bitte Adresse manuell pruefen.'); }); it('blocks implausible delivery address fields', function () { $result = (new DhlAddressValidator)->validate(validDhlAddress([ 'street' => '12', 'postal_code' => '12@@@', 'city' => '1', ])); expect($result['status'])->toBe('error') ->and($result['can_create_label'])->toBeFalse() ->and($result['errors'])->toContain('Straße ist zu kurz.') ->and($result['errors'])->toContain('Straße muss Buchstaben enthalten.') ->and($result['errors'])->toContain('Ort ist zu kurz.') ->and($result['errors'])->toContain('Ort muss Buchstaben enthalten.') ->and($result['errors'])->toContain('Postleitzahl enthaelt ungueltige Zeichen.'); }); it('blocks placeholder delivery addresses', function () { $result = (new DhlAddressValidator)->validate(validDhlAddress([ 'street' => 'Teststrasse', 'city' => 'Fakeort', ])); expect($result['status'])->toBe('error') ->and($result['can_create_label'])->toBeFalse() ->and($result['errors'])->toContain('Straße wirkt wie eine Test- oder Platzhalteradresse.') ->and($result['errors'])->toContain('Ort wirkt wie eine Test- oder Platzhalterangabe.'); }); it('blocks DACH addresses with house numbers without digits', function () { $result = (new DhlAddressValidator)->validate(validDhlAddress([ 'house_number' => 'links', ])); expect($result['status'])->toBe('error') ->and($result['can_create_label'])->toBeFalse() ->and($result['errors'])->toContain('Hausnummer muss fuer DACH-Adressen eine Ziffer enthalten.'); }); it('allows warning-only addresses but marks them for review', function () { $result = (new DhlAddressValidator)->validate(validDhlAddress([ 'phone' => '', ])); expect($result['status'])->toBe('warning') ->and($result['can_create_label'])->toBeTrue() ->and($result['warnings'])->toContain('Telefonnummer fehlt. DHL kann Empfaenger bei Zustellproblemen eventuell nicht kontaktieren.'); }); it('validates German packstation addresses', function () { $result = (new DhlAddressValidator)->validate(validDhlAddress([ 'street' => 'Packstation', 'house_number' => '145', 'postnumber' => '12345678', ])); expect($result['status'])->toBe('valid') ->and($result['can_create_label'])->toBeTrue(); }); it('blocks invalid packstation postnumbers', function () { $result = (new DhlAddressValidator)->validate(validDhlAddress([ 'street' => 'Packstation', 'house_number' => '145', 'postnumber' => 'abc', ])); expect($result['status'])->toBe('error') ->and($result['errors'])->toContain('DHL Postnummer muss 6-10 Ziffern enthalten.'); }); it('requires postnumber and locker number for packstation addresses', function () { $result = (new DhlAddressValidator)->validate(validDhlAddress([ 'street' => 'Packstation', 'house_number' => '', 'postnumber' => '', ])); expect($result['status'])->toBe('error') ->and($result['errors'])->toContain('DHL Postnummer ist fuer Packstation/Paketbox erforderlich.'); });