Files
2026-05-16 19:03:49 +03:00

247 lines
8.7 KiB
Python

from review_engine import review_snapshot
from semantic_kernel import index_project
from sir import ReferenceKind, SirSnapshot, SourceRef, UnresolvedReference
def test_review_snapshot_reports_unresolved_references():
snapshot = SirSnapshot(
snapshot_id="snapshot.demo",
project_id="demo",
unresolved_references=[
UnresolvedReference(
reference_id="ref.1",
kind=ReferenceKind.CALL,
source_lineage="lineage.procedure.demo",
target_name="Missing",
source_ref=SourceRef(source_path="module.bsl", line_start=2),
)
],
)
findings = review_snapshot(snapshot)
assert findings[0].title == "Unresolved call"
assert findings[0].source_path == "module.bsl"
def test_review_snapshot_reports_1c_objects_without_role_access(tmp_path):
xml = tmp_path / "metadata.xml"
xml.write_text(
"""
<Configuration>
<Document name="ЗаказПокупателя" qualifiedName="Документ.ЗаказПокупателя" />
</Configuration>
""",
encoding="utf-8",
)
snapshot = index_project(tmp_path, project_id="review-security")
findings = review_snapshot(snapshot)
assert findings[0].title == "Missing 1C role access"
assert "Документ.ЗаказПокупателя" in findings[0].message
def test_review_snapshot_reports_external_integrations(tmp_path):
module = tmp_path / "integration.bsl"
module.write_text(
"""
Процедура Отправить()
Адрес = "https://api.example.local/orders";
КонецПроцедуры
""",
encoding="utf-8",
)
snapshot = index_project(tmp_path, project_id="review-integrations")
findings = review_snapshot(snapshot)
assert any(finding.title == "External integration endpoint" for finding in findings)
def test_review_snapshot_reports_unresolved_1c_command_handler(tmp_path):
xml = tmp_path / "metadata.xml"
xml.write_text(
"""
<Configuration>
<Document name="ЗаказПокупателя" qualifiedName="Документ.ЗаказПокупателя">
<Form name="ФормаДокумента" qualifiedName="Документ.ЗаказПокупателя.ФормаДокумента">
<Command name="Провести" qualifiedName="Документ.ЗаказПокупателя.ФормаДокумента.Провести" action="ПровестиКоманда" />
</Form>
</Document>
</Configuration>
""",
encoding="utf-8",
)
snapshot = index_project(tmp_path, project_id="review-ui-handler")
findings = review_snapshot(snapshot)
assert any(
finding.title == "Unresolved 1C command handler"
and "ПровестиКоманда" in finding.message
for finding in findings
)
def test_review_snapshot_reports_unresolved_1c_form_event_handler(tmp_path):
xml = tmp_path / "metadata.xml"
xml.write_text(
"""
<Configuration>
<Document name="ЗаказПокупателя" qualifiedName="Документ.ЗаказПокупателя">
<Form
name="ФормаДокумента"
qualifiedName="Документ.ЗаказПокупателя.ФормаДокумента"
onCreate="ПриСозданииНаСервере"
beforeWrite="ПередЗаписью"
/>
</Document>
</Configuration>
""",
encoding="utf-8",
)
module = tmp_path / "form_module.bsl"
module.write_text("Процедура ПриСозданииНаСервере()\nКонецПроцедуры\n", encoding="utf-8")
snapshot = index_project(tmp_path, project_id="review-form-handler")
findings = review_snapshot(snapshot)
assert any(
finding.title == "Unresolved 1C form event handler"
and "ПередЗаписью" in finding.message
for finding in findings
)
assert not any(
finding.title == "Unresolved 1C form event handler"
and "ПриСозданииНаСервере" in finding.message
for finding in findings
)
def test_review_snapshot_reports_empty_1c_tabular_section(tmp_path):
xml = tmp_path / "metadata.xml"
xml.write_text(
"""
<Configuration>
<Document name="ЗаказПокупателя" qualifiedName="Документ.ЗаказПокупателя">
<TabularSection name="Услуги" qualifiedName="Документ.ЗаказПокупателя.Услуги" />
</Document>
</Configuration>
""",
encoding="utf-8",
)
snapshot = index_project(tmp_path, project_id="review-empty-tabular-section")
findings = review_snapshot(snapshot)
assert any(
finding.title == "Empty 1C tabular section"
and "Документ.ЗаказПокупателя.Услуги" in finding.message
for finding in findings
)
def test_review_snapshot_reports_tabular_section_without_subject_column(tmp_path):
xml = tmp_path / "metadata.xml"
xml.write_text(
"""
<Configuration>
<Document name="ЗаказПокупателя" qualifiedName="Документ.ЗаказПокупателя">
<TabularSection name="Товары" qualifiedName="Документ.ЗаказПокупателя.Товары">
<Attribute name="Количество" qualifiedName="Документ.ЗаказПокупателя.Товары.Количество" />
</TabularSection>
</Document>
</Configuration>
""",
encoding="utf-8",
)
snapshot = index_project(tmp_path, project_id="review-no-subject-column")
findings = review_snapshot(snapshot)
assert any(
finding.title == "No subject column in 1C tabular section"
and finding.severity.value == "INFO"
and "Документ.ЗаказПокупателя.Товары" in finding.message
for finding in findings
)
def test_review_snapshot_accepts_tabular_section_with_subject_column(tmp_path):
xml = tmp_path / "metadata.xml"
xml.write_text(
"""
<Configuration>
<Document name="ЗаказПокупателя" qualifiedName="Документ.ЗаказПокупателя">
<TabularSection name="Товары" qualifiedName="Документ.ЗаказПокупателя.Товары">
<Attribute name="Номенклатура" qualifiedName="Документ.ЗаказПокупателя.Товары.Номенклатура" />
<Attribute name="Количество" qualifiedName="Документ.ЗаказПокупателя.Товары.Количество" />
</TabularSection>
</Document>
</Configuration>
""",
encoding="utf-8",
)
snapshot = index_project(tmp_path, project_id="review-subject-column")
findings = review_snapshot(snapshot)
assert not any(finding.title == "No subject column in 1C tabular section" for finding in findings)
def test_review_snapshot_reports_document_posting_without_register_writes(tmp_path):
xml = tmp_path / "metadata.xml"
xml.write_text(
"""
<Configuration>
<Document name="ЗаказПокупателя" qualifiedName="Документ.ЗаказПокупателя" />
</Configuration>
""",
encoding="utf-8",
)
module = tmp_path / "Documents" / "ЗаказПокупателя" / "Ext" / "ObjectModule.bsl"
module.parent.mkdir(parents=True)
module.write_text("Процедура Проведение()\nКонецПроцедуры\n", encoding="utf-8")
snapshot = index_project(tmp_path, project_id="review-document-posting")
findings = review_snapshot(snapshot)
assert any(
finding.title == "Document posting has no register writes"
and finding.severity.value == "INFO"
and "Документ.ЗаказПокупателя" in finding.message
for finding in findings
)
def test_review_snapshot_reports_register_read_write_dependency(tmp_path):
module = tmp_path / "module.bsl"
module.write_text(
"""
Процедура ПроверитьОстатки()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
Остатки.Номенклатура
ИЗ
РегистрНакопления.ОстаткиТоваров КАК Остатки";
КонецПроцедуры
Процедура Проведение()
Движения.ОстаткиТоваров.Записать();
КонецПроцедуры
""",
encoding="utf-8",
)
snapshot = index_project(tmp_path, project_id="review-query-conflict")
findings = review_snapshot(snapshot)
assert any(
finding.title == "Register read/write dependency"
and "ПроверитьОстатки" in finding.message
and "Проведение" in finding.message
for finding in findings
)