feat(message-formatter): build Telegram HTML payload with inline tel button
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Cf7stg\Tests;
|
||||
|
||||
use Cf7stg\MessageFormatter;
|
||||
use Cf7stg\Classifier;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class MessageFormatterTest extends TestCase
|
||||
{
|
||||
public function test_full_client_payload(): void
|
||||
{
|
||||
$fields = [
|
||||
'your-name' => 'Анна Петровна',
|
||||
'your-tel' => '+79031234567',
|
||||
'your-email' => 'anna@mail.ru',
|
||||
'your-message' => 'Нужна сиделка для бабушки',
|
||||
];
|
||||
$classification = Classifier::classify($fields, ['reason' => 'Akismet']);
|
||||
$result = MessageFormatter::build([
|
||||
'fields' => $fields,
|
||||
'classification' => $classification,
|
||||
'site_title' => 'вашаняня.рф',
|
||||
'form_title' => 'Обратная связь',
|
||||
'submitted_at' => '17.04.2026 19:45',
|
||||
'reason' => 'Akismet',
|
||||
'ip' => '185.15.56.12',
|
||||
'user_agent' => 'Mozilla/5.0',
|
||||
'is_retro' => false,
|
||||
]);
|
||||
|
||||
self::assertIsArray($result);
|
||||
self::assertArrayHasKey('text', $result);
|
||||
self::assertArrayHasKey('reply_markup', $result);
|
||||
|
||||
self::assertStringContainsString('🟢 похоже клиент', $result['text']);
|
||||
self::assertStringContainsString('вашаняня.рф', $result['text']);
|
||||
self::assertStringContainsString('Анна Петровна', $result['text']);
|
||||
self::assertStringContainsString('+7 (903) 123-45-67', $result['text']);
|
||||
self::assertStringContainsString('anna@mail.ru', $result['text']);
|
||||
self::assertStringContainsString('Akismet', $result['text']);
|
||||
}
|
||||
|
||||
public function test_tel_button_present_when_phone_valid(): void
|
||||
{
|
||||
$fields = ['your-tel' => '+79031234567', 'your-name' => 'Анна'];
|
||||
$classification = Classifier::classify($fields, ['reason' => 'Akismet']);
|
||||
$r = MessageFormatter::build([
|
||||
'fields' => $fields, 'classification' => $classification,
|
||||
'site_title' => 's.ru', 'form_title' => 'f',
|
||||
'submitted_at' => '17.04.2026', 'reason' => 'Akismet',
|
||||
'ip' => '', 'user_agent' => '', 'is_retro' => false,
|
||||
]);
|
||||
|
||||
self::assertNotNull($r['reply_markup']);
|
||||
$json = json_encode($r['reply_markup']);
|
||||
self::assertStringContainsString('tel:+79031234567', $json);
|
||||
}
|
||||
|
||||
public function test_no_tel_button_when_no_phone(): void
|
||||
{
|
||||
$fields = ['your-email' => 'a@b.com'];
|
||||
$classification = Classifier::classify($fields, ['reason' => 'Akismet']);
|
||||
$r = MessageFormatter::build([
|
||||
'fields' => $fields, 'classification' => $classification,
|
||||
'site_title' => 's.ru', 'form_title' => 'f',
|
||||
'submitted_at' => '17.04.2026', 'reason' => 'Akismet',
|
||||
'ip' => '', 'user_agent' => '', 'is_retro' => false,
|
||||
]);
|
||||
|
||||
self::assertNull($r['reply_markup']);
|
||||
}
|
||||
|
||||
public function test_html_injection_in_name_is_escaped(): void
|
||||
{
|
||||
$fields = ['your-name' => '<script>alert(1)</script>', 'your-tel' => '+79031234567'];
|
||||
$classification = Classifier::classify($fields, ['reason' => 'Akismet']);
|
||||
$r = MessageFormatter::build([
|
||||
'fields' => $fields, 'classification' => $classification,
|
||||
'site_title' => 's.ru', 'form_title' => 'f',
|
||||
'submitted_at' => '17.04.2026', 'reason' => 'Akismet',
|
||||
'ip' => '', 'user_agent' => '', 'is_retro' => false,
|
||||
]);
|
||||
|
||||
self::assertStringNotContainsString('<script>', $r['text']);
|
||||
self::assertStringContainsString('<script>', $r['text']);
|
||||
}
|
||||
|
||||
public function test_long_message_is_truncated(): void
|
||||
{
|
||||
$long = str_repeat('А', 5000);
|
||||
$fields = ['your-message' => $long, 'your-tel' => '+79031234567'];
|
||||
$classification = Classifier::classify($fields, ['reason' => 'Akismet']);
|
||||
$r = MessageFormatter::build([
|
||||
'fields' => $fields, 'classification' => $classification,
|
||||
'site_title' => 's.ru', 'form_title' => 'f',
|
||||
'submitted_at' => '17.04.2026', 'reason' => 'Akismet',
|
||||
'ip' => '', 'user_agent' => '', 'is_retro' => false,
|
||||
]);
|
||||
|
||||
self::assertLessThanOrEqual(4096, mb_strlen($r['text']));
|
||||
self::assertStringContainsString('…[обрезано]', $r['text']);
|
||||
}
|
||||
|
||||
public function test_retro_prefix_added(): void
|
||||
{
|
||||
$fields = ['your-tel' => '+79031234567'];
|
||||
$classification = Classifier::classify($fields, ['reason' => 'Akismet']);
|
||||
$r = MessageFormatter::build([
|
||||
'fields' => $fields, 'classification' => $classification,
|
||||
'site_title' => 's.ru', 'form_title' => 'f',
|
||||
'submitted_at' => '17.04.2026', 'reason' => 'Akismet',
|
||||
'ip' => '', 'user_agent' => '', 'is_retro' => true,
|
||||
]);
|
||||
|
||||
self::assertStringContainsString('📂 Ретроспектива', $r['text']);
|
||||
}
|
||||
|
||||
public function test_spam_label_emoji(): void
|
||||
{
|
||||
$fields = [
|
||||
'your-name' => 'Melissa',
|
||||
'your-message' => 'SEO promotion, visit http://spam.net',
|
||||
];
|
||||
$classification = Classifier::classify($fields, ['reason' => 'Akismet']);
|
||||
$r = MessageFormatter::build([
|
||||
'fields' => $fields, 'classification' => $classification,
|
||||
'site_title' => 's.ru', 'form_title' => 'f',
|
||||
'submitted_at' => '17.04.2026', 'reason' => 'Akismet',
|
||||
'ip' => '', 'user_agent' => '', 'is_retro' => false,
|
||||
]);
|
||||
|
||||
self::assertStringContainsString('🔴 похоже спам', $r['text']);
|
||||
}
|
||||
|
||||
public function test_unclear_label_emoji(): void
|
||||
{
|
||||
$fields = ['your-name' => 'Олег', 'your-message' => 'Здравствуйте'];
|
||||
$classification = Classifier::classify($fields, ['reason' => 'Akismet']);
|
||||
$r = MessageFormatter::build([
|
||||
'fields' => $fields, 'classification' => $classification,
|
||||
'site_title' => 's.ru', 'form_title' => 'f',
|
||||
'submitted_at' => '17.04.2026', 'reason' => 'Akismet',
|
||||
'ip' => '', 'user_agent' => '', 'is_retro' => false,
|
||||
]);
|
||||
|
||||
self::assertStringContainsString('🟡 неясно', $r['text']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user