From e175ee3a4db10872c28dd5db83a6013912d72eb6 Mon Sep 17 00:00:00 2001 From: kshitijk4poor <82637225+kshitijk4poor@users.noreply.github.com> Date: Tue, 22 Sep 2026 16:52:44 +0530 Subject: [PATCH] test(desktop): trim kanban scope tests to their invariants Store test header points at the store/connections.ts comment instead of restating it; drop the two assertions implied by the final-tag check; drawer test invalidates via taskKey() instead of a raw prefix literal. Revert the comment-style churn on the unrelated $activeConnectionProfile subscription. --- apps/desktop/src/plugins/kanban/drawer.test.tsx | 4 ++-- apps/desktop/src/store/connections.ts | 7 +++---- .../src/store/kanban-connection-scope.test.ts | 16 ++-------------- 3 files changed, 7 insertions(+), 20 deletions(-) diff --git a/apps/desktop/src/plugins/kanban/drawer.test.tsx b/apps/desktop/src/plugins/kanban/drawer.test.tsx index bb7d5d5aa5..d834d262d2 100644 --- a/apps/desktop/src/plugins/kanban/drawer.test.tsx +++ b/apps/desktop/src/plugins/kanban/drawer.test.tsx @@ -7,7 +7,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' // eslint-disable-next-line no-restricted-imports import { registerPluginLocales } from '@/i18n/plugin-i18n' -import { bindApi } from './api' +import { bindApi, taskKey } from './api' import { TaskDrawer } from './drawer' import { en, KANBAN_LOCALES } from './i18n' import type { KanbanTaskDetail } from './types' @@ -94,7 +94,7 @@ describe('task attachment compatibility', () => { // A later backend response restores the capability without remounting. detail = { ...legacyDetail, attachments: [] } - await act(() => client.invalidateQueries({ queryKey: ['kanban', 'task'] })) + await act(() => client.invalidateQueries({ queryKey: taskKey('local', '', legacyDetail.task.id) })) expect(await screen.findByRole('button', { name: en.uploadAttachment })).toBeTruthy() expect(screen.getByText(en.noAttachments)).toBeTruthy() } diff --git a/apps/desktop/src/store/connections.ts b/apps/desktop/src/store/connections.ts index 455844d301..0a0809127a 100644 --- a/apps/desktop/src/store/connections.ts +++ b/apps/desktop/src/store/connections.ts @@ -85,10 +85,9 @@ const $activeConnectionProfile = computed( // fire, and the computed dedupes equal ids, so this only runs on a real switch. $activeConnectionId.listen(() => invalidateProfileScopedQueries()) -/** Remember one profile per source, so switching machines is a re-home rather - * than a reset to `default`. The map is local UI preference only; Electron - * remains the authority for the connection registry and all secrets. - */ +// Remember one profile per source, so switching machines is a re-home rather +// than a reset to `default`. The map is local UI preference only; Electron +// remains the authority for the connection registry and all secrets. $activeConnectionProfile.subscribe(({ connectionId, descriptorProfile, profile, registryScoped }) => { // A migrated v1 per-profile remote may expose a client-side alias such as // "work" while the registered source's actual profile is "default". Only diff --git a/apps/desktop/src/store/kanban-connection-scope.test.ts b/apps/desktop/src/store/kanban-connection-scope.test.ts index f7871cc8be..83015cedd8 100644 --- a/apps/desktop/src/store/kanban-connection-scope.test.ts +++ b/apps/desktop/src/store/kanban-connection-scope.test.ts @@ -4,16 +4,8 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import type { HermesConnection } from '@/global' // A connection switch must leave every profile-scoped query refetched against -// the NEW gateway. The switch commit point (beginGatewaySwitch → -// wipeSessionListsForGatewaySwitch → invalidateProfileScopedQueries) runs -// inside beforeActivate — BEFORE the activation publishes the new request -// scope (applyActive → setApiRequestConnection) — so that invalidation's -// refetches ride the OUTGOING backend. When the connection id later moves and -// the profile atom is unchanged, nothing re-invalidates: a kanban pane (or -// any connection-scoped query) keeps painting the previous gateway's data. -// store/connections closes the hole with the CONNECTION twin of profile.ts's -// $activeGatewayProfile subscription: invalidate on the actual connection-id -// change, so the refetch lands on the backend the tags now name. +// the NEW gateway — see the $activeConnectionId.listen comment in +// store/connections.ts for why the switch's own wipe is not enough. // // Real store chain (store/gateway + store/profile + store/connections), only // the HermesGateway socket class stubbed — same harness as @@ -69,7 +61,6 @@ const registry = { describe('connection-switch query invalidation', () => { let tagsAtFetch: Array - let observer: QueryObserver | undefined beforeEach(() => { @@ -142,9 +133,6 @@ describe('connection-switch query invalidation', () => { // spark-tagged. await vi.waitFor(() => expect(tagsAtFetch.at(-1)).toBe('spark'), { timeout: 2_000 }) - expect(getApiRequestConnection()).toBe('spark') - expect(tagsAtFetch).toContain('spark') - unsubscribe() })