remixed v0
This commit is contained in:
4
test/setup-test-env.ts
Normal file
4
test/setup-test-env.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import { installGlobals } from "@remix-run/node/globals";
|
||||
import "@testing-library/jest-dom/extend-expect";
|
||||
|
||||
installGlobals();
|
@ -1,20 +0,0 @@
|
||||
jest.mock("next-pwa", () => ({ __esModule: true, default: jest.fn().mockImplementation((config) => config) }));
|
||||
|
||||
import { setConfig } from "blitz";
|
||||
|
||||
// see https://github.com/vercel/next.js/issues/4024
|
||||
const config = require("../blitz.config");
|
||||
|
||||
setConfig({
|
||||
serverRuntimeConfig: config.serverRuntimeConfig,
|
||||
publicRuntimeConfig: config.publicRuntimeConfig,
|
||||
});
|
||||
|
||||
jest.mock("../integrations/logger", () => ({
|
||||
child: jest.fn().mockReturnValue({
|
||||
log: jest.fn(),
|
||||
error: jest.fn(),
|
||||
debug: jest.fn(),
|
||||
warn: jest.fn(),
|
||||
}),
|
||||
}));
|
@ -1,120 +0,0 @@
|
||||
import listen from "test-listen";
|
||||
import fetch from "isomorphic-unfetch";
|
||||
import { createServer } from "http";
|
||||
import { parse as parseUrl } from "url";
|
||||
import { apiResolver } from "next/dist/server/api-utils";
|
||||
|
||||
import type { PromiseValue } from "type-fest";
|
||||
import type { NextApiHandler } from "next";
|
||||
import type { IncomingMessage, ServerResponse } from "http";
|
||||
|
||||
type FetchReturnValue = PromiseValue<ReturnType<typeof fetch>>;
|
||||
type FetchReturnType<NextResponseJsonType> = Promise<
|
||||
Omit<FetchReturnValue, "json"> & {
|
||||
json: (...args: Parameters<FetchReturnValue["json"]>) => Promise<NextResponseJsonType>;
|
||||
}
|
||||
>;
|
||||
|
||||
/**
|
||||
* The parameters expected by `testApiHandler`.
|
||||
*/
|
||||
export type TestParameters<NextResponseJsonType = unknown> = {
|
||||
/**
|
||||
* A function that receives an `IncomingMessage` object. Use this function to
|
||||
* edit the request before it's injected into the handler.
|
||||
*/
|
||||
requestPatcher?: (req: IncomingMessage) => void;
|
||||
/**
|
||||
* A function that receives a `ServerResponse` object. Use this functions to
|
||||
* edit the request before it's injected into the handler.
|
||||
*/
|
||||
responsePatcher?: (res: ServerResponse) => void;
|
||||
/**
|
||||
* A function that receives an object representing "processed" dynamic routes;
|
||||
* _modifications_ to this object are passed directly to the handler. This
|
||||
* should not be confused with query string parsing, which is handled
|
||||
* automatically.
|
||||
*/
|
||||
paramsPatcher?: (params: Record<string, unknown>) => void;
|
||||
/**
|
||||
* `params` is passed directly to the handler and represent processed dynamic
|
||||
* routes. This should not be confused with query string parsing, which is
|
||||
* handled automatically.
|
||||
*
|
||||
* `params: { id: 'some-id' }` is shorthand for `paramsPatcher: (params) =>
|
||||
* (params.id = 'some-id')`. This is most useful for quickly setting many
|
||||
* params at once.
|
||||
*/
|
||||
params?: Record<string, string | string[]>;
|
||||
/**
|
||||
* `url: 'your-url'` is shorthand for `requestPatcher: (req) => (req.url =
|
||||
* 'your-url')`
|
||||
*/
|
||||
url?: string;
|
||||
/**
|
||||
* The actual handler under test. It should be an async function that accepts
|
||||
* `NextApiRequest` and `NextApiResult` objects (in that order) as its two
|
||||
* parameters.
|
||||
*/
|
||||
handler: NextApiHandler<NextResponseJsonType>;
|
||||
/**
|
||||
* `test` must be a function that runs your test assertions, returning a
|
||||
* promise (or async). This function receives one parameter: `fetch`, which is
|
||||
* the unfetch package's `fetch(...)` function but with the first parameter
|
||||
* omitted.
|
||||
*/
|
||||
test: (obj: { fetch: (init?: RequestInit) => FetchReturnType<NextResponseJsonType> }) => Promise<void>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Uses Next's internal `apiResolver` to execute api route handlers in a
|
||||
* Next-like testing environment.
|
||||
*/
|
||||
export async function testApiHandler<NextResponseJsonType = any>({
|
||||
requestPatcher,
|
||||
responsePatcher,
|
||||
paramsPatcher,
|
||||
params,
|
||||
url,
|
||||
handler,
|
||||
test,
|
||||
}: TestParameters<NextResponseJsonType>) {
|
||||
let server = null;
|
||||
|
||||
try {
|
||||
const localUrl = await listen(
|
||||
(server = createServer((req, res) => {
|
||||
if (!apiResolver) {
|
||||
res.end();
|
||||
throw new Error("missing apiResolver export from next-server/api-utils");
|
||||
}
|
||||
|
||||
url && (req.url = url);
|
||||
requestPatcher && requestPatcher(req);
|
||||
responsePatcher && responsePatcher(res);
|
||||
|
||||
const finalParams = { ...parseUrl(req.url || "", true).query, ...params };
|
||||
paramsPatcher && paramsPatcher(finalParams);
|
||||
|
||||
/**
|
||||
*? From next internals:
|
||||
** apiResolver(
|
||||
** req: IncomingMessage,
|
||||
** res: ServerResponse,
|
||||
** query: any,
|
||||
** resolverModule: any,
|
||||
** apiContext: __ApiPreviewProps,
|
||||
** propagateError: boolean
|
||||
** )
|
||||
*/
|
||||
void apiResolver(req, res, finalParams, handler, undefined as any, true, { route: "", config: {} });
|
||||
})),
|
||||
);
|
||||
|
||||
await test({
|
||||
fetch: (init?: RequestInit) => fetch(localUrl, init) as FetchReturnType<NextResponseJsonType>,
|
||||
});
|
||||
} finally {
|
||||
server?.close();
|
||||
}
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
import { RouterContext, BlitzRouter, BlitzProvider } from "blitz";
|
||||
import { render as defaultRender } from "@testing-library/react";
|
||||
import { renderHook as defaultRenderHook } from "@testing-library/react-hooks";
|
||||
|
||||
export * from "@testing-library/react";
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// This file customizes the render() and renderHook() test functions provided
|
||||
// by React testing library. It adds a router context wrapper with a mocked router.
|
||||
//
|
||||
// You should always import `render` and `renderHook` from this file
|
||||
//
|
||||
// This is the place to add any other context providers you need while testing.
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
// --------------------------------------------------
|
||||
// render()
|
||||
// --------------------------------------------------
|
||||
// Override the default test render with our own
|
||||
//
|
||||
// You can override the router mock like this:
|
||||
//
|
||||
// const { baseElement } = render(<MyComponent />, {
|
||||
// router: { pathname: '/my-custom-pathname' },
|
||||
// });
|
||||
// --------------------------------------------------
|
||||
export function render(ui: RenderUI, { wrapper, router, dehydratedState, ...options }: RenderOptions = {}) {
|
||||
if (!wrapper) {
|
||||
// Add a default context wrapper if one isn't supplied from the test
|
||||
wrapper = ({ children }) => (
|
||||
<BlitzProvider dehydratedState={dehydratedState}>
|
||||
<RouterContext.Provider value={{ ...mockRouter, ...router }}>{children}</RouterContext.Provider>
|
||||
</BlitzProvider>
|
||||
);
|
||||
}
|
||||
return defaultRender(ui, { wrapper, ...options });
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// renderHook()
|
||||
// --------------------------------------------------
|
||||
// Override the default test renderHook with our own
|
||||
//
|
||||
// You can override the router mock like this:
|
||||
//
|
||||
// const result = renderHook(() => myHook(), {
|
||||
// router: { pathname: '/my-custom-pathname' },
|
||||
// });
|
||||
// --------------------------------------------------
|
||||
export function renderHook(hook: RenderHook, { wrapper, router, dehydratedState, ...options }: RenderHookOptions = {}) {
|
||||
if (!wrapper) {
|
||||
// Add a default context wrapper if one isn't supplied from the test
|
||||
wrapper = ({ children }) => (
|
||||
<BlitzProvider dehydratedState={dehydratedState}>
|
||||
<RouterContext.Provider value={{ ...mockRouter, ...router }}>{children}</RouterContext.Provider>
|
||||
</BlitzProvider>
|
||||
);
|
||||
}
|
||||
return defaultRenderHook(hook, { wrapper, ...options });
|
||||
}
|
||||
|
||||
export const mockRouter: BlitzRouter = {
|
||||
basePath: "",
|
||||
pathname: "/",
|
||||
route: "/",
|
||||
asPath: "/",
|
||||
params: {},
|
||||
query: {},
|
||||
isReady: true,
|
||||
isLocaleDomain: false,
|
||||
isPreview: false,
|
||||
push: jest.fn(),
|
||||
replace: jest.fn(),
|
||||
reload: jest.fn(),
|
||||
back: jest.fn(),
|
||||
prefetch: jest.fn(),
|
||||
beforePopState: jest.fn(),
|
||||
events: {
|
||||
on: jest.fn(),
|
||||
off: jest.fn(),
|
||||
emit: jest.fn(),
|
||||
},
|
||||
isFallback: false,
|
||||
};
|
||||
|
||||
type DefaultParams = Parameters<typeof defaultRender>;
|
||||
type RenderUI = DefaultParams[0];
|
||||
type RenderOptions = DefaultParams[1] & {
|
||||
router?: Partial<BlitzRouter>;
|
||||
dehydratedState?: unknown;
|
||||
};
|
||||
|
||||
type DefaultHookParams = Parameters<typeof defaultRenderHook>;
|
||||
type RenderHook = DefaultHookParams[0];
|
||||
type RenderHookOptions = DefaultHookParams[1] & {
|
||||
router?: Partial<BlitzRouter>;
|
||||
dehydratedState?: unknown;
|
||||
};
|
Reference in New Issue
Block a user