Hallo

'; $clean = sanitizer()->clean($dirty); expect($clean)->toContain('

Hallo

'); expect($clean)->not->toContain('not->toContain('alert'); expect($clean)->not->toContain('clean($dirty); expect($clean)->not->toContain('onclick'); expect($clean)->not->toContain('
  • Punkt A
  • Punkt B
  • ' .'
    Zitat
    ' .'Link'; $clean = sanitizer()->clean($dirty); expect($clean)->toContain('

    Headline

    '); expect($clean)->toContain('fett'); expect($clean)->toContain('kursiv'); expect($clean)->toContain('
      '); expect($clean)->toContain('
    • Punkt A
    • '); expect($clean)->toContain('
      '); expect($clean)->toContain('href="https://example.test"'); }); test('clean removes disallowed tags like h1 table img', function () { $dirty = '

      Big

      x
      '; $clean = sanitizer()->clean($dirty); expect($clean)->not->toContain('not->toContain('not->toContain('clean($dirty); expect($clean)->toContain('rel='); expect($clean)->toContain('nofollow'); expect($clean)->toContain('target="_blank"'); }); test('clean returns empty string for null and whitespace input', function () { expect(sanitizer()->clean(null))->toBe(''); expect(sanitizer()->clean(' '))->toBe(''); }); test('isHtml detects html content', function () { expect(sanitizer()->isHtml('

      Hi

      '))->toBeTrue(); expect(sanitizer()->isHtml('foo'))->toBeTrue(); expect(sanitizer()->isHtml('Plain text only'))->toBeFalse(); expect(sanitizer()->isHtml(''))->toBeFalse(); expect(sanitizer()->isHtml(null))->toBeFalse(); }); test('render wraps legacy plain text into paragraphs and br tags', function () { $plain = "Zeile eins\nZeile zwei\n\nNeuer Absatz"; $html = (string) sanitizer()->render($plain); expect($html)->toContain('

      '); expect($html)->toContain('Zeile einstoContain('Zeile zwei'); expect($html)->toContain('Neuer Absatz'); }); test('render escapes html-special chars in legacy plain text', function () { $plain = 'Skript: '; $html = (string) sanitizer()->render($plain); expect($html)->not->toContain('toContain('<script'); }); test('render returns sanitized html for stored html content', function () { $stored = '

      Hallo

      '; $html = (string) sanitizer()->render($stored); expect($html)->toContain('

      Hallo

      '); expect($html)->not->toContain('plainTextLength('

      Hallo Welt

      '))->toBe(10); expect(sanitizer()->plainTextLength('

      Eins

      Zwei

      '))->toBe(9); expect(sanitizer()->plainTextLength(null))->toBe(0); }); test('PressRelease::renderedText uses the sanitizer', function () { $pr = PressRelease::factory()->create([ 'text' => '

      Hallo

      ', ]); $rendered = (string) $pr->renderedText(); expect($rendered)->toContain('

      Hallo

      '); expect($rendered)->not->toContain('render('

      Produkt

      '); expect($html)->toContain('rel="sponsored nofollow noopener"') ->and($html)->toContain('target="_blank"'); }); test('rendered internal portal links stay follow', function () { $html = (string) sanitizer()->render('

      Unternehmensprofil

      '); expect($html)->not->toContain('nofollow') ->and($html)->not->toContain('sponsored') ->and($html)->toContain('href="https://presseecho.test/firma/alpha-gmbh"'); }); test('relative links are treated as internal and stay follow', function () { $html = (string) sanitizer()->render('

      Profil

      '); expect($html)->not->toContain('nofollow') ->and($html)->not->toContain('target='); }); test('author-supplied rel attributes are always overridden', function () { $html = (string) sanitizer()->render('

      Link

      '); expect($html)->not->toContain('dofollow') ->and($html)->toContain('rel="sponsored nofollow noopener"'); }); test('mailto and tel links get no rel and no target', function () { $html = (string) sanitizer()->render('

      Mail

      '); expect($html)->not->toContain('rel=') ->and($html)->not->toContain('target='); }); test('www variants of portal domains count as internal', function () { $html = (string) sanitizer()->render('

      Profil

      '); expect($html)->not->toContain('nofollow'); });