From 67062208ccb9136e14fad09f44292b1e80568b0b Mon Sep 17 00:00:00 2001 From: omrsamer Date: Mon, 20 Jul 2026 11:38:38 +0100 Subject: [PATCH] fix(palette): trim search query before matching (flaky Property 41) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The palette filter checked query.trim() for emptiness but matched with the UNTRIMMED query, so 'a ' excluded items containing 'a' — trailing whitespace changed search results. The fast-check exclusion property caught this intermittently (counterexample 'A '; property tests are seed-random, which is why CI was green on some runs and red on others — including the main run after the xyflow merge). Trim before matching in both ComponentPalette and the extracted test copy; 253 frontend tests pass, palette property suite verified across 5 randomized runs. Co-Authored-By: Claude Opus 4.8 --- frontend/src/components/palette/ComponentPalette.tsx | 7 +++++-- frontend/src/utils/paletteSearch.test.ts | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/palette/ComponentPalette.tsx b/frontend/src/components/palette/ComponentPalette.tsx index a2bca62..54bb445 100644 --- a/frontend/src/components/palette/ComponentPalette.tsx +++ b/frontend/src/components/palette/ComponentPalette.tsx @@ -349,11 +349,14 @@ export function ComponentPalette({ new Set(['compute', 'integration', 'security', 'tools', 'connectors']) ); - // Filter items based on search query + // Filter items based on search query. Trim BEFORE matching — an untrimmed + // query like "a " excludes items that contain "a" but not "a " (trailing + // whitespace should never change search results); Property 41 checks the + // trimmed semantics. const filteredItems = useMemo(() => { if (!searchQuery.trim()) return PALETTE_ITEMS; - const query = searchQuery.toLowerCase(); + const query = searchQuery.trim().toLowerCase(); return PALETTE_ITEMS.filter( (item) => item.label.toLowerCase().includes(query) || diff --git a/frontend/src/utils/paletteSearch.test.ts b/frontend/src/utils/paletteSearch.test.ts index ca1a3f1..da53b76 100644 --- a/frontend/src/utils/paletteSearch.test.ts +++ b/frontend/src/utils/paletteSearch.test.ts @@ -20,7 +20,11 @@ import { PALETTE_ITEMS, type PaletteItem } from '../components/palette/Component export function filterPaletteItems(items: PaletteItem[], query: string): PaletteItem[] { if (!query.trim()) return items; - const normalizedQuery = query.toLowerCase(); + // Trim BEFORE matching (mirrors ComponentPalette): a query like "a " must + // match the same items as "a" — trailing whitespace never changes results. + // Without the trim, the exclusion property fails on counterexamples like + // "A " (item contains "a" but not "a "). + const normalizedQuery = query.trim().toLowerCase(); return items.filter( (item) => item.label.toLowerCase().includes(normalizedQuery) ||