|
|
|
@ -104,21 +104,21 @@ tap.test('should search products by basic search method', async () => {
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('should search products with searchWithLucene method', async () => {
|
|
|
|
|
tap.test('should search products with search method', async () => {
|
|
|
|
|
// Using the robust searchWithLucene method
|
|
|
|
|
const wirelessResults = await Product.searchWithLucene('wireless');
|
|
|
|
|
console.log(
|
|
|
|
|
`Found ${wirelessResults.length} products matching 'wireless' using searchWithLucene`,
|
|
|
|
|
);
|
|
|
|
|
const wirelessResults = await Product.search('wireless');
|
|
|
|
|
console.log(
|
|
|
|
|
`Found ${wirelessResults.length} products matching 'wireless' using search`,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(wirelessResults.length).toEqual(1);
|
|
|
|
|
expect(wirelessResults[0].name).toEqual('AirPods');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('should search products by category with searchWithLucene', async () => {
|
|
|
|
|
tap.test('should search products by category with search', async () => {
|
|
|
|
|
// Using field-specific search with searchWithLucene
|
|
|
|
|
const kitchenResults = await Product.searchWithLucene('category:Kitchen');
|
|
|
|
|
console.log(`Found ${kitchenResults.length} products in Kitchen category using searchWithLucene`);
|
|
|
|
|
const kitchenResults = await Product.search('category:Kitchen');
|
|
|
|
|
console.log(`Found ${kitchenResults.length} products in Kitchen category using search`);
|
|
|
|
|
|
|
|
|
|
expect(kitchenResults.length).toEqual(2);
|
|
|
|
|
expect(kitchenResults[0].category).toEqual('Kitchen');
|
|
|
|
@ -127,7 +127,7 @@ tap.test('should search products by category with searchWithLucene', async () =>
|
|
|
|
|
|
|
|
|
|
tap.test('should search products with partial word matches', async () => {
|
|
|
|
|
// Testing partial word matches
|
|
|
|
|
const proResults = await Product.searchWithLucene('Pro');
|
|
|
|
|
const proResults = await Product.search('Pro');
|
|
|
|
|
console.log(`Found ${proResults.length} products matching 'Pro'`);
|
|
|
|
|
|
|
|
|
|
// Should match both "MacBook Pro" and "professionals" in description
|
|
|
|
@ -136,7 +136,7 @@ tap.test('should search products with partial word matches', async () => {
|
|
|
|
|
|
|
|
|
|
tap.test('should search across multiple searchable fields', async () => {
|
|
|
|
|
// Test searching across all searchable fields
|
|
|
|
|
const bookResults = await Product.searchWithLucene('book');
|
|
|
|
|
const bookResults = await Product.search('book');
|
|
|
|
|
console.log(`Found ${bookResults.length} products matching 'book' across all fields`);
|
|
|
|
|
|
|
|
|
|
// Should match "MacBook" in name and "Books" in category
|
|
|
|
@ -145,8 +145,8 @@ tap.test('should search across multiple searchable fields', async () => {
|
|
|
|
|
|
|
|
|
|
tap.test('should handle case insensitive searches', async () => {
|
|
|
|
|
// Test case insensitivity
|
|
|
|
|
const electronicsResults = await Product.searchWithLucene('electronics');
|
|
|
|
|
const ElectronicsResults = await Product.searchWithLucene('Electronics');
|
|
|
|
|
const electronicsResults = await Product.search('electronics');
|
|
|
|
|
const ElectronicsResults = await Product.search('Electronics');
|
|
|
|
|
|
|
|
|
|
console.log(`Found ${electronicsResults.length} products matching lowercase 'electronics'`);
|
|
|
|
|
console.log(`Found ${ElectronicsResults.length} products matching capitalized 'Electronics'`);
|
|
|
|
@ -166,14 +166,14 @@ tap.test('should demonstrate search fallback mechanisms', async () => {
|
|
|
|
|
|
|
|
|
|
// Use a simpler term that should be found in descriptions
|
|
|
|
|
// Avoid using "OR" operator which requires a text index
|
|
|
|
|
const results = await Product.searchWithLucene('high');
|
|
|
|
|
const results = await Product.search('high');
|
|
|
|
|
console.log(`Found ${results.length} products matching 'high'`);
|
|
|
|
|
|
|
|
|
|
// "High-speed blender" contains "high"
|
|
|
|
|
expect(results.length).toBeGreaterThan(0);
|
|
|
|
|
|
|
|
|
|
// Try another fallback example that won't need $text
|
|
|
|
|
const powerfulResults = await Product.searchWithLucene('powerful');
|
|
|
|
|
const powerfulResults = await Product.search('powerful');
|
|
|
|
|
console.log(`Found ${powerfulResults.length} products matching 'powerful'`);
|
|
|
|
|
|
|
|
|
|
// "Powerful laptop for professionals" contains "powerful"
|
|
|
|
@ -192,6 +192,35 @@ tap.test('should explain the advantages of the integrated approach', async () =>
|
|
|
|
|
expect(true).toEqual(true);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Additional robustness tests
|
|
|
|
|
tap.test('should search exact name using field:value', async () => {
|
|
|
|
|
const nameResults = await Product.search('name:AirPods');
|
|
|
|
|
expect(nameResults.length).toEqual(1);
|
|
|
|
|
expect(nameResults[0].name).toEqual('AirPods');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('should throw when searching non-searchable field', async () => {
|
|
|
|
|
let error: Error;
|
|
|
|
|
try {
|
|
|
|
|
await Product.search('price:129');
|
|
|
|
|
} catch (err) {
|
|
|
|
|
error = err as Error;
|
|
|
|
|
}
|
|
|
|
|
expect(error).toBeTruthy();
|
|
|
|
|
expect(error.message).toMatch(/not searchable/);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('empty query should return all products', async () => {
|
|
|
|
|
const allResults = await Product.search('');
|
|
|
|
|
expect(allResults.length).toEqual(8);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('should search multi-word term across fields', async () => {
|
|
|
|
|
const termResults = await Product.search('iPhone 12');
|
|
|
|
|
expect(termResults.length).toEqual(1);
|
|
|
|
|
expect(termResults[0].name).toEqual('iPhone 12');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('close database connection', async () => {
|
|
|
|
|
await testDb.mongoDb.dropDatabase();
|
|
|
|
|
await testDb.close();
|
|
|
|
|