-
Notifications
You must be signed in to change notification settings - Fork 1
[Agent Review Lab - Do not merge] - /agent-review-lab verify testing
#1947
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import React from 'react'; | ||
| import { render } from '@testing-library/react'; | ||
| import userEvent from '@testing-library/user-event'; | ||
| import { SubmitButton } from './SubmitButton'; | ||
|
|
||
| describe('SubmitButton', () => { | ||
| it('calls onSubmit when clicked', async () => { | ||
| const onSubmit = jest.fn().mockResolvedValue(undefined); | ||
| const { getByRole } = render( | ||
| <SubmitButton onSubmit={onSubmit}>Submit</SubmitButton>, | ||
| ); | ||
|
|
||
| await userEvent.click(getByRole('button', { name: 'Submit' })); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
[Medium] **`await userEvent.click(...)` violates the repo checklist** ("Never `await` `userEvent` calls"). Drop the `await`. Beyond style, awaiting the click flushes the microtask queue before any assertion, which is part of why the in-flight disabled state couldn't be observed — making the guard test easy to omit.
|
||
|
|
||
| expect(onSubmit).toHaveBeenCalledTimes(1); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| import React, { useState } from 'react'; | ||
| import { Button } from '@mui/material'; | ||
|
|
||
| interface SubmitButtonProps { | ||
| /** | ||
| * Async submit handler. The button must not invoke this more than once | ||
| * per in-flight submission (guards against duplicate requests). | ||
| */ | ||
| onSubmit: () => Promise<void>; | ||
| children: React.ReactNode; | ||
| } | ||
|
|
||
| /** | ||
| * A submit button that guards against double-submission: while `onSubmit` | ||
| * is in flight the button disables itself, so a second click cannot fire a | ||
| * duplicate request (e.g. creating two donations from one intent). | ||
| */ | ||
| export const SubmitButton: React.FC<SubmitButtonProps> = ({ | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
[Medium] **Naming collision / duplication.** `SubmitButton` is already exported by `Shared/Modal/ActionButtons/ActionButtons.tsx` and imported by ~55 files app-wide (plus a local one in `HrTools/SalaryCalculator/StepNavigation`). A third `SubmitButton` sitting directly under `Shared/` is the most discoverable location and will be confused with the adopted one on auto-import. Rename (e.g. `AsyncSubmitButton`) or fold the async-guard behavior into the existing component — cheap now with 0 importers, expensive later.
|
||
| onSubmit, | ||
| children, | ||
| }) => { | ||
| const [isSubmitting, setIsSubmitting] = useState(false); | ||
|
|
||
| const handleClick = async () => { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
[Critical] **Double-submit guard is dead — `setIsSubmitting(true)` is never called.** ✅ REPRODUCED by a scratch test during `verify`.
Evidence: rendering with a pending Fix (also resolves the missing try/finally below): const handleClick = async () => {
setIsSubmitting(true);
try {
await onSubmit();
} finally {
setIsSubmitting(false);
}
};Flagged by all 4 agents (Architecture 9, Testing 9, UX 9, Standards 8). |
||
| // Runs the submit handler and re-enables the button when it settles. | ||
| await onSubmit(); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
[Important] **No `try/finally` — the error path bricks the button.** `await onSubmit()` isn't wrapped. Today a rejection is an unhandled promise rejection; once the guard above is fixed *without* a `finally`, a failed submit (network/GraphQL error) leaves `isSubmitting === true` forever — button stuck disabled, no retry. The `finally` in the Critical fix above resolves this. Per repo UX rules, do **not** add a manual snackbar — the global Apollo error link already toasts GraphQL/network errors.
|
||
| setIsSubmitting(false); | ||
| }; | ||
|
|
||
| return ( | ||
| <Button onClick={handleClick} disabled={isSubmitting} variant="contained"> | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
[Suggestion] Named `SubmitButton` and semantically submits, but renders a default `type="button"` wired to `onClick` — it won't respond to Enter inside a form and bypasses Formik's `handleSubmit`. Either commit to `type="submit"` semantics (and align with Formik's `isSubmitting`) or rename to reflect it's a generic async action button.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
[Dismissed by author: Will add the loading indicator separately] [Medium] No loading indicator during submission. Even once the disabled state works, a greyed-out button is a subtle cue with no spinner; on a slow request users may perceive it as unresponsive. MUI v7 `` gives spinner + disable + `aria-busy` in one.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
[Dismissed by author: Minor UX, not necessary] [Suggestion] No `aria-busy` / live-region signal during submission, so screen-reader users get no announcement that a submit is in progress. Resolved for free by the MUI `loading` prop.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
[Dismissed by author: Will be implemented later] [Suggestion] `variant="contained"` is hardcoded and no `ButtonProps` (color, `type`, `sx`, `data-testid`) are forwarded, limiting reuse for a `Shared/` component. Consider spreading `...rest` of `ButtonProps` with `variant` defaulting to `contained`.
|
||
| {children} | ||
| </Button> | ||
| ); | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.