[api][shop] add product/search、product/create、order/batch
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
from asgiref.sync import sync_to_async
|
||||
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseServerError
|
||||
from django.test import AsyncClient, Client
|
||||
from shop.models import Product
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.asyncio
|
||||
async def test_create_and_search_product():
|
||||
# 新增商品
|
||||
product = await sync_to_async(Product.objects.create)(
|
||||
name="测试商品", description="描述", price="9.99", stock=10, keywords="测试,商品"
|
||||
)
|
||||
# 搜索商品
|
||||
client = AsyncClient()
|
||||
response = await client.get("/shop/product/search/", {"q": "测试"})
|
||||
assert response.status_code == HttpResponse.status_code
|
||||
data = response.json()
|
||||
assert "products" in data
|
||||
found = any(str(product.id) == str(p.get("id")) or product.name == p.get("name") for p in data["products"])
|
||||
assert found
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_update_product_view():
|
||||
# 新增商品
|
||||
product = Product.objects.create(name="待更新商品", description="desc", price="19.99", stock=5, keywords="更新")
|
||||
client = Client()
|
||||
url = "/shop/product/update/"
|
||||
update_data = {"id": product.id, "data": {"name": "已更新商品", "price": "29.99"}}
|
||||
response = client.post(url, data=json.dumps(update_data), content_type="application/json")
|
||||
assert response.status_code == HttpResponse.status_code
|
||||
product.refresh_from_db()
|
||||
assert product.name == "已更新商品"
|
||||
assert str(product.price) == "29.99"
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_update_product_view_invalid():
|
||||
client = Client()
|
||||
url = "/shop/product/update/"
|
||||
# 缺少id
|
||||
response = client.post(url, data=json.dumps({"data": {"name": "x"}}), content_type="application/json")
|
||||
assert response.status_code == HttpResponseBadRequest.status_code
|
||||
# 缺少data
|
||||
response = client.post(url, data=json.dumps({"id": 1}), content_type="application/json")
|
||||
assert response.status_code == HttpResponseBadRequest.status_code
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_delete_product():
|
||||
# 新增商品
|
||||
product = Product.objects.create(name="待删除商品", description="desc", price="5.00", stock=1, keywords="删除")
|
||||
pid = product.id
|
||||
product.delete()
|
||||
assert not Product.objects.filter(id=pid).exists()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_update_product_empty_fields():
|
||||
client = Client()
|
||||
response = client.post("/shop/product/update/", data="{}", content_type="application/json")
|
||||
assert response.status_code == HttpResponseBadRequest.status_code
|
||||
assert "商品ID和更新数据不能为空" in response.json().get("error", "")
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_product_success():
|
||||
client = AsyncClient()
|
||||
with patch(
|
||||
"shop.services.ProductService.update_product", new_callable=AsyncMock, return_value={"updated": True}
|
||||
) as mock_update:
|
||||
data = {"id": 1, "data": {"name": "新商品名"}}
|
||||
response = await client.post("/shop/product/update/", data=json.dumps(data), content_type="application/json")
|
||||
assert response.status_code == HttpResponse.status_code
|
||||
assert response.json()["result"] == {"updated": True}
|
||||
mock_update.assert_called_once()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_product_exception():
|
||||
client = AsyncClient()
|
||||
with patch(
|
||||
"shop.services.ProductService.update_product", new_callable=AsyncMock, side_effect=Exception("mock error")
|
||||
):
|
||||
data = {"id": 1, "data": {"name": "新商品名"}}
|
||||
response = await client.post("/shop/product/update/", data=json.dumps(data), content_type="application/json")
|
||||
assert response.status_code == HttpResponseServerError.status_code
|
||||
assert response.json()["error"] == "系统异常"
|
||||
assert "mock error" in response.json().get("detail", "")
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_batch_order_empty_items():
|
||||
client = Client()
|
||||
response = client.post("/shop/order/batch/", data="{}", content_type="application/json")
|
||||
assert response.status_code == HttpResponseBadRequest.status_code
|
||||
assert "订单明细不能为空" in response.json().get("error", "")
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_batch_order_success():
|
||||
client = Client()
|
||||
order_id = 123
|
||||
with patch(
|
||||
"shop.services.OrderService.batch_create_order",
|
||||
return_value=(
|
||||
order_id,
|
||||
[
|
||||
{"product_id": 1, "status": "success"},
|
||||
],
|
||||
),
|
||||
) as mock_batch:
|
||||
data = {"items": [{"product_id": 1, "quantity": 2}]}
|
||||
response = client.post("/shop/order/batch/", data=json.dumps(data), content_type="application/json")
|
||||
assert response.status_code == HttpResponse.status_code
|
||||
assert response.json()["order_id"] == order_id
|
||||
assert response.json()["results"] == [{"product_id": 1, "status": "success"}]
|
||||
mock_batch.assert_called_once()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_batch_order_exception():
|
||||
client = Client()
|
||||
with patch("shop.services.OrderService.batch_create_order", side_effect=Exception("mock error")):
|
||||
data = {"items": [{"product_id": 1, "quantity": 2}]}
|
||||
response = client.post("/shop/order/batch/", data=json.dumps(data), content_type="application/json")
|
||||
assert response.status_code == HttpResponseServerError.status_code
|
||||
assert response.json()["error"] == "系统异常"
|
||||
assert "mock error" in response.json().get("detail", "")
|
||||
Reference in New Issue
Block a user