From 1e486dbf2cca7a72631b948673f97ccb63497431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjam=C3=ADn=20Vicente?= Date: Sun, 8 Jun 2025 22:26:50 -0400 Subject: [PATCH 1/3] test(custom-functions): add working test with type error --- .../server/customFunctions.test.ts | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/packages/convex-helpers/server/customFunctions.test.ts b/packages/convex-helpers/server/customFunctions.test.ts index 7a5e615e..8b2358c3 100644 --- a/packages/convex-helpers/server/customFunctions.test.ts +++ b/packages/convex-helpers/server/customFunctions.test.ts @@ -358,6 +358,18 @@ export const outerRemoves = outerRemover({ return { ctxInner: ctx["inner"], ctxOuter: ctx["outer"], ...args }; }, }); +export const outerExtender = customQuery(inner, { + args: { outer: v.string() }, + input: async (ctx, args) => { + return { ctx: { outer: [args.outer, ctx.inner] }, args: {} }; + }, +}); +export const outerExtends = outerExtender({ + args: { a: v.string() }, + handler: async (ctx, args) => { + return { outer: ctx.outer, ...args }; + }, +}); /** * Test helpers @@ -388,6 +400,7 @@ const testApi: ApiFromModules<{ create: typeof create; outerAdds: typeof outerAdds; outerRemoves: typeof outerRemoves; + outerExtends: typeof outerExtends; }; }>["fns"] = anyApi["customFunctions.test"] as any; @@ -562,6 +575,16 @@ describe("nested custom functions", () => { }); }); + test("extends prev ctx", async () => { + const t = convexTest(schema, modules); + expect( + await t.query(testApi.outerExtends, { a: "hi", outer: "extended" }), + ).toMatchObject({ + outer: ["extended", "inner"], + a: "hi", + }); + }); + test("still validates args", async () => { const t = convexTest(schema, modules); await expect(() => From 70bfa20ff3c16561d393c73dfce7c9a5e596c490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjam=C3=ADn=20Vicente?= Date: Sun, 8 Jun 2025 22:37:37 -0400 Subject: [PATCH 2/3] test(custom-functions): add inner to output --- packages/convex-helpers/server/customFunctions.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/convex-helpers/server/customFunctions.test.ts b/packages/convex-helpers/server/customFunctions.test.ts index 8b2358c3..053806f9 100644 --- a/packages/convex-helpers/server/customFunctions.test.ts +++ b/packages/convex-helpers/server/customFunctions.test.ts @@ -367,7 +367,7 @@ export const outerExtender = customQuery(inner, { export const outerExtends = outerExtender({ args: { a: v.string() }, handler: async (ctx, args) => { - return { outer: ctx.outer, ...args }; + return { outer: ctx.outer, inner: ctx.inner, ...args }; }, }); @@ -580,6 +580,7 @@ describe("nested custom functions", () => { expect( await t.query(testApi.outerExtends, { a: "hi", outer: "extended" }), ).toMatchObject({ + inner: "inner", outer: ["extended", "inner"], a: "hi", }); From d47d6a2e77e4464c7184416c7dc37fe18d52f2cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjam=C3=ADn=20Vicente?= Date: Sun, 8 Jun 2025 22:50:10 -0400 Subject: [PATCH 3/3] test(custom-functions): add type error on removal --- .../server/customFunctions.test.ts | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/packages/convex-helpers/server/customFunctions.test.ts b/packages/convex-helpers/server/customFunctions.test.ts index 053806f9..8b2af8f9 100644 --- a/packages/convex-helpers/server/customFunctions.test.ts +++ b/packages/convex-helpers/server/customFunctions.test.ts @@ -358,6 +358,7 @@ export const outerRemoves = outerRemover({ return { ctxInner: ctx["inner"], ctxOuter: ctx["outer"], ...args }; }, }); +// Extend the previous ctx with new args export const outerExtender = customQuery(inner, { args: { outer: v.string() }, input: async (ctx, args) => { @@ -370,6 +371,21 @@ export const outerExtends = outerExtender({ return { outer: ctx.outer, inner: ctx.inner, ...args }; }, }); +// Deleted ctx is correctly undefined on nested functions +export const dbRemover = customQuery( + query, + customCtx(() => ({ db: undefined })), +); +export const outerDBRemover = customQuery( + dbRemover, + customCtx(() => ({ outer: "outer" })), +); +export const outerRemovesDB = outerDBRemover({ + args: {}, + handler: async (ctx, args) => { + return { db: ctx?.db ? "present" : "missing", outer: ctx.outer, ...args }; + }, +}); /** * Test helpers @@ -401,6 +417,7 @@ const testApi: ApiFromModules<{ outerAdds: typeof outerAdds; outerRemoves: typeof outerRemoves; outerExtends: typeof outerExtends; + outerRemovesDB: typeof outerRemovesDB; }; }>["fns"] = anyApi["customFunctions.test"] as any; @@ -575,6 +592,13 @@ describe("nested custom functions", () => { }); }); + test("still validates args", async () => { + const t = convexTest(schema, modules); + await expect(() => + t.query(testApi.outerAdds, { a: 3 as any, outer: "" }), + ).rejects.toThrow("Validator error: Expected `string`"); + }); + test("extends prev ctx", async () => { const t = convexTest(schema, modules); expect( @@ -586,10 +610,11 @@ describe("nested custom functions", () => { }); }); - test("still validates args", async () => { + test("keeps deleted ctx", async () => { const t = convexTest(schema, modules); - await expect(() => - t.query(testApi.outerAdds, { a: 3 as any, outer: "" }), - ).rejects.toThrow("Validator error: Expected `string`"); + expect(await t.query(testApi.outerRemovesDB, {})).toMatchObject({ + db: "missing", + outer: "outer", + }); }); });