Skip to content

Commit 426912b

Browse files
committed
added tests to cover new code
1 parent 9f9e3cb commit 426912b

File tree

2 files changed

+379
-17
lines changed

2 files changed

+379
-17
lines changed

src/__tests__/components/flow/CodeEditorModal.test.tsx

Lines changed: 177 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ describe('CodeEditorModal', () => {
6262
expect(screen.getByText(/Edge ID: edge-123/i)).toBeInTheDocument();
6363
});
6464

65-
it('calls onSave when Save is clicked and shows success feedback', async () => {
65+
it('calls onSave when Save is clicked and modal stays open', async () => {
6666
const onSave = jest.fn().mockResolvedValue(undefined);
6767
const onClose = jest.fn();
6868

@@ -74,7 +74,7 @@ describe('CodeEditorModal', () => {
7474
/>,
7575
);
7676

77-
fireEvent.click(screen.getByRole('button', { name: /Save/i }));
77+
fireEvent.click(screen.getByRole('button', { name: /💾 Save/i }));
7878

7979
await waitFor(() => {
8080
expect(onSave).toHaveBeenCalledWith('initial code');
@@ -93,9 +93,182 @@ describe('CodeEditorModal', () => {
9393
/>,
9494
);
9595

96-
fireEvent.click(screen.getByRole('button', { name: /Save/i }));
96+
fireEvent.click(screen.getByRole('button', { name: /💾 Save/i }));
9797

9898
expect(await screen.findByTestId('confirm-Unable to save file')).toBeInTheDocument();
9999
});
100-
});
101100

101+
it('does not render when isOpen is false', () => {
102+
render(<CodeEditorModal {...defaultProps} isOpen={false} />);
103+
expect(screen.queryByText(/Reaction Editor/i)).not.toBeInTheDocument();
104+
});
105+
106+
it('updates code when editor content changes', () => {
107+
render(<CodeEditorModal {...defaultProps} />);
108+
109+
const editor = screen.getByTestId('monaco-editor');
110+
fireEvent.change(editor, { target: { value: 'new code' } });
111+
112+
expect(editor).toHaveValue('new code');
113+
});
114+
115+
it('shows unsaved changes indicator after editing', async () => {
116+
render(<CodeEditorModal {...defaultProps} />);
117+
118+
const editor = screen.getByTestId('monaco-editor');
119+
fireEvent.change(editor, { target: { value: 'modified code' } });
120+
121+
expect(screen.getByText(/Unsaved changes/i)).toBeInTheDocument();
122+
});
123+
124+
it('hides unsaved changes indicator when code matches initial code', () => {
125+
render(<CodeEditorModal {...defaultProps} />);
126+
127+
// Initially no unsaved changes
128+
expect(screen.queryByText(/Unsaved changes/i)).not.toBeInTheDocument();
129+
});
130+
131+
it('shows unsaved changes dialog when closing with unsaved changes', async () => {
132+
const onClose = jest.fn();
133+
render(
134+
<CodeEditorModal
135+
{...defaultProps}
136+
onClose={onClose}
137+
/>,
138+
);
139+
140+
// Modify the code
141+
fireEvent.change(screen.getByTestId('monaco-editor'), {
142+
target: { value: 'modified code' },
143+
});
144+
145+
// Click the X close button
146+
fireEvent.click(screen.getByTitle('Close (Esc)'));
147+
148+
// Should show confirmation dialog, not close immediately
149+
expect(onClose).not.toHaveBeenCalled();
150+
expect(screen.getByTestId('confirm-Unsaved Changes')).toBeInTheDocument();
151+
});
152+
153+
it('closes without saving when confirming unsaved changes dialog', async () => {
154+
const onClose = jest.fn();
155+
render(
156+
<CodeEditorModal
157+
{...defaultProps}
158+
onClose={onClose}
159+
/>,
160+
);
161+
162+
fireEvent.change(screen.getByTestId('monaco-editor'), {
163+
target: { value: 'modified code' },
164+
});
165+
166+
fireEvent.click(screen.getByTitle('Close (Esc)'));
167+
168+
// Click "Discard" / confirm button in dialog
169+
const dialog = screen.getByTestId('confirm-Unsaved Changes');
170+
fireEvent.click(dialog.querySelector('button')!);
171+
172+
expect(onClose).toHaveBeenCalled();
173+
});
174+
175+
it('closes without confirmation when no unsaved changes', () => {
176+
const onClose = jest.fn();
177+
render(
178+
<CodeEditorModal
179+
{...defaultProps}
180+
onClose={onClose}
181+
/>,
182+
);
183+
184+
// Click close without making changes
185+
fireEvent.click(screen.getByTitle('Close (Esc)'));
186+
187+
// Should close immediately without confirmation
188+
expect(onClose).toHaveBeenCalled();
189+
expect(screen.queryByTestId('confirm-Unsaved Changes')).not.toBeInTheDocument();
190+
});
191+
192+
it('hides unsaved changes indicator after successful save', async () => {
193+
const onSave = jest.fn().mockResolvedValue(undefined);
194+
render(
195+
<CodeEditorModal
196+
{...defaultProps}
197+
onSave={onSave}
198+
/>,
199+
);
200+
201+
// Make a change
202+
fireEvent.change(screen.getByTestId('monaco-editor'), {
203+
target: { value: 'modified code' },
204+
});
205+
206+
expect(screen.getByText(/Unsaved changes/i)).toBeInTheDocument();
207+
208+
// Save
209+
fireEvent.click(screen.getByRole('button', { name: /💾 Save/i }));
210+
211+
await waitFor(() => {
212+
expect(screen.queryByText(/Unsaved changes/i)).not.toBeInTheDocument();
213+
});
214+
});
215+
216+
it('calls onDelete and onClose when Delete is clicked and confirmed', async () => {
217+
const onDelete = jest.fn();
218+
const onClose = jest.fn();
219+
220+
render(
221+
<CodeEditorModal
222+
{...defaultProps}
223+
onDelete={onDelete}
224+
onClose={onClose}
225+
/>,
226+
);
227+
228+
fireEvent.click(screen.getByTitle('Delete relation'));
229+
230+
// Confirm the deletion dialog
231+
const dialog = await screen.findByTestId('confirm-Delete Relation');
232+
fireEvent.click(dialog.querySelector('button')!);
233+
234+
expect(onDelete).toHaveBeenCalled();
235+
});
236+
237+
it('does not call onDelete when deletion is cancelled', async () => {
238+
const onDelete = jest.fn();
239+
240+
render(
241+
<CodeEditorModal
242+
{...defaultProps}
243+
onDelete={onDelete}
244+
/>,
245+
);
246+
247+
fireEvent.click(screen.getByTitle('Delete relation'));
248+
249+
const dialog = await screen.findByTestId('confirm-Delete Relation');
250+
const buttons = dialog.querySelectorAll('button');
251+
// Click cancel (second button)
252+
fireEvent.click(buttons[1]);
253+
254+
expect(onDelete).not.toHaveBeenCalled();
255+
});
256+
257+
it('resets code and unsaved state when initialCode prop changes', async () => {
258+
const { rerender } = render(<CodeEditorModal {...defaultProps} />);
259+
260+
// Modify code
261+
fireEvent.change(screen.getByTestId('monaco-editor'), {
262+
target: { value: 'modified code' },
263+
});
264+
expect(screen.getByText(/Unsaved changes/i)).toBeInTheDocument();
265+
266+
// Rerender with new initialCode (simulates reopening editor)
267+
rerender(<CodeEditorModal {...defaultProps} initialCode="new initial code" />);
268+
269+
await waitFor(() => {
270+
expect(screen.getByTestId('monaco-editor')).toHaveValue('new initial code');
271+
expect(screen.queryByText(/Unsaved changes/i)).not.toBeInTheDocument();
272+
});
273+
});
274+
});

0 commit comments

Comments
 (0)