arm-core/api/tests/test_clients.py

86 lines
2.7 KiB
Python
Raw 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.

"""`S3Storage.get_bytes` на заглушке Minio (без сети):
чтение, закрытие response, `NoSuchKey` → `ObjectNotFoundError`."""
from typing import Any
from unittest.mock import MagicMock
import pytest
from miniopy_async.error import S3Error
from src.core.clients import S3Storage
from src.core.storage import ObjectNotFoundError
class StubResponse:
"""Ответ `aiohttp` с флагами закрытия."""
def __init__(self, data: bytes, *, fail_read: bool = False) -> None:
self._data = data
self._fail_read = fail_read
self.closed = False
self.released = False
async def read(self) -> bytes:
if self._fail_read:
raise ConnectionError("обрыв чтения")
return self._data
def close(self) -> None:
self.closed = True
async def release(self) -> None:
self.released = True
class StubMinio:
def __init__(self, response: StubResponse | None = None, error: Exception | None = None) -> None:
self._response = response
self._error = error
self.calls: list[tuple[str, str]] = []
async def get_object(self, bucket: str, obj_name: str) -> StubResponse:
self.calls.append((bucket, obj_name))
if self._error is not None:
raise self._error
assert self._response is not None # noqa: S101
return self._response
def _s3_error(code: str) -> S3Error:
return S3Error(code, "сообщение", None, None, None, MagicMock())
def _storage(minio: StubMinio) -> S3Storage:
client: Any = minio
return S3Storage(client, "arm-ka")
async def test_get_bytes_returns_content_and_closes_response() -> None:
response = StubResponse(b"payload")
minio = StubMinio(response)
assert await _storage(minio).get_bytes("uploads/a/b.xls") == b"payload"
assert minio.calls == [("arm-ka", "uploads/a/b.xls")]
assert response.closed is True
assert response.released is True
async def test_get_bytes_closes_response_when_read_fails() -> None:
response = StubResponse(b"", fail_read=True)
with pytest.raises(ConnectionError):
await _storage(StubMinio(response)).get_bytes("k")
assert response.closed is True
assert response.released is True
async def test_get_bytes_no_such_key_is_object_not_found() -> None:
with pytest.raises(ObjectNotFoundError):
await _storage(StubMinio(error=_s3_error("NoSuchKey"))).get_bytes("missing")
async def test_get_bytes_other_s3_error_is_not_swallowed() -> None:
with pytest.raises(S3Error) as caught:
await _storage(StubMinio(error=_s3_error("AccessDenied"))).get_bytes("k")
assert caught.value.code == "AccessDenied"