fix(tests): add noCompactor mock + fix note-widget event simulation
Tessera CI/CD / Lint & Type Check (push) Successful in 42s
Tessera CI/CD / Tests (push) Successful in 46s
Tessera CI/CD / Build & Publish Images (push) Successful in 4m3s

- dashboard-grid.test: add noCompactor to react-grid-layout mock
- note-widget.test: enable edit mode before typing (onChange is undefined
  when isEditing=false), replace native dispatchEvent with fireEvent.change

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-02 10:15:17 +02:00
parent 745bd66266
commit 384b2409a2
2 changed files with 19 additions and 46 deletions
@@ -41,6 +41,7 @@ vi.mock('react-grid-layout', () => ({
}: {
children: React.ReactNode;
}) => <div data-testid="responsive-grid">{children}</div>,
noCompactor: () => null,
}));
// Mock dashboard-api
@@ -1,4 +1,4 @@
import { act, render, screen } from '@testing-library/react';
import { act, fireEvent, render, screen } from '@testing-library/react';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
// Mock next-intl
@@ -80,32 +80,15 @@ describe('NoteWidget', () => {
<NoteWidget instanceId="note-1" config={{}} isEditMode={false} />,
);
const editor = screen.getByTestId('md-editor');
// Type into editor
// Enable edit mode so onChange is wired up
await act(async () => {
editor.dispatchEvent(
new Event('change', { bubbles: true }),
);
// Simulate onChange via the mock
const event = new Event('input', { bubbles: true });
Object.defineProperty(event, 'target', { value: { value: '# Hello' } });
// Use fireEvent approach
fireEvent.click(screen.getByRole('button'));
});
// Directly trigger onChange via the textarea
await act(async () => {
const textarea = screen.getByTestId('md-editor') as HTMLTextAreaElement;
// Change value triggers onChange in our mock
Object.getOwnPropertyDescriptor(
HTMLTextAreaElement.prototype,
'value',
)?.set?.call(textarea, '# Hello');
textarea.dispatchEvent(new Event('input', { bubbles: true }));
textarea.dispatchEvent(new Event('change', { bubbles: true }));
});
const textarea = screen.getByTestId('md-editor') as HTMLTextAreaElement;
// Before debounce fires, fetch should NOT have been called
fireEvent.change(textarea, { target: { value: '# Hello' } });
expect(fetchSpy).not.toHaveBeenCalled();
// Advance past debounce window
@@ -126,18 +109,16 @@ describe('NoteWidget', () => {
<NoteWidget instanceId="note-1" config={{}} isEditMode={false} />,
);
// Enable edit mode so onChange is wired up
await act(async () => {
fireEvent.click(screen.getByRole('button'));
});
const textarea = screen.getByTestId('md-editor') as HTMLTextAreaElement;
// Simulate rapid typing — three changes in quick succession
for (const char of ['H', 'He', 'Hel']) {
await act(async () => {
Object.getOwnPropertyDescriptor(
HTMLTextAreaElement.prototype,
'value',
)?.set?.call(textarea, char);
textarea.dispatchEvent(new Event('change', { bubbles: true }));
});
// Small delay between keystrokes (less than debounce)
fireEvent.change(textarea, { target: { value: char } });
await act(async () => {
vi.advanceTimersByTime(200);
});
@@ -162,17 +143,15 @@ describe('NoteWidget', () => {
<NoteWidget instanceId="note-1" config={{}} isEditMode={false} />,
);
// Enable edit mode so onChange is wired up
await act(async () => {
fireEvent.click(screen.getByRole('button'));
});
const textarea = screen.getByTestId('md-editor') as HTMLTextAreaElement;
// First change -> debounce -> save starts
await act(async () => {
Object.getOwnPropertyDescriptor(
HTMLTextAreaElement.prototype,
'value',
)?.set?.call(textarea, 'first');
textarea.dispatchEvent(new Event('change', { bubbles: true }));
});
fireEvent.change(textarea, { target: { value: 'first' } });
await act(async () => {
vi.advanceTimersByTime(1500);
});
@@ -181,14 +160,7 @@ describe('NoteWidget', () => {
expect(fetchSpy).toHaveBeenCalledTimes(1);
// Second change -> debounce -> should abort the first
await act(async () => {
Object.getOwnPropertyDescriptor(
HTMLTextAreaElement.prototype,
'value',
)?.set?.call(textarea, 'second');
textarea.dispatchEvent(new Event('change', { bubbles: true }));
});
fireEvent.change(textarea, { target: { value: 'second' } });
await act(async () => {
vi.advanceTimersByTime(1500);
});