paymentservice/api/tests.py
2026-10-18 15:13:03 +00:00

134 lines
5.4 KiB
Python

from django.test import TestCase
from rest_framework.test import APIClient
from unittest.mock import patch, MagicMock
from api.typesense_client import (
TypesenseService,
safe_str,
safe_int,
safe_float,
safe_bool,
)
class TypesenseServiceUnitTests(TestCase):
def test_safe_helpers(self):
self.assertEqual(safe_str(None, "default"), "default")
self.assertEqual(safe_str(123), "123")
self.assertEqual(safe_int(None, 10), 10)
self.assertEqual(safe_int("42"), 42)
self.assertEqual(safe_int("invalid", 5), 5)
self.assertEqual(safe_float(None, 3.14), 3.14)
self.assertEqual(safe_float("99.95"), 99.95)
self.assertEqual(safe_float("invalid", 0.0), 0.0)
self.assertTrue(safe_bool("true"))
self.assertTrue(safe_bool("1"))
self.assertFalse(safe_bool("false"))
self.assertFalse(safe_bool("0"))
self.assertFalse(safe_bool(None, False))
def test_prepare_product_doc_handles_nulls_gracefully(self):
raw_product = {
'id': 101,
'sku': 'TRDX-TEST-001',
'title': 'Test Silk Saree',
'description': None,
'category': None,
'supplier_id': None,
'supplier_name': None,
'price': None,
'compare_at_price': None,
'stock': None,
'image': None,
'is_gi_tagged': None,
'is_active': None,
'status': None,
'created_at': None
}
doc = TypesenseService.prepare_product_doc(raw_product)
self.assertEqual(doc['id'], '101')
self.assertEqual(doc['sku'], 'TRDX-TEST-001')
self.assertEqual(doc['title'], 'Test Silk Saree')
self.assertEqual(doc['description'], '')
self.assertEqual(doc['category'], 'Uncategorized')
self.assertEqual(doc['supplier_id'], 0)
self.assertEqual(doc['price'], 0.0)
self.assertEqual(doc['compare_at_price'], 0.0)
self.assertEqual(doc['stock'], 0)
self.assertFalse(doc['is_gi_tagged'])
self.assertTrue(doc['is_active'])
self.assertEqual(doc['status'], 'active')
self.assertEqual(doc['created_at'], 0)
class SearchAndIndexApiTests(TestCase):
def setUp(self):
self.client = APIClient()
@patch.object(TypesenseService, 'search_products')
def test_search_view_defaults(self, mock_search):
mock_search.return_value = {
'hits': [{'document': {'id': '1', 'title': 'Product 1'}}],
'found': 1,
'facet_counts': []
}
response = self.client.get('/api/search/', {'q': 'saree'})
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['count'], 1)
self.assertEqual(len(response.data['results']), 1)
mock_search.assert_called_once()
_, kwargs = mock_search.call_args
self.assertEqual(kwargs['query'], 'saree')
self.assertIn('is_active:=true', kwargs['filter_by'])
self.assertEqual(kwargs['sort_by'], '_text_match:desc,created_at:desc')
@patch.object(TypesenseService, 'search_products')
def test_search_view_filters_and_sorting(self, mock_search):
mock_search.return_value = {'hits': [], 'found': 0, 'facet_counts': []}
response = self.client.get('/api/search/', {
'q': '*',
'category': 'Textiles & Silk',
'min_price': '100',
'max_price': '500',
'is_gi_tagged': 'false',
'supplier_id': '42',
'sort_by': 'price_asc',
'page': '2',
'per_page': '10'
})
self.assertEqual(response.status_code, 200)
_, kwargs = mock_search.call_args
self.assertIn('category:="Textiles & Silk"', kwargs['filter_by'])
self.assertIn('price:[100.0..500.0]', kwargs['filter_by'])
self.assertIn('is_gi_tagged:=false', kwargs['filter_by'])
self.assertIn('supplier_id:=42', kwargs['filter_by'])
self.assertEqual(kwargs['sort_by'], 'price:asc')
self.assertEqual(kwargs['page'], 2)
self.assertEqual(kwargs['per_page'], 10)
@patch.object(TypesenseService, 'index_product')
def test_index_single_product(self, mock_index):
mock_index.return_value = {'success': True}
payload = {'id': 1, 'sku': 'SKU123', 'title': 'Test Item', 'price': 99.0}
response = self.client.post('/api/index/product/', payload, format='json')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['status'], 'indexed')
@patch.object(TypesenseService, 'index_products_batch')
def test_index_batch_products(self, mock_batch):
mock_batch.return_value = [{'success': True}, {'success': True}]
payload = [
{'id': 1, 'sku': 'SKU1', 'title': 'Item 1'},
{'id': 2, 'sku': 'SKU2', 'title': 'Item 2'}
]
response = self.client.post('/api/index/product/', payload, format='json')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['count'], 2)
@patch.object(TypesenseService, 'delete_product')
def test_delete_product(self, mock_delete):
mock_delete.return_value = {'deleted': True}
response = self.client.delete('/api/index/product/TRDX-001/')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['status'], 'deleted')
mock_delete.assert_called_once_with('TRDX-001')