166 lines
6.2 KiB
Python
166 lines
6.2 KiB
Python
"""Tests for product review tools."""
|
|
|
|
import json
|
|
|
|
import pytest
|
|
from pydantic import ValidationError
|
|
|
|
from shopify import state as shopify_state
|
|
from shopify.models import (
|
|
CreateReviewArgs,
|
|
DeleteReviewArgs,
|
|
GetProductReviewsArgs,
|
|
UpdateReviewArgs,
|
|
)
|
|
from shopify.tools.reviews_returns import (
|
|
handle_create_review,
|
|
handle_delete_review,
|
|
handle_get_product_reviews,
|
|
handle_update_review,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def shopify_data(tmp_path):
|
|
data_file = tmp_path / "shopify_data.json"
|
|
data_file.write_text(
|
|
json.dumps(
|
|
{
|
|
"products": {
|
|
"product-1": {
|
|
"id": "product-1",
|
|
"title": "Widget",
|
|
"variants": [],
|
|
},
|
|
},
|
|
"carts": {},
|
|
"orders": {},
|
|
"customers": {},
|
|
"collections": {},
|
|
"reviews": {},
|
|
"policies": [],
|
|
"counters": {
|
|
"cart_id": 1000,
|
|
"line_id": 1000,
|
|
"order_id": 2000,
|
|
"line_item_id": 3000,
|
|
"customer_id": 4000,
|
|
"collection_id": 5000,
|
|
"review_id": 6000,
|
|
},
|
|
}
|
|
)
|
|
)
|
|
return data_file
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _patch_state(shopify_data, monkeypatch):
|
|
monkeypatch.setattr(shopify_state, "_STATE_FILE", shopify_data)
|
|
shopify_state._current_state = None
|
|
shopify_state._stores.clear()
|
|
shopify_state._active_store_id = "default"
|
|
shopify_state.load_state()
|
|
|
|
|
|
class TestCreateReview:
|
|
def test_create_review(self):
|
|
result = handle_create_review(
|
|
CreateReviewArgs(product_id="product-1", rating=5, author="Alice", title="Great!", body="Love it")
|
|
)
|
|
assert result["userErrors"] == []
|
|
r = result["review"]
|
|
assert r["id"].startswith("gid://shopify/Review/")
|
|
assert r["rating"] == 5
|
|
assert r["author"] == "Alice"
|
|
assert r["status"] == "PUBLISHED"
|
|
|
|
def test_create_review_nonexistent_product(self):
|
|
result = handle_create_review(CreateReviewArgs(product_id="nonexistent", rating=3, author="Bob"))
|
|
assert result["review"] is None
|
|
assert len(result["userErrors"]) == 1
|
|
|
|
def test_create_multiple_reviews(self):
|
|
handle_create_review(CreateReviewArgs(product_id="product-1", rating=5, author="Alice"))
|
|
handle_create_review(CreateReviewArgs(product_id="product-1", rating=3, author="Bob"))
|
|
reviews = handle_get_product_reviews(GetProductReviewsArgs(product_id="product-1"))
|
|
assert reviews["totalCount"] == 2
|
|
|
|
|
|
class TestGetProductReviews:
|
|
def test_get_reviews_empty(self):
|
|
result = handle_get_product_reviews(GetProductReviewsArgs(product_id="product-1"))
|
|
assert result["totalCount"] == 0
|
|
assert result["averageRating"] is None
|
|
|
|
def test_get_reviews_with_average(self):
|
|
handle_create_review(CreateReviewArgs(product_id="product-1", rating=5, author="A"))
|
|
handle_create_review(CreateReviewArgs(product_id="product-1", rating=3, author="B"))
|
|
result = handle_get_product_reviews(GetProductReviewsArgs(product_id="product-1"))
|
|
assert result["totalCount"] == 2
|
|
assert result["averageRating"] == 4.0
|
|
|
|
def test_get_reviews_filter_by_status(self):
|
|
r1 = handle_create_review(CreateReviewArgs(product_id="product-1", rating=5, author="A"))
|
|
handle_update_review(UpdateReviewArgs(review_id=r1["review"]["id"], status="HIDDEN"))
|
|
|
|
handle_create_review(CreateReviewArgs(product_id="product-1", rating=3, author="B"))
|
|
|
|
result = handle_get_product_reviews(GetProductReviewsArgs(product_id="product-1", status="PUBLISHED"))
|
|
assert result["totalCount"] == 1
|
|
|
|
def test_get_reviews_nonexistent_product(self):
|
|
result = handle_get_product_reviews(GetProductReviewsArgs(product_id="nonexistent"))
|
|
assert len(result["userErrors"]) == 1
|
|
|
|
def test_get_reviews_pagination(self):
|
|
handle_create_review(CreateReviewArgs(product_id="product-1", rating=5, author="A"))
|
|
handle_create_review(CreateReviewArgs(product_id="product-1", rating=4, author="B"))
|
|
result = handle_get_product_reviews(GetProductReviewsArgs(product_id="product-1", limit=1))
|
|
assert len(result["reviews"]) == 1
|
|
assert result["pageInfo"]["hasNextPage"] is True
|
|
|
|
|
|
class TestUpdateReview:
|
|
def test_update_status(self):
|
|
create = handle_create_review(CreateReviewArgs(product_id="product-1", rating=5, author="A"))
|
|
rid = create["review"]["id"]
|
|
|
|
result = handle_update_review(UpdateReviewArgs(review_id=rid, status="HIDDEN"))
|
|
assert result["review"]["status"] == "HIDDEN"
|
|
|
|
def test_update_rating(self):
|
|
create = handle_create_review(CreateReviewArgs(product_id="product-1", rating=3, author="A"))
|
|
rid = create["review"]["id"]
|
|
|
|
result = handle_update_review(UpdateReviewArgs(review_id=rid, rating=5))
|
|
assert result["review"]["rating"] == 5
|
|
|
|
def test_update_invalid_status(self):
|
|
create = handle_create_review(CreateReviewArgs(product_id="product-1", rating=5, author="A"))
|
|
rid = create["review"]["id"]
|
|
|
|
with pytest.raises(ValidationError):
|
|
UpdateReviewArgs.model_validate({"review_id": rid, "status": "INVALID"})
|
|
|
|
def test_update_nonexistent(self):
|
|
result = handle_update_review(UpdateReviewArgs(review_id="nonexistent"))
|
|
assert result["review"] is None
|
|
|
|
|
|
class TestDeleteReview:
|
|
def test_delete_review(self):
|
|
create = handle_create_review(CreateReviewArgs(product_id="product-1", rating=5, author="A"))
|
|
rid = create["review"]["id"]
|
|
|
|
result = handle_delete_review(DeleteReviewArgs(review_id=rid))
|
|
assert result["deletedReviewId"] == rid
|
|
|
|
reviews = handle_get_product_reviews(GetProductReviewsArgs(product_id="product-1"))
|
|
assert reviews["totalCount"] == 0
|
|
|
|
def test_delete_nonexistent(self):
|
|
result = handle_delete_review(DeleteReviewArgs(review_id="nonexistent"))
|
|
assert result["deletedReviewId"] is None
|
|
assert len(result["userErrors"]) == 1
|