Files
sfera/packages/impact-engine/tests/test_impact.py
T
2026-05-16 19:03:49 +03:00

191 lines
8.0 KiB
Python

from pathlib import Path
from impact_engine import object_impact, object_impact_from_snapshot, routine_impact
from projection_engine import InMemoryProjection
from semantic_kernel import index_project
def test_routine_impact_uses_projection(tmp_path: Path):
module = tmp_path / "demo_module.bsl"
module.write_text(
"""
Процедура Проведение()
ПроверитьОстатки();
КонецПроцедуры
Процедура ПроверитьОстатки()
КонецПроцедуры
""",
encoding="utf-8",
)
graph = InMemoryProjection()
graph.project_snapshot(index_project(tmp_path, project_id="demo"))
impact = routine_impact(graph, "Проведение")
assert [node.name for node in impact.callees] == ["ПроверитьОстатки"]
def test_object_impact_collects_1c_metadata_module_routines_and_writes(tmp_path: Path):
(tmp_path / "metadata.xml").write_text(
"""
<Configuration>
<Document name="ЗаказПокупателя" qualifiedName="Документ.ЗаказПокупателя">
<Attribute name="Контрагент" qualifiedName="Документ.ЗаказПокупателя.Контрагент" />
<TabularSection name="Товары" qualifiedName="Документ.ЗаказПокупателя.Товары">
<Attribute name="Номенклатура" qualifiedName="Документ.ЗаказПокупателя.Товары.Номенклатура" />
</TabularSection>
<Form name="ФормаДокумента" qualifiedName="Документ.ЗаказПокупателя.ФормаДокумента">
<Command name="Провести" qualifiedName="Документ.ЗаказПокупателя.ФормаДокумента.Провести" action="ПровестиКоманда" />
</Form>
</Document>
<Role name="Менеджер" qualifiedName="Роль.Менеджер">
<Right object="Документ.ЗаказПокупателя" read="true" write="true" post="true" />
</Role>
</Configuration>
""",
encoding="utf-8",
)
module = tmp_path / "Documents" / "ЗаказПокупателя" / "Ext" / "ObjectModule.bsl"
module.parent.mkdir(parents=True)
module.write_text(
"""
Процедура Проведение()
ПроверитьОстатки();
Движения.ОстаткиТоваров.Записать();
КонецПроцедуры
Процедура ПроверитьОстатки()
КонецПроцедуры
Процедура ПровестиКоманда()
КонецПроцедуры
""",
encoding="utf-8",
)
graph = InMemoryProjection()
graph.project_snapshot(index_project(tmp_path, project_id="object-impact"))
impact = object_impact(graph, "Документ.ЗаказПокупателя")
assert impact is not None
assert impact.object.name == "ЗаказПокупателя"
assert [node.name for node in impact.modules] == ["ObjectModule"]
assert [node.name for node in impact.routines] == ["ПровестиКоманда", "Проведение", "ПроверитьОстатки"]
assert [node.name for node in impact.forms] == ["ФормаДокумента"]
assert [node.name for node in impact.commands] == ["Провести"]
assert [node.name for node in impact.attributes] == ["Контрагент"]
assert [node.name for node in impact.tabular_sections] == ["Товары"]
goods = impact.tabular_sections[0]
assert [node.name for node in impact.tabular_section_columns[goods.lineage_id]] == ["Номенклатура"]
assert [node.name for node in impact.roles] == ["Менеджер"]
assert impact.role_access[0].permissions["post"] == "true"
assert [node.name for node in impact.callees] == ["ПроверитьОстатки"]
assert [node.name for node in impact.writes] == ["ОстаткиТоваров"]
def test_object_impact_collects_form_event_handler_dependencies(tmp_path: Path):
(tmp_path / "metadata.xml").write_text(
"""
<Configuration>
<Document name="ЗаказПокупателя" qualifiedName="Документ.ЗаказПокупателя">
<Form
name="ФормаДокумента"
qualifiedName="Документ.ЗаказПокупателя.ФормаДокумента"
beforeWrite="ПередЗаписью"
/>
</Document>
</Configuration>
""",
encoding="utf-8",
)
module = tmp_path / "Documents" / "ЗаказПокупателя" / "Ext" / "ObjectModule.bsl"
module.parent.mkdir(parents=True)
module.write_text(
"""
Процедура ПередЗаписью()
Движения.ОстаткиТоваров.Записать();
КонецПроцедуры
""",
encoding="utf-8",
)
graph = InMemoryProjection()
graph.project_snapshot(index_project(tmp_path, project_id="form-event-impact"))
impact = object_impact(graph, "Документ.ЗаказПокупателя")
assert impact is not None
assert [node.name for node in impact.routines] == ["ПередЗаписью"]
assert [node.name for node in impact.writes] == ["ОстаткиТоваров"]
def test_object_impact_collects_scheduled_job_routine(tmp_path: Path):
(tmp_path / "metadata.xml").write_text(
"""
<Configuration>
<ScheduledJob name="ОбновлениеЦен" qualifiedName="РегламентноеЗадание.ОбновлениеЦен" method="ОбновитьЦены" />
</Configuration>
""",
encoding="utf-8",
)
module = tmp_path / "CommonModules" / "РегламентныеОперации" / "Module.bsl"
module.parent.mkdir(parents=True)
module.write_text("Процедура ОбновитьЦены()\nКонецПроцедуры\n", encoding="utf-8")
graph = InMemoryProjection()
graph.project_snapshot(index_project(tmp_path, project_id="job-impact"))
impact = object_impact(graph, "РегламентноеЗадание.ОбновлениеЦен")
assert impact is not None
assert [node.name for node in impact.jobs] == ["ОбновлениеЦен"]
assert [node.name for node in impact.routines] == ["ОбновитьЦены"]
def test_object_impact_from_snapshot_collects_scheduled_job_integrations(tmp_path: Path):
(tmp_path / "metadata.xml").write_text(
"""
<Configuration>
<ScheduledJob name="ОтправкаЗаказов" qualifiedName="РегламентноеЗадание.ОтправкаЗаказов" method="ОтправитьЗаказы" />
</Configuration>
""",
encoding="utf-8",
)
module = tmp_path / "CommonModules" / "Интеграция" / "Module.bsl"
module.parent.mkdir(parents=True)
module.write_text(
"""
Процедура ОтправитьЗаказы()
Адрес = "https://api.example.local/orders";
КонецПроцедуры
""",
encoding="utf-8",
)
snapshot = index_project(tmp_path, project_id="job-integration-impact")
impact = object_impact_from_snapshot(snapshot, "РегламентноеЗадание.ОтправкаЗаказов")
assert impact is not None
assert [node.name for node in impact.routines] == ["ОтправитьЗаказы"]
assert [endpoint.name for endpoint in impact.integrations] == ["https://api.example.local/orders"]
def test_object_impact_supports_report_metadata_owner(tmp_path: Path):
(tmp_path / "metadata.xml").write_text(
"""
<Configuration>
<Report name="Продажи" qualifiedName="Отчет.Продажи">
<Attribute name="Период" qualifiedName="Отчет.Продажи.Период" />
</Report>
</Configuration>
""",
encoding="utf-8",
)
graph = InMemoryProjection()
graph.project_snapshot(index_project(tmp_path, project_id="report-impact"))
impact = object_impact(graph, "Отчет.Продажи")
assert impact is not None
assert impact.object.name == "Продажи"
assert [node.name for node in impact.attributes] == ["Период"]