507 lines
21 KiB
Python
507 lines
21 KiB
Python
from pathlib import Path
|
|
|
|
from semantic_kernel import index_project
|
|
from sir import EdgeKind, NodeKind
|
|
from ui_semantics import form_semantics
|
|
|
|
|
|
def test_index_project_extracts_xml_ui_semantics(tmp_path: Path):
|
|
xml = tmp_path / "form.xml"
|
|
xml.write_text(
|
|
"""
|
|
<Form name="ФормаДокумента" qualifiedName="Документ.Заказ.ФормаДокумента">
|
|
<Command name="Провести" qualifiedName="Документ.Заказ.ФормаДокумента.Провести" />
|
|
</Form>
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
snapshot = index_project(tmp_path, project_id="demo")
|
|
|
|
assert any(node.kind == NodeKind.FORM for node in snapshot.nodes)
|
|
assert any(edge.kind == EdgeKind.HAS_COMMAND for edge in snapshot.edges)
|
|
assert form_semantics(snapshot)[0].commands[0].name == "Провести"
|
|
|
|
|
|
def test_index_project_extracts_1c_metadata_objects(tmp_path: Path):
|
|
xml = tmp_path / "metadata.xml"
|
|
xml.write_text(
|
|
"""
|
|
<Configuration>
|
|
<Catalog name="Номенклатура" qualifiedName="Справочник.Номенклатура">
|
|
<Attribute name="Артикул" qualifiedName="Справочник.Номенклатура.Артикул" />
|
|
</Catalog>
|
|
<Document name="ЗаказПокупателя" qualifiedName="Документ.ЗаказПокупателя">
|
|
<TabularSection name="Товары" qualifiedName="Документ.ЗаказПокупателя.Товары">
|
|
<Attribute name="Номенклатура" qualifiedName="Документ.ЗаказПокупателя.Товары.Номенклатура" />
|
|
</TabularSection>
|
|
<Form name="ФормаДокумента" qualifiedName="Документ.ЗаказПокупателя.ФормаДокумента">
|
|
<Command name="Провести" qualifiedName="Документ.ЗаказПокупателя.ФормаДокумента.Провести" />
|
|
</Form>
|
|
</Document>
|
|
<Role name="Менеджер" qualifiedName="Роль.Менеджер" />
|
|
<MetadataObject type="ScheduledJob">
|
|
<Name>ОбменСКассовымУзлом</Name>
|
|
<QualifiedName>РегламентноеЗадание.ОбменСКассовымУзлом</QualifiedName>
|
|
</MetadataObject>
|
|
</Configuration>
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
snapshot = index_project(tmp_path, project_id="metadata")
|
|
|
|
assert any(node.kind == NodeKind.CATALOG and node.name == "Номенклатура" for node in snapshot.nodes)
|
|
assert any(node.kind == NodeKind.DOCUMENT and node.name == "ЗаказПокупателя" for node in snapshot.nodes)
|
|
assert any(node.kind == NodeKind.TABULAR_SECTION and node.name == "Товары" for node in snapshot.nodes)
|
|
assert any(node.kind == NodeKind.ROLE and node.name == "Менеджер" for node in snapshot.nodes)
|
|
assert any(node.kind == NodeKind.SCHEDULED_JOB for node in snapshot.nodes)
|
|
assert any(edge.kind == EdgeKind.HAS_ATTRIBUTE for edge in snapshot.edges)
|
|
assert any(edge.kind == EdgeKind.HAS_TABULAR_SECTION for edge in snapshot.edges)
|
|
tabular_section = next(node for node in snapshot.nodes if node.kind == NodeKind.TABULAR_SECTION)
|
|
column = next(node for node in snapshot.nodes if node.kind == NodeKind.ATTRIBUTE and node.name == "Номенклатура")
|
|
assert any(
|
|
edge.kind == EdgeKind.HAS_ATTRIBUTE
|
|
and edge.source_lineage == tabular_section.lineage_id
|
|
and edge.target_lineage == column.lineage_id
|
|
for edge in snapshot.edges
|
|
)
|
|
assert any(edge.kind == EdgeKind.HAS_FORM for edge in snapshot.edges)
|
|
assert any(edge.kind == EdgeKind.HAS_COMMAND for edge in snapshot.edges)
|
|
|
|
|
|
def test_index_project_keeps_extended_1c_metadata_objects(tmp_path: Path):
|
|
xml = tmp_path / "metadata.xml"
|
|
xml.write_text(
|
|
"""
|
|
<Configuration>
|
|
<Subsystem name="Продажи" qualifiedName="Подсистема.Продажи" />
|
|
<Role name="Менеджер" qualifiedName="Роль.Менеджер" />
|
|
<Sequence name="ПроведениеДокументов" qualifiedName="Последовательность.ПроведениеДокументов" />
|
|
<DocumentNumerator name="ОбщийНумератор" qualifiedName="НумераторДокументов.ОбщийНумератор" />
|
|
<CommonForm name="ФормаПодбора" qualifiedName="ОбщаяФорма.ФормаПодбора" />
|
|
<FunctionalOption name="ДоступностьСкидок" qualifiedName="ФункциональнаяОпция.ДоступностьСкидок" />
|
|
<WebService name="Обмен" qualifiedName="WebСервис.Обмен" />
|
|
<WSReference name="ВнешнийСервис" qualifiedName="WSСсылка.ВнешнийСервис" />
|
|
<WebSocketClient name="Чат" qualifiedName="WebSocketКлиент.Чат" />
|
|
<IntegrationService name="Интеграция" qualifiedName="СервисИнтеграции.Интеграция" />
|
|
</Configuration>
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
snapshot = index_project(tmp_path, project_id="extended-metadata")
|
|
by_kind = {node.kind for node in snapshot.nodes}
|
|
|
|
assert {
|
|
NodeKind.SUBSYSTEM,
|
|
NodeKind.ROLE,
|
|
NodeKind.SEQUENCE,
|
|
NodeKind.DOCUMENT_NUMERATOR,
|
|
NodeKind.COMMON_FORM,
|
|
NodeKind.FUNCTIONAL_OPTION,
|
|
NodeKind.WEB_SERVICE,
|
|
NodeKind.WS_REFERENCE,
|
|
NodeKind.WEBSOCKET_CLIENT,
|
|
NodeKind.INTEGRATION_SERVICE,
|
|
}.issubset(by_kind)
|
|
|
|
|
|
def test_index_project_links_access_profiles_groups_and_users(tmp_path: Path):
|
|
xml = tmp_path / "access.xml"
|
|
xml.write_text(
|
|
"""
|
|
<AccessData>
|
|
<Role name="ЧтениеПродаж" qualifiedName="Роль.ЧтениеПродаж" />
|
|
<AccessProfile name="МенеджерПродаж">
|
|
<Role name="ЧтениеПродаж" />
|
|
</AccessProfile>
|
|
<AccessGroup name="ОтделПродаж" profile="МенеджерПродаж">
|
|
<Member user="ivanov" />
|
|
</AccessGroup>
|
|
<InfobaseUser name="ivanov" fullName="Иванов Иван" />
|
|
</AccessData>
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
snapshot = index_project(tmp_path, project_id="access-graph")
|
|
|
|
assert any(node.kind == NodeKind.ACCESS_PROFILE and node.name == "МенеджерПродаж" for node in snapshot.nodes)
|
|
assert any(node.kind == NodeKind.ACCESS_GROUP and node.name == "ОтделПродаж" for node in snapshot.nodes)
|
|
assert any(node.kind == NodeKind.ACCESS_USER and node.name == "ivanov" for node in snapshot.nodes)
|
|
assert any(edge.kind == EdgeKind.ASSIGNS_ROLE for edge in snapshot.edges)
|
|
assert any(edge.kind == EdgeKind.MEMBER_OF for edge in snapshot.edges)
|
|
|
|
|
|
def test_index_project_remaps_edges_from_duplicate_metadata_nodes(tmp_path: Path):
|
|
first = tmp_path / "first.xml"
|
|
first.write_text(
|
|
"""
|
|
<Configuration>
|
|
<MetadataObject type="ChartOfCharacteristicTypes">
|
|
<Name>СвойстваОбъектов</Name>
|
|
<QualifiedName>ПланВидовХарактеристик.СвойстваОбъектов</QualifiedName>
|
|
</MetadataObject>
|
|
</Configuration>
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
second = tmp_path / "second.xml"
|
|
second.write_text(
|
|
"""
|
|
<Configuration>
|
|
<MetadataObject type="ChartOfCharacteristicTypes">
|
|
<Name>СвойстваОбъектов</Name>
|
|
<QualifiedName>ПланВидовХарактеристик.СвойстваОбъектов</QualifiedName>
|
|
</MetadataObject>
|
|
<Attribute name="ТипЗначения" qualifiedName="ПланВидовХарактеристик.СвойстваОбъектов.ТипЗначения" />
|
|
</Configuration>
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
snapshot = index_project(tmp_path, project_id="metadata-duplicates")
|
|
|
|
chart = next(node for node in snapshot.nodes if node.kind == NodeKind.CHART_OF_CHARACTERISTIC_TYPES)
|
|
attribute = next(node for node in snapshot.nodes if node.kind == NodeKind.ATTRIBUTE)
|
|
assert any(
|
|
edge.kind == EdgeKind.HAS_ATTRIBUTE
|
|
and edge.source_lineage == chart.lineage_id
|
|
and edge.target_lineage == attribute.lineage_id
|
|
for edge in snapshot.edges
|
|
)
|
|
|
|
|
|
def test_index_project_links_document_metadata_to_object_module(tmp_path: 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(
|
|
"""
|
|
Процедура Проведение()
|
|
КонецПроцедуры
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
snapshot = index_project(tmp_path, project_id="metadata-links")
|
|
|
|
document = next(node for node in snapshot.nodes if node.kind == NodeKind.DOCUMENT)
|
|
module_node = next(node for node in snapshot.nodes if node.kind == NodeKind.MODULE)
|
|
link = next(
|
|
edge
|
|
for edge in snapshot.edges
|
|
if edge.kind == EdgeKind.CONTAINS
|
|
and edge.source_lineage == document.lineage_id
|
|
and edge.target_lineage == module_node.lineage_id
|
|
)
|
|
assert link.attributes["module_role"] == "OBJECT_MODULE"
|
|
|
|
|
|
def test_index_project_links_common_module_metadata_to_bsl_module(tmp_path: Path):
|
|
xml = tmp_path / "metadata.xml"
|
|
xml.write_text(
|
|
"""
|
|
<Configuration>
|
|
<CommonModule name="ИнтеграцияСКассой" qualifiedName="ОбщийМодуль.ИнтеграцияСКассой" />
|
|
</Configuration>
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
module = tmp_path / "CommonModules" / "ИнтеграцияСКассой" / "Module.bsl"
|
|
module.parent.mkdir(parents=True)
|
|
module.write_text(
|
|
"""
|
|
Процедура ОтправитьЧек()
|
|
КонецПроцедуры
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
snapshot = index_project(tmp_path, project_id="common-module-links")
|
|
|
|
common_module = next(node for node in snapshot.nodes if node.kind == NodeKind.COMMON_MODULE)
|
|
bsl_module = next(node for node in snapshot.nodes if node.kind == NodeKind.MODULE)
|
|
assert any(
|
|
edge.kind == EdgeKind.CONTAINS
|
|
and edge.source_lineage == common_module.lineage_id
|
|
and edge.target_lineage == bsl_module.lineage_id
|
|
for edge in snapshot.edges
|
|
)
|
|
|
|
|
|
def test_index_project_reads_edt_mdo_metadata(tmp_path: Path):
|
|
catalog_dir = tmp_path / "src" / "Catalogs" / "Товары"
|
|
catalog_dir.mkdir(parents=True)
|
|
(catalog_dir / "Товары.mdo").write_text(
|
|
"""
|
|
<mdclass:Catalog xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass">
|
|
<name>Товары</name>
|
|
<attributes>
|
|
<name>Артикул</name>
|
|
</attributes>
|
|
<forms>
|
|
<name>ФормаЭлемента</name>
|
|
</forms>
|
|
</mdclass:Catalog>
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
report_dir = tmp_path / "src" / "Reports" / "АнализПродаж"
|
|
report_dir.mkdir(parents=True)
|
|
(report_dir / "АнализПродаж.mdo").write_text(
|
|
"""
|
|
<mdclass:Report xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass">
|
|
<name>АнализПродаж</name>
|
|
</mdclass:Report>
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
snapshot = index_project(tmp_path, project_id="edt-mdo")
|
|
|
|
catalog = next(node for node in snapshot.nodes if node.kind == NodeKind.CATALOG)
|
|
attribute = next(node for node in snapshot.nodes if node.kind == NodeKind.ATTRIBUTE and node.name == "Артикул")
|
|
form = next(node for node in snapshot.nodes if node.kind == NodeKind.FORM)
|
|
report = next(node for node in snapshot.nodes if node.kind == NodeKind.REPORT)
|
|
assert catalog.qualified_name == "Справочник.Товары"
|
|
assert attribute.qualified_name == "Справочник.Товары.Артикул"
|
|
assert form.qualified_name == "Справочник.Товары.ФормаЭлемента"
|
|
assert report.qualified_name == "Отчет.АнализПродаж"
|
|
assert any(edge.kind == EdgeKind.HAS_ATTRIBUTE and edge.source_lineage == catalog.lineage_id for edge in snapshot.edges)
|
|
assert any(edge.kind == EdgeKind.HAS_FORM and edge.source_lineage == catalog.lineage_id for edge in snapshot.edges)
|
|
|
|
|
|
def test_index_project_preserves_register_dimension_and_resource_roles(tmp_path: Path):
|
|
register_dir = tmp_path / "src" / "AccumulationRegisters" / "ОстаткиТоваров"
|
|
register_dir.mkdir(parents=True)
|
|
(register_dir / "ОстаткиТоваров.mdo").write_text(
|
|
"""
|
|
<mdclass:AccumulationRegister xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass">
|
|
<name>ОстаткиТоваров</name>
|
|
<dimensions>
|
|
<name>Номенклатура</name>
|
|
</dimensions>
|
|
<resources>
|
|
<name>Количество</name>
|
|
</resources>
|
|
</mdclass:AccumulationRegister>
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
snapshot = index_project(tmp_path, project_id="register-fields")
|
|
|
|
register = next(node for node in snapshot.nodes if node.kind == NodeKind.REGISTER)
|
|
dimension = next(node for node in snapshot.nodes if node.kind == NodeKind.ATTRIBUTE and node.name == "Номенклатура")
|
|
resource = next(node for node in snapshot.nodes if node.kind == NodeKind.ATTRIBUTE and node.name == "Количество")
|
|
assert dimension.attributes["attribute_role"] == "DIMENSION"
|
|
assert resource.attributes["attribute_role"] == "RESOURCE"
|
|
assert any(
|
|
edge.kind == EdgeKind.HAS_ATTRIBUTE
|
|
and edge.source_lineage == register.lineage_id
|
|
and edge.target_lineage == dimension.lineage_id
|
|
for edge in snapshot.edges
|
|
)
|
|
assert any(
|
|
edge.kind == EdgeKind.HAS_ATTRIBUTE
|
|
and edge.source_lineage == register.lineage_id
|
|
and edge.target_lineage == resource.lineage_id
|
|
for edge in snapshot.edges
|
|
)
|
|
|
|
|
|
def test_index_project_links_role_rights_to_metadata_objects(tmp_path: Path):
|
|
xml = tmp_path / "roles.xml"
|
|
xml.write_text(
|
|
"""
|
|
<Configuration>
|
|
<Document name="ЗаказПокупателя" qualifiedName="Документ.ЗаказПокупателя" />
|
|
<Role name="Менеджер" qualifiedName="Роль.Менеджер">
|
|
<Right object="Документ.ЗаказПокупателя" read="true" write="true" post="true" />
|
|
</Role>
|
|
</Configuration>
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
snapshot = index_project(tmp_path, project_id="role-rights")
|
|
|
|
role = next(node for node in snapshot.nodes if node.kind == NodeKind.ROLE)
|
|
document = next(node for node in snapshot.nodes if node.kind == NodeKind.DOCUMENT)
|
|
right = next(edge for edge in snapshot.edges if edge.kind == EdgeKind.GRANTS_ACCESS)
|
|
assert right.source_lineage == role.lineage_id
|
|
assert right.target_lineage == document.lineage_id
|
|
assert right.attributes["post"] == "true"
|
|
|
|
|
|
def test_index_project_links_child_element_command_action_and_role_right(tmp_path: Path):
|
|
xml = tmp_path / "metadata.xml"
|
|
xml.write_text(
|
|
"""
|
|
<Configuration>
|
|
<Document>
|
|
<Name>ЗаказПокупателя</Name>
|
|
<QualifiedName>Документ.ЗаказПокупателя</QualifiedName>
|
|
<Form>
|
|
<Name>ФормаДокумента</Name>
|
|
<Command>
|
|
<Name>Провести</Name>
|
|
<Action>ПровестиКоманда</Action>
|
|
</Command>
|
|
</Form>
|
|
</Document>
|
|
<Role>
|
|
<Name>Менеджер</Name>
|
|
<Right read="true">
|
|
<Object>Документ.ЗаказПокупателя</Object>
|
|
</Right>
|
|
</Role>
|
|
</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="child-element-metadata")
|
|
|
|
document = next(node for node in snapshot.nodes if node.kind == NodeKind.DOCUMENT)
|
|
role = next(node for node in snapshot.nodes if node.kind == NodeKind.ROLE)
|
|
command = next(node for node in snapshot.nodes if node.kind == NodeKind.COMMAND)
|
|
assert any(
|
|
edge.kind == EdgeKind.GRANTS_ACCESS
|
|
and edge.source_lineage == role.lineage_id
|
|
and edge.target_lineage == document.lineage_id
|
|
for edge in snapshot.edges
|
|
)
|
|
assert any(
|
|
edge.kind == EdgeKind.HANDLES
|
|
and edge.source_lineage == command.lineage_id
|
|
and edge.attributes["handler_name"] == "ПровестиКоманда"
|
|
for edge in snapshot.edges
|
|
)
|
|
|
|
|
|
def test_index_project_links_form_command_to_handler(tmp_path: Path):
|
|
xml = tmp_path / "form.xml"
|
|
xml.write_text(
|
|
"""
|
|
<Form name="ФормаДокумента" qualifiedName="Документ.Заказ.ФормаДокумента">
|
|
<Command name="Провести" qualifiedName="Документ.Заказ.ФормаДокумента.Провести" action="ПровестиКоманда" />
|
|
</Form>
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
module = tmp_path / "form_module.bsl"
|
|
module.write_text("Процедура ПровестиКоманда()\nКонецПроцедуры\n", encoding="utf-8")
|
|
|
|
snapshot = index_project(tmp_path, project_id="ui-handlers")
|
|
|
|
assert any(edge.kind == EdgeKind.HANDLES for edge in snapshot.edges)
|
|
|
|
|
|
def test_index_project_extracts_managed_form_items_without_layouts(tmp_path: Path):
|
|
xml = tmp_path / "form.xml"
|
|
xml.write_text(
|
|
"""
|
|
<Form name="ФормаДокумента" qualifiedName="Документ.Заказ.ФормаДокумента">
|
|
<items xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="form:FormGroup" name="Основное">
|
|
<caption>Основное</caption>
|
|
<items xsi:type="form:FormField" name="Номер">
|
|
<caption>Номер</caption>
|
|
<dataPath>Объект.Номер</dataPath>
|
|
</items>
|
|
</items>
|
|
<Layout name="ПечатнаяФорма" qualifiedName="Документ.Заказ.ФормаДокумента.ПечатнаяФорма" />
|
|
</Form>
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
snapshot = index_project(tmp_path, project_id="ui-form-items")
|
|
|
|
form = form_semantics(snapshot)[0]
|
|
assert [element.name for element in form.elements] == ["Основное", "Номер"]
|
|
assert all(element.kind == NodeKind.FORM_ELEMENT for element in form.elements)
|
|
assert form.elements[1].attributes["dataPath"] == "Объект.Номер"
|
|
assert not any(element.name == "ПечатнаяФорма" for element in form.elements)
|
|
|
|
|
|
def test_index_project_extracts_edt_form_items_from_form_file_path(tmp_path: Path):
|
|
form_dir = tmp_path / "src" / "Catalogs" / "ВидыЗаказовПокупателей" / "Forms" / "ФормаСписка"
|
|
form_dir.mkdir(parents=True)
|
|
(form_dir / "Form.form").write_text(
|
|
"""
|
|
<form:Form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:form="http://g5.1c.ru/v8/dt/form">
|
|
<items xsi:type="form:Table">
|
|
<name>Список</name>
|
|
<dataPath xsi:type="form:DataPath">
|
|
<segments>Список</segments>
|
|
</dataPath>
|
|
<items xsi:type="form:FormField">
|
|
<name>Наименование</name>
|
|
<dataPath xsi:type="form:DataPath">
|
|
<segments>Список.Description</segments>
|
|
</dataPath>
|
|
</items>
|
|
</items>
|
|
</form:Form>
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
snapshot = index_project(tmp_path, project_id="edt-form-items")
|
|
|
|
form = next(item for item in form_semantics(snapshot) if item.form.name == "ФормаСписка")
|
|
assert form.form.qualified_name == "Справочник.ВидыЗаказовПокупателей.ФормаСписка"
|
|
assert [element.name for element in form.elements] == ["Список", "Наименование"]
|
|
assert form.elements[0].attributes["control_kind"] == "Table"
|
|
assert form.elements[1].attributes["dataPath"] == "Список.Description"
|
|
|
|
|
|
def test_index_project_links_form_events_to_handlers(tmp_path: Path):
|
|
xml = tmp_path / "form.xml"
|
|
xml.write_text(
|
|
"""
|
|
<Form
|
|
name="ФормаДокумента"
|
|
qualifiedName="Документ.Заказ.ФормаДокумента"
|
|
onCreate="ПриСозданииНаСервере"
|
|
beforeWrite="ПередЗаписью"
|
|
/>
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
module = tmp_path / "form_module.bsl"
|
|
module.write_text(
|
|
"""
|
|
Процедура ПриСозданииНаСервере()
|
|
КонецПроцедуры
|
|
|
|
Процедура ПередЗаписью()
|
|
КонецПроцедуры
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
snapshot = index_project(tmp_path, project_id="ui-form-events")
|
|
|
|
form = next(node for node in snapshot.nodes if node.kind == NodeKind.FORM)
|
|
handlers = {
|
|
edge.attributes["handler_name"]: edge
|
|
for edge in snapshot.edges
|
|
if edge.kind == EdgeKind.HANDLES and edge.source_lineage == form.lineage_id
|
|
}
|
|
assert set(handlers) == {"ПриСозданииНаСервере", "ПередЗаписью"}
|
|
assert {edge.attributes["link_type"] for edge in handlers.values()} == {"FORM_EVENT"}
|