# services/sales/tests/unit/test_repositories.py """ Unit tests for Sales Repository """ import pytest from datetime import datetime, timezone from decimal import Decimal from uuid import UUID from app.repositories.sales_repository import SalesRepository from app.models.sales import SalesData from app.schemas.sales import SalesDataCreate, SalesDataUpdate, SalesDataQuery @pytest.mark.asyncio class TestSalesRepository: """Test Sales Repository operations""" async def test_create_sales_record(self, test_db_session, sample_tenant_id, sample_sales_data): """Test creating a sales record""" repository = SalesRepository(test_db_session) record = await repository.create_sales_record(sample_sales_data, sample_tenant_id) assert record is not None assert record.id is not None assert record.tenant_id == sample_tenant_id assert record.inventory_product_id == sample_sales_data.inventory_product_id assert record.quantity_sold == sample_sales_data.quantity_sold assert record.revenue == sample_sales_data.revenue async def test_get_by_id(self, test_db_session, sample_tenant_id, sample_sales_data): """Test getting a sales record by ID""" repository = SalesRepository(test_db_session) # Create record first created_record = await repository.create_sales_record(sample_sales_data, sample_tenant_id) # Get by ID retrieved_record = await repository.get_by_id(created_record.id) assert retrieved_record is not None assert retrieved_record.id == created_record.id assert retrieved_record.inventory_product_id == created_record.inventory_product_id async def test_get_by_tenant(self, populated_db, sample_tenant_id): """Test getting records by tenant""" repository = SalesRepository(populated_db) records = await repository.get_by_tenant(sample_tenant_id) assert len(records) == 3 # From populated_db fixture assert all(record.tenant_id == sample_tenant_id for record in records) async def test_get_by_product(self, populated_db, sample_tenant_id): """Test getting records by product""" repository = SalesRepository(populated_db) # Get by inventory_product_id instead of product name test_product_id = "550e8400-e29b-41d4-a716-446655440001" records = await repository.get_by_inventory_product_id(sample_tenant_id, test_product_id) assert len(records) == 1 assert records[0].inventory_product_id == test_product_id async def test_update_record(self, test_db_session, sample_tenant_id, sample_sales_data): """Test updating a sales record""" repository = SalesRepository(test_db_session) # Create record first created_record = await repository.create_sales_record(sample_sales_data, sample_tenant_id) # Update record update_data = SalesDataUpdate( inventory_product_id="550e8400-e29b-41d4-a716-446655440999", product_name="Updated Product", quantity_sold=10, revenue=Decimal("25.00") ) updated_record = await repository.update(created_record.id, update_data.model_dump(exclude_unset=True)) assert updated_record.inventory_product_id == "550e8400-e29b-41d4-a716-446655440999" assert updated_record.quantity_sold == 10 assert updated_record.revenue == Decimal("25.00") async def test_delete_record(self, test_db_session, sample_tenant_id, sample_sales_data): """Test deleting a sales record""" repository = SalesRepository(test_db_session) # Create record first created_record = await repository.create_sales_record(sample_sales_data, sample_tenant_id) # Delete record success = await repository.delete(created_record.id) assert success is True # Verify record is deleted deleted_record = await repository.get_by_id(created_record.id) assert deleted_record is None async def test_get_analytics(self, populated_db, sample_tenant_id): """Test getting analytics for tenant""" repository = SalesRepository(populated_db) analytics = await repository.get_analytics(sample_tenant_id) assert "total_revenue" in analytics assert "total_quantity" in analytics assert "total_transactions" in analytics assert "average_transaction_value" in analytics assert analytics["total_transactions"] == 3 async def test_get_product_categories(self, populated_db, sample_tenant_id): """Test getting distinct product categories""" repository = SalesRepository(populated_db) categories = await repository.get_product_categories(sample_tenant_id) assert isinstance(categories, list) # Should be empty since populated_db doesn't set categories async def test_validate_record(self, test_db_session, sample_tenant_id, sample_sales_data): """Test validating a sales record""" repository = SalesRepository(test_db_session) # Create record first created_record = await repository.create_sales_record(sample_sales_data, sample_tenant_id) # Validate record validated_record = await repository.validate_record(created_record.id, "Test validation") assert validated_record.is_validated is True assert validated_record.validation_notes == "Test validation" async def test_query_with_filters(self, populated_db, sample_tenant_id): """Test querying with filters""" repository = SalesRepository(populated_db) query = SalesDataQuery( inventory_product_id="550e8400-e29b-41d4-a716-446655440001", limit=10, offset=0 ) records = await repository.get_by_tenant(sample_tenant_id, query) assert len(records) == 1 assert records[0].inventory_product_id == "550e8400-e29b-41d4-a716-446655440001" async def test_bulk_create(self, test_db_session, sample_tenant_id): """Test bulk creating records""" repository = SalesRepository(test_db_session) # Create multiple records data bulk_data = [ { "date": datetime.now(timezone.utc), "inventory_product_id": f"550e8400-e29b-41d4-a716-{i+100:012x}", "product_name": f"Product {i}", "quantity_sold": i + 1, "revenue": Decimal(str((i + 1) * 2.5)), "source": "bulk_test" } for i in range(5) ] created_count = await repository.bulk_create_sales_data(bulk_data, sample_tenant_id) assert created_count == 5 # Verify records were created all_records = await repository.get_by_tenant(sample_tenant_id) assert len(all_records) == 5 async def test_repository_error_handling(self, test_db_session, sample_tenant_id): """Test repository error handling""" repository = SalesRepository(test_db_session) # Test getting non-existent record non_existent = await repository.get_by_id("non-existent-id") assert non_existent is None # Test deleting non-existent record delete_success = await repository.delete("non-existent-id") assert delete_success is False async def test_performance_bulk_operations(self, test_db_session, sample_tenant_id, performance_test_data): """Test performance of bulk operations""" repository = SalesRepository(test_db_session) # Test bulk create performance import time start_time = time.time() created_count = await repository.bulk_create_sales_data(performance_test_data, sample_tenant_id) end_time = time.time() execution_time = end_time - start_time assert created_count == len(performance_test_data) assert execution_time < 5.0 # Should complete in under 5 seconds # Test bulk retrieval performance start_time = time.time() all_records = await repository.get_by_tenant(sample_tenant_id) end_time = time.time() execution_time = end_time - start_time assert len(all_records) == len(performance_test_data) assert execution_time < 2.0 # Should complete in under 2 seconds