159 lines
5.2 KiB
Python
159 lines
5.2 KiB
Python
from __future__ import annotations
|
||
|
||
from pathlib import Path
|
||
from unittest.mock import Mock, patch
|
||
|
||
import pytest
|
||
import requests
|
||
|
||
from app.opencloud_access import (
|
||
OpenCloudDriveResolutionError,
|
||
OpenCloudUploadError,
|
||
build_opencloud_url,
|
||
resolve_personal_drive,
|
||
upload_local_file_to_opencloud,
|
||
)
|
||
|
||
|
||
def test_build_opencloud_url_encodes_cyrillic_and_spaces() -> None:
|
||
url = build_opencloud_url(
|
||
space_id="storage123$space456",
|
||
folder_segments=("Райков М.С.",),
|
||
file_name="report 2026.xlsx",
|
||
)
|
||
assert url == (
|
||
"https://docs.raisa.go.rshbank.ru/dav/spaces/storage123$space456/"
|
||
"%D0%A0%D0%B0%D0%B9%D0%BA%D0%BE%D0%B2%20%D0%9C.%D0%A1./"
|
||
"report%202026.xlsx"
|
||
)
|
||
|
||
|
||
def test_build_opencloud_url_without_folder() -> None:
|
||
url = build_opencloud_url(
|
||
space_id="abc", folder_segments=(), file_name="report.xlsx"
|
||
)
|
||
assert url == "https://docs.raisa.go.rshbank.ru/dav/spaces/abc/report.xlsx"
|
||
|
||
|
||
def test_build_opencloud_url_requires_space_id() -> None:
|
||
with pytest.raises(OpenCloudUploadError):
|
||
build_opencloud_url(space_id="", folder_segments=(), file_name="report.xlsx")
|
||
|
||
|
||
def test_upload_local_file_to_opencloud_success(tmp_path: Path) -> None:
|
||
local_file = tmp_path / "report.xlsx"
|
||
local_file.write_bytes(b"fake-xlsx-bytes")
|
||
|
||
fake_response = Mock(status_code=201, text="")
|
||
with patch("app.opencloud_access.requests.put", return_value=fake_response) as put:
|
||
url = upload_local_file_to_opencloud(
|
||
local_file,
|
||
space_id="abc$def",
|
||
folder_segments=("Райков М.С.",),
|
||
file_name="report.xlsx",
|
||
access_token="token-123",
|
||
)
|
||
|
||
assert url.endswith("/report.xlsx")
|
||
_, kwargs = put.call_args
|
||
assert kwargs["headers"]["Authorization"] == "Bearer token-123"
|
||
|
||
|
||
def test_upload_local_file_to_opencloud_missing_token(tmp_path: Path) -> None:
|
||
local_file = tmp_path / "report.xlsx"
|
||
local_file.write_bytes(b"data")
|
||
with pytest.raises(OpenCloudUploadError):
|
||
upload_local_file_to_opencloud(
|
||
local_file,
|
||
space_id="abc",
|
||
folder_segments=(),
|
||
file_name="report.xlsx",
|
||
access_token="",
|
||
)
|
||
|
||
|
||
def test_upload_local_file_to_opencloud_missing_local_file(tmp_path: Path) -> None:
|
||
missing_file = tmp_path / "does-not-exist.xlsx"
|
||
with pytest.raises(OpenCloudUploadError):
|
||
upload_local_file_to_opencloud(
|
||
missing_file,
|
||
space_id="abc",
|
||
folder_segments=(),
|
||
file_name="report.xlsx",
|
||
access_token="token-123",
|
||
)
|
||
|
||
|
||
def test_upload_local_file_to_opencloud_http_error(tmp_path: Path) -> None:
|
||
local_file = tmp_path / "report.xlsx"
|
||
local_file.write_bytes(b"data")
|
||
|
||
fake_response = Mock(status_code=401, text="Unauthorized")
|
||
with patch("app.opencloud_access.requests.put", return_value=fake_response):
|
||
with pytest.raises(OpenCloudUploadError):
|
||
upload_local_file_to_opencloud(
|
||
local_file,
|
||
space_id="abc",
|
||
folder_segments=(),
|
||
file_name="report.xlsx",
|
||
access_token="token-123",
|
||
)
|
||
|
||
|
||
def test_resolve_personal_drive_success() -> None:
|
||
fake_response = Mock(
|
||
status_code=200,
|
||
json=lambda: {
|
||
"value": [
|
||
{"driveType": "project", "id": "irrelevant$irrelevant"},
|
||
{
|
||
"driveType": "personal",
|
||
"id": "storage123$space456",
|
||
"root": {
|
||
"webDavUrl": "https://example.test/dav/spaces/storage123$space456"
|
||
},
|
||
},
|
||
]
|
||
},
|
||
)
|
||
with patch("app.opencloud_access.requests.get", return_value=fake_response) as get:
|
||
drive = resolve_personal_drive("token-123")
|
||
|
||
assert drive == {
|
||
"id": "storage123$space456",
|
||
"web_dav_url": "https://example.test/dav/spaces/storage123$space456",
|
||
}
|
||
_, kwargs = get.call_args
|
||
assert kwargs["headers"]["Authorization"] == "Bearer token-123"
|
||
|
||
|
||
def test_resolve_personal_drive_missing_token() -> None:
|
||
with pytest.raises(OpenCloudDriveResolutionError):
|
||
resolve_personal_drive("")
|
||
|
||
|
||
def test_resolve_personal_drive_unauthorized() -> None:
|
||
fake_response = Mock(status_code=401, text="Unauthorized")
|
||
with patch("app.opencloud_access.requests.get", return_value=fake_response):
|
||
with pytest.raises(OpenCloudDriveResolutionError):
|
||
resolve_personal_drive("token-123")
|
||
|
||
|
||
def test_resolve_personal_drive_no_personal_drive_found() -> None:
|
||
fake_response = Mock(
|
||
status_code=200,
|
||
json=lambda: {"value": [{"driveType": "project", "id": "abc$def"}]},
|
||
)
|
||
with patch("app.opencloud_access.requests.get", return_value=fake_response):
|
||
with pytest.raises(OpenCloudDriveResolutionError):
|
||
resolve_personal_drive("token-123")
|
||
|
||
|
||
def test_resolve_personal_drive_network_error() -> None:
|
||
with patch(
|
||
"app.opencloud_access.requests.get",
|
||
side_effect=requests.RequestException("boom"),
|
||
):
|
||
with pytest.raises(OpenCloudDriveResolutionError):
|
||
resolve_personal_drive("token-123")
|