cuatrolabs-scm-ms / tests /test_catalogue_code_responses.py
MukeshKapoor25's picture
refactor(database): consolidate shared database base and fix foreign key schema references
cd357c6
#!/usr/bin/env python3
"""
Test script to verify catalogue_code is included in all API responses.
Tests create, update, and list operations to ensure catalogue_code is always returned.
"""
import json
import sys
import os
# Add the app directory to Python path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'app'))
from app.catalogues.schemas.schema import Catalogue, Identifier, Pricing
def test_catalogue_response_structure():
"""Test that catalogue responses include both catalogue_id and catalogue_code"""
print("πŸ§ͺ Testing Catalogue Response Structure")
print("=" * 50)
# Test catalogue creation response
print("\nπŸ“‹ Create Response Structure:")
print("-" * 30)
# Mock catalogue object (as would be returned by service)
test_catalogue = Catalogue(
catalogue_id="550e8400-e29b-41d4-a716-446655440000",
catalogue_code="LOR-SHA-000001",
catalogue_name="L'Oreal Professional Shampoo",
catalogue_type="Product",
brand="LOREAL",
category="SHAMPOO",
identifiers=Identifier(
sku="LOR-SHA-500ML",
ean_code="1234567890123"
),
pricing=Pricing(
retail_price=850.00,
mrp=1000.00,
currency="INR"
)
)
# Convert to dict (as API would return)
catalogue_dict = test_catalogue.model_dump()
print("βœ… Create Response Format:")
print(json.dumps({
"data": {
"catalogue_id": catalogue_dict["catalogue_id"],
"catalogue_code": catalogue_dict["catalogue_code"],
"catalogue_name": catalogue_dict["catalogue_name"],
"catalogue_type": catalogue_dict["catalogue_type"],
"brand": catalogue_dict["brand"],
"category": catalogue_dict["category"],
"identifiers": catalogue_dict["identifiers"],
"pricing": catalogue_dict["pricing"]
}
}, indent=2))
# Verify essential fields
essential_fields = ["catalogue_id", "catalogue_code", "catalogue_name"]
missing_fields = [field for field in essential_fields if field not in catalogue_dict]
if missing_fields:
print(f"❌ Missing essential fields: {missing_fields}")
return False
print(f"\nβœ… All essential fields present: {essential_fields}")
# Test update response structure
print(f"\nπŸ“ Update Response Structure:")
print("-" * 30)
print("βœ… Update Response Format:")
print(json.dumps({
"data": {
"catalogue_id": catalogue_dict["catalogue_id"],
"catalogue_code": catalogue_dict["catalogue_code"],
"catalogue_name": "Updated Product Name",
"catalogue_type": catalogue_dict["catalogue_type"],
"brand": catalogue_dict["brand"],
"category": catalogue_dict["category"]
}
}, indent=2))
# Test list response structure
print(f"\nπŸ“‹ List Response Structure:")
print("-" * 30)
# Test with projection
projection_fields = ["catalogue_id", "catalogue_code", "catalogue_name", "brand", "category"]
projected_data = {field: catalogue_dict[field] for field in projection_fields if field in catalogue_dict}
print("βœ… List Response with Projection:")
print(json.dumps({
"data": [projected_data],
"count": 1,
"page": 1,
"page_size": 10,
"status": "Success"
}, indent=2))
# Verify catalogue_code is always included in projections
if "catalogue_code" not in projected_data:
print("❌ catalogue_code missing from projection")
return False
print(f"\nβœ… catalogue_code included in projection: {projected_data['catalogue_code']}")
return True
def test_api_examples():
"""Test realistic API request/response examples"""
print(f"\n🌐 API Request/Response Examples:")
print("=" * 40)
# Create request example
print("1️⃣ CREATE Request:")
create_request = {
"catalogue_name": "L'Oreal Professional Shampoo 500ml",
"catalogue_type": "Product",
"brand": "LOREAL",
"category": "SHAMPOO",
"description": "Professional grade shampoo for all hair types",
"identifiers": {
"sku": "LOR-SHA-500ML",
"ean_code": "1234567890123"
},
"pricing": {
"retail_price": 850.00,
"mrp": 1000.00,
"currency": "INR"
}
}
print("Request Body:")
print(json.dumps(create_request, indent=2))
print("\nExpected Response:")
create_response = {
"data": {
"catalogue_id": "550e8400-e29b-41d4-a716-446655440000",
"catalogue_code": "LOR-SHA-000001",
**create_request
}
}
print(json.dumps(create_response, indent=2))
# Update request example
print(f"\n2️⃣ UPDATE Request:")
update_request = {
"pricing": {
"retail_price": 900.00,
"mrp": 1100.00
},
"description": "Updated description"
}
print("Request Body:")
print(json.dumps(update_request, indent=2))
print("\nExpected Response:")
update_response = {
"data": {
"catalogue_id": "550e8400-e29b-41d4-a716-446655440000",
"catalogue_code": "LOR-SHA-000001",
"catalogue_name": "L'Oreal Professional Shampoo 500ml",
"catalogue_type": "Product",
"brand": "LOREAL",
"category": "SHAMPOO",
"description": "Updated description",
"pricing": {
"retail_price": 900.00,
"mrp": 1100.00,
"currency": "INR"
}
}
}
print(json.dumps(update_response, indent=2))
# List request example
print(f"\n3️⃣ LIST Request with Projection:")
list_request = {
"filters": {
"brand": "LOREAL",
"status": "Active"
},
"page": 1,
"page_size": 10,
"projection_list": ["catalogue_id", "catalogue_code", "catalogue_name", "brand", "pricing.mrp"]
}
print("Request Body:")
print(json.dumps(list_request, indent=2))
print("\nExpected Response:")
list_response = {
"data": [
{
"catalogue_id": "550e8400-e29b-41d4-a716-446655440000",
"catalogue_code": "LOR-SHA-000001",
"catalogue_name": "L'Oreal Professional Shampoo 500ml",
"brand": "LOREAL",
"pricing": {"mrp": 1100.00}
}
],
"count": 1,
"page": 1,
"page_size": 10,
"status": "Success"
}
print(json.dumps(list_response, indent=2))
print(f"\nβœ… All API examples include catalogue_code!")
return True
def test_essential_fields_validation():
"""Test that essential fields are always included"""
print(f"\nπŸ” Essential Fields Validation:")
print("-" * 35)
essential_fields = ["catalogue_id", "catalogue_code"]
# Test different projection scenarios
test_projections = [
["catalogue_name", "brand"], # Should auto-include essential fields
["catalogue_id", "catalogue_name"], # Should auto-include catalogue_code
["catalogue_code", "brand"], # Should auto-include catalogue_id
["pricing.mrp", "category"], # Should auto-include both essential fields
]
for i, projection in enumerate(test_projections, 1):
print(f"\n{i}. Projection: {projection}")
# Simulate the service logic
projection_dict = {field: 1 for field in projection}
# Add essential fields (as implemented in service)
for field in essential_fields:
if field not in projection_dict:
projection_dict[field] = 1
final_fields = list(projection_dict.keys())
print(f" Final fields: {final_fields}")
# Verify essential fields are included
missing_essential = [field for field in essential_fields if field not in final_fields]
if missing_essential:
print(f" ❌ Missing essential fields: {missing_essential}")
return False
else:
print(f" βœ… All essential fields included")
print(f"\nβœ… Essential fields validation passed!")
return True
if __name__ == "__main__":
print("πŸš€ Starting Catalogue Response Tests\n")
# Run all tests
success1 = test_catalogue_response_structure()
success2 = test_api_examples()
success3 = test_essential_fields_validation()
overall_success = success1 and success2 and success3
print(f"\n{'='*50}")
print(f"πŸ“Š Test Results:")
print(f" Response Structure: {'βœ… PASS' if success1 else '❌ FAIL'}")
print(f" API Examples: {'βœ… PASS' if success2 else '❌ FAIL'}")
print(f" Essential Fields: {'βœ… PASS' if success3 else '❌ FAIL'}")
print(f" Overall: {'βœ… PASS' if overall_success else '❌ FAIL'}")
if overall_success:
print(f"\nπŸŽ‰ catalogue_code is properly included in all responses!")
print(f" βœ… Create responses include catalogue_code")
print(f" βœ… Update responses include catalogue_code")
print(f" βœ… List responses always include catalogue_code")
print(f" βœ… Essential fields auto-included in projections")
sys.exit(0 if overall_success else 1)