assertStringNotContainsString('@', $result);
$this->assertStringContainsString('@', $result); // decimal entity for @
}
public function testEncodeOutputIsNumericEntities(): void
{
$result = EmailObfuscator::email('a@b.c');
// Every original character should be a xx; entity
$this->assertMatchesRegularExpression('/^(?:\d+;)+$/', $result);
$this->assertNotEmpty($result);
}
// ── email() ───────────────────────────────────────────────────────────────
public function testEmailReturnsObfuscatedAddress(): void
{
$result = EmailObfuscator::email('hello@world.org');
$this->assertStringNotContainsString('hello', $result);
$this->assertStringNotContainsString('@', $result);
$this->assertStringContainsString('h', $result); // 'h'
$this->assertStringContainsString('@', $result); // '@'
}
// ── mailto() ──────────────────────────────────────────────────────────────
public function testMailtoBuildsCorrectHrefStructure(): void
{
$result = EmailObfuscator::mailto('x@y.com');
$this->assertStringStartsWith('mailto:', $result);
$this->assertStringNotContainsString('@', $result);
$this->assertStringContainsString('@', $result);
}
// ── emailText() ───────────────────────────────────────────────────────────
public function testEmailTextReplacesBareEmail(): void
{
$input = 'Contact xamxam@erg.be for help';
$result = EmailObfuscator::emailText($input);
$this->assertStringNotContainsString('xamxam@erg.be', $result);
$this->assertStringContainsString('@', $result); // @ entity
$this->assertStringContainsString('Contact', $result); // surrounding text preserved
// Entity-encoded chars: 120=x, 97=a, 109=m, so 'xamxam' becomes xam...
$this->assertStringContainsString('x', $result); // 'x'
$this->assertStringContainsString('a', $result); // 'a'
$this->assertStringContainsString('m', $result); // 'm'
}
public function testEmailTextReplacesMultipleEmails(): void
{
$input = 'a@b.com and c@d.org';
$result = EmailObfuscator::emailText($input);
$this->assertStringNotContainsString('@', $result);
$this->assertStringContainsString('@', $result);
// Should have two occurrences of the @ entity
$this->assertEquals(2, substr_count($result, '@'));
}
// ── mailtoInText() ────────────────────────────────────────────────────────
public function testMailtoInTextReplacesMailtoLinks(): void
{
$input = 'contact';
$result = EmailObfuscator::mailtoInText($input);
$this->assertStringNotContainsString('contact@example.com', $result);
$this->assertStringContainsString('mailto:', $result);
$this->assertStringContainsString('@', $result);
}
// ── obfuscateHtml() ───────────────────────────────────────────────────────
public function testObfuscateHtmlReplacesAnchorTag(): void
{
$input = 'contact@example.com';
$result = EmailObfuscator::obfuscateHtml($input);
$this->assertStringNotContainsString('contact@example.com', $result);
$this->assertStringContainsString('assertStringContainsString('href="mailto:', $result);
// @ entity should appear twice (href + link text)
$this->assertGreaterThanOrEqual(2, substr_count($result, '@'));
}
public function testObfuscateHtmlKeepsNonMailtoLinksUnchanged(): void
{
$input = 'ERG and x@y.z';
$result = EmailObfuscator::obfuscateHtml($input);
$this->assertStringContainsString('https://erg.be', $result);
$this->assertStringContainsString('ERG', $result);
$this->assertStringNotContainsString('x@y.z', $result);
}
public function testObfuscateHtmlPreservesCustomLinkText(): void
{
// When the link text differs from the email, only the href is obfuscated
$input = 'custom text';
$result = EmailObfuscator::obfuscateHtml($input);
$this->assertStringNotContainsString('foobar@test.com', $result);
$this->assertStringContainsString('@', $result); // in href
$this->assertStringContainsString('custom text', $result); // link text unchanged
}
// ── Edge cases ────────────────────────────────────────────────────────────
public function testEmptyStringReturnsEmpty(): void
{
$this->assertSame('', EmailObfuscator::email(''));
}
public function testStringWithNoEmailsIsUnchanged(): void
{
$input = 'Hello, world! No emails here.';
$this->assertSame($input, EmailObfuscator::emailText($input));
}
public function testAlreadyObfuscatedContentIsNotDoubleEncoded(): void
{
// Already entity-encoded email — no literal '@' to match
$input = 'Contact xamxam@erg.be here';
$result = EmailObfuscator::emailText($input);
// Should be unchanged (regex won't match entity-encoded @)
$this->assertSame($input, $result);
}
public function testMultipleEmailsInOneString(): void
{
$input = 'Mail to a@b.com or c@d.org pls';
$result = EmailObfuscator::emailText($input);
$this->assertStringNotContainsString('a@b.com', $result);
$this->assertStringNotContainsString('c@d.org', $result);
// Two @ entities
$this->assertEquals(2, substr_count($result, '@'));
}
public function testEmailWithPlusSign(): void
{
$result = EmailObfuscator::email('user+tag@domain.com');
$this->assertStringContainsString('+', $result); // '+'
$this->assertStringContainsString('@', $result); // '@'
}
}