Skip to content

Commit

Permalink
Added server-side tests for hooks, added back previously-commented-ou…
Browse files Browse the repository at this point in the history
…t tests, tested hooks with potential errors in functions
  • Loading branch information
doseofted committed Mar 4, 2024
1 parent 07205f1 commit 14ee571
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 26 deletions.
12 changes: 12 additions & 0 deletions libs/rpc/src/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,18 @@ describe("Prim Client can use its specific hooks", () => {
expect(result).not.toEqual(expectedNormally)
expect(result).toEqual(expected)
})
test("Post-call hooks with remote module, errored", async () => {
const { callbackPlugin, methodPlugin, callbackHandler, methodHandler } = createPrimTestingPlugins()
createPrimServer({ module, callbackHandler, methodHandler })
const prim = createPrimClient<IModule>({
callbackPlugin,
methodPlugin,
postRequest(_error) {
return "Intercepted!"
},
})
await expect(prim.oops()).rejects.toBe("Intercepted!")
})
})

describe("Prim Client can make use of callbacks", () => {
Expand Down
4 changes: 4 additions & 0 deletions libs/rpc/src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,8 @@ export interface PrimOptions<M extends PossibleModule = object, J extends JsonHa
preRequest?: (args: unknown[], name: string) => { args: unknown[]; result?: unknown } | undefined
/** Transform given result prior to being returned to the RPC caller */
postRequest?: (result: unknown, name: string) => unknown
/** Transform given error prior to being thrown */
// postRequestError?: (result: unknown, name: string) => unknown
// TODO: Prim Server should create these options and hold references. This will be removed.
/** Properties belonging to `internal` are for internal use by Prim-RPC. */
internal?: {
Expand Down Expand Up @@ -477,6 +479,8 @@ export interface PrimServerOptions<M extends PossibleModule = object, J extends
) => { args: unknown[]; result?: unknown } | undefined
/** After function call, transform return result before sending back to client */
postCall?: (result: unknown, func?: (...args: unknown[]) => unknown) => unknown
/** Transform given error before sending back to client */
// postCallError?: (error: unknown, func?: (...args: unknown[]) => unknown) => unknown
}

export type PrimServerSocketAnswer = (result: string) => void
Expand Down
94 changes: 68 additions & 26 deletions libs/rpc/src/server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,6 @@ async function handlePost(server: PrimServerActionsExtended, call: RpcCall): Pro
}

describe("Prim Server cannot call non-RPC", () => {
// function prepareCall (given: RpcCall) {
// const body = JSON.stringify(given)
// return { method: "POST", body }
// }
test("with exported object", async () => {
const prim = createPrimServer({ module, prefix: "/prim" })
const server = prim.server()
Expand Down Expand Up @@ -285,28 +281,74 @@ describe("Prim Server can handle invalid requests", () => {
const result = JSON.parse(response.body) as RpcAnswer
expect(result).toEqual({ error: "Invalid RPC" })
})
// TODO: "Invalid method name" may not be the correct error (this may be related to testing plugin, need to check)
// test("with wrong HTTP method and body/url given (GET)", async () => {
// const server = prim.server()
// const call: RpcCall = {
// method: "greetings",
// id: 1,
// }
// const body = JSON.stringify(call)
// const response = await server.call({ method: "GET", body })
// const result = JSON.parse(response.body) as RpcAnswer
// expect(result).toEqual({ error: "Invalid method name" })
// })
// test("with wrong HTTP method and body/url given (POST)", async () => {
// const server = prim.server()
// const url = queryString.stringifyUrl({
// url: "/greetings",
// query: { greeting: "Howdy", name: "Ted" },
// })
// const response = await server.call({ method: "POST", url })
// const result = JSON.parse(response.body) as RpcAnswer
// expect(result).toEqual({ error: "Invalid method name" })
// })
// TODO: "Invalid method name" may not be the most correct error (this may be related to testing plugin, need to check)
test("with wrong HTTP method and body/url given (GET)", async () => {
const server = prim.server()
const call: RpcCall = {
method: "greetings",
id: 1,
}
const body = JSON.stringify(call)
const response = await server.call({ method: "GET", body })
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
const result = JSON.parse(response.body) as RpcAnswer
expect(result).toEqual({ error: "Invalid method name" })
})
test("with wrong HTTP method and body/url given (POST)", async () => {
const server = prim.server()
const url = queryString.stringifyUrl({
url: "/greetings",
query: { greeting: "Howdy", name: "Ted" },
})
const response = await server.call({ method: "POST", url })
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
const result = JSON.parse(response.body) as RpcAnswer
expect(result).toEqual({ error: "Invalid method name" })
})
})

describe("Prim Server can make use of server-side hooks", () => {
test("pre-call and post-call hooks", async () => {
const { callbackHandler, methodHandler } = createPrimTestingPlugins()
const prim = createPrimServer({
module,
callbackHandler,
methodHandler,
preCall(args, func) {
console.log("Pre-call hook", func.name)
if (typeof args[0] === "object" && "greeting" in args[0]) args[0].greeting = "Bonjour"
return { args }
},
postCall(result, func) {
console.log("Post-call hook", func.name)
return typeof result === "string" ? result.replace("Bonjour", "Salut") : result
},
})
const server = prim.server()
const result = await handlePost(server, {
method: "sayHello",
args: { greeting: "Hello", name: "Ted" },
id: 1,
})
expect(result).toEqual({ result: "Salut Ted!", id: 1 })
})
test("pre-call hook with thrown error", async () => {
const { callbackHandler, methodHandler } = createPrimTestingPlugins()
const prim = createPrimServer({
module,
callbackHandler,
methodHandler,
postCall(_result, _func) {
return "What"
},
})
const server = prim.server()
const result = await handlePost(server, {
method: "oops",
id: 1,
})
expect(result).toEqual({ error: "What", id: 1 })
})
})

describe("Prim Server can understand its given context", () => {
Expand Down

0 comments on commit 14ee571

Please sign in to comment.