Adding vendor api tests
This commit is contained in:
300
tests/integration/api/v1/vendor/test_dashboard.py
vendored
Normal file
300
tests/integration/api/v1/vendor/test_dashboard.py
vendored
Normal file
@@ -0,0 +1,300 @@
|
||||
# tests/integration/api/v1/test_vendor_api_dashboard.py
|
||||
"""
|
||||
Integration tests for vendor dashboard API endpoints.
|
||||
|
||||
Tests cover:
|
||||
1. Dashboard stats retrieval
|
||||
2. Vendor-specific data isolation
|
||||
3. Permission checks
|
||||
4. Data accuracy
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
@pytest.mark.api
|
||||
@pytest.mark.vendor
|
||||
class TestVendorDashboardAPI:
|
||||
"""Test vendor dashboard stats endpoint"""
|
||||
|
||||
def test_get_dashboard_stats_structure(
|
||||
self, client, vendor_user_headers, test_vendor_with_vendor_user, db
|
||||
):
|
||||
"""Test dashboard stats returns correct data structure"""
|
||||
response = client.get(
|
||||
"/api/v1/vendor/dashboard/stats",
|
||||
headers=vendor_user_headers
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
||||
# Verify top-level structure
|
||||
assert "vendor" in data
|
||||
assert "products" in data
|
||||
assert "orders" in data
|
||||
assert "customers" in data
|
||||
assert "revenue" in data
|
||||
|
||||
# Verify vendor info
|
||||
assert "id" in data["vendor"]
|
||||
assert "name" in data["vendor"]
|
||||
assert "vendor_code" in data["vendor"]
|
||||
assert data["vendor"]["id"] == test_vendor_with_vendor_user.id
|
||||
|
||||
# Verify products stats
|
||||
assert "total" in data["products"]
|
||||
assert "active" in data["products"]
|
||||
assert isinstance(data["products"]["total"], int)
|
||||
assert isinstance(data["products"]["active"], int)
|
||||
|
||||
# Verify orders stats
|
||||
assert "total" in data["orders"]
|
||||
assert "pending" in data["orders"]
|
||||
assert "completed" in data["orders"]
|
||||
|
||||
# Verify customers stats
|
||||
assert "total" in data["customers"]
|
||||
assert "active" in data["customers"]
|
||||
|
||||
# Verify revenue stats
|
||||
assert "total" in data["revenue"]
|
||||
assert "this_month" in data["revenue"]
|
||||
|
||||
def test_dashboard_stats_vendor_isolation(
|
||||
self, client, db, test_vendor_user, auth_manager
|
||||
):
|
||||
"""Test that dashboard stats only show data for the authenticated vendor"""
|
||||
from models.database.vendor import Vendor, VendorUser
|
||||
from models.database.product import Product
|
||||
from models.database.marketplace_product import MarketplaceProduct
|
||||
|
||||
# Create two separate vendors with different data
|
||||
vendor1 = Vendor(
|
||||
vendor_code="VENDOR1",
|
||||
subdomain="vendor1",
|
||||
name="Vendor One",
|
||||
owner_user_id=test_vendor_user.id,
|
||||
is_active=True,
|
||||
is_verified=True,
|
||||
)
|
||||
db.add(vendor1)
|
||||
db.commit()
|
||||
db.refresh(vendor1)
|
||||
|
||||
# Associate vendor1 with test_vendor_user
|
||||
vendor_user1 = VendorUser(
|
||||
vendor_id=vendor1.id,
|
||||
user_id=test_vendor_user.id,
|
||||
is_owner=True,
|
||||
is_active=True,
|
||||
)
|
||||
db.add(vendor_user1)
|
||||
db.commit()
|
||||
|
||||
# Create marketplace product for vendor1
|
||||
mp1 = MarketplaceProduct(
|
||||
gtin="1234567890123",
|
||||
title="Product for Vendor 1",
|
||||
is_active=True,
|
||||
)
|
||||
db.add(mp1)
|
||||
db.commit()
|
||||
|
||||
# Create products for vendor1
|
||||
for i in range(3):
|
||||
product = Product(
|
||||
vendor_id=vendor1.id,
|
||||
marketplace_product_id=mp1.id,
|
||||
price=10.0 + i,
|
||||
is_active=True,
|
||||
)
|
||||
db.add(product)
|
||||
db.commit()
|
||||
|
||||
# Get token for vendor1 user
|
||||
token_data = auth_manager.create_access_token(test_vendor_user)
|
||||
vendor1_headers = {"Authorization": f"Bearer {token_data['access_token']}"}
|
||||
|
||||
# Get stats for vendor1
|
||||
response = client.get(
|
||||
"/api/v1/vendor/dashboard/stats",
|
||||
headers=vendor1_headers
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
||||
# Should show 3 products for vendor1
|
||||
assert data["vendor"]["id"] == vendor1.id
|
||||
assert data["products"]["total"] == 3
|
||||
|
||||
def test_dashboard_stats_without_vendor_association(
|
||||
self, client, db, auth_manager
|
||||
):
|
||||
"""Test dashboard stats for user not associated with any vendor"""
|
||||
from models.database.user import User
|
||||
|
||||
# Create vendor user without vendor association
|
||||
hashed_password = auth_manager.hash_password("testpass123")
|
||||
orphan_user = User(
|
||||
email="orphan@example.com",
|
||||
username="orphanvendor",
|
||||
hashed_password=hashed_password,
|
||||
role="vendor",
|
||||
is_active=True,
|
||||
)
|
||||
db.add(orphan_user)
|
||||
db.commit()
|
||||
db.refresh(orphan_user)
|
||||
|
||||
# Get token
|
||||
token_data = auth_manager.create_access_token(orphan_user)
|
||||
headers = {"Authorization": f"Bearer {token_data['access_token']}"}
|
||||
|
||||
# Try to get dashboard stats
|
||||
response = client.get("/api/v1/vendor/dashboard/stats", headers=headers)
|
||||
|
||||
# Should fail - user not associated with vendor
|
||||
assert response.status_code == 403
|
||||
data = response.json()
|
||||
assert "not associated with any vendor" in data["message"]
|
||||
|
||||
def test_dashboard_stats_with_inactive_vendor(
|
||||
self, client, db, test_vendor_user, auth_manager
|
||||
):
|
||||
"""Test dashboard stats for inactive vendor"""
|
||||
from models.database.vendor import Vendor, VendorUser
|
||||
|
||||
# Create inactive vendor
|
||||
vendor = Vendor(
|
||||
vendor_code="INACTIVE",
|
||||
subdomain="inactive",
|
||||
name="Inactive Vendor",
|
||||
owner_user_id=test_vendor_user.id,
|
||||
is_active=False, # Inactive
|
||||
is_verified=True,
|
||||
)
|
||||
db.add(vendor)
|
||||
db.commit()
|
||||
|
||||
# Associate with user
|
||||
vendor_user = VendorUser(
|
||||
vendor_id=vendor.id,
|
||||
user_id=test_vendor_user.id,
|
||||
is_owner=True,
|
||||
is_active=True,
|
||||
)
|
||||
db.add(vendor_user)
|
||||
db.commit()
|
||||
|
||||
# Get token
|
||||
token_data = auth_manager.create_access_token(test_vendor_user)
|
||||
headers = {"Authorization": f"Bearer {token_data['access_token']}"}
|
||||
|
||||
# Try to get dashboard stats
|
||||
response = client.get("/api/v1/vendor/dashboard/stats", headers=headers)
|
||||
|
||||
# Should fail - vendor is inactive
|
||||
assert response.status_code == 404
|
||||
data = response.json()
|
||||
assert "not found or inactive" in data["message"]
|
||||
|
||||
def test_dashboard_stats_empty_vendor(
|
||||
self, client, vendor_user_headers, test_vendor_with_vendor_user
|
||||
):
|
||||
"""Test dashboard stats for vendor with no data"""
|
||||
response = client.get(
|
||||
"/api/v1/vendor/dashboard/stats",
|
||||
headers=vendor_user_headers
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
||||
# Should return zeros for empty vendor
|
||||
assert data["products"]["total"] == 0
|
||||
assert data["products"]["active"] == 0
|
||||
assert data["orders"]["total"] == 0
|
||||
assert data["customers"]["total"] == 0
|
||||
assert data["revenue"]["total"] == 0
|
||||
|
||||
def test_dashboard_stats_with_products(
|
||||
self, client, db, vendor_user_headers, test_vendor_with_vendor_user
|
||||
):
|
||||
"""Test dashboard stats accuracy with actual products"""
|
||||
from models.database.product import Product
|
||||
from models.database.marketplace_product import MarketplaceProduct
|
||||
|
||||
# Create marketplace products
|
||||
mp = MarketplaceProduct(
|
||||
gtin="1234567890124",
|
||||
title="Test Product",
|
||||
is_active=True,
|
||||
)
|
||||
db.add(mp)
|
||||
db.commit()
|
||||
|
||||
# Create products (3 active, 2 inactive)
|
||||
for i in range(5):
|
||||
product = Product(
|
||||
vendor_id=test_vendor_with_vendor_user.id,
|
||||
marketplace_product_id=mp.id,
|
||||
price=10.0 + i,
|
||||
is_active=(i < 3), # First 3 are active
|
||||
)
|
||||
db.add(product)
|
||||
db.commit()
|
||||
|
||||
# Get stats
|
||||
response = client.get(
|
||||
"/api/v1/vendor/dashboard/stats",
|
||||
headers=vendor_user_headers
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
||||
assert data["products"]["total"] == 5
|
||||
assert data["products"]["active"] == 3
|
||||
|
||||
def test_dashboard_stats_response_time(
|
||||
self, client, vendor_user_headers, test_vendor_with_vendor_user
|
||||
):
|
||||
"""Test that dashboard stats responds quickly"""
|
||||
import time
|
||||
|
||||
start_time = time.time()
|
||||
response = client.get(
|
||||
"/api/v1/vendor/dashboard/stats",
|
||||
headers=vendor_user_headers
|
||||
)
|
||||
end_time = time.time()
|
||||
|
||||
assert response.status_code == 200
|
||||
# Should respond in less than 2 seconds
|
||||
assert (end_time - start_time) < 2.0
|
||||
|
||||
def test_dashboard_stats_caching_behavior(
|
||||
self, client, vendor_user_headers, test_vendor_with_vendor_user
|
||||
):
|
||||
"""Test that dashboard stats can be called multiple times"""
|
||||
# Make multiple requests
|
||||
responses = []
|
||||
for _ in range(3):
|
||||
response = client.get(
|
||||
"/api/v1/vendor/dashboard/stats",
|
||||
headers=vendor_user_headers
|
||||
)
|
||||
responses.append(response)
|
||||
|
||||
# All should succeed
|
||||
for response in responses:
|
||||
assert response.status_code == 200
|
||||
|
||||
# All should return consistent data
|
||||
data_list = [r.json() for r in responses]
|
||||
for data in data_list[1:]:
|
||||
assert data["vendor"]["id"] == data_list[0]["vendor"]["id"]
|
||||
assert data["products"]["total"] == data_list[0]["products"]["total"]
|
||||
Reference in New Issue
Block a user