8efb82ca43
Three pilot-surfaced issues in one pass: 1. PhoneParser regex used '\s' in the candidate character class, so a digit on a following flattened line bled into the phone. '+7977 6277470\n1' (phone + trailing checkbox value) parsed as 12 digits, producing '+797762774701'. Replaced '\s' with a literal space so newlines/tabs stop the candidate. 2. Custom-themed forms don't use 'your-name' / 'your-email' keys (washanyanya.ru has text-211 / text-212 / name_user). Added FieldDetector::find_name + find_email as fallbacks. Classifier and MessageFormatter now call them if no standard key matches, so 'Александр' in text-211 is recognised as a cyrillic name and scored / displayed accordingly. 3. FlamingoHelper copied '_from_email' into 'your-email' without validating it. Flamingo derives that meta from whatever field it considers "first"; on phone-first forms it ends up holding the phone number. Now we only copy _from_email if it contains '@', and dropped the _from_name shortcut entirely — FieldDetector handles the name via the actual field values. Tests: +1 FieldDetectorTest (13 cases); +2 PhoneParserTest cases for newline/tab bleeds; +1 ClassifierTest case; +1 MessageFormatterTest case for custom field keys. Full suite 53/53 green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
94 lines
2.9 KiB
PHP
94 lines
2.9 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Cf7stg\Tests;
|
|
|
|
use Cf7stg\PhoneParser;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class PhoneParserTest extends TestCase
|
|
{
|
|
public function test_ru_plus7_formatted(): void
|
|
{
|
|
$r = PhoneParser::parse('+7 (903) 123-45-67');
|
|
self::assertSame('+79031234567', $r['e164']);
|
|
self::assertSame('+7 (903) 123-45-67', $r['pretty']);
|
|
self::assertTrue($r['is_russian']);
|
|
}
|
|
|
|
public function test_ru_leading_eight(): void
|
|
{
|
|
$r = PhoneParser::parse('89031234567');
|
|
self::assertSame('+79031234567', $r['e164']);
|
|
self::assertSame('+7 (903) 123-45-67', $r['pretty']);
|
|
self::assertTrue($r['is_russian']);
|
|
}
|
|
|
|
public function test_ru_bare_ten_digits(): void
|
|
{
|
|
$r = PhoneParser::parse('9031234567');
|
|
self::assertSame('+79031234567', $r['e164']);
|
|
self::assertTrue($r['is_russian']);
|
|
}
|
|
|
|
public function test_foreign_us_number(): void
|
|
{
|
|
$r = PhoneParser::parse('+1 555 123 4567');
|
|
self::assertSame('+15551234567', $r['e164']);
|
|
self::assertFalse($r['is_russian']);
|
|
}
|
|
|
|
public function test_embedded_in_text(): void
|
|
{
|
|
$r = PhoneParser::parse('Позвоните мне: +7-903-123-45-67, после 18:00');
|
|
self::assertSame('+79031234567', $r['e164']);
|
|
self::assertTrue($r['is_russian']);
|
|
}
|
|
|
|
public function test_returns_first_of_multiple(): void
|
|
{
|
|
$r = PhoneParser::parse('Домашний 84951234567, мобильный 89031234567');
|
|
self::assertSame('+74951234567', $r['e164']);
|
|
}
|
|
|
|
public function test_garbage_returns_null(): void
|
|
{
|
|
self::assertNull(PhoneParser::parse('позвоните!!!'));
|
|
}
|
|
|
|
public function test_empty_returns_null(): void
|
|
{
|
|
self::assertNull(PhoneParser::parse(''));
|
|
}
|
|
|
|
public function test_too_short_returns_null(): void
|
|
{
|
|
self::assertNull(PhoneParser::parse('12345'));
|
|
}
|
|
|
|
public function test_ru_moscow_landline(): void
|
|
{
|
|
$r = PhoneParser::parse('+7 (495) 123-45-67');
|
|
self::assertSame('+74951234567', $r['e164']);
|
|
self::assertTrue($r['is_russian']);
|
|
}
|
|
|
|
public function test_digits_on_next_line_do_not_leak_into_number(): void
|
|
{
|
|
// Pilot bug: CF7 spam flatten joined values with "\n"; '\s' in the
|
|
// candidate regex matched newlines, so '+79776277470\n1' (phone then
|
|
// a checkbox value on the next line) turned into a 12-digit number
|
|
// ending in 1.
|
|
$r = PhoneParser::parse("+79776277470\n1");
|
|
self::assertSame('+79776277470', $r['e164']);
|
|
self::assertTrue($r['is_russian']);
|
|
}
|
|
|
|
public function test_tab_between_fields_does_not_leak(): void
|
|
{
|
|
// Same family as above but with tabs.
|
|
$r = PhoneParser::parse("89031234567\t1");
|
|
self::assertSame('+79031234567', $r['e164']);
|
|
}
|
|
}
|