SFM/tests/smoke/test_batch_links.py
Raykov-MS ef0f955585 fix
2026-10-16 11:19:18 +03:00

163 lines
6.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Ссылки на результат обработки: на файл -> на папку запуска.
Ссылка на папку запуска собирается по пути в формате адресной строки
веб-интерфейса OpenCloud и есть всегда, поэтому без ссылки пользователь не
останется, а обработка из-за ссылок не падает.
"""
from __future__ import annotations
from pathlib import Path
from unittest.mock import Mock
import requests
from app import opencloud_access
from app.opencloud_access import OpenCloudUploadResult
from app.pipeline import service
from app.pipeline.config import build_date_parts
from app.pipeline.service import BatchResult, run_batch
from main import _result_links
from tests.smoke.test_batch_smoke import _patch_opencloud, _valid_xml
WEB_SPACE = "https://docs.raisa.go.rshbank.ru/files/spaces/personal"
def _loose_xml(tmp_path: Path) -> Path:
path = tmp_path / "SKO115FZ_01_123456789_20260616_X00001.xml"
path.write_text(_valid_xml(), encoding="utf-8")
return path
def _run(tmp_path: Path):
return run_batch(
input_paths=[_loose_xml(tmp_path)],
launcher="tester",
opencloud_username="test-user",
opencloud_access_token="token-123",
)
def _run_folder_path() -> str:
year, month, day, _ = build_date_parts()
return f"Out/{year}/{month}/{day}/1"
def test_links_open_files_and_run_folder_in_web_ui(tmp_path: Path, monkeypatch) -> None:
_patch_opencloud(monkeypatch)
folder_requests: list[str] = []
def _folder_file_id(dav_url, username, token):
folder_requests.append(dav_url)
return "store$space!folder"
monkeypatch.setattr(service, "resolve_opencloud_file_id", _folder_file_id)
result = _run(tmp_path)
assert result.status == "success"
assert result.report_url.startswith("https://opencloud.test/f/")
assert result.report_url.endswith(".xlsx")
assert result.protocol_url.startswith("https://opencloud.test/f/")
assert result.log_url.endswith(".log")
# Формат — как в адресной строке интерфейса: путь + fileId папки.
assert result.folder_url == (
f"{WEB_SPACE}/test-user/{_run_folder_path()}" "?fileId=store%24space%21folder"
)
# fileId запрашивается именно для папки запуска Out/год/месяц/день/номер.
assert folder_requests == [
f"https://docs.raisa.go.rshbank.ru/dav/spaces/personal-space-1/"
f"{_run_folder_path()}"
]
# WebDAV-адреса остаются для протокола и отладки.
assert "/Out/" in result.report_path
assert not any("веб-интерфейсе" in message for message in result.messages)
def test_file_without_link_falls_back_to_run_folder(
tmp_path: Path, monkeypatch
) -> None:
_patch_opencloud(monkeypatch)
def _upload_without_link(
local_path, space_id, folder_segments, file_name, username, token
):
return OpenCloudUploadResult(dav_url=f"https://dav.test/{file_name}")
monkeypatch.setattr(service, "upload_local_file_to_opencloud", _upload_without_link)
result = _run(tmp_path)
assert result.status == "success"
assert result.folder_url.startswith(f"{WEB_SPACE}/test-user/Out/")
assert result.report_url == result.folder_url
assert result.protocol_url == result.folder_url
assert result.log_url == result.folder_url
assert any("веб-интерфейсе" in message for message in result.messages)
def test_nothing_resolved_still_gives_run_folder_link(
tmp_path: Path, monkeypatch
) -> None:
"""Сквозной сценарий на уровне requests: в ответе на PUT нет OC-FileId,
PROPFIND за ссылками падает, Graph API не вернул driveAlias — обработка
успешна, все кнопки ведут в папку запуска (путь из логина, без fileId)."""
calls: list[tuple[str, str]] = []
def _get(url, **kwargs):
return Mock(
status_code=200,
json=lambda: {"value": [{"id": "s$p", "driveType": "personal"}]},
)
def _request(method, url, **kwargs):
depth = kwargs.get("headers", {}).get("Depth")
calls.append((method, depth))
if method == "PROPFIND" and depth == "1":
return Mock(status_code=404, text="")
if method == "MKCOL":
return Mock(status_code=201, text="")
raise requests.ConnectionError("PROPFIND за ссылкой не прошёл")
def _put(url, **kwargs):
return Mock(status_code=201, text="", headers={})
monkeypatch.setattr(opencloud_access.requests, "get", _get)
monkeypatch.setattr(opencloud_access.requests, "request", _request)
monkeypatch.setattr(opencloud_access.requests, "put", _put)
result = _run(tmp_path)
assert result.status == "success"
assert result.folder_url == f"{WEB_SPACE}/test-user/{_run_folder_path()}"
assert result.report_url == result.folder_url
assert result.protocol_url == result.folder_url
assert result.log_url == result.folder_url
assert result.report_path.startswith(
"https://docs.raisa.go.rshbank.ru/dav/spaces/s$p/Out/"
)
# Три файла без OC-FileId + папка запуска: по одному PROPFIND (Depth: 0).
assert calls.count(("PROPFIND", "0")) == 4
def test_result_link_buttons_skip_missing_addresses() -> None:
result = BatchResult(
status="success",
processed=1,
partial=0,
errors=0,
report_path="dav-report",
protocol_path="dav-protocol",
log_path="dav-log",
report_url="https://x/f/1",
protocol_url="https://x/f/2",
log_url="",
folder_url="https://x/f/3",
)
assert _result_links(result) == [
("Открыть отчёт", "https://x/f/1"),
("Протокол", "https://x/f/2"),
("Папка с результатами", "https://x/f/3"),
]