Files
evo-sync/tests/test_tasks_catalog.py

134 lines
5.2 KiB
Python
Raw Normal View History

"""Unit tests for catalog task helpers and refresh_catalog logic."""
from unittest.mock import MagicMock, patch
import pytest
from web.tasks.catalog import _fetch_groups, _fetch_products, _fetch_stores
# ── _fetch_stores ─────────────────────────────────────────────────────────────
def test_fetch_stores_list_response():
mock = MagicMock()
mock.raise_for_status = MagicMock()
mock.json.return_value = [{"id": "s1", "name": "Магазин"}]
with patch("web.tasks.catalog.httpx.get", return_value=mock):
result = _fetch_stores("tok")
assert result == [{"id": "s1", "name": "Магазин"}]
def test_fetch_stores_dict_with_items():
mock = MagicMock()
mock.raise_for_status = MagicMock()
mock.json.return_value = {"items": [{"id": "s1"}], "total": 1}
with patch("web.tasks.catalog.httpx.get", return_value=mock):
result = _fetch_stores("tok")
assert result == [{"id": "s1"}]
# ── _fetch_groups ─────────────────────────────────────────────────────────────
def test_fetch_groups_success():
mock = MagicMock()
mock.status_code = 200
mock.raise_for_status = MagicMock()
mock.json.return_value = {"items": [{"id": "g1", "name": "Чай"}]}
with patch("web.tasks.catalog.httpx.get", return_value=mock):
result = _fetch_groups("tok", "s1")
assert result == [{"id": "g1", "name": "Чай"}]
@pytest.mark.parametrize("status_code", [402, 403])
def test_fetch_groups_returns_none_on_restricted(status_code):
mock = MagicMock()
mock.status_code = status_code
with patch("web.tasks.catalog.httpx.get", return_value=mock):
result = _fetch_groups("tok", "s1")
assert result is None
# ── _fetch_products ───────────────────────────────────────────────────────────
def test_fetch_products_success():
mock = MagicMock()
mock.status_code = 200
mock.raise_for_status = MagicMock()
mock.json.return_value = [{"id": "p1", "name": "Пуэр", "price": {"sum": 15000}}]
with patch("web.tasks.catalog.httpx.get", return_value=mock):
result = _fetch_products("tok", "s1")
assert len(result) == 1
assert result[0]["name"] == "Пуэр"
@pytest.mark.parametrize("status_code", [402, 403])
def test_fetch_products_returns_none_on_restricted(status_code):
mock = MagicMock()
mock.status_code = status_code
with patch("web.tasks.catalog.httpx.get", return_value=mock):
result = _fetch_products("tok", "s1")
assert result is None
# ── refresh_catalog task (integration with mocked HTTP) ──────────────────────
@pytest.mark.asyncio
async def test_refresh_catalog_upserts_stores(override_db):
from web.database import SessionLocal
from web.models.connections import CachedStore, EvotorConnection
from web.tasks.catalog import _sync_user
user_id = 1
token = "test-tok"
stores_data = [{"id": "s-new", "name": "Новый магазин", "address": "ул. Ленина 1"}]
groups_data = []
products_data = []
with patch("web.tasks.catalog._fetch_stores", return_value=stores_data), \
patch("web.tasks.catalog._fetch_groups", return_value=groups_data), \
patch("web.tasks.catalog._fetch_products", return_value=products_data):
_sync_user(override_db, user_id, token)
store = override_db.query(CachedStore).filter_by(user_id=user_id, evotor_id="s-new").first()
assert store is not None
assert store.name == "Новый магазин"
@pytest.mark.asyncio
async def test_refresh_catalog_upserts_products(override_db):
from web.models.connections import CachedProduct
from web.tasks.catalog import _sync_user
user_id = 2
token = "tok"
stores_data = [{"id": "s1", "name": "Магазин"}]
groups_data = [{"id": "g1", "name": "Чай"}]
products_data = [{
"id": "p1", "name": "Пуэр", "price": 35000,
"quantity": 10, "measureName": "шт", "code": "001",
"allowToSell": True, "group": "g1",
}]
with patch("web.tasks.catalog._fetch_stores", return_value=stores_data), \
patch("web.tasks.catalog._fetch_groups", return_value=groups_data), \
patch("web.tasks.catalog._fetch_products", return_value=products_data):
_sync_user(override_db, user_id, token)
p = override_db.query(CachedProduct).filter_by(user_id=user_id, evotor_id="p1").first()
assert p is not None
assert p.name == "Пуэр"
assert p.group_evotor_id == "g1"
assert p.allow_to_sell is True
@pytest.mark.asyncio
async def test_refresh_catalog_skips_fetch_stores_failure(override_db):
from web.models.connections import CachedStore
from web.tasks.catalog import _sync_user
with patch("web.tasks.catalog._fetch_stores", side_effect=Exception("network error")):
_sync_user(override_db, user_id=99, token="tok")
assert override_db.query(CachedStore).filter_by(user_id=99).count() == 0