Skip to content

Commit

Permalink
Added tests for search products
Browse files Browse the repository at this point in the history
  • Loading branch information
pkirilin committed Oct 30, 2024
1 parent f40cd7f commit 3e38fef
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 11 deletions.
28 changes: 28 additions & 0 deletions src/frontend/src/features/addNote/lib/searchProductsByName.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { type ProductSelectOption } from '@/entities/product';
import { searchProductsByName } from './searchProductsByName';

type GivenProducts = 'cheese' | 'cheesecake' | 'chocolateCake' | 'creamCheese';

const given: Record<GivenProducts, ProductSelectOption> = {
cheese: { id: 1, name: 'Cheese', defaultQuantity: 120 },
cheesecake: { id: 2, name: 'Cheesecake', defaultQuantity: 50 },
chocolateCake: { id: 3, name: 'Chocolate cake', defaultQuantity: 60 },
creamCheese: { id: 4, name: 'Cream cheese', defaultQuantity: 100 },
};

const sourceProducts = Object.values(given);

test.each<[string, ProductSelectOption[]]>([
['che', [given.cheese, given.cheesecake, given.creamCheese]],
['cream', [given.creamCheese]],
['Cake ', [given.cheesecake, given.chocolateCake]],
])('should find products by search query: "%s"', (query, foundProducts) => {
expect(searchProductsByName(sourceProducts, query)).toStrictEqual(foundProducts);
});

test.each<string>(['', ' ', 'ch', 'sadsfafds'])(
'should not find any products by search query: "%s"',
query => {
expect(searchProductsByName(sourceProducts, query)).toStrictEqual<ProductSelectOption[]>([]);
},
);
18 changes: 18 additions & 0 deletions src/frontend/src/features/addNote/lib/searchProductsByName.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { type ProductSelectOption } from '@/entities/product';

const QUERY_LENGTH_THRESHOLD = 3;

export const searchProductsByName = (
sourceProducts: ProductSelectOption[],
query: string,
): ProductSelectOption[] => {
const queryTrimmed = query.trim();

if (queryTrimmed.length < QUERY_LENGTH_THRESHOLD) {
return [];
}

return sourceProducts.filter(product =>
product.name.trim().toLowerCase().includes(queryTrimmed.toLowerCase()),
);
};
14 changes: 3 additions & 11 deletions src/frontend/src/features/addNote/ui/SearchProducts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useState, type FC, useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { useDebounce } from 'use-debounce';
import { type ProductSelectOption, productApi } from '@/entities/product';
import { searchProductsByName } from '../lib/searchProductsByName';
import { FoundProductsList } from './FoundProductsList';
import { UploadImageButton } from './UploadImageButton';

Expand All @@ -12,10 +13,8 @@ interface FormValues {
}

const DEBOUNCE_QUERY_DELAY = 300;
const DEBOUNCE_QUERY_LENGTH_THRESHOLD = 3;
const EMPTY_PRODUCTS: ProductSelectOption[] = [];

// TODO: add tests
export const SearchProducts: FC = () => {
const { register, watch } = useForm<FormValues>({
mode: 'onChange',
Expand All @@ -33,17 +32,10 @@ export const SearchProducts: FC = () => {
const [foundProducts, setFoundProducts] = useState<ProductSelectOption[]>([]);

useEffect(() => {
if (debouncedQuery.trim().length >= DEBOUNCE_QUERY_LENGTH_THRESHOLD) {
setFoundProducts(
products.filter(product =>
product.name.trim().toLowerCase().includes(debouncedQuery.trim().toLowerCase()),
),
);
} else {
setFoundProducts([]);
}
setFoundProducts(searchProductsByName(products, debouncedQuery));
}, [products, debouncedQuery]);

// TODO: add auto focuses
return (
<>
<TextField
Expand Down

0 comments on commit 3e38fef

Please sign in to comment.