From 82d5f7cf168144b4877d78794a37bc18674018fa Mon Sep 17 00:00:00 2001 From: Dotta Date: Wed, 4 Nov 2026 16:55:43 -0600 Subject: [PATCH] fix(evals): require authored skill company prefix Co-Authored-By: Paperclip --- .../integrator-skill-authoring-v2.test.ts | 6 ++++++ tests/runner-e2e/chat-catalog-domains/integrator-skills.ts | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/runner-e2e/chat-catalog-domains/integrator-skill-authoring-v2.test.ts b/tests/runner-e2e/chat-catalog-domains/integrator-skill-authoring-v2.test.ts index 414d57ab50b..7140270093c 100644 --- a/tests/runner-e2e/chat-catalog-domains/integrator-skill-authoring-v2.test.ts +++ b/tests/runner-e2e/chat-catalog-domains/integrator-skill-authoring-v2.test.ts @@ -83,3 +83,9 @@ it("inspects real rich-text blocks without applying Markdown marker assumptions }); it("retains exact direct Studio card navigation when the UI uses it", async()=>{ const f=fixture();f.ui.directStudio=true;await inspectAuthoredSkill(f.ctx,f.state,f.o);expect(f.events).toEqual(["Skills","My Skills","open-skill","reload","return-chat"]);expect(f.state.authoredSkillInspection).toMatchObject({readbackMatched:true,editorSurface:"studio"}); }); + +it.each([undefined, null, ""])("rejects missing company prefix %s before any UI navigation", async prefix => { + const f=fixture();Object.assign(f.ctx.input.fixtures.company,{issuePrefix:prefix}); + await expect(inspectAuthoredSkill(f.ctx,f.state,f.o)).rejects.toThrow("company prefix"); + expect(f.events).toEqual([]);expect(f.state.authoredSkillInspection).toBeUndefined(); +}); diff --git a/tests/runner-e2e/chat-catalog-domains/integrator-skills.ts b/tests/runner-e2e/chat-catalog-domains/integrator-skills.ts index 05af772d071..a12d5c09f96 100644 --- a/tests/runner-e2e/chat-catalog-domains/integrator-skills.ts +++ b/tests/runner-e2e/chat-catalog-domains/integrator-skills.ts @@ -102,6 +102,8 @@ interface AuthoredSkillInspection { companyId: string; skillId: string; versionI export async function inspectAuthoredSkill(ctx: ChatCatalogContext, state: Record, o: InternalObservation): Promise { const remaining = () => remainingIdentityObservationBudget(ctx); remaining(); + const prefix = ctx.input.fixtures.company.issuePrefix; + if (typeof prefix !== "string" || !prefix.trim()) throw new Error("Authored skill inspection requires its actual company prefix"); const observed = skillsObservation(o); const authored = observed?.skills.filter(skill => observed.activity.some(event => event.action === "company.skill_created" && event.entityId === skill.id && event.agentId === observed.leadId)) ?? []; const skill = authored[0], version = skill && observed?.versions[skill.id]?.find(row => row.id === skill.currentVersionId); @@ -112,7 +114,7 @@ export async function inspectAuthoredSkill(ctx: ChatCatalogContext, state: Recor await ctx.input.page.getByRole("link", { name: "My Skills", exact: true }).first().click({ timeout: remaining() }); const card = ctx.input.page.getByRole("button").filter({ has: ctx.input.page.getByText(skill.name, { exact: true }) }).first(); await expect(card).toBeVisible({ timeout: remaining() }); await card.click({ timeout: remaining() }); - const companyPath = `/${encodeURIComponent(ctx.input.fixtures.company.issuePrefix)}`; + const companyPath = `/${encodeURIComponent(prefix)}`; const studioRoute = `${companyPath}${skillStudioRoute(skill.id)}`; const detailRoute = `${companyPath}${skillRoute(skill, observed.skills)}`; const openSavedEditor = async () => {