mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-09-30 19:21:33 +02:00
Add tests for core_weight_catalog_id handling
This commit is contained in:
@@ -62,6 +62,7 @@ const existingSpool: InventorySpool = {
|
||||
rgba: 'FF0000FF',
|
||||
label_weight: 1000,
|
||||
core_weight: 250,
|
||||
core_weight_catalog_id: null,
|
||||
weight_used: 300,
|
||||
slicer_filament: 'GFL99',
|
||||
slicer_filament_name: 'Generic PLA',
|
||||
@@ -183,4 +184,140 @@ describe('SpoolFormModal weightTouched', () => {
|
||||
// weight_used MUST be included for new spools (default value 0)
|
||||
expect(payload).toHaveProperty('weight_used', 0);
|
||||
});
|
||||
|
||||
it('preserves core_weight_catalog_id when editing other fields', async () => {
|
||||
const spoolWithCatalogId: InventorySpool = {
|
||||
...existingSpool,
|
||||
core_weight_catalog_id: 5,
|
||||
};
|
||||
|
||||
render(
|
||||
<SpoolFormModal
|
||||
isOpen={true}
|
||||
onClose={vi.fn()}
|
||||
spool={spoolWithCatalogId}
|
||||
/>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Edit Spool')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Change the note field (unrelated to catalog ID)
|
||||
const noteInputs = screen.getAllByPlaceholderText(/note/i);
|
||||
expect(noteInputs.length).toBeGreaterThan(0);
|
||||
fireEvent.change(noteInputs[0], { target: { value: 'Updated note' } });
|
||||
|
||||
// Click Save
|
||||
const saveButton = screen.getByRole('button', { name: /save/i });
|
||||
fireEvent.click(saveButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(api.updateSpool).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
const [spoolId, payload] = vi.mocked(api.updateSpool).mock.calls[0];
|
||||
expect(spoolId).toBe(1);
|
||||
// core_weight_catalog_id MUST be preserved when editing other fields
|
||||
expect(payload).toHaveProperty('core_weight_catalog_id', 5);
|
||||
// Other changes should also be present
|
||||
expect(payload).toHaveProperty('note', 'Updated note');
|
||||
});
|
||||
|
||||
it('includes core_weight_catalog_id when selecting from catalog', async () => {
|
||||
const mockCatalog = [
|
||||
{ id: 1, name: 'Generic 250g', weight: 250 },
|
||||
{ id: 2, name: 'Bambu Lab 250g', weight: 250 },
|
||||
{ id: 3, name: 'Standard 300g', weight: 300 },
|
||||
];
|
||||
|
||||
vi.mocked(api.getSpoolCatalog).mockResolvedValue(mockCatalog);
|
||||
|
||||
render(
|
||||
<SpoolFormModal
|
||||
isOpen={true}
|
||||
onClose={vi.fn()}
|
||||
/>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('heading', { name: 'Add Spool' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Wait for catalog to load
|
||||
await waitFor(() => {
|
||||
expect(api.getSpoolCatalog).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// Click on the empty spool weight field to open dropdown
|
||||
const weightInputs = screen.getAllByPlaceholderText(/search/i);
|
||||
const weightPicker = weightInputs.find(input =>
|
||||
input.getAttribute('placeholder')?.toLowerCase().includes('spool')
|
||||
);
|
||||
expect(weightPicker).toBeTruthy();
|
||||
fireEvent.focus(weightPicker!);
|
||||
|
||||
// Click on "Bambu Lab 250g" option
|
||||
await waitFor(() => {
|
||||
const bambuOption = screen.queryByText('Bambu Lab 250g');
|
||||
if (bambuOption) fireEvent.click(bambuOption);
|
||||
});
|
||||
|
||||
// Click the add spool button
|
||||
const addButtons = screen.getAllByRole('button', { name: /add spool/i });
|
||||
const submitButton = addButtons.find(btn => btn.tagName === 'BUTTON' && btn.querySelector('svg.lucide-save'));
|
||||
expect(submitButton).toBeTruthy();
|
||||
fireEvent.click(submitButton!);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(api.createSpool).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
const [payload] = vi.mocked(api.createSpool).mock.calls[0];
|
||||
// Both weight AND catalog ID should be sent
|
||||
expect(payload).toHaveProperty('core_weight', 250);
|
||||
expect(payload).toHaveProperty('core_weight_catalog_id', 2); // ID of "Bambu Lab 250g"
|
||||
});
|
||||
|
||||
it('displays correct catalog name when duplicates exist', async () => {
|
||||
const spoolWithCatalogId: InventorySpool = {
|
||||
...existingSpool,
|
||||
core_weight: 250,
|
||||
core_weight_catalog_id: 2, // "Bambu Lab 250g", not the first match
|
||||
};
|
||||
|
||||
const mockCatalog = [
|
||||
{ id: 1, name: 'Generic 250g', weight: 250 },
|
||||
{ id: 2, name: 'Bambu Lab 250g', weight: 250 },
|
||||
{ id: 3, name: 'Standard 300g', weight: 300 },
|
||||
];
|
||||
|
||||
vi.mocked(api.getSpoolCatalog).mockResolvedValue(mockCatalog);
|
||||
|
||||
render(
|
||||
<SpoolFormModal
|
||||
isOpen={true}
|
||||
onClose={vi.fn()}
|
||||
spool={spoolWithCatalogId}
|
||||
/>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Edit Spool')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Wait for catalog to load
|
||||
await waitFor(() => {
|
||||
expect(api.getSpoolCatalog).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// Should display "Bambu Lab 250g" (by ID), not "Generic 250g" (first match by weight)
|
||||
await waitFor(() => {
|
||||
const weightInputs = screen.getAllByDisplayValue(/250|Bambu/i);
|
||||
const bambuFound = weightInputs.some(input =>
|
||||
input.value === 'Bambu Lab 250g' || input.getAttribute('value') === 'Bambu Lab 250g'
|
||||
);
|
||||
expect(bambuFound || screen.queryByText('Bambu Lab 250g')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user