From 0385e155444d36203a6ef431f635223d78490d34 Mon Sep 17 00:00:00 2001 From: isfttr Date: Sun, 19 Jul 2026 09:59:15 -0700 Subject: [PATCH] =?UTF-8?q?test(desktop):=20contract=20test=20=E2=80=94=20?= =?UTF-8?q?every=20cron=20helper=20is=20profile-scoped?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Salvaged from #59888 by @isfttr: the profileScoped() fix itself landed via #67493 (salvaged from the earlier #49948), but this PR contributed a contract test locking all 9 cron helpers to the active gateway profile — omitted when none is set (single-profile users unaffected), attached when one is active. Keeps the multi-profile/remote cron routing from silently regressing. --- apps/desktop/src/hermes-cron-scope.test.ts | 59 +++++++++++++++++++ .../emails/lucas.fernandes.df@gmail.com | 1 + 2 files changed, 60 insertions(+) create mode 100644 apps/desktop/src/hermes-cron-scope.test.ts create mode 100644 contributors/emails/lucas.fernandes.df@gmail.com diff --git a/apps/desktop/src/hermes-cron-scope.test.ts b/apps/desktop/src/hermes-cron-scope.test.ts new file mode 100644 index 000000000000..a9d13256f751 --- /dev/null +++ b/apps/desktop/src/hermes-cron-scope.test.ts @@ -0,0 +1,59 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + +import { + createCronJob, + deleteCronJob, + getCronJob, + getCronJobRuns, + getCronJobs, + pauseCronJob, + resumeCronJob, + setApiRequestProfile, + triggerCronJob, + updateCronJob +} from './hermes' + +// Contract: every cron helper must carry the active gateway profile, so a +// multi-profile / remote user's cron list, runs, and mutations hit the backend +// they're actually on — not the primary/default. Without it, selecting a remote +// profile still showed the local primary's jobs (the "remote cron jobs don't +// show up" bug), the counterpart to the backend-action-helper fix in +// hermes-profile-scope.test.ts. +describe('cron helpers are profile-scoped', () => { + const api = vi.fn(async (_req: { path: string; profile?: string }) => ({}) as never) + + beforeEach(() => { + ;(window as { hermesDesktop?: unknown }).hermesDesktop = { api } + api.mockClear() + }) + + afterEach(() => { + setApiRequestProfile(null) + delete (window as { hermesDesktop?: unknown }).hermesDesktop + }) + + const lastProfile = () => api.mock.calls.at(-1)?.[0].profile + + it('omits profile when none is active (single-profile users unaffected)', () => { + void getCronJobs() + expect(lastProfile()).toBeUndefined() + }) + + it('forwards the active profile to every cron helper', () => { + setApiRequestProfile('coder') + + void getCronJobs() + void getCronJob('job-1') + void getCronJobRuns('job-1') + void createCronJob({ name: 'nightly', prompt: 'run', schedule: '0 3 * * *' } as never) + void updateCronJob('job-1', { enabled: false } as never) + void pauseCronJob('job-1') + void resumeCronJob('job-1') + void triggerCronJob('job-1') + void deleteCronJob('job-1') + + for (const call of api.mock.calls) { + expect(call[0].profile).toBe('coder') + } + }) +}) diff --git a/contributors/emails/lucas.fernandes.df@gmail.com b/contributors/emails/lucas.fernandes.df@gmail.com new file mode 100644 index 000000000000..516ed2c38c69 --- /dev/null +++ b/contributors/emails/lucas.fernandes.df@gmail.com @@ -0,0 +1 @@ +isfttr