| description |
|---|
Add a global app wrapper to provide common meta tags or context for application routes.
|
To ensure that your application works as expected we can write tests. Any aspect of Fresh can be tested as a whole together or in isolation. We use Deno's built-in test runner to write tests.
To test middlewares we're going to create a
dummy app and return the relevant info we want to check in a custom / handler.
import { expect } from "@std/expect";
import { App } from "fresh";
const middleware = define.middleware((ctx) => {
ctx.state.text = "middleware text";
return await ctx.next();
});
Deno.test("My middleware - sets ctx.state.text", async () => {
const handler = new App()
.use(middleware)
.get("/", (ctx) => new Response(ctx.state.text))
.handler();
const res = await handler(new Request("http://localhost"));
const text = await res.text();
expect(text).toEqual("middleware text");
});You can extend this pattern for other middlewares. When you have a middleware that adds a header to the returned response, you can assert against that too.
Both the app wrapper component and layouts can be tested in the same way.
import { expect } from "@std/expect";
import { App } from "fresh";
function AppWrapper({ Component }) {
return (
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My App</title>
</head>
<body>
<Component />
</body>
</html>
);
}
Deno.test("App Wrapper - renders title and content", async () => {
const handler = new App()
.appWrapper(AppWrapper)
.get("/", (ctx) => ctx.render(<h1>hello</h1>))
.handler();
const res = await handler(new Request("http://localhost"));
const text = await res.text();
expect(text).toContain("My App");
expect(text).toContain("Hello");
});Same can be done for layouts.
import { expect } from "@std/expect";
import { App } from "fresh";
function MyLayout({ Component }) {
return (
<div>
<h1>My Layout</h1>
<Component />
</div>
);
}
Deno.test("MyLayout - renders heading and content", async () => {
const handler = new App()
.layout("*", MyLayout)
.get("/", (ctx) => ctx.render(<h1>hello</h1>))
.handler();
const res = await handler(new Request("http://localhost"));
const text = await res.text();
expect(text).toContain("My Layout");
expect(text).toContain("Hello");
});File routes are collected by the
Builder class and not just by
App alone. We can generate a snapshot and re-use it for
many app instances in our test suite.
// Best to do this once instead of for every test case for
// performance reasons.
const builder = new Builder();
const applySnapshot = await builder.build({ snapshot: "memory" });
function testApp() {
const app = new App()
.get("/", () => new Response("hello"))
.fsRoutes();
// Applies build snapshot to this app instance.
applySnapshot(app);
}
Deno.test("My Test", () => {
const handler = testApp().handler();
const response = await handler(new Request("http://localhost"));
const text = await response.text();
if (text !== "hello") {
throw new Error("fail");
}
});