mirror of
https://github.com/block/buzz.git
synced 2026-10-29 21:41:33 +00:00
Disambiguate selected people by pubkey
Always expose the canonical pubkey for access-picker search results and include the full key in each Add action accessible name. Verify keyboard selection persists only the chosen identity. Co-authored-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
This commit is contained in:
@@ -70,10 +70,13 @@ function formatSearchUserName(user: UserSearchResult) {
|
||||
function formatSearchUserSecondary(user: UserSearchResult) {
|
||||
const displayName = user.displayName?.trim();
|
||||
const nip05Handle = user.nip05Handle?.trim();
|
||||
if (displayName && nip05Handle) {
|
||||
return nip05Handle;
|
||||
}
|
||||
return truncatePubkey(user.pubkey);
|
||||
return displayName && nip05Handle ? nip05Handle : null;
|
||||
}
|
||||
|
||||
function formatSearchUserAccessibleName(user: UserSearchResult) {
|
||||
const name = formatSearchUserName(user);
|
||||
const secondary = formatSearchUserSecondary(user);
|
||||
return `Add ${name}${secondary ? `, ${secondary}` : ""}, public key ${user.pubkey}`;
|
||||
}
|
||||
|
||||
const RESPOND_TO_OPTIONS: PersonaDropdownOption[] = [
|
||||
@@ -443,12 +446,10 @@ function AllowlistPicker({
|
||||
>
|
||||
{searchResults.length > 0 ? (
|
||||
searchResults.map((result) => (
|
||||
<button
|
||||
<div
|
||||
className="flex w-full items-center justify-between rounded-md px-2.5 py-1.5 text-left transition-colors hover:bg-accent hover:text-accent-foreground"
|
||||
data-testid={`agent-respond-to-result-${result.pubkey}`}
|
||||
key={result.pubkey}
|
||||
onClick={() => onAddSearchResult(result)}
|
||||
type="button"
|
||||
>
|
||||
<div className="flex items-center gap-2 min-w-0">
|
||||
<UserAvatar
|
||||
@@ -460,13 +461,27 @@ function AllowlistPicker({
|
||||
<p className="truncate text-sm font-medium leading-5">
|
||||
{formatSearchUserName(result)}
|
||||
</p>
|
||||
<p className="truncate text-xs text-muted-foreground">
|
||||
{formatSearchUserSecondary(result)}
|
||||
</p>
|
||||
{formatSearchUserSecondary(result) ? (
|
||||
<p className="truncate text-xs text-muted-foreground">
|
||||
{formatSearchUserSecondary(result)}
|
||||
</p>
|
||||
) : null}
|
||||
<PubKey
|
||||
className="text-xs text-muted-foreground"
|
||||
pubkey={result.pubkey}
|
||||
testId={`agent-respond-to-result-pubkey-${result.pubkey}`}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<span className="text-xs text-muted-foreground">Add</span>
|
||||
</button>
|
||||
<button
|
||||
aria-label={formatSearchUserAccessibleName(result)}
|
||||
className="text-xs text-muted-foreground"
|
||||
onClick={() => onAddSearchResult(result)}
|
||||
type="button"
|
||||
>
|
||||
Add
|
||||
</button>
|
||||
</div>
|
||||
))
|
||||
) : queryIsHexPubkey ? (
|
||||
<button
|
||||
|
||||
@@ -145,8 +145,16 @@ test("selected-people search keeps same-name people independently selectable", a
|
||||
},
|
||||
],
|
||||
searchProfiles: [
|
||||
{ pubkey: firstWillPubkey, displayName: "Will" },
|
||||
{ pubkey: secondWillPubkey, displayName: "Will" },
|
||||
{
|
||||
pubkey: firstWillPubkey,
|
||||
displayName: "Will",
|
||||
nip05Handle: "will@example.com",
|
||||
},
|
||||
{
|
||||
pubkey: secondWillPubkey,
|
||||
displayName: "Will",
|
||||
nip05Handle: "will@example.com",
|
||||
},
|
||||
],
|
||||
});
|
||||
await page.goto("/");
|
||||
@@ -162,18 +170,52 @@ test("selected-people search keeps same-name people independently selectable", a
|
||||
`agent-respond-to-result-${secondWillPubkey}`,
|
||||
);
|
||||
await expect(firstWill).toContainText("Will");
|
||||
await expect(firstWill).toContainText("will@example.com");
|
||||
await expect(firstWill).toContainText("11111111…1111");
|
||||
await expect(secondWill).toContainText("Will");
|
||||
await expect(secondWill).toContainText("will@example.com");
|
||||
await expect(secondWill).toContainText("22222222…2222");
|
||||
const firstAdd = firstWill.getByRole("button", {
|
||||
name: `Add Will, will@example.com, public key ${firstWillPubkey}`,
|
||||
});
|
||||
const secondAdd = secondWill.getByRole("button", {
|
||||
name: `Add Will, will@example.com, public key ${secondWillPubkey}`,
|
||||
});
|
||||
await expect(firstAdd).toBeVisible();
|
||||
await expect(secondAdd).toBeVisible();
|
||||
await page
|
||||
.getByTestId("agent-respond-to-allowlist")
|
||||
.screenshot({ path: `${SHOTS}/duplicate-will-selected-people.png` });
|
||||
|
||||
await secondWill.click();
|
||||
await secondAdd.focus();
|
||||
await secondAdd.press("Enter");
|
||||
await expect(
|
||||
page.getByTestId(`agent-respond-to-chip-${secondWillPubkey}`),
|
||||
).toBeVisible();
|
||||
await expect(firstWill).toHaveCount(0);
|
||||
await expect(
|
||||
page.getByTestId(`agent-respond-to-chip-${firstWillPubkey}`),
|
||||
).toHaveCount(0);
|
||||
await page.getByRole("button", { name: "Save access" }).click();
|
||||
const updateCommand = await page.evaluate(
|
||||
(agentPubkey) =>
|
||||
window.__BUZZ_E2E_COMMAND_LOG__?.findLast(
|
||||
(entry) =>
|
||||
entry.command === "update_managed_agent" &&
|
||||
(entry.payload as { input?: { pubkey?: string } })?.input?.pubkey ===
|
||||
agentPubkey,
|
||||
),
|
||||
agent.pubkey,
|
||||
);
|
||||
expect(updateCommand?.payload).toMatchObject({
|
||||
input: {
|
||||
pubkey: agent.pubkey,
|
||||
respondTo: "allowlist",
|
||||
respondToAllowlist: [secondWillPubkey],
|
||||
},
|
||||
});
|
||||
expect(updateCommand?.payload).not.toMatchObject({
|
||||
input: { respondToAllowlist: [firstWillPubkey] },
|
||||
});
|
||||
});
|
||||
|
||||
for (const selectedFirstPageCount of [50, 49]) {
|
||||
|
||||
Reference in New Issue
Block a user