test(desktop): supply the thread edit guard to the activity exclusivity harness

**Category:** test

`#6575` made `requireThreadEditResolution` a required dependency of
`useChannelAgentSessions`, which this branch's exclusivity harness predates —
so after the rebase all five cases threw `requireThreadEditResolution is not
a function` rather than exercising last-opened-wins. Production wiring was
never affected; `ChannelScreen` supplies it from `useChannelPaneHandlers`.

Rather than stub it silently, the harness takes it as an injectable so the
guard's interaction with the replacement is itself covered: a refused open
must leave the thread and its draft exactly as they were, with no
half-applied replacement that cleared the thread before the guard turned the
activity open away. Verified to fail with the guard's early return removed.

Signed-off-by: ss-dev-00 <a02c4e0850e5e612b4ddf95dbe2f5c56467cf27c6552203bc833ff438fb31971@buzz.block.builderlab.xyz>
Co-authored-by: Bradley Axen <baxen@squareup.com>
Signed-off-by: Bradley Axen <baxen@squareup.com>
This commit is contained in:
ss-dev-00
2026-08-24 14:26:25 -07:00
committed by Rizz
parent 32c9eaf248
commit 5aae5c5bfd

View File

@@ -36,7 +36,10 @@ const OTHER_THREAD_HEAD_ID = "thread-head-2";
* Last-opened-wins is a property of these two handlers clearing each other's
* state, so the assertions are on the state writes, not on a rendered surface.
*/
async function renderAgentSessionHandlers({ openThreadHeadId = null } = {}) {
async function renderAgentSessionHandlers({
openThreadHeadId = null,
requireThreadEditResolution = () => true,
} = {}) {
const React = await import("react");
const { act, renderHook } = await import("@testing-library/react");
const { useChannelAgentSessions } = await import(
@@ -82,6 +85,7 @@ async function renderAgentSessionHandlers({ openThreadHeadId = null } = {}) {
openAgentSessionPubkey: state.openAgentSessionPubkey,
openThreadHeadId: state.openThreadHeadId,
profilePanelPubkey: state.profilePanelPubkey,
requireThreadEditResolution,
setChannelManagementOpen: (open) => write("channelManagementOpen", open),
setExpandedThreadReplyIds: () => {},
setOpenAgentSessionChannelId: (value) =>
@@ -175,3 +179,19 @@ test("back never resurrects a thread from an earlier replacement", async () => {
assert.equal(state.openThreadHeadId, OTHER_THREAD_HEAD_ID);
});
test("an unresolved thread edit blocks the replacement entirely", async () => {
// Last-opened-wins runs *after* the thread edit guard `#6575` added, so a
// refused open must leave both surfaces exactly as they were — the thread
// still on screen with its draft, and no half-applied replacement that
// cleared the thread before the guard turned the activity open away.
const { run, state } = await renderAgentSessionHandlers({
openThreadHeadId: THREAD_HEAD_ID,
requireThreadEditResolution: () => false,
});
await run((handlers) => handlers.openAgentSession(AGENT_PUBKEY, "channel-1"));
assert.equal(state.openAgentSessionPubkey, null);
assert.equal(state.openThreadHeadId, THREAD_HEAD_ID);
});