Skip to content

Commit

Permalink
🐛 Handle confirm deletes with multiple spaces (#1572)
Browse files Browse the repository at this point in the history
Resolves: https://issues.redhat.com/browse/MTA-1725

When confirming the deletion of an entity by requiring the user to enter
the name of the entity, the string check needs to ignore differences in
white space.

The entity name may contain multiple spaces between words, but not show
the spaces when viewing the name outside of an input box. HTML normally
collapses multiple spaces into a single space. Also if the confirming
name gets an extra space typed, that can cause a hard to see string
mismatch. Trimming and then collapsing multiple spaces into a single
space before comparing the string avoids this problem.

Signed-off-by: Scott J Dickerson <[email protected]>
  • Loading branch information
sjd78 authored Nov 27, 2023
1 parent c7c6d7c commit ae8c567
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
Text,
TextInput,
} from "@patternfly/react-core";
import { collapseSpacesAndCompare } from "@app/utils/utils";

import "./ConfirmDeleteDialog.css";

Expand Down Expand Up @@ -39,7 +40,12 @@ const ConfirmDeleteDialog: FC<ConfirmDeleteDialogProps> = ({

const [nameToDeleteInput, setNameToDeleteInput] = useState<string>("");

const isDisabled = nameToDeleteInput !== nameToDelete;
/*
Enable the delete button once the input name matches the `nameToDelete`, BUT
collapse spaces since that is the way the name is rendered
*/
const isDisabled =
collapseSpacesAndCompare(nameToDeleteInput, nameToDelete) !== 0;

const handleClose = () => {
setNameToDeleteInput("");
Expand Down
34 changes: 34 additions & 0 deletions client/src/app/utils/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
standardURLRegex,
formatPath,
extractFirstSha,
collapseSpacesAndCompare,
} from "./utils";
import { Paths } from "@app/Paths";

Expand Down Expand Up @@ -219,3 +220,36 @@ describe("SHA extraction", () => {
expect(first).toBe("9c04cd6372077e9b11f70ca111c9807dc7137e4b");
});
});

describe("space collapse string compare (using en-US compares)", () => {
it("both undefined matches", () => {
const result = collapseSpacesAndCompare(undefined, undefined, "en-US");
expect(result).toBe(0);
});

it("left undefined goes before right defined", () => {
const result = collapseSpacesAndCompare(undefined, "anything", "en-US");
expect(result).toBe(-1);
});

it("left defined goes after right undefined", () => {
const result = collapseSpacesAndCompare("anything", undefined, "en-US");
expect(result).toBe(1);
});

it.each([
["alpha", "alpha", 0],
["alpha", "bravo", -1],
["bravo", "alpha", 1],
[" alpha", "alpha ", 0],
["alpha bravo", "alpha bravo", 0],
["bravo alpha", "bravo bravo", -1],
["The quick brown fox ", "The quick brown fox", 0],
])(
"mismatching spaces work as if spaces are collapsed (%s) to (%s) = %i",
(a, b, expected) => {
const result = collapseSpacesAndCompare(a, b, "en-US");
expect(result).toBe(expected);
}
);
});
21 changes: 21 additions & 0 deletions client/src/app/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,24 @@ export const extractFirstSha = (str: string): string | undefined => {
const match = str.match(SHA_REGEX);
return match && match[0] ? match[0] : undefined;
};

export const collapseSpacesAndCompare = (
str1: string | undefined,
str2: string | undefined,
locale?: string
): number => {
if (!str1 && !str2) {
return 0;
}
if (str1 && !str2) {
return 1;
}
if (!str1 && str2) {
return -1;
}

const a = str1?.trim().replace(/\s+/g, " ") ?? "";
const b = str2?.trim().replace(/\s+/g, " ") ?? "";

return a.localeCompare(b, locale);
};

0 comments on commit ae8c567

Please sign in to comment.