fix: correct contradictory toggle-sequence copy in schedule-repair toast

The blocking toast told operators to toggle the weekly window "off then
on" to confirm clearing a corrupt schedule, but the toggle starts off
for a corrupt rule, so that sequence leaves it on and trips the
no-selected-day validation instead. The correct, tested sequence is on
then off, matching the inline hint below the toggle. Also add a
regression test confirming the invalid-schedule save gate resets
cleanly across edit sessions on different rules.
This commit is contained in:
SaelixCode
2026-07-21 14:09:58 -04:00
parent cb97cc097c
commit 95df639d7b
2 changed files with 26 additions and 1 deletions
@@ -282,7 +282,7 @@ export function NotificationSuppressionSection({
if (!formName.trim()) { toast.error('Name is required.'); return; }
if (formScheduleInvalid && !formScheduleTouched) {
toast.error(
"This rule's stored weekly window could not be read. Turn the weekly window on to set a new schedule, or toggle it off then on to confirm clearing it.",
"This rule's stored weekly window could not be read. Turn the weekly window on to set a new schedule, or toggle it on then off to confirm clearing it.",
);
return;
}
@@ -368,4 +368,29 @@ describe('NotificationSuppressionSection', () => {
});
});
});
it('does not carry the invalid-schedule save gate over to a later edit of a different, valid rule', async () => {
mockListRules([corruptScheduleRule, scheduledRule]);
render(<NotificationSuppressionSection />);
await waitFor(() => expect(screen.getByText('Corrupt window')).toBeInTheDocument());
const editButtons = screen.getAllByTitle('Edit');
await userEvent.click(editButtons[0]);
await waitFor(() => expect(screen.getByRole('dialog', { name: /Edit mute rule/i })).toBeInTheDocument());
await userEvent.click(screen.getByRole('button', { name: 'Cancel' }));
await waitFor(() => expect(screen.queryByRole('dialog')).not.toBeInTheDocument());
await userEvent.click(screen.getAllByTitle('Edit')[1]);
await waitFor(() => expect(screen.getByRole('dialog', { name: /Edit mute rule/i })).toBeInTheDocument());
await userEvent.click(screen.getByRole('button', { name: /Create|Update/i }));
await waitFor(() => {
const put = mockedFetch.mock.calls.find(
([url, opts]) =>
url === '/notification-suppression-rules/42' && (opts as { method?: string })?.method === 'PUT',
);
expect(put).toBeTruthy();
});
expect(toast.error).not.toHaveBeenCalledWith(expect.stringContaining('could not be read'));
});
});