This release is 5 versions behind 17.1.4 — the latest version of @oak/oak. Jump to latest
Built and signed on GitHub ActionsBuilt and signed on GitHub Actions
Built and signed on GitHub Actions
A middleware framework for handling HTTP with Deno, Node.js, Bun and Cloudflare Workers 🐿️🦕🥟⚙️
This package works with Cloudflare Workers, Node.js, Deno, Bun
JSR Score
94%
Published
4 months ago (17.0.0)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189// Copyright 2018-2024 the oak authors. All rights reserved. MIT license. // deno-lint-ignore-file no-explicit-any /** * A collection of utility APIs which can make testing of an oak application * easier. * * @module */ import type { Application, State } from "./application.ts"; import { accepts, createHttpError, type ErrorStatus, SecureCookieMap, } from "./deps.ts"; import type { RouteParams, RouterContext } from "./router.ts"; import type { Request } from "./request.ts"; import { Response } from "./response.ts"; /** Creates a mock of `Application`. */ export function createMockApp< S extends Record<PropertyKey, any> = Record<string, any>, >( state: S = {} as S, ): Application<S> { const app = { state, use() { return app; }, [Symbol.for("Deno.customInspect")]() { return "MockApplication {}"; }, [Symbol.for("nodejs.util.inspect.custom")]( depth: number, options: any, inspect: (value: unknown, options?: unknown) => string, ) { if (depth < 0) { return options.stylize(`[MockApplication]`, "special"); } const newOptions = Object.assign({}, options, { depth: options.depth === null ? null : options.depth - 1, }); return `${options.stylize("MockApplication", "special")} ${ inspect({}, newOptions) }`; }, } as any; return app; } /** Options that can be set in a mock context. */ export interface MockContextOptions< R extends string, P extends RouteParams<R> = RouteParams<R>, S extends State = Record<string, any>, > { app?: Application<S>; ip?: string; method?: string; params?: P; path?: string; state?: S; headers?: [string, string][]; } /** Allows external parties to modify the context state. */ export const mockContextState = { /** Adjusts the return value of the `acceptedEncodings` in the context's * `request` object. */ encodingsAccepted: "identity", }; /** Create a mock of `Context` or `RouterContext`. */ export function createMockContext< R extends string, P extends RouteParams<R> = RouteParams<R>, S extends State = Record<string, any>, >( { ip = "127.0.0.1", method = "GET", params, path = "/", state, app = createMockApp(state), headers: requestHeaders, }: MockContextOptions<R> = {}, ): RouterContext<R, P, S> { function createMockRequest(): Request { const headers = new Headers(requestHeaders); return { get source(): globalThis.Request | undefined { return new globalThis.Request(new URL(path, "http://localhost/"), { method, headers, }); }, accepts(...types: string[]) { if (!headers.has("Accept")) { return; } if (types.length) { return accepts({ headers }, ...types); } return accepts({ headers }); }, acceptsEncodings() { return mockContextState.encodingsAccepted; }, headers, ip, method, path, search: undefined, searchParams: new URLSearchParams(), url: new URL(path, "http://localhost/"), } as any; } const request = createMockRequest(); const response = new Response(request); const cookies = new SecureCookieMap(request, { response }); return ({ app, params, request, cookies, response, state: Object.assign({}, app.state), assert( condition: any, errorStatus: ErrorStatus = 500, message?: string, props?: Record<string, unknown>, ): asserts condition { if (condition) { return; } const err = createHttpError(errorStatus, message); if (props) { Object.assign(err, props); } throw err; }, throw( errorStatus: ErrorStatus, message?: string, props?: Record<string, unknown>, ): never { const err = createHttpError(errorStatus, message); if (props) { Object.assign(err, props); } throw err; }, [Symbol.for("Deno.customInspect")]() { return `MockContext {}`; }, [Symbol.for("nodejs.util.inspect.custom")]( depth: number, options: any, inspect: (value: unknown, options?: unknown) => string, ) { if (depth < 0) { return options.stylize(`[MockContext]`, "special"); } const newOptions = Object.assign({}, options, { depth: options.depth === null ? null : options.depth - 1, }); return `${options.stylize("MockContext", "special")} ${ inspect({}, newOptions) }`; }, } as unknown) as RouterContext<R, P, S>; } /** Creates a mock `next()` function which can be used when calling * middleware. */ export function createMockNext(): () => Promise<void> { return async function next() {}; }