All checks were successful
Deploy Beta (NATIVE) / deploy (push) Successful in 16s
134 lines
5.4 KiB
Python
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')
|