improve bazdid 4
This commit is contained in:
1 parent
f86d060e4d
commit
8fd881e0ea
10 files changed
+1752
-320
No files matched your search
@@ -9,6 +9,8 @@
|
||||
هیچ پاسخی نباید کد ۵۰۰ داشته باشد.
|
||||
"""
|
||||
import json
|
||||
import re
|
||||
from html.parser import HTMLParser
|
||||
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
@@ -257,3 +259,114 @@ class ViewSmokeTests(TestCase):
|
||||
f"دادهاند: {failures}"
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class _DivBalanceParser(HTMLParser):
|
||||
"""شمارندهٔ عمق <div> با احترام به محتوای <script>/<style>.
|
||||
|
||||
نکته: HTMLParser محتوای script/style را متن خام میداند، پس `<div>` داخل
|
||||
رشتهٔ جاوااسکریپت بهاشتباه شمرده نمیشود — همان چیزی که شمارش متنی ساده
|
||||
اشتباه میکند.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(convert_charrefs=True)
|
||||
self.depth = 0
|
||||
self.min_depth = 0
|
||||
self.depth_at_body = None
|
||||
|
||||
def handle_starttag(self, tag, attrs):
|
||||
if tag == 'div':
|
||||
self.depth += 1
|
||||
|
||||
def handle_endtag(self, tag):
|
||||
if tag == 'div':
|
||||
self.depth -= 1
|
||||
self.min_depth = min(self.min_depth, self.depth)
|
||||
elif tag == 'body':
|
||||
self.depth_at_body = self.depth
|
||||
|
||||
|
||||
class BaseTemplateStructureTests(TestCase):
|
||||
"""ساختار HTML قالب پایه.
|
||||
|
||||
چرا؟ قالب `base.html` یک `<div class="">` باز میکرد که هرگز بسته نمیشد.
|
||||
مرورگر آن را در EOF خودکار میبست، پس هیچ خطایی دیده نمیشد؛ ولی همهٔ
|
||||
صفحات HTML نامعتبر تولید میکردند و بازسازی DOM توسط جاوااسکریپت و
|
||||
پارسرهای سختگیر میتوانست بشکند.
|
||||
"""
|
||||
|
||||
URLS = ['/panel/', '/panel/customers/', '/panel/entezar/', '/panel/rezayat/',
|
||||
'/panel/hesabdari/', '/panel/report/']
|
||||
|
||||
def setUp(self):
|
||||
self.user = make_user('structureAdmin', superuser=True)
|
||||
self.client.force_login(self.user)
|
||||
|
||||
def _parsed_pages(self):
|
||||
"""صفحاتی که در محیط تست کد ۲۰۰ میدهند را پارس میکند.
|
||||
|
||||
برخی صفحات روی دیتابیس خالی خطای داخلی میدهند (باگ مستقل، پوششدادهشده
|
||||
در تست دودی)؛ آنها اینجا کنار گذاشته میشوند. برای اینکه تست بیاثر
|
||||
نشود، تعداد صفحات بررسیشده assert میشود.
|
||||
"""
|
||||
parsed = []
|
||||
for url in self.URLS:
|
||||
response = self.client.get(url)
|
||||
if response.status_code != 200:
|
||||
continue
|
||||
parser = _DivBalanceParser()
|
||||
parser.feed(response.content.decode('utf-8', 'replace'))
|
||||
parsed.append((url, parser))
|
||||
return parsed
|
||||
|
||||
def test_every_page_has_balanced_divs(self):
|
||||
"""در پایان سند، هیچ <div> بازی نباید باقی بماند."""
|
||||
parsed = self._parsed_pages()
|
||||
self.assertGreaterEqual(len(parsed), 5,
|
||||
msg='صفحات کافی برای بررسی ساختار رندر نشدند')
|
||||
for url, parser in parsed:
|
||||
with self.subTest(url=url):
|
||||
self.assertEqual(
|
||||
parser.depth_at_body, 0,
|
||||
msg='در %s هنگام </body> تعداد %d تگ <div> بستهنشده ماند'
|
||||
% (url, parser.depth_at_body),
|
||||
)
|
||||
|
||||
def test_no_stray_closing_div(self):
|
||||
"""عمق هرگز نباید منفی شود؛ یعنی </div> اضافی هم وجود ندارد."""
|
||||
parsed = self._parsed_pages()
|
||||
self.assertGreaterEqual(len(parsed), 5)
|
||||
for url, parser in parsed:
|
||||
with self.subTest(url=url):
|
||||
self.assertGreaterEqual(parser.min_depth, 0,
|
||||
msg='در %s تگ </div> اضافی وجود دارد' % url)
|
||||
|
||||
def test_base_template_comments_are_single_line(self):
|
||||
"""کامنتهای {# ... #} باید تکخطی باشند.
|
||||
|
||||
موتور قالب جنگو (۳.۲) الگوی کامنت را بدون re.DOTALL میشناسد؛ کامنت
|
||||
چندخطی حذف نمیشود و عیناً در HTML چاپ میشود — در همین اصلاح، یک
|
||||
`<div class="">` داخل کامنت چندخطی، بهعنوان تگ واقعی به خروجی اضافه
|
||||
شده بود و تگ بستن را میبلعید.
|
||||
"""
|
||||
import io
|
||||
import os
|
||||
|
||||
templates_root = os.path.join('admin_panel', 'templates')
|
||||
offenders = []
|
||||
for base, _dirs, files in os.walk(templates_root):
|
||||
for name in files:
|
||||
if not name.endswith('.html'):
|
||||
continue
|
||||
path = os.path.join(base, name)
|
||||
text = io.open(path, encoding='utf-8', errors='replace').read()
|
||||
for match in re.finditer(r'\{#', text):
|
||||
tail = text[match.start():match.start() + 500]
|
||||
line_end = tail.find('\n')
|
||||
end = line_end if line_end > -1 else len(tail)
|
||||
if tail.find('#}', 0, end) == -1:
|
||||
offenders.append('%s:%d' % (
|
||||
path, text[:match.start()].count('\n') + 1))
|
||||
self.assertEqual(offenders, [],
|
||||
msg='کامنت چندخطی در این قالبها حذف نمیشود: %s' % offenders)
|
||||
Reference in new issue
Block a user