fix(frontend): sprint 3 post-review — real dedup test + Apply 0 guard + Link stopPropagation

- MitreTechniquesField test: rewrite dedup test to actually exercise picker
  selection path — types query, waits for option, fires pointerDown,
  asserts no PATCH sent (dedup guard in handleSelect now truly covered)
- MitreMatrixModal: Apply button disabled only when totalSelected === 0
  AND initialSelection.length === 0 (no-op case); when totalSelected === 0
  but initialSelection was non-empty, shows "Clear all" and stays enabled
  so user can explicitly wipe the list
- MitreMatrixModal tests: update disabled test to match "Clear all" label,
  add "Clear all" enabled + onApply([]) path test
- SimulationList: stopPropagation on Name <Link> to prevent double-navigate
  with row onClick handler

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Knacky
2026-05-27 04:22:23 +02:00
parent 771483f3b0
commit 39f4076a81
4 changed files with 57 additions and 6 deletions

View File

@@ -333,9 +333,11 @@ export function MitreMatrixModal({
type="button"
className="btn-primary"
onClick={handleApply}
disabled={isLoading || isError}
disabled={isLoading || isError || (totalSelected === 0 && initialSelection.length === 0)}
>
Apply {totalSelected > 0 ? `${totalSelected} technique${totalSelected !== 1 ? 's' : ''}` : ''}
{totalSelected === 0
? 'Clear all'
: `Apply ${totalSelected} technique${totalSelected !== 1 ? 's' : ''}`}
</button>
</div>
</div>

View File

@@ -90,6 +90,7 @@ export function SimulationList({ engagementId }: SimulationListProps): JSX.Eleme
<Link
to={`/engagements/${engagementId}/simulations/${sim.id}/edit`}
className="text-ink font-medium hover:underline"
onClick={(e) => e.stopPropagation()}
>
{sim.name}
</Link>