From 3151837a93ad10a054eecd6c507201990ffcdde9 Mon Sep 17 00:00:00 2001 From: Nico Pappagianis Date: Fri, 28 Aug 2026 14:03:06 -0700 Subject: [PATCH] test: reuse provisioned agent user in create NUT to fix flake The 'agent create' NUT generated a spec with no agentUser and ran 'agent create' against it, so agentSettings.userId was never set and core auto-created the licensed Bot User in the same transaction as the BotDefinition save. The pre-save validation trigger intermittently could not see the fresh license/permset assignment, failing with 'User doesn't have access to agent.' Shared setup already provisions an agent user via 'org create agent-user' and exposes it through getAgentUsername(), but it was only wired into publish, not create. Write that already-committed user into the spec's agentUser field so 'agent create' threads agentSettings.userId and core reuses it instead of racing on a new one. --- test/nuts/z0.agent.create.nut.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/test/nuts/z0.agent.create.nut.ts b/test/nuts/z0.agent.create.nut.ts index 9f50c892..9b0b3edf 100644 --- a/test/nuts/z0.agent.create.nut.ts +++ b/test/nuts/z0.agent.create.nut.ts @@ -15,13 +15,13 @@ */ import { join } from 'node:path'; -import { readdirSync, statSync } from 'node:fs'; +import { appendFileSync, readdirSync, statSync } from 'node:fs'; import { expect } from 'chai'; import { genUniqueString, TestSession } from '@salesforce/cli-plugins-testkit'; import { execCmd } from '@salesforce/cli-plugins-testkit'; import type { AgentCreateSpecResult } from '../../src/commands/agent/generate/agent-spec.js'; import type { AgentCreateResult } from '../../src/commands/agent/create.js'; -import { getTestSession, getUsername } from './shared-setup.js'; +import { getAgentUsername, getTestSession, getUsername } from './shared-setup.js'; /* eslint-disable no-console */ @@ -68,6 +68,18 @@ describe('agent create', function () { const expectedFilePath = join(session.project.dir, 'specs', specFileName); const name = 'Plugin Agent Test'; const apiName = 'Plugin_Agent_Test'; + + // Reuse the Bot User pre-provisioned in shared setup (via `org create agent-user`) instead of + // letting core auto-create one during the save. The 'customer' agentType maps to core's + // EinsteinServiceAgent, which requires a licensed Bot User; when no user is supplied, core creates + // that user in the SAME transaction as the BotDefinition save, and the pre-save validation trigger + // intermittently cannot see the just-created license/permset assignment, failing with "User + // doesn't have access to agent." `agent create` sets agentSettings.userId from the spec's + // `agentUser`, so writing the already-committed agent user into the spec removes that race. + const agentUser = getAgentUsername(); + expect(agentUser, 'agent user should have been provisioned in shared setup').to.be.a('string'); + appendFileSync(expectedFilePath, `\nagentUser: "${agentUser!}"\n`); + const command = `agent create --spec ${expectedFilePath} --target-org ${username} --name "${name}" --api-name ${apiName} --json`; const result = execCmd(command, { ensureExitCode: 0 }).jsonOutput?.result; expect(result).to.be.ok;