Bläddra i källkod

Add tests for core_weight_catalog_id handling

Matteo Parenti 3 månader sedan
förälder
incheckning
e17b55fe22
1 ändrade filer med 137 tillägg och 0 borttagningar
  1. 137 0
      frontend/src/__tests__/components/SpoolFormModal.test.tsx

+ 137 - 0
frontend/src/__tests__/components/SpoolFormModal.test.tsx

@@ -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();
+    });
+  });
 });