feat: add RichTextEditor component for rich text editing in articles

feat: create SanitizeBlogBodiesCommand to clean existing blog bodies according to current HTML sanitization policies

test: add AppointmentTreatmentSessionLinkTest to ensure appointment booking functionality works correctly with treatment session links
This commit is contained in:
hamed
2026-08-08 11:40:17 +03:30
parent 934405c42d
commit 47323daa27
36 changed files with 3461 additions and 12686 deletions
+24
View File
@@ -97,6 +97,30 @@ class BlogBodySanitizerTest extends ApiTestCase
$this->assertStringContainsString('ویرایش', $body);
}
/**
* جدول‌های مقاله‌های موجود ظاهرشان را از attributeهای قدیمیِ HTML می‌گیرند.
* این سه غیرقابل‌اجرا هستند و از ۲۰۲۶-۰۸-۰۸ مجازند؛ `style` همچنان می‌رود چون
* تنها attributeِ ظاهریِ جدول است که می‌تواند بارِ اجرایی حمل کند.
*/
public function testTableKeepsInertLayoutAttributesButLosesStyle(): void
{
$admin = $this->createUser(['ROLE_ADMIN']);
$res = $this->authJson('POST', '/api/v1/blog', $admin, [
'title' => 'مقالهٔ جدول',
'body' => '<table border="1" cellpadding="7" cellspacing="0" style="width:100%">'
. '<tr><td>سلول</td></tr></table>',
]);
$uuid = $res['data']['data']['uuid'] ?? $res['data']['uuid'];
$body = $this->storedBody($uuid);
$this->assertStringContainsString('border="1"', $body);
$this->assertStringContainsString('cellpadding="7"', $body);
$this->assertStringContainsString('cellspacing="0"', $body);
$this->assertStringNotContainsString('style=', $body);
$this->assertStringContainsString('سلول', $body);
}
/** بدنه‌ای که چیزی جز markup ناامن ندارد، بعد از پاک‌سازی خالی است → ۴۲۲، نه ذخیره. */
public function testBodyThatIsOnlyUnsafeMarkupIsRejected(): void
{