Initial SFERA platform baseline
This commit is contained in:
@@ -0,0 +1,658 @@
|
||||
from pathlib import Path
|
||||
|
||||
from one_c_normalizer import (
|
||||
COMMON_BRANCH_CHILDREN,
|
||||
METADATA_TYPE_BY_BRANCH,
|
||||
METADATA_TYPE_BY_CODE,
|
||||
build_normalized_project,
|
||||
normalize_bsl_source,
|
||||
normalize_one_c_project,
|
||||
normalize_source_path,
|
||||
parse_one_c_xml_file,
|
||||
)
|
||||
|
||||
|
||||
def test_normalize_bsl_source_removes_bom_and_normalizes_newlines():
|
||||
assert normalize_bsl_source("\ufeffПроцедура X()\r\n A = 1; \r\n\r\n") == (
|
||||
"Процедура X()\n A = 1;\n"
|
||||
)
|
||||
|
||||
|
||||
def test_normalize_source_path_uses_forward_slashes():
|
||||
assert normalize_source_path("src\\module.bsl") == "src/module.bsl"
|
||||
|
||||
|
||||
def test_parse_one_c_xml_file_extracts_ui_objects(tmp_path: Path):
|
||||
xml = tmp_path / "form.xml"
|
||||
xml.write_text(
|
||||
"""
|
||||
<Form name="ФормаДокумента" qualifiedName="Документ.Заказ.ФормаДокумента">
|
||||
<Command name="Провести" />
|
||||
<Attribute name="Контрагент" />
|
||||
</Form>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
objects = parse_one_c_xml_file(xml)
|
||||
|
||||
assert [item.object_kind for item in objects] == ["FORM", "COMMAND", "ATTRIBUTE"]
|
||||
assert objects[0].qualified_name == "Документ.Заказ.ФормаДокумента"
|
||||
|
||||
|
||||
def test_parse_one_c_xml_file_extracts_metadata_objects(tmp_path: Path):
|
||||
xml = tmp_path / "metadata.xml"
|
||||
xml.write_text(
|
||||
"""
|
||||
<Configuration>
|
||||
<Catalog name="Номенклатура" qualifiedName="Справочник.Номенклатура">
|
||||
<Attribute name="Артикул" qualifiedName="Справочник.Номенклатура.Артикул" />
|
||||
</Catalog>
|
||||
<Document>
|
||||
<Name>ЗаказПокупателя</Name>
|
||||
<QualifiedName>Документ.ЗаказПокупателя</QualifiedName>
|
||||
<TabularSection name="Товары" qualifiedName="Документ.ЗаказПокупателя.Товары" />
|
||||
<Form name="ФормаДокумента" qualifiedName="Документ.ЗаказПокупателя.ФормаДокумента" />
|
||||
</Document>
|
||||
<MetadataObject type="AccumulationRegister">
|
||||
<Name>ОстаткиТоваров</Name>
|
||||
<QualifiedName>РегистрНакопления.ОстаткиТоваров</QualifiedName>
|
||||
</MetadataObject>
|
||||
</Configuration>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
objects = parse_one_c_xml_file(xml)
|
||||
|
||||
assert [item.object_kind for item in objects] == [
|
||||
"CATALOG",
|
||||
"ATTRIBUTE",
|
||||
"DOCUMENT",
|
||||
"TABULAR_SECTION",
|
||||
"FORM",
|
||||
"ACCUMULATION_REGISTER",
|
||||
]
|
||||
assert objects[2].qualified_name == "Документ.ЗаказПокупателя"
|
||||
assert objects[5].name == "ОстаткиТоваров"
|
||||
|
||||
|
||||
def test_normalize_one_c_project_preserves_configuration_root_metadata(tmp_path: Path):
|
||||
xml = tmp_path / "configuration.xml"
|
||||
xml.write_text(
|
||||
"""
|
||||
<Configuration name="УправлениеТорговлей" synonym="Управление торговлей" platformVersion="8.3.24" compatibilityMode="8.3.20">
|
||||
<Catalog name="Контрагенты" qualifiedName="Справочник.Контрагенты" />
|
||||
</Configuration>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
normalized = normalize_one_c_project(tmp_path, project_id="configuration-root")
|
||||
|
||||
assert normalized.configuration.name == "УправлениеТорговлей"
|
||||
assert normalized.configuration.metadata["synonym"] == "Управление торговлей"
|
||||
assert normalized.configuration.metadata["platformVersion"] == "8.3.24"
|
||||
assert normalized.configuration.metadata["compatibilityMode"] == "8.3.20"
|
||||
assert normalized.configuration.metadata["source_path"].endswith("configuration.xml")
|
||||
assert [group.name for group in normalized.configuration.groups] == ["Справочники"]
|
||||
|
||||
|
||||
def test_parse_edt_mdo_derives_qualified_names(tmp_path: Path):
|
||||
mdo = tmp_path / "Товары.mdo"
|
||||
mdo.write_text(
|
||||
"""
|
||||
<mdclass:Catalog xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass">
|
||||
<name>Товары</name>
|
||||
<attributes>
|
||||
<name>Артикул</name>
|
||||
</attributes>
|
||||
<tabularSections>
|
||||
<name>Цены</name>
|
||||
<attributes>
|
||||
<name>ВидЦены</name>
|
||||
</attributes>
|
||||
</tabularSections>
|
||||
<forms>
|
||||
<name>ФормаЭлемента</name>
|
||||
</forms>
|
||||
</mdclass:Catalog>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
objects = parse_one_c_xml_file(mdo)
|
||||
by_name = {item.name: item for item in objects}
|
||||
|
||||
assert by_name["Товары"].qualified_name == "Справочник.Товары"
|
||||
assert by_name["Артикул"].qualified_name == "Справочник.Товары.Артикул"
|
||||
assert by_name["Цены"].qualified_name == "Справочник.Товары.Цены"
|
||||
assert by_name["ВидЦены"].qualified_name == "Справочник.Товары.Цены.ВидЦены"
|
||||
assert by_name["ФормаЭлемента"].qualified_name == "Справочник.Товары.ФормаЭлемента"
|
||||
|
||||
|
||||
def test_normalize_http_service_keeps_url_templates_and_methods(tmp_path: Path):
|
||||
mdo = tmp_path / "ПубличныйAPI.mdo"
|
||||
mdo.write_text(
|
||||
"""
|
||||
<mdclass:HTTPService xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass">
|
||||
<name>ПубличныйAPI</name>
|
||||
<rootURL>api</rootURL>
|
||||
<urlTemplates>
|
||||
<name>Orders</name>
|
||||
<template>/orders/{id}</template>
|
||||
<methods>
|
||||
<httpMethod>GET</httpMethod>
|
||||
<handler>ПолучитьЗаказ</handler>
|
||||
</methods>
|
||||
</urlTemplates>
|
||||
</mdclass:HTTPService>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
normalized = normalize_one_c_project(tmp_path, project_id="http-service")
|
||||
http_group = next(group for group in normalized.configuration.groups if group.name == "HTTP-сервисы")
|
||||
service = http_group.objects[0]
|
||||
|
||||
assert service.qualified_name == "HTTPСервис.ПубличныйAPI"
|
||||
assert service.metadata["rootURL"] == "api"
|
||||
assert service.url_templates[0].name == "Orders"
|
||||
assert service.url_templates[0].attributes["template"] == "/orders/{id}"
|
||||
assert service.url_templates[0].children[0].kind == "METHOD"
|
||||
assert service.url_templates[0].children[0].name == "ПолучитьЗаказ"
|
||||
|
||||
|
||||
def test_normalize_edt_project_keeps_tabular_section_columns_nested(tmp_path: Path):
|
||||
mdo = tmp_path / "ЗаказПокупателя.mdo"
|
||||
mdo.write_text(
|
||||
"""
|
||||
<mdclass:Document xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass">
|
||||
<name>ЗаказПокупателя</name>
|
||||
<tabularSections>
|
||||
<name>Товары</name>
|
||||
<attributes>
|
||||
<name>Номенклатура</name>
|
||||
</attributes>
|
||||
<attributes>
|
||||
<name>Количество</name>
|
||||
</attributes>
|
||||
</tabularSections>
|
||||
</mdclass:Document>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
normalized = normalize_one_c_project(tmp_path, project_id="edt-tabular")
|
||||
documents = next(group for group in normalized.configuration.groups if group.name == "Документы")
|
||||
document = documents.objects[0]
|
||||
|
||||
assert document.attributes == []
|
||||
assert document.tabular_sections[0].qualified_name == "Документ.ЗаказПокупателя.Товары"
|
||||
assert [child.name for child in document.tabular_sections[0].children] == ["Номенклатура", "Количество"]
|
||||
assert [child.qualified_name for child in document.tabular_sections[0].children] == [
|
||||
"Документ.ЗаказПокупателя.Товары.Номенклатура",
|
||||
"Документ.ЗаказПокупателя.Товары.Количество",
|
||||
]
|
||||
|
||||
|
||||
def test_normalize_edt_project_preserves_source_path_and_common_object_descriptions(tmp_path: Path):
|
||||
common_form = tmp_path / "ФормаПодбора.mdo"
|
||||
common_form.write_text(
|
||||
"""
|
||||
<mdclass:CommonForm xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass">
|
||||
<name>ФормаПодбора</name>
|
||||
<synonym>Форма подбора</synonym>
|
||||
<comment>Используется в подборе товаров</comment>
|
||||
</mdclass:CommonForm>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
normalized = normalize_one_c_project(tmp_path, project_id="edt-common")
|
||||
groups = {group.name: group for group in normalized.configuration.groups}
|
||||
common_forms = groups["Общие формы"].objects
|
||||
|
||||
assert common_forms[0].qualified_name == "ОбщаяФорма.ФормаПодбора"
|
||||
assert common_forms[0].source_path.endswith("ФормаПодбора.mdo")
|
||||
assert common_forms[0].metadata["synonym"] == "Форма подбора"
|
||||
assert common_forms[0].metadata["comment"] == "Используется в подборе товаров"
|
||||
|
||||
|
||||
def test_normalize_edt_project_preserves_localized_descriptions(tmp_path: Path):
|
||||
catalog = tmp_path / "Контрагенты.mdo"
|
||||
catalog.write_text(
|
||||
"""
|
||||
<mdclass:Catalog xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass">
|
||||
<name>Контрагенты</name>
|
||||
<synonym>
|
||||
<key>ru</key>
|
||||
<value>Контрагенты</value>
|
||||
</synonym>
|
||||
<comment>
|
||||
<key>ru</key>
|
||||
<value>Описание справочника контрагентов</value>
|
||||
</comment>
|
||||
<attributes>
|
||||
<name>ИНН</name>
|
||||
<synonym>
|
||||
<key>ru</key>
|
||||
<value>ИНН</value>
|
||||
</synonym>
|
||||
<comment>
|
||||
<key>ru</key>
|
||||
<value>Идентификационный номер налогоплательщика</value>
|
||||
</comment>
|
||||
</attributes>
|
||||
</mdclass:Catalog>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
normalized = normalize_one_c_project(tmp_path, project_id="edt-localized")
|
||||
catalogs = next(group for group in normalized.configuration.groups if group.name == "Справочники")
|
||||
metadata_object = catalogs.objects[0]
|
||||
attribute = metadata_object.attributes[0]
|
||||
|
||||
assert metadata_object.metadata["synonym"] == "Контрагенты"
|
||||
assert metadata_object.metadata["synonym_localized"] == {"ru": "Контрагенты"}
|
||||
assert metadata_object.metadata["comment"] == "Описание справочника контрагентов"
|
||||
assert metadata_object.metadata["comment_localized"] == {"ru": "Описание справочника контрагентов"}
|
||||
assert attribute.attributes["synonym"] == "ИНН"
|
||||
assert attribute.attributes["comment"] == "Идентификационный номер налогоплательщика"
|
||||
|
||||
|
||||
def test_normalize_edt_project_attaches_bsl_modules_to_metadata_objects(tmp_path: Path):
|
||||
catalog_dir = tmp_path / "Catalogs" / "Контрагенты"
|
||||
module_dir = catalog_dir / "Ext"
|
||||
module_dir.mkdir(parents=True)
|
||||
(catalog_dir / "Контрагенты.mdo").write_text(
|
||||
"""
|
||||
<mdclass:Catalog xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass">
|
||||
<name>Контрагенты</name>
|
||||
</mdclass:Catalog>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(module_dir / "ObjectModule.bsl").write_text(
|
||||
"""
|
||||
Процедура ПроверитьКонтрагента() Экспорт
|
||||
КонецПроцедуры
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(module_dir / "ManagerModule.bsl").write_text(
|
||||
"""
|
||||
Процедура Создать() Экспорт
|
||||
КонецПроцедуры
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
normalized = normalize_one_c_project(tmp_path, project_id="edt-modules")
|
||||
catalogs = next(group for group in normalized.configuration.groups if group.name == "Справочники")
|
||||
catalog = catalogs.objects[0]
|
||||
|
||||
assert [module.module_kind for module in catalog.modules] == ["MANAGER_MODULE", "OBJECT_MODULE"]
|
||||
assert all(module.source_path.endswith(".bsl") for module in catalog.modules)
|
||||
assert all(module.attributes["source_hash"] for module in catalog.modules)
|
||||
|
||||
|
||||
def test_normalize_edt_project_attaches_form_modules_to_owner_with_form_name(tmp_path: Path):
|
||||
catalog_dir = tmp_path / "Catalogs" / "Контрагенты"
|
||||
form_dir = catalog_dir / "Forms" / "ФормаЭлемента" / "Ext"
|
||||
form_dir.mkdir(parents=True)
|
||||
(catalog_dir / "Контрагенты.mdo").write_text(
|
||||
"""
|
||||
<mdclass:Catalog xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass">
|
||||
<name>Контрагенты</name>
|
||||
<forms>
|
||||
<name>ФормаЭлемента</name>
|
||||
</forms>
|
||||
</mdclass:Catalog>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(form_dir / "Module.bsl").write_text(
|
||||
"""
|
||||
Процедура ПриОткрытии()
|
||||
КонецПроцедуры
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
normalized = normalize_one_c_project(tmp_path, project_id="edt-form-module")
|
||||
catalog = next(group for group in normalized.configuration.groups if group.name == "Справочники").objects[0]
|
||||
|
||||
assert catalog.modules[0].module_kind == "FORM_MODULE"
|
||||
assert catalog.modules[0].attributes["form_name"] == "ФормаЭлемента"
|
||||
assert catalog.modules[0].qualified_name == "Справочник.Контрагенты.Форма.ФормаЭлемента.Модуль"
|
||||
|
||||
|
||||
def test_normalize_edt_project_attaches_common_form_modules(tmp_path: Path):
|
||||
common_form_dir = tmp_path / "CommonForms" / "ФормаПодбора"
|
||||
module_dir = common_form_dir / "Ext"
|
||||
module_dir.mkdir(parents=True)
|
||||
(common_form_dir / "ФормаПодбора.mdo").write_text(
|
||||
"""
|
||||
<mdclass:CommonForm xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass">
|
||||
<name>ФормаПодбора</name>
|
||||
</mdclass:CommonForm>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(module_dir / "Module.bsl").write_text(
|
||||
"""
|
||||
Процедура ПриСозданииНаСервере() Экспорт
|
||||
КонецПроцедуры
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
normalized = normalize_one_c_project(tmp_path, project_id="edt-common-form-module")
|
||||
common_forms = next(group for group in normalized.configuration.groups if group.name == "Общие формы")
|
||||
common_form = common_forms.objects[0]
|
||||
|
||||
assert common_form.qualified_name == "ОбщаяФорма.ФормаПодбора"
|
||||
assert len(common_form.modules) == 1
|
||||
assert common_form.modules[0].module_kind == "MODULE"
|
||||
assert common_form.modules[0].source_path.endswith("Module.bsl")
|
||||
|
||||
|
||||
def test_parse_register_dimensions_and_resources_preserves_attribute_roles(tmp_path: Path):
|
||||
mdo = tmp_path / "ОстаткиТоваров.mdo"
|
||||
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>
|
||||
<attributes>
|
||||
<name>Комментарий</name>
|
||||
</attributes>
|
||||
</mdclass:AccumulationRegister>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
objects = parse_one_c_xml_file(mdo)
|
||||
by_name = {item.name: item for item in objects}
|
||||
|
||||
assert by_name["ОстаткиТоваров"].object_kind == "ACCUMULATION_REGISTER"
|
||||
assert by_name["ОстаткиТоваров"].qualified_name == "РегистрНакопления.ОстаткиТоваров"
|
||||
assert by_name["Номенклатура"].attributes["attribute_role"] == "DIMENSION"
|
||||
assert by_name["Количество"].attributes["attribute_role"] == "RESOURCE"
|
||||
assert by_name["Комментарий"].attributes["attribute_role"] == "REQUISITE"
|
||||
|
||||
|
||||
def test_normalize_edt_project_preserves_specific_register_kinds(tmp_path: Path):
|
||||
for file_name, tag, name in (
|
||||
("Цены.mdo", "InformationRegister", "Цены"),
|
||||
("ОстаткиТоваров.mdo", "AccumulationRegister", "ОстаткиТоваров"),
|
||||
("Хозрасчетный.mdo", "AccountingRegister", "Хозрасчетный"),
|
||||
("Начисления.mdo", "CalculationRegister", "Начисления"),
|
||||
):
|
||||
(tmp_path / file_name).write_text(
|
||||
f"""
|
||||
<mdclass:{tag} xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass">
|
||||
<name>{name}</name>
|
||||
</mdclass:{tag}>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
normalized = normalize_one_c_project(tmp_path, project_id="edt-register-kinds")
|
||||
groups = {group.name: group for group in normalized.configuration.groups}
|
||||
|
||||
assert groups["Регистры сведений"].objects[0].object_kind == "INFORMATION_REGISTER"
|
||||
assert groups["Регистры накопления"].objects[0].qualified_name == "РегистрНакопления.ОстаткиТоваров"
|
||||
assert groups["Регистры бухгалтерии"].objects[0].object_kind == "ACCOUNTING_REGISTER"
|
||||
assert groups["Регистры расчета"].objects[0].object_kind == "CALCULATION_REGISTER"
|
||||
|
||||
|
||||
def test_parse_one_c_xml_file_extracts_role_rights(tmp_path: Path):
|
||||
xml = tmp_path / "roles.xml"
|
||||
xml.write_text(
|
||||
"""
|
||||
<Configuration>
|
||||
<Role name="Менеджер" qualifiedName="Роль.Менеджер">
|
||||
<Right object="Документ.ЗаказПокупателя" read="true" write="true" post="true" />
|
||||
</Role>
|
||||
</Configuration>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
objects = parse_one_c_xml_file(xml)
|
||||
|
||||
assert [item.object_kind for item in objects] == ["ROLE", "RIGHT"]
|
||||
assert objects[1].name == "Документ.ЗаказПокупателя"
|
||||
assert objects[1].attributes["role"] == "Роль.Менеджер"
|
||||
assert objects[1].attributes["post"] == "true"
|
||||
|
||||
|
||||
def test_normalized_project_attaches_role_rights(tmp_path: Path):
|
||||
xml = tmp_path / "roles.xml"
|
||||
xml.write_text(
|
||||
"""
|
||||
<Configuration>
|
||||
<Role name="Менеджер" qualifiedName="Роль.Менеджер">
|
||||
<Right object="Документ.ЗаказПокупателя" read="true" write="true" />
|
||||
</Role>
|
||||
</Configuration>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
normalized = build_normalized_project(parse_one_c_xml_file(xml), project_id="roles", source_path=str(tmp_path))
|
||||
roles_group = next(group for group in normalized.configuration.groups if group.name == "Роли")
|
||||
role = roles_group.objects[0]
|
||||
|
||||
assert role.name == "Менеджер"
|
||||
assert role.rights[0].target == "Документ.ЗаказПокупателя"
|
||||
assert role.rights[0].permissions["write"] == "true"
|
||||
|
||||
|
||||
def test_parse_one_c_xml_file_extracts_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",
|
||||
)
|
||||
|
||||
objects = parse_one_c_xml_file(xml)
|
||||
by_kind = {item.object_kind: item for item in objects}
|
||||
command = next(item for item in objects if item.object_kind == "COMMAND")
|
||||
right = next(item for item in objects if item.object_kind == "RIGHT")
|
||||
|
||||
assert by_kind["FORM"].qualified_name == "Документ.ЗаказПокупателя.ФормаДокумента"
|
||||
assert command.attributes["Action"] == "ПровестиКоманда"
|
||||
assert right.name == "Документ.ЗаказПокупателя"
|
||||
assert right.attributes["role"] == "Роль.Менеджер"
|
||||
|
||||
|
||||
def test_normalized_project_groups_extended_1c_objects(tmp_path: Path):
|
||||
xml = tmp_path / "extended.xml"
|
||||
xml.write_text(
|
||||
"""
|
||||
<Configuration>
|
||||
<Subsystem name="Продажи" qualifiedName="Подсистема.Продажи" />
|
||||
<HTTPService name="ПубличныйAPI" qualifiedName="HTTPСервис.ПубличныйAPI" />
|
||||
<XDTOPackage name="ИнтеграцияCRM" qualifiedName="XDTO.ИнтеграцияCRM" />
|
||||
<Document name="ЗаказПокупателя" qualifiedName="Документ.ЗаказПокупателя">
|
||||
<Layout name="ПечатнаяФорма" qualifiedName="Документ.ЗаказПокупателя.ПечатнаяФорма" />
|
||||
<Movement name="Остатки" qualifiedName="Документ.ЗаказПокупателя.Движения.Остатки" />
|
||||
</Document>
|
||||
<Extension name="CRM" version="1.0" />
|
||||
</Configuration>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
objects = parse_one_c_xml_file(xml)
|
||||
normalized = build_normalized_project(objects, project_id="extended", source_path=str(tmp_path))
|
||||
groups = {group.name: group for group in normalized.configuration.groups}
|
||||
document = next(item for item in groups["Документы"].objects if item.name == "ЗаказПокупателя")
|
||||
|
||||
assert "Подсистемы" in groups
|
||||
assert "HTTP-сервисы" in groups
|
||||
assert "XDTO-пакеты" in groups
|
||||
assert document.layouts[0].name == "ПечатнаяФорма"
|
||||
assert document.movements[0].name == "Остатки"
|
||||
assert normalized.configuration.extensions[0].name == "CRM"
|
||||
|
||||
|
||||
def test_normalize_one_c_project_skips_unreadable_or_invalid_metadata(tmp_path: Path):
|
||||
(tmp_path / "valid.xml").write_text(
|
||||
"""
|
||||
<Configuration>
|
||||
<Catalog name="Контрагенты" qualifiedName="Справочник.Контрагенты" />
|
||||
</Configuration>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(tmp_path / "broken.xml").write_text("<Configuration><Catalog>", encoding="utf-8")
|
||||
|
||||
normalized = normalize_one_c_project(tmp_path, project_id="skip-invalid")
|
||||
catalogs = next(group for group in normalized.configuration.groups if group.name == "Справочники")
|
||||
|
||||
assert catalogs.objects[0].qualified_name == "Справочник.Контрагенты"
|
||||
|
||||
|
||||
def test_configuration_extension_has_own_metadata_tree_structure(tmp_path: Path):
|
||||
xml = tmp_path / "extension.mdo"
|
||||
xml.write_text(
|
||||
"""
|
||||
<mdclass:ConfigurationExtension xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass/extension">
|
||||
<name>CRM</name>
|
||||
<version>1.0</version>
|
||||
<catalogs>
|
||||
<name>КонтрагентыCRM</name>
|
||||
<attributes>
|
||||
<name>ВнешнийКод</name>
|
||||
</attributes>
|
||||
</catalogs>
|
||||
<commonModules>
|
||||
<name>CRMСервер</name>
|
||||
</commonModules>
|
||||
</mdclass:ConfigurationExtension>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
objects = parse_one_c_xml_file(xml)
|
||||
normalized = build_normalized_project(objects, project_id="extension-structure", source_path=str(tmp_path))
|
||||
|
||||
assert normalized.configuration.groups == []
|
||||
extension = normalized.configuration.extensions[0]
|
||||
assert extension.name == "CRM"
|
||||
assert extension.version == "1.0"
|
||||
extension_groups = {group.name: group for group in extension.groups}
|
||||
assert extension_groups["Справочники"].objects[0].name == "КонтрагентыCRM"
|
||||
assert extension_groups["Справочники"].objects[0].attributes[0].name == "ВнешнийКод"
|
||||
assert extension_groups["Общие модули"].objects[0].name == "CRMСервер"
|
||||
|
||||
|
||||
def test_report_metadata_parts_include_dcs_variants_settings_and_tabular_documents(tmp_path: Path):
|
||||
xml = tmp_path / "report.mdo"
|
||||
xml.write_text(
|
||||
"""
|
||||
<mdclass:Report xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass">
|
||||
<name>АнализПродаж</name>
|
||||
<attributes>
|
||||
<name>Период</name>
|
||||
</attributes>
|
||||
<tabularSections>
|
||||
<name>Показатели</name>
|
||||
</tabularSections>
|
||||
<forms>
|
||||
<name>ФормаОтчета</name>
|
||||
</forms>
|
||||
<templates>
|
||||
<name>ПечатнаяФорма</name>
|
||||
</templates>
|
||||
<tabularDocuments>
|
||||
<name>ТабличныйДокумент</name>
|
||||
</tabularDocuments>
|
||||
<mainDataCompositionSchema>
|
||||
<name>ОсновнаяСхемаКомпоновкиДанных</name>
|
||||
</mainDataCompositionSchema>
|
||||
<reportVariants>
|
||||
<name>Основной</name>
|
||||
</reportVariants>
|
||||
<settings>
|
||||
<name>НастройкиПоУмолчанию</name>
|
||||
</settings>
|
||||
</mdclass:Report>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
objects = parse_one_c_xml_file(xml)
|
||||
normalized = build_normalized_project(objects, project_id="report-parts", source_path=str(tmp_path))
|
||||
reports = next(group for group in normalized.configuration.groups if group.name == "Отчеты")
|
||||
report = reports.objects[0]
|
||||
|
||||
assert report.qualified_name == "Отчет.АнализПродаж"
|
||||
assert report.attributes[0].name == "Период"
|
||||
assert report.tabular_sections[0].name == "Показатели"
|
||||
assert report.forms[0].name == "ФормаОтчета"
|
||||
assert report.layouts[0].name == "ПечатнаяФорма"
|
||||
assert report.tabular_documents[0].name == "ТабличныйДокумент"
|
||||
assert report.data_composition_schemas[0].name == "ОсновнаяСхемаКомпоновкиДанных"
|
||||
assert report.report_variants[0].name == "Основной"
|
||||
assert report.report_settings[0].name == "НастройкиПоУмолчанию"
|
||||
|
||||
|
||||
def test_metadata_catalog_describes_core_1c_tree_branches():
|
||||
assert "Общие модули" in COMMON_BRANCH_CHILDREN
|
||||
assert "HTTP-сервисы" in COMMON_BRANCH_CHILDREN
|
||||
|
||||
document = METADATA_TYPE_BY_CODE["DOCUMENT"]
|
||||
assert document.tree_branch == "Документы"
|
||||
assert "Реквизиты" in document.child_groups
|
||||
assert "Табличные части" in document.child_groups
|
||||
assert "Движения" in document.child_groups
|
||||
assert document.module_kinds == ("Модуль объекта", "Модуль менеджера")
|
||||
|
||||
register = METADATA_TYPE_BY_CODE["ACCUMULATION_REGISTER"]
|
||||
assert register.tree_branch == "Регистры накопления"
|
||||
assert "Измерения" in register.child_groups
|
||||
assert "Ресурсы" in register.child_groups
|
||||
|
||||
common_form = METADATA_TYPE_BY_CODE["COMMON_FORM"]
|
||||
assert common_form.tree_branch == "Общие формы"
|
||||
assert "Модуль формы" in common_form.child_groups
|
||||
|
||||
report = METADATA_TYPE_BY_CODE["REPORT"]
|
||||
assert "СКД" in report.child_groups
|
||||
assert "Табличные документы" in report.child_groups
|
||||
assert "Варианты отчета" in report.child_groups
|
||||
assert "Настройки" in report.child_groups
|
||||
|
||||
assert METADATA_TYPE_BY_BRANCH["XDTO-пакеты"].code == "XDTO_PACKAGE"
|
||||
assert METADATA_TYPE_BY_BRANCH["Сервисы интеграции"].code == "INTEGRATION_SERVICE"
|
||||
Reference in New Issue
Block a user