Fix add product dialog opening and duplicate validation tests
This commit is contained in:
@@ -15,6 +15,7 @@ import {
|
|||||||
import CloseIcon from '@mui/icons-material/Close';
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import { useDatabase } from '../context/DBProvider';
|
import { useDatabase } from '../context/DBProvider';
|
||||||
|
import { useProducts } from '../hooks/dataHooks';
|
||||||
import { BarcodeScannerView } from './BarcodeScannerView';
|
import { BarcodeScannerView } from './BarcodeScannerView';
|
||||||
import { ExternalProductInfo, fetchProductFromOFF } from '../modules/openFoodFacts';
|
import { ExternalProductInfo, fetchProductFromOFF } from '../modules/openFoodFacts';
|
||||||
import { DEFAULT_BULK_NAME, DEFAULT_UNIT_TYPE, Product } from '../models/Product';
|
import { DEFAULT_BULK_NAME, DEFAULT_UNIT_TYPE, Product } from '../models/Product';
|
||||||
@@ -35,6 +36,7 @@ export const AddProductDialog = ({
|
|||||||
initialBarcode,
|
initialBarcode,
|
||||||
}: AddProductDialogProps) => {
|
}: AddProductDialogProps) => {
|
||||||
const db = useDatabase();
|
const db = useDatabase();
|
||||||
|
const products = useProducts();
|
||||||
const [name, setName] = useState('');
|
const [name, setName] = useState('');
|
||||||
const [category, setCategory] = useState('');
|
const [category, setCategory] = useState('');
|
||||||
const [barcode, setBarcode] = useState('');
|
const [barcode, setBarcode] = useState('');
|
||||||
@@ -83,20 +85,26 @@ export const AddProductDialog = ({
|
|||||||
const findBarcodeConflict = useCallback(
|
const findBarcodeConflict = useCallback(
|
||||||
async (value?: string) => {
|
async (value?: string) => {
|
||||||
if (!value) return undefined;
|
if (!value) return undefined;
|
||||||
const conflict = await db.products.where('barcode').equals(value).first();
|
const conflict = products.find((product) => product.barcode === value);
|
||||||
return conflict ?? undefined;
|
if (conflict) return conflict;
|
||||||
|
const dbConflict = await db.products.where('barcode').equals(value).first();
|
||||||
|
return dbConflict ?? undefined;
|
||||||
},
|
},
|
||||||
[db.products],
|
[db.products, products],
|
||||||
);
|
);
|
||||||
|
|
||||||
const findNameConflict = useCallback(
|
const findNameConflict = useCallback(
|
||||||
async (value?: string) => {
|
async (value?: string) => {
|
||||||
if (!value) return undefined;
|
if (!value) return undefined;
|
||||||
const normalizedValue = value.trim().toLowerCase();
|
const normalizedValue = value.trim().toLowerCase();
|
||||||
const conflict = await db.products.filter((product) => product.name.trim().toLowerCase() === normalizedValue).first();
|
const conflict = products.find((product) => product.name.trim().toLowerCase() === normalizedValue);
|
||||||
return conflict ?? undefined;
|
if (conflict) return conflict;
|
||||||
|
const dbConflict = await db.products
|
||||||
|
.filter((product) => product.name.trim().toLowerCase() === normalizedValue)
|
||||||
|
.first();
|
||||||
|
return dbConflict ?? undefined;
|
||||||
},
|
},
|
||||||
[db.products],
|
[db.products, products],
|
||||||
);
|
);
|
||||||
|
|
||||||
const assertUniqueBarcode = useCallback(
|
const assertUniqueBarcode = useCallback(
|
||||||
@@ -254,7 +262,14 @@ export const AddProductDialog = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} onClose={handleDialogClose} aria-label="Add product dialog" fullWidth maxWidth="sm">
|
<Dialog
|
||||||
|
open={open}
|
||||||
|
onClose={handleDialogClose}
|
||||||
|
aria-label="Add product dialog"
|
||||||
|
fullWidth
|
||||||
|
maxWidth="sm"
|
||||||
|
PaperProps={{ role: 'form' }}
|
||||||
|
>
|
||||||
<DialogTitle sx={{ pr: 6 }}>
|
<DialogTitle sx={{ pr: 6 }}>
|
||||||
Add product
|
Add product
|
||||||
<IconButton
|
<IconButton
|
||||||
@@ -294,6 +309,7 @@ export const AddProductDialog = ({
|
|||||||
inputProps={{ 'data-testid': 'product-barcode-input' }}
|
inputProps={{ 'data-testid': 'product-barcode-input' }}
|
||||||
error={!!barcodeError}
|
error={!!barcodeError}
|
||||||
helperText={barcodeError || ' '}
|
helperText={barcodeError || ' '}
|
||||||
|
FormHelperTextProps={{ 'data-testid': 'barcode-error' }}
|
||||||
fullWidth
|
fullWidth
|
||||||
/>
|
/>
|
||||||
<Button onClick={() => setScannerOpen(true)}>Scan barcode</Button>
|
<Button onClick={() => setScannerOpen(true)}>Scan barcode</Button>
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ describe('ManageProductsScreen add and update flows', () => {
|
|||||||
</MemoryRouter>,
|
</MemoryRouter>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await user.click(screen.getByRole('button', { name: /add product/i }));
|
||||||
await user.type(screen.getByLabelText(/name/i), 'New Product');
|
await user.type(screen.getByLabelText(/name/i), 'New Product');
|
||||||
await selectCategory(user, 'Snacks');
|
await selectCategory(user, 'Snacks');
|
||||||
await user.type(screen.getByLabelText(/barcode/i), '111');
|
await user.type(screen.getByLabelText(/barcode/i), '111');
|
||||||
@@ -91,6 +92,7 @@ describe('ManageProductsScreen add and update flows', () => {
|
|||||||
</MemoryRouter>,
|
</MemoryRouter>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await user.click(screen.getByRole('button', { name: /add product/i }));
|
||||||
await user.type(screen.getByLabelText(/name/i), 'Another');
|
await user.type(screen.getByLabelText(/name/i), 'Another');
|
||||||
await selectCategory(user, 'Snacks');
|
await selectCategory(user, 'Snacks');
|
||||||
await user.click(screen.getByText(/scan barcode/i));
|
await user.click(screen.getByText(/scan barcode/i));
|
||||||
@@ -139,6 +141,7 @@ describe('ManageProductsScreen add and update flows', () => {
|
|||||||
</MemoryRouter>,
|
</MemoryRouter>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await user.click(screen.getByRole('button', { name: /add product/i }));
|
||||||
await user.type(screen.getByLabelText(/name/i), 'Lettuce');
|
await user.type(screen.getByLabelText(/name/i), 'Lettuce');
|
||||||
await selectCategory(user, 'Fresh');
|
await selectCategory(user, 'Fresh');
|
||||||
await clickSaveButton(user);
|
await clickSaveButton(user);
|
||||||
|
|||||||
Reference in New Issue
Block a user