
























@@ -126,6 +126,26 @@ function sha256(bytes: Buffer): string {
126126return createHash("sha256").update(bytes).digest("hex");
127127}
128128129+async function expectPathMissing(targetPath: string): Promise<void> {
130+try {
131+await fs.stat(targetPath);
132+throw new Error(`Expected path to be missing: ${targetPath}`);
133+} catch (error) {
134+expect((error as NodeJS.ErrnoException).code).toBe("ENOENT");
135+}
136+}
137+138+function expectError(result: CallResult, code: string, message: string): void {
139+expect(result.error?.code).toBe(code);
140+expect(result.error?.message).toBe(message);
141+}
142+143+function firstCallArg<T>(mock: { mock: { calls: unknown[][] } }): T {
144+const call = mock.mock.calls[0];
145+expect(call).toBeDefined();
146+return call?.[0] as T;
147+}
148+129149async function makeSkillArchive(params: {
130150name?: string;
131151description?: string;
@@ -227,9 +247,7 @@ describe("skill upload gateway handlers", () => {
227247expect(begin.ok).toBe(false);
228248expect(begin.error?.code).toBe("UNAVAILABLE");
229249expect(begin.error?.message).toContain("skills.install.allowUploadedArchives");
230-await expect(fs.stat(path.join(stateDir, "tmp", "skill-uploads"))).rejects.toMatchObject({
231-code: "ENOENT",
232-});
250+await expectPathMissing(path.join(stateDir, "tmp", "skill-uploads"));
233251234252const install = await call(
235253handlers,
@@ -265,20 +283,14 @@ describe("skill upload gateway handlers", () => {
265283});
266284267285expect(install.ok).toBe(true);
268-expect(install.payload).toMatchObject({
269-ok: true,
270-slug: "uploaded-demo",
271-sha256: digest,
272-});
286+expect((install.payload as { ok?: unknown }).ok).toBe(true);
287+expect((install.payload as { slug?: unknown }).slug).toBe("uploaded-demo");
288+expect((install.payload as { sha256?: unknown }).sha256).toBe(digest);
273289await expect(
274290fs.readFile(path.join(workspaceDir, "skills", "uploaded-demo", "SKILL.md"), "utf8"),
275291).resolves.toContain("Uploaded Demo");
276-await expect(
277-fs.stat(path.join(workspaceDir, "skills", "archive-internal-name")),
278-).rejects.toMatchObject({ code: "ENOENT" });
279-await expect(
280-fs.stat(path.join(stateDir, "tmp", "skill-uploads", uploadId)),
281-).rejects.toMatchObject({ code: "ENOENT" });
292+await expectPathMissing(path.join(workspaceDir, "skills", "archive-internal-name"));
293+await expectPathMissing(path.join(stateDir, "tmp", "skill-uploads", uploadId));
282294283295const status = await call(handlers, "skills.status", {});
284296expect(status.ok).toBe(true);
@@ -357,13 +369,8 @@ describe("skill upload gateway handlers", () => {
357369});
358370359371expect(install.ok).toBe(false);
360-expect(install.error).toMatchObject({
361-code: "INVALID_REQUEST",
362-message: "install sha256 does not match uploaded archive",
363-});
364-await expect(
365-fs.stat(path.join(stateDir, "tmp", "skill-uploads", upload.uploadId)),
366-).rejects.toMatchObject({ code: "ENOENT" });
372+expectError(install, "INVALID_REQUEST", "install sha256 does not match uploaded archive");
373+await expectPathMissing(path.join(stateDir, "tmp", "skill-uploads", upload.uploadId));
367374});
368375369376it("rejects expired committed uploads through skills.install", async () => {
@@ -390,13 +397,8 @@ describe("skill upload gateway handlers", () => {
390397});
391398392399expect(install.ok).toBe(false);
393-expect(install.error).toMatchObject({
394-code: "INVALID_REQUEST",
395-message: "upload has expired",
396-});
397-await expect(
398-fs.stat(path.join(stateDir, "tmp", "skill-uploads", upload.uploadId)),
399-).rejects.toMatchObject({ code: "ENOENT" });
400+expectError(install, "INVALID_REQUEST", "upload has expired");
401+await expectPathMissing(path.join(stateDir, "tmp", "skill-uploads", upload.uploadId));
400402});
401403402404it("rejects invalid slugs, missing SKILL.md, and archive traversal", async () => {
@@ -421,9 +423,7 @@ describe("skill upload gateway handlers", () => {
421423expect(missingInstall.ok).toBe(false);
422424expect(missingInstall.error?.code).toBe("INVALID_REQUEST");
423425expect(missingInstall.error?.message).toContain("SKILL.md");
424-await expect(
425-fs.stat(path.join(stateDir, "tmp", "skill-uploads", missingSkill.uploadId)),
426-).rejects.toMatchObject({ code: "ENOENT" });
426+await expectPathMissing(path.join(stateDir, "tmp", "skill-uploads", missingSkill.uploadId));
427427428428const legacyMarker = await uploadArchive(handlers, {
429429archive: await makeSkillArchive({
@@ -440,9 +440,7 @@ describe("skill upload gateway handlers", () => {
440440expect(legacyMarkerInstall.ok).toBe(false);
441441expect(legacyMarkerInstall.error?.code).toBe("INVALID_REQUEST");
442442expect(legacyMarkerInstall.error?.message).toContain("SKILL.md");
443-await expect(
444-fs.stat(path.join(stateDir, "tmp", "skill-uploads", legacyMarker.uploadId)),
445-).rejects.toMatchObject({ code: "ENOENT" });
443+await expectPathMissing(path.join(stateDir, "tmp", "skill-uploads", legacyMarker.uploadId));
446444447445const traversal = await uploadArchive(handlers, {
448446archive: await makeSkillArchive({ traversal: true }),
@@ -458,9 +456,7 @@ describe("skill upload gateway handlers", () => {
458456expect(traversalInstall.error?.message).toMatch(
459457/escapes destination|absolute|extract archive/i,
460458);
461-await expect(
462-fs.stat(path.join(workspaceDir, "skills", "traversal-skill")),
463-).rejects.toMatchObject({ code: "ENOENT" });
459+await expectPathMissing(path.join(workspaceDir, "skills", "traversal-skill"));
464460});
465461466462it("treats security scan blocks as terminal invalid uploads", async () => {
@@ -484,19 +480,14 @@ describe("skill upload gateway handlers", () => {
484480});
485481486482expect(install.ok).toBe(false);
487-expect(install.error).toMatchObject({
488-code: "INVALID_REQUEST",
489-message: expect.stringContaining("blocked dependencies"),
490-});
491-expect(installSecurityScanState.scanSkillInstallSource).toHaveBeenCalledWith(
492-expect.objectContaining({
493-origin: "skill-upload",
494-skillName: "scan-blocked",
495-}),
483+expect(install.error?.code).toBe("INVALID_REQUEST");
484+expect(install.error?.message).toContain("blocked dependencies");
485+const scanInput = firstCallArg<{ origin?: string; skillName?: string }>(
486+installSecurityScanState.scanSkillInstallSource,
496487);
497-await expect(
498- fs.stat(path.join(stateDir, "tmp", "skill-uploads", upload.uploadId)),
499-).rejects.toMatchObject({ code: "ENOENT" });
488+expect(scanInput.origin).toBe("skill-upload");
489+expect(scanInput.skillName).toBe("scan-blocked");
490+await expectPathMissing(path.join(stateDir, "tmp", "skill-uploads", upload.uploadId));
500491});
501492502493it("preserves existing installs unless force was bound at begin", async () => {
@@ -533,9 +524,7 @@ describe("skill upload gateway handlers", () => {
533524expect(blockedInstall.ok).toBe(false);
534525expect(blockedInstall.error?.code).toBe("INVALID_REQUEST");
535526expect(blockedInstall.error?.message).toContain("already exists");
536-await expect(
537-fs.stat(path.join(stateDir, "tmp", "skill-uploads", blocked.uploadId)),
538-).rejects.toMatchObject({ code: "ENOENT" });
527+await expectPathMissing(path.join(stateDir, "tmp", "skill-uploads", blocked.uploadId));
539528540529const forced = await uploadArchive(handlers, {
541530archive: await makeSkillArchive({
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。